Skip to content

Commit

Permalink
Adding CLI extension for Private DNS Public Preview (#100)
Browse files Browse the repository at this point in the history
* Adding CLI extension for Private DNS Public Preview.

* Running test_static.sh

* Adding dependency on msrestazure

* Adding a pylint ignore for import-error

* Fixing more pylint errors

* Recording tests and uploading wheel package to blob storage.

* Adding API version when creating DnsManagementClient

* Re-recording tests.

* Correcting sha256Digest

* Re-recording test with latest master

* Adding summary for tags.
  • Loading branch information
muwaqar authored and derekbekoe committed Mar 15, 2018
1 parent 6014725 commit 60bcba6
Show file tree
Hide file tree
Showing 42 changed files with 7,939 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@

/src/alias/ @chewong @troydai

/src/managementpartner/ @jeffrey-ace
/src/managementpartner/ @jeffrey-ace

/src/dns/ @muwaqar
30 changes: 30 additions & 0 deletions src/dns/azext_dns/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azure.cli.core import AzCommandsLoader
from azure.cli.core.profiles import ResourceType
from ._help import helps # pylint: disable=unused-import


class DnsCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
dns_custom = CliCommandType(operations_tmpl='azext_dns.custom#{}')
super(DnsCommandsLoader, self).__init__(cli_ctx=cli_ctx,
resource_type=ResourceType.MGMT_NETWORK,
custom_command_type=dns_custom)

def load_command_table(self, args):
from .commands import load_command_table
load_command_table(self, args)
return self.command_table

def load_arguments(self, command):
from ._params import load_arguments
load_arguments(self, command)


COMMAND_LOADER_CLS = DnsCommandsLoader
10 changes: 10 additions & 0 deletions src/dns/azext_dns/_client_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------


def cf_dns_mgmt_zones(cli_ctx, _):
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from azext_dns.dns.dns_management_client import DnsManagementClient
return get_mgmt_service_client(cli_ctx, DnsManagementClient).zones
52 changes: 52 additions & 0 deletions src/dns/azext_dns/_help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from knack.help_files import helps

# pylint: disable=line-too-long, too-many-lines

helps['network dns'] = """
type: group
short-summary: Manage DNS domains in Azure.
"""

helps['network dns zone'] = """
type: group
short-summary: Manage DNS zones.
"""

helps['network dns zone create'] = """
type: command
short-summary: Create a DNS zone.
parameters:
- name: --if-none-match
short-summary: Only create a DNS zone if one doesn't exist that matches the given name.
- name: --tags
short-summary: Resource tags for the DNS zone.
- name: --zone-type
short-summary: Type of the zone to be created. Valid values are 'Public' and 'Private'.
- name: --registration-vnets
short-summary: Space-separated names or IDs of virtual networks that register hostnames in this DNS zone. Only applies to 'Private' zones.
- name: --resolution-vnets
short-summary: Space-separated names or IDs of virtual networks that resolve records in this DNS zone. Only applies to 'Private' zones.
examples:
- name: Create a DNS zone using a fully qualified domain name.
text: >
az network dns zone create -g MyResourceGroup -n www.mysite.com
"""

helps['network dns zone update'] = """
type: command
short-summary: Update a DNS zone's properties. Does not modify DNS records within the zone.
parameters:
- name: --if-match
short-summary: Update only if the resource with the same ETAG exists.
- name: --tags
short-summary: Resource tags for the DNS zone.
- name: --registration-vnets
short-summary: Space-separated names or IDs of virtual networks that register hostnames in this DNS zone. Only applies to 'Private' zones.
- name: --resolution-vnets
short-summary: Space-separated names or IDs of virtual networks that resolve records in this DNS zone. Only applies to 'Private' zones.
"""
28 changes: 28 additions & 0 deletions src/dns/azext_dns/_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

# pylint: disable=line-too-long
from azure.cli.core.commands.parameters import get_enum_type
from azext_dns.dns.models import ZoneType
from azext_dns._validators import (dns_zone_name_type, get_vnet_validator, validate_metadata)
from knack.arguments import CLIArgumentType


def load_arguments(self, _):
name_arg_type = CLIArgumentType(options_list=('--name', '-n'), metavar='NAME')

with self.argument_context('network dns') as c:
c.argument('record_set_name', name_arg_type, help='The name of the record set, relative to the name of the zone.')
c.argument('relative_record_set_name', name_arg_type, help='The name of the record set, relative to the name of the zone.')
c.argument('zone_name', options_list=('--zone-name', '-z'), help='The name of the zone.', type=dns_zone_name_type)
c.argument('metadata', nargs='+', help='Metadata in space-separated key=value pairs. This overwrites any existing metadata.', validator=validate_metadata)

with self.argument_context('network dns zone') as c:
c.argument('zone_name', name_arg_type)
c.ignore('location')

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'))
45 changes: 45 additions & 0 deletions src/dns/azext_dns/_validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azure.cli.core.commands.client_factory import get_subscription_id


# pylint: disable=inconsistent-return-statements
def dns_zone_name_type(value):
if value:
return value[:-1] if value[-1] == '.' else value


def validate_metadata(namespace):
if namespace.metadata:
namespace.metadata = dict(x.split('=', 1) for x in namespace.metadata)


def get_vnet_validator(dest):
from msrestazure.tools import is_valid_resource_id, resource_id # pylint:disable=import-error

def _validate_vnet_name_or_id(cmd, namespace):
SubResource = cmd.get_models('SubResource')
subscription_id = get_subscription_id(cmd.cli_ctx)

resource_group = namespace.resource_group_name
names_or_ids = getattr(namespace, dest)
ids = []

if names_or_ids == [""] or not names_or_ids:
return

for val in names_or_ids:
if not is_valid_resource_id(val):
val = resource_id(
subscription=subscription_id,
resource_group=resource_group,
namespace='Microsoft.Network', type='virtualNetworks',
name=val
)
ids.append(SubResource(id=val))
setattr(namespace, dest, ids)

return _validate_vnet_name_or_id
19 changes: 19 additions & 0 deletions src/dns/azext_dns/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azure.cli.core.commands import CliCommandType
from azext_dns._client_factory import (cf_dns_mgmt_zones)


def load_command_table(self, _):

network_dns_zone_sdk = CliCommandType(
operations_tmpl='azext_dns.dns.operations.zones_operations#ZonesOperations.{}',
client_factory=cf_dns_mgmt_zones
)

with self.command_group('network dns zone', network_dns_zone_sdk) as g:
g.custom_command('create', 'create_dns_zone', client_factory=cf_dns_mgmt_zones)
g.generic_update_command('update', custom_func_name='update_dns_zone')
43 changes: 43 additions & 0 deletions src/dns/azext_dns/custom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from __future__ import print_function
from knack.log import get_logger
from azext_dns.dns.models import (Zone)

logger = get_logger(__name__)


def create_dns_zone(client, resource_group_name, zone_name, location='global', tags=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'):
zone.zone_type = zone_type
zone.registration_virtual_networks = registration_vnets
zone.resolution_virtual_networks = resolution_vnets

return client.create_or_update(resource_group_name, zone_name, zone, if_none_match='*' if if_none_match else None)


def update_dns_zone(instance, tags=None, zone_type=None, resolution_vnets=None, registration_vnets=None):

if tags is not None:
instance.tags = tags

if zone_type:
instance.zone_type = zone_type

if resolution_vnets == ['']:
instance.resolution_virtual_networks = None
elif resolution_vnets:
instance.resolution_virtual_networks = resolution_vnets

if registration_vnets == ['']:
instance.registration_virtual_networks = None
elif registration_vnets:
instance.registration_virtual_networks = registration_vnets

return instance
17 changes: 17 additions & 0 deletions src/dns/azext_dns/dns/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
#
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from .dns_management_client import DnsManagementClient
from .version import VERSION

__all__ = ['DnsManagementClient']

__version__ = VERSION
88 changes: 88 additions & 0 deletions src/dns/azext_dns/dns/dns_management_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
#
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from msrest.service_client import ServiceClient
from msrest import Serializer, Deserializer
from msrestazure import AzureConfiguration
from .version import VERSION
from .operations.record_sets_operations import RecordSetsOperations
from .operations.zones_operations import ZonesOperations
from . import models


class DnsManagementClientConfiguration(AzureConfiguration):
"""Configuration for DnsManagementClient
Note that all parameters used to create this instance are saved as instance
attributes.
:param credentials: Credentials needed for the client to connect to Azure.
:type credentials: :mod:`A msrestazure Credentials
object<msrestazure.azure_active_directory>`
:param subscription_id: Specifies the Azure subscription ID, which
uniquely identifies the Microsoft Azure subscription.
:type subscription_id: str
:param str base_url: Service URL
"""

def __init__(
self, credentials, subscription_id, base_url=None):

if credentials is None:
raise ValueError("Parameter 'credentials' must not be None.")
if subscription_id is None:
raise ValueError("Parameter 'subscription_id' must not be None.")
if not base_url:
base_url = 'https://management.azure.com'

super(DnsManagementClientConfiguration, self).__init__(base_url)

self.add_user_agent('azure-mgmt-dns/{}'.format(VERSION))
self.add_user_agent('Azure-SDK-For-Python')

self.credentials = credentials
self.subscription_id = subscription_id


class DnsManagementClient(object):
"""The DNS Management Client.
:ivar config: Configuration for client.
:vartype config: DnsManagementClientConfiguration
:ivar record_sets: RecordSets operations
:vartype record_sets: azure.mgmt.dns.operations.RecordSetsOperations
:ivar zones: Zones operations
:vartype zones: azure.mgmt.dns.operations.ZonesOperations
:param credentials: Credentials needed for the client to connect to Azure.
:type credentials: :mod:`A msrestazure Credentials
object<msrestazure.azure_active_directory>`
:param subscription_id: Specifies the Azure subscription ID, which
uniquely identifies the Microsoft Azure subscription.
:type subscription_id: str
:param str base_url: Service URL
"""

def __init__(
self, credentials, subscription_id, base_url=None):

self.config = DnsManagementClientConfiguration(credentials, subscription_id, base_url)
self._client = ServiceClient(self.config.credentials, self.config)

client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
self.api_version = '2018-03-01-preview'
self._serialize = Serializer(client_models)
self._deserialize = Deserializer(client_models)

self.record_sets = RecordSetsOperations(
self._client, self.config, self._serialize, self._deserialize)
self.zones = ZonesOperations(
self._client, self.config, self._serialize, self._deserialize)
Loading

0 comments on commit 60bcba6

Please sign in to comment.