def run_example():
    """Azure NetApp Files SDK management example."""

    print_header("Azure NetAppFiles Python SDK Sample - Sample "
                 "project that creates an NFS v4.1 volume with Azure NetApp "
                 " Files SDK with Python")

    # Creating the Azure NetApp Files Client with an Application
    # (service principal) token provider
    credentials, subscription_id = sample_utils.get_credentials()
    anf_client = NetAppManagementClient(credentials, subscription_id)

    # Checking if vnet/subnet information leads to a valid resource
    resources_client = ResourceManagementClient(credentials, subscription_id)
    subnet_id = ('/subscriptions/{}'
                 '/resourceGroups/{}'
                 '/providers/Microsoft.Network/virtualNetworks/{}'
                 '/subnets/{}').format(subscription_id,
                                       VNET_RESOURCE_GROUP_NAME, VNET_NAME,
                                       SUBNET_NAME)

    result = resource_exists(resources_client, subnet_id,
                             VIRTUAL_NETWORKS_SUBNET_API_VERSION)

    if not result:
        console_output(
            "ERROR: Subnet not with id {} not found".format(subnet_id))
        raise Exception(
            "Subnet not found error. Subnet Id {}".format(subnet_id))

    # Creating an Azure NetApp Account
    console_output('Creating Azure NetApp Files account ...')
    account = None
    try:
        account = create_account(anf_client, RESOURCE_GROUP_NAME,
                                 ANF_ACCOUNT_NAME, LOCATION)
        console_output(
            '\tAccount successfully created, resource id: {}'.format(
                account.id))
    except AzureError as ex:
        console_output('An error ocurred. Error details: {}'.format(
            ex.message))
        raise

    # Creating a Capacity Pool
    console_output('Creating Capacity Pool ...')
    capacity_pool = None
    try:
        capacity_pool = create_capacitypool_async(
            anf_client, RESOURCE_GROUP_NAME, account.name, CAPACITYPOOL_NAME,
            CAPACITYPOOL_SERVICE_LEVEL, CAPACITYPOOL_SIZE, LOCATION)
        console_output(
            '\tCapacity Pool successfully created, resource id: {}'.format(
                capacity_pool.id))
    except AzureError as ex:
        console_output('An error ocurred. Error details: {}'.format(
            ex.message))
        raise

    # Creating a Volume

    # Note: With exception of Accounts, all resources with Name property
    # returns a relative path up to the name and to use this property in
    # other methods, like Get for example, the argument needs to be
    # sanitized and just the actual name needs to be used (the hierarchy
    # needs to be cleaned up in the name).
    # Capacity Pool Name property example: "pmarques-anf01/pool01"
    # "pool01" is the actual name that needs to be used instead. Below
    # you will see a sample function that parses the name from its
    # resource id: resource_uri_utils.get_anf_capacity_pool()
    console_output('Creating a Volume ...')
    subnet_id = ('/subscriptions/{}'
                 '/resourceGroups/{}'
                 '/providers/Microsoft.Network/virtualNetworks/{}'
                 '/subnets/{}').format(subscription_id,
                                       VNET_RESOURCE_GROUP_NAME, VNET_NAME,
                                       SUBNET_NAME)
    volume = None
    try:
        pool_name = resource_uri_utils.get_anf_capacity_pool(capacity_pool.id)

        volume = create_volume(anf_client, RESOURCE_GROUP_NAME, account.name,
                               pool_name, VOLUME_NAME, VOLUME_USAGE_QUOTA,
                               CAPACITYPOOL_SERVICE_LEVEL, subnet_id, LOCATION)

        # ARM Workaround to wait for the creation completion
        sample_utils.wait_for_anf_resource(anf_client, volume.id)

        console_output('\tVolume successfully created, resource id: {}'.format(
            volume.id))
    except AzureError as ex:
        console_output('An error ocurred. Error details: {}'.format(
            ex.message))
        raise

    # Cleaning up volumes - for this to happen, please change the value of
    # SHOULD_CLEANUP variable to true.
    # Note: Volume deletion operations at the RP level are executed serially
    if SHOULD_CLEANUP:
        # Cleaning up. This process needs to start the cleanup from the
        # innermost resources down in the hierarchy chain in our case
        # Snapshots->Volumes->Capacity Pools->Accounts
        console_output('Cleaning up...')

        console_output("\tDeleting Volumes...")
        try:
            volume_ids = [volume.id]
            for volume_id in volume_ids:
                console_output("\t\tDeleting {}".format(volume_id))
                anf_client.volumes.begin_delete(
                    RESOURCE_GROUP_NAME, account.name,
                    resource_uri_utils.get_anf_capacity_pool(capacity_pool.id),
                    resource_uri_utils.get_anf_volume(volume_id)).wait()

                # ARM Workaround to wait the deletion complete/propagate
                sample_utils.wait_for_no_anf_resource(anf_client, volume_id)

                console_output('\t\tDeleted Volume: {}'.format(volume_id))
        except AzureError as ex:
            console_output('An error ocurred. Error details: {}'.format(
                ex.message))
            raise

        # Cleaning up Capacity Pool
        console_output("\tDeleting Capacity Pool {} ...".format(
            resource_uri_utils.get_anf_capacity_pool(capacity_pool.id)))
        try:
            anf_client.pools.begin_delete(
                RESOURCE_GROUP_NAME, account.name,
                resource_uri_utils.get_anf_capacity_pool(
                    capacity_pool.id)).wait()

            # ARM Workaround to wait the deletion complete/propagate
            sample_utils.wait_for_no_anf_resource(anf_client, capacity_pool.id)

            console_output('\t\tDeleted Capacity Pool: {}'.format(
                capacity_pool.id))
        except AzureError as ex:
            console_output('An error ocurred. Error details: {}'.format(
                ex.message))
            raise

        # Cleaning up Account
        console_output("\tDeleting Account {} ...".format(account.name))
        try:
            anf_client.accounts.begin_delete(RESOURCE_GROUP_NAME, account.name)
            console_output('\t\tDeleted Account: {}'.format(account.id))
        except AzureError as ex:
            console_output('An error ocurred. Error details: {}'.format(
                ex.message))
            raise
