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,126 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""This file provides the implementation of the `functions add-iam-policy-binding` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.command_lib.functions import run_util
from googlecloudsdk.command_lib.functions.v2.add_invoker_policy_binding import command as add_invoker_policy_binding_command
from googlecloudsdk.command_lib.iam import iam_util
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
def Run(args, release_track):
"""Adds a binding to the IAM policy for a Google Cloud Function.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
release_track: The relevant value from the
googlecloudsdk.calliope.base.ReleaseTrack enum.
Returns:
The updated IAM policy.
"""
client = api_util.GetClientInstance(release_track=release_track)
messages = api_util.GetMessagesModule(release_track=release_track)
function_ref = args.CONCEPTS.name.Parse()
function_relative_name = function_ref.RelativeName()
if args.role == 'roles/run.invoker':
log.warning(
'The role [roles/run.invoker] cannot be bound to a Cloud Function IAM'
' policy as it is a Cloud Run role. For 2nd gen functions, this role'
' must be granted on the underlying Cloud Run service. This'
' can be done by running the `gcloud functions'
' add-invoker-policy-binding` comand.\n'
)
if console_io.CanPrompt() and console_io.PromptContinue(
prompt_string=(
'Would you like to run this command instead and grant [{}]'
' permission to invoke function [{}]'.format(
args.member, function_ref.Name()
)
)
):
return add_invoker_policy_binding_command.Run(args, release_track)
policy = client.projects_locations_functions.GetIamPolicy(
messages.CloudfunctionsProjectsLocationsFunctionsGetIamPolicyRequest(
resource=function_relative_name))
iam_util.AddBindingToIamPolicy(
messages.Binding, policy, args.member, args.role
)
policy = client.projects_locations_functions.SetIamPolicy(
messages.CloudfunctionsProjectsLocationsFunctionsSetIamPolicyRequest(
resource=function_relative_name,
setIamPolicyRequest=messages.SetIamPolicyRequest(policy=policy),
)
)
if args.role in [
'roles/cloudfunctions.admin',
'roles/cloudfunctions.developer',
'roles/cloudfunctions.invoker',
]:
log.warning(
'The role [{role}] was successfully bound to member [{member}] but this'
' does not grant the member permission to invoke 2nd gen function'
' [{name}]. Instead, the role [roles/run.invoker] must be granted on'
' the underlying Cloud Run service. This can be done by running the'
' `gcloud functions add-invoker-policy-binding` command.\n'.format(
role=args.role, member=args.member, name=function_ref.Name()
)
)
if console_io.CanPrompt() and console_io.PromptContinue(
prompt_string=(
'Would you like to run this command and additionally grant [{}]'
' permission to invoke function [{}]'
).format(args.member, function_ref.Name()),
):
function = client.projects_locations_functions.Get(
messages.CloudfunctionsProjectsLocationsFunctionsGetRequest(
name=function_ref.RelativeName()
)
)
run_util.AddOrRemoveInvokerBinding(
function, args.member, add_binding=True
)
log.status.Print(
'The role [roles/run.invoker] was successfully bound to the'
' underlying Cloud Run service. You can view its IAM policy by'
' running:\n'
'gcloud run services get-iam-policy {}\n'.format(
function.serviceConfig.service
)
)
return policy
log.status.Print(
'Additional information on authenticating function calls can be found'
' at:\n'
'https://cloud.google.com/functions/docs/securing/authenticating#authenticating_function_to_function_calls'
)
return policy

View File

@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""This file provides the implementation of the `functions add-invoker-policy-binding` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.command_lib.functions import run_util
CLOUD_RUN_SERVICE_COLLECTION_K8S = 'run.namespaces.services'
CLOUD_RUN_SERVICE_COLLECTION_ONE_PLATFORM = 'run.projects.locations.services'
def Run(args, release_track):
"""Add an invoker binding to the IAM policy of a Google Cloud Function."""
client = api_util.GetClientInstance(release_track=release_track)
messages = api_util.GetMessagesModule(release_track=release_track)
function_ref = args.CONCEPTS.name.Parse()
function = client.projects_locations_functions.Get(
messages.CloudfunctionsProjectsLocationsFunctionsGetRequest(
name=function_ref.RelativeName()))
return run_util.AddOrRemoveInvokerBinding(
function, args.member, add_binding=True
)

View File

