def Run(self, args): """Run 'service-management operations describe'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the operations.Get API call. Raises: HttpException: An http error response was received while executing api request. """ # If a user includes the leading "operations/", just strip it off if args.operation.startswith(OPTIONAL_PREFIX_TO_STRIP): args.operation = args.operation[len(OPTIONAL_PREFIX_TO_STRIP):] request = self.services_messages.ServicemanagementOperationsGetRequest( operationsId=args.operation, ) try: result = self.services_client.operations.Get(request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) if not args.full: log.warn('Response portion of Operation redacted. ' 'Use --full to see the whole Operation.\n') result.response = None return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management operations wait'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If successful, the response from the operations.Get API call. Raises: HttpException: An http error response was received while executing api request. """ result = services_util.WaitForOperation(args.operation, self.services_client) return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management disable'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the consumer settings API call. Raises: HttpException: An http error response was received while executing api request. """ # Shorten the patch request name for better readability patch_request = (self.services_messages. ServicemanagementServicesProjectSettingsPatchRequest) usage_settings = self.services_messages.UsageSettings( consumerEnableStatus=( self.services_messages.UsageSettings. ConsumerEnableStatusValueValuesEnum.DISABLED)) project_settings = self.services_messages.ProjectSettings( usageSettings=usage_settings) request = patch_request( serviceName=args.service, consumerProjectId=args.consumer_project, projectSettings=project_settings, updateMask='usage_settings.consumer_enable_status') try: # TODO(user): Add support for Operation completion, and --async flag result = self.services_client.services_projectSettings.Patch( request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management enable'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the consumer settings API call. Raises: HttpException: An http error response was received while executing api request. """ # TODO(b/25392897): Add support for Operation completion, and --async flag result = enable_api.EnableServiceApiCall(self.services_client, self.services_messages, args.consumer_project, args.service) return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management delete'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the Delete API call (or None if cancelled). Raises: HttpException: An http error response was received while executing api request. """ # If the user doesn't specify --force, prompt with a warning before # continuing. if not args.force: continue_prompt_response = console_io.PromptContinue( message='Are you sure? This will permanently delete the service ' 'configuration and all of the associated consumer ' 'information. This CANNOT be undone!', prompt_string='Continue anyway', default=True, throw_if_unattended=True) if not continue_prompt_response: return request = self.services_messages.ServicemanagementServicesDeleteRequest( serviceName=args.service, ) try: result = self.services_client.services.Delete(request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management remove-visibility-label'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the consumer settings API call. Raises: HttpException: An http error response was received while executing api request. ToolException: The label that was supposed to be removed is not currently set for the given service and consumer project. """ # Shorten the request names for better readability get_request = (self.services_messages. ServicemanagementServicesProjectSettingsGetRequest) patch_request = (self.services_messages. ServicemanagementServicesProjectSettingsPatchRequest) # TODO(user): change this to a conditional update once the service # supports it. Until then... # # 1. Get the current labels request = get_request( serviceName=args.service, consumerProjectId=args.consumer_project, view=get_request.ViewValueValuesEnum.PRODUCER_VIEW, ) try: response = self.services_client.services_projectSettings.Get( request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) # 2. Remove the provided label from the current labels if it exists visibility_labels = [] if (response.visibilitySettings and response.visibilitySettings.visibilityLabels): visibility_labels.extend( response.visibilitySettings.visibilityLabels) if args.label in visibility_labels: visibility_labels.remove(args.label) else: raise exceptions.ToolException(( 'Label {0} is not currently applied to service {1} for consumer ' 'project {2}').format(args.label, args.service, args.consumer_project)) visibility_settings = self.services_messages.VisibilitySettings( visibilityLabels=visibility_labels) project_settings = self.services_messages.ProjectSettings( visibilitySettings=visibility_settings, ) request = patch_request( serviceName=args.service, consumerProjectId=args.consumer_project, projectSettings=project_settings, updateMask='visibility_settings.visibility_labels') try: # TODO(user): Add support for Operation completion, and --async flag result = self.services_client.services_projectSettings.Patch( request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management add-visibility-label'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the consumer settings API call. Raises: HttpException: An http error response was received while executing api request. """ # Shorten the request names for better readability get_request = (self.services_messages. ServicemanagementServicesProjectSettingsGetRequest) patch_request = (self.services_messages. ServicemanagementServicesProjectSettingsPatchRequest) # TODO(user): change this to a conditional update once the service # supports it. Until then... # # 1. Get the current labels request = get_request( serviceName=args.service, consumerProjectId=args.consumer_project, view=get_request.ViewValueValuesEnum.PRODUCER_VIEW, ) try: response = self.services_client.services_projectSettings.Get( request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) # 2. Add the new label to the current labels visibility_labels = [args.label] if (response.visibilitySettings and response.visibilitySettings.visibilityLabels): visibility_labels.extend( response.visibilitySettings.visibilityLabels) visibility_settings = self.services_messages.VisibilitySettings( visibilityLabels=visibility_labels) project_settings = self.services_messages.ProjectSettings( visibilitySettings=visibility_settings, ) request = patch_request( serviceName=args.service, consumerProjectId=args.consumer_project, projectSettings=project_settings, updateMask='visibility_settings.visibility_labels') try: # TODO(user): Add support for Operation completion, and --async flag result = self.services_client.services_projectSettings.Patch( request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management deploy'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the Update API call. Raises: HttpException: An http error response was received while executing api request. """ with open(args.service_config_file, 'r') as f: config_contents = f.read() # Try to load the file as JSON. If that fails, try YAML. service_config_dict = services_util.LoadJsonOrYaml(config_contents) if not service_config_dict: raise exceptions.BadFileException( 'Could not read JSON or YAML from service config file %s.' % args.service_config_file) # Check if the provided file is a swagger spec that needs to be converted # to Google Service Configuration if 'swagger' in service_config_dict: swagger_file = self.services_messages.File( contents=config_contents, path=args.service_config_file) # TODO(user): Add support for swagger file references later # This requires the API to support multiple files first. b/23353397 swagger_spec = self.services_messages.SwaggerSpec( swaggerFiles=[swagger_file]) request = self.services_messages.ConvertConfigRequest( swaggerSpec=swagger_spec, ) try: response = self.services_client.v1.ConvertConfig(request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) diagnostics = response.diagnostics if diagnostics: kind = self.services_messages.Diagnostic.KindValueValuesEnum for diagnostic in diagnostics: logger = log.error if diagnostic.kind == kind.ERROR else log.warning logger('{l}: {m}'.format(l=diagnostic.location, m=diagnostic.message)) service_config = response.serviceConfig else: # If not Swagger, assume that we are dealing with Google Service Config service_config = encoding.JsonToMessage( self.services_messages.Service, config_contents) managed_service = self.services_messages.ManagedService( serviceConfig=service_config, serviceName=service_config.name) # Set the serviceConfig producerProjectId if it is not already set if not managed_service.serviceConfig.producerProjectId: managed_service.serviceConfig.producerProjectId = self.project request = self.services_messages.ServicemanagementServicesUpdateRequest( serviceName=managed_service.serviceName, managedService=managed_service, ) try: result = self.services_client.services.Update(request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) # Remove the response portion of the resulting operation since # it can be extremely large. result.response = None return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management add-quota-override'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the consumer settings API call. Raises: HttpException: An http error response was received while executing api request. """ # Shorten the name for better readability patch_request = (self.services_messages. ServicemanagementServicesProjectSettingsPatchRequest) # TODO(user): What happens when --quota-limit is not specified? # Should there be a default value? Should it be required? quota_override = self.services_messages.QuotaLimitOverride( limit=args.quota_limit) # Create a QuotaSettings object to store the added override if args.consumer: overrides = self.services_messages.QuotaSettings.ConsumerOverridesValue( ) overrides.additionalProperties.append( self.services_messages.QuotaSettings.ConsumerOverridesValue. AdditionalProperty(key=args.quota_limit_key, value=quota_override)) quota_settings = self.services_messages.QuotaSettings( consumerOverrides=overrides) elif args.producer: overrides = self.services_messages.QuotaSettings.ProducerOverridesValue( ) overrides.additionalProperties.append( self.services_messages.QuotaSettings.ProducerOverridesValue. AdditionalProperty(key=args.quota_limit_key, value=quota_override)) quota_settings = self.services_messages.QuotaSettings( producerOverrides=overrides) project_settings = self.services_messages.ProjectSettings( quotaSettings=quota_settings, ) update_mask = 'quota_settings.{0}_overrides[{1}]'.format( 'consumer' if args.consumer else 'producer', args.quota_limit_key) request = patch_request(serviceName=args.service, consumerProjectId=args.consumer_project, projectSettings=project_settings, updateMask=update_mask) try: # TODO(user): Add support for Operation completion, and --async flag result = self.services_client.services_projectSettings.Patch( request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management remove-quota-override'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the consumer settings API call. Raises: HttpException: An http error response was received while executing api request. """ # Shorten the request names for better readability get_request = (self.services_messages. ServicemanagementServicesProjectSettingsGetRequest) patch_request = (self.services_messages. ServicemanagementServicesProjectSettingsPatchRequest) views = services_util.GetCallerViews() # Get the current list of quota settings to see if the quota override # exists in the first place. request = get_request( serviceName=args.service, consumerProjectId=args.consumer_project, view=views.get(args.view), ) try: response = self.services_client.services_projectSettings.Get( request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) # Check to see if the quota override was present in the first place. override_present = False overrides = None if args.consumer: if response.quotaSettings and response.quotaSettings.consumerOverrides: overrides = response.quotaSettings.consumerOverrides else: overrides = (self.services_messages.QuotaSettings. ConsumerOverridesValue()) elif args.producer: if response.quotaSettings and response.quotaSettings.producerOverrides: overrides = response.quotaSettings.producerOverrides else: overrides = (self.services_messages.QuotaSettings. ProducerOverridesValue()) if overrides: for override in overrides.additionalProperties: if override.key == args.quota_limit_key: override_present = True break if not override_present: log.warn('No quota override found for "{0}"'.format( args.quota_limit_key)) return project_settings = self.services_messages.ProjectSettings( quotaSettings=self.services_messages.QuotaSettings(), ) update_mask = 'quota_settings.{0}_overrides[{1}]'.format( 'consumer' if args.consumer else 'producer', args.quota_limit_key) request = patch_request(serviceName=args.service, consumerProjectId=args.consumer_project, projectSettings=project_settings, updateMask=update_mask) try: # TODO(user): Add support for Operation completion, and --async flag result = self.services_client.services_projectSettings.Patch( request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) return services_util.ProcessOperationResult(result)
def Run(self, args): """Run 'service-management deploy'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the Update API call. Raises: HttpException: An http error response was received while executing api request. """ with open(args.service_config_file, 'r') as f: config_contents = f.read() # Try to load the file as JSON. If that fails, try YAML. service_config_dict = services_util.LoadJsonOrYaml(config_contents) if not service_config_dict: raise exceptions.BadFileException( 'Could not read JSON or YAML from service config file %s.' % args.service_config_file) # Check if the provided file is a swagger spec that needs to be converted # to Google Service Configuration if 'swagger' in service_config_dict: swagger_file = self.services_messages.File( contents=config_contents, path=args.service_config_file) # TODO(user): Add support for swagger file references later # This requires the API to support multiple files first. b/23353397 swagger_spec = self.services_messages.SwaggerSpec( swaggerFiles=[swagger_file]) request = self.services_messages.ConvertConfigRequest( swaggerSpec=swagger_spec, ) try: response = self.services_client.v1.ConvertConfig(request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) diagnostics = response.diagnostics if diagnostics: kind = self.services_messages.Diagnostic.KindValueValuesEnum for diagnostic in diagnostics: logger = log.error if diagnostic.kind == kind.ERROR else log.warning logger('{l}: {m}'.format(l=diagnostic.location, m=diagnostic.message)) service_config = response.serviceConfig else: # If not Swagger, assume that we are dealing with Google Service Config service_config = encoding.JsonToMessage( self.services_messages.Service, config_contents) managed_service = self.services_messages.ManagedService( serviceConfig=service_config, serviceName=service_config.name) # Set the serviceConfig producerProjectId if it is not already set if not managed_service.serviceConfig.producerProjectId: managed_service.serviceConfig.producerProjectId = self.project request = self.services_messages.ServicemanagementServicesUpdateRequest( serviceName=managed_service.serviceName, managedService=managed_service, ) try: result = self.services_client.services.Update(request) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(services_util.GetError(error)) # Validate the response type to avoid surprise errors below services_util.RaiseIfResultNotTypeOf(result, self.services_messages.Operation) service_name = None config_id = None # Fish the serviceName and serviceConfig.id fields from the proto Any # that is returned in result.response for prop in result.response.additionalProperties: if prop.key == 'serviceName': service_name = prop.value.string_value elif prop.key == 'serviceConfig': for item in prop.value.object_value.properties: if item.key == 'id': config_id = item.value.string_value break if service_name and config_id: log.status.Print( ('\nService Configuration with version "{0}" uploaded ' 'for service "{1}"\n').format(config_id, service_name)) else: log.error('Failed to retrieve Service Name and ' 'Service Configuration Version') # Remove the response portion of the resulting operation since # it can be extremely large. result.response = None return services_util.ProcessOperationResult(result)