def Run(self, args): """Run 'service-management check-access'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the access API call. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() all_iam_permissions = services_util.ALL_IAM_PERMISSIONS # Shorten the query request name for better readability query_request = messages.ServicemanagementServicesTestIamPermissionsRequest service = arg_parsers.GetServiceNameFromArg(args.service) request = query_request( servicesId=service, testIamPermissionsRequest=messages.TestIamPermissionsRequest( permissions=all_iam_permissions)) return client.services.TestIamPermissions(request)
def Run(self, args): """Run 'service-management operations list'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The list of operations for this project. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() service = arg_parsers.GetServiceNameFromArg(args.service) msg_filter = 'serviceName="{0}"'.format(service) if args.filter: msg_filter += ' AND ({0})'.format(args.filter) args.filter = None # We don't want Display() to handle the filter. msg = messages.ServicemanagementOperationsListRequest( filter=msg_filter) return list_pager.YieldFromList(client.operations, msg, limit=args.limit, batch_size_attribute='pageSize', batch_size=args.page_size, field='operations')
def _GetConfig(self, service, config_id): messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() request = messages.ServicemanagementServicesConfigsGetRequest( serviceName=service, configId=config_id) return client.services_configs.Get(request)
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). """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() # Prompt with a warning before continuing. console_io.PromptContinue( message= 'Are you sure? This will set the service configuration to be ' 'deleted, along with all of the associated consumer ' 'information. Note: This does not immediately delete the ' 'service configuration or data and can be undone using the ' 'undelete command for 30 days. Only after 30 days will the ' 'service be purged from the system.', prompt_string='Continue anyway', default=True, throw_if_unattended=True, cancel_on_no=True) service = arg_parsers.GetServiceNameFromArg(args.service) request = messages.ServicemanagementServicesDeleteRequest( serviceName=service, ) operation = client.services.Delete(request) return services_util.ProcessOperationResult(operation, args.async_)
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. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() operation_id = arg_parsers.GetOperationIdFromArg(args.operation) request = messages.ServicemanagementOperationsGetRequest( operationsId=operation_id,) operation = client.operations.Get(request) if (sys.getsizeof(str(operation.response)) > MAX_RESPONSE_BYTES and not args.full): log.warning('Response portion of operation resource redacted. ' 'Use --full to see the whole Operation.\n') operation.response = None # Set async to True because we don't need to wait for the operation # to complete to check the status of it. return services_util.GetProcessedOperationResult(operation, is_async=True)
def Run(self, args): """Run 'service-management configs list'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the List API call. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() service = arg_parsers.GetServiceNameFromArg(args.service) request = messages.ServicemanagementServicesConfigsListRequest( serviceName=service) return list_pager.YieldFromList( client.services_configs, request, limit=args.limit, batch_size_attribute='pageSize', batch_size=args.page_size, field='serviceConfigs')
def Run(self, args): """Run 'service-management remove-iam-policy-binding'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the access API call. Raises: ToolException: An error such as specifying a label that doesn't exist or a principal that is already a member of the service or visibility label. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() service = arg_parsers.GetServiceNameFromArg(args.service) request = messages.ServicemanagementServicesGetIamPolicyRequest( servicesId=service) policy = client.services.GetIamPolicy(request) iam_util.RemoveBindingFromIamPolicy(policy, args.member, args.role) # Send updated access policy to backend request = messages.ServicemanagementServicesSetIamPolicyRequest( servicesId=service, setIamPolicyRequest=messages.SetIamPolicyRequest(policy=policy)) return client.services.SetIamPolicy(request)
def __DeleteEndpointsService(self, service_name): messages = endpoints.GetMessagesModule() client = endpoints.GetClientInstance() request = messages.ServicemanagementServicesDeleteRequest( serviceName=service_name) operation = client.services.Delete(request) return endpoints.ProcessOperationResult(operation, False)
def GenerateManagementUrl(service): """Generate a service management url for this service.""" # It is actually possible to deploy a service configuration for a service # which is not in the current project, as long as you have appropriate # permissions. Because of this, we need to explicitly query for the service's # project. messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() get_request = messages.ServicemanagementServicesGetRequest( serviceName=service, ) response = client.services.Get(get_request) project = response.producerProjectId return ('https://console.cloud.google.com/endpoints/api/' '{service}/overview?project={project}'.format( service=six.moves.urllib.parse.quote(service), project=six.moves.urllib.parse.quote(project)))
def Run(self, args): """Run 'service-management describe'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the Get API call. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() service = arg_parsers.GetServiceNameFromArg(args.service) request = messages.ServicemanagementServicesGetRequest( serviceName=service, ) return client.services.Get(request)
def Run(self, args): """Run 'service-management add-iam-policy-binding'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the access API call. Raises: ToolException: An error such as specifying a label that doesn't exist or a principal that is already a member of the service or visibility label. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() service = arg_parsers.GetServiceNameFromArg(args.service) request = messages.ServicemanagementServicesGetIamPolicyRequest( servicesId=service) try: policy = client.services.GetIamPolicy(request) except apitools_exceptions.HttpError as error: # If the error is a 404, no IAM policy exists, so just create a blank one. exc = exceptions.HttpException(error) if exc.payload.status_code == 404: policy = messages.Policy() else: raise iam_util.AddBindingToIamPolicy(messages.Binding, policy, args.member, args.role) # Send updated access policy to backend request = messages.ServicemanagementServicesSetIamPolicyRequest( servicesId=service, setIamPolicyRequest=(messages.SetIamPolicyRequest(policy=policy))) return client.services.SetIamPolicy(request)
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. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() operation_id = arg_parsers.GetOperationIdFromArg(args.operation) request = messages.ServicemanagementOperationsGetRequest( operationsId=operation_id,) operation = client.operations.Get(request) return services_util.ProcessOperationResult(operation, is_async=False)
def Run(self, args): """Run 'service-management undelete'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the Undelete API call (or None if cancelled). """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() service = arg_parsers.GetServiceNameFromArg(args.service) request = messages.ServicemanagementServicesUndeleteRequest( serviceName=service, ) operation = client.services.Undelete(request) return services_util.ProcessOperationResult(operation, args. async)
def Run(self, args): """Run 'service-management get-iam-policy'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the access API call. Raises: HttpException: An http error response was received while executing api request. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() service = arg_parsers.GetServiceNameFromArg(args.service) request = messages.ServicemanagementServicesGetIamPolicyRequest( servicesId=service) return client.services.GetIamPolicy(request)
def Run(self, args): """Run 'endpoints list'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The list of managed services for this project. """ client = services_util.GetClientInstance() validated_project = services_util.GetValidatedProject(args.project) request = services_util.GetProducedListRequest(validated_project) return list_pager.YieldFromList(client.services, request, limit=args.limit, batch_size_attribute='pageSize', batch_size=args.page_size or self._DEFAULT_PAGE_SIZE, field='services')
def Run(self, args): """Run 'endpoints operations describe'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: The response from the operations.Get API call. """ messages = services_util.GetMessagesModule() client = services_util.GetClientInstance() operation_id = arg_parsers.GetOperationIdFromArg(args.operation) request = messages.ServicemanagementOperationsGetRequest( operationsId=operation_id,) operation = client.operations.Get(request) # Set async to True because we don't need to wait for the operation # to complete to check the status of it. return services_util.GetProcessedOperationResult(operation, is_async=True)
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 # 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)) 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)) # 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. services_util.CreateServiceIfNew( self.service_name, properties.VALUES.core.project.Get(required=True)) 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), 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