@@ -0,0 +1,81 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""Calls cloud run service of a Google Cloud Function."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import util as v2_api_util
from googlecloudsdk.command_lib.config import config_helper
from googlecloudsdk.command_lib.functions import call_util
from googlecloudsdk.core.credentials import store
def GenerateIdToken(impersonate_service_account: bool = False):
"""Generate an expiring Google-signed OAuth2 identity token.
Args:
impersonate_service_account: bool, whether to enable a service account
impersonationwhen generating the token.
Returns:
token: str, expiring Google-signed OAuth2 identity token
"""
# str | None, account is either a user account or google service account.
account = None
# oauth2client.client.OAuth2Credentials |
# core.credentials.google_auth_credentials.Credentials
cred = store.Load(
# if account is None, implicitly retrieves properties.VALUES.core.account
account,
allow_account_impersonation=True,
use_google_auth=True)
# sets token on property of either
# credentials.token_response['id_token'] or
# credentials.id_tokenb64
store.Refresh(cred, is_impersonated_credential=impersonate_service_account)
credential = config_helper.Credential(cred)
# str, Expiring Google-signed OAuth2 identity token
token = credential.id_token
return token
def Run(args, release_track):
"""Call a v2 Google Cloud Function."""
v2_client = v2_api_util.GetClientInstance(release_track=release_track)
v2_messages = v2_client.MESSAGES_MODULE
function_ref = args.CONCEPTS.name.Parse()
# cloudfunctions_v2alpha_messages.Function
function = v2_client.projects_locations_functions.Get(
v2_messages.CloudfunctionsProjectsLocationsFunctionsGetRequest(
name=function_ref.RelativeName()))
call_util.UpdateHttpTimeout(args, function, 'v2', release_track)
cloud_run_uri = function.serviceConfig.uri
token = GenerateIdToken(args.IsSpecified('impersonate_service_account'))
auth_header = {'Authorization': 'Bearer {}'.format(token)}
return call_util.MakePostRequest(
cloud_run_uri, args, extra_headers=auth_header)

View File

@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""This file provides the implementation of the `functions delete` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import exceptions
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
def Run(args, release_track):
"""Delete a Google Cloud Function."""
client = api_util.GetClientInstance(release_track=release_track)
messages = api_util.GetMessagesModule(release_track=release_track)
function_ref = args.CONCEPTS.name.Parse()
function_relative_name = function_ref.RelativeName()
prompt_message = '2nd gen function [{0}] will be deleted.'.format(
function_relative_name
)
if not console_io.PromptContinue(message=prompt_message):
raise exceptions.FunctionsError('Deletion aborted by user.')
operation = client.projects_locations_functions.Delete(
messages.CloudfunctionsProjectsLocationsFunctionsDeleteRequest(
name=function_relative_name))
api_util.WaitForOperation(client, messages, operation, 'Deleting function')
log.DeletedResource(function_relative_name)

View File

@@ -0,0 +1,120 @@
# -*- 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.
"""'functions deploy' utilities for environment variables."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import argparse
from googlecloudsdk.command_lib.util.args import map_util
import six
def EnvVarKeyType(key):
"""Validator for environment variable keys.
Args:
key: The environment variable key.
Returns:
The environment variable key.
Raises:
ArgumentTypeError: If the key is not a valid environment variable key.
"""
if not key:
raise argparse.ArgumentTypeError(
'Environment variable keys cannot be empty.'
)
if key.startswith('X_GOOGLE_'):
raise argparse.ArgumentTypeError(
'Environment variable keys that start with `X_GOOGLE_` are reserved '
'for use by deployment tools and cannot be specified manually.'
)
if '=' in key:
raise argparse.ArgumentTypeError(
'Environment variable keys cannot contain `=`.'
)
return key
def EnvVarValueType(value):
if not isinstance(value, six.text_type):
raise argparse.ArgumentTypeError(
'Environment variable values must be strings. Found {} (type {})'
.format(value, type(value))
)
return value
def AddUpdateEnvVarsFlags(parser):
"""Add flags for setting and removing environment variables.
Args:
parser: The argument parser.
"""
map_util.AddUpdateMapFlags(
parser,
'env-vars',
long_name='environment variables',
key_type=EnvVarKeyType,
value_type=EnvVarValueType,
)
def BuildEnvVarKeyType(key):
"""Validator for build environment variable keys.
All existing validations for environment variables are also applicable for
build environment variables.
Args:
key: The build environment variable key.
Returns:
The build environment variable key type.
Raises:
ArgumentTypeError: If the key is not valid.
"""
if key in [
'GOOGLE_ENTRYPOINT',
'GOOGLE_FUNCTION_TARGET',
'GOOGLE_RUNTIME',
'GOOGLE_RUNTIME_VERSION',
]:
raise argparse.ArgumentTypeError(
'{} is reserved for internal use by GCF deployments and cannot be used.'
.format(key)
)
return EnvVarKeyType(key)
def BuildEnvVarValueType(value):
return value
def AddBuildEnvVarsFlags(parser):
"""Add flags for managing build environment variables.
Args:
parser: The argument parser.
"""
map_util.AddUpdateMapFlags(
parser,
'build-env-vars',
long_name='build environment variables',
key_type=BuildEnvVarKeyType,
value_type=BuildEnvVarValueType,
)

View File

@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
"""Utility functions for Functions specific to deploying Gen2 functions."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.command_lib.projects import util as projects_util
def ensure_pubsub_sa_has_token_creator_role():
"""Ensures the project's Pub/Sub service account has permission to create tokens.
If the permission is missing, prompts the user to grant it. If the console
cannot prompt, prints a warning instead.
"""
pubsub_sa = 'service-{}@gcp-sa-pubsub.iam.gserviceaccount.com'.format(
projects_util.GetProjectNumber(api_util.GetProject())
)
api_util.PromptToBindRoleIfMissing(
pubsub_sa,
'roles/iam.serviceAccountTokenCreator',
alt_roles=['roles/pubsub.serviceAgent'],
reason=(
'Pub/Sub needs this role to create identity tokens. '
'For more details, please see '
'https://cloud.google.com/pubsub/docs/push#authentication'
),
)
def ensure_data_access_logs_are_enabled(trigger_event_filters):
# type: (list[cloudfunctions_v2_messages.EventFilter]) -> None
"""Ensures appropriate Data Access Audit Logs are enabled for the given event filters.
If they're not, the user will be prompted to enable them or warned if the
console cannot prompt.
Args:
trigger_event_filters: the CAL trigger's event filters.
"""
service_filter = [
f for f in trigger_event_filters if f.attribute == 'serviceName'
]
if service_filter:
api_util.PromptToEnableDataAccessAuditLogs(service_filter[0].value)

View File

@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""List event types available to Google Cloud Functions v2."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.eventarc import providers
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.eventarc.types import EventType
from googlecloudsdk.core import properties
def Run(args, release_track):
"""Lists GCF v2 available event_types.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
release_track: base.ReleaseTrack, The release track (ga, beta, alpha)
Returns:
event_types: List[EventType], The list of supported event types.
"""
del release_track
client = providers.ProvidersClient(base.ReleaseTrack.GA)
project = args.project or properties.VALUES.core.project.GetOrFail()
provider_list = client.List(
'projects/{}/locations/-'.format(project), limit=None, page_size=None)
event_types = {}
for p in provider_list:
for t in p.eventTypes:
name = t.type
description = '{}: {}'.format(p.displayName, t.description)
attributes = ','.join(fa.attribute for fa in t.filteringAttributes)
if name not in event_types:
event_types[name] = EventType(name, description, attributes)
return [v for k, v in event_types.items()]

View File

@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""This file provides the implementation of the `functions get-iam-policy` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.core import log
def Run(args, release_track):
"""Get the IAM policy for a Google Cloud Function."""
client = api_util.GetClientInstance(release_track=release_track)
messages = api_util.GetMessagesModule(release_track=release_track)
function_ref = args.CONCEPTS.name.Parse()
function_relative_name = function_ref.RelativeName()
function = client.projects_locations_functions.Get(
messages.CloudfunctionsProjectsLocationsFunctionsGetRequest(
name=function_ref.RelativeName()
)
)
log.warning(
'To view more details about the invoker policy in the underlying Cloud'
' Run Service, please run:\n\n gcloud run services get-iam-policy {}\n'
.format(function.serviceConfig.service)
)
return client.projects_locations_functions.GetIamPolicy(
messages.CloudfunctionsProjectsLocationsFunctionsGetIamPolicyRequest(
resource=function_relative_name
)
)

View File

@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""This file provides the implementation of the `functions list` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import list_pager
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
def _YieldFromLocations(
locations, project, limit, messages, client, filter_exp
):
"""Yield the functions from the given locations.
Args:
locations: List[str], list of gcp regions.
project: str, Name of the API to modify. E.g. "cloudfunctions"
limit: int, List messages limit.
messages: module, Generated messages module.
client: base_api.BaseApiClient, cloud functions client library.
filter_exp: Filter expression in list functions request.
Yields:
protorpc.message.Message, The resources listed by the service.
"""
def _ReadAttrAndLogUnreachable(message, attribute):
if message.unreachable:
log.warning(
(
'The following regions were fully or partially unreachable '
'for query: %s\n'
'This could be due to permission setup. Additional information'
'can be found in: '
'https://cloud.google.com/functions/docs/troubleshooting'
),
', '.join(message.unreachable),
)
return getattr(message, attribute)
for location in locations:
location_ref = resources.REGISTRY.Parse(
location,
params={'projectsId': project},
collection='cloudfunctions.projects.locations',
)
for function in list_pager.YieldFromList(
service=client.projects_locations_functions,
request=messages.CloudfunctionsProjectsLocationsFunctionsListRequest(
parent=location_ref.RelativeName(), filter=filter_exp
),
limit=limit,
field='functions',
batch_size_attribute='pageSize',
get_field_func=_ReadAttrAndLogUnreachable,
):
yield function
def Run(args, release_track, filter_exp=None):
"""List Google Cloud Functions."""
client = api_util.GetClientInstance(release_track=release_track)
messages = api_util.GetMessagesModule(release_track=release_track)
project = properties.VALUES.core.project.GetOrFail()
limit = args.limit
return _YieldFromLocations(
args.regions, project, limit, messages, client, filter_exp
)

View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""List regions available to Google Cloud Functions."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import client
def Run(args, release_track):
"""Lists GCF gen2 regions available with the given args.
Args:
args: argparse.Namespace, All the arguments that were provided to this
command invocation.
release_track: base.ReleaseTrack, The release track (ga, beta, alpha)
Returns:
Iterable[cloudfunctions_v2alpha.Location], Generator of available GCF gen2
regions.
"""
del args # unused by list command
return client.FunctionsClient(release_track).ListRegions()

View File

@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""This file provides the implementation of the `functions remove-iam-policy-binding` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.command_lib.functions import run_util
from googlecloudsdk.command_lib.iam import iam_util
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
def Run(args, release_track):
"""Removes a binding from the IAM policy for a Google Cloud Function."""
client = api_util.GetClientInstance(release_track=release_track)
messages = api_util.GetMessagesModule(release_track=release_track)
function_ref = args.CONCEPTS.name.Parse()
function_relative_name = function_ref.RelativeName()
policy = client.projects_locations_functions.GetIamPolicy(
messages.CloudfunctionsProjectsLocationsFunctionsGetIamPolicyRequest(
resource=function_relative_name
)
)
iam_util.RemoveBindingFromIamPolicy(policy, args.member, args.role)
policy = client.projects_locations_functions.SetIamPolicy(
messages.CloudfunctionsProjectsLocationsFunctionsSetIamPolicyRequest(
resource=function_relative_name,
setIamPolicyRequest=messages.SetIamPolicyRequest(policy=policy),
)
)
if args.role in [
'roles/cloudfunctions.admin',
'roles/cloudfunctions.developer',
'roles/cloudfunctions.invoker',
]:
log.warning(
'The binding between member {member} and role {role} has been'
' successfully removed. However, to make sure the member {member}'
" doesn't have the permission to invoke the 2nd gen function, you need"
' to remove the invoker binding in the underlying Cloud Run service.'
' This can be done by running the following command:\n '
' gcloud functions remove-invoker-policy-binding {function_ref}'
' --member={member} \n'.format(
member=args.member, role=args.role, function_ref=function_ref.Name()
)
)
if console_io.CanPrompt() and console_io.PromptContinue(
prompt_string=(
'Would you like to run this command and additionally deny [{}]'
' permission to invoke function [{}]'
).format(args.member, function_ref.Name()),
):
function = client.projects_locations_functions.Get(
messages.CloudfunctionsProjectsLocationsFunctionsGetRequest(
name=function_ref.RelativeName()
)
)
run_util.AddOrRemoveInvokerBinding(
function, args.member, add_binding=False
)
log.status.Print(
'The role [roles/run.invoker] was successfully removed for member '
'{member} in the underlying Cloud Run service. You can view '
'its IAM policy by running:\n'
'gcloud run services get-iam-policy {service}\n'.format(
service=function.serviceConfig.service, member=args.member
)
)
return policy

