feat: Add new gcloud commands, API clients, and third-party libraries across various services.

This commit is contained in:
2026-01-01 20:26:35 +01:00
parent 5e23cbece0
commit a19e592eb7
25221 changed files with 8324611 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The command group for the projects CLI."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import util
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class Projects(base.Group):
"""Create and manage project access policies.
The {command} group lets you create and manage IAM policies for projects on
the Google Cloud Platform. Resources are organized hierarchically and assigned
to a particular project. A Project resource is required to use Google Cloud
Platform, and forms the basis for creating, enabling and using all Cloud
Platform services, managing APIs, enabling billing, adding and removing
collaborators, and managing permissions.
More information on the Cloud Platform Resource Hierarchy and the project
resource can be found here:
https://cloud.google.com/resource-manager/docs/creating-managing-organization
and detailed documentation on creating and managing projects can be found
here:
https://cloud.google.com/resource-manager/docs/creating-managing-projects
"""
category = base.MANAGEMENT_TOOLS_CATEGORY
@staticmethod
def Args(parser):
parser.display_info.AddUriFunc(util.ProjectsUriFunc)
def Filter(self, context, args):
del context, args
# Don't ever take this off. Use gcloud quota for projects operations so
# you can create a project before you have a project.
base.DisableUserProjectQuota()

View File

@@ -0,0 +1,43 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Add IAM policy binding for a project
description: |
Adds a policy binding to the IAM policy of a project, given a
project ID and the binding. One binding consists of a member, a role, and
an optional condition.
examples: |
To add an IAM policy binding for the role of `roles/editor` for the user
`test-user@gmail.com` on a project with identifier `example-project-id-1`,
run:
$ {command} example-project-id-1 --member='user:test-user@gmail.com' --role='roles/editor'
To add an IAM policy binding for the role of `roles/editor` to the service
account `test-proj1@example.domain.com` on a project with identifier `example-project-id-1`,
run:
$ {command} example-project-id-1 --member='serviceAccount:test-proj1@example.domain.com' --role='roles/editor'
To add an IAM policy binding that expires at the end of the year 2021 for
the role of `roles/browser` and the user `test-user@gmail.com` on a project
with identifier `example-project-id-1`, run:
$ {command} example-project-id-1 --member='user:test-user@gmail.com' --role='roles/browser' --condition='expression=request.time < timestamp("2019-01-01T00:00:00Z"),title=expires_end_of_2021,description=Expires at midnight on 2021-12-31'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
request:
collection: cloudresourcemanager.projects
use_relative_name: false
arguments:
resource:
help_text: The project to add the IAM policy binding.
spec: !REF googlecloudsdk.command_lib.projects.resources:project
iam:
enable_condition: true
policy_version: 3
get_iam_policy_version_path: getIamPolicyRequest.options.requestedPolicyVersion

View File

