Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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)
Пример #7
0
    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)
Пример #8
0
    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)
Пример #11
0
    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)