feat: Add new gcloud commands, API clients, and third-party libraries across various services.

This commit is contained in:
2026-01-01 20:26:35 +01:00
parent 5e23cbece0
commit a19e592eb7
25221 changed files with 8324611 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 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.
"""The gcloud domains group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DomainsAlpha(base.Group):
"""Manage domains for your Google Cloud projects."""
category = base.NETWORKING_CATEGORY
@base.ReleaseTracks(base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class Domains(base.Group):
"""Base class for gcloud domains command group."""
category = base.NETWORKING_CATEGORY
detailed_help = {
'brief': 'Manage domains for your Google Cloud projects.',
'DESCRIPTION': """
The gcloud domains command group lets you view and manage your
custom domains for use across Google projects.
""",
'EXAMPLES': """\
To verify a domain you own, run:
$ {command} verify example.com
To list your verified domains, run:
$ {command} list-user-verified
"""
}
def Filter(self, context, args):
del context, args
base.DisableUserProjectQuota()

View File

@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 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.
"""The `domains list-user-verified` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.app.api import appengine_domains_api_client as api_client
from googlecloudsdk.api_lib.run import global_methods as run_methods
from googlecloudsdk.calliope import base
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class ListUserVerified(base.Command):
"""Lists the user's verified domains."""
detailed_help = {
'DESCRIPTION':
'{description}',
'EXAMPLES':
"""\
To list domains that have been verified by the current user, run:
$ {command}
Use the {parent_command} verify command to verify additional
domains.
""",
}
@staticmethod
def Args(parser):
parser.display_info.AddFormat('table(id:sort=1)')
def Run(self, args):
try:
project = properties.VALUES.core.project.Get()
client = api_client.GetApiClientForTrack(self.ReleaseTrack())
return client.ListVerifiedDomains()
# Note: the domain user-verified listing API is availible through two
# routes, one App Engine and one Cloud Run. The command should work if the
# user has *either* API activated. The following falls back to Cloud Run
# if the user does not have App Engine activated.
except (apitools_exceptions.HttpNotFoundError,
apitools_exceptions.HttpForbiddenError) as appengine_err:
try:
run_client = run_methods.GetServerlessClientInstance()
return run_methods.ListVerifiedDomains(run_client)
except (apitools_exceptions.HttpNotFoundError,
apitools_exceptions.HttpForbiddenError):
log.error('To list user-verified domains, you must activate either'
' the App Engine or Cloud Run API and have read permissions '
'on one of them.')
log.error('To activate App Engine, visit:')
log.error('https://console.cloud.google.com/apis/api/'
'appengine.googleapis.com/overview?project={}'.format(
project))
log.error('To activate Cloud Run, visit:')
log.error('https://console.cloud.google.com/apis/api/'
'run.googleapis.com/overview?project={}'.format(project))
raise appengine_err

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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.
"""The registrations command group for the Cloud Domains."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Registrations(base.Group):
"""Manage Cloud Domains registrations.
Commands for managing Cloud Domains registrations.
"""

View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations authorization-code command group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class DomainRegistrationAuthorizationCode(base.Group):
"""Manage Cloud Domains registration's authorization code.
Commands for managing Cloud Domains registration's authorization code.
"""
pass

View File

@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations authorization-code get` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
@base.DefaultUniverseOnly
class GetAuthorizationCode(base.DescribeCommand):
"""Get authorization code of a specific Cloud Domains registration.
Get authorization code of a specific registration.
You can call this API only after 60 days have elapsed since initial
registration.
## EXAMPLES
To get authorization code of ``example.com'', run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser,
'to get authorization code for')
def Run(self, args):
"""Run get authorization code command."""
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
registration = client.Get(registration_ref)
util.AssertRegistrationOperational(api_version, registration)
return client.RetrieveAuthorizationCode(registration_ref)

View File

