Beispiel #1
0
 def testComputeInstancesEnablement(self):
     service = 'compute.googleapis.com'
     self.assertFalse(
         services_enable_api.IsServiceEnabled(self.project_id, service))
     self._Run('compute instances list')
     self.assertTrue(
         services_enable_api.IsServiceEnabled(self.project_id, service))
Beispiel #2
0
 def testComputeInstancesEnablement(self):
     service = 'compute.googleapis.com'
     self.assertFalse(
         services_enable_api.IsServiceEnabled(self.project_id, service))
     instance_name = next(self.name_generator)
     self._Run('compute instances create --zone=us-east1-d {}'.format(
         instance_name))
     self._Run('compute instances list')
     self.AssertOutputContains(instance_name)
     self.assertTrue(
         services_enable_api.IsServiceEnabled(self.project_id, service))
Beispiel #3
0
def DisplayProposedConfigDeployments(project, configs):
  """Prints the details of the proposed config deployments.

  Args:
    project: The name of the current project.
    configs: [yaml_parsing.ConfigYamlInfo], The configurations being
      deployed.
  """
  log.status.Print('Configurations to update:\n')
  for c in configs:
    log.status.Print(DEPLOY_CONFIG_MESSAGE_TEMPLATE.format(
        project=project, type=CONFIG_TYPES[c.config], descriptor=c.file))

    if c.name == yaml_parsing.ConfigYamlInfo.QUEUE:
      # If useful, this logic can be broken out and moved to enable_api.py,
      # under IsServiceMaybeEnabled(...) or similar.
      try:
        api_maybe_enabled = enable_api.IsServiceEnabled(
            project, 'cloudtasks.googleapis.com')
      except s_exceptions.ListServicesPermissionDeniedException:
        api_maybe_enabled = True  # We can't know, so presume it is enabled
      if api_maybe_enabled:
        # Display this warning with a false positive rate for when the Service
        # Manangement API is not enabled or accessible.
        log.warning(QUEUE_TASKS_WARNING)
Beispiel #4
0
def _CheckIamPermissions(project_id, service_account_roles):
  """Check for needed IAM permissions and prompt to add if missing.

  Args:
    project_id: A string with the name of the project.
    service_account_roles: roles to be used by service account in addition to
      compute.admin.
  """
  project = projects_api.Get(project_id)
  # If the user's project doesn't have cloudbuild enabled yet, then the service
  # account won't even exist. If so, then ask to enable it before continuing.
  # Also prompt them to enable Stackdriver Logging if they haven't yet.
  expected_services = ['cloudbuild.googleapis.com', 'logging.googleapis.com']
  for service_name in expected_services:
    if not services_api.IsServiceEnabled(project.projectId, service_name):
      # TODO(b/112757283): Split this out into a separate library.
      prompt_message = (
          'The "{0}" service is not enabled for this project. '
          'It is required for this operation.\n').format(service_name)
      console_io.PromptContinue(
          prompt_message,
          'Would you like to enable this service?',
          throw_if_unattended=True,
          cancel_on_no=True)
      operation = services_api.EnableServiceApiCall(project.projectId,
                                                    service_name)
      # Wait for the operation to finish.
      services_util.ProcessOperationResult(operation, is_async=False)

  # Now that we're sure the service account exists, actually check permissions.
  service_account = 'serviceAccount:{0}@cloudbuild.gserviceaccount.com'.format(
      project.projectNumber)
  expected_permissions = {'roles/compute.admin': service_account}
  if service_account_roles:
    for role in service_account_roles:
      expected_permissions[role] = service_account

  permissions = projects_api.GetIamPolicy(project_id)
  for binding in permissions.bindings:
    if expected_permissions.get(binding.role) in binding.members:
      del expected_permissions[binding.role]

  if expected_permissions:
    ep_table = [
        '{0} {1}'.format(role, account)
        for role, account in expected_permissions.items()
    ]
    prompt_message = (
        'The following IAM permissions are needed for this operation:\n'
        '[{0}]\n'.format('\n'.join(ep_table)))
    console_io.PromptContinue(
        message=prompt_message,
        prompt_string='Would you like to add the permissions',
        throw_if_unattended=True,
        cancel_on_no=True)

    for role, account in expected_permissions.items():
      log.info('Adding [{0}] to [{1}]'.format(account, role))
      projects_api.AddIamPolicyBinding(project_id, account, role)