@@ -0,0 +1,188 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to create a new project."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.api_lib.cloudresourcemanager import projects_util
from googlecloudsdk.api_lib.resource_manager import operations
from googlecloudsdk.api_lib.services import enable_api
from googlecloudsdk.api_lib.util import apis
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.projects import flags as project_flags
from googlecloudsdk.command_lib.projects import util as command_lib_projects_util
from googlecloudsdk.command_lib.resource_manager import flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import exceptions as core_exceptions
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
from googlecloudsdk.core.console import console_io
ID_DESCRIPTION = ('Project IDs are immutable and can be set only during '
'project creation. They must start with a lowercase letter '
'and can have lowercase ASCII letters, digits or hyphens. '
'Project IDs must be between 6 and 30 characters.')
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA)
class Create(base.CreateCommand):
"""Create a new project.
Creates a new project with the given project ID. By default, projects are not
created under a parent resource. To do so, use either the `--organization` or
`--folder` flag.
## EXAMPLES
The following command creates a project with ID `example-foo-bar-1`, name
`Happy project` and label `type=happy`:
$ {command} example-foo-bar-1 --name="Happy project" --labels=type=happy
By default, projects are not created under a parent resource. The following
command creates a project with ID `example-2` with parent `folders/12345`:
$ {command} example-2 --folder=12345
The following command creates a project with ID `example-3` with parent
`organizations/2048`:
$ {command} example-3 --organization=2048
## SEE ALSO
{see_also}
"""
detailed_help = {'see_also': project_flags.CREATE_DELETE_IN_CONSOLE_SEE_ALSO}
@staticmethod
def Args(parser):
"""Default argument specification."""
labels_util.AddCreateLabelsFlags(parser)
if properties.IsDefaultUniverse():
type_ = arg_parsers.RegexpValidator(
r'[a-z][a-z0-9-]{5,29}', ID_DESCRIPTION
)
else:
type_ = arg_parsers.RegexpValidator(
r'^(?!.*-$)(((?:[a-z][\.a-z0-9-]{2,29})\:?)?(?:[a-z][a-z0-9-]{5,29})$)',
ID_DESCRIPTION,
)
parser.add_argument(
'id',
metavar='PROJECT_ID',
type=type_,
nargs='?',
help='ID for the project you want to create.\n\n{0}'.format(
ID_DESCRIPTION
),
)
parser.add_argument(
'--name',
help=(
'Name for the project you want to create. '
'If not specified, will use project id as name.'
),
)
parser.add_argument(
'--enable-cloud-apis',
action='store_true',
default=True
if properties.VALUES.core.universe_domain.Get() == 'googleapis.com'
else False,
help=arg_parsers.UniverseHelpText(
default='Enable `cloudapis.googleapis.com` during creation.',
universe_help='This is not available.\n',
),
)
parser.add_argument(
'--set-as-default',
action='store_true',
default=False,
help='Set newly created project as [core/project] property.',
)
flags.TagsFlag().AddToParser(parser)
flags.OrganizationIdFlag('to use as a parent').AddToParser(parser)
flags.FolderIdFlag('to use as a parent').AddToParser(parser)
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_projects_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 or a name must be provided for the new project')
project_ref = command_lib_projects_util.ParseProject(project_id)
labels = labels_util.ParseCreateArgs(
args, projects_util.GetMessages().Project.LabelsValue)
tags = flags.GetTagsFromFlags(
args, projects_util.GetMessages().Project.TagsValue)
try:
create_op = projects_api.Create(
project_ref,
display_name=args.name,
parent=projects_api.ParentNameToResourceId(
flags.GetParentFromFlags(args)),
labels=labels,
tags=tags)
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)
project = operations.ExtractOperationResponse(
create_op, apis.GetMessagesModule('cloudresourcemanager', 'v1').Project
)
# Enable cloudapis.googleapis.com
if args.enable_cloud_apis:
log.debug('Enabling cloudapis.googleapis.com')
enable_api.EnableService(project_ref.Name(), 'cloudapis.googleapis.com')
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)
)
command_lib_projects_util.PrintEnvironmentTagMessage(
project.projectId
)
return project

View File

@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to delete a project."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.api_lib.smart_guardrails import smart_guardrails
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
from googlecloudsdk.command_lib.resource_manager import completers
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.UniverseCompatible
class Delete(base.DeleteCommand):
"""Delete a project.
Deletes the project with the given project ID.
This command can fail for the following reasons:
* The project specified does not exist.
* The active account does not have IAM role `role/owner` or another IAM role
with the `resourcemanager.projects.delete` permission for the given project.
See [Access control for projects using
IAM](https://cloud.google.com/resource-manager/docs/access-control-proj) for
more information.
## EXAMPLES
The following command deletes the project with the ID `example-foo-bar-1`:
$ {command} example-foo-bar-1
## SEE ALSO
{see_also}
"""
detailed_help = {'see_also': flags.CREATE_DELETE_IN_CONSOLE_SEE_ALSO}
@classmethod
def Args(cls, parser):
flags.GetProjectIDNumberFlag('delete').AddToParser(parser)
if cls.ReleaseTrack() != base.ReleaseTrack.GA:
flags.GetRecommendFlag('project deletion').AddToParser(parser)
parser.display_info.AddCacheUpdater(completers.ProjectCompleter)
def Run(self, args):
project_ref = command_lib_util.ParseProject(args.id)
if self.ReleaseTrack() != base.ReleaseTrack.GA and args.recommend:
# Projects command group explicitly disables user project quota.
# Call with user project quota enabled, so that
# default project can be used as quota project.
base.EnableUserProjectQuota()
prompt_message = smart_guardrails.GetProjectDeletionRisk(
base.ReleaseTrack.GA,
project_ref.Name(),
)
base.DisableUserProjectQuota()
else:
prompt_message = 'Your project will be deleted: [{0}]'.format(args.id)
if not console_io.PromptContinue(prompt_message):
return None
result = projects_api.Delete(project_ref)
log.DeletedResource(project_ref)
# Print this here rather than in Epilog because Epilog doesn't have access
# to the deleted resource.
# We can't be more specific than "limited period" because the API says
# "at an unspecified time".
log.status.Print(
'\nYou can undo this operation for a limited period by running'
' the command below.\n $ gcloud projects undelete {1}\n\n{0}'.format(
flags.SHUT_DOWN_PROJECTS, args.id))
return result

View File

@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to show metadata for a specified project."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
class Describe(base.DescribeCommand):
"""Show metadata for a project.
Shows metadata for a project given a valid project ID.
This command can fail for the following reasons:
* The project specified does not exist.
* The active account does not have permission to access the given project.
## EXAMPLES
The following command prints metadata for a project with the ID
`example-foo-bar-1`:
$ {command} example-foo-bar-1
"""
@staticmethod
def Args(parser):
flags.GetProjectIDNumberFlag('describe').AddToParser(parser)
def Run(self, args):
project_ref = command_lib_util.ParseProject(args.id)
return projects_api.Get(project_ref)

View File

@@ -0,0 +1,23 @@
- release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Get the ancestors for a project.
description: |
*{command}* displays the ancestors for a project. Projects may be grouped under folders and an organization. This comand will print the folder and organization hierarchy for the given project.
examples: |
To print the ancestors for a project with ID `my-project`, run:
$ {command} my-project
request:
collection: cloudresourcemanager.projects
use_relative_name: false
method: getAncestry
arguments:
resource:
help_text: The project for which to display ancestors.
spec: !REF googlecloudsdk.command_lib.projects.resources:project
output:
flatten: ['ancestor[].resourceId']
format: table(id, type)

View File

@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to get IAM policy for a resource and its ancestors."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.iam import policies_flags
from googlecloudsdk.command_lib.projects import flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
class GetIamPolicy(base.ListCommand):
"""Get IAM policies for a project and its ancestors.
Get IAM policies for a project and its ancestors, given a project ID.
## EXAMPLES
To get IAM policies for project `example-project-id-1` and its ancestors, run:
$ {command} example-project-id-1
"""
@staticmethod
def Args(parser):
flags.GetProjectResourceArg('get IAM policy for').AddToParser(parser)
base.URI_FLAG.RemoveFromParser(parser)
policies_flags.AddIncludeDenyFlag(parser)
def Run(self, args):
return command_lib_util.GetIamPolicyWithAncestors(args.project_id,
args.include_deny,
self.ReleaseTrack())

View File

@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to get IAM policy for a resource."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class GetIamPolicy(base.ListCommand):
"""Get IAM policy for a project.
Gets the IAM policy for a project, given a project ID.
## EXAMPLES
The following command prints the IAM policy for a project with the ID
`example-project-id-1`:
$ {command} example-project-id-1
"""
@staticmethod
def Args(parser):
flags.GetProjectIDNumberFlag('get IAM policy for').AddToParser(parser)
base.URI_FLAG.RemoveFromParser(parser)
def Run(self, args):
project_ref = command_lib_util.ParseProject(args.id)
return projects_api.GetIamPolicy(project_ref)

View File

@@ -0,0 +1,28 @@
- release_tracks: [ALPHA]
help_text:
brief: Get the IAM policy for a project.
description: |
*{command}* displays the IAM policy associated with a project.
If formatted as JSON, the output can be edited and used as
a policy file for *set-iam-policy*. The output includes an "etag"
field identifying the version emitted and allowing detection of
concurrent policy updates; see
$ {parent} set-iam-policy for additional details.
examples: |
To print the IAM policy for a given project, run:
$ {command} my-project
request:
collection: cloudresourcemanager.projects
use_relative_name: false
arguments:
resource:
help_text: The project for which to display the IAM policy.
spec: !REF googlecloudsdk.command_lib.projects.resources:project
iam:
policy_version: 3
get_iam_policy_version_path: getIamPolicyRequest.options.requestedPolicyVersion

View File

@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to list all project IDs associated with the active user."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import filter_rewrite
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import util as command_lib_util
from googlecloudsdk.command_lib.resource_manager import flags
from googlecloudsdk.core import log
from googlecloudsdk.core.resource import resource_projection_spec
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListAlpha(base.ListCommand):
"""List projects for which the user has resourcemanager.projects.list permission.
List all projects to which the user has access under the specified
parent (either an Organization or a Folder). Exactly one of --folder
or --organization can be provided.
The output format slightly differs from the Beta and GA versions.
## EXAMPLES
The following command lists projects under the organization with
ID `123456789`:
$ {command} --organization=123456789
The following command lists projects with display names starting with a
under folder with ID `123456789`:
$ {command} --folder=123456789 --filter='displayName:a*'
The following command lists the last five created projects, sorted
alphabetically by project ID:
$ {command} --sort-by=projectId --limit=5
To list projects that have been marked for deletion:
$ {command} --filter='lifecycleState:DELETE_REQUESTED'
"""
@staticmethod
def Args(parser):
flags.FolderIdFlag('to list projects under').AddToParser(parser)
flags.OrganizationIdFlag('to list projects under').AddToParser(parser)
parser.display_info.AddFormat(command_lib_util.LIST_FORMAT)
def Run(self, args):
"""Run the list command."""
display_info = args.GetDisplayInfo()
defaults = resource_projection_spec.ProjectionSpec(
symbols=display_info.transforms, aliases=display_info.aliases)
args.filter, server_filter = filter_rewrite.ListRewriter().Rewrite(
args.filter, defaults=defaults)
log.info('client_filter="%s" server_filter="%s"',
args.filter, server_filter)
server_limit = args.limit
if args.filter:
# We must use client-side limiting if we
# are using client-side filtering.
server_limit = None
if args.organization or args.folder:
flags.CheckParentFlags(args)
return projects_api.ListV3(parent=flags.GetParentFromFlags(args),
limit=args.limit, batch_size=args.page_size)
else:
return projects_api.List(limit=server_limit, filter=server_filter)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class List(base.ListCommand):
"""List projects accessible by the active account.
Lists all active projects, where the active account has Owner, Editor, Browser
or Viewer permissions. Projects are listed in alphabetical order by project
name. Projects that have been deleted or are pending deletion are not
included.
You can specify the maximum number of projects to list using the `--limit`
flag.
## EXAMPLES
The following command lists the last five created projects, sorted
alphabetically by project ID:
$ {command} --sort-by=projectId --limit=5
To list projects that have been marked for deletion:
$ {command} --filter='lifecycleState:DELETE_REQUESTED'
"""
@staticmethod
def Args(parser):
parser.display_info.AddFormat(command_lib_util.LIST_FORMAT)
def Run(self, args):
"""Run the list command."""
display_info = args.GetDisplayInfo()
defaults = resource_projection_spec.ProjectionSpec(
symbols=display_info.transforms, aliases=display_info.aliases)
args.filter, server_filter = filter_rewrite.ListRewriter().Rewrite(
args.filter, defaults=defaults)
log.info('client_filter="%s" server_filter="%s"',
args.filter, server_filter)
server_limit = args.limit
if args.filter:
# We must use client-side limiting if we are using client-side filtering.
server_limit = None
return projects_api.List(limit=server_limit, filter=server_filter)

View File

@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to move a project into an organization."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import flags as project_flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
from googlecloudsdk.command_lib.resource_manager import flags as folder_flags
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA)
class Move(base.Command):
"""Move a project into an organization.
Moves the given project into the given organization.
This command can fail for the following reasons:
* There is no project with the given ID.
* There is no organization with the given ID, if an organization is given
as the destination.
* There is no folder with the given ID, if a folder is given as the
destination.
* More than one of organization or folder is provided.
* The active account does not have the
resourcemanager.projects.update permission for the given
project.
* The active account does not have the
resourcemanager.projects.create permission for the given
organization.
* The given project is already in an organization.
## EXAMPLES
The following command moves a project with the ID `super-awesome-project` into
the organization `25872158`:
$ {command} super-awesome-project --organization=25872158
"""
@staticmethod
def Args(parser):
project_flags.GetProjectIDNumberFlag('move').AddToParser(parser)
folder_flags.AddParentFlagsToParser(parser)
parser.display_info.AddFormat(command_lib_util.LIST_FORMAT)
def Run(self, args):
folder_flags.CheckParentFlags(args)
project_ref = command_lib_util.ParseProject(args.id)
if not console_io.PromptContinue(
'Your project will be moved. This may alter the policies enforced on '
'your Project, either exposing your Project to more security risk '
'through looser polices or cause an outage through stricter polices. '
'See these public notes on policy implications for more information: '
'https://cloud.google.com/resource-manager/docs/'
'creating-managing-folders#moving-folders-policy-considerations and '
'https://cloud.google.com/resource-manager/docs/'
'migrating-projects-billing#note_on_policy_implications. '
'Once moved, you can move the Project again so long as you have the '
'appropriate permissions. See our public documentation for more '
'information: https://cloud.google.com/resource-manager/docs/'
'creating-managing-folders#moving_a_project_into_a_folder'
):
return None
result = projects_api.Update(
project_ref,
parent=projects_api.ParentNameToResourceId(
folder_flags.GetParentFromFlags(args)))
log.UpdatedResource(project_ref)
return result

View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to remove IAM policy binding for a resource."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.api_lib.smart_guardrails import smart_guardrails
from googlecloudsdk.api_lib.util import http_retry
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.iam import iam_util
from googlecloudsdk.command_lib.projects import flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
from googlecloudsdk.command_lib.resource_manager import completers
from googlecloudsdk.core.console import console_io
import six.moves.http_client
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA)
class RemoveIamPolicyBinding(base.Command):
"""Remove IAM policy binding from the IAM policy of a project.
Removes a policy binding from the IAM policy of a project, given a project ID
and the binding.
"""
detailed_help = command_lib_util.GetDetailedHelpForRemoveIamPolicyBinding()
@classmethod
def Args(cls, parser):
flags.GetProjectResourceArg('remove IAM policy binding from').AddToParser(
parser
)
iam_util.AddArgsForRemoveIamPolicyBinding(
parser,
role_completer=completers.ProjectsIamRolesCompleter,
add_condition=True,
)
if cls.ReleaseTrack() != base.ReleaseTrack.GA:
flags.GetRecommendFlag('IAM policy binding removal').AddToParser(parser)
@http_retry.RetryOnHttpStatus(six.moves.http_client.CONFLICT)
def Run(self, args):
project_ref = command_lib_util.ParseProject(args.project_id)
condition = iam_util.ValidateAndExtractConditionMutexRole(args)
# If recommend is enabled and there is no condition,
# get risk assesment from Smart Guardrails.
if (
self.ReleaseTrack() != base.ReleaseTrack.GA
and args.recommend
and not condition
):
# Projects command group explicitly disables user project quota.
# Call with user project quota enabled, so that
# default project can be used as quota project.
base.EnableUserProjectQuota()
risk_message = smart_guardrails.GetIamPolicyBindingDeletionRisk(
base.ReleaseTrack.GA, project_ref.Name(), args.member, args.role
)
base.DisableUserProjectQuota()
if risk_message:
if not console_io.PromptContinue(risk_message):
return None
result = projects_api.RemoveIamPolicyBindingWithCondition(
project_ref, args.member, args.role, condition, args.all
)
iam_util.LogSetIamPolicy(args.project_id, 'project')
return result

View File

@@ -0,0 +1,51 @@
release_tracks: [GA]
help_text:
brief: Remove IAM policy binding for a project.
description: |
Removes a policy binding to the IAM policy of a project, given a
project ID and the binding. One binding consists of a member, a role and an
optional condition.
examples: |
To remove an IAM policy binding for the role of `roles/editor` for the user
`test-user@gmail.com` on project with identifier `example-project-id-1`,
run:
$ {command} example-project-id-1 --member='user:test-user@gmail.com' --role='roles/editor'
To remove an IAM policy binding for the role of `roles/editor` from all
authenticated users on project `example-project-id-1`, run:
$ {command} example-project-id-1 --member='allAuthenticatedUsers' --role='roles/editor'
To remove an IAM policy binding with a condition of
`expression='request.time < timestamp("2019-01-01T00:00:00Z")',
title='expires_end_of_2018'`, and description=`Expires at midnight on
2018-12-31` for the role of `roles/browser` for the user
`test-user@gmail.com` on project with identifier `example-project-id-1`,
run:
$ {command} example-project-id-1 --member='user:test-user@gmail.com' --role='roles/browser' --condition='expression=request.time < timestamp("2019-01-01T00:00:00Z"),title=expires_end_of_2018,description=Expires at midnight on 2018-12-31'
To remove all IAM policy bindings regardless of the condition for the role
of `roles/browser` and for the user `test-user@gmail.com` on project with
identifier `example-project-id-1`, run:
$ {command} example-project-id-1 --member='user:test-user@gmail.com' --role='roles/browser' --all
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
request:
collection: cloudresourcemanager.projects
use_relative_name: false
arguments:
resource:
help_text: The project to remove the IAM policy binding from.
spec: !REF googlecloudsdk.command_lib.projects.resources:project
iam:
enable_condition: true
policy_version: 3
get_iam_policy_version_path: getIamPolicyRequest.options.requestedPolicyVersion

View File

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to search projects associated with the active user."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import sys
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class Search(base.Command):
"""Search for projects matching the given query.
You can specify the maximum number of projects to list using the `--limit`
flag.
## EXAMPLES
The following command lists the last five created projects with
names starting with z, sorted by the project number (now called name)
with 2 projects listed on each page
$ {command} --query="name:z*" --sort-by=name --limit=5 --page-size=2
To list projects that have been marked for deletion:
$ {command} --query='state:DELETE_REQUESTED'
"""
@staticmethod
def Args(parser):
parser.display_info.AddFormat("""
table(
displayName,
name,
parent,
state
)
""")
base.LIMIT_FLAG.AddToParser(parser)
base.SORT_BY_FLAG.AddToParser(parser)
parser.add_argument(
'--query',
help="""\
A boolean expression for the search criteria used to select the projects to return.
If no search criteria is specified then all accessible projects will be returned.
Query expressions can be used to restrict results based upon displayName, state
and parent, where the operators `=` (`:`) `NOT`, `AND` and `OR` can be used along
with the suffix wildcard symbol `*`. The `displayName` field in a query expression should
use escaped quotes for values that include whitespace to prevent unexpected behavior.
""")
parser.add_argument(
'--page-size',
type=arg_parsers.BoundedInt(1, sys.maxsize, unlimited=True),
require_coverage_in_tests=False,
category=base.LIST_COMMAND_FLAGS,
help="""\
This flag specifies the maximum number of projects per page.
""")
def Run(self, args):
"""Run the search command."""
return projects_api.Search(limit=args.limit, query=args.query)

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to set IAM policy for a resource."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.iam import iam_util
from googlecloudsdk.command_lib.projects import flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class SetIamPolicy(base.Command):
"""Set IAM policy for a project.
Sets the IAM policy for a project, given a project ID and a file encoded in
JSON or YAML that contains the IAM policy.
## EXAMPLES
The following command reads an IAM policy defined in a JSON file `policy.json`
and sets it for a project with the ID `example-project-id-1`:
$ {command} example-project-id-1 policy.json
"""
@staticmethod
def Args(parser):
flags.GetProjectIDNumberFlag('set IAM policy for').AddToParser(parser)
iam_util.AddArgForPolicyFile(parser)
def Run(self, args):
project_ref = command_lib_util.ParseProject(args.id)
results = projects_api.SetIamPolicyFromFile(project_ref, args.policy_file)
iam_util.LogSetIamPolicy(project_ref.Name(), 'project')
return results

View File

