Ejemplo n.º 1
0
def PromptToEnableApi(project, service_token, exception,
                      is_batch_request=False):
  """Prompts to enable the API and throws if the answer is no.

  Args:
    project (str): The project that the API is not enabled on.
    service_token (str): The service token of the API to prompt for.
    exception (api_Exceptions.HttpException): Exception to throw if the prompt
      is denied.
    is_batch_request: If the request is a batch request. This determines how to
      get apitools to retry the request.

  Raises:
    api_exceptions.HttpException: API not enabled error if the user chooses to
      not enable the API.
  """
  if console_io.PromptContinue(
      default=False,
      prompt_string=('API [{}] not enabled on project [{}]. '
                     'Would you like to enable and retry (this will take a '
                     'few minutes)?')
      .format(service_token, project)):
    enable_api.EnableServiceIfDisabled(project, service_token)
    # In the case of a batch request, as long as the error's retryable code
    # (in this case 403) was set, after this runs it should retry. This
    # error code should be consistent with apis.GetApiEnablementInfo
    if not is_batch_request:
      raise apitools_exceptions.RequestError('Retry')
  else:
    raise exception
 def Enable(self, feature):
     project = properties.VALUES.core.project.GetOrFail()
     enable_api.EnableServiceIfDisabled(project, self.feature.api)
     parent = util.LocationResourceName(project)
     try:
         # Retry if we still get "API not activated"; it can take a few minutes
         # for Chemist to catch up. See b/28800908.
         # TODO(b/177098463): Add a spinner here?
         retryer = retry.Retryer(max_retrials=4,
                                 exponential_sleep_multiplier=1.75)
         op = retryer.RetryOnException(
             self.hubclient.CreateFeature,
             args=(parent, self.feature_name, feature),
             should_retry_if=self._FeatureAPINotEnabled,
             sleep_ms=1000)
     except retry.MaxRetrialsException:
         raise exceptions.Error(
             'Retry limit exceeded waiting for {} to enable'.format(
                 self.feature.api))
     except apitools_exceptions.HttpConflictError as e:
         # If the error is not due to the object already existing, re-raise.
         error = core_api_exceptions.HttpErrorPayload(e)
         if error.status_description != 'ALREADY_EXISTS':
             raise
         # TODO(b/177098463): Decide if this should be a hard error if a spec was
         # set, but not applied, because the Feature already existed.
         log.status.Print(
             '{} Feature for project [{}] is already enabled'.format(
                 self.feature.display_name, project))
         return
     msg = 'Waiting for Feature {} to be created'.format(
         self.feature.display_name)
     return self.WaitForHubOp(self.hubclient.feature_waiter,
                              op=op,
                              message=msg)
Ejemplo n.º 3
0
  def Run(self, args):
    if not args.config_membership:
      memberships = base.ListMemberships()
      if not memberships:
        raise exceptions.Error('No Memberships available in the fleet.')
      index = console_io.PromptChoice(
          options=memberships, message='Please specify a config membership:\n')
      config_membership = memberships[index]
    else:
      # Strip to the final path component to allow short and long names.
      # Assumes long names are for the same project and global location.
      # TODO(b/192580393): Use the resource args instead of this hack.
      config_membership = os.path.basename(args.config_membership)
    config_membership = self.MembershipResourceName(config_membership)

    # MCI requires MCSD. Enablement of the fleet feature for MCSD is taken care
    # of by CLH but we need to enable the OP API before that happens. If not,
    # CLH will return an error asking for the API to be enabled.
    mcsd_api = info.Get('multiclusterservicediscovery').api
    enable_api.EnableServiceIfDisabled(self.Project(), mcsd_api)

    f = self.messages.Feature(
        spec=self.messages.CommonFeatureSpec(
            multiclusteringress=self.messages.MultiClusterIngressFeatureSpec(
                configMembership=config_membership)))
    result = self.Enable(f)

    # We only want to poll for usability if everything above succeeded.
    if result is not None:
      self.PollForUsability()
Ejemplo n.º 4
0
    def testEnableServiceIfDisabled_AlreadyEnabled(self):
        """Test EnableServiceIfDisabled runs successfully if already enabled."""
        service = self._NewServiceConfig(self.PROJECT_NAME,
                                         self.DEFAULT_SERVICE_NAME,
                                         enabled=True)
        self.ExpectGetService(service)

        enable_api.EnableServiceIfDisabled(self.PROJECT_NAME,
                                           self.DEFAULT_SERVICE_NAME)
