def PromptForContactPrivacy(api_version, choices, current_privacy=None): """Asks a user for Contacts Privacy. Args: api_version: Cloud Domains API version to call. choices: List of privacy choices. current_privacy: Current privacy. Should be nonempty in update calls. Returns: Privacy enum or None if the user cancelled. """ if not choices: raise exceptions.Error('Could not find supported contact privacy.') domains_messages = registrations.GetMessagesModule(api_version) # Sort the choices according to the privacy strength. choices.sort(key=flags.PrivacyChoiceStrength, reverse=True) if current_privacy: if len(choices) == 1: log.status.Print( 'Your current contact privacy is {}. It cannot be changed.'. format(current_privacy)) return None else: update = console_io.PromptContinue( 'Your current contact privacy is {}.'.format(current_privacy), 'Do you want to change it', default=False) if not update: return None current_choice = 0 for ix, privacy in enumerate(choices): if privacy == flags.ContactPrivacyEnumMapper( domains_messages).GetChoiceForEnum(current_privacy): current_choice = ix else: current_choice = 0 # The strongest available privacy if len(choices) == 1: ack = console_io.PromptContinue( 'The only supported contact privacy is {}.'.format(choices[0]), default=True) if not ack: return None return ParseContactPrivacy(api_version, choices[0]) else: index = console_io.PromptChoice(options=choices, default=current_choice, message='Specify contact privacy') return ParseContactPrivacy(api_version, choices[index])
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 ParseContactPrivacy(api_version, contact_privacy): domains_messages = registrations.GetMessagesModule(api_version) if contact_privacy is None: return None return flags.ContactPrivacyEnumMapper(domains_messages).GetEnumForChoice( contact_privacy)
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