Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/azure-cli/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ Release History

* Fix #6371: Support filename and environment variable completion in Bash

**NetAppFiles**

* Modified volume create to allow data protection volumes and added cmdlets for replication operations, approve, pause, resume and remove.

**Network**

* Fix #2092: az network dns record-set add/remove: add warning when record-set is not found. In the future, an extra argument will be supported to confirm this auto creation.
Expand Down
95 changes: 95 additions & 0 deletions src/azure-cli/azure/cli/command_modules/netappfiles/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,14 @@
short-summary: The ARM Id or name of the subnet for the vnet. If omitted 'default' will be used
- name: --protocol-types
short-summary: Space seperated list of protocols that the volume can use
- name: --volume-type
short-summary: Whether the volume should be a data protection volume ("DataProtection")
- name: --endpoint-type
short-summary: Whether the volume is source ("src") or destination ("dst")
- name: --remote-volume-resource-id
short-summary: The volume id of the remote volume of the replication (the destination for "src" volume endpoints and the source for "dst" endpoints)
- name: --replication-schedule
short-summary: The replication schedule, e.g. "_10minutely"
- name: --tags
short-summary: Space-separated tags in `key[=value]` format
examples:
Expand All @@ -362,6 +370,93 @@
az netappfiles volume delete -g mygroup --account-name myaccname --pool-name mypoolname --name myvolname
"""

helps['netappfiles volume replication'] = """
type: group
short-summary: Manage Azure NetApp Files (ANF) Volume replication operations.
"""

helps['netappfiles volume replication approve'] = """
type: command
short-summary: Authorize a volume as a replication destination for a specified source.
parameters:
- name: --account-name -a
short-summary: The name of the ANF account
- name: --pool-name -p
short-summary: The name of the ANF pool
- name: --name --volume-name -n -v
short-summary: The name of the replication source volume
- name: --remote-volume-resource-id -d
short-summary: The resource id of the destination replication volume
examples:
- name: Authorize the volume as the replication destination for the source
text: >
az netappfiles volume replication approve -g mygroup --account-name myaccname --pool-name mypoolname --name mysourcevolname --remote-volume-resource-id /subscriptions/69a75bda-882e-44d5-8431-63421204131c/resourceGroups/mygroup1/providers/Microsoft.NetApp/netAppAccounts/myaccount1/capacityPools/mypool1/volumes/mydestinationvolume
"""

helps['netappfiles volume replication pause'] = """
type: command
short-summary: Break a volume replication for the specified destination volume. The replication process is paused until resumed or deleted.
parameters:
- name: --account-name -a
short-summary: The name of the ANF account
- name: --pool-name -p
short-summary: The name of the ANF pool
- name: --name --volume-name -n -v
short-summary: The name of the replication destination volume
examples:
- name: Pause the replication process
text: >
az netappfiles volume replication pause -g mygroup --account-name myaccname --pool-name mypoolname --name mydestinationvolname
"""

helps['netappfiles volume replication resume'] = """
type: command
short-summary: Resync a volume replication for the specified destination volume. The replication process is resumed from source to destination.
parameters:
- name: --account-name -a
short-summary: The name of the ANF account
- name: --pool-name -p
short-summary: The name of the ANF pool
- name: --name --volume-name -n -v
short-summary: The name of the replication destination volume
examples:
- name: Resume the replication process
text: >
az netappfiles volume replication resume -g mygroup --account-name myaccname --pool-name mypoolname --name mydestinationvolname
"""

helps['netappfiles volume replication remove'] = """
type: command
short-summary: Delete a volume replication for the specified destination volume. The data replication objects of source and destination volumes will be removed.
parameters:
- name: --account-name -a
short-summary: The name of the ANF account
- name: --pool-name -p
short-summary: The name of the ANF pool
- name: --name --volume-name -n -v
short-summary: The name of the replication destination volume
examples:
- name: Delete the replication objects of the paired volumes
text: >
az netappfiles volume replication remove -g mygroup --account-name myaccname --pool-name mypoolname --name mydestinationvolname
"""

helps['netappfiles volume replication status'] = """
type: command
short-summary: Get the replication status for the specified replication volume.
parameters:
- name: --account-name -a
short-summary: The name of the ANF account
- name: --pool-name -p
short-summary: The name of the ANF pool
- name: --name --volume-name -n -v
short-summary: The name of the replication destination volume
examples:
- name: Get the replication status for the volume. Returns whether the replication is healthy, the replication schedule and the mirror state (whether replication is paused/broken or synced/mirrored)
text: >
az netappfiles volume replication status -g mygroup --account-name myaccname --pool-name mypoolname --name mydestinationvolname
"""

helps['netappfiles volume export-policy'] = """
type: group
short-summary: Manage Azure NetApp Files (ANF) Volume export policies.
Expand Down
10 changes: 10 additions & 0 deletions src/azure-cli/azure/cli/command_modules/netappfiles/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def load_arguments(self, _):
with self.argument_context('netappfiles account ad list') as c:
c.argument('account_name', help='The name of the ANF account', id_part=None)

load_additionalArguments(self, account_name_type, pool_name_type, volume_name_type)


def load_additionalArguments(self, account_name_type, pool_name_type, volume_name_type):
with self.argument_context('netappfiles pool') as c:
c.argument('account_name', id_part='name')
c.argument('pool_name', pool_name_type, options_list=['--pool-name', '-p', '--name', '-n'])
Expand All @@ -54,6 +58,12 @@ def load_arguments(self, _):
c.argument('pool_name', pool_name_type, id_part=None)
c.argument('volume_name', volume_name_type, options_list=['--volume-name', '-v', '--name', '-n'], id_part=None)