@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations authorization-code reset` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
@base.DefaultUniverseOnly
class ResetAuthorizationCode(base.DescribeCommand):
"""Resets authorization code of a specific Cloud Domains registration.
Resets authorization code of a specific registration.
You can call this API only after 60 days have elapsed since initial
registration.
## EXAMPLES
To reset authorization code of ``example.com'', run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser,
'to reset authorization code for')
def Run(self, args):
"""Run reset authorization code command."""
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
registration = client.Get(registration_ref)
util.AssertRegistrationOperational(api_version, registration)
return client.ResetAuthorizationCode(registration_ref)

View File

@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations configure command group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class DomainRegistrationAuthorizationCode(base.Group):
"""Configure Cloud Domains registrations' management, DNS or contact settings.
Commands for configuring Cloud Domains registrations' management, DNS or
contact settings.
"""
pass

View File

@@ -0,0 +1,149 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations configure contacts` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import contacts_util
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
class ConfigureContacts(base.UpdateCommand):
"""Configure contact settings of a Cloud Domains registration.
Configure registration's contact settings: email, phone number, postal
address and also contact privacy.
In some cases such changes have to be confirmed through an email sent to
the registrant before they take effect. In order to resend the email, execute
this command again.
NOTE: Please consider carefully any changes to contact privacy settings when
changing from "redacted-contact-data" to "public-contact-data."
There may be a delay in reflecting updates you make to registrant
contact information such that any changes you make to contact privacy
(including from "redacted-contact-data" to "public-contact-data")
will be applied without delay but changes to registrant contact
information may take a limited time to be publicized. This means that
changes to contact privacy from "redacted-contact-data" to
"public-contact-data" may make the previous registrant contact
data public until the modified registrant contact details are published.
## EXAMPLES
To start an interactive flow to configure contact settings for
``example.com'', run:
$ {command} example.com
To enable contact privacy for ``example.com'', run:
$ {command} example.com --contact-privacy=private-contact-data
To change contact data for ``example.com'' according to information from a
YAML file ``contacts.yaml'', run:
$ {command} example.com --contact-data-from-file=contacts.yaml
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(
parser, 'to configure contact settings for')
flags.AddConfigureContactsSettingsFlagsToParser(parser)
flags.AddValidateOnlyFlagToParser(parser,
'configure contact settings of the')
flags.AddAsyncFlagToParser(parser)
def CheckPendingContacts(self, client, registration_ref):
registration = client.Get(registration_ref)
return bool(registration.pendingContactSettings)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
registration = client.Get(registration_ref)
util.AssertRegistrationOperational(api_version, registration)
contacts = contacts_util.ParseContactData(api_version,
args.contact_data_from_file)
contact_privacy = contacts_util.ParseContactPrivacy(api_version,
args.contact_privacy)
public_contacts_ack = contacts_util.ParsePublicContactsAck(
api_version, args.notices)
if contacts is None:
contacts = contacts_util.PromptForContacts(api_version,
registration.contactSettings)
if contact_privacy is None:
choices = list(
map(
flags.ContactPrivacyEnumMapper(client.messages).GetChoiceForEnum,
registration.supportedPrivacy))
contact_privacy = contacts_util.PromptForContactPrivacy(
api_version, choices, registration.contactSettings.privacy)
if contacts is None and contact_privacy is None:
# Nothing to update.
return None
new_privacy = contact_privacy or registration.contactSettings.privacy
privacy = client.messages.ContactSettings.PrivacyValueValuesEnum
if not public_contacts_ack and new_privacy == privacy.PUBLIC_CONTACT_DATA:
merged_contacts = contacts_util.MergeContacts(
api_version,
prev_contacts=registration.contactSettings,
new_contacts=contacts)
if registration.contactSettings.privacy != privacy.PUBLIC_CONTACT_DATA:
public_contacts_ack = contacts_util.PromptForPublicContactsUpdateAck(
registration.domainName, merged_contacts)
else:
public_contacts_ack = contacts_util.PromptForPublicContactsAck(
registration.domainName, merged_contacts)
response = client.ConfigureContacts(
registration_ref,
contacts,
contact_privacy,
public_contacts_ack,
validate_only=args.validate_only)
if args.validate_only:
log.status.Print('The command will not have any effect because '
'validate-only flag is present.')
else:
response = util.WaitForOperation(api_version, response, args.async_)
note = None
if not args.async_ and self.CheckPendingContacts(client,
registration_ref):
note = ('Note:\nThe contact settings are currently pending.\nIn order '
'to finalize the update you need to confirm the change.\nAn '
'email with instructions has been sent to the registrant.')
log.UpdatedResource(
registration_ref.Name(), 'registration', args.async_, details=note)
return response

View File

@@ -0,0 +1,155 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations configure dns` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import dns_util
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
class ConfigureDNS(base.UpdateCommand):
"""Configure DNS settings of a Cloud Domains registration.
Configure DNS settings of a Cloud Domains registration.
In most cases, this command is used for changing the authoritative name
servers and DNSSEC options for the given domain. However, advanced options
like glue records are available.
## EXAMPLES
To start an interactive flow to configure DNS settings for ``example.com'',
run:
$ {command} example.com
To use Cloud DNS managed-zone ``example-zone'' for ``example.com'', run:
$ {command} example.com --cloud-dns-zone=example-zone
DNSSEC will not be enabled as it may not be safe to enable it (e.g. when the
Cloud DNS managed-zone was signed less than 24h ago).
To use a signed Cloud DNS managed-zone ``example-zone'' for ``example.com''
and enable DNSSEC, run:
$ {command} example.com --cloud-dns-zone=example-zone --no-disable-dnssec
To change DNS settings for ``example.com'' according to information from a
YAML file ``dns_settings.yaml'', run:
$ {command} example.com --dns-settings-from-file=dns_settings.yaml
To disable DNSSEC, run:
$ {command} example.com --disable-dnssec
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser,
'to configure DNS settings for')
flags.AddConfigureDNSSettingsFlagsToParser(parser)
flags.AddValidateOnlyFlagToParser(parser, 'configure DNS settings of the')
flags.AddAsyncFlagToParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
dnssec_flag_provided = args.IsSpecified('disable_dnssec')
if dnssec_flag_provided and args.dns_settings_from_file:
raise exceptions.Error(
'argument --disable-dnssec: At most one of '
'--dns-settings-from-file | --disable-dnssec can be specified.')
registration = client.Get(registration_ref)
util.AssertRegistrationOperational(api_version, registration)
dnssec_update = dns_util.DNSSECUpdate.NO_CHANGE
if dnssec_flag_provided and args.disable_dnssec:
dnssec_update = dns_util.DNSSECUpdate.DISABLE
elif dnssec_flag_provided and not args.disable_dnssec:
dnssec_update = dns_util.DNSSECUpdate.ENABLE
dns_settings, update_mask = dns_util.ParseDNSSettings(
api_version,
args.name_servers,
args.cloud_dns_zone,
args.use_google_domains_dns,
args.dns_settings_from_file,
registration_ref.registrationsId,
dnssec_update=dnssec_update,
dns_settings=registration.dnsSettings,
)
if dns_settings is None:
dns_settings, update_mask = dns_util.PromptForNameServers(
api_version,
registration_ref.registrationsId,
dnssec_update=dnssec_update,
dns_settings=registration.dnsSettings,
)
if dns_settings is None:
return None
if registration.dnsSettings.glueRecords and not update_mask.glue_records:
# It's ok to leave Glue records while changing name servers.
log.status.Print(
'Glue records will not be cleared. If you want to clear '
'them, use --dns-settings-from-file flag.'
)
ds_records_present = dns_util.DnssecEnabled(registration.dnsSettings)
new_ds_records = dns_util.DnssecEnabled(dns_settings)
name_servers_changed = (
update_mask.name_servers
and not dns_util.NameServersEquivalent(
registration.dnsSettings, dns_settings
)
)
if (ds_records_present or new_ds_records) and name_servers_changed:
log.warning('Name servers should not be changed if DS '
'records are present or added. Disable DNSSEC first and wait '
'24 hours before you change name servers. Otherwise '
'your domain may stop serving.')
if not args.unsafe_dns_update:
dns_util.PromptForUnsafeDnsUpdate()
response = client.ConfigureDNS(
registration_ref,
dns_settings,
update_mask,
validate_only=args.validate_only)
if args.validate_only:
log.status.Print('The command will not have any effect because '
'validate-only flag is present.')
else:
response = util.WaitForOperation(api_version, response, args.async_)
log.UpdatedResource(registration_ref.Name(), 'registration', args.async_)
return response

View File

