def Run(self, args): """Runs 'operations wait'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Raises: ServiceRegistryError: One or more operations finished with error(s) or the wait timed out. """ client = self.context['serviceregistry_client'] messages = self.context['serviceregistry_messages'] project = properties.VALUES.core.project.Get(required=True) writer = write_support.ServiceRegistryClient(client, messages, project) failed_operations = [] for operation in args.operations: try: # TODO(b/27272474): need to use resources.Parse with write_support writer.wait_for_operation(operation) except write_support.ServiceRegistryError as error: log.Print(error) failed_operations.append(operation) if failed_operations: raise write_support.ServiceRegistryError( 'There were operations with errors: {0}'.format( failed_operations)) log.Print('All operations completed successfully.')
def Run(self, args): """Runs 'operations wait'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Raises: ServiceRegistryError: One or more operations finished with error(s) or the wait timed out. """ client = self.context[constants.CLIENT] resources = self.context[constants.RESOURCES] writer = write_support.ServiceRegistryClient(client, resources) failed_operations = [] for operation in args.operations: operation_ref = resources.Parse( operation, collection=constants.OPERATIONS_COLLECTION) try: writer.wait_for_operation(operation_ref) except write_support.ServiceRegistryError as error: log.Print(error) failed_operations.append(operation) if failed_operations: raise write_support.ServiceRegistryError( 'There were operations with errors: {0}'.format( failed_operations)) log.Print('All operations completed successfully.')
def Run(self, args): self._CheckPlatform() conn_context = connection_context.GetConnectionContext( args, flags.Product.RUN, self.ReleaseTrack()) service_ref = args.CONCEPTS.service.Parse() flags.ValidateResource(service_ref) with serverless_operations.Connect(conn_context) as client: serv = client.GetService(service_ref) if not serv: raise exceptions.ArgumentError('Cannot find service [{}]'.format( service_ref.servicesId)) bind = '127.0.0.1:' + (args.port if args.port else '8080') host = self._GetUrl(serv, args.tag, service_ref.servicesId) command_executor = proxy.ProxyWrapper() log.Print('Proxying service [{}] in region [{}] locally...'.format( service_ref.servicesId, serv.region)) log.Print('http://{} proxies to {}'.format(bind, host)) if args.token: response = command_executor(host=host, token=args.token, bind=bind) else: # Keep restarting the proxy with fresh token before the token expires (1h) # until hitting a failure. while True: response = command_executor(host=host, token=_GetFreshIdToken(), bind=bind, duration='55m') if response.failed: break return self._DefaultOperationResponseHandler(response)
def _LogStructuredStdOut(line): """Parse and log stdout text as an OutputMessage. Attempts to parse line into an OutputMessage and log any resource output or status messages accordingly. If message can not be parsed, raises a StructuredOutputError. Args: line: string, line of output read from stdout. Returns: Tuple: (str, object): Tuple of parsed OutputMessage body and processed resources or None. Raises: StructuredOutputError, if line can not be parsed. """ msg = None resources = None if line: msg_rec = line.strip() msg = ReadStructuredOutput(msg_rec) # if there are resources, log the message body to stderr # process message resource_body with any supplied resource_processors # then log the processed message resource_body to stdout if msg.resource_body: log.status.Print(msg.body) log.Print(msg.resource_body) else: # Otherwise just log the message body to stdout log.Print(msg.body) return (msg.body, resources)
def Display(self, args, info): log.Print(info) if args.show_log and info.logs.last_log: log.Print('\nContents of log file: [{0}]\n' '==========================================================\n' '{1}\n\n' .format(info.logs.last_log, info.logs.LastLogContents()))
def Display(self, args, info): if not info: return if not args.show_log: log.Print(info) elif info.logs.last_log: log.Print( '\nContents of log file: [{0}]\n' '==========================================================\n' '{1}\n\n'.format(info.logs.last_log, info.logs.LastLogContents()))
def Run(self, args): api = api_factory.get_api(storage_url.ProviderPrefix.GCS) service_agent = api.get_service_agent() if args.authorize_cmek: requests.AddCryptoKeyPermission(args.authorize_cmek, 'serviceAccount:' + service_agent) log.Print( 'Authorized project {} to encrypt and decrypt with key:\n{}'. format(properties.VALUES.core.project.Get(), args.authorize_cmek)) else: log.Print(service_agent)
def Display(self, args, results): """Display prints information about what just happened to stdout. Args: args: The same as the args in Run. results: The results of the Run() method. """ for resource in results: if args.limit: log.Print(self.GetInstanceNameFromUrl(resource)) else: log.Print(resource)
def Run(self, args): log.Print(args.verbosity) log.Print(args.group_required_test) log.Print(args.group_not_required_test) log.Print(args.command_required_test) log.Print(args.command_not_required_test) log.Print(args.config) log.Print(args.positional) log.Print('=====') log.Print('\n'.join( '{}={}'.format(name, value) for name, value in sorted(six.iteritems(args.GetSpecifiedArgs())))) log.Print('=====')
def Display(self, args, readgroupset): """This method is called to print the result of the Run() method. Args: args: The arguments that command was run with. readgroupset: The value returned from the Run() method. """ if readgroupset: log.Print('Updated readgroupset {0}'.format(readgroupset.id)) if args.name: log.Print(' name: {0}'.format(readgroupset.name)) if args.reference_set_id: log.Print(' referenceSetId: {0}'.format( readgroupset.referenceSetId))
def Run(self, args): """Run 'instance-groups delete'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ log.warn('Please use instead [gcloud compute instance-groups ' 'unmanaged delete].') client = self.context['instanceGroupsClient'] project = properties.VALUES.core.project.Get(required=True) for group_name in args.name: request = client.delete(project=project, zone=args.zone, resourceView=group_name) try: request.execute() log.Print('Instance group {0} deleted.'.format(group_name)) except errors.HttpError as error: raise exceptions.HttpException(util.GetError(error)) except errors.Error as error: raise exceptions.ToolException(error)
def WaitForRestoreToFinish(restore, max_wait_ms=1800000, exponential_sleep_multiplier=1.4, jitter_ms=1000, wait_ceiling_ms=180000, status_update=_RestoreStatusUpdate, sleep_ms=2000, client=None): """Waits for restore resource to be terminal state.""" if not client: client = GetClientInstance() messages = GetMessagesModule() retryer = retry.Retryer( max_retrials=None, max_wait_ms=max_wait_ms, exponential_sleep_multiplier=exponential_sleep_multiplier, jitter_ms=jitter_ms, wait_ceiling_ms=wait_ceiling_ms, status_update_func=status_update) restore_poller = RestorePoller(client, messages) try: result = retryer.RetryOnResult( func=restore_poller.Poll, args=(restore,), should_retry_if=restore_poller.IsNotDone, sleep_ms=sleep_ms) log.Print('Restore completed. Restore state: {0}'.format(result.state)) return result # No need to catch MaxRetrialsException since we retry unlimitedly. except retry.WaitException: raise WaitForCompletionTimeoutError( 'Timeout waiting for restore to complete. Restore is not completed, use "gcloud container backup-restore restores describe" command to check restore status.' )
def Run(self, args): """Run 'replicapool resize'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: An object representing the service response obtained by the Resize API if the Resize call was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ client = self.context['replicapool'] project = properties.VALUES.core.project.Get(required=True) request = client.pools().resize(projectName=project, zone=args.zone, poolName=args.pool, numReplicas=args.new_size) try: request.execute() log.Print('Replica pool {0} is being resized.'.format(args.pool)) except errors.HttpError as error: raise exceptions.HttpException(util.GetError(error)) except errors.Error as error: raise exceptions.ToolException(error)
def Run(self, args): """Run 'managed-instance-groups delete'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. Returns: response: the response returned by the service, expected to be a zonal operation resource """ log.warn('Please use instead [gcloud compute instance-groups ' 'managed delete].') client = self.context['managedInstanceGroupsClient'] project = properties.VALUES.core.project.Get(required=True) request = client.instanceGroupManagers().delete( project=project, zone=args.zone, instanceGroupManager=args.group) try: response = request.execute() log.Print(('Managed instance group {0} is being deleted. ' 'Operation: {1}').format(args.group, response['name'])) return response except errors.HttpError as error: raise exceptions.HttpException(util.GetError(error)) except errors.Error as error: raise exceptions.ToolException(error)
def Run(self, args): """Create a GCP repository to the current directory. Args: args: argparse.Namespace, the arguments this command is run with. Returns: (sourcerepo_v1_messages.Repo) The created respository. Raises: ToolException: on project initialization errors, on missing billing account, and when the repo name is already in use. """ res = sourcerepo.ParseRepo(args.repository_name) # check that the name does not have forbidden characters. # we'd like to do this by putting the validator in the flag type, but # we cannot for now because it needs to work on the parsed name. flags.REPO_NAME_VALIDATOR(res.Name()) source_handler = sourcerepo.Source() try: repo = source_handler.CreateRepo(res) if repo: log.CreatedResource(res.Name()) log.Print('You may be billed for this repository. ' 'See {url} for details.'.format(url=_BILLING_URL)) return repo except exceptions.HttpError as error: exc = c_exc.HttpException(error) exc.error_format = _ERROR_FORMAT if 'API is not enabled' in unicode(exc): link = _LINK_FORMAT.format( project=properties.VALUES.core.project.GetOrFail()) exc.error_format += link raise exc
def Run(self, args): """This is what gets called when the user runs this command. Args: args: an argparse namespace, All the arguments that were provided to this command invocation. Raises: HttpException: An http error response was received while executing api request. Returns: None """ prompt_message = ( 'Deleting dataset {0} will delete all objects in the dataset. ' 'Deleted datasets can be recovered with the "restore" command ' 'up to one week after the deletion occurs.').format(args.id) if not console_io.PromptContinue(message=prompt_message): raise GenomicsError('Deletion aborted by user.') apitools_client = self.context[commands.GENOMICS_APITOOLS_CLIENT_KEY] genomics_messages = self.context[commands.GENOMICS_MESSAGES_MODULE_KEY] dataset = genomics_messages.GenomicsDatasetsDeleteRequest( datasetId=str(args.id), ) apitools_client.datasets.Delete(dataset) log.Print('Deleted dataset {0}'.format(args.id))
def __enter__(self): """Creates a fake metadata environment.""" log.Print('Surfacing credentials via {metadata}...'.format( metadata=self.name)) # Use JSON to inject structured data into the YAML since it # is an effective way to create indentation-insensitive YAML # NOTE: YAML 1.2 is a superset of JSON. with open(self.manifest_file, 'w') as f_out: f_out.write( MANIFEST_FORMAT.format( attributes=json.dumps(self._options.attributes), project_id=self._options.project, email=self._options.account, scopes=json.dumps(self._options.scopes))) # We refresh credentials in case a pull is needed. docker.UpdateDockerCredentials(constants.DEFAULT_REGISTRY) result = docker.Execute([ 'run', '-d', '--name', self.name, '-v', self.manifest_file + ':' + self.manifest_file, self.image, # Arguments to the //cloud/containers/metadata binary, # which is the entrypoint: '-manifest_file=' + self.manifest_file, '-refresh_token=' + self._options.credential.refresh_token ]) if result != 0: raise exceptions.Error('Unable to launch fake-metadata.') return self
def Display(self, unused_args, result): """Display prints information about what just happened to stdout. Args: unused_args: The same as the args in Run. result: an Operation (may be in progress or completed) to display or a list of Resources, if a synchronous preview or create completed. Raises: ValueError: if result is not a list of Resources or an Operation """ messages = self.context['deploymentmanager-messages'] if isinstance(result, messages.Operation): resource_printer.Print(resources=result, print_format=unused_args.format or 'yaml', out=log.out) elif isinstance(result, list) and not result: log.Print('No Deployments were found in your project!') elif isinstance(result, list) and isinstance(result[0], messages.Resource): list_printer.PrintResourceList('deploymentmanagerv2.resources', result) else: raise ValueError( 'result must be an Operation or list of Resources')
def Run(self, args): """Creates a database for a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the create operation if the create was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ client = api_util.SqlClient(api_util.API_VERSION_DEFAULT) sql_client = client.sql_client sql_messages = client.sql_messages validate.ValidateInstanceName(args.instance) instance_ref = client.resource_parser.Parse( args.instance, params={'project': properties.VALUES.core.project.GetOrFail}, collection='sql.instances') new_database = sql_messages.Database(project=instance_ref.project, instance=instance_ref.instance, name=args.database, charset=args.charset, collation=args.collation) # TODO(b/36052521): Move this API call logic per b/35386183. result_operation = sql_client.databases.Insert(new_database) operation_ref = client.resource_parser.Create( 'sql.operations', operation=result_operation.name, project=instance_ref.project) if args. async: result = sql_client.operations.Get( sql_messages.SqlOperationsGetRequest( project=operation_ref.project, operation=operation_ref.operation)) else: try: operations.OperationsV1Beta4.WaitForOperation( sql_client, operation_ref, 'Creating Cloud SQL database') except errors.OperationError: log.Print( 'Database creation failed. Check if a database named {0} ' 'already exists.'.format(args.database)) # Must fail with non-zero exit code on API request failure. # TODO(b/36051979): Refactor when b/35156765 is resolved. raise result = new_database log.CreatedResource(args.database, kind='database', async=args. async)
def Run(self, args): command_list = args.command.split(' ') if args.command else ['bash -l'] project = properties.VALUES.core.project.Get() connection_info = util.PrepareEnvironment(args) command = ssh.SSHCommand( remote=ssh.Remote(host=connection_info.host, user=connection_info.user), port=six.text_type(connection_info.port), identity_file=connection_info.key, remote_command=(['DEVSHELL_PROJECT_ID=' + project] if project else []) + command_list, extra_flags=args.ssh_flag, tty=not args.command, options={'StrictHostKeyChecking': 'no'}, ) if args.dry_run: log.Print(' '.join(command.Build(connection_info.ssh_env))) else: self.done = threading.Event() thread = threading.Thread(target=self.Reauthorize, args=()) thread.daemon = True thread.start() command.Run(connection_info.ssh_env) self.done.set()
def Run(self, args): req = self._CreateDecryptRequest(args) client = cloudkms_base.GetClientInstance() try: resp = client.projects_locations_keyRings_cryptoKeys.Decrypt(req) # Intercept INVALID_ARGUMENT errors related to checksum verification to # present a user-friendly message. All other errors are surfaced as-is. except apitools_exceptions.HttpBadRequestError as error: e2e_integrity.ProcessHttpBadRequestError(error) if self._PerformIntegrityVerification(args): self._VerifyResponseIntegrityFields(req, resp) try: if resp.plaintext is None: with files.FileWriter(args.plaintext_file): # to create an empty file pass log.Print('Decrypted file is empty') else: log.WriteToFileOrStdout(args.plaintext_file, resp.plaintext, binary=True, overwrite=True) except files.Error as e: raise exceptions.BadFileException(e)
def __enter__(self): """Makes FakeMetadata usable with "with" statement.""" log.Print('Surfacing credentials via {metadata}...'.format( metadata=self._name)) manifest = tempfile.NamedTemporaryFile(suffix='.yaml').name with open(manifest, 'w') as f_out: f_out.write( MANIFEST_FORMAT.format( attributes=json.dumps(self._options.attributes), project_id=self._options.project, email=self._options.account, scopes=json.dumps(self._options.scopes))) # We refresh credentials in case a pull is needed. docker_lib.UpdateDockerCredentials(const_lib.DEFAULT_REGISTRY) subprocess.check_call( [ 'docker', 'run', '-d', '--name', self._name, '-v', manifest + ':' + manifest, self.image, # Arguments to the //cloud/containers/metadata binary, # which is the entrypoint: '-manifest_file=' + manifest, '-refresh_token=' + self._options.credential.refresh_token ], stdin=None, stdout=None, stderr=None) return self
def Display(self, unused_args, deployment): """Display prints information about what just happened to stdout. Args: unused_args: The same as the args in Run. deployment: a Deployment to print Raises: ValueError: if result is None or not a deployment """ client = self.context['deploymentmanager-client'] messages = self.context['deploymentmanager-messages'] if not isinstance(deployment, messages.Deployment): raise ValueError('result must be a Deployment') # Get resources belonging to the deployment to display project = properties.VALUES.core.project.Get(required=True) resources = None try: response = client.resources.List( messages.DeploymentmanagerResourcesListRequest( project=project, deployment=deployment.name)) resources = response.resources except apitools_base.HttpError: pass # Couldn't get resources, skip adding them to the table. resource_printer.Print(resources=deployment, print_format=unused_args.format or 'yaml', out=log.out) if resources: log.Print('resources:') list_printer.PrintResourceList('deploymentmanagerv2.resources', resources)
def _PrintQuestion(self): """Prints question and lists all choices.""" # index choices from 1 question_repr = self._FormatQuestion( indexes=range(1, len(self._choices) + 1)) log.Print(question_repr)
def Run(self, args): """Run 'replicapool replicas delete'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Raises: HttpException: An http error response was received while executing api request. ToolException: An error other than http error occurred while executing the command. """ client = self.context['replicapool'] project = properties.VALUES.core.project.Get(required=True) delete_body = {} if args.abandon_instance: delete_body['abandonInstance'] = args.abandon_instance is True request = client.replicas().delete(projectName=project, zone=args.zone, poolName=args.pool, replicaName=args.replica, body=delete_body) try: request.execute() log.Print('Replica {0} in pool {1} is being deleted.'.format( args.replica, args.pool)) except errors.HttpError as error: raise exceptions.HttpException(util.GetError(error)) except errors.Error as error: raise exceptions.ToolException(error)
def __exit__(self, type, value, traceback): """Makes FakeMetadata usable with "with" statement.""" log.Print('Shutting down metadata credentials') subprocess.check_call(['docker', 'rm', '-f', self._name], stdin=None, stdout=None, stderr=None)
def _OpenLocalTcpSocket(self): """Attempt to open a local socket listening on specified host and port.""" s = None for res in socket.getaddrinfo( self._local_host, self._local_port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE): af, socktype, proto, unused_canonname, socket_address = res try: s = socket.socket(af, socktype, proto) except socket.error: s = None continue try: s.bind(socket_address) s.listen(1) break except (EnvironmentError, socket.error): try: s.close() except socket.error: pass s = None continue if s is None: raise UnableToOpenPortError('Unable to open socket on port [%d].' % self._local_port) log.Print('Listening on port [%d].' % self._local_port) return s
def Display(self, unused_args, result): """Display prints information about what just happened to stdout. Args: unused_args: The same as the args in Run. result: a generator of Manifests, where each dict has a name attribute. Raises: ValueError: if result is None or not a generator """ empty_generator = True for manifest in result: empty_generator = False log.Print(manifest.name) if empty_generator: log.Print('No Manifests were found in your deployment!')
def Display(self, args, deleted_list): """This method is called to print the result of the Run() method. Args: args: The arguments that command was run with. deleted_list: The captures deleted by the Run() method. """ log.Print('Deleted {0} captures.'.format(len(deleted_list)))
def __exit__(self, type, value, traceback): """Cleans up a fake metadata environment.""" log.Print('Shutting down metadata credentials') result = docker.Execute(['rm', '-f', self.name]) if result != 0: raise exceptions.Error('Unable to tear down fake-metadata.') # Clean up the temporary file. os.remove(self.manifest_file)