@@ -0,0 +1,27 @@
- release_tracks: [ALPHA]
help_text:
brief: Set IAM policy for a project.
description: |
Sets the IAM policy for a project, given a project ID and a file encoded
in JSON or YAML that contains the IAM policy.
examples: |
The following command reads an IAM policy defined in a JSON file
`policy.json` and sets it for a project with the ID
`example-project-id-1`:
$ {command} example-project-id-1 policy.json
See https://cloud.google.com/iam/docs/managing-policies for details of the
policy file format and contents.
request:
collection: cloudresourcemanager.projects
use_relative_name: false
modify_request_hooks:
- googlecloudsdk.command_lib.projects.util:SetIamPolicyFromFileHook
- googlecloudsdk.command_lib.iam.hooks:UseMaxRequestedPolicyVersion:api_field=setIamPolicyRequest.policy.version
arguments:
resource:
help_text: The project to set the IAM policy for.
spec: !REF googlecloudsdk.command_lib.projects.resources:project

View File

@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to undelete a project."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
from googlecloudsdk.core import log
class Undelete(base.CreateCommand):
"""Undelete a project.
Undeletes the project with the given project ID.
This command can fail for the following reasons:
* There is no project with the given ID.
* The active account does not have Owner or Editor permissions for the
given project.
## EXAMPLES
The following command undeletes the project with the ID `example-foo-bar-1`:
$ {command} example-foo-bar-1
## SEE ALSO
{see_also}
"""
detailed_help = {'see_also': flags.CREATE_DELETE_IN_CONSOLE_SEE_ALSO}
@staticmethod
def Args(parser):
flags.GetProjectIDNumberFlag('undelete').AddToParser(parser)
def Run(self, args):
project_ref = command_lib_util.ParseProject(args.id)
result = projects_api.Undelete(project_ref)
log.RestoredResource(project_ref, kind='project')
return result

View File

@@ -0,0 +1,107 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command to update a new project."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.cloudresourcemanager import projects_api
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import flags
from googlecloudsdk.command_lib.projects import util as command_lib_util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(base.UpdateCommand):
"""Update the name and/or labels of a project.
Update the name and/or labels of the given project.
This command can fail for the following reasons:
* There is no project with the given ID.
* The active account does not have Owner or Editor permissions for the
given project.
## EXAMPLES
The following command updates a project with the ID
`example-foo-bar-1` to have the name `Foo Bar & Grill` and removes the
label `dive`:
$ {command} example-foo-bar-1 --name="Foo Bar & Grill" --remove-labels=dive
The following command updates a project with the ID `example-foo-bar-1` to
have labels `foo` and `bar` with values of `abc` and `def`, respectively:
$ {command} example-foo-bar-1 --update-labels="foo=abc,bar=def"
"""
@staticmethod
def Args(parser):
flags.GetProjectIDNumberFlag('update').AddToParser(parser)
update_flags = parser.add_group(required=True)
update_flags.add_argument('--name', help='New name for the project.')
labels_group = update_flags.add_group('Labels Flags')
labels_util.AddUpdateLabelsFlags(labels_group)
parser.display_info.AddFormat(command_lib_util.LIST_FORMAT)
def Run(self, args):
labels_diff = labels_util.Diff.FromUpdateArgs(args)
project_ref = command_lib_util.ParseProject(args.id)
result = projects_api.Update(project_ref, name=args.name,
labels_diff=labels_diff)
log.UpdatedResource(project_ref)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update the name of a project.
Update the name of the given project.
This command can fail for the following reasons:
* There is no project with the given ID.
* The active account does not have Owner or Editor permissions for the
given project.
## EXAMPLES
The following command updates a project with the ID
`example-foo-bar-1` to have the name `Foo Bar & Grill`:
$ {command} example-foo-bar-1 --name="Foo Bar & Grill"
"""
def GetUriFunc(self):
return command_lib_util.ProjectsUriFunc
@staticmethod
def Args(parser):
flags.GetProjectFlag('update').AddToParser(parser)
parser.add_argument('--name', required=True,
help='New name for the project.')
def Run(self, args):
project_ref = command_lib_util.ParseProject(args.id)
result = projects_api.Update(project_ref, name=args.name,
labels_diff=labels_util.Diff())
log.UpdatedResource(project_ref)
return result