diff --git a/src/command_modules/azure-cli-network/HISTORY.rst b/src/command_modules/azure-cli-network/HISTORY.rst index 5badc505dc9..29e201585cd 100644 --- a/src/command_modules/azure-cli-network/HISTORY.rst +++ b/src/command_modules/azure-cli-network/HISTORY.rst @@ -3,6 +3,11 @@ Release History =============== +2.0.26 +++++++ +* `network dns zone create`: Adding support for creating Private DNS zones. +* `network dns zone update`: Adding support for updating Private DNS zones. + 2.0.25 ++++++ * Support Autorest 3.0 based SDKs @@ -171,7 +176,7 @@ Release History * Add support for active-active VNet gateways * Remove nulls values from output of `network vpn-connection list/show` commands. -* BC: Fix bug in the output of `vpn-connection create` +* BC: Fix bug in the output of `vpn-connection create` * Fix bug where '--key-length' argument of 'vpn-connection create' was not parsed correctly. * Fix bug in `dns zone import` where records were not imported correctly. * Fix bug where `traffic-manager endpoint update` did not work. diff --git a/src/command_modules/azure-cli-network/azure/cli/command_modules/network/_params.py b/src/command_modules/azure-cli-network/azure/cli/command_modules/network/_params.py index 977f90cde1a..48fc4c13dc1 100644 --- a/src/command_modules/azure-cli-network/azure/cli/command_modules/network/_params.py +++ b/src/command_modules/azure-cli-network/azure/cli/command_modules/network/_params.py @@ -25,7 +25,7 @@ validate_private_ip_address, get_servers_validator, get_public_ip_validator, get_nsg_validator, get_subnet_validator, get_network_watcher_from_vm, get_network_watcher_from_location, - get_asg_validator, validate_ip_tags) + get_asg_validator, get_vnet_validator, validate_ip_tags) from azure.mgmt.network.models import ApplicationGatewaySslProtocol from azure.mgmt.trafficmanager.models import MonitorProtocol from azure.cli.command_modules.network._completers import ( @@ -42,13 +42,13 @@ def load_arguments(self, _): ExpressRouteCircuitPeeringType, ExpressRouteCircuitSkuFamily, ExpressRouteCircuitSkuTier, IPAllocationMethod, IPVersion, LoadBalancerSkuName, LoadDistribution, ProbeProtocol, ProcessorArchitecture, Protocol, PublicIPAddressSkuName, RouteNextHopType, SecurityRuleAccess, SecurityRuleProtocol, SecurityRuleDirection, TransportProtocol, - VirtualNetworkGatewaySkuName, VirtualNetworkGatewayType, VpnClientProtocol, VpnType) = self.get_models( + VirtualNetworkGatewaySkuName, VirtualNetworkGatewayType, VpnClientProtocol, VpnType, ZoneType) = self.get_models( 'Access', 'ApplicationGatewayFirewallMode', 'ApplicationGatewayProtocol', 'ApplicationGatewayRedirectType', 'ApplicationGatewayRequestRoutingRuleType', 'ApplicationGatewaySkuName', 'AuthenticationMethod', 'Direction', 'ExpressRouteCircuitPeeringType', 'ExpressRouteCircuitSkuFamily', 'ExpressRouteCircuitSkuTier', 'IPAllocationMethod', 'IPVersion', 'LoadBalancerSkuName', 'LoadDistribution', 'ProbeProtocol', 'ProcessorArchitecture', 'Protocol', 'PublicIPAddressSkuName', 'RouteNextHopType', 'SecurityRuleAccess', 'SecurityRuleProtocol', 'SecurityRuleDirection', 'TransportProtocol', - 'VirtualNetworkGatewaySkuName', 'VirtualNetworkGatewayType', 'VpnClientProtocol', 'VpnType') + 'VirtualNetworkGatewaySkuName', 'VirtualNetworkGatewayType', 'VpnClientProtocol', 'VpnType', 'ZoneType') default_existing = 'If only one exists, omit to use as default.' @@ -315,15 +315,9 @@ def load_arguments(self, _): c.argument('zone_name', name_arg_type) c.ignore('location') - # TODO: remove when feature ready - c.ignore('zone_type') - c.ignore('registration_vnets') - c.ignore('resolution_vnets') - - # TODO: Uncomment when feature is ready - # c.argument('zone_type', help='Type of DNS zone to create.', arg_type=get_enum_type(ZoneType)) - # c.argument('registration_vnets', arg_group='Private Zone', nargs='+', help='Space-separated names or IDs of virtual networks that register hostnames in this DNS zone.', validator=get_vnet_validator('registration_vnets')) - # c.argument('resolution_vnets', arg_group='Private Zone', nargs='+', help='Space-separated names or IDs of virtual networks that resolve records in this DNS zone.', validator=get_vnet_validator('resolution_vnets')) + c.argument('zone_type', help='Type of DNS zone to create.', arg_type=get_enum_type(ZoneType)) + c.argument('registration_vnets', arg_group='Private Zone', nargs='+', help='Space-separated names or IDs of virtual networks that register hostnames in this DNS zone.', validator=get_vnet_validator('registration_vnets')) + c.argument('resolution_vnets', arg_group='Private Zone', nargs='+', help='Space-separated names or IDs of virtual networks that resolve records in this DNS zone.', validator=get_vnet_validator('resolution_vnets')) with self.argument_context('network dns zone import') as c: c.argument('file_name', options_list=('--file-name', '-f'), type=file_type, completer=FilesCompleter(), help='Path to the DNS zone file to import') diff --git a/src/command_modules/azure-cli-network/azure/cli/command_modules/network/commands.py b/src/command_modules/azure-cli-network/azure/cli/command_modules/network/commands.py index 99caefffc38..ddb4f0de4c2 100644 --- a/src/command_modules/azure-cli-network/azure/cli/command_modules/network/commands.py +++ b/src/command_modules/azure-cli-network/azure/cli/command_modules/network/commands.py @@ -303,7 +303,7 @@ def _make_singular(value): g.custom_command('import', 'import_zone') g.custom_command('export', 'export_zone') g.custom_command('create', 'create_dns_zone', client_factory=cf_dns_mgmt_zones) - g.generic_update_command('update') + g.generic_update_command('update', custom_func_name='update_dns_zone') with self.command_group('network dns record-set') as g: g.custom_command('list', 'list_dns_record_set', client_factory=cf_dns_mgmt_record_sets, transform=transform_dns_record_set_output) diff --git a/src/command_modules/azure-cli-network/azure/cli/command_modules/network/custom.py b/src/command_modules/azure-cli-network/azure/cli/command_modules/network/custom.py index 7cd60c883ca..f15ed116642 100644 --- a/src/command_modules/azure-cli-network/azure/cli/command_modules/network/custom.py +++ b/src/command_modules/azure-cli-network/azure/cli/command_modules/network/custom.py @@ -822,7 +822,7 @@ def update_asg(instance, tags=None): # region DNS Commands def create_dns_zone(client, resource_group_name, zone_name, location='global', tags=None, - if_none_match=False, zone_type=None, resolution_vnets=None, registration_vnets=None): + if_none_match=False, zone_type='Public', resolution_vnets=None, registration_vnets=None): zone = Zone(location=location, tags=tags) if hasattr(zone, 'zone_type'): diff --git a/src/command_modules/azure-cli-network/azure/cli/command_modules/network/tests/latest/test_dns_commands.py b/src/command_modules/azure-cli-network/azure/cli/command_modules/network/tests/latest/test_dns_commands.py index 592adb81981..3793076cce5 100644 --- a/src/command_modules/azure-cli-network/azure/cli/command_modules/network/tests/latest/test_dns_commands.py +++ b/src/command_modules/azure-cli-network/azure/cli/command_modules/network/tests/latest/test_dns_commands.py @@ -159,6 +159,84 @@ def test_dns(self, resource_group): self.cmd('network dns zone delete -g {rg} -n {zone} -y', checks=self.is_empty()) + @ResourceGroupPreparer(name_prefix='cli_test_dns') + def test_private_dns(self, resource_group): + + self.kwargs['zone'] = 'myprivatezone.com' + self.kwargs['regvnet'] = 'regvnet' + self.kwargs['resvnet'] = 'resvnet' + + self.cmd('network vnet create -n {regvnet} -g {rg}') + self.cmd('network vnet create -n {resvnet} -g {rg}') + + self.cmd('network dns zone list') # just verify is works (no Exception raised) + self.cmd('network dns zone create -n {zone} -g {rg} --zone-type Private --registration-vnets {regvnet} --resolution-vnets {resvnet}') + self.cmd('network dns zone list -g {rg}', + checks=self.check('length(@)', 1)) + + base_record_sets = 1 + self.cmd('network dns zone show -n {zone} -g {rg}', + checks=self.check('numberOfRecordSets', base_record_sets)) + + args = { + 'a': '--ipv4-address 10.0.0.10', + 'aaaa': '--ipv6-address 2001:db8:0:1:1:1:1:1', + 'caa': '--flags 0 --tag foo --value "my value"', + 'cname': '--cname mycname', + 'mx': '--exchange 12 --preference 13', + 'ptr': '--ptrdname foobar.com', + 'soa': '--email foo.com --expire-time 30 --minimum-ttl 20 --refresh-time 60 --retry-time 90 --serial-number 123', + 'srv': '--port 1234 --priority 1 --target target.com --weight 50', + 'txt': '--value some_text' + } + + # Private Zones do NOT support delegation through NS records + record_types = ['a', 'aaaa', 'caa', 'cname', 'mx', 'ptr', 'srv', 'txt'] + + for t in record_types: + # test creating the record set and then adding records + self.cmd('network dns record-set {0} create -n myrs{0} -g {{rg}} --zone-name {{zone}}'.format(t)) + add_command = 'set-record' if t == 'cname' else 'add-record' + self.cmd('network dns record-set {0} {2} -g {{rg}} --zone-name {{zone}} --record-set-name myrs{0} {1}'.format(t, args[t], add_command)) + # test creating the record set at the same time you add records + self.cmd('network dns record-set {0} {2} -g {{rg}} --zone-name {{zone}} --record-set-name myrs{0}alt {1}'.format(t, args[t], add_command)) + + self.cmd('network dns record-set a add-record -g {rg} --zone-name {zone} --record-set-name myrsa --ipv4-address 10.0.0.11') + self.cmd('network dns record-set soa update -g {{rg}} --zone-name {{zone}} {0}'.format(args['soa'])) + + long_value = '0123456789' * 50 + self.cmd('network dns record-set txt add-record -g {{rg}} -z {{zone}} -n longtxt -v {0}'.format(long_value)) + + typed_record_sets = 2 * len(record_types) + 1 + self.cmd('network dns zone show -n {zone} -g {rg}', + checks=self.check('numberOfRecordSets', base_record_sets + typed_record_sets)) + self.cmd('network dns record-set a show -n myrsa -g {rg} --zone-name {zone}', + checks=self.check('length(arecords)', 2)) + + # test list vs. list type + self.cmd('network dns record-set list -g {rg} -z {zone}', + checks=self.check('length(@)', base_record_sets + typed_record_sets)) + + self.cmd('network dns record-set txt list -g {rg} -z {zone}', + checks=self.check('length(@)', 3)) + + for t in record_types: + self.cmd('network dns record-set {0} remove-record -g {{rg}} --zone-name {{zone}} --record-set-name myrs{0} {1}'.format(t, args[t])) + + self.cmd('network dns record-set a show -n myrsa -g {rg} --zone-name {zone}', + checks=self.check('length(arecords)', 1)) + + self.cmd('network dns record-set a remove-record -g {rg} --zone-name {zone} --record-set-name myrsa --ipv4-address 10.0.0.11') + + self.cmd('network dns record-set a show -n myrsa -g {rg} --zone-name {zone}', + checks=self.is_empty()) + + self.cmd('network dns record-set a delete -n myrsa -g {rg} --zone-name {zone} -y') + self.cmd('network dns record-set a show -n myrsa -g {rg} --zone-name {zone}') + + self.cmd('network dns zone delete -g {rg} -n {zone} -y', + checks=self.is_empty()) + class DnsParseZoneFiles(unittest.TestCase): def _check_soa(self, zone, zone_name, ttl, serial_number, refresh, retry, expire, min_ttl): diff --git a/src/command_modules/azure-cli-network/setup.py b/src/command_modules/azure-cli-network/setup.py index 73a56c92f8d..47077887664 100644 --- a/src/command_modules/azure-cli-network/setup.py +++ b/src/command_modules/azure-cli-network/setup.py @@ -14,7 +14,7 @@ logger.warn("Wheel is not available, disabling bdist_wheel hook") cmdclass = {} -VERSION = "2.0.25" +VERSION = "2.0.26" CLASSIFIERS = [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers',