Ejemplo n.º 1
0
  def Run(self, args):
    apis = apis_client.ApiClient()
    api_configs = api_configs_client.ApiConfigClient()
    ops = operations_client.OperationsClient()

    api_config_ref = args.CONCEPTS.api_config.Parse()
    api_ref = api_config_ref.Parent()

    service_name = common_flags.ProcessApiRefToEndpointsService(api_ref)

    # Check if OP service exists with Api name, create if not, activate it
    if not endpoints.DoesServiceExist(service_name):
      endpoints.CreateService(service_name, api_ref.projectsId)

    # Check to see if Api exists, create if not
    if not apis.DoesExist(api_ref):
      res = apis.Create(api_ref, service_name)
      operations_util.PrintOperationResult(
          res.name, ops,
          wait_string='Waiting for API [{}] to be created'.format(
              api_ref.Name()))

    # Create OP ServiceConfig and Rollout

    # Creating a suffix to avoid name collisions on ServiceConfig IDs.
    suffix = '-' + str(int(time.time()))
    length = MAX_SERVICE_CONFIG_ID_LENGTH - len(suffix)
    config_id = api_config_ref.Name()[:length] + suffix

    if args.openapi_spec:
      service_config_id = self.__PushOpenApiServiceFile(
          args.openapi_spec,
          service_name,
          api_config_ref.projectsId,
          config_id=config_id)
    else:
      service_config_id = self.__PushGrpcConfigFiles(
          args.grpc_files,
          service_name,
          api_config_ref.projectsId,
          config_id=config_id)
    rollout = endpoints.CreateRollout(service_config_id, service_name)

    # Create ApiConfig object using the service config and rollout
    # Only piece affected by async right now
    resp = api_configs.Create(api_config_ref,
                              rollout['rolloutId'],
                              labels=args.labels,
                              display_name=args.display_name,
                              backend_auth=args.backend_auth_service_account)

    wait = 'Waiting for API Config [{}] to be created for API [{}]'.format(
        api_config_ref.Name(), api_ref.Name())

    return operations_util.PrintOperationResult(
        resp.name,
        ops,
        service=api_configs.service,
        wait_string=wait,
        is_async=args.async_)
Ejemplo n.º 2
0
    def Run(self, args):
        apis = apis_client.ApiClient()
        api_configs = api_configs_client.ApiConfigClient()
        ops = operations_client.OperationsClient()

        api_config_ref = args.CONCEPTS.api_config.Parse()
        api_ref = api_config_ref.Parent()

        service_name = '{}.apigateway.{}.cloud.goog'.format(
            api_ref.Name(), api_ref.projectsId)

        # Check if OP service exists with Api name, create if not, activate it
        if not endpoints.DoesServiceExist(service_name):
            endpoints.CreateService(service_name, api_ref.projectsId)

        # Check to see if Api exists, create if not
        if not apis.DoesExist(api_ref):
            res = apis.Create(api_ref, service_name)
            ops.GetOperationResult(res)

        # Create OP ServiceConfig and Rollout
        if args.openapi_spec:
            service_config_id = self.__PushOpenApiServiceFile(
                args.openapi_spec,
                service_name,
                api_config_ref.projectsId,
                config_id=api_config_ref.Name())
        else:
            service_config_id = self.__PushGrpcConfigFiles(
                args.grpc_files,
                service_name,
                api_config_ref.projectsId,
                config_id=api_config_ref.Name())
        rollout = endpoints.CreateRollout(service_config_id, service_name)

        # Create ApiConfig object using the service config and rollout
        # Only piece affected by async right now
        resp = api_configs.Create(
            api_config_ref,
            rollout['rolloutId'],
            labels=args.labels,
            display_name=args.display_name,
            backend_auth=args.backend_auth_service_account)

        return ops.GetOperationResult(resp, is_async=args.async_)
Ejemplo n.º 3
0
  def Run(self, args):
    api_ref = args.CONCEPTS.api.Parse()
    service_name = common_flags.ProcessApiRefToEndpointsService(api_ref)
    api_client = apis.ApiClient()

    # Check if OP service exists with Api name, create if not, activate it
    if not endpoints.DoesServiceExist(service_name):
      endpoints.CreateService(service_name, api_ref.projectsId)

    resp = api_client.Create(api_ref,
                             service_name,
                             labels=args.labels,
                             display_name=args.display_name)

    return operations_util.PrintOperationResult(
        resp.name,
        ops.OperationsClient(),
        service=api_client.service,
        wait_string='Waiting for API [{}] to be created'.format(api_ref.Name()),
        is_async=args.async_)
Ejemplo n.º 4
0
    def Run(self, args):
        """Run 'endpoints services deploy'.

    Args:
      args: argparse.Namespace, The arguments that this command was invoked
          with.

    Returns:
      The response from the Update API call.

    Raises:
      BadFileExceptionn: if the provided service configuration files are
          invalid or cannot be read.
    """
        messages = services_util.GetMessagesModule()
        client = services_util.GetClientInstance()

        file_types = messages.ConfigFile.FileTypeValueValuesEnum
        self.service_name = self.service_version = config_contents = None
        config_files = []

        self.validate_only = args.validate_only

        # TODO(b/77867100): remove .proto support and deprecation warning.
        give_proto_deprecate_warning = False

        # If we're not doing a validate-only run, we don't want to output the
        # resource directly unless the user specifically requests it using the
        # --format flag. The Epilog will show useful information after deployment
        # is complete.
        if not self.validate_only and not args.IsSpecified('format'):
            args.format = 'none'

        for service_config_file in args.service_config_file:
            config_contents = services_util.ReadServiceConfigFile(
                service_config_file)

            if services_util.FilenameMatchesExtension(
                    service_config_file, ['.json', '.yaml', '.yml']):
                # 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 calliope_exceptions.BadFileException(
                        'Could not read JSON or YAML from service config file '
                        '[{0}].'.format(service_config_file))

                if 'swagger' in service_config_dict:
                    if 'host' not in service_config_dict:
                        raise calliope_exceptions.BadFileException((
                            'Malformed input. Found Swagger service config in file [{}], '
                            'but no host was specified. Add a host specification to the '
                            'config file.').format(service_config_file))
                    if not self.service_name and service_config_dict.get(
                            'host'):
                        self.service_name = service_config_dict.get('host')

                    # Always use YAML for Open API because JSON is a subset of YAML.
                    config_files.append(
                        self.MakeConfigFileMessage(config_contents,
                                                   service_config_file,
                                                   file_types.OPEN_API_YAML))
                elif service_config_dict.get('type') == 'google.api.Service':
                    if not self.service_name and service_config_dict.get(
                            'name'):
                        self.service_name = service_config_dict.get('name')

                    config_files.append(
                        self.MakeConfigFileMessage(
                            config_contents, service_config_file,
                            file_types.SERVICE_CONFIG_YAML))
                elif 'name' in service_config_dict:
                    # This is a special case. If we have been provided a Google Service
                    # Configuration file which has a service 'name' field, but no 'type'
                    # field, we have to assume that this is a normalized service config,
                    # and can be uploaded via the CreateServiceConfig API. Therefore,
                    # we can short circute the process here.
                    if len(args.service_config_file) > 1:
                        raise calliope_exceptions.BadFileException((
                            'Ambiguous input. Found normalized service configuration in '
                            'file [{0}], but received multiple input files. To upload '
                            'normalized service config, please provide it separately from '
                            'other input files to avoid ambiguity.'
                        ).format(service_config_file))

                    # If this is a validate-only run, abort now, since this is not
                    # supported in the ServiceConfigs.Create API
                    if self.validate_only:
                        raise exceptions.InvalidFlagError(
                            'The --validate-only flag is not supported when using '
                            'normalized service configs as input.')

                    self.service_name = service_config_dict.get('name')
                    config_files = []
                    break
                else:
                    raise calliope_exceptions.BadFileException((
                        'Unable to parse Open API, or Google Service Configuration '
                        'specification from {0}').format(service_config_file))

            elif services_util.IsProtoDescriptor(service_config_file):
                config_files.append(
                    self.MakeConfigFileMessage(
                        config_contents, service_config_file,
                        file_types.FILE_DESCRIPTOR_SET_PROTO))
            elif services_util.IsRawProto(service_config_file):
                give_proto_deprecate_warning = True
                config_files.append(
                    self.MakeConfigFileMessage(config_contents,
                                               service_config_file,
                                               file_types.PROTO_FILE))
            else:
                raise calliope_exceptions.BadFileException((
                    'Could not determine the content type of file [{0}]. Supported '
                    'extensions are .json .yaml .yml .pb and .descriptor'
                ).format(service_config_file))

        if give_proto_deprecate_warning:
            log.warning(
                'Support for uploading uncompiled .proto files is deprecated and '
                'will soon be removed. Use compiled descriptor sets (.pb) instead.'
            )

        # Check to see if the Endpoints meta service needs to be enabled.
        enable_api.EnableServiceIfDisabled(
            properties.VALUES.core.project.Get(required=True),
            services_util.GetEndpointsServiceName(), args. async)
        # Check if we need to create the service.
        if not services_util.DoesServiceExist(self.service_name):
            project_id = properties.VALUES.core.project.Get(required=True)
            # Deploying, even with validate-only, cannot succeed without the service
            # being created
            if self.validate_only:
                if not console_io.CanPrompt():
                    log.error(
                        VALIDATE_NEW_ERROR.format(
                            service_name=self.service_name,
                            project_id=project_id))
                    return None
                if not console_io.PromptContinue(
                        VALIDATE_NEW_PROMPT.format(
                            service_name=self.service_name,
                            project_id=project_id)):
                    return None
            services_util.CreateService(self.service_name, project_id)

        if config_files:
            push_config_result = services_util.PushMultipleServiceConfigFiles(
                self.service_name,
                config_files,
                args. async,
                validate_only=self.validate_only)
            self.service_config_id = (
                services_util.GetServiceConfigIdFromSubmitConfigSourceResponse(
                    push_config_result))
        else:
            push_config_result = services_util.PushNormalizedGoogleServiceConfig(
                self.service_name,
                properties.VALUES.core.project.Get(required=True),
                services_util.LoadJsonOrYaml(config_contents))
            self.service_config_id = push_config_result.id

        if not self.service_config_id:
            raise exceptions.InvalidConditionError(
                'Failed to retrieve Service Configuration Id.')

        # Run the Push Advisor to see if we need to warn the user of any
        # potentially hazardous changes to the service configuration.
        if self.CheckPushAdvisor(args.force):
            return None

        # Create a Rollout for the new service configuration
        if not self.validate_only:
            percentages = messages.TrafficPercentStrategy.PercentagesValue()
            percentages.additionalProperties.append(
                (messages.TrafficPercentStrategy.PercentagesValue.
                 AdditionalProperty(key=self.service_config_id, value=100.0)))
            traffic_percent_strategy = messages.TrafficPercentStrategy(
                percentages=percentages)
            rollout = messages.Rollout(
                serviceName=self.service_name,
                trafficPercentStrategy=traffic_percent_strategy,
            )
            rollout_create = messages.ServicemanagementServicesRolloutsCreateRequest(
                rollout=rollout,
                serviceName=self.service_name,
            )
            rollout_operation = client.services_rollouts.Create(rollout_create)
            services_util.ProcessOperationResult(rollout_operation,
                                                 args. async)

            # Check to see if the service is already enabled
            enable_api.EnableServiceIfDisabled(
                properties.VALUES.core.project.Get(required=True),
                self.service_name, args. async)

        return push_config_result
Ejemplo n.º 5
0
    def Run(self, args):
        apis = apis_client.ApiClient()
        api_configs = api_configs_client.ApiConfigClient()
        ops = operations_client.OperationsClient()

        api_config_ref = args.CONCEPTS.api_config.Parse()
        api_ref = api_config_ref.Parent()

        service_name = '{}.apigateway.{}.cloud.goog'.format(
            api_ref.Name(), api_ref.projectsId)

        # Check if OP service exists with Api name, create if not, activate it
        if not endpoints.DoesServiceExist(service_name):
            endpoints.CreateService(service_name, api_ref.projectsId)

        # Check to see if Api exists, create if not
        if not apis.DoesExist(api_ref):
            res = apis.Create(api_ref, service_name)
            operation_ref = resources.REGISTRY.Parse(
                res.name,
                collection='apigateway.projects.locations.operations')

            ops.WaitForOperation(
                operation_ref,
                'Waiting for API [{}] to be created'.format(api_ref.Name()))

        # Create OP ServiceConfig and Rollout
        if args.openapi_spec:
            service_config_id = self.__PushOpenApiServiceFile(
                args.openapi_spec,
                service_name,
                api_config_ref.projectsId,
                config_id=api_config_ref.Name())
        else:
            service_config_id = self.__PushGrpcConfigFiles(
                args.grpc_files,
                service_name,
                api_config_ref.projectsId,
                config_id=api_config_ref.Name())
        rollout = endpoints.CreateRollout(service_config_id, service_name)

        # Create ApiConfig object using the service config and rollout
        # Only piece affected by async right now
        resp = api_configs.Create(
            api_config_ref,
            rollout['rolloutId'],
            labels=args.labels,
            display_name=args.display_name,
            backend_auth=args.backend_auth_service_account)
        operation_ref = resources.REGISTRY.Parse(
            resp.name, collection='apigateway.projects.locations.operations')

        # If async operation, simply log and return the result on passed in object
        if args.async_:
            operations_util.PrintOperationResultWithWaitEpilogue(
                operation_ref, 'Asynchronous operation is in progress')
            return resp

        return ops.WaitForOperation(
            operation_ref,
            'Waiting for API Config [{}] to be created for API [{}]'.format(
                api_config_ref.Name(), api_ref.Name()),
            api_configs.client.projects_locations_apis_configs)