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) if transfer_lock_state is None: transfer_lock_state = util.PromptForTransferLockState( api_version, registration.managementSettings.transferLockState) if transfer_lock_state is None: return None response = client.ConfigureManagement(registration_ref, transfer_lock_state) response = util.WaitForOperation(api_version, response, args.async_) log.UpdatedResource(registration_ref.Name(), 'registration', args.async_) return response
def Run(self, args): client = registrations.RegistrationsClient() 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(response, args.async_) log.ExportResource( registration_ref.Name(), 'registration', is_async=args.async_, details=('Note:\nRegistration remains valid until expiry. See ' 'https://support.google.com/domains/answer/6339340 for ' 'information how to access it in Google Domains.')) return response
def Run(self, args): client = registrations.RegistrationsClient() 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(response, args.async_) log.UpdatedResource(registration_ref.Name(), 'registration', args.async_) return response
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() if args.disable_dnssec 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) 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, enable_dnssec=not args.disable_dnssec, dns_settings=registration.dnsSettings) if dns_settings is None: dns_settings, update_mask = dns_util.PromptForNameServers( api_version, registration_ref.registrationsId, enable_dnssec=not args.disable_dnssec, 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) name_servers_changed = update_mask.name_servers and not dns_util.NameServersEquivalent( registration.dnsSettings, dns_settings) if ds_records_present and name_servers_changed: log.warning('Name servers should not be changed if DS ' 'records are present. 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
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 if not public_contacts_ack and new_privacy == client.messages.ContactSettings.PrivacyValueValuesEnum.PUBLIC_CONTACT_DATA: merged_contacts = contacts_util.MergeContacts( api_version, prev_contacts=registration.contactSettings, new_contacts=contacts) 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
def Run(self, args): api_version = registrations.GetApiVersionFromArgs(args) client = registrations.RegistrationsClient(api_version) 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) dns_settings, _ = dns_util.ParseDNSSettings( api_version, args.name_servers, args.cloud_dns_zone, args.use_google_domains_dns, None, registration_ref.registrationsId, enable_dnssec=not args.disable_dnssec) 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, enable_dnssec=not args.disable_dnssec) 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
def Run(self, args): api_version = registrations.GetApiVersionFromArgs(args) client = registrations.RegistrationsClient(api_version) 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, enable_dnssec=False) 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.\nTo check the status of the domain transfer,' ' sign into Google Domains by visiting ' 'https://domains.google.com/registrar.')) return response