View File

@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""This file provides the implementation of the `functions remove-invoker-policy-binding` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.api_lib.run import global_methods
from googlecloudsdk.command_lib.run import connection_context
from googlecloudsdk.command_lib.run import serverless_operations
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
CLOUD_RUN_SERVICE_COLLECTION_K8S = 'run.namespaces.services'
CLOUD_RUN_SERVICE_COLLECTION_ONE_PLATFORM = 'run.projects.locations.services'
def Run(args, release_track):
"""Remove an invoker binding from the IAM policy of a Google Cloud Function."""
client = api_util.GetClientInstance(release_track=release_track)
messages = api_util.GetMessagesModule(release_track=release_track)
function_ref = args.CONCEPTS.name.Parse()
function = client.projects_locations_functions.Get(
messages.CloudfunctionsProjectsLocationsFunctionsGetRequest(
name=function_ref.RelativeName()))
service_ref_one_platform = resources.REGISTRY.ParseRelativeName(
function.serviceConfig.service, CLOUD_RUN_SERVICE_COLLECTION_ONE_PLATFORM)
run_connection_context = connection_context.RegionalConnectionContext(
service_ref_one_platform.locationsId, global_methods.SERVERLESS_API_NAME,
global_methods.SERVERLESS_API_VERSION)
with serverless_operations.Connect(run_connection_context) as operations:
service_ref_k8s = resources.REGISTRY.ParseRelativeName(
'namespaces/{}/services/{}'.format(
properties.VALUES.core.project.GetOrFail(),
service_ref_one_platform.Name()), CLOUD_RUN_SERVICE_COLLECTION_K8S)
return operations.AddOrRemoveIamPolicyBinding(
service_ref_k8s,
False, # Remove the binding
member=args.member,
role=serverless_operations.ALLOW_UNAUTH_POLICY_BINDING_ROLE)

View File

@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""List runtimes available to Google Cloud Functions."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import collections
from googlecloudsdk.api_lib.functions.v2 import client
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def Run(args, release_track):
"""Lists GCF runtimes available with the given args from the v2 API.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
release_track: base.ReleaseTrack, The release track (ga, beta, alpha)
Returns:
List[Runtime], List of available GCF runtimes
"""
del args
if not properties.VALUES.functions.region.IsExplicitlySet():
log.status.Print('Suggest using `--region us-west1`')
region = properties.VALUES.functions.region.Get()
gcf_client = client.FunctionsClient(release_track=release_track)
# ListRuntimesResponse
response = gcf_client.ListRuntimes(region)
if response:
runtime_mapping = collections.OrderedDict()
for runtime in response.runtimes:
runtime_mapping.setdefault(runtime.name, []).append(runtime)
return [Runtime(value) for value in runtime_mapping.values()]
else:
return []
class Runtime:
"""Runtimes wrapper for ListRuntimesResponse#Runtimes.
The runtimes response from GCFv2 duplicates runtimes for each environment. To
make formatting easier, this includes all environments under a single object.
Attributes:
name: A string name of the runtime.
stage: An enum of the release state of the runtime, e.g., GA, BETA, etc.
environments: A list of supported runtimes, [GEN_1, GEN_2]
"""
def __init__(self, runtimes):
for runtime in runtimes:
if runtime.name != runtimes[0].name:
raise ValueError('Only runtimes with the same name should be included')
self.name = runtimes[0].name if runtimes else ''
self.stage = runtimes[0].stage if runtimes else ''
self.environments = [runtime.environment for runtime in runtimes]

View File

@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 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.
"""This file provides the implementation of the `functions set-iam-policy` command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v2 import util as api_util
from googlecloudsdk.command_lib.iam import iam_util
def Run(args, release_track):
"""Set the IAM policy for a Google Cloud Function."""
client = api_util.GetClientInstance(release_track=release_track)
messages = api_util.GetMessagesModule(release_track=release_track)
function_ref = args.CONCEPTS.name.Parse()
function_relative_name = function_ref.RelativeName()
policy, update_mask = iam_util.ParseYamlOrJsonPolicyFile(
args.policy_file, messages.Policy)
return client.projects_locations_functions.SetIamPolicy(
messages.CloudfunctionsProjectsLocationsFunctionsSetIamPolicyRequest(
resource=function_relative_name,
setIamPolicyRequest=messages.SetIamPolicyRequest(
policy=policy, updateMask=update_mask)))