def _GetDiagnosticsServiceAccount(self, project): """Locates or creates a service account with the correct permissions. Attempts to locate the service account meant for creating the signed url. If not found, it will subsequently create the service account. It will then give the service account the correct IAM permissions to create a signed url to a GCS Bucket. Args: project: The project to search for the service account in. Returns: A string email of the service account to use. """ # Search for service account by name. service_account = None for account in self._diagnose_client.ListServiceAccounts(project): if account.email.startswith('{}@'.format(_SERVICE_ACCOUNT_NAME)): service_account = account.email if service_account is None: service_account = self._diagnose_client.CreateServiceAccount( project, _SERVICE_ACCOUNT_NAME) # We can apply the correct IAM permissions for accessing the GCS Bucket # regardless of whether or not the account already has them. project_ref = projects_util.ParseProject(project) service_account_ref = 'serviceAccount:{}'.format(service_account) projects_api.AddIamPolicyBinding(project_ref, service_account_ref, 'roles/storage.objectCreator') projects_api.AddIamPolicyBinding(project_ref, service_account_ref, 'roles/storage.objectViewer') return service_account
def _VerifyRolesAndPromptIfMissing(project_id, account, applied_roles, required_roles): """Check for IAM permissions for an account and prompt to add if missing. Args: project_id: A string with the id of the project. account: A string with the identifier of an account. applied_roles: A set of strings containing the current roles for the account. required_roles: A set of strings containing the required roles for the account. If a role isn't found, then the user is prompted to add the role. """ # If there were unsatisfied roles, then prompt the user to add them. missing_roles = required_roles - applied_roles if missing_roles: ep_table = ['{0} {1}'.format(role, account) for role in missing_roles] 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=False) for role in missing_roles: log.info('Adding [{0}] to [{1}]'.format(account, role)) projects_api.AddIamPolicyBinding(project_id, account, role)
def Run(self, args): """This is what gets called when the user runs this command. Args: args: an argparse namespace. All the arguments that were provided to this command invocation. """ client = apis.GetClientInstance('ml', 'v1beta1') msgs = apis.GetMessagesModule('ml', 'v1beta1') project = properties.VALUES.core.project.Get(required=True) project_ref = resources.REGISTRY.Parse( project, collection='cloudresourcemanager.projects') console_io.PromptContinue( message= '\nCloud ML needs to add its service accounts to your project ' '({0}) as Editors. This will enable Cloud Machine Learning to access ' 'resources in your project when running your training and ' 'prediction jobs.'.format(project), cancel_on_no=True) # Get service account information from cloud ml service. req = msgs.MlProjectsGetConfigRequest(projectsId=project) resp = client.projects.GetConfig(req) # Add cloud ml service account. cloud_ml_service_account = 'serviceAccount:' + resp.serviceAccount projects_api.AddIamPolicyBinding(project_ref, cloud_ml_service_account, EDITOR_ROLE) log.status.Print('Added {0} as an Editor to project \'{1}\'.'.format( cloud_ml_service_account, project))
def _InitProject(version): """Initialize the current project.""" client = apis.GetClientInstance('ml', version) msgs = apis.GetMessagesModule('ml', version) project = properties.VALUES.core.project.GetOrFail() project_ref = resources.REGISTRY.Create('ml.projects', projectsId=project) console_io.PromptContinue( message='\nCloud ML Engine needs to add its service accounts to your ' 'project [{0}] as Editors. This will enable Cloud Machine Learning to ' 'access resources in your project when running your training and ' 'prediction jobs. This operation requires OWNER permissions.'.format( project), cancel_on_no=True) # Get service account information from Cloud ML Engine service. req = msgs.MlProjectsGetConfigRequest(name=project_ref.RelativeName()) resp = client.projects.GetConfig(req) # Add Cloud ML Engine service account. cloud_ml_service_account = 'serviceAccount:' + resp.serviceAccount cloudresourcemanager_project_ref = resources.REGISTRY.Create( 'cloudresourcemanager.projects', projectId=project) projects_api.AddIamPolicyBinding(cloudresourcemanager_project_ref, cloud_ml_service_account, EDITOR_ROLE) log.status.Print('Added {0} as an Editor to project \'{1}\'.'.format( cloud_ml_service_account, project))
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 Run(self, args): project_ref = args.CONCEPTS.project.Parse() service_account = 'service-' + str( project_util.GetProjectNumber(project_ref.projectsId) ) + '@gcp-sa-dataplex.iam.gserviceaccount.com' if args.IsSpecified('storage_bucket_resource'): return storage_api.StorageClient().AddIamPolicyBinding( storage_util.BucketReference(args.storage_bucket_resource), 'serviceAccount:' + service_account, 'roles/dataplex.serviceAgent') if args.IsSpecified('bigquery_dataset_resource'): get_dataset_request = apis.GetMessagesModule( 'bigquery', 'v2').BigqueryDatasetsGetRequest( datasetId=args.bigquery_dataset_resource, projectId=args.secondary_project) dataset = apis.GetClientInstance( 'bigquery', 'v2').datasets.Get(request=get_dataset_request) lake.AddServiceAccountToDatasetPolicy( apis.GetMessagesModule('bigquery', 'v2').Dataset.AccessValueListEntry, dataset, service_account, 'roles/dataplex.serviceAgent') return apis.GetClientInstance('bigquery', 'v2').datasets.Patch( apis.GetMessagesModule( 'bigquery', 'v2').BigqueryDatasetsPatchRequest( datasetId=args.bigquery_dataset_resource, projectId=args.secondary_project, dataset=dataset)) if args.IsSpecified('project_resource'): return projects_api.AddIamPolicyBinding( project_util.ParseProject(args.project_resource), 'serviceAccount:' + service_account, 'roles/dataplex.serviceAgent')
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 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 _VerifyRolesAndPromptIfMissing(project_id, account, applied_roles, required_roles): """Check for IAM permissions for an account and prompt to add if missing. Args: project_id: A string with the id of the project. account: A string with the identifier of an account. applied_roles: A set of strings containing the current roles for the account. required_roles: A set of strings containing the required roles for the account. If a role isn't found, then the user is prompted to add the role. """ # If there were unsatisfied roles, then prompt the user to add them. try: missing_roles = _FindMissingRoles(applied_roles, required_roles) except apitools_exceptions.HttpForbiddenError: missing_roles = required_roles - applied_roles if not missing_roles: return ep_table = [ '{0} {1}'.format(role, account) for role in sorted(missing_roles) ] prompt_message = ( 'The following IAM permissions are needed for this operation:\n' '[{0}]\n'.format('\n'.join(ep_table))) add_roles = console_io.PromptContinue( message=prompt_message, prompt_string='Would you like to add the permissions', throw_if_unattended=True, cancel_on_no=False) if not add_roles: return for role in sorted(missing_roles): log.info('Adding [{0}] to [{1}]'.format(account, role)) try: projects_api.AddIamPolicyBinding(project_id, account, role) except apitools_exceptions.HttpForbiddenError: log.warning( 'Your account does not have permission to add roles to the ' 'service account {0}. If import fails, ' 'ensure "{0}" has the roles "{1}" before retrying.'.format( account, required_roles)) return
def Run(self, args): project_ref = command_lib_util.ParseProject(args.id) return projects_api.AddIamPolicyBinding(project_ref, args.member, args.role)