with self.argument_context('netappfiles volume replication approve') as c:
c.argument('account_name', id_part=None)
c.argument('pool_name', pool_name_type, id_part=None)
c.argument('volume_name', volume_name_type, options_list=['--volume-name', '-v', '--name', '-n'], id_part=None)
c.argument('remote_volume_resource_id', options_list=['--remote-volume-resource-id', '-d'], help='The id of the destination replication volume', id_part=None)

with self.argument_context('netappfiles volume export-policy add') as c:
c.argument('unix_read_only', help="Indication of read only access", arg_type=get_three_state_flag())
c.argument('unix_read_write', help="Indication of read and write access", arg_type=get_three_state_flag())
Expand Down
10 changes: 10 additions & 0 deletions src/azure-cli/azure/cli/command_modules/netappfiles/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ def load_command_table(self, _):
doc_string_source='azure.mgmt.netapp.models#VolumePatch',
exception_handler=netappfiles_exception_handler)

with self.command_group('netappfiles volume replication', netappfiles_volumes_sdk) as g:
g.custom_command('approve', 'authorize_replication',
client_factory=volumes_mgmt_client_factory,
doc_string_source='azure.mgmt.netapp.models#Volume',
exception_handler=netappfiles_exception_handler)
g.command('pause', 'break_replication')
g.command('resume', 'resync_replication')
g.command('remove', 'delete_replication')
g.command('status', 'replication_status_method')

with self.command_group('netappfiles', netappfiles_mount_targets_sdk) as g:
g.command('list-mount-targets', 'list')

Expand Down
34 changes: 32 additions & 2 deletions src/azure-cli/azure/cli/command_modules/netappfiles/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# pylint: disable=line-too-long

from knack.log import get_logger
from azure.mgmt.netapp.models import ActiveDirectory, NetAppAccount, NetAppAccountPatch, CapacityPool, CapacityPoolPatch, Volume, VolumePatch, VolumePropertiesExportPolicy, ExportPolicyRule, Snapshot
from azure.mgmt.netapp.models import ActiveDirectory, NetAppAccount, NetAppAccountPatch, CapacityPool, CapacityPoolPatch, Volume, VolumePatch, VolumePropertiesExportPolicy, ExportPolicyRule, Snapshot, ReplicationObject, VolumePropertiesDataProtection
from azure.cli.core.commands.client_factory import get_subscription_id
from msrestazure.tools import is_valid_resource_id, parse_resource_id

Expand All @@ -24,6 +24,8 @@ def _update_mapper(existing, new, keys):
setattr(new, key, new_value if new_value is not None else existing_value)


# -- account --

# pylint: disable=unused-argument
# account update - active_directory is amended with subgroup commands
def create_account(cmd, client, account_name, resource_group_name, location, tags=None):
Expand Down Expand Up @@ -74,6 +76,8 @@ def patch_account(cmd, instance, account_name, resource_group_name, tags=None):
return body


# -- pool --

def create_pool(cmd, client, account_name, pool_name, resource_group_name, service_level, location, size, tags=None):
body = CapacityPool(service_level=service_level, size=int(size) * tib_scale, location=location, tags=tags)
return client.create_or_update(body, resource_group_name, account_name, pool_name)
Expand All @@ -89,7 +93,9 @@ def patch_pool(cmd, instance, size=None, service_level=None, tags=None):
return body


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, tags=None):
# -- volume --
# pylint: disable=too-many-locals
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):
subs_id = get_subscription_id(cmd.cli_ctx)

# determine vnet - supplied value can be name or ARM resource Id
Expand Down Expand Up @@ -119,6 +125,18 @@ def create_volume(cmd, client, account_name, pool_name, volume_name, resource_gr
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,
Expand All @@ -128,6 +146,8 @@ def create_volume(cmd, client, account_name, pool_name, volume_name, resource_gr
subnet_id=subnet_id,
protocol_types=protocol_types,
export_policy=volume_export_policy,
volume_type=volume_type,
data_protection=data_protection,
tags=tags)

return client.create_or_update(body, resource_group_name, account_name, pool_name, volume_name)
Expand All @@ -144,6 +164,7 @@ def patch_volume(cmd, instance, usage_threshold=None, service_level=None, protoc
return params


# -- volume export policy --
# add new rule to policy
def add_export_policy_rule(cmd, instance, allowed_clients, rule_index, unix_read_only, unix_read_write, cifs, nfsv3, nfsv41):
rules = []
Expand Down Expand Up @@ -179,6 +200,15 @@ def remove_export_policy_rule(cmd, instance, rule_index):
return instance


# -- volume replication --

# authorize replication (targets source volume with destination volume in payload)
def authorize_replication(cmd, client, resource_group_name, account_name, pool_name, volume_name, remote_volume_resource_id):
return client.authorize_replication(resource_group_name, account_name, pool_name, volume_name, remote_volume_resource_id)


# -- snapshot --

def create_snapshot(cmd, client, account_name, pool_name, volume_name, snapshot_name, resource_group_name, location, file_system_id=None):
body = Snapshot(location=location, file_system_id=file_system_id)
return client.create(body, resource_group_name, account_name, pool_name, volume_name, snapshot_name)
Loading