def run_example():
    """Azure NetApp Files SDK management example."""

    print("Azure NetAppFiles Python SDK Sample")
    print("Sample project that performs CRUD management operations with Azure NetApp Files SDK with Python")
    print("-----------------------------------------------------------------------------------------------")

    # Creating the Azure NetApp Files Client with an Application
    # (service principal) token provider
    credentials, subscription_id = sample_utils.get_credentials()
    anf_client = AzureNetAppFilesManagementClient(
        credentials, subscription_id)

    # Creating an Azure NetApp Account
    console_output('Creating Azure NetApp Files account ...')
    account = None
    try:
        account = create_account(
            anf_client, RESOURCE_GROUP_NAME, ANF_ACCOUNT_NAME, LOCATION)
        console_output(
            '\tAccount successfully created, resource id: {}'.format(
                account.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Creating a Capacity Pool
    console_output('Creating Capacity Pool ...')
    capacity_pool = None
    try:
        capacity_pool = create_capacitypool_async(
            anf_client,
            RESOURCE_GROUP_NAME,
            account.name,
            CAPACITYPOOL_NAME,
            CAPACITYPOOL_SERVICE_LEVEL,
            CAPACITYPOOL_SIZE, LOCATION)

        console_output('\tCapacity Pool successfully created, resource id: {}'
                       .format(capacity_pool.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Creating a Volume
    #
    # Note: With exception of Accounts, all resources with Name property
    # returns a relative path up to the name and to use this property in
    # other methods, like Get for example, the argument needs to be
    # sanitized and just the actual name needs to be used (the hierarchy
    # needs to be cleaned up in the name).
    # Capacity Pool Name property example: "pmarques-anf01/pool01"
    # "pool01" is the actual name that needs to be used instead. Below you
    # will see a sample function that parses the name from its
    # resource id: resource_uri_utils.get_anf_capacity_pool()
    console_output('Creating a Volume ...')
    subnet_id = '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Network/virtualNetworks/{}/subnets/{}'\
                .format(subscription_id,
                        VNET_RESOURCE_GROUP_NAME,
                        VNET_NAME,
                        SUBNET_NAME)
    volume = None
    try:
        pool_name = resource_uri_utils.get_anf_capacity_pool(capacity_pool.id)

        volume = create_volume(anf_client,
                               RESOURCE_GROUP_NAME,
                               account.name, pool_name,
                               VOLUME_NAME,
                               VOLUME_USAGE_QUOTA,
                               CAPACITYPOOL_SERVICE_LEVEL,
                               subnet_id,
                               LOCATION)

        console_output('\tVolume successfully created, resource id: {}'
                       .format(volume.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Creating a snapshot
    console_output('Creating a Snapshot ...')
    snapshot = None
    try:
        volume_name = resource_uri_utils.get_anf_volume(volume.id)

        snapshot = create_snapshot(anf_client,
                                   RESOURCE_GROUP_NAME,
                                   account.name,
                                   pool_name,
                                   VOLUME_NAME,
                                   SNAPSHOT_NAME,
                                   LOCATION)

        sample_utils.wait_for_anf_resource(anf_client, snapshot.id)

        console_output(
            '\tSnapshot successfully created, resource id: {}'
            .format(snapshot.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Creating a new volume from snapshot
    #
    # Note: SnapshotId is not the actual resource Id of the snapshot, this
    # value is the unique identifier (guid) of the snapshot, represented
    # by the SnapshotId instead.
    console_output('Creating New Volume from Snapshot ...')
    volume_from_snapshot = None
    try:
        new_volume_name = "Vol-{}".format(
            resource_uri_utils.get_anf_snapshot(snapshot.id))

        volume_from_snapshot = create_volume_from_snapshot(anf_client,
                                                           RESOURCE_GROUP_NAME,
                                                           account.name,
                                                           pool_name,
                                                           volume,
                                                           snapshot.snapshot_id,
                                                           new_volume_name)

        console_output('\tNew volume from snapshot successfully created, resource id: {}'.format(
            volume_from_snapshot.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Updating a Capacity Pool
    console_output('Performing updates on Capacity Pool and Volume...')
    new_capacity_pool_size_tib = 10
    console_output('\tChanging Capacity Pools size from {}TiB to {}TiB'.format(
        sample_utils.get_bytes_in_tib(capacity_pool.size),
        new_capacity_pool_size_tib))
    try:
        capacity_pool_patch = CapacityPoolPatch(location=capacity_pool.location,
                                                service_level=capacity_pool.service_level,
                                                size=sample_utils.get_tib_in_bytes(new_capacity_pool_size_tib))

        capacity_pool = anf_client.pools.update(capacity_pool_patch,
                                                RESOURCE_GROUP_NAME,
                                                account.name,
                                                resource_uri_utils.get_anf_capacity_pool(capacity_pool.id))

        console_output('\t\tCapacity Pool successfully updated, new size {}TiB, resource id: {}'.format(
            sample_utils.get_bytes_in_tib(capacity_pool.size), capacity_pool.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Volume updates: resize and adding a new export policy
    new_volume_size_tib = 1
    console_output('\tChanging volume size from {}TiB to {}TiB'.format(
        sample_utils.get_bytes_in_tib(volume.usage_threshold), new_volume_size_tib))

    # Getting list of export policies and adding a new one at the end
    rule_list = sorted(volume.export_policy.rules,
                       key=lambda r: r.rule_index, reverse=True)

    # Currently, ANF's volume export policy supports up to 5 rules
    export_policies_patch = None
    if len(rule_list) <= 4:
        rule_list.append(ExportPolicyRule(
            allowed_clients="10.0.0.4/32",
            cifs=False,
            nfsv3=True,
            nfsv41=False,
            rule_index=rule_list[0].rule_index + 1,
            unix_read_only=False,
            unix_read_write=True))

        export_policies_patch = VolumePatchPropertiesExportPolicy(
            rules=rule_list)

    if export_policies_patch is None:
        volume_patch = VolumePatch(
            location=volume.location,
            service_level=volume.service_level,
            usage_threshold=sample_utils.get_tib_in_bytes(new_volume_size_tib))
    else:
        volume_patch = VolumePatch(
            location=volume.location,
            service_level=volume.service_level,
            usage_threshold=sample_utils.get_tib_in_bytes(new_volume_size_tib),
            export_policy=export_policies_patch)

    try:
        updated_volume = anf_client.volumes.update(volume_patch,
                                                   RESOURCE_GROUP_NAME,
                                                   account.name,
                                                   resource_uri_utils.get_anf_capacity_pool(
                                                       capacity_pool.id),
                                                   resource_uri_utils.get_anf_volume(volume.id))

        console_output('\t\tVolume successfully updated, new size: {}TiB, export policy count: {}, resource id: {}'
                       .format(sample_utils.get_bytes_in_tib(updated_volume.usage_threshold),
                               len(updated_volume.export_policy.rules),
                               updated_volume.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Retrieving resources
    console_output('Performing retrieval operations ...')

    # Accounts
    # Getting a list of ANF Accounts
    console_output('\tListing accounts...')
    account_list = None
    try:
        account_list = list(anf_client.accounts.list(RESOURCE_GROUP_NAME))

        for i, retrieved_account in enumerate(account_list):
            console_output('\t\t{} - Account Name: {}, Id: {}'
                           .format(i,
                                   retrieved_account.name,
                                   retrieved_account.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Getting a single ANF Account
    console_output('\tGetting a single account...')
    try:
        retrieved_account = anf_client.accounts.get(
            RESOURCE_GROUP_NAME, account.name)

        console_output('\t\tAccount Name: {}, Id: {}'.format(
            retrieved_account.name, retrieved_account.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Capacity Pools
    # Getting a list of capacity pools from an account
    console_output('\tListing capacity pools from account {}...'
                   .format(account.name))
    capacitypool_list = None
    try:
        capacitypool_list = list(anf_client.pools.list(RESOURCE_GROUP_NAME,
                                                       resource_uri_utils.get_anf_account(account.id)))

        for i, retrieved_pool in enumerate(capacitypool_list):
            console_output('\t\t{} - Capacity Pool Name: {}, Id: {}'
                           .format(i,
                                   retrieved_pool.name,
                                   retrieved_pool.id))

    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Getting a single capacity pool
    console_output('\tGetting a single capacity pool...')
    try:
        retrieved_pool = anf_client.pools.get(RESOURCE_GROUP_NAME,
                                              resource_uri_utils.get_anf_account(
                                                  account.id),
                                              resource_uri_utils.get_anf_capacity_pool(capacity_pool.id))

        console_output('\t\tCapacity Pool Name: {}, Id: {}'.format(
            retrieved_pool.name, retrieved_pool.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Volumes
    # Getting a list of volumes from a capacity pool
    console_output('\tListing volumes from capacity pool {}...'.format(
        capacity_pool.name))
    volume_list = None
    try:
        volume_list = list(anf_client.volumes.list(RESOURCE_GROUP_NAME,
                                                   resource_uri_utils.get_anf_account(
                                                       account.id),
                                                   resource_uri_utils.get_anf_capacity_pool(capacity_pool.id)))

        for i, retrieved_volume in enumerate(volume_list):
            console_output('\t\t{} - Volume Name: {}, Id: {}'
                           .format(i,
                                   retrieved_volume.name,
                                   retrieved_volume.id))

    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Getting a single volume
    console_output('\tGetting a single volume...')
    try:
        retrieved_volume = anf_client.volumes.get(RESOURCE_GROUP_NAME,
                                                  resource_uri_utils.get_anf_account(
                                                      account.id),
                                                  resource_uri_utils.get_anf_capacity_pool(
                                                      capacity_pool.id),
                                                  resource_uri_utils.get_anf_volume(volume.id))

        console_output('\t\tVolume Name: {}, Id: {}'.format(
            retrieved_volume.name, retrieved_volume.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Snapshots
    # Getting a list of snapshots from volume
    console_output(
        '\tListing snapshots from from volume {}...'.format(volume.name))
    snapshot_list = None
    try:
        snapshot_list = list(anf_client.snapshots.list(RESOURCE_GROUP_NAME,
                                                       resource_uri_utils.get_anf_account(
                                                           account.id),
                                                       resource_uri_utils.get_anf_capacity_pool(
                                                           capacity_pool.id),
                                                       resource_uri_utils.get_anf_volume(volume.id)))

        for i, retrieved_snapshot in enumerate(snapshot_list):
            console_output('\t\t{} - Snapshot Name: {}, Id: {}'
                           .format(i,
                                   retrieved_snapshot.name,
                                   retrieved_snapshot.id))

    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Getting a single snapshot
    console_output('\tGetting a single snapshot...')
    try:
        retrieved_snapshot = anf_client.snapshots.get(RESOURCE_GROUP_NAME,
                                                      resource_uri_utils.get_anf_account(
                                                          account.id),
                                                      resource_uri_utils.get_anf_capacity_pool(
                                                          capacity_pool.id),
                                                      resource_uri_utils.get_anf_volume(
                                                          volume.id),
                                                      resource_uri_utils.get_anf_snapshot(snapshot.id))

        console_output('\t\tSnapshot Name: {}, Id: {}'.format(
            retrieved_snapshot.name, retrieved_snapshot.id))
    except CloudError as ex:
        console_output(
            'An error ocurred. Error details: {}'.format(ex.message))
        raise

    # Cleaning up. This process needs to start the cleanup from the innermost
    # resources down in the hierarchy chain in our case
    # Snapshots->Volumes->Capacity Pools->Accounts
    if SHOULD_CLEANUP:
        console_output('Cleaning up...')

        # Cleaning up snapshot
        console_output(
            "\tWaiting for 1 minute to let the snapshot used to create a new \
            volume to complete the split operation therefore not being locked...")
        time.sleep(60)
        console_output("\tDeleting Snapshot {}...".format(
            resource_uri_utils.get_anf_snapshot(snapshot.id)))

        try:
            anf_client.snapshots.delete(RESOURCE_GROUP_NAME,
                                        account.name,
                                        resource_uri_utils.get_anf_capacity_pool(
                                            capacity_pool.id),
                                        resource_uri_utils.get_anf_volume(
                                            volume.id),
                                        resource_uri_utils.get_anf_snapshot(snapshot.id)).wait()

            # ARM Workaround to wait the deletion complete/propagate
            sample_utils.wait_for_no_anf_resource(anf_client, snapshot.id)

            console_output('\t\tDeleted Snapshot: {}'.format(snapshot.id))
        except CloudError as ex:
            console_output(
                'An error ocurred. Error details: {}'.format(ex.message))
            raise

        # Cleaning up volumes
        # Note: Volume deletion operations at the RP level are executed
        # serially
        console_output("\tDeleting Volumes...")
        try:
            volume_ids = [volume.id, volume_from_snapshot.id]
            for volume_id in volume_ids:
                console_output("\t\tDeleting {}".format(volume_id))
                anf_client.volumes.delete(RESOURCE_GROUP_NAME,
                                          account.name,
                                          resource_uri_utils.get_anf_capacity_pool(
                                             capacity_pool.id),
                                          resource_uri_utils.get_anf_volume(volume_id)).wait()

                sample_utils.wait_for_no_anf_resource(anf_client, volume_id)

                console_output('\t\tDeleted Volume: {}'.format(volume_id))
        except CloudError as ex:
            console_output(
                'An error ocurred. Error details: {}'.format(ex.message))
            raise

        # Cleaning up Capacity Pool
        console_output("\tDeleting Capacity Pool {} ...".format(
            resource_uri_utils.get_anf_capacity_pool(capacity_pool.id)))
        try:
            anf_client.pools.delete(RESOURCE_GROUP_NAME,
                                    account.name,
                                    resource_uri_utils.get_anf_capacity_pool(
                                        capacity_pool.id)).wait()

            sample_utils.wait_for_no_anf_resource(anf_client, capacity_pool.id)

            console_output(
                '\t\tDeleted Capacity Pool: {}'.format(capacity_pool.id))
        except CloudError as ex:
            console_output(
                'An error ocurred. Error details: {}'.format(ex.message))
            raise

        # Cleaning up Account
        console_output("\tDeleting Account {} ...".format(account.name))
        try:
            anf_client.accounts.delete(RESOURCE_GROUP_NAME, account.name)
            sample_utils.wait_for_no_anf_resource(anf_client, account.id)
            console_output('\t\tDeleted Account: {}'.format(account.id))
        except CloudError as ex:
            console_output(
                'An error ocurred. Error details: {}'.format(ex.message))
            raise
Пример #3
0
def run_example():
    """Azure NetApp Files Snapshot Policy SDK management example"""

    print_header(
        "Azure NetAppFiles Python SDK Samples - Sample project that creates and updates a Snapshot Policy using "
        "the Azure NetApp Files SDK")

    # 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 ANF Resources...")
    # Creating ANF Primary Account
    console_output("Creating Account...")

    anf_account = None
    try:
        anf_account = create_account(anf_client, RESOURCE_GROUP_NAME,
                                     ANF_ACCOUNT_NAME, LOCATION)

        console_output(
            "\tAccount successfully created. Resource id: {}".format(
                anf_account.id))
    except AzureError as ex:
        console_output("An error occurred while creating Account: {}".format(
            ex.message))
        raise

    # Creating Snapshot Policy
    console_output("Creating Snapshot Policy...")

    snapshot_policy = None
    try:
        snapshot_policy = create_snapshot_policy(anf_client,
                                                 RESOURCE_GROUP_NAME,
                                                 anf_account.name,
                                                 SNAPSHOT_POLICY_NAME,
                                                 LOCATION)

        console_output(
            "\tSnapshot Policy successfully created. Resource id: {}".format(
                snapshot_policy.id))
    except AzureError as ex:
        console_output(
            "An error occurred while creating Snapshot Policy: {}".format(
                ex.message))
        raise

    # Creating Capacity Pool
    console_output("Creating Capacity Pool...")

    capacity_pool = None
    try:
        capacity_pool = create_capacity_pool(anf_client, RESOURCE_GROUP_NAME,
                                             anf_account.name,
                                             CAPACITY_POOL_NAME,
                                             CAPACITY_POOL_SIZE, LOCATION)

        console_output(
            "\tCapacity Pool successfully created. Resource id: {}".format(
                capacity_pool.id))
    except AzureError as ex:
        console_output(
            "An error occurred while creating Capacity Pool: {}".format(
                ex.message))
        raise

    # Creating Volume
    console_output("Creating Volume...")
    subnet_id = '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Network/virtualNetworks/{}/subnets/{}'.format(
        subscription_id, RESOURCE_GROUP_NAME, VNET_NAME, SUBNET_NAME)

    volume = None
    try:
        pool_name = resource_uri_utils.get_anf_capacity_pool(capacity_pool.id)

        volume = create_volume(anf_client, RESOURCE_GROUP_NAME,
                               anf_account.name, pool_name, VOLUME_NAME,
                               VOLUME_SIZE, subnet_id, LOCATION)

        console_output("\tVolume successfully created. Resource id: {}".format(
            volume.id))
    except AzureError as ex:
        console_output("An error occurred while creating Volume: {}".format(
            ex.message))
        raise

    # Update Snapshot Policy
    console_output("Updating Snapshot Policy...")

    # Updating number of snapshots to keep for hourly schedule
    hourly_schedule = snapshot_policy.hourly_schedule
    hourly_schedule.snapshotsToKeep = 5

    snapshot_policy_patch = SnapshotPolicyPatch(
        hourly_schedule=hourly_schedule,
        location=snapshot_policy.location,
        enabled=True)

    try:
        anf_client.snapshot_policies.begin_update(RESOURCE_GROUP_NAME,
                                                  ANF_ACCOUNT_NAME,
                                                  SNAPSHOT_POLICY_NAME,
                                                  snapshot_policy_patch)

        console_output("\tSnapshot Policy successfully updated")
    except AzureError as ex:
        console_output(
            "An error occurred while updating Snapshot Policy: {}".format(
                ex.message))
        raise
    """
    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 -> (Snapshot Policy) -> Accounts
        console_output("Cleaning up resources")

        # Cleaning up Volumes
        console_output("Deleting Volumes...")

        try:
            volume_ids = [volume.id]
            for volume_id in volume_ids:
                pool_name = resource_uri_utils.get_resource_value(
                    volume_id, "capacityPools")
                volume_name = resource_uri_utils.get_anf_volume(volume_id)
                console_output("\tDeleting {}".format(volume_name))

                anf_client.volumes.begin_delete(RESOURCE_GROUP_NAME,
                                                anf_account.name, pool_name,
                                                volume_name).wait()

                # ARM Workaround to wait the deletion complete/propagate
                wait_for_no_anf_resource(anf_client, volume_id)
                console_output(
                    "\t\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 = [capacity_pool.id]
            for pool_id in pool_ids:
                pool_name = resource_uri_utils.get_anf_capacity_pool(pool_id)
                console_output("\tDeleting {}".format(pool_name))

                anf_client.pools.begin_delete(RESOURCE_GROUP_NAME,
                                              anf_account.name,
                                              pool_name).wait()

                wait_for_no_anf_resource(anf_client, pool_id)
                console_output(
                    "\t\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 Snapshot Policy
        console_output("Deleting Snapshot Policy...")

        try:
            console_output("\tDeleting {}".format(snapshot_policy.name))

            anf_client.snapshot_policies.begin_delete(
                RESOURCE_GROUP_NAME, anf_account.name,
                SNAPSHOT_POLICY_NAME).wait()

            wait_for_no_anf_resource(anf_client, snapshot_policy.id)
            console_output(
                "\t\tSuccessfully deleted Snapshot Policy: {}".format(
                    snapshot_policy.id))
        except AzureError as ex:
            console_output(
                "An error occurred while deleting snapshot policy: {}".format(
                    ex.message))
            raise

        # Cleaning up Account
        console_output("Deleting Account...")

        try:
            console_output("\tDeleting {}".format(anf_account.name))

            anf_client.accounts.begin_delete(RESOURCE_GROUP_NAME,
                                             anf_account.name).wait()

            console_output("\t\tSuccessfully deleted Account: {}".format(
                anf_account.id))
        except AzureError as ex:
            console_output(
                "An error occurred while deleting accounts: {}".format(
                    ex.message))
            raise

    console_output("ANF Snapshot Policy sample has completed successfully")
Пример #4
0
def run_example():
    """Azure NetApp Files SDK management example."""

    print_header("Azure NetAppFiles Python SDK Sample - Sample "
                 "project that creates a SMB Volume with Azure NetApp "
                 "Files SDK with Python")

    # Getting Active Directory Identity's password
    domain_join_user_password = getpass(
        ("Please type Active Directory's user password that will "
         "domain join ANF's SMB server and press [ENTER]:"))

    if len(domain_join_user_password) == 0:
        console_output('An error ocurred. Password cannot be empty string')
        raise Exception('Password cannot be empty string')

    # Creating the Azure NetApp Files Client with an Application
    # (service principal) token provider
    credentials, subscription_id = sample_utils.get_credentials()
    anf_client = AzureNetAppFilesManagementClient(credentials, subscription_id)

    # Checking if vnet/subnet information leads to a valid resource
    resources_client = ResourceManagementClient(credentials, subscription_id)
    SUBNET_ID = '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Network/virtualNetworks/{}/subnets/{}'.format(
        subscription_id, VNET_RESOURCE_GROUP_NAME, VNET_NAME, SUBNET_NAME)

    result = resource_exists(resources_client, SUBNET_ID,
                             VIRTUAL_NETWORKS_SUBNET_API_VERSION)

    if not result:
        console_output(
            "ERROR: Subnet not with id {} not found".format(SUBNET_ID))
        raise Exception(
            "Subnet not found error. Subnet Id {}".format(SUBNET_ID))

    # Creating an Azure NetApp Account
    '''
    Building the ActiveDirectories object to be passed down to 
    create_account() function. Notice that this is a list but only one
    active directory configuration is supported per subscription and 
    region at the time this sample was first published 
    '''
    active_directories = [
        ActiveDirectory(dns=DNS_LIST,
                        domain=AD_FQDN,
                        username=DOMAIN_JOIN_USERNAME,
                        password=domain_join_user_password,
                        smb_server_name=SMB_SERVERNAME_PREFIX)
    ]

    console_output('Creating Azure NetApp Files account ...')
    account = None
    try:
        account = create_account(anf_client, RESOURCE_GROUP_NAME,
                                 ANF_ACCOUNT_NAME, LOCATION,
                                 active_directories)
        console_output(
            '\tAccount successfully created, resource id: {}'.format(
                account.id))
    except CloudError as ex:
        console_output('An error ocurred. Error details: {}'.format(
            ex.message))
        raise

    # Creating a Capacity Pool
    console_output('Creating Capacity Pool ...')
    capacity_pool = None
    try:
        capacity_pool = create_capacitypool(anf_client, RESOURCE_GROUP_NAME,
                                            account.name, CAPACITYPOOL_NAME,
                                            CAPACITYPOOL_SERVICE_LEVEL,
                                            CAPACITYPOOL_SIZE, LOCATION)
        console_output(
            '\tCapacity Pool successfully created, resource id: {}'.format(
                capacity_pool.id))
    except CloudError as ex:
        console_output('An error ocurred. Error details: {}'.format(
            ex.message))
        raise

    # Creating a Volume
    '''    
    Note: With exception of Accounts, all resources with Name property
    returns a relative path up to the name and to use this property in
    other methods, like Get for example, the argument needs to be
    sanitized and just the actual name needs to be used (the hierarchy
    needs to be cleaned up in the name).
    Capacity Pool Name property example: "pmarques-anf01/pool01"
    "pool01" is the actual name that needs to be used instead. Below
    you will see a sample function that parses the name from its
    resource id: resource_uri_utils.get_anf_capacity_pool()
    '''

    console_output('Creating a Volume ...')

    volume = None
    try:
        pool_name = resource_uri_utils.get_anf_capacity_pool(capacity_pool.id)

        volume = create_volume(anf_client, RESOURCE_GROUP_NAME, account.name,
                               pool_name, VOLUME_NAME, VOLUME_USAGE_QUOTA,
                               CAPACITYPOOL_SERVICE_LEVEL, SUBNET_ID, LOCATION)
        console_output('\tVolume successfully created, resource id: {}'.format(
            volume.id))
        console_output('\t====> SMB Server FQDN: {}'.format(
            volume.mount_targets[0].additional_properties["smbServerFQDN"]))
    except CloudError as ex:
        console_output('An error ocurred. Error details: {}'.format(
            ex.message))
        raise
    '''
    Cleaning up volumes - for this to happen, please change the value of
    SHOULD_CLEANUP variable to true.
    Note: Volume deletion operations at the RP level are executed serially
    '''
    if SHOULD_CLEANUP:
        '''
        Cleaning up. This process needs to start the cleanup from the
        innermost resources down in the hierarchy chain in our case
        Snapshots->Volumes->Capacity Pools->Accounts
        '''
        console_output('Cleaning up...')

        console_output("\tDeleting Volumes...")
        try:
            volume_ids = [volume.id]
            for volume_id in volume_ids:
                console_output("\t\tDeleting {}".format(volume_id))
                anf_client.volumes.delete(
                    RESOURCE_GROUP_NAME, account.name,
                    resource_uri_utils.get_anf_capacitypool(capacity_pool.id),
                    resource_uri_utils.get_anf_volume(volume_id)).wait()

                # ARM Workaround to wait the deletion complete/propagate
                sample_utils.wait_for_no_anf_resource(anf_client, volume_id)

                console_output('\t\tDeleted Volume: {}'.format(volume_id))
        except CloudError as ex:
            console_output('An error ocurred. Error details: {}'.format(
                ex.message))
            raise

        # Cleaning up Capacity Pool
        console_output("\tDeleting Capacity Pool {} ...".format(
            resource_uri_utils.get_anf_capacitypool(capacity_pool.id)))
        try:
            anf_client.pools.delete(
                RESOURCE_GROUP_NAME, account.name,
                resource_uri_utils.get_anf_capacitypool(
                    capacity_pool.id)).wait()

            # ARM Workaround to wait the deletion complete/propagate
            sample_utils.wait_for_no_anf_resource(anf_client, capacity_pool.id)

            console_output('\t\tDeleted Capacity Pool: {}'.format(
                capacity_pool.id))
        except CloudError as ex:
            console_output('An error ocurred. Error details: {}'.format(
                ex.message))
            raise

        # Cleaning up Account
        console_output("\tDeleting Account {} ...".format(account.name))
        try:
            anf_client.accounts.delete(RESOURCE_GROUP_NAME, account.name)
            console_output('\t\tDeleted Account: {}'.format(account.id))
        except CloudError as ex:
            console_output('An error ocurred. Error details: {}'.format(
                ex.message))
            raise
Пример #5
0
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")