File: //snap/google-cloud-cli/394/lib/surface/dns/managed_zones/create.py
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""gcloud dns managed-zone create command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.dns import util
from googlecloudsdk.api_lib.util import apis
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.dns import flags
from googlecloudsdk.command_lib.dns import util as command_util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def _AddArgsCommon(parser, messages, api_version='v1'):
"""Adds the common arguments for all versions."""
flags.GetDnsZoneArg(
'The name of the managed-zone to be created.'
).AddToParser(parser)
flags.GetManagedZonesDnsNameArg().AddToParser(parser)
flags.GetManagedZonesDescriptionArg().AddToParser(parser)
flags.AddCommonManagedZonesDnssecArgs(parser, messages, api_version)
labels_util.AddCreateLabelsFlags(parser)
flags.GetManagedZoneNetworksArg().AddToParser(parser)
flags.GetManagedZoneVisibilityArg().AddToParser(parser)
flags.GetForwardingTargetsArg().AddToParser(parser)
flags.GetDnsPeeringArgs().AddToParser(parser)
flags.GetPrivateForwardingTargetsArg().AddToParser(parser)
flags.GetReverseLookupArg().AddToParser(parser)
flags.GetServiceDirectoryArg().AddToParser(parser)
flags.GetManagedZoneLoggingArg().AddToParser(parser)
flags.GetManagedZoneGkeClustersArg().AddToParser(parser)
flags.GetLocationArg().AddToParser(parser)
def _MakeDnssecConfig(args, messages, api_version='v1'):
"""Parse user-specified args into a DnssecConfig message."""
dnssec_config = None
if args.dnssec_state is not None:
dnssec_config = command_util.ParseDnssecConfigArgs(
args, messages, api_version
)
else:
bad_args = [
'denial_of_existence',
'ksk_algorithm',
'zsk_algorithm',
'ksk_key_length',
'zsk_key_length',
]
for bad_arg in bad_args:
if getattr(args, bad_arg, None) is not None:
raise exceptions.InvalidArgumentException(
bad_arg,
'DNSSEC must be enabled in order to use other DNSSEC arguments. '
'Please set --dnssec-state to "on" or "transfer".',
)
return dnssec_config
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
@base.UniverseCompatible
class Create(base.CreateCommand):
r"""Create a Cloud DNS managed-zone.
This command creates a Cloud DNS managed-zone.
## EXAMPLES
To create a managed-zone, run:
$ {command} my-zone --dns-name=my.zone.com. --description="My zone!"
To create a managed-zone with DNSSEC, run:
$ {command} my-zone-2 --description="Signed Zone"
--dns-name=myzone.example
--dnssec-state=on
To create a zonal managed-zone scoped to a GKE Cluster in us-east1-a, run:
$ {command} my-zonal-zone --description="Signed Zone"
--dns-name=cluster.local
--visibility=private
--gkeclusters=cluster1
--location=us-east1-a
"""
@classmethod
def _BetaOrAlpha(cls):
return cls.ReleaseTrack() in (
base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA,
)
@classmethod
def Args(cls, parser):
api_version = util.GetApiFromTrack(cls.ReleaseTrack())
messages = apis.GetMessagesModule('dns', api_version)
_AddArgsCommon(parser, messages, api_version=api_version)
parser.display_info.AddCacheUpdater(flags.ManagedZoneCompleter)
def Run(self, args):
# We explicitly want to allow --networks='' as a valid option and we need
# to differentiate between that option and not passing --networks at all.
if args.visibility == 'public':
if args.IsSpecified('networks'):
raise exceptions.InvalidArgumentException(
'--networks',
'If --visibility is set to public (default), setting networks is '
'not allowed.',
)
# We explicitly want to allow --gkeclusters='' as an optional flag.
elif args.IsSpecified('gkeclusters'):
raise exceptions.InvalidArgumentException(
'--gkeclusters',
'If --visibility is set to public (default), setting gkeclusters is'
' not allowed.',
)
if (
args.visibility == 'private'
and args.networks is None
and args.gkeclusters is None
):
raise exceptions.RequiredArgumentException(
'--networks, --gkeclusters',
("""If --visibility is set to private, a list of networks or list of
GKE clusters must be provided.'
NOTE: You can provide an empty value ("") for private zones that
have NO network or GKE clusters binding.
"""),
)
api_version = util.GetApiFromTrackAndArgs(self.ReleaseTrack(), args)
dns = util.GetApiClient(api_version)
messages = apis.GetMessagesModule('dns', api_version)
registry = util.GetRegistry(api_version)
zone_ref = registry.Parse(
args.dns_zone,
util.GetParamsForRegistry(api_version, args),
collection='dns.managedZones',
)
visibility_flag = args.visibility
private_enum = None
if api_version == 'v2':
# v2 doesn't set lower_camel_enums, so enums are in upper case
private_enum = messages.ManagedZone.VisibilityValueValuesEnum.PRIVATE
visibility_flag = args.visibility.upper()
else:
private_enum = messages.ManagedZone.VisibilityValueValuesEnum.private
visibility = messages.ManagedZone.VisibilityValueValuesEnum(visibility_flag)
visibility_config = None
if visibility == private_enum:
# Handle explicitly empty networks case (--networks='')
networks = (
args.networks if args.networks and args.networks != [''] else []
)
def GetNetworkSelfLink(network):
return registry.Parse(
network,
collection='compute.networks',
params={'project': zone_ref.project},
).SelfLink()
network_urls = [GetNetworkSelfLink(n) for n in networks]
network_configs = [
messages.ManagedZonePrivateVisibilityConfigNetwork(networkUrl=nurl)
for nurl in network_urls
]
# Handle the case when '--gkeclusters' is not specified.
gkeclusters = args.gkeclusters or []
gkecluster_configs = [
messages.ManagedZonePrivateVisibilityConfigGKECluster(
gkeClusterName=name
)
for name in gkeclusters
]
visibility_config = messages.ManagedZonePrivateVisibilityConfig(
networks=network_configs, gkeClusters=gkecluster_configs
)
forwarding_config = None
if args.forwarding_targets or args.private_forwarding_targets:
forwarding_config = (
command_util.ParseManagedZoneForwardingConfigWithForwardingPath(
messages=messages,
server_list=args.forwarding_targets,
private_server_list=args.private_forwarding_targets,
)
)
dnssec_config = _MakeDnssecConfig(args, messages, api_version)
labels = labels_util.ParseCreateArgs(args, messages.ManagedZone.LabelsValue)
peering_config = None
if args.target_project and args.target_network:
peering_network = (
f'https://www.{properties.VALUES.core.universe_domain.Get()}/compute/v1/projects'
'/{}/global/networks/{}'.format(
args.target_project, args.target_network
)
)
peering_config = messages.ManagedZonePeeringConfig()
peering_config.targetNetwork = (
messages.ManagedZonePeeringConfigTargetNetwork(
networkUrl=peering_network
)
)
reverse_lookup_config = None
if (
args.IsSpecified('managed_reverse_lookup')
and args.managed_reverse_lookup
):
reverse_lookup_config = messages.ManagedZoneReverseLookupConfig()
service_directory_config = None
if (
args.IsSpecified('service_directory_namespace')
and args.service_directory_namespace
):
service_directory_config = messages.ManagedZoneServiceDirectoryConfig(
namespace=messages.ManagedZoneServiceDirectoryConfigNamespace(
namespaceUrl=args.service_directory_namespace
)
)
cloud_logging_config = None
if args.IsSpecified('log_dns_queries'):
cloud_logging_config = messages.ManagedZoneCloudLoggingConfig()
cloud_logging_config.enableLogging = args.log_dns_queries
zone = messages.ManagedZone(
name=zone_ref.managedZone,
dnsName=util.AppendTrailingDot(args.dns_name),
description=args.description,
dnssecConfig=dnssec_config,
labels=labels,
visibility=visibility,
forwardingConfig=forwarding_config,
privateVisibilityConfig=visibility_config,
peeringConfig=peering_config,
reverseLookupConfig=reverse_lookup_config,
serviceDirectoryConfig=service_directory_config,
cloudLoggingConfig=cloud_logging_config,
)
request = messages.DnsManagedZonesCreateRequest(
managedZone=zone, project=zone_ref.project
)
if api_version == 'v2':
# For a request with location, use v2 api.
request.location = args.location
result = dns.managedZones.Create(request)
log.CreatedResource(zone_ref)
return [result]