def Run(self, args): client = registrations.RegistrationsClient() args.registration = util.NormalizeResourceName(args.registration) registration_ref = args.CONCEPTS.registration.Parse() registration = client.Get(registration_ref) util.AssertRegistrationOperational(registration) contacts = contacts_util.ParseContactData(args.contact_data_from_file) contact_privacy = contacts_util.ParseContactPrivacy( args.contact_privacy) public_contacts_ack = contacts_util.ParsePublicContactsAck( args.notices) if contacts is None: contacts = contacts_util.PromptForContacts( registration.contactSettings) if contact_privacy is None: choices = list( map(flags.CONTACT_PRIVACY_ENUM_MAPPER.GetChoiceForEnum, registration.supportedPrivacy)) contact_privacy = contacts_util.PromptForContactPrivacy( 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( 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(response, args.async_) note = None if not args.async_ and self.CheckPendingContacts(registration_ref): note = ( 'Note:\nThe contact settings are currently pending.\nIn order ' 'to finalize the update you need to confirm the ' 'change using an email sent to the registrant.') log.UpdatedResource(registration_ref.Name(), 'registration', args.async_, details=note) return response
def Run(self, args): client = registrations.RegistrationsClient() registration_ref = args.CONCEPTS.registration.Parse() # TODO(b/110077203) Tweak the message. console_io.PromptContinue( 'You are about to detach registration [{}]'.format( registration_ref.registrationsId), throw_if_unattended=True, cancel_on_no=True) response = client.Detach(registration_ref) if args. async: # TODO(b/110077203): Log something sensible. return response operations_client = operations.Client.FromApiVersion('v1alpha1') operation_ref = util.ParseOperation(response.name) response = operations_client.WaitForOperation( operation_ref, 'Waiting for [{}] to complete'.format(operation_ref.Name())) log.UpdatedResource( registration_ref.Name(), 'registration', 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): """Run the check availability command.""" client = registrations.RegistrationsClient() location_ref = args.CONCEPTS.location.Parse() return client.CheckAvailability(location_ref, args.domain).availability
def Run(self, args): """Run the search domains command.""" client = registrations.RegistrationsClient() location_ref = args.CONCEPTS.location.Parse() return client.SearchAvailability(location_ref, args.domain_query)
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
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
def Run(self, args): """Run the list command.""" client = registrations.RegistrationsClient() location_ref = args.CONCEPTS.location.Parse() # TODO(b/110077203): Add server-side filtering. return client.List(location_ref, args.limit, args.page_size)
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)
def Run(self, args): """Run the get register parameters command.""" client = registrations.RegistrationsClient() location_ref = args.CONCEPTS.location.Parse() domain = util.NormalizeDomainName(args.domain) return client.RetrieveRegisterParameters(location_ref, domain)
def Run(self, args): """Run the search domains command.""" client = registrations.RegistrationsClient() location_ref = args.CONCEPTS.location.Parse() # Sending the query direcyly to server (without normalization). return client.SearchDomains(location_ref, args.domain_query)
def Run(self, args): client = registrations.RegistrationsClient() 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 may be specified.') registration = client.Get(registration_ref) util.AssertRegistrationOperational(registration) dns_settings, updated = dns_util.ParseDNSSettings( 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, updated = dns_util.PromptForNameServers( 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 updated.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 = updated.dns_provider 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, updated, 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(response, args.async_) log.UpdatedResource(registration_ref.Name(), 'registration', args.async_) return response
def Run(self, args): """Run reset authorization code command.""" client = registrations.RegistrationsClient() args.registration = util.NormalizeResourceName(args.registration) registration_ref = args.CONCEPTS.registration.Parse() registration = client.Get(registration_ref) util.AssertRegistrationOperational(registration) return client.ResetAuthorizationCode(registration_ref)
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)
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)
def Run(self, args): """Run the search domains command.""" client = registrations.RegistrationsClient() 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: messages = registrations.GetMessagesModule() suggestions.append(messages.RegisterParameters()) return suggestions
def Run(self, args): client = registrations.RegistrationsClient() registration_ref = args.CONCEPTS.registration.Parse() name_servers = util.ParseNameServers(args.name_servers, args.cloud_dns_zone, registration_ref.registrationsId) registrant_contact = util.ParseWhoisContact( args.registrant_contact_from_file) whois_privacy = util.ParseWhoisPrivacy(args.whois_privacy) new_labels = None labels_diff = labels_util.Diff.FromUpdateArgs(args) if labels_diff.MayHaveUpdates(): orig_resource = client.Get(registration_ref) new_labels = labels_diff.Apply( client.messages.Registration.LabelsValue, orig_resource.labels).GetOrNone() response = client.Patch(registration_ref, name_servers=name_servers, registrant_contact=registrant_contact, whois_privacy=whois_privacy, labels=new_labels, validate_only=args.validate_only) if args.validate_only: # TODO(b/110077203): Log something sensible. return if args. async: # TODO(b/110077203): Log something sensible. return response operations_client = operations.Client.FromApiVersion('v1alpha1') operation_ref = util.ParseOperation(response.name) response = operations_client.WaitForOperation( operation_ref, 'Waiting for [{}] to complete'.format(operation_ref.Name())) log.UpdatedResource(registration_ref.Name(), 'registration') 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() 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
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()) transfer_pending_enum = client.messages.Registration.StateValueValuesEnum.TRANSFER_PENDING transfer_failed_enum = client.messages.Registration.StateValueValuesEnum.TRANSFER_FAILED if (registration.state == transfer_pending_enum or registration.state == transfer_failed_enum): # We would prefer to print this after the resource but Epilog() doesn't # accept other method arguments. log.status.Print( 'For more details on the status of the domain transfer, sign into ' 'Google Domains by visiting https://domains.google.com/registrar.' ) return registration
def Run(self, args): client = registrations.RegistrationsClient() args.registration = util.NormalizeResourceName(args.registration) registration_ref = args.CONCEPTS.registration.Parse() registration = client.Get(registration_ref) util.AssertRegistrationOperational(registration) transfer_lock_state = util.ParseTransferLockState(args.transfer_lock_state) if transfer_lock_state is None: transfer_lock_state = util.PromptForTransferLockState( registration.managementSettings.transferLockState) if transfer_lock_state is None: return None response = client.ConfigureManagement(registration_ref, transfer_lock_state) response = util.WaitForOperation(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): api_version = registrations.GetApiVersionFromArgs(args) client = registrations.RegistrationsClient(api_version) args.registration = util.NormalizeResourceName(args.registration) return client.Get(args.CONCEPTS.registration.Parse())
def Run(self, args): client = registrations.RegistrationsClient() registration_ref = args.CONCEPTS.registration.Parse() location_ref = registration_ref.Parent() labels = labels_util.ParseCreateArgs( args, client.messages.Registration.LabelsValue) name_servers = util.ParseNameServers(args.name_servers, args.cloud_dns_zone, registration_ref.registrationsId) registrant_contact = util.ParseWhoisContact( args.registrant_contact_from_file) if registrant_contact is None: registrant_contact = util.PromptForWhoisContact() if registrant_contact is None: raise exceptions.Error( 'Registrant contact is required. It can be provided interactively or ' 'through --registrant-contact-from-file flag.') availability = client.CheckAvailability( location_ref, registration_ref.registrationsId).availability if availability.available != client.availability_enum.AVAILABLE: raise exceptions.Error( 'Domain [{}] is not available for registration: [{}]'.format( registration_ref.registrationsId, availability.available)) whois_privacy = util.ParseWhoisPrivacy(args.whois_privacy) if whois_privacy is None: whois_privacy = util.PromptForWhoisPrivacy( availability.supportedWhoisPrivacy) hsts_notice_accepted = False if client.notices_enum.HSTS_PRELOADED in availability.notices: console_io.PromptContinue( ('{} is a secure namespace. You may purchase {} now but it will ' 'require an SSL certificate for website connection.').format( util.DomainNamespace(availability.domainName), availability.domainName), throw_if_unattended=True, cancel_on_no=True) hsts_notice_accepted = True console_io.PromptContinue( 'Yearly price: {}\n'.format( util.TransformMoneyType(availability.yearlyPrice)), throw_if_unattended=True, cancel_on_no=True) response = client.Create( location_ref, registration_ref.registrationsId, name_servers=name_servers, registrant_contact=registrant_contact, whois_privacy=whois_privacy, yearly_price=availability.yearlyPrice, hsts_notice_accepted=hsts_notice_accepted, labels=labels, validate_only=args.validate_only) if args.validate_only: # TODO(b/110077203): Log something sensible. return if args.async: # TODO(b/110077203): Log something sensible. return response operations_client = operations.Client.FromApiVersion('v1alpha1') operation_ref = util.ParseOperation(response.name) response = operations_client.WaitForOperation( operation_ref, 'Waiting for [{}] to complete'.format(operation_ref.Name())) log.CreatedResource(registration_ref.Name(), 'registration') 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
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): client = registrations.RegistrationsClient() return client.Get(args.CONCEPTS.registration.Parse())
def CheckPendingContacts(self, registration_ref): client = registrations.RegistrationsClient() registration = client.Get(registration_ref) return bool(registration.pendingContactSettings)
def Run(self, args): client = registrations.RegistrationsClient() args.registration = util.NormalizeResourceName(args.registration) return client.Get(args.CONCEPTS.registration.Parse())