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) 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)
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)
def testGetHttpError(self): test_project = util.GetTestActiveProject() test_project_ref = command_lib_util.ParseProject(test_project.projectId) self.mock_client.projects.Get.Expect( self.messages.CloudresourcemanagerProjectsGetRequest( projectId=test_project.projectId), exception=self.HttpError()) with self.assertRaises(exceptions.HttpError): projects_api.Get(test_project_ref)
def testGet(self): test_project = util.GetTestActiveProject() test_project_ref = command_lib_util.ParseProject(test_project.projectId) self.mock_client.projects.Get.Expect( self.messages.CloudresourcemanagerProjectsGetRequest( projectId=test_project.projectId), test_project) response = projects_api.Get(test_project_ref) self.assertEqual(response, test_project)
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'))
def _IsExistingProject(project_id): project_ref = projects_command_util.ParseProject(project_id) try: project = projects_api.Get(project_ref) return projects_util.IsActive(project) except Exception: # pylint: disable=broad-except # Yeah, this isn't great, but there isn't a perfect exception super class # that covers both API related errors and network errors. return False
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)
def GetAnthosSupportUser(project_id): """Get P4SA account name for Anthos Support when user not specified.""" project_number = projects_api.Get( projects_util.ParseProject(project_id)).projectNumber endpoint_overrides = properties.VALUES.api_endpoint_overrides.AllValues() hub_endpoint_override = endpoint_overrides.get('gkehub', '') if not hub_endpoint_override: return ANTHOS_SUPPORT_USER.format(project_number=project_number, instance_name='') elif 'autopush-gkehub' in hub_endpoint_override: return ANTHOS_SUPPORT_USER.format(project_number=project_number, instance_name='autopush-') else: raise memberships_errors.UnknownApiEndpointOverrideError('gkehub')
def Describe(project_id: str = None) -> Project: """ Return the protobuf message describing the project. project_id: the string ID of the project. If omitted, the current configured project is used. A helper function ap_to_dict is provided, which also handles a case of a missing collection (and returns an empty dict in this case): ap_to_dict(proj.labels) -> dict """ if not project_id: project_id = GetCurrent() # Use the SimpleNamespace ducky instead of the "official" ProjectReference # instance, because 'projectId' is all the API wants. return _projapi.Get(_Ducky(projectId=project_id))
def _WarnIfSettingProjectWithNoAccess(scope, project): """Warn if setting 'core/project' config to inaccessible project.""" # Only display a warning if the following conditions are true: # # * The current scope is USER (not occurring in the context of installation). # * The 'core/account' value is set (a user has authed). # # If the above conditions are met, check that the project being set exists # and is accessible to the current user, otherwise show a warning. if (scope == properties.Scope.USER and properties.VALUES.core.account.Get()): project_ref = command_lib_util.ParseProject(project) base.DisableUserProjectQuota() try: projects_api.Get(project_ref) except (apitools_exceptions.HttpError, c_store.NoCredentialsForAccountException): log.warning('You do not appear to have access to project [{}] or' ' it does not exist.'.format(project)) finally: base.EnableUserProjectQuota()
def _GetProjectNumber(self, project_id): """Converts a project id to a project number.""" project_ref = projects_util.ParseProject(project_id) project = projects_api.Get(project_ref) return project.projectNumber
def Run(self, args): project_ref = command_lib_util.ParseProject(args.id) return projects_api.Get(project_ref)
def _GetOrganizationId(): """Gets id of current organization.""" proj = projects_api.Get(projects_util.ParseProject(_GetProjectName())) return (proj.parent.id if proj.parent and proj.parent.type == 'organization' else _ORG_ID_PLACE_HOLDER)
def GetProjectNumber(project): project_id = project or properties.VALUES.core.project.Get(required=True) return projects_api.Get( projects_util.ParseProject(project_id)).projectNumber
def GetProjectNumber(project_id): return projects_api.Get(ParseProject(project_id)).projectNumber
def _GetProjectNumber(project_id): return projects_api.Get( projects_util.ParseProject(project_id)).projectNumber
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)