@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations configure management` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
class ConfigureManagement(base.UpdateCommand):
"""Configure management settings of a Cloud Domains registration.
Configure management settings of a registration. This includes settings
related to transfers, billing and renewals of a registration.
## EXAMPLES
To start an interactive flow to configure management settings for
``example.com'', run:
$ {command} example.com
To unlock a transfer lock of a registration for ``example.com'', run:
$ {command} example.com --transfer-lock-state=unlocked
To disable automatic renewals for ``example.com'', run:
$ {command} example.com --preferred-renewal-method=renewal-disabled
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(
parser, 'to configure management settings for')
flags.AddManagementSettingsFlagsToParser(parser)
flags.AddAsyncFlagToParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
registration = client.Get(registration_ref)
util.AssertRegistrationOperational(api_version, registration)
transfer_lock_state = util.ParseTransferLockState(api_version,
args.transfer_lock_state)
renewal_method = util.ParseRenewalMethod(
api_version, args.preferred_renewal_method
)
if transfer_lock_state is None and renewal_method is None:
transfer_lock_state = util.PromptForTransferLockState(
api_version, registration.managementSettings.transferLockState)
renewal_method = util.PromptForRenewalMethod(
api_version, registration.managementSettings.preferredRenewalMethod
)
if transfer_lock_state is None and renewal_method is None:
return None
response = client.ConfigureManagement(
registration_ref, transfer_lock_state, renewal_method
)
response = util.WaitForOperation(api_version, response, args.async_)
log.UpdatedResource(registration_ref.Name(), 'registration', args.async_)
return response

View File

@@ -0,0 +1,69 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations delete` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
class Delete(base.DeleteCommand):
"""Delete a Cloud Domains registration.
Delete a registration resource.
Delete can only be called on registrations in state EXPORTED with expire_time
in the past.
It also works for registrations in state REGISTRATION_FAILED, TRANSFER_FAILED,
and TRANSFER_PENDING.
## EXAMPLES
To delete a registration for ``example.com'', run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser, 'to delete')
flags.AddAsyncFlagToParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
console_io.PromptContinue(
'You are about to delete registration \'{}\''.format(
registration_ref.registrationsId),
throw_if_unattended=True,
cancel_on_no=True)
response = client.Delete(registration_ref)
response = util.WaitForOperation(api_version, response, args.async_)
log.DeletedResource(
registration_ref.Name(), 'registration', is_async=args.async_)
return response

View File

@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations describe` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import registration_printer
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core.resource import resource_printer
from googlecloudsdk.core import log
class Describe(base.DescribeCommand):
"""Describe an existing Cloud Domains registration.
Print information about an existing registration.
## EXAMPLES
To describe a registration for ``example.com'', run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser, 'to describe')
resource_printer.RegisterFormatter(
registration_printer.REGISTRATION_PRINTER_FORMAT,
registration_printer.RegistrationPrinter)
parser.display_info.AddFormat(
registration_printer.REGISTRATION_PRINTER_FORMAT)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration = client.Get(args.CONCEPTS.registration.Parse())
return registration

View File

@@ -0,0 +1,91 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations export` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.Deprecate(
is_removed=True,
warning=(
'This command is deprecated. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
error=(
'This command has been removed. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
)
class Export(base.DeleteCommand):
"""Export a Cloud Domains registration.
Export the domain to direct management by Google Domains. The domain remains
valid until expiry.
After you export a registered domain, the auto-renewal will be disabled, but
you will continue to incur billing charges until the next yearly renewal date.
You will also become the sole owner of the domain in Google Domains, and Cloud
IAM is not used anymore.
To manage your domain after exporting, visit Google Domains at
https://domains.google.com/registrar, or see
https://support.google.com/domains/answer/3251174 for more information.
## EXAMPLES
To export a registration for ``example.com'', run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser, 'to export')
flags.AddAsyncFlagToParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
console_io.PromptContinue(
'You are about to export registration \'{}\''.format(
registration_ref.registrationsId),
throw_if_unattended=True,
cancel_on_no=True)
response = client.Export(registration_ref)
response = util.WaitForOperation(api_version, response, args.async_)
log.ExportResource(
registration_ref.Name(),
'registration',
is_async=args.async_,
details=('Note:\nRegistration remains valid until expiry. Manage it in '
'Google Domains at https://domains.google.com/registrar, or '
'see https://support.google.com/domains/answer/3251174 for '
'more information.'))
return response

View File

@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations get-register-parameters` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
class GetRegisterParameters(base.DescribeCommand):
"""Get register parameters (including availability) of a specific domain.
Get parameters needed to register a new domain, including
price, availability, supported privacy modes and notices.
In contrast to the search-domains command, this command returns up-to-date
domain name availability information.
## EXAMPLES
To check if ``example.com'' is available for registration, run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddLocationResourceArg(parser)
base.Argument(
'domain',
help='Domain to get register parameters for.',
).AddToParser(parser)
def Run(self, args):
"""Run the get register parameters command."""
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
location_ref = args.CONCEPTS.location.Parse()
domain = util.NormalizeDomainName(args.domain)
if domain != args.domain:
log.status.Print(
'Domain name \'{}\' has been normalized to equivalent \'{}\'.'.format(
args.domain, domain))
return client.RetrieveRegisterParameters(location_ref, domain)

View File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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 domains registrations get-transfer-parameters` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import log
@base.Deprecate(
is_removed=True,
warning=(
'This command is deprecated. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
error=(
'This command has been removed. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
)
@base.DefaultUniverseOnly
class GetTransferParameters(base.DescribeCommand):
"""Get transfer parameters of a specific domain.
Get parameters needed to transfer an existing domain from a different
registrar. The parameters include the current registrar, name servers,
transfer lock state, price, and supported privacy modes.
## EXAMPLES
To check if ``example.com'' is available for transfer, run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddLocationResourceArg(parser)
base.Argument(
'domain',
help='Domain to get transfer parameters for.',
).AddToParser(parser)
def Run(self, args):
"""Run the get transfer parameters command."""
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
location_ref = args.CONCEPTS.location.Parse()
domain = util.NormalizeDomainName(args.domain)
if domain != args.domain:
log.status.Print(
'Domain name \'{}\' has been normalized to equivalent \'{}\'.'.format(
args.domain, domain))
return client.RetrieveTransferParameters(location_ref, domain)

View File

