Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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 @@ -301,6 +301,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
97 changes: 96 additions & 1 deletion src/azure-cli/azure/cli/command_modules/netappfiles/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,15 @@
- name: --subnet
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
short-summary: Space seperated list of protocols that the volume can use, available protocols are "NFSv4.1", "NFSv3", "CIFS"
- name: --volume-type
short-summary: Whether the volume should be a data protection volume ("DataProtection"), empty if this is not a data protection volume
- name: --endpoint-type
short-summary: Whether the volume is source ("src") or destination ("dst")
Copy link
Contributor

@Juliehzl Juliehzl Mar 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use get_enum_type() for allowed values?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we do this change for next version/update that will come very soon.

- 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, hourly, daily, weekly, monthly"
- 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we both support destination volume name and resource id here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The remote-volume-resource-id parameter expects the resource id.

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 suspend'] = """
type: command
short-summary: Suspend/break a volume replication for the specified destination volume. The replication process is suspended 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: Suspend the replication process
text: >
az netappfiles volume replication suspend -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'] = """
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about changing to show command?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we do this change for next version/update that will come very soon.

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 suspened/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('suspend', 'break_replication')
g.command('resume', 'resync_replication')
g.command('remove', 'delete_replication')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about changing to show command and provide confirmation kwargs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I am misunderstanding I am not sure show is appropriate here this is a custom command that performs an action on approves/authorize the replication connection on the source volume.

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