def create_volume(cmd, client, account_name, pool_name, volume_name, resource_group_name, location, file_path, usage_threshold, vnet, subnet='default', service_level=None, protocol_types=None, volume_type=None, endpoint_type=None, replication_schedule=None, remote_volume_resource_id=None, tags=None, snapshot_id=None): subs_id = get_subscription_id(cmd.cli_ctx) # determine vnet - supplied value can be name or ARM resource Id if is_valid_resource_id(vnet): resource_parts = parse_resource_id(vnet) vnet = resource_parts['resource_name'] # default the resource group of the subnet to the volume's rg unless the subnet is specified by id subnet_rg = resource_group_name # determine subnet - supplied value can be name or ARM reource Id if is_valid_resource_id(subnet): resource_parts = parse_resource_id(subnet) subnet = resource_parts['resource_name'] subnet_rg = resource_parts['resource_group'] # if NFSv4 is specified then the export policy must reflect this # the RP ordinarily only creates a default setting NFSv3. Export # policy is not settable directly on creation in CLI only via the # add export policy subcommand if (protocol_types is not None) and ("NFSv4.1" in protocol_types): rules = [] export_policy = ExportPolicyRule(rule_index=1, unix_read_only=False, unix_read_write=True, cifs=False, nfsv3=False, nfsv41=True, allowed_clients="0.0.0.0/0") rules.append(export_policy) volume_export_policy = VolumePropertiesExportPolicy(rules=rules) else: volume_export_policy = None # if we have a data protection volume requested then build the component if volume_type == "DataProtection": replication = ReplicationObject( endpoint_type=endpoint_type, replication_schedule=replication_schedule, remote_volume_resource_id=remote_volume_resource_id ) data_protection = VolumePropertiesDataProtection(replication=replication) else: data_protection = None subnet_id = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s" % (subs_id, subnet_rg, vnet, subnet) body = Volume( usage_threshold=int(usage_threshold) * gib_scale, creation_token=file_path, service_level=service_level, location=location, subnet_id=subnet_id, protocol_types=protocol_types, export_policy=volume_export_policy, volume_type=volume_type, data_protection=data_protection, tags=tags, snapshot_id=snapshot_id) return client.create_or_update(body, resource_group_name, account_name, pool_name, volume_name)
def create_dp_volume(client, source_volume, rg=TEST_REMOTE_RG, account_name=TEST_ACC_2, pool_name=TEST_POOL_2, volume_name=TEST_VOL_2, location=REMOTE_LOCATION, volume_only=False, live=False): if not volume_only: pool = create_pool( client, rg, account_name, pool_name, location, False) if live: time.sleep(10) # data protection and replication object replication = ReplicationObject( endpoint_type = "dst", remote_volume_resource_id = source_volume.id, replication_schedule = "_10minutely" ) data_protection = VolumePropertiesDataProtection( replication = replication ) default_protocol_type = { "NFSv3" } volume_body = Volume( location=location, usage_threshold = 100 * GIGABYTE, protocol_types = default_protocol_type, creation_token=volume_name, subnet_id = "/subscriptions/" + SUBSID + "/resourceGroups/" + rg + "/providers/Microsoft.Network/virtualNetworks/" + REMOTE_VNET + "/subnets/default", volume_type = "DataProtection", data_protection = data_protection ) destination_volume = client.volumes.create_or_update( volume_body, rg, account_name, pool_name, volume_name ).result() return destination_volume
def create_volume(cmd, client, account_name, pool_name, volume_name, resource_group_name, location, file_path, usage_threshold, vnet, subnet='default', service_level=None, protocol_types=None, volume_type=None, endpoint_type=None, replication_schedule=None, remote_volume_resource_id=None, tags=None, snapshot_id=None, snapshot_policy_id=None, backup_policy_id=None, backup_enabled=None, backup_id=None, policy_enforced=None, vault_id=None, kerberos_enabled=None, security_style=None, throughput_mibps=None, kerberos5_r=None, kerberos5_rw=None, kerberos5i_r=None, kerberos5i_rw=None, kerberos5p_r=None, kerberos5p_rw=None, has_root_access=None, snapshot_dir_visible=None, smb_encryption=None, smb_continuously_avl=None, encryption_key_source=None, rule_index=None, unix_read_only=None, unix_read_write=None, cifs=None, allowed_clients=None, ldap_enabled=None): subs_id = get_subscription_id(cmd.cli_ctx) # default the resource group of the subnet to the volume's rg unless the subnet is specified by id subnet_rg = resource_group_name # determine vnet - supplied value can be name or ARM resource Id if is_valid_resource_id(vnet): resource_parts = parse_resource_id(vnet) vnet = resource_parts['resource_name'] subnet_rg = resource_parts['resource_group'] # determine subnet - supplied value can be name or ARM reource Id if is_valid_resource_id(subnet): resource_parts = parse_resource_id(subnet) subnet = resource_parts['resource_name'] subnet_rg = resource_parts['resource_group'] # if NFSv4 is specified then the export policy must reflect this # the RP ordinarily only creates a default setting NFSv3. if (protocol_types is not None) and ("NFSv4.1" in protocol_types): rules = [] if allowed_clients is None: raise CLIError( "Parameter allowed-clients needs to be set when protocol-type is NFSv4.1" ) if rule_index is None: raise CLIError( "Parameter rule-index needs to be set when protocol-type is NFSv4.1" ) export_policy = ExportPolicyRule(rule_index=rule_index, unix_read_only=unix_read_only, unix_read_write=unix_read_write, cifs=cifs, nfsv3=False, nfsv41=True, allowed_clients=allowed_clients, kerberos5_read_only=kerberos5_r, kerberos5_read_write=kerberos5_rw, kerberos5i_read_only=kerberos5i_r, kerberos5i_read_write=kerberos5i_rw, kerberos5p_read_only=kerberos5p_r, kerberos5p_read_write=kerberos5p_rw, has_root_access=has_root_access) rules.append(export_policy) volume_export_policy = VolumePropertiesExportPolicy(rules=rules) else: volume_export_policy = None data_protection = None replication = None snapshot = None backup = None # Make sure volume_type is set correctly if replication parameters are set if endpoint_type is not None and replication_schedule is not None and remote_volume_resource_id is not None: volume_type = "DataProtection" if volume_type == "DataProtection": replication = ReplicationObject( endpoint_type=endpoint_type, replication_schedule=replication_schedule, remote_volume_resource_id=remote_volume_resource_id) if snapshot_policy_id is not None: snapshot = VolumeSnapshotProperties( snapshot_policy_id=snapshot_policy_id) if backup_policy_id is not None: backup = VolumeBackupProperties(backup_policy_id=backup_policy_id, policy_enforced=policy_enforced, vault_id=vault_id, backup_enabled=backup_enabled) if replication is not None or snapshot is not None or backup is not None: data_protection = VolumePropertiesDataProtection( replication=replication, snapshot=snapshot, backup=backup) subnet_id = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s" % ( subs_id, subnet_rg, vnet, subnet) body = Volume(usage_threshold=int(usage_threshold) * gib_scale, creation_token=file_path, service_level=service_level, location=location, subnet_id=subnet_id, protocol_types=protocol_types, export_policy=volume_export_policy, volume_type=volume_type, data_protection=data_protection, backup_id=backup_id, kerberos_enabled=kerberos_enabled, throughput_mibps=throughput_mibps, snapshot_directory_visible=snapshot_dir_visible, security_style=security_style, tags=tags, snapshot_id=snapshot_id, smb_encryption=smb_encryption, smb_continuously_available=smb_continuously_avl, encryption_key_source=encryption_key_source, ldap_enabled=ldap_enabled) return client.begin_create_or_update(resource_group_name, account_name, pool_name, volume_name, body)
def run_example(): """Azure NetApp Files Cross-Region Replication (CRR) SDK management example""" print_header( "Azure NetApp Files Python CRR SDK Sample - Sample " "project that creates a primary ANF Account, Capacity Pool, and an " "NFS v4.1 Volume. Then it creates secondary resources and a " "Data Replication Volume.") # Authenticating using service principal, refer to README.md file for requirement details credentials, subscription_id = get_credentials() console_output( "Instantiating a new Azure NetApp Files management client...") anf_client = NetAppManagementClient(credentials, subscription_id) console_output("Creating Primary ANF Resources...") # Creating ANF Primary Account console_output("Creating Primary Account...") primary_account = None try: primary_account = create_account(anf_client, PRIMARY_RESOURCE_GROUP_NAME, PRIMARY_ANF_ACCOUNT_NAME, PRIMARY_LOCATION) console_output( "\tAccount successfully created. Resource id: {}".format( primary_account.id)) except AzureError as ex: console_output("An error occurred while creating Account: {}".format( ex.message)) raise # Creating Primary Capacity Pool console_output("Creating Primary Capacity Pool...") primary_capacity_pool = None try: primary_capacity_pool = create_capacity_pool( anf_client, PRIMARY_RESOURCE_GROUP_NAME, primary_account.name, PRIMARY_CAPACITY_POOL_NAME, CAPACITY_POOL_SIZE, PRIMARY_LOCATION) console_output( "\tCapacity Pool successfully created. Resource id: {}".format( primary_capacity_pool.id)) except AzureError as ex: console_output( "An error occurred while creating Capacity Pool: {}".format( ex.message)) raise # Creating Primary Volume console_output("Creating Primary Volume...") primary_subnet_id = '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Network/virtualNetworks/{}/subnets/{}'.format( subscription_id, PRIMARY_RESOURCE_GROUP_NAME, PRIMARY_VNET_NAME, PRIMARY_SUBNET_NAME) primary_volume = None try: pool_name = resource_uri_utils.get_anf_capacity_pool( primary_capacity_pool.id) primary_volume = create_volume(anf_client, PRIMARY_RESOURCE_GROUP_NAME, primary_account.name, pool_name, PRIMARY_VOLUME_NAME, VOLUME_SIZE, primary_subnet_id, PRIMARY_LOCATION) console_output("\tVolume successfully created. Resource id: {}".format( primary_volume.id)) except AzureError as ex: console_output("An error occurred while creating Volume: {}".format( ex.message)) raise # Wait for primary volume to be ready console_output("Waiting for {} to be available...".format( resource_uri_utils.get_anf_volume(primary_volume.id))) wait_for_anf_resource(anf_client, primary_volume.id) console_output("Creating Secondary ANF Resources...") # Creating ANF Secondary Account console_output("Creating Secondary Account...") secondary_account = None try: secondary_account = create_account(anf_client, SECONDARY_RESOURCE_GROUP_NAME, SECONDARY_ANF_ACCOUNT_NAME, SECONDARY_LOCATION) console_output( "\tAccount successfully created. Resource id: {}".format( secondary_account.id)) except AzureError as ex: console_output("An error occurred while creating Account: {}".format( ex.message)) raise # Creating Secondary Capacity Pool console_output("Creating Secondary Capacity Pool...") secondary_capacity_pool = None try: secondary_capacity_pool = create_capacity_pool( anf_client, SECONDARY_RESOURCE_GROUP_NAME, secondary_account.name, SECONDARY_CAPACITY_POOL_NAME, CAPACITY_POOL_SIZE, SECONDARY_LOCATION) console_output( "\tCapacity Pool successfully created. Resource id: {}".format( secondary_capacity_pool.id)) except AzureError as ex: console_output( "An error occurred while creating Capacity Pool: {}".format( ex.message)) raise # Creating Secondary Volume console_output("Creating Secondary Volume...") secondary_subnet_id = '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Network/virtualNetworks/{}/subnets/{}'.format( subscription_id, SECONDARY_RESOURCE_GROUP_NAME, SECONDARY_VNET_NAME, SECONDARY_SUBNET_NAME) data_replication_volume = None try: replication_object = ReplicationObject( endpoint_type="dst", remote_volume_region=PRIMARY_LOCATION, remote_volume_resource_id=primary_volume.id, replication_schedule="hourly") data_protection_object = VolumePropertiesDataProtection( replication=replication_object) pool_name = resource_uri_utils.get_anf_capacity_pool( secondary_capacity_pool.id) data_replication_volume = create_volume( anf_client, SECONDARY_RESOURCE_GROUP_NAME, secondary_account.name, pool_name, SECONDARY_VOLUME_NAME, VOLUME_SIZE, secondary_subnet_id, SECONDARY_LOCATION, data_protection_object) console_output("\tVolume successfully created. Resource id: {}".format( data_replication_volume.id)) except AzureError as ex: console_output("An error occurred while creating Volume: {}".format( ex.message)) raise # Wait for data replication volume to be ready console_output("Waiting for {} to be available...".format( resource_uri_utils.get_anf_volume(data_replication_volume.id))) wait_for_anf_resource(anf_client, data_replication_volume.id) console_output("Authorizing replication in source region...") # Authorize replication between the two volumes authorization_replication_body = AuthorizeRequest( remote_volume_resource_id=data_replication_volume.id) anf_client.volumes.begin_authorize_replication( resource_uri_utils.get_resource_group(primary_account.id), resource_uri_utils.get_anf_account(primary_account.id), resource_uri_utils.get_anf_capacity_pool(primary_capacity_pool.id), resource_uri_utils.get_anf_volume(primary_volume.id), authorization_replication_body).wait() # Wait for replication to initialize on source volume wait_for_anf_resource(anf_client, primary_volume.id, replication=True) console_output("\tSuccessfully authorized replication in source region") # """ # Cleanup process. For this process to take effect please change the value of # CLEANUP_RESOURCES global variable to 'True' # Note: Volume deletion operations at the RP level are executed serially # """ if CLEANUP_RESOURCES: # The cleanup process starts from the innermost resources down in the hierarchy chain. # In this case: Volumes -> Capacity Pools -> Accounts console_output("Cleaning up resources") # Cleaning up volumes console_output("Deleting Volumes...") # We need to break and then remove the replication attached to the destination # volume before we can delete either volume in a replication. As a result, volumes # must be deleted in the order of destination and then source in this code. # First, we check if the volume is a destination volume and act accordingly. # Note that we need to delete the replication using the destination volume's id # This erases the replication for both destination and source volumes. try: volume_ids = [data_replication_volume.id, primary_volume.id] for volume_id in volume_ids: resource_group = resource_uri_utils.get_resource_group( volume_id) account_name = resource_uri_utils.get_anf_account(volume_id) pool_name = resource_uri_utils.get_anf_capacity_pool(volume_id) volume_name = resource_uri_utils.get_anf_volume(volume_id) current_volume = anf_client.volumes.get( resource_group, account_name, pool_name, volume_name) # If the volume is a destination volume, the replication must be broken and deleted if current_volume.data_protection.replication is not None and \ (current_volume.data_protection.replication.endpoint_type == "dst" or current_volume.data_protection.replication.additional_properties["endPointType"] == "Dst"): console_output( "Deleting replication on Volume {}".format(volume_id)) try: wait_for_mirror_state(anf_client, resource_group, account_name, pool_name, volume_name, mirror_state.MIRRORED) anf_client.volumes.begin_break_replication( resource_group, account_name, pool_name, volume_name).wait() except AzureError as e: if e.status_code == 404: # If replication is not found then the volume can be safely deleted. Therefore we pass on this error and proceed to delete the volume pass else: # Throw all other exceptions console_output( "An error occurred while breaking replication: {}" .format(e.message)) raise try: wait_for_mirror_state(anf_client, resource_group, account_name, pool_name, volume_name, mirror_state.BROKEN) anf_client.volumes.begin_delete_replication( resource_group, account_name, pool_name, volume_name).wait() # Wait for replication to finish deleting wait_for_no_anf_resource(anf_client, volume_id, replication=True) console_output( "\tSuccessfully deleted replication on Volume {}". format(volume_id)) except AzureError as e: if e.status_code == 404: # If replication is not found then the volume can be safely deleted. Therefore we pass on this error and proceed to delete the volume pass else: # Throw all other exceptions console_output( "An error occurred while deleting replication: {}" .format(e.message)) raise console_output("Deleting Volume {}".format(volume_id)) anf_client.volumes.begin_delete(resource_group, account_name, pool_name, volume_name).wait() # ARM workaround to wait for the deletion to complete wait_for_no_anf_resource(anf_client, volume_id) console_output( "\tSuccessfully deleted Volume {}".format(volume_id)) except AzureError as ex: console_output( "An error occurred while deleting volumes: {}".format( ex.message)) raise # Cleaning up capacity pools console_output("Deleting Capacity Pools...") try: pool_ids = [primary_capacity_pool.id, secondary_capacity_pool.id] for pool_id in pool_ids: resource_group = resource_uri_utils.get_resource_group(pool_id) account_name = resource_uri_utils.get_anf_account(pool_id) pool_name = resource_uri_utils.get_anf_capacity_pool(pool_id) console_output("Deleting Capacity Pool {}".format(pool_id)) anf_client.pools.begin_delete(resource_group, account_name, pool_name).wait() # ARM workaround to wait for the deletion to complete wait_for_no_anf_resource(anf_client, pool_id) console_output( "\tSuccessfully deleted Capacity Pool {}".format(pool_id)) except AzureError as ex: console_output( "An error occurred while deleting capacity pools: {}".format( ex.message)) raise # Cleaning up accounts console_output("Deleting Accounts...") try: account_ids = [primary_account.id, secondary_account.id] for account_id in account_ids: resource_group = resource_uri_utils.get_resource_group( account_id) account_name = resource_uri_utils.get_anf_account(account_id) console_output("Deleting Account {}".format(account_id)) anf_client.accounts.begin_delete(resource_group, account_name).wait() # ARM workaround to wait for the deletion to complete wait_for_no_anf_resource(anf_client, account_id) console_output( "\tSuccessfully deleted Account {}".format(account_id)) except AzureError as ex: console_output( "An error occurred while deleting accounts: {}".format( ex.message)) raise console_output("ANF Cross-Region Replication has completed successfully")