@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 domains registrations google-domains-dns` command group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
class RetrieveGoogleDomainsDnsRecords(base.Group):
"""Manage deprecated Google Domains DNS configuration.
Commands for managing DNS records and forwarding configuration of Cloud
Domains registrations that use deprecated Google Domains DNS.
"""
pass

View File

@@ -0,0 +1,127 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 domains registrations google-domains-dns export-dns-record-sets` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.dns import export_util
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import log
from googlecloudsdk.core.util import files
class ResourceRecordSet:
def __init__(self, name, record_type, ttl, rrdatas):
self.name = name
self.type = record_type
self.ttl = ttl
self.rrdatas = rrdatas
@base.DefaultUniverseOnly
class ExportDNSRecordSets(base.Command):
"""Export your registration's Google Domains DNS zone's record-sets into a file.
Export your registration's Google Domains DNS (deprecated) zone's record-sets
into a file.
The formats you can export to are YAML records format (default) and
BIND zone file format.
## EXAMPLES
To export DNS record-sets of ``example.com'' into a YAML file, run:
$ gcloud domains registrations google-domains-dns export-dns-record-sets
example.com --records-file=records.yaml
To export DNS record-sets of ``example.com'' into a BIND zone formatted file,
run:
$ gcloud domains registrations google-domains-dns export-dns-record-sets
example.com --records-file=records.zonefile --zone-file-format
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(
parser, 'to get the DNS records for'
)
parser.add_argument(
'--records-file',
required=True,
help='File to which record-sets should be exported.',
)
parser.add_argument(
'--zone-file-format',
required=False,
action='store_true',
help=(
'Indicates that records-file should be in the zone file format. '
'When using this flag, expect the record-set '
'to be exported to a BIND zone formatted file. If you omit this '
'flag, the record-set is exported into a YAML formatted records '
'file. Note, this format flag determines the format of the '
'output recorded in the records-file; it is different from the '
'global `--format` flag which affects console output alone.'
),
)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
# Get all the record-sets.
record_sets = []
page_token = ''
while True:
resp = client.RetrieveGoogleDomainsDnsRecords(
registration_ref, page_token=page_token, page_size=0
)
rrset = resp.rrset
if rrset is not None:
for rr in rrset:
record_sets.append(
ResourceRecordSet(rr.name, rr.type, rr.ttl, rr.rrdata)
)
page_token = resp.nextPageToken
if not page_token:
break
# Export the record-sets.
try:
with files.FileWriter(args.records_file) as export_file:
if args.zone_file_format:
export_util.WriteToZoneFile(
export_file,
record_sets,
registration_ref.registrationsId, # domain name
)
else:
export_util.WriteToYamlFile(export_file, record_sets)
except Exception as exp:
msg = 'Unable to export record-sets to file [{0}]: {1}'.format(
args.records_file, exp
)
raise export_util.UnableToExportRecordsToFile(msg)
log.status.Print('Exported record-sets to [{0}].'.format(args.records_file))

View File

@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 domains registrations google-domains-dns get-forwarding-config` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
@base.DefaultUniverseOnly
class GetForwardingConfig(base.DescribeCommand):
"""Get forwarding configuration of a specific Cloud Domains registration.
Get forwarding configuration (deprecated) of a specific registration.
## EXAMPLES
To get forwarding configuration of ``example.com'', run:
$ gcloud domains registrations google-domains-dns get-forwarding-config
example.com
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(
parser, 'to get the forwarding config for'
)
def Run(self, args):
"""Run get forwarding config command."""
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
registration = client.Get(registration_ref)
util.AssertRegistrationOperational(api_version, registration)
return client.RetrieveGoogleDomainsForwardingConfig(registration_ref)

View File