Beispiel #5
0
def _IsResourceSettingsEnabled(project):
    api_endpoint = apis.GetEffectiveApiEndpoint(
        resourcesettings_service.RESOURCE_SETTINGS_API_NAME,
        resourcesettings_service.RESOURCE_SETTINGS_API_VERSION)
    # removes initial https:// and trailing slash
    api_endpoint = re.sub(r'https://(.*)/', r'\1', api_endpoint)

    return enable_api.IsServiceEnabled(project, api_endpoint)
Beispiel #6
0
 def testDoesntUseResourceQuota(self):
     mock_http_client = self.StartObjectPatch(http, 'Http')
     mock_http_client.return_value.request.return_value = \
         (httplib2.Response({'status': 200}), b'')
     self.request_mock = mock_http_client.return_value.request
     properties.VALUES.core.project.Set('myproject')
     enable_api.IsServiceEnabled('myproj', 'service1.googleapis.com')
     self.assertNotIn(b'X-Goog-User-Project',
                      self.request_mock.call_args[0][3])
Beispiel #7
0
def _CheckIamPermissions(project_id):
  """Check for needed IAM permissions and prompt to add if missing.

  Args:
    project_id: A string with the id of the project.
  """
  project = projects_api.Get(project_id)
  # If the user's project doesn't have cloudbuild enabled yet, then the service
  # account won't even exist. If so, then ask to enable it before continuing.
  # Also prompt them to enable Stackdriver Logging if they haven't yet.
  expected_services = ['cloudbuild.googleapis.com', 'logging.googleapis.com']
  for service_name in expected_services:
    if not services_api.IsServiceEnabled(project.projectId, service_name):
      # TODO(b/112757283): Split this out into a separate library.
      prompt_message = (
          'The "{0}" service is not enabled for this project. '
          'It is required for this operation.\n').format(service_name)
      console_io.PromptContinue(
          prompt_message,
          'Would you like to enable this service?',
          throw_if_unattended=True,
          cancel_on_no=True)
      services_api.EnableService(project.projectId, service_name)

  # Now that we're sure the service account exists, actually check permissions.
  policy = projects_api.GetIamPolicy(project_id)
  build_account = 'serviceAccount:{0}@cloudbuild.gserviceaccount.com'.format(
      project.projectNumber)
  _VerifyRolesAndPromptIfMissing(
      project_id, build_account, _CurrentRolesForAccount(policy, build_account),
      {
          'roles/compute.admin', 'roles/iam.serviceAccountUser',
          'roles/iam.serviceAccountTokenCreator'
      })

  # https://cloud.google.com/compute/docs/access/service-accounts#default_service_account
  compute_account = (
      'serviceAccount:{0}[email protected]'.format(
          project.projectNumber))
  current_compute_account_roles = _CurrentRolesForAccount(
      policy, compute_account)

  # By default, the Compute Engine service account has the role `roles/editor`
  # applied to it, which is sufficient for import and export. If that's not
  # present, then request the minimal number of permissions.
  if 'roles/editor' not in current_compute_account_roles:
    try:
      _VerifyRolesAndPromptIfMissing(
          project_id, compute_account, current_compute_account_roles,
          {'roles/compute.storageAdmin', 'roles/storage.objectViewer'})
    except apitools_exceptions.HttpForbiddenError:
      log.warning(
          'Your account does not have permission to add roles to the '
          'default compute engine service account. If import fails, '
          'ensure "{0}" has the roles "{1}" and "{2}" before retrying.'.format(
              compute_account, 'roles/compute.storageAdmin',
              'roles/storage.objectViewer'))
Beispiel #8
0
    def testIsServiceEnabled_OtherError(self):
        """Test IsServiceEnabled raises HttpError when expected."""
        server_error = http_error.MakeDetailedHttpError(
            code=401, message='Something else.')
        self.ExpectGetService(None, error=server_error)

        with self.assertRaisesRegex(apitools_exceptions.HttpError,
                                    r'Something else.'):
            enable_api.IsServiceEnabled(self.PROJECT_NAME,
                                        self.DEFAULT_SERVICE_NAME)
Beispiel #9
0
    def testIsServiceEnabled_PermissionsError(self):
        """Test IsServiceEnabled raises PermissionsError when expected."""
        server_error = http_error.MakeDetailedHttpError(code=403,
                                                        message='Something.')
        self.ExpectGetService(None, error=server_error)

        with self.assertRaisesRegex(
                exceptions.GetServicePermissionDeniedException, r'Something.'):
            enable_api.IsServiceEnabled(self.PROJECT_NAME,
                                        self.DEFAULT_SERVICE_NAME)
Beispiel #10
0
    def testIsServiceEnabled_False(self):
        """Test IsServiceEnabled when result is False."""
        service = self._NewServiceConfig(self.PROJECT_NAME,
                                         self.DEFAULT_SERVICE_NAME,
                                         enabled=False)
        self.ExpectGetService(service)

        self.assertFalse(
            enable_api.IsServiceEnabled(self.PROJECT_NAME,
                                        self.DEFAULT_SERVICE_NAME))
def CheckIamPermissions(project_id):
    """Check for needed IAM permissions and prompt to add if missing.

  Args:
    project_id: A string with the name of the project.
  """
    project = projects_api.Get(project_id)
    # If the user's project doesn't have cloudbuild enabled yet, then the service
    # account won't even exist. If so, then ask to enable it before continuing.
    cloudbuild_service_name = 'cloudbuild.googleapis.com'
    if not services_api.IsServiceEnabled(project.projectId,
                                         cloudbuild_service_name):
        prompt_message = ('The Google Cloud Build service is not '
                          'enabled for this project. It is required for this '
                          'operation.\n')
        console_io.PromptContinue(
            prompt_message,
            'Would you like to enable Container Builder?',
            throw_if_unattended=True,
            cancel_on_no=True)
        operation = services_api.EnableServiceApiCall(project.projectId,
                                                      cloudbuild_service_name)
        # Wait for the operation to finish.
        services_util.ProcessOperationResult(operation, is_async=False)

    # Now that we're sure the service account exists, actually check permissions.
    service_account = 'serviceAccount:{0}@cloudbuild.gserviceaccount.com'.format(
        project.projectNumber)
    expected_permissions = {
        'roles/compute.admin': service_account,
        'roles/iam.serviceAccountActor': service_account
    }
    permissions = projects_api.GetIamPolicy(project_id)
    for binding in permissions.bindings:
        if expected_permissions.get(binding.role) in binding.members:
            del expected_permissions[binding.role]

    if expected_permissions:
        ep_table = [
            '{0} {1}'.format(role, account)
            for role, account in expected_permissions.items()
        ]
        prompt_message = (
            'The following IAM permissions are needed for this operation:\n'
            '[{0}]\n'.format('\n'.join(ep_table)))
        console_io.PromptContinue(
            message=prompt_message,
            prompt_string='Would you like to add the permissions',
            throw_if_unattended=True,
            cancel_on_no=True)

        for role, account in expected_permissions.items():
            log.info('Adding [{0}] to [{1}]'.format(account, role))
            projects_api.AddIamPolicyBinding(project_id, account, role)
Beispiel #12
0
def CheckForAssetInventoryEnablementWithPrompt(project=None):
  """Checks if the cloudasset API is enabled, prompts to enable if not."""
  project = project or properties.VALUES.core.project.GetOrFail()
  service_name = 'cloudasset.googleapis.com'
  if not enable_api.IsServiceEnabled(project, service_name):
    if console_io.PromptContinue(
        default=False,
        prompt_string=(
            'API [{}] is required to continue, but is not enabled on project [{}]. '
            'Would you like to enable and retry (this will take a '
            'few minutes)?').format(service_name, project)):
      enable_api.EnableService(project, service_name)
    else:
      raise AssetInventoryNotEnabledException(
          'Aborted by user: API [{}] must be enabled on project [{}] to continue.'
          .format(service_name, project))
Beispiel #13
0
def CheckForContainerFileSystemApiEnablementWithPrompt(project):
    """Checks if the Container File System API is enabled."""
    service_name = 'containerfilesystem.googleapis.com'
    try:
        if not enable_api.IsServiceEnabled(project, service_name):
            log.warning(
                'Container File System API (containerfilesystem.googleapis.com) has not been enabled on the project. '
                'Please enable it for image streaming to fully work. '
                'For additional details, please refer to https://cloud.google.com/kubernetes-engine/docs/how-to/image-streaming#requirements'
            )
    except (exceptions.GetServicePermissionDeniedException,
            apitools_exceptions.HttpError):
        log.warning(
            'Failed to check if Container File System API (containerfilesystem.googleapis.com) has been enabled. '
            'Please make sure to enable it for image streaming to work. '
            'For additional details, please refer to https://cloud.google.com/kubernetes-engine/docs/how-to/image-streaming#requirements'
        )
Beispiel #14
0
def PromptToEnableApi(service_name):
  """Prompts to enable the API and throws if the answer is no.

  Args:
    service_name: str, The service token of the API to prompt for.
  """
  if not properties.VALUES.core.should_prompt_to_enable_api.GetBool():
    return

  project = properties.VALUES.core.project.Get(required=True)
  # Don't prompt to enable an already enabled API
  if not enable_api.IsServiceEnabled(project, service_name):
    if console_io.PromptContinue(
        default=False,
        cancel_on_no=True,
        prompt_string=('API [{}] not enabled on project [{}]. '
                       'Would you like to enable and retry (this will take a '
                       'few minutes)?').format(service_name, project)):
      enable_api.EnableService(project, service_name)
Beispiel #15
0
def _CheckIamPermissions(project_id, cloudbuild_service_account_roles,
                         compute_service_account_roles,
                         custom_compute_service_account=''):
  """Check for needed IAM permissions and prompt to add if missing.

  Args:
    project_id: A string with the id of the project.
    cloudbuild_service_account_roles: A set of roles required for cloudbuild
      service account.
    compute_service_account_roles: A set of roles required for compute service
      account.
    custom_compute_service_account: Custom compute service account
  """
  project = projects_api.Get(project_id)
  # If the user's project doesn't have cloudbuild enabled yet, then the service
  # account won't even exist. If so, then ask to enable it before continuing.
  # Also prompt them to enable Cloud Logging if they haven't yet.
  expected_services = ['cloudbuild.googleapis.com', 'logging.googleapis.com',
                       'compute.googleapis.com']
  for service_name in expected_services:
    if not services_api.IsServiceEnabled(project.projectId, service_name):
      # TODO(b/112757283): Split this out into a separate library.
      prompt_message = (
          'The "{0}" service is not enabled for this project. '
          'It is required for this operation.\n').format(service_name)
      enable_service = console_io.PromptContinue(
          prompt_message,
          'Would you like to enable this service?',
          throw_if_unattended=True)
      if enable_service:
        services_api.EnableService(project.projectId, service_name)
      else:
        log.warning(
            'If import fails, manually enable {0} before retrying. For '
            'instructions on enabling services, see '
            'https://cloud.google.com/service-usage/docs/enable-disable.'
            .format(service_name))

  build_account = 'serviceAccount:{0}@cloudbuild.gserviceaccount.com'.format(
      project.projectNumber)
  # https://cloud.google.com/compute/docs/access/service-accounts#default_service_account
  compute_account = (
      'serviceAccount:{0}[email protected]'.format(
          project.projectNumber))
  if custom_compute_service_account:
    compute_account = 'serviceAccount:{0}'.format(
        custom_compute_service_account)

  # Now that we're sure the service account exists, actually check permissions.
  try:
    policy = projects_api.GetIamPolicy(project_id)
  except apitools_exceptions.HttpForbiddenError:
    log.warning(
        'Your account does not have permission to check roles for the '
        'service account {0}. If import fails, '
        'ensure "{0}" has the roles "{1}" and "{2}" has the roles "{3}" before '
        'retrying.'.format(build_account, cloudbuild_service_account_roles,
                           compute_account, compute_service_account_roles))
    return

  _VerifyRolesAndPromptIfMissing(project_id, build_account,
                                 _CurrentRolesForAccount(policy, build_account),
                                 frozenset(cloudbuild_service_account_roles))

  current_compute_account_roles = _CurrentRolesForAccount(
      policy, compute_account)

  # By default, the Compute Engine service account has the role `roles/editor`
  # applied to it, which is sufficient for import and export. If that's not
  # present, then request the minimal number of permissions.
  if ROLE_EDITOR not in current_compute_account_roles:
    _VerifyRolesAndPromptIfMissing(
        project_id, compute_account, current_compute_account_roles,
        compute_service_account_roles)