Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding CLI extension for Private DNS Public Preview #100

Merged
merged 12 commits into from
Mar 15, 2018
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'))
Copy link
Member

Choose a reason for hiding this comment

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

There is no description for --tags in az network dns zone create

Copy link
Member

Choose a reason for hiding this comment

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

Same for az network dns zone update

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