@@ -0,0 +1,102 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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 domains registrations import` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.Deprecate(
is_removed=True,
warning=(
'This command is deprecated. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
error=(
'This command has been removed. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
)
@base.DefaultUniverseOnly
class Import(base.CreateCommand):
# pylint: disable=line-too-long
"""Import a domain from Google Domains registrar to Cloud Domains.
Create a new Cloud Domains registration resource by importing an existing
domain from Google Domains registrar.
The new resource's ID will be equal to the domain name.
After this command executes, a resource is created with state ACTIVE,
indicating that the import was successful. Cloud Domains will automatically
renew your domain as long as your Cloud Billing account is active. If this
command fails, no resource is created.
Other users may lose access to the domain and will need IAM permissions on the
Cloud project containing the registration resource to regain access.
## EXAMPLES
To import ``example.com'', run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(
parser, noun='The domain name', verb='to import')
labels_util.AddCreateLabelsFlags(parser)
flags.AddAsyncFlagToParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
client.PrintSQSPAck()
normalized = util.NormalizeResourceName(args.registration)
if normalized != args.registration:
console_io.PromptContinue(
u'Domain name \'{}\' has been normalized to equivalent \'{}\'.'.format(
args.registration, normalized),
throw_if_unattended=False,
cancel_on_no=True,
default=True)
args.registration = normalized
registration_ref = args.CONCEPTS.registration.Parse()
location_ref = registration_ref.Parent()
labels = labels_util.ParseCreateArgs(
args, client.messages.ImportDomainRequest.LabelsValue)
response = client.Import(
location_ref, registration_ref.registrationsId, labels=labels)
response = util.WaitForOperation(api_version, response, args.async_)
log.CreatedResource(
registration_ref.Name(),
'registration',
args.async_)
return response

View File

@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 domains registrations initiate-push-transfer` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.DefaultUniverseOnly
class InitiatePushTransfer(base.UpdateCommand):
"""Initiates the push transfer process.
Initiates the `Push Transfer` process to transfer the domain to another
registrar. The process might complete instantly or might require confirmation
or additional work. Check the emails sent to the email address of the
registrant. The process is aborted after a timeout if it's not completed.
This method is only supported for domains that have the
`REQUIRE_PUSH_TRANSFER` property in the list of `domain_properties`. The
domain must also be unlocked before it can be transferred to a different
registrar.
## EXAMPLES
To initiate a push transfer for ``example.co.uk'', run:
$ {command} example.co.uk --tag=NEW_REGISTRY_TAG
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser, 'to transfer')
flags.AddTagFlagToParser(parser)
flags.AddAsyncFlagToParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
console_io.PromptContinue(
('You are about to start the push transfer process of '
'registration \'{}\'').format(
registration_ref.registrationsId),
throw_if_unattended=True,
cancel_on_no=True)
response = client.InitiatePushTransfer(registration_ref, args.tag)
response = util.WaitForOperation(api_version, response, args.async_)
log.UpdatedResource(registration_ref.Name(), 'registration', args.async_)
return response

View File

@@ -0,0 +1,106 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations list` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
_FORMAT = """\
table(
name.scope("registrations"):label=DOMAIN,
state:label=STATE,
managementSettings.renewalMethod:label=RENEWAL_METHOD,
expireTime:label=EXPIRE_TIME
)
"""
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@base.DefaultUniverseOnly
class List(base.ListCommand):
"""List Cloud Domains registrations.
List Cloud Domains registrations in the project.
## EXAMPLES
To list all registrations in the project, run:
$ {command}
"""
@staticmethod
def ArgsPerVersion(api_version, parser):
resource_args.AddLocationResourceArg(parser, 'to list registrations for')
parser.display_info.AddFormat(_FORMAT)
parser.display_info.AddUriFunc(util.RegistrationsUriFunc(api_version))
@staticmethod
def Args(parser):
List.ArgsPerVersion(registrations.BETA_API_VERSION, parser)
def Run(self, args):
"""Run the list command."""
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
location_ref = args.CONCEPTS.location.Parse()
return client.List(location_ref, args.limit, args.page_size)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@base.DefaultUniverseOnly
class ListAlpha(List):
"""List Cloud Domains registrations.
List Cloud Domains registrations in the project.
## EXAMPLES
To list all registrations in the project, run:
$ {command}
"""
@staticmethod
def Args(parser):
List.ArgsPerVersion(registrations.ALPHA_API_VERSION, parser)
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.DefaultUniverseOnly
class ListGa(List):
"""List Cloud Domains registrations.
List Cloud Domains registrations in the project.
## EXAMPLES
To list all registrations in the project, run:
$ {command}
"""
@staticmethod
def Args(parser):
List.ArgsPerVersion(registrations.GA_API_VERSION, parser)

View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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 domains registrations list-importable-domains` command."""
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
_FORMAT = """\
table(
domainName.scope("domains"):label=DOMAIN,
resourceState:label=RESOURCE_STATE,
yearlyPrice.price():label=YEARLY_PRICE
)
"""
@base.Deprecate(
is_removed=True,
warning=(
'This command is deprecated. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
error=(
'This command has been removed. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
)
@base.DefaultUniverseOnly
class ListImportableDomains(base.ListCommand):
# pylint: disable=line-too-long
"""List Google Domains registrations importable into Cloud Domains.
List Google Domains registrations that can be imported to a Cloud Domains
project.
Registrations with an IMPORTABLE resource state can be imported from
Google Domains registrar to Cloud Domains.
Registrations with a SUSPENDED, EXPIRED, or DELETED resource state must have
their states resolved with Google Domains registrar to be imported.
Registrations with an UNSUPPORTED resource state are not currently supported
for import.
## EXAMPLES
To list Google Domains registrations that can be imported, run:
$ {command}
"""
@staticmethod
def Args(parser):
resource_args.AddLocationResourceArg(parser, 'to import to')
parser.display_info.AddTransforms({'price': util.TransformMoneyType})
parser.display_info.AddFormat(_FORMAT)
base.URI_FLAG.RemoveFromParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
location_ref = args.CONCEPTS.location.Parse()
return client.RetrieveImportableDomains(
location_ref,
limit=args.limit,
page_size=args.page_size,
batch_size=util.GetListBatchSize(args))

View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations operations command group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class DomainRegistrationOperations(base.Group):
"""Manage Cloud Domains operations.
Commands for managing Cloud Domains operations.
"""
pass

View File

@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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.
"""The `gcloud domains registrations operations describe` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import operations
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
@base.DefaultUniverseOnly
class Describe(base.DescribeCommand):
"""Show details about a Cloud Domains operation.
Print information about a Cloud Domains operation.
## EXAMPLES
To describe an operation ``operation-id'', run:
$ {command} operation-id
"""
@staticmethod
def Args(parser):
resource_args.AddOperationResourceArg(parser, 'to describe')
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = operations.Client.FromApiVersion(api_version)
operation_ref = args.CONCEPTS.operation.Parse()
return client.Get(operation_ref)

View File

@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations operations list` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import operations
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
_FORMAT = """\
table(
name.basename():label=OPERATION_NAME,
metadata.verb:label=TYPE,
metadata.target.basename(),
done,
metadata.createTime.date():reverse,
duration(start=metadata.createTime,end=metadata.endTime,precision=0,calendar=false).slice(2:).join("").yesno(no="<1S"):label=DURATION
)
"""
@base.DefaultUniverseOnly
class List(base.ListCommand):
"""List Cloud Domains operations.
List Cloud Domains operations in the project.
## EXAMPLES
To list all operations in the project, run:
$ {command}
"""
@staticmethod
def Args(parser):
resource_args.AddLocationResourceArg(parser, 'in which to list operations')
parser.display_info.AddFormat(_FORMAT)
def Run(self, args):
"""Run the list command."""
api_version = registrations.GetApiVersionFromArgs(args)
client = operations.Client.FromApiVersion(api_version)
location_ref = args.CONCEPTS.location.Parse()
return client.List(location_ref, args.limit, args.page_size)

View File

@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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.
"""Command to wait for operation completion."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import operations
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
@base.DefaultUniverseOnly
class Wait(base.SilentCommand):
"""Wait for asynchronous operation to complete.
Wait for a specified Cloud Domains operation to complete.
## EXAMPLES
To wait for an operation ``operation-id'', run:
$ {command} operation-id
"""
@staticmethod
def Args(parser):
resource_args.AddOperationResourceArg(parser, 'to wait for')
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = operations.Client.FromApiVersion(api_version)
operation_ref = args.CONCEPTS.operation.Parse()
return client.WaitForOperation(
operation_ref,
'Waiting for \'{}\' to complete'.format(operation_ref.Name()))

View File

@@ -0,0 +1,217 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations register` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import contacts_util
from googlecloudsdk.command_lib.domains import dns_util
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.DefaultUniverseOnly
class Register(base.CreateCommand):
# pylint: disable=line-too-long
"""Register a new domain.
Create a new Cloud Domains registration resource by registering a new domain.
The new resource's ID will be equal to the domain name.
After this command executes, the resource will be in state
REGISTRATION_PENDING. The registration process should complete in less than 5
minutes. After that the resource will be in state ACTIVE. In rare
cases this process can take much longer due, for example, to a downtime of the
domain registry.
Also in rare cases, the domain may end up in state REGISTRATION_FAILED. In
that case, delete the registration resource and try again.
When using Cloud DNS Zone DNSSEC will be enabled by default whenever the Zone
is DNSSEC signed. You can choose to not enable DNSSEC by using the
--disable-dnssec flag.
## EXAMPLES
To register ``example.com'' interactively, run:
$ {command} example.com
To register ``example.com'' using contact data from a YAML file
``contacts.yaml'', run:
$ {command} example.com --contact-data-from-file=contacts.yaml
To register ``example.com'' with interactive prompts disabled, provide
--contact-data-from-file, --contact-privacy, --yearly-price flags and one of
the flags for setting authoritative name servers. Sometimes also --notices
flag is required. For example, run:
$ {command} example.com --contact-data-from-file=contacts.yaml --contact-privacy=private-contact-data --yearly-price="12.00 USD" --cloud-dns-zone=example-com --quiet
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(
parser, noun='The domain name', verb='to register')
flags.AddRegisterFlagsToParser(parser)
labels_util.AddCreateLabelsFlags(parser)
flags.AddValidateOnlyFlagToParser(parser, 'create')
flags.AddAsyncFlagToParser(parser)
def _ValidateContacts(self, contacts):
if contacts is None:
raise exceptions.Error('Providing contacts is required.')
for field in ['registrantContact', 'adminContact', 'technicalContact']:
if not contacts.get_assigned_value(field):
raise exceptions.Error('Providing {} is required.'.format(field))
# TODO(b/166210862): Call Register with validate_only to check contacts.
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
client.PrintSQSPAck()
normalized = util.NormalizeResourceName(args.registration)
if normalized != args.registration:
console_io.PromptContinue(
'Domain name \'{}\' has been normalized to equivalent \'{}\'.'.format(
args.registration, normalized),
throw_if_unattended=False,
cancel_on_no=True,
default=True)
args.registration = normalized
registration_ref = args.CONCEPTS.registration.Parse()
location_ref = registration_ref.Parent()
# First check if the domain is available, then parse all the parameters,
# ask for price and only then ask for additional data.
register_params = client.RetrieveRegisterParameters(
location_ref, registration_ref.registrationsId)
available_enum = client.messages.RegisterParameters.AvailabilityValueValuesEnum.AVAILABLE
if register_params.availability != available_enum:
raise exceptions.Error(
'Domain \'{}\' is not available for registration: \'{}\''.format(
registration_ref.registrationsId, register_params.availability))
labels = labels_util.ParseCreateArgs(
args, client.messages.Registration.LabelsValue)
dnssec_update = dns_util.DNSSECUpdate.ENABLE
if args.disable_dnssec:
dnssec_update = dns_util.DNSSECUpdate.DISABLE
dns_settings, _ = dns_util.ParseDNSSettings(
api_version,
args.name_servers,
args.cloud_dns_zone,
args.use_google_domains_dns,
None,
registration_ref.registrationsId,
dnssec_update=dnssec_update)
contacts = contacts_util.ParseContactData(api_version,
args.contact_data_from_file)
if contacts:
self._ValidateContacts(contacts)
contact_privacy = contacts_util.ParseContactPrivacy(api_version,
args.contact_privacy)
yearly_price = util.ParseYearlyPrice(api_version, args.yearly_price)
public_contacts_ack, hsts_ack = util.ParseRegisterNotices(args.notices)
if yearly_price is None:
yearly_price = util.PromptForYearlyPriceAck(register_params.yearlyPrice)
if yearly_price is None:
raise exceptions.Error('Accepting yearly price is required.')
if not util.EqualPrice(yearly_price, register_params.yearlyPrice):
raise exceptions.Error(
'Incorrect yearly_price: \'{}\', expected: {}.'.format(
util.TransformMoneyType(yearly_price),
util.TransformMoneyType(register_params.yearlyPrice)))
hsts_enum = client.messages.RegisterParameters.DomainNoticesValueListEntryValuesEnum.HSTS_PRELOADED
if hsts_enum in register_params.domainNotices and not hsts_ack:
hsts_ack = util.PromptForHSTSAck(register_params.domainName)
if hsts_ack is None:
raise exceptions.Error('Acceptance is required.')
if dns_settings is None:
dns_settings, _ = dns_util.PromptForNameServers(
api_version,
registration_ref.registrationsId,
dnssec_update=dnssec_update)
if dns_settings is None:
raise exceptions.Error('Providing DNS settings is required.')
if contacts is None:
contacts = contacts_util.PromptForContacts(api_version)
self._ValidateContacts(contacts)
if contact_privacy is None:
choices = [
flags.ContactPrivacyEnumMapper(client.messages).GetChoiceForEnum(enum)
for enum in register_params.supportedPrivacy
]
contact_privacy = contacts_util.PromptForContactPrivacy(
api_version, choices)
if contact_privacy is None:
raise exceptions.Error('Providing Contact Privacy is required.')
contacts.privacy = contact_privacy
public_privacy_enum = client.messages.ContactSettings.PrivacyValueValuesEnum.PUBLIC_CONTACT_DATA
if not public_contacts_ack and contact_privacy == public_privacy_enum:
public_contacts_ack = contacts_util.PromptForPublicContactsAck(
register_params.domainName, contacts)
if public_contacts_ack is None:
raise exceptions.Error('Acceptance is required.')
response = client.Register(
location_ref,
registration_ref.registrationsId,
dns_settings=dns_settings,
contact_settings=contacts,
yearly_price=yearly_price,
hsts_notice_accepted=hsts_ack,
public_privacy_accepted=public_contacts_ack,
labels=labels,
validate_only=args.validate_only)
if args.validate_only:
log.status.Print('The command will not have any effect because '
'validate-only flag is present.')
else:
response = util.WaitForOperation(api_version, response, args.async_)
log.CreatedResource(
registration_ref.Name(),
'registration',
args.async_,
details=(
'Note:\nThe domain is not yet registered.\n'
'Wait until the registration resource changes state to ACTIVE.'))
return response

View File

@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 domains registrations renew-domain` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import re
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
class RenewDomain(base.UpdateCommand):
"""Renew a recently expired Cloud Domains registration.
Use this method to renew domains that expired within the last 30 days.
Renewing your domain extends it for one year from the previous expiration date
and you are charged the yearly renewal price.
## EXAMPLES
To renew a registration for ``example.com'' interactively, run:
$ {command} example.com
To renew ``example.com'' with interactive prompts disabled, provide the
--yearly-price flag. For example, run:
$ {command} example.com --yearly-price="12.00 USD" --quiet
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser, 'to renew')
flags.AddPriceFlagsToParser(parser, flags.MutationOp.RENEWAL)
flags.AddValidateOnlyFlagToParser(parser, 'renew')
flags.AddAsyncFlagToParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
yearly_price = util.ParseYearlyPrice(api_version, args.yearly_price)
if yearly_price is None:
messages = registrations.GetMessagesModule(api_version)
empty_price = messages.Money()
try:
client.Renew(registration_ref, empty_price, validate_only=True)
except apitools_exceptions.HttpError as e:
match = re.search(r'INVALID: expected (\d+).(\d{2}) USD', e.content)
if match:
units, cents = match.groups()
yearly_price = messages.Money(
units=int(units), nanos=int(cents) * 10**7, currencyCode='USD')
yearly_price = util.PromptForYearlyPriceAck(yearly_price)
if yearly_price is None:
raise exceptions.Error('Accepting yearly price is required.')
else:
raise e
response = client.Renew(registration_ref, yearly_price, args.validate_only)
if args.validate_only:
log.status.Print('The command will not have any effect because '
'validate-only flag is present.')
else:
response = util.WaitForOperation(api_version, response, args.async_)
log.UpdatedResource(registration_ref.Name(), 'registration', args.async_)
return response

View File

@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations search-domains` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
_FORMAT = """\
table(
domainName:label=DOMAIN,
availability:label=AVAILABILITY,
yearlyPrice.price():label=YEARLY_PRICE,
domainNotices.list():label=NOTICES
)
"""
@base.DefaultUniverseOnly
class SearchDomains(base.DescribeCommand):
"""Search for available domains.
Search for available domains relevant to a specified query.
This command uses cached domain name availability information. Use the
get-register-params command to get up-to-date availability information.
## EXAMPLES
To search for domains for ``my-new-project'', run:
$ {command} my-new-project
To search for a specific domain, like ``example.com'', and get suggestions for
other domain endings, run:
$ {command} example.com
"""
@staticmethod
def Args(parser):
resource_args.AddLocationResourceArg(parser, 'to search domains in')
parser.display_info.AddTransforms({'price': util.TransformMoneyType})
parser.display_info.AddFormat(_FORMAT)
base.Argument(
'domain_query',
help=('Domain search query. '
'May be a domain name or arbitrary search terms.'),
).AddToParser(parser)
def Run(self, args):
"""Run the search domains command."""
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
location_ref = args.CONCEPTS.location.Parse()
# Sending the query direcyly to server (without normalization).
suggestions = client.SearchDomains(location_ref, args.domain_query)
for s in suggestions:
try:
s.domainName = util.PunycodeToUnicode(s.domainName)
except UnicodeError:
pass # Do not change the domain name.
if not suggestions:
suggestions.append(client.messages.RegisterParameters())
return suggestions

View File

@@ -0,0 +1,230 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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 domains registrations transfer` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import contacts_util
from googlecloudsdk.command_lib.domains import dns_util
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.Deprecate(
is_removed=True,
warning=(
'This command is deprecated. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
error=(
'This command has been removed. See'
' https://cloud.google.com/domains/docs/deprecations/feature-deprecations.'
),
)
@base.DefaultUniverseOnly
class Transfer(base.CreateCommand):
# pylint: disable=line-too-long
"""Transfer a domain from another registrar.
Create a new Cloud Domains registration resource by transferring an existing
domain from another registrar.
The new resource's ID will be equal to the domain name.
After this command executes, the resource will be in state
TRANSFER_PENDING. To complete the transfer, the registrant may need to approve
the transfer through an email sent by the current registrar. Domain transfers
can take 5-7 days to complete. After the transfer is completed, the resource
transitions to state ACTIVE, indicating that the transfer was successful. If
the transfer is rejected or the request expires without being approved, the
resource ends up in state TRANSFER_FAILED. If the transfer fails, you can
safely delete the resource and retry the transfer. Transfers in state
TRANSFER_PENDING can also be cancelled with the delete command.
## EXAMPLES
To transfer ``example.com'' interactively, run:
$ {command} example.com
To transfer ``example.com'' using contact data from a YAML file
``contacts.yaml'', run:
$ {command} example.com --contact-data-from-file=contacts.yaml
To transfer ``example.com'' with interactive prompts disabled, provide
--authorization-code-from-file, --contact-data-from-file, --contact-privacy,
--yearly-price flags and one of the flags for setting authoritative name
servers. Sometimes also --notices flag is required.
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(
parser, noun='The domain name', verb='to transfer')
flags.AddTransferFlagsToParser(parser)
labels_util.AddCreateLabelsFlags(parser)
flags.AddValidateOnlyFlagToParser(parser, verb='transfer', noun='domain')
flags.AddAsyncFlagToParser(parser)
def _ValidateContacts(self, contacts):
if contacts is None:
raise exceptions.Error('Providing contacts is required.')
for field in ['registrantContact', 'adminContact', 'technicalContact']:
if not contacts.get_assigned_value(field):
raise exceptions.Error('Providing {} is required.'.format(field))
# TODO(b/166210862): Call Transfer with validate_only to check contacts.
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
client.PrintSQSPAck()
normalized = util.NormalizeResourceName(args.registration)
if normalized != args.registration:
console_io.PromptContinue(
'Domain name \'{}\' has been normalized to equivalent \'{}\'.'.format(
args.registration, normalized),
throw_if_unattended=False,
cancel_on_no=True,
default=True)
args.registration = normalized
registration_ref = args.CONCEPTS.registration.Parse()
location_ref = registration_ref.Parent()
# First check if the domain is available for transfer, then parse all the
# parameters, ask for price and only then ask for additional data.
transfer_params = client.RetrieveTransferParameters(
location_ref, registration_ref.registrationsId)
locked_enum = client.messages.TransferParameters.TransferLockStateValueValuesEnum.LOCKED
if transfer_params.transferLockState == locked_enum:
raise exceptions.Error(
'Domains must be unlocked before transferring. Transfer lock state: {}'
.format(transfer_params.transferLockState))
auth_code = util.ReadFileContents(args.authorization_code_from_file)
labels = labels_util.ParseCreateArgs(
args, client.messages.Registration.LabelsValue)
dns_settings = None
if not args.keep_dns_settings:
# Assume DNSSEC is off following transfer when changing name servers.
dns_settings, _ = dns_util.ParseDNSSettings(
api_version,
None,
args.cloud_dns_zone,
args.use_google_domains_dns,
None,
registration_ref.registrationsId,
dnssec_update=dns_util.DNSSECUpdate.DISABLE)
contacts = contacts_util.ParseContactData(api_version,
args.contact_data_from_file)
if contacts:
self._ValidateContacts(contacts)
contact_privacy = contacts_util.ParseContactPrivacy(api_version,
args.contact_privacy)
yearly_price = util.ParseYearlyPrice(api_version, args.yearly_price)
# Ignore HSTS notices for transfer.
public_contacts_ack, _ = util.ParseRegisterNotices(args.notices)
if auth_code is None:
# TODO(b/186472865): Handle transfers without auth codes e.g. co.uk.
auth_code = util.PromptForAuthCode()
if yearly_price is None:
yearly_price = util.PromptForYearlyPriceAck(transfer_params.yearlyPrice)
if yearly_price is None:
raise exceptions.Error('Accepting yearly price is required.')
if not util.EqualPrice(yearly_price, transfer_params.yearlyPrice):
raise exceptions.Error(
'Incorrect yearly_price: \'{}\', expected: {}.'.format(
util.TransformMoneyType(yearly_price),
util.TransformMoneyType(transfer_params.yearlyPrice)))
keep_dns_settings = args.keep_dns_settings
if dns_settings is None and not keep_dns_settings:
# Assume DNSSEC is off following transfer when changing name servers.
dns_settings, _, keep_dns_settings = dns_util.PromptForNameServersTransfer(
api_version, registration_ref.registrationsId)
if dns_settings is None and not keep_dns_settings:
raise exceptions.Error('Providing DNS settings is required.')
if contacts is None:
contacts = contacts_util.PromptForContacts(api_version)
self._ValidateContacts(contacts)
if contact_privacy is None:
choices = [
flags.ContactPrivacyEnumMapper(client.messages).GetChoiceForEnum(enum)
for enum in transfer_params.supportedPrivacy
]
contact_privacy = contacts_util.PromptForContactPrivacy(
api_version, choices)
if contact_privacy is None:
raise exceptions.Error('Providing Contact Privacy is required.')
contacts.privacy = contact_privacy
public_privacy_enum = client.messages.ContactSettings.PrivacyValueValuesEnum.PUBLIC_CONTACT_DATA
if not public_contacts_ack and contact_privacy == public_privacy_enum:
public_contacts_ack = contacts_util.PromptForPublicContactsAck(
transfer_params.domainName, contacts)
if public_contacts_ack is None:
raise exceptions.Error('Acceptance is required.')
response = client.Transfer(
location_ref,
registration_ref.registrationsId,
dns_settings=dns_settings,
contact_settings=contacts,
authorization_code=auth_code.strip(),
yearly_price=yearly_price,
public_privacy_accepted=public_contacts_ack,
labels=labels,
validate_only=args.validate_only)
if args.validate_only:
log.status.Print('The command will not have any effect because '
'validate-only flag is present.')
else:
response = util.WaitForOperation(api_version, response, args.async_)
log.CreatedResource(
registration_ref.Name(),
'registration',
args.async_,
details=(
'Note:\nThe domain transfer has been initiated, but is not yet '
'complete. The registrant may need to follow instructions in a '
'transfer confirmation email sent by the current registrar in '
'order for the transfer to proceed. Even after confirmation, '
'transfers can sometimes take several days to complete. The '
'transfer will be complete when the registration resource changes'
' state to ACTIVE.'))
return response

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 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 domains registrations update` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.domains import registrations
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.domains import flags
from googlecloudsdk.command_lib.domains import resource_args
from googlecloudsdk.command_lib.domains import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
class Update(base.UpdateCommand):
"""Update a Cloud Domains registration.
Update an existing registration. Currently used for updating labels only.
Run:
$ gcloud help alpha domains registrations configure
to see how to change management, DNS or contact settings.
## EXAMPLES
To add a label with key ``environment'' and value ``test'' for
``example.com'', run:
$ {command} example.com --update-labels="project=example,environment=test"
"""
@staticmethod
def Args(parser):
resource_args.AddRegistrationResourceArg(parser, 'to update')
labels_util.AddUpdateLabelsFlags(parser)
flags.AddAsyncFlagToParser(parser)
def Run(self, args):
api_version = registrations.GetApiVersionFromArgs(args)
client = registrations.RegistrationsClient(api_version)
args.registration = util.NormalizeResourceName(args.registration)
registration_ref = args.CONCEPTS.registration.Parse()
labels_update = None
labels_diff = labels_util.Diff.FromUpdateArgs(args)
if labels_diff.MayHaveUpdates():
orig_resource = client.Get(registration_ref)
labels_update = labels_diff.Apply(
client.messages.Registration.LabelsValue,
orig_resource.labels).GetOrNone()
else:
raise exceptions.Error(
'Specify labels to update.\n'
'Run `gcloud help alpha domains registrations configure` to see '
'how to change management, DNS or contact settings.')
if labels_update:
response = client.Patch(registration_ref, labels=labels_update)
response = util.WaitForOperation(api_version, response, args.async_)
log.UpdatedResource(registration_ref.Name(), 'registration', args.async_)
return response

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 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.
"""The `domains verify` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.app import browser_dispatcher
VERIFY_DOMAINS_URL = (
'https://search.google.com/search-console/welcome'
'?authuser=0&new_domain_name={domain}&pli=1'
)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class Verify(base.Command):
"""Verifies a domain via an in-browser workflow."""
detailed_help = {
'DESCRIPTION': '{description}',
'EXAMPLES': """\
To verify a domain for the current user, run:
$ {command} example.com
This will allow the domain to be used with App Engine through
{parent_command} app domain-mappings and across Google Cloud products.
""",
}
@staticmethod
def Args(parser):
parser.add_argument('domain', help='The domain to be verified.')
def Run(self, args):
url = VERIFY_DOMAINS_URL.format(domain=args.domain)
browser_dispatcher.OpenURL(url)