def CreateRequests(self, args): """Returns a list of requests necessary for adding users.""" owner = args.owner if not owner: owner = gaia.GetAuthenticatedGaiaEmail(self.http) name = args.name if not name: name = gaia.MapGaiaEmailToDefaultAccountName(owner) user_ref = self.clouduseraccounts_resources.Parse( name, params={'project': properties.VALUES.core.project.GetOrFail}, collection='clouduseraccounts.users') user = self.messages.User( name=user_ref.Name(), description=args.description, owner=owner, ) request = self.messages.ClouduseraccountsUsersInsertRequest( project=self.project, user=user) return [request]
def _EnsureSSHKeyExistsForUser(self, fetcher, user): """Ensure the user's public SSH key is known by the Account Service.""" public_key = self.keys.GetPublicKey().ToEntry(include_comment=True) should_upload = True try: user_info = fetcher.LookupUser(user) except user_client.UserException: owner_email = gaia.GetAuthenticatedGaiaEmail(self.http) fetcher.CreateUser(user, owner_email) user_info = fetcher.LookupUser(user) for remote_public_key in user_info.publicKeys: if remote_public_key.key.rstrip() == public_key: expiration_time = remote_public_key.expirationTimestamp if expiration_time and time_util.IsExpired(expiration_time): # If a key is expired we remove and reupload fetcher.RemovePublicKey(user_info.name, remote_public_key.fingerprint) else: should_upload = False break if should_upload: fetcher.UploadPublicKey(user, public_key) return True
def Run(self, args): """Issues requests necessary for adding users.""" compute_holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) holder = base_classes.ComputeUserAccountsApiHolder(self.ReleaseTrack()) client = holder.client owner = args.owner if not owner: owner = gaia.GetAuthenticatedGaiaEmail(client.http) name = args.name if not name: name = gaia.MapGaiaEmailToDefaultAccountName(owner) user_ref = holder.resources.Parse( name, params={'project': properties.VALUES.core.project.GetOrFail}, collection='clouduseraccounts.users') user = client.MESSAGES_MODULE.User( name=user_ref.Name(), description=args.description, owner=owner, ) request = client.MESSAGES_MODULE.ClouduseraccountsUsersInsertRequest( project=user_ref.project, user=user) return compute_holder.client.MakeRequests([(client.users, 'Insert', request)])
def Run(self, args): """See ssh_utils.BaseSSHCLICommand.Run.""" oslogin_client = client.OsloginClient(self.ReleaseTrack()) user_email = gaia.GetAuthenticatedGaiaEmail(oslogin_client.client.http) keys = oslogin_utils.GetKeysFromProfile(user_email, oslogin_client) return keys
def Run(self, args): """See ssh_utils.BaseSSHCLICommand.Run.""" key = flags.GetKeyFromArgs(args) oslogin_client = client.OsloginClient(self.ReleaseTrack()) user_email = gaia.GetAuthenticatedGaiaEmail(oslogin_client.client.http) keys = oslogin_utils.GetKeyDictionaryFromProfile( user_email, oslogin_client) fingerprint = oslogin_utils.FindKeyInKeyList(key, keys) if fingerprint: return oslogin_client.DeleteSshPublicKey(user_email, fingerprint) else: raise client.OsloginKeyNotFoundError( 'Cannot find requested SSH key.')
def CheckForOsloginAndGetUser(self, instance, project, requested_user, release_track, http): """Checks instance/project metadata for oslogin and update username.""" # Instance metadata has priority use_oslogin = False oslogin_enabled = _MetadataHasOsloginEnable(instance.metadata) if oslogin_enabled is None: project_metadata = project.commonInstanceMetadata oslogin_enabled = _MetadataHasOsloginEnable(project_metadata) if not oslogin_enabled: return requested_user, use_oslogin # Connect to the oslogin API and add public key to oslogin user account. oslogin = oslogin_client.OsloginClient(release_track) if not oslogin: log.warn( 'OS Login is enabled on Instance/Project, but is not availabe ' 'in the {0} version of gcloud.'.format(release_track.id)) return requested_user, use_oslogin public_key = self.keys.GetPublicKey().ToEntry(include_comment=True) user_email = gaia.GetAuthenticatedGaiaEmail(http) login_profile = oslogin.ImportSshPublicKey(user_email, public_key) use_oslogin = True # Get the username for the oslogin user. If the username is the same as the # default user, return that one. Otherwise, return the 'primary' username. # If no 'primary' exists, return the first username. oslogin_user = None for pa in login_profile.loginProfile.posixAccounts: oslogin_user = oslogin_user or pa.username if pa.username == requested_user: return requested_user, use_oslogin elif pa.primary: oslogin_user = pa.username log.warn( 'Using OS Login user [{0}] instead of default user [{1}]'.format( oslogin_user, requested_user)) return oslogin_user, use_oslogin
def Run(self, args): """Issues requests necessary for adding users.""" holder = base_classes.ComputeUserAccountsApiHolder(self.ReleaseTrack()) client = holder.client owner = args.owner if not owner: owner = gaia.GetAuthenticatedGaiaEmail(client.http) name = args.name if not name: name = gaia.MapGaiaEmailToDefaultAccountName(owner) user_ref = holder.resources.Parse( name, params={'project': properties.VALUES.core.project.GetOrFail}, collection='clouduseraccounts.users') user = client.MESSAGES_MODULE.User( name=user_ref.Name(), description=args.description, owner=owner, ) request = client.MESSAGES_MODULE.ClouduseraccountsUsersInsertRequest( project=user_ref.project, user=user) errors = [] responses = list( request_helper.MakeRequests( requests=[(client.users, 'Insert', request)], http=client.http, batch_url='https://www.googleapis.com/batch/', errors=errors)) if errors: utils.RaiseToolException( errors, error_message='Could not fetch resource:') return responses
def Run(self, args): start = time_util.CurrentTimeSec() # Set up Encryption utilities. openssl_executable = files.FindExecutableOnPath('openssl') if windows_encryption_utils: crypt = windows_encryption_utils.WinCrypt() elif openssl_executable: crypt = openssl_encryption_utils.OpensslCrypt(openssl_executable) else: raise utils.MissingDependencyError( 'Your platform does not support OpenSSL.') # Get Authenticated email address and default username. email = gaia.GetAuthenticatedGaiaEmail(self.http) if args.user: user = args.user else: user = gaia.MapGaiaEmailToDefaultAccountName(email) if args.name == user: raise utils.InvalidUserError( MACHINE_USERNAME_SAME_ERROR.format(user, args.name)) # Warn user (This warning doesn't show for non-interactive sessions). message = RESET_PASSWORD_WARNING.format(user) prompt_string = ( 'Would you like to set or reset the password for [{0}]'.format( user)) console_io.PromptContinue(message=message, prompt_string=prompt_string, cancel_on_no=True) log.status.Print( 'Resetting and retrieving password for [{0}] on [{1}]'.format( user, args.name)) # Get Encryption Keys. key = crypt.GetKeyPair() modulus, exponent = crypt.GetModulusExponentFromPublicKey( crypt.GetPublicKey(key)) # Create Windows key entry. self.windows_key_entry = self._ConstructWindowsKeyEntry( user, modulus, exponent, email) # Call ReadWriteCommad.Run() which will fetch the instance and update # the metadata (using the data in self.windows_key_entry). objects = super(ResetWindowsPassword, self).Run(args) updated_instance = list(objects)[0] # Retrieve and Decrypt the password from the serial console. enc_password = self._GetEncryptedPasswordFromSerialPort(modulus) password = crypt.DecryptMessage(key, enc_password) # Get External IP address. try: access_configs = updated_instance['networkInterfaces'][0][ 'accessConfigs'] external_ip_address = access_configs[0]['natIP'] except KeyError: log.warn(NO_IP_WARNING.format(updated_instance['name'])) external_ip_address = None # Check for old Windows credentials. if self.old_metadata_keys: log.warn( OLD_KEYS_WARNING.format(self.ref.Name(), self.ref.Name(), self.ref.zone, ','.join(self.old_metadata_keys))) log.info('Total Elapsed Time: {0}'.format(time_util.CurrentTimeSec() - start)) # The connection info resource. connection_info = { 'username': user, 'password': password, 'ip_address': external_ip_address } return connection_info
def Run(self, args): holder = base_classes.ComputeApiHolder(self.ReleaseTrack()) client = holder.client start = time_util.CurrentTimeSec() # Set up Encryption utilities. openssl_executable = files.FindExecutableOnPath('openssl') if windows_encryption_utils: crypt = windows_encryption_utils.WinCrypt() elif openssl_executable: crypt = openssl_encryption_utils.OpensslCrypt(openssl_executable) else: raise utils.MissingDependencyError( 'Your platform does not support OpenSSL.') # Get Authenticated email address and default username. email = gaia.GetAuthenticatedGaiaEmail(client.apitools_client.http) if args.user: user = args.user else: user = gaia.MapGaiaEmailToDefaultAccountName(email) if args.instance_name == user: raise utils.InvalidUserError( MACHINE_USERNAME_SAME_ERROR.format(user, args.instance_name)) # Warn user (This warning doesn't show for non-interactive sessions). message = RESET_PASSWORD_WARNING.format(user) prompt_string = ( 'Would you like to set or reset the password for [{0}]'.format( user)) console_io.PromptContinue(message=message, prompt_string=prompt_string, cancel_on_no=True) log.status.Print( 'Resetting and retrieving password for [{0}] on [{1}]'.format( user, args.instance_name)) # Get Encryption Keys. key = crypt.GetKeyPair() modulus, exponent = crypt.GetModulusExponentFromPublicKey( crypt.GetPublicKey(key)) # Create Windows key entry. self.windows_key_entry = self._ConstructWindowsKeyEntry( user, modulus, exponent, email) # Call ReadWriteCommad.Run() which will fetch the instance and update # the metadata (using the data in self.windows_key_entry). instance_ref = self.CreateReference(client, holder.resources, args) get_request = self.GetGetRequest(client, instance_ref) objects = client.MakeRequests([get_request]) new_object = self.Modify(client, objects[0]) # If existing object is equal to the proposed object or if # Modify() returns None, then there is no work to be done, so we # print the resource and return. if objects[0] == new_object: log.status.Print( 'No change requested; skipping update for [{0}].'.format( objects[0].name)) return objects updated_instance = client.MakeRequests( [self.GetSetRequest(client, instance_ref, new_object)])[0] # Retrieve and Decrypt the password from the serial console. enc_password = self._GetEncryptedPasswordFromSerialPort( client, instance_ref, modulus) password = crypt.DecryptMessage(key, enc_password) # Get External IP address. try: access_configs = updated_instance.networkInterfaces[ 0].accessConfigs external_ip_address = access_configs[0].natIP except (KeyError, IndexError) as _: log.warn(NO_IP_WARNING.format(updated_instance.name)) external_ip_address = None # Check for old Windows credentials. if self.old_metadata_keys: log.warn( OLD_KEYS_WARNING.format(instance_ref.instance, instance_ref.instance, instance_ref.zone, ','.join(self.old_metadata_keys))) log.info('Total Elapsed Time: {0}'.format(time_util.CurrentTimeSec() - start)) # The connection info resource. connection_info = { 'username': user, 'password': password, 'ip_address': external_ip_address } return connection_info