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 Run(self, args): """Default Run method implementation.""" flags.CheckParentFlags(args, parent_required=False) project_id = args.id if not project_id and args.name: candidate = command_lib_util.IdFromName(args.name) if candidate and console_io.PromptContinue( 'No project id provided.', 'Use [{}] as project id'.format(candidate), throw_if_unattended=True): project_id = candidate if not project_id: raise exceptions.RequiredArgumentException( 'PROJECT_ID', 'an id must be provided for the new project') project_ref = command_lib_util.ParseProject(project_id) labels = labels_util.ParseCreateArgs( args, projects_util.GetMessages().Project.LabelsValue) try: create_op = projects_api.Create( project_ref, display_name=args.name, parent=projects_api.ParentNameToResourceId( flags.GetParentFromFlags(args)), labels=labels) except apitools_exceptions.HttpConflictError: msg = ( 'Project creation failed. The project ID you specified is ' 'already in use by another project. Please try an alternative ' 'ID.') core_exceptions.reraise(exceptions.HttpException(msg)) log.CreatedResource(project_ref, is_async=True) create_op = operations.WaitForOperation(create_op) # Enable cloudapis.googleapis.com if args.enable_cloud_apis: log.debug('Enabling cloudapis.googleapis.com') services_client = apis.GetClientInstance('servicemanagement', 'v1') enable_operation = services_enable_api.EnableServiceApiCall( project_ref.Name(), 'cloudapis.googleapis.com') enable_operation_ref = resources.REGISTRY.Parse( enable_operation.name, collection='servicemanagement.operations') services_util.WaitForOperation(enable_operation_ref, services_client) if args.set_as_default: project_property = properties.FromString('core/project') properties.PersistProperty(project_property, project_id) log.status.Print( 'Updated property [core/project] to [{0}].'.format(project_id)) return operations.ExtractOperationResponse( create_op, apis.GetMessagesModule('cloudresourcemanager', 'v1').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) # 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 Run(self, args): """Run 'services enable'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: Nothing. """ project = properties.VALUES.core.project.Get(required=True) for service_name in args.service: service_name = arg_parsers.GetServiceNameFromArg(service_name) operation = enable_api.EnableServiceApiCall(project, service_name) services_util.ProcessOperationResult(operation, args. async)