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,38 @@
# -*- 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.
"""Commands for reading and manipulating service attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class ServiceAttachments(base.Group):
"""List, create, describe, update and delete service attachments."""
ServiceAttachments.category = base.NETWORKING_CATEGORY
ServiceAttachments.detailed_help = {
'brief':
'Manage Compute Engine service attachment resources.',
'DESCRIPTION':
'List, create, describe, update and delete service attachments.',
}

View File

@@ -0,0 +1,200 @@
# -*- 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 for creating service attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.forwarding_rules import flags as forwarding_rule_flags
from googlecloudsdk.command_lib.compute.networks.subnets import flags as subnetwork_flags
from googlecloudsdk.command_lib.compute.service_attachments import flags
from googlecloudsdk.command_lib.compute.service_attachments import service_attachments_utils
def _DetailedHelp():
return {
'brief':
'Create a Google Compute Engine service attachment.',
'DESCRIPTION':
"""\
*{command}* is used to create service attachments. A service producer
creates service attachments to make a service available to consumers.
Service consumers use Private Service Connect endpoints to privately
forward traffic to the service attachment.
""",
'EXAMPLES':
"""\
If there is an already-created internal load balancer (ILB) with the name
MY_ILB in region us-central1 and there is an already-created Private
Service Connect subnets MY_SUBNET1 and MY_SUBNET2, create a service
attachment pointing to the ILB by running:
$ {command} SERVICE_ATTACHMENT_NAME --region=us-central1 --producer-forwarding-rule=MY_ILB --connection-preference=ACCEPT_AUTOMATIC --nat-subnets=MY_SUBNET1,MY_SUBNET2
To create a service attachment with a textual description, run:
$ {command} SERVICE_ATTACHMENT_NAME --region=us-central1 --producer-forwarding-rule=MY_ILB --connection-preference=ACCEPT_AUTOMATIC --nat-subnets=MY_SUBNET1,MY_SUBNET2 --description='default service attachment'
""",
}
class CreateHelper(object):
"""Helper class to create a service attachment."""
SERVICE_ATTACHMENT_ARG = None
PRODUCER_FORWARDING_RULE_ARG = None
NAT_SUBNETWORK_ARG = None
def __init__(self, holder):
self._holder = holder
@classmethod
def Args(cls, parser):
"""Create a Google Compute Engine service attachment.
Args:
parser: the parser that parses the input from the user.
"""
cls.SERVICE_ATTACHMENT_ARG = flags.ServiceAttachmentArgument()
cls.SERVICE_ATTACHMENT_ARG.AddArgument(parser, operation_type='create')
cls.PRODUCER_FORWARDING_RULE_ARG = (
forwarding_rule_flags.ForwardingRuleArgumentForServiceAttachment()
)
cls.NAT_SUBNETWORK_ARG = (
subnetwork_flags.SubnetworkArgumentForServiceAttachment()
)
cls.NAT_SUBNETWORK_ARG.AddArgument(parser)
parser.display_info.AddFormat(flags.DEFAULT_LIST_FORMAT)
parser.display_info.AddCacheUpdater(flags.ServiceAttachmentsCompleter)
flags.AddDescription(parser)
flags.AddTargetServiceAndProducerForwardingRuleArgs(parser)
flags.AddConnectionPreference(parser, is_update=False)
flags.AddEnableProxyProtocolForCreate(parser)
flags.AddReconcileConnectionsForCreate(parser)
flags.AddConsumerRejectList(parser)
flags.AddConsumerAcceptListOld(parser)
flags.AddDomainNames(parser)
flags.AddPropagatedConnectionLimit(parser)
def Run(self, args):
"""Issue a service attachment INSERT request."""
client = self._holder.client
service_attachment_ref = self.SERVICE_ATTACHMENT_ARG.ResolveAsResource(
args,
self._holder.resources,
default_scope=compute_scope.ScopeEnum.REGION,
)
producer_forwarding_rule_ref = (
self.PRODUCER_FORWARDING_RULE_ARG.ResolveAsResource(
args,
self._holder.resources,
default_scope=compute_scope.ScopeEnum.REGION,
)
)
if target_service_args := args.target_service:
target_service = target_service_args
producer_forwarding_rule = None
elif producer_forwarding_rule_ref:
producer_forwarding_rule = producer_forwarding_rule_ref.SelfLink()
target_service = producer_forwarding_rule_ref.SelfLink()
nat_subnetwork_refs = self.NAT_SUBNETWORK_ARG.ResolveAsResource(
args,
self._holder.resources,
default_scope=compute_scope.ScopeEnum.REGION,
scope_lister=compute_flags.GetDefaultScopeLister(client),
)
nat_subnetworks = [
nat_subnetwork_ref.SelfLink()
for nat_subnetwork_ref in nat_subnetwork_refs
]
connection_preference = service_attachments_utils.GetConnectionPreference(
args, client.messages)
enable_proxy_protocol = args.enable_proxy_protocol
service_attachment = client.messages.ServiceAttachment(
description=args.description,
name=service_attachment_ref.Name(),
natSubnets=nat_subnetworks,
connectionPreference=connection_preference,
enableProxyProtocol=enable_proxy_protocol,
producerForwardingRule=producer_forwarding_rule,
targetService=target_service,
)
if args.IsSpecified('consumer_reject_list'):
service_attachment.consumerRejectLists = args.consumer_reject_list
if args.IsSpecified('consumer_accept_list'):
accept_list = service_attachments_utils.GetConsumerAcceptList(
args, client.messages)
service_attachment.consumerAcceptLists = accept_list
if args.IsSpecified('domain_names'):
service_attachment.domainNames = args.domain_names
if args.IsSpecified('reconcile_connections'):
service_attachment.reconcileConnections = args.reconcile_connections
if args.IsSpecified('propagated_connection_limit'):
service_attachment.propagatedConnectionLimit = (
args.propagated_connection_limit
)
request = client.messages.ComputeServiceAttachmentsInsertRequest(
project=service_attachment_ref.project,
region=service_attachment_ref.region,
serviceAttachment=service_attachment)
collection = client.apitools_client.serviceAttachments
return client.MakeRequests([(collection, 'Insert', request)])
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.GA,
)
class Create(base.CreateCommand):
"""Create a Google Compute Engine service attachment."""
detailed_help = _DetailedHelp()
@classmethod
def Args(cls, parser):
CreateHelper.Args(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
return CreateHelper(holder).Run(args)
@base.ReleaseTracks(
base.ReleaseTrack.BETA,
)
class CreateBeta(Create):
"""Create a Google Compute Engine service attachment."""
detailed_help = _DetailedHelp()
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA,
)
class CreateAlpha(Create):
"""Create a Google Compute Engine service attachment."""
detailed_help = _DetailedHelp()

View File

@@ -0,0 +1,79 @@
# -*- 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 for deleting service attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import utils
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.service_attachments import flags
def _DetailedHelp():
return {
'EXAMPLES':
"""\
To delete a service attachment, run:
$ {command} SERVICE_ATTACHMENT_NAME --region=us-central1"""
}
def _Run(holder, service_attachment_refs):
"""Issues requests necessary to delete service attachments.
Args:
holder: the class that holds lazy initialized API client and resources.
service_attachment_refs: the list of references for service attachments that
need to be deleted.
Returns:
A list of responses. One response for each deletion request.
"""
client = holder.client
utils.PromptForDeletion(service_attachment_refs)
requests = []
for service_attachment_ref in service_attachment_refs:
requests.append((client.apitools_client.serviceAttachments, 'Delete',
client.messages.ComputeServiceAttachmentsDeleteRequest(
**service_attachment_ref.AsDict())))
return client.MakeRequests(requests)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class Delete(base.DeleteCommand):
"""Delete one or more Google Compute Engine service attachments."""
SERVICE_ATTACHMENT_ARG = None
detailed_help = _DetailedHelp()
@classmethod
def Args(cls, parser):
cls.SERVICE_ATTACHMENT_ARG = flags.ServiceAttachmentArgument(plural=True)
cls.SERVICE_ATTACHMENT_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(flags.ServiceAttachmentsCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
service_attachment_refs = self.SERVICE_ATTACHMENT_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.REGION)
return _Run(holder, service_attachment_refs)

View File

@@ -0,0 +1,73 @@
# -*- 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 for describing a service attachment."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.service_attachments import flags
def _DetailedHelp():
return {
'EXAMPLES':
"""\
To describe a service attachment, run:
$ {command} SERVICE_ATTACHMENT_NAME --region=us-central1"""
}
def _Run(args, holder, service_attachment_arg):
"""Issues requests necessary to describe a service attachment."""
service_attachment_ref = service_attachment_arg.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.REGION
)
client = holder.client
request = client.messages.ComputeServiceAttachmentsGetRequest(
**service_attachment_ref.AsDict())
if args.show_nat_ips is not None:
request.showNatIps = args.show_nat_ips
collection = client.apitools_client.serviceAttachments
return client.MakeRequests([(collection, 'Get', request)])[0]
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
@base.UniverseCompatible
class Describe(base.DescribeCommand):
"""Display details about a Google Compute Engine service attachment."""
SERVICE_ATTACHMENT_ARG = None
detailed_help = _DetailedHelp()
@classmethod
def Args(cls, parser):
cls.SERVICE_ATTACHMENT_ARG = flags.ServiceAttachmentArgument()
cls.SERVICE_ATTACHMENT_ARG.AddArgument(parser, operation_type='describe')
flags.AddShowNatIpsFlag(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
return _Run(args, holder, self.SERVICE_ATTACHMENT_ARG)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DescribeAlpha(Describe):
"""Display details about a Google Compute Engine service attachment."""

View File

@@ -0,0 +1,57 @@
# -*- 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 for listing service attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import lister
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.service_attachments import flags
def _Args(parser):
parser.display_info.AddFormat(flags.DEFAULT_LIST_FORMAT)
lister.AddRegionsArg(parser)
parser.display_info.AddCacheUpdater(flags.ServiceAttachmentsCompleter)
def _Run(args, holder):
"""Issues requests necessary to list service attachments."""
client = holder.client
request_data = lister.ParseRegionalFlags(args, holder.resources)
list_implementation = lister.RegionalLister(
client, client.apitools_client.serviceAttachments)
return lister.Invoke(request_data, list_implementation)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class List(base.ListCommand):
"""List service attachments."""
detailed_help = base_classes.GetRegionalListerHelp('service attachments')
@classmethod
def Args(cls, parser):
_Args(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
return _Run(args, holder)

View File

@@ -0,0 +1,304 @@
# -*- 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.
"""Command for updating service attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import encoding
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.networks.subnets import flags as subnetwork_flags
from googlecloudsdk.command_lib.compute.service_attachments import flags
from googlecloudsdk.command_lib.compute.service_attachments import service_attachments_utils
def _DetailedHelp():
return {
'brief':
'Update a Google Compute Engine service attachment.',
'DESCRIPTION':
"""\
*{command}* is used to update service attachments. A service producer
creates service attachments to make a service available to consumers.
Service consumers use Private Service Connect endpoints to privately
forward traffic to the service attachment.
""",
'EXAMPLES':
"""\
To update the connection policy of a service attachment to be ACCEPT_MANUAL, run:
$ {command} SERVICE_ATTACHMENT_NAME --region=us-central1 --connection-preference=ACCEPT_MANUAL
To update all supported fields of a service attachment, run:
$ {command} SERVICE_ATTACHMENT_NAME --region=us-central1 --connection-preference=ACCEPT_AUTOMATIC --nat-subnets=MY_SUBNET1,MY_SUBNET2 --enable-proxy-protocol --consumer-reject-list=PROJECT_ID1,PROJECT_ID2 --consumer-accept-list=PROJECT_ID3=10,PROJECT_ID4=20
""",
}
class UpdateHelper(object):
"""Update a Google Compute Engine service attachment."""
SERVICE_ATTACHMENT_ARG = None
NAT_SUBNETWORK_ARG = None
def __init__(
self,
holder,
support_target_service_arg,
support_endpoint_based_security_arg,
):
self._holder = holder
self._support_target_service_arg = support_target_service_arg
self._support_endpoint_based_security_arg = (
support_endpoint_based_security_arg
)
@classmethod
def Args(
cls,
parser,
support_target_service_arg,
support_endpoint_based_security_arg,
):
"""Create a Google Compute Engine service attachment.
Args:
parser: the parser that parses the input from the user.
support_target_service_arg: Whether to add arguments for producer
forwarding rule.
support_endpoint_based_security_arg: Whether to support endpoint based
security.
cls: Hold onto the definition of a complex argument so it can be used later
to process the user's input.
flags: Define and register command-line arguments with the argument parser.
"""
cls.SERVICE_ATTACHMENT_ARG = flags.ServiceAttachmentArgument()
cls.SERVICE_ATTACHMENT_ARG.AddArgument(parser, operation_type='update')
cls.NAT_SUBNETWORK_ARG = (
subnetwork_flags.SubnetworkArgumentForServiceAttachment(required=False)
)
cls.NAT_SUBNETWORK_ARG.AddArgument(parser)
flags.AddDescription(parser)
if support_target_service_arg:
flags.AddTargetServiceArgsForUpdate(parser)
flags.AddConnectionPreference(parser, is_update=True)
flags.AddEnableProxyProtocolForUpdate(parser)
flags.AddReconcileConnectionsForUpdate(parser)
flags.AddConsumerRejectList(parser)
if support_endpoint_based_security_arg:
flags.AddConsumerAcceptList(parser)
else:
flags.AddConsumerAcceptListOld(parser)
flags.AddPropagatedConnectionLimit(parser)
def _GetConsumerAcceptList(self, args, holder):
if self._support_endpoint_based_security_arg:
return service_attachments_utils.GetConsumerAcceptListWithEndpointBasedSecurity(
args, holder.client.messages
)
return service_attachments_utils.GetConsumerAcceptList(
args, holder.client.messages
)
def _GetProjectOrNetworkOrEndpointBasedOnArg(self, consumer_limit):
if self._support_endpoint_based_security_arg:
return self._GetProjectOrNetworkOrEndpoint(consumer_limit)
return self._GetProjectOrNetwork(consumer_limit)
def _GetProjectOrNetwork(self, consumer_limit):
if consumer_limit.projectIdOrNum is not None:
return (consumer_limit.projectIdOrNum, consumer_limit.connectionLimit)
return (consumer_limit.networkUrl, consumer_limit.connectionLimit)
def _GetProjectOrNetworkOrEndpoint(self, consumer_limit):
if consumer_limit.projectIdOrNum is not None:
return (consumer_limit.projectIdOrNum, consumer_limit.connectionLimit)
elif consumer_limit.endpointUrl is not None:
return (consumer_limit.endpointUrl, consumer_limit.connectionLimit)
return (consumer_limit.networkUrl, consumer_limit.connectionLimit)
def _GetOldResource(self, client, service_attachment_ref):
"""Returns the existing ServiceAttachment resource."""
request = client.messages.ComputeServiceAttachmentsGetRequest(
**service_attachment_ref.AsDict())
collection = client.apitools_client.serviceAttachments
return client.MakeRequests([(collection, 'Get', request)])[0]
def _GetPatchRequest(self, client, service_attachment_ref, replacement):
"""Returns a request to update the service attachment."""
return (client.apitools_client.serviceAttachments, 'Patch',
client.messages.ComputeServiceAttachmentsPatchRequest(
project=service_attachment_ref.project,
region=service_attachment_ref.region,
serviceAttachment=service_attachment_ref.Name(),
serviceAttachmentResource=replacement))
def _GetNatSubnets(self, holder, args):
"""Returns nat subnetwork urls from the argument."""
nat_subnetwork_refs = self.NAT_SUBNETWORK_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.REGION,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
nat_subnetworks = [
nat_subnetwork_ref.SelfLink()
for nat_subnetwork_ref in nat_subnetwork_refs
]
return nat_subnetworks
def _Modify(self, holder, args, old_resource, cleared_fields):
"""Returns the updated service attachment."""
replacement = encoding.CopyProtoMessage(old_resource)
is_updated = False
if self._support_target_service_arg and args.IsSpecified('target_service'):
is_updated = True
replacement.targetService = args.target_service
if args.IsSpecified('description'):
if args.description != old_resource.description:
replacement.description = args.description
is_updated = True
if args.IsSpecified('connection_preference'):
new_connection_preference = (
service_attachments_utils.GetConnectionPreference(
args, holder.client.messages
)
)
if new_connection_preference != old_resource.connectionPreference:
replacement.connectionPreference = new_connection_preference
is_updated = True
if args.IsSpecified('enable_proxy_protocol'):
if args.enable_proxy_protocol != old_resource.enableProxyProtocol:
replacement.enableProxyProtocol = args.enable_proxy_protocol
is_updated = True
if args.IsSpecified('nat_subnets'):
new_nat_subnets = sorted(self._GetNatSubnets(holder, args))
if old_resource.natSubnets is None or new_nat_subnets != sorted(
old_resource.natSubnets):
replacement.natSubnets = new_nat_subnets
is_updated = True
if args.IsSpecified('consumer_reject_list'):
new_reject_list = sorted(args.consumer_reject_list)
if old_resource.consumerRejectLists is None or new_reject_list != sorted(
old_resource.consumerRejectLists):
replacement.consumerRejectLists = new_reject_list
is_updated = True
if not new_reject_list:
# The user can clear up the reject list
cleared_fields.append('consumerRejectLists')
if args.IsSpecified('consumer_accept_list'):
consumer_accept_list = self._GetConsumerAcceptList(args, holder)
new_accept_list = sorted(
consumer_accept_list,
key=self._GetProjectOrNetworkOrEndpointBasedOnArg,
)
if old_resource.consumerAcceptLists is None or new_accept_list != sorted(
old_resource.consumerAcceptLists,
key=self._GetProjectOrNetworkOrEndpointBasedOnArg,
):
replacement.consumerAcceptLists = new_accept_list
is_updated = True
if not new_accept_list:
# The user can clear up the accept list
cleared_fields.append('consumerAcceptLists')
if args.IsSpecified('reconcile_connections'):
if args.reconcile_connections != old_resource.reconcileConnections:
replacement.reconcileConnections = args.reconcile_connections
is_updated = True
if args.IsSpecified('propagated_connection_limit'):
if (
args.propagated_connection_limit
!= old_resource.propagatedConnectionLimit
):
replacement.propagatedConnectionLimit = args.propagated_connection_limit
is_updated = True
if is_updated:
return replacement
return None
def Run(self, args):
"""Issue a service attachment PATCH request."""
client = self._holder.client
service_attachment_ref = self.SERVICE_ATTACHMENT_ARG.ResolveAsResource(
args,
self._holder.resources,
default_scope=compute_scope.ScopeEnum.REGION,
)
old_resource = self._GetOldResource(client, service_attachment_ref)
cleared_fields = []
replacement = self._Modify(self._holder, args, old_resource, cleared_fields)
if replacement is None:
return old_resource
with client.apitools_client.IncludeFields(cleared_fields):
return client.MakeRequests(
[self._GetPatchRequest(client, service_attachment_ref, replacement)])
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Google Compute Engine service attachment."""
_support_target_service_arg = False
_support_endpoint_based_security_arg = False
detailed_help = _DetailedHelp()
@classmethod
def Args(cls, parser):
UpdateHelper.Args(
parser,
cls._support_target_service_arg,
cls._support_endpoint_based_security_arg,
)
def Run(self, args):
"""Issue a service attachment PATCH request."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
return UpdateHelper(
holder,
self._support_target_service_arg,
self._support_endpoint_based_security_arg,
).Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Google Compute Engine service attachment."""
_support_endpoint_based_security_arg = True
detailed_help = _DetailedHelp()
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Google Compute Engine service attachment."""
_support_target_service_arg = True
detailed_help = _DetailedHelp()