Ejemplo n.º 5
0
    def testEnableServiceIfDisabled_NotYetEnabled_Success(self):
        """Test EnableServiceifDisabled enables service if not yet enabled."""
        service = self._NewServiceConfig(self.PROJECT_NAME,
                                         self.DEFAULT_SERVICE_NAME)
        self.ExpectGetService(service)
        self.ExpectEnableApiCall(self.OPERATION_NAME)
        self.ExpectOperation(self.OPERATION_NAME, 3)

        enable_api.EnableServiceIfDisabled(self.PROJECT_NAME,
                                           self.DEFAULT_SERVICE_NAME)
Ejemplo n.º 6
0
    def testEnableServiceIfDisabled_NotYetEnabled_EventualFailure(self):
        """Test EnableServiceIfDisabled raises if operation fails."""
        service = self._NewServiceConfig(self.PROJECT_NAME,
                                         self.DEFAULT_SERVICE_NAME)
        self.ExpectGetService(service)
        self.ExpectEnableApiCall(self.OPERATION_NAME)
        server_error = http_error.MakeDetailedHttpError(code=403,
                                                        message='Error.')
        self.ExpectOperation(self.OPERATION_NAME, 0, error=server_error)

        with self.assertRaises(exceptions.OperationErrorException):
            enable_api.EnableServiceIfDisabled(self.PROJECT_NAME,
                                               self.DEFAULT_SERVICE_NAME)
def PossiblyEnableFlex(project):
    """Attempts to enable the Flexible Environment API on the project.

  Possible scenarios:
  -If Flexible Environment is already enabled, success.
  -If Flexible Environment API is not yet enabled, attempts to enable it. If
   that succeeds, success.
  -If the account doesn't have permissions to confirm that the Flexible
   Environment API is or isn't enabled on this project, succeeds with a warning.
     -If the account is a service account, adds an additional warning that
      the Service Management API may need to be enabled.
  -If the Flexible Environment API is not enabled on the project and the attempt
   to enable it fails, raises PrepareFailureError.

  Args:
    project: str, the project ID.

  Raises:
    PrepareFailureError: if enabling the API fails with a 403 or 404 error code.
    googlecloudsdk.api_lib.util.exceptions.HttpException: miscellaneous errors
        returned by server.
  """
    try:
        enable_api.EnableServiceIfDisabled(project,
                                           'appengineflex.googleapis.com')
    except s_exceptions.ListServicesPermissionDeniedException:
        # If we can't find out whether the Flexible API is enabled, proceed with
        # a warning.
        warning = FLEXIBLE_SERVICE_VERIFY_WARNING.format(project)
        # If user is using a service account, add more info about what might
        # have gone wrong.
        credential = c_store.LoadIfEnabled()
        if credential:
            account_type = creds.CredentialType.FromCredentials(credential)
            if account_type in (creds.CredentialType.SERVICE_ACCOUNT,
                                creds.CredentialType.P12_SERVICE_ACCOUNT):
                warning += '\n\n{}'.format(
                    FLEXIBLE_SERVICE_VERIFY_WITH_SERVICE_ACCOUNT)
        log.warning(warning)
    except s_exceptions.EnableServicePermissionDeniedException:
        # If enabling the Flexible API fails due to a permissions error, the
        # deployment fails.
        raise PrepareFailureError(PREPARE_FAILURE_MSG.format(project))
    except apitools_exceptions.HttpError as err:
        # The deployment should also fail if there are unforeseen errors in
        # enabling the Flexible API. If so, display detailed information.
        raise api_lib_exceptions.HttpException(
            err,
            error_format=('Error [{status_code}] {status_message}'
                          '{error.details?'
                          '\nDetailed error information:\n{?}}'))
Ejemplo n.º 8
0
 def RunCommand(self, args, **kwargs):
     try:
         project = properties.VALUES.core.project.GetOrFail()
         enable_api.EnableServiceIfDisabled(project, self.FEATURE_API)
         return CreateFeature(project, self.FEATURE_NAME,
                              self.FEATURE_DISPLAY_NAME, **kwargs)
     except apitools_exceptions.HttpUnauthorizedError as e:
         raise exceptions.Error(
             'You are not authorized to enable {} Feature from project [{}]. '
             'Underlying error: {}'.format(self.FEATURE_DISPLAY_NAME,
                                           project, e))
     except properties.RequiredPropertyError as e:
         raise exceptions.Error('Failed to retrieve the project ID.')
     except apitools_exceptions.HttpConflictError as e:
         # If the error is not due to the object already existing, re-raise.
         error = core_api_exceptions.HttpErrorPayload(e)
         if error.status_description != 'ALREADY_EXISTS':
             raise
         else:
             log.status.Print(
                 '{} Feature for project [{}] is already enabled'.format(
                     self.FEATURE_DISPLAY_NAME, project))
Ejemplo n.º 9
0
 def Run(self, args):
     cloudbuild_api = info.Get('cloudbuild').api
     enable_api.EnableServiceIfDisabled(self.Project(), cloudbuild_api)
     self.Enable(self.messages.Feature())