Microsoft Azure Service Bus Management Client Library for programmatic control of Service Bus namespaces, queues, topics, subscriptions, and authorization rules
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Geo-disaster recovery configuration, pairing management, failover operations, and data replication control. Service Bus Geo-disaster recovery provides automatic failover capability by pairing a primary namespace with a secondary namespace in different Azure regions.
Create, retrieve, update, and delete geo-disaster recovery configurations for namespace pairing.
def list(
self,
resource_group_name: str,
namespace_name: str
) -> ItemPaged[ArmDisasterRecovery]:
"""List disaster recovery configurations for a namespace.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the primary namespace.
Returns:
ItemPaged[ArmDisasterRecovery]: Iterable of disaster recovery configurations.
"""
def create_or_update(
self,
resource_group_name: str,
namespace_name: str,
alias: str,
parameters: ArmDisasterRecovery
) -> ArmDisasterRecovery:
"""Create or update a disaster recovery configuration.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the primary namespace.
alias (str): Name of the disaster recovery alias.
parameters (ArmDisasterRecovery): DR configuration parameters.
Returns:
ArmDisasterRecovery: The disaster recovery configuration.
"""
def get(
self,
resource_group_name: str,
namespace_name: str,
alias: str
) -> ArmDisasterRecovery:
"""Get disaster recovery configuration details.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the primary namespace.
alias (str): Name of the disaster recovery alias.
Returns:
ArmDisasterRecovery: The disaster recovery configuration.
"""
def delete(
self,
resource_group_name: str,
namespace_name: str,
alias: str
) -> None:
"""Delete a disaster recovery configuration.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the primary namespace.
alias (str): Name of the disaster recovery alias.
"""Control pairing relationships and perform failover operations between primary and secondary namespaces.
def break_pairing(
self,
resource_group_name: str,
namespace_name: str,
alias: str
) -> None:
"""Break the pairing between primary and secondary namespaces.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the primary namespace.
alias (str): Name of the disaster recovery alias.
"""
def fail_over(
self,
resource_group_name: str,
namespace_name: str,
alias: str
) -> None:
"""Initiate failover from primary to secondary namespace.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the secondary namespace.
alias (str): Name of the disaster recovery alias.
Note:
This operation is called on the secondary namespace to promote it to primary.
"""Manage authorization rules for disaster recovery aliases that work across both namespaces.
def list_authorization_rules(
self,
resource_group_name: str,
namespace_name: str,
alias: str
) -> ItemPaged[SBAuthorizationRule]:
"""List authorization rules for a disaster recovery configuration.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the namespace.
alias (str): Name of the disaster recovery alias.
Returns:
ItemPaged[SBAuthorizationRule]: Iterable of authorization rules.
"""
def get_authorization_rule(
self,
resource_group_name: str,
namespace_name: str,
alias: str,
authorization_rule_name: str
) -> SBAuthorizationRule:
"""Get an authorization rule for a disaster recovery configuration.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the namespace.
alias (str): Name of the disaster recovery alias.
authorization_rule_name (str): Name of the authorization rule.
Returns:
SBAuthorizationRule: The authorization rule.
"""
def list_keys(
self,
resource_group_name: str,
namespace_name: str,
alias: str,
authorization_rule_name: str
) -> AccessKeys:
"""Get access keys for a disaster recovery authorization rule.
Args:
resource_group_name (str): Name of the resource group.
namespace_name (str): Name of the namespace.
alias (str): Name of the disaster recovery alias.
authorization_rule_name (str): Name of the authorization rule.
Returns:
AccessKeys: Keys with alias connection strings for disaster recovery.
"""from azure.mgmt.servicebus import ServiceBusManagementClient
from azure.mgmt.servicebus.models import ArmDisasterRecovery
from azure.identity import DefaultAzureCredential
client = ServiceBusManagementClient(DefaultAzureCredential(), subscription_id)
# First, create primary and secondary namespaces in different regions
# (This example assumes they already exist)
# Configure geo-disaster recovery pairing
dr_config = ArmDisasterRecovery(
partner_namespace="/subscriptions/{subscription-id}/resourceGroups/my-secondary-rg/providers/Microsoft.ServiceBus/namespaces/my-secondary-namespace",
alternate_name="my-dr-alias" # Optional friendly name
)
disaster_recovery = client.disaster_recovery_configs.create_or_update(
resource_group_name="my-primary-rg",
namespace_name="my-primary-namespace",
alias="my-dr-alias",
parameters=dr_config
)
print(f"Disaster recovery configured: {disaster_recovery.name}")
print(f"Partner namespace: {disaster_recovery.partner_namespace}")
print(f"Role: {disaster_recovery.role}")
print(f"Provisioning state: {disaster_recovery.provisioning_state}")
# Wait for the pairing to be established
import time
while True:
dr_status = client.disaster_recovery_configs.get(
resource_group_name="my-primary-rg",
namespace_name="my-primary-namespace",
alias="my-dr-alias"
)
if dr_status.provisioning_state == "Succeeded":
print("Disaster recovery pairing established successfully")
break
elif dr_status.provisioning_state == "Failed":
print("Disaster recovery pairing failed")
break
else:
print(f"Waiting for pairing... Status: {dr_status.provisioning_state}")
time.sleep(10)# Get authorization rules for the disaster recovery alias
dr_auth_rules = client.disaster_recovery_configs.list_authorization_rules(
resource_group_name="my-primary-rg",
namespace_name="my-primary-namespace",
alias="my-dr-alias"
)
for rule in dr_auth_rules:
print(f"DR Auth Rule: {rule.name}")
print(f"Rights: {rule.rights}")
# Get access keys for disaster recovery
# These connection strings automatically point to the active namespace
dr_keys = client.disaster_recovery_configs.list_keys(
resource_group_name="my-primary-rg",
namespace_name="my-primary-namespace",
alias="my-dr-alias",
authorization_rule_name="RootManageSharedAccessKey"
)
print("Disaster Recovery Connection Strings:")
print(f"Primary: {dr_keys.alias_primary_connection_string}")
print(f"Secondary: {dr_keys.alias_secondary_connection_string}")
# Applications should use these alias connection strings
# They automatically redirect to the active namespace
connection_string = dr_keys.alias_primary_connection_stringfrom azure.mgmt.servicebus.models import RoleDisasterRecovery, ProvisioningStateDR
# Monitor disaster recovery configuration
dr_config = client.disaster_recovery_configs.get(
resource_group_name="my-primary-rg",
namespace_name="my-primary-namespace",
alias="my-dr-alias"
)
print(f"Disaster Recovery Status:")
print(f"Alias: {dr_config.name}")
print(f"Role: {dr_config.role}")
print(f"Provisioning State: {dr_config.provisioning_state}")
print(f"Partner Namespace: {dr_config.partner_namespace}")
print(f"Alternate Name: {dr_config.alternate_name}")
print(f"Pending Replication Operations: {dr_config.pending_replication_operations_count}")
# Check the role to understand the current active namespace
if dr_config.role == RoleDisasterRecovery.PRIMARY:
print("This namespace is currently the PRIMARY (active)")
elif dr_config.role == RoleDisasterRecovery.SECONDARY:
print("This namespace is currently the SECONDARY (standby)")
elif dr_config.role == RoleDisasterRecovery.PRIMARY_NOT_REPLICATING:
print("This namespace is PRIMARY but not replicating (pairing broken)")
# Monitor replication status
if dr_config.pending_replication_operations_count > 0:
print(f"Warning: {dr_config.pending_replication_operations_count} operations pending replication")# Before failover, check the current status
primary_dr = client.disaster_recovery_configs.get(
resource_group_name="my-primary-rg",
namespace_name="my-primary-namespace",
alias="my-dr-alias"
)
print(f"Before failover - Primary role: {primary_dr.role}")
# Initiate failover from the secondary namespace
# Note: This promotes the secondary to become the new primary
try:
client.disaster_recovery_configs.fail_over(
resource_group_name="my-secondary-rg",
namespace_name="my-secondary-namespace",
alias="my-dr-alias"
)
print("Failover initiated successfully")
# Wait for failover to complete
time.sleep(30)
# Check the new status
secondary_dr = client.disaster_recovery_configs.get(
resource_group_name="my-secondary-rg",
namespace_name="my-secondary-namespace",
alias="my-dr-alias"
)
print(f"After failover - Secondary role: {secondary_dr.role}")
except Exception as e:
print(f"Failover failed: {e}")# Break the pairing when DR is no longer needed
# This should be done from the primary namespace
try:
client.disaster_recovery_configs.break_pairing(
resource_group_name="my-primary-rg",
namespace_name="my-primary-namespace",
alias="my-dr-alias"
)
print("Disaster recovery pairing broken successfully")
# After breaking, both namespaces become independent
# The alias connection strings will no longer work
except Exception as e:
print(f"Failed to break pairing: {e}")
# Clean up the disaster recovery configuration
client.disaster_recovery_configs.delete(
resource_group_name="my-primary-rg",
namespace_name="my-primary-namespace",
alias="my-dr-alias"
)
print("Disaster recovery configuration deleted")def setup_disaster_recovery_with_monitoring():
"""Complete disaster recovery setup with monitoring"""
# 1. Create the DR pairing
dr_config = ArmDisasterRecovery(
partner_namespace="/subscriptions/{subscription-id}/resourceGroups/secondary-rg/providers/Microsoft.ServiceBus/namespaces/secondary-namespace"
)
dr = client.disaster_recovery_configs.create_or_update(
resource_group_name="primary-rg",
namespace_name="primary-namespace",
alias="production-dr",
parameters=dr_config
)
# 2. Wait for pairing to complete
max_wait_time = 300 # 5 minutes
wait_interval = 10 # 10 seconds
elapsed_time = 0
while elapsed_time < max_wait_time:
status = client.disaster_recovery_configs.get(
resource_group_name="primary-rg",
namespace_name="primary-namespace",
alias="production-dr"
)
if status.provisioning_state == "Succeeded":
print("Disaster recovery pairing established")
break
elif status.provisioning_state == "Failed":
raise Exception("Disaster recovery pairing failed")
time.sleep(wait_interval)
elapsed_time += wait_interval
# 3. Get DR connection strings for applications
dr_keys = client.disaster_recovery_configs.list_keys(
resource_group_name="primary-rg",
namespace_name="primary-namespace",
alias="production-dr",
authorization_rule_name="RootManageSharedAccessKey"
)
# 4. Store connection strings securely (e.g., Azure Key Vault)
dr_connection_string = dr_keys.alias_primary_connection_string
return {
"dr_alias": "production-dr",
"connection_string": dr_connection_string,
"status": "active"
}
def check_disaster_recovery_health():
"""Monitor disaster recovery health"""
dr_status = client.disaster_recovery_configs.get(
resource_group_name="primary-rg",
namespace_name="primary-namespace",
alias="production-dr"
)
health_check = {
"alias": dr_status.name,
"role": dr_status.role,
"provisioning_state": dr_status.provisioning_state,
"pending_operations": dr_status.pending_replication_operations_count,
"healthy": True,
"issues": []
}
# Check for issues
if dr_status.provisioning_state != "Succeeded":
health_check["healthy"] = False
health_check["issues"].append(f"Provisioning state: {dr_status.provisioning_state}")
if dr_status.pending_replication_operations_count > 10:
health_check["healthy"] = False
health_check["issues"].append(f"High pending operations: {dr_status.pending_replication_operations_count}")
if dr_status.role == RoleDisasterRecovery.PRIMARY_NOT_REPLICATING:
health_check["healthy"] = False
health_check["issues"].append("Primary not replicating - pairing may be broken")
return health_check
# Example usage
try:
dr_info = setup_disaster_recovery_with_monitoring()
print(f"DR setup complete: {dr_info}")
# Periodic health checks
health = check_disaster_recovery_health()
if not health["healthy"]:
print(f"DR Health Issues: {health['issues']}")
else:
print("Disaster recovery is healthy")
except Exception as e:
print(f"Disaster recovery setup failed: {e}")class ArmDisasterRecovery:
def __init__(self, **kwargs): ...
# Disaster recovery properties
id: Optional[str]
name: Optional[str]
type: Optional[str]
# Configuration
provisioning_state: Optional[Union[str, ProvisioningStateDR]]
pending_replication_operations_count: Optional[int]
partner_namespace: Optional[str] # ARM resource ID of partner namespace
alternate_name: Optional[str] # Friendly name for the alias
role: Optional[Union[str, RoleDisasterRecovery]]
class ArmDisasterRecoveryListResult:
def __init__(self, **kwargs): ...
value: Optional[List[ArmDisasterRecovery]]
next_link: Optional[str]
from enum import Enum
class ProvisioningStateDR(str, Enum):
ACCEPTED = "Accepted"
SUCCEEDED = "Succeeded"
FAILED = "Failed"
class RoleDisasterRecovery(str, Enum):
PRIMARY = "Primary" # Active namespace receiving traffic
PRIMARY_NOT_REPLICATING = "PrimaryNotReplicating" # Primary but pairing broken
SECONDARY = "Secondary" # Standby namespace receiving replicationpending_replication_operations_countInstall with Tessl CLI
npx tessl i tessl/pypi-azure-mgmt-servicebus