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,45 @@
# -*- 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.
"""Commands for reading and manipulating VPN Gateways."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class VpnTunnels(base.Group):
"""Read and manipulate Compute Engine VPN tunnels."""
# Placeholder to indicate that a detailed_help field exists and should
# be set outside the class definition.
detailed_help = None
VpnTunnels.category = base.NETWORKING_CATEGORY
VpnTunnels.detailed_help = {
'DESCRIPTION': """
Read and manipulate Cloud VPN tunnels.
For more information about Cloud VPN tunnels, see the
[Cloud VPN tunnels documentation](https://cloud.google.com//network-connectivity/docs/vpn/concepts/overview).
See also: [VPN tunnels API](https://cloud.google.com/compute/docs/reference/rest/v1/vpnTunnels).
""",
}

View File

@@ -0,0 +1,26 @@
# -*- 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 group for managing Compute Engine vpn tunnel configurations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class Config(base.Group):
"""Manage Compute Engine vpn tunnel configurations."""

View File

@@ -0,0 +1,38 @@
release_tracks: [ALPHA]
command_type: CONFIG_EXPORT
help_text:
brief: Export the configuration for a Compute Engine vpn tunnel.
description: |
*{command}* exports the configuration for a Compute Engine vpn tunnel.
Vpn tunnel configurations can be exported in
Kubernetes Resource Model (krm) or Terraform HCL formats. The
default format is `krm`.
Specifying `--all` allows you to export the configurations for all
vpn tunnels within the project.
Specifying `--path` allows you to export the configuration(s) to
a local directory.
examples: |
To export the configuration for a vpn tunnel, run:
$ {command} my-vpn-tunnel
To export the configuration for a vpn tunnel to a file, run:
$ {command} my-vpn-tunnel --path=/path/to/dir/
To export the configuration for a vpn tunnel in Terraform
HCL format, run:
$ {command} my-vpn-tunnel --resource-format=terraform
To export the configurations for all vpn tunnels within a
project, run:
$ {command} --all
arguments:
resource:
help_text: Vpn tunnel to export the configuration for.
spec: !REF googlecloudsdk.command_lib.compute.resources:vpn_tunnel

View File

@@ -0,0 +1,546 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 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 VPN tunnels."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import argparse
import re
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.vpn_tunnels import vpn_tunnels_utils
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute import resource_manager_tags_utils
from googlecloudsdk.command_lib.compute.external_vpn_gateways import flags as external_vpn_gateway_flags
from googlecloudsdk.command_lib.compute.routers import flags as router_flags
from googlecloudsdk.command_lib.compute.target_vpn_gateways import flags as target_vpn_gateway_flags
from googlecloudsdk.command_lib.compute.vpn_gateways import flags as vpn_gateway_flags
from googlecloudsdk.command_lib.compute.vpn_tunnels import flags
import six
_PRINTABLE_CHARS_PATTERN = r'[ -~]+'
_ROUTER_ARG = router_flags.RouterArgumentForVpnTunnel(required=False)
_VPN_TUNNEL_ARG = flags.VpnTunnelArgument()
class DeprecatedArgumentException(exceptions.ToolException):
def __init__(self, arg, msg):
super(DeprecatedArgumentException, self).__init__(
'{0} is deprecated. {1}'.format(arg, msg))
def ValidateSimpleSharedSecret(possible_secret):
"""ValidateSimpleSharedSecret checks its argument is a vpn shared secret.
ValidateSimpleSharedSecret(v) returns v iff v matches [ -~]+.
Args:
possible_secret: str, The data to validate as a shared secret.
Returns:
The argument, if valid.
Raises:
ArgumentTypeError: The argument is not a valid vpn shared secret.
"""
if not possible_secret:
raise argparse.ArgumentTypeError(
'--shared-secret requires a non-empty argument.')
if re.match(_PRINTABLE_CHARS_PATTERN, possible_secret):
return possible_secret
raise argparse.ArgumentTypeError(
'The argument to --shared-secret is not valid it contains '
'non-printable charcters.')
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.UniverseCompatible
class CreateGA(base.CreateCommand):
"""Create a VPN tunnel.
*{command}* is used to create a Classic VPN tunnel between a target VPN
gateway in Google Cloud Platform and a peer address; or create Highly
Available VPN tunnel between HA VPN gateway and another HA VPN gateway, or
Highly Available VPN tunnel between HA VPN gateway and an external VPN
gateway.
"""
_TARGET_VPN_GATEWAY_ARG = (
target_vpn_gateway_flags.TargetVpnGatewayArgumentForVpnTunnel(
required=False))
_VPN_GATEWAY_ARG = (
vpn_gateway_flags.GetVpnGatewayArgumentForOtherResource(required=False))
_EXTERNAL_VPN_GATEWAY_ARG = (
external_vpn_gateway_flags.ExternalVpnGatewayArgumentForVpnTunnel(
required=False))
_PEER_GCP_GATEWAY_ARG = (
vpn_gateway_flags.GetPeerVpnGatewayArgumentForOtherResource(
required=False))
_support_cipher_suite = True
_support_tagging_at_creation = False
@classmethod
def _AddCommonFlags(cls, parser):
_ROUTER_ARG.AddArgument(parser)
parser.add_argument(
'--description',
help='An optional, textual description for the VPN tunnel.')
parser.add_argument(
'--ike-version',
choices=[1, 2],
type=int,
help='Internet Key Exchange protocol version number. Default is 2.')
parser.add_argument(
'--shared-secret',
type=ValidateSimpleSharedSecret,
required=True,
help="""\
Shared secret consisting of printable characters. Valid
arguments match the regular expression """ + _PRINTABLE_CHARS_PATTERN)
parser.add_argument(
'--ike-networks',
type=arg_parsers.ArgList(min_length=1),
hidden=True,
help='THIS ARGUMENT NEEDS HELP TEXT.')
@classmethod
def _AddCipherSuiteFlags(cls, parser):
parser.add_argument('--phase1-encryption',
metavar='ALGORITHMS',
type=arg_parsers.ArgList(min_length=1),
help='Phase 1 encryption algorithms.')
parser.add_argument('--phase1-integrity',
metavar='ALGORITHMS',
type=arg_parsers.ArgList(min_length=1),
help='Phase 1 integrity algorithms.')
parser.add_argument('--phase1-prf',
metavar='PSEUDORANDOM FUNCTIONS',
type=arg_parsers.ArgList(min_length=1),
help='Phase 1 pseudorandom functions.')
parser.add_argument('--phase1-dh',
metavar='GROUPS',
type=arg_parsers.ArgList(min_length=1),
help='Phase 1 Diffie-Hellman groups.')
parser.add_argument('--phase2-encryption',
metavar='ALGORITHMS',
type=arg_parsers.ArgList(min_length=1),
help='Phase 2 encryption algorithms.')
parser.add_argument('--phase2-integrity',
metavar='ALGORITHMS',
type=arg_parsers.ArgList(min_length=1),
help='Phase 2 integrity algorithms.')
parser.add_argument('--phase2-pfs',
metavar='ALGORITHMS',
type=arg_parsers.ArgList(min_length=1),
help='Phase 2 perfect forward secerecy algorithms.')
@classmethod
def Args(cls, parser):
"""Adds arguments to the supplied parser."""
# TODO(b/129011963): add e2e tests for HA VPN tunnels
parser.display_info.AddFormat(flags.HA_VPN_LIST_FORMAT)
_VPN_TUNNEL_ARG.AddArgument(parser, operation_type='create')
vpn_gateway_group_parser = parser.add_mutually_exclusive_group(
required=True)
cls._TARGET_VPN_GATEWAY_ARG.AddArgument(vpn_gateway_group_parser)
cls._VPN_GATEWAY_ARG.AddArgument(vpn_gateway_group_parser)
peer_vpn_gateway_group_parser = parser.add_mutually_exclusive_group(
required=True)
cls._EXTERNAL_VPN_GATEWAY_ARG.AddArgument(peer_vpn_gateway_group_parser)
cls._PEER_GCP_GATEWAY_ARG.AddArgument(peer_vpn_gateway_group_parser)
peer_vpn_gateway_group_parser.add_argument(
'--peer-address',
required=False,
help='Valid IPV4 address representing the remote tunnel endpoint, '
'the peer address must be specified when creating Classic VPN '
'tunnels from Classic Target VPN gateway')
cls._AddCommonFlags(parser)
parser.add_argument(
'--local-traffic-selector',
type=arg_parsers.ArgList(min_length=1),
metavar='CIDR',
help=("""\
Traffic selector is an agreement between IKE peers to permit traffic
through a tunnel if the traffic matches a specified pair of local and
remote addresses.
--local-traffic-selector allows to configure the local addresses that are
permitted. The value should be a comma separated list of CIDR formatted
strings. Example: 192.168.0.0/16,10.0.0.0/24.
Local traffic selector must be specified only for VPN tunnels that
do not use dynamic routing with a Cloud Router. Omit this flag when
creating a tunnel using dynamic routing, including a tunnel for a
Highly Available VPN gateway."""))
parser.add_argument(
'--remote-traffic-selector',
type=arg_parsers.ArgList(min_length=1),
metavar='CIDR',
help=("""\
Traffic selector is an agreement between IKE peers to permit traffic
through a tunnel if the traffic matches a specified pair of local and
remote addresses.
--remote-traffic-selector allows to configure the remote addresses that
are permitted. The value should be a comma separated list of CIDR
formatted strings. Example: 192.168.0.0/16,10.0.0.0/24.
Remote traffic selector must be specified for VPN tunnels that do
not use dynamic routing with a Cloud Router. Omit this flag when
creating a tunnel using dynamic routing, including a tunnel for a
Highly Available VPN gateway."""))
parser.add_argument(
'--interface',
choices=[0, 1],
type=int,
required=False,
help="""\
Numeric interface ID of the VPN gateway with which this VPN tunnel
is associated. This flag is required if the tunnel is being attached
to a Highly Available VPN gateway. This option is only available
for use with Highly Available VPN gateway and must be omitted if the
tunnel is going to be connected to a Classic VPN gateway.""")
parser.add_argument(
'--peer-external-gateway-interface',
choices=[0, 1, 2, 3],
type=int,
required=False,
help="""\
Interface ID of the external VPN gateway to which this VPN tunnel
is connected to.
This flag is required if the tunnel is being created from
a Highly Available VPN gateway to an External Vpn Gateway.""")
if(cls._support_cipher_suite):
cls._AddCipherSuiteFlags(parser)
if cls._support_tagging_at_creation:
parser.add_argument(
'--resource-manager-tags',
type=arg_parsers.ArgDict(),
metavar='KEY=VALUE',
help="""\
A comma-separated list of Resource Manager tags to apply to the VPN tunnel.
""",
)
parser.display_info.AddCacheUpdater(flags.VpnTunnelsCompleter)
def _ValidateHighAvailabilityVpnArgs(self, args):
if args.IsSpecified('vpn_gateway'):
if not args.IsSpecified('interface'):
raise exceptions.InvalidArgumentException(
'--interface',
'When creating Highly Available VPN tunnels, the VPN gateway '
'interface must be specified using the --interface flag.')
if not args.IsSpecified('router'):
raise exceptions.InvalidArgumentException(
'--router',
'When creating Highly Available VPN tunnels, a Cloud Router '
'must be specified using the --router flag.')
if not args.IsSpecified('peer_gcp_gateway') and not args.IsSpecified(
'peer_external_gateway'):
raise exceptions.InvalidArgumentException(
'--peer-gcp-gateway',
'When creating Highly Available VPN tunnels, either '
'--peer-gcp-gateway or --peer-external-gateway must be specified.')
if args.IsSpecified('peer_external_gateway') and not args.IsSpecified(
'peer_external_gateway_interface'):
raise exceptions.InvalidArgumentException(
'--peer-external-gateway-interface',
'The flag --peer-external-gateway-interface must be specified along'
' with --peer-external-gateway.')
if args.IsSpecified('local_traffic_selector'):
raise exceptions.InvalidArgumentException(
'--local-traffic-selector',
'Cannot specify local traffic selector with Highly Available '
'VPN tunnels.')
if args.IsSpecified('remote_traffic_selector'):
raise exceptions.InvalidArgumentException(
'--remote-traffic-selector',
'Cannot specify remote traffic selector with Highly Available '
'VPN tunnels.')
if args.IsSpecified('peer_address'):
raise exceptions.InvalidArgumentException(
'--peer-address',
'Cannot specify the flag peer address with Highly Available '
'VPN tunnels.')
def _ValidateClassicVpnArgs(self, args):
if args.IsSpecified('target_vpn_gateway'):
if not args.IsSpecified('peer_address'):
raise exceptions.InvalidArgumentException(
'--peer-address',
'When creating Classic VPN tunnels, the peer address '
'must be specified.')
if args.IsSpecified('router'):
raise exceptions.InvalidArgumentException(
'--router',
'Cannot specify router with Classic VPN tunnels.',
)
def _GetPeerGcpGateway(self, api_resource_registry, args):
if args.IsSpecified('peer_gcp_gateway'):
peer_gcp_gateway = self._PEER_GCP_GATEWAY_ARG.ResolveAsResource(
args, api_resource_registry).SelfLink()
return peer_gcp_gateway
return None
def _GetPeerExternalGateway(self, api_resource_registry, args):
if args.IsSpecified('peer_external_gateway'):
peer_external_gateway = self._EXTERNAL_VPN_GATEWAY_ARG.ResolveAsResource(
args, api_resource_registry).SelfLink()
return peer_external_gateway
return None
def _Run(self, args, is_vpn_gateway_supported):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
helper = vpn_tunnels_utils.VpnTunnelHelper(holder)
# TODO(b/38253176) Add test coverage
if args.ike_networks is not None:
raise DeprecatedArgumentException(
'--ike-networks',
'It has been renamed to --local-traffic-selector.')
vpn_tunnel_ref = _VPN_TUNNEL_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client))
router_link = None
if args.IsSpecified('router'):
args.router_region = vpn_tunnel_ref.region
router_ref = _ROUTER_ARG.ResolveAsResource(args, holder.resources)
router_link = router_ref.SelfLink()
target_vpn_gateway = None
vpn_gateway = None
vpn_gateway_interface = None
peer_external_gateway = None
peer_external_gateway_interface = None
peer_gcp_gateway = None
resource_manager_tags = None
if is_vpn_gateway_supported and args.IsSpecified('vpn_gateway'):
self._ValidateHighAvailabilityVpnArgs(args)
args.vpn_gateway_region = vpn_tunnel_ref.region
vpn_gateway = self._VPN_GATEWAY_ARG.ResolveAsResource(
args, holder.resources
).SelfLink()
vpn_gateway_interface = args.interface
peer_external_gateway = self._GetPeerExternalGateway(
holder.resources, args
)
peer_external_gateway_interface = args.peer_external_gateway_interface
peer_gcp_gateway = self._GetPeerGcpGateway(holder.resources, args)
else:
self._ValidateClassicVpnArgs(args)
args.target_vpn_gateway_region = vpn_tunnel_ref.region
target_vpn_gateway = self._TARGET_VPN_GATEWAY_ARG.ResolveAsResource(
args, holder.resources
).SelfLink()
if self._support_tagging_at_creation:
if args.resource_manager_tags is not None:
resource_manager_tags = self._CreateVpnTunnelParams(
client.messages, args.resource_manager_tags
)
if target_vpn_gateway:
if self._support_cipher_suite:
phase1_algo = helper.GetVpnTunnelPhase1Algorithms(
phase1_encryption=args.phase1_encryption,
phase1_integrity=args.phase1_integrity,
phase1_dh=args.phase1_dh,
phase1_prf=args.phase1_prf,
)
phase2_algo = helper.GetVpnTunnelPhase2Algorithms(
phase2_encryption=args.phase2_encryption,
phase2_integrity=args.phase2_integrity,
phase2_pfs=args.phase2_pfs,
)
cipher_suite = client.messages.VpnTunnelCipherSuite()
if phase1_algo:
cipher_suite.phase1 = phase1_algo
if phase2_algo:
cipher_suite.phase2 = phase2_algo
if not cipher_suite.phase1 and not cipher_suite.phase2:
cipher_suite = None
vpn_tunnel_to_insert = (
helper.GetClassicVpnTunnelForInsertWithCipherSuite(
name=vpn_tunnel_ref.Name(),
description=args.description,
ike_version=args.ike_version,
peer_ip=args.peer_address,
shared_secret=args.shared_secret,
target_vpn_gateway=target_vpn_gateway,
local_traffic_selector=args.local_traffic_selector,
remote_traffic_selector=args.remote_traffic_selector,
cipher_suite=cipher_suite,
params=resource_manager_tags,
support_tagging_at_creation=self._support_tagging_at_creation,
)
)
else:
vpn_tunnel_to_insert = helper.GetClassicVpnTunnelForInsert(
name=vpn_tunnel_ref.Name(),
description=args.description,
ike_version=args.ike_version,
peer_ip=args.peer_address,
shared_secret=args.shared_secret,
target_vpn_gateway=target_vpn_gateway,
local_traffic_selector=args.local_traffic_selector,
remote_traffic_selector=args.remote_traffic_selector,
params=resource_manager_tags,
support_tagging_at_creation=self._support_tagging_at_creation,
)
else:
if(self._support_cipher_suite):
phase1_algo = helper.GetVpnTunnelPhase1Algorithms(
phase1_encryption=args.phase1_encryption,
phase1_integrity=args.phase1_integrity,
phase1_dh=args.phase1_dh,
phase1_prf=args.phase1_prf,
)
phase2_algo = helper.GetVpnTunnelPhase2Algorithms(
phase2_encryption=args.phase2_encryption,
phase2_integrity=args.phase2_integrity,
phase2_pfs=args.phase2_pfs,
)
cipher_suite = client.messages.VpnTunnelCipherSuite()
if phase1_algo:
cipher_suite.phase1 = phase1_algo
if phase2_algo:
cipher_suite.phase2 = phase2_algo
if not cipher_suite.phase1 and not cipher_suite.phase2:
cipher_suite = None
vpn_tunnel_to_insert = (
helper.GetHighAvailabilityVpnTunnelForInsertWithCipherSuite(
name=vpn_tunnel_ref.Name(),
description=args.description,
ike_version=args.ike_version,
peer_ip=args.peer_address,
shared_secret=args.shared_secret,
vpn_gateway=vpn_gateway,
vpn_gateway_interface=vpn_gateway_interface,
router=router_link,
peer_external_gateway=peer_external_gateway,
peer_external_gateway_interface=peer_external_gateway_interface,
peer_gcp_gateway=peer_gcp_gateway,
cipher_suite=cipher_suite,
params=resource_manager_tags,
support_tagging_at_creation=self._support_tagging_at_creation,
)
)
else:
vpn_tunnel_to_insert = helper.GetHighAvailabilityVpnTunnelForInsert(
name=vpn_tunnel_ref.Name(),
description=args.description,
ike_version=args.ike_version,
# TODO(b/127839209): remove peer_ip for HA
# tunnels once peer gateway
# feature is enabled in Arcus.
peer_ip=args.peer_address,
shared_secret=args.shared_secret,
vpn_gateway=vpn_gateway,
vpn_gateway_interface=vpn_gateway_interface,
router=router_link,
peer_external_gateway=peer_external_gateway,
peer_external_gateway_interface=peer_external_gateway_interface,
peer_gcp_gateway=peer_gcp_gateway,
params=resource_manager_tags,
support_tagging_at_creation=self._support_tagging_at_creation,
)
operation_ref = helper.Create(vpn_tunnel_ref, vpn_tunnel_to_insert)
return helper.WaitForOperation(vpn_tunnel_ref, operation_ref,
'Creating VPN tunnel')
def Run(self, args):
"""Issues API requests to construct VPN Tunnels."""
return self._Run(args, is_vpn_gateway_supported=True)
def _CreateVpnTunnelParams(self, messages, resource_manager_tags):
resource_manager_tags_map = (
resource_manager_tags_utils.GetResourceManagerTags(
resource_manager_tags
)
)
params = messages.VpnTunnelParams
additional_properties = [
params.ResourceManagerTagsValue.AdditionalProperty(key=key, value=value)
for key, value in sorted(six.iteritems(resource_manager_tags_map))
]
return params(
resourceManagerTags=params.ResourceManagerTagsValue(
additionalProperties=additional_properties
)
)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(CreateGA):
"""Create a VPN tunnel.
*{command}* is used to create a Classic VPN tunnel between a target VPN
gateway in Google Cloud Platform and a peer address; or create Highly
Available VPN tunnel between HA VPN gateway and another HA VPN gateway, or
Highly Available VPN tunnel between HA VPN gateway and an external VPN
gateway.
"""
_support_cipher_suite = True
_support_tagging_at_creation = False
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Create a VPN tunnel.
*{command}* is used to create a Classic VPN tunnel between a target VPN
gateway in Google Cloud Platform and a peer address; or create Highly
Available VPN tunnel between HA VPN gateway and another HA VPN gateway, or
Highly Available VPN tunnel between HA VPN gateway and an external VPN
gateway.
"""
_support_cipher_suite = True
_support_tagging_at_creation = True

View File

@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 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 vpn tunnels."""
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.api_lib.compute.operations import poller
from googlecloudsdk.api_lib.compute.vpn_tunnels import vpn_tunnels_utils
from googlecloudsdk.api_lib.util import waiter
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.vpn_tunnels import flags
_VPN_TUNNEL_ARG = flags.VpnTunnelArgument(plural=True)
class DeleteBatchPoller(poller.BatchPoller):
def GetResult(self, operation_batch):
# For delete operations, once the operation status is DONE, there is
# nothing further to fetch.
return
class Delete(base.DeleteCommand):
"""Delete VPN tunnels.
*{command}* deletes one or more Compute Engine VPN tunnels.
"""
@staticmethod
def Args(parser):
_VPN_TUNNEL_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(flags.VpnTunnelsCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
helper = vpn_tunnels_utils.VpnTunnelHelper(holder)
vpn_tunnel_refs = _VPN_TUNNEL_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client))
utils.PromptForDeletion(vpn_tunnel_refs, 'region')
operation_refs = [helper.Delete(ref) for ref in vpn_tunnel_refs]
wait_message = 'Deleting VPN {}'.format(
('tunnels' if (len(operation_refs) > 1) else 'tunnel'))
operation_poller = DeleteBatchPoller(client,
client.apitools_client.vpnTunnels)
return waiter.WaitFor(operation_poller,
poller.OperationBatch(operation_refs), wait_message)

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 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 vpn tunnels."""
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.vpn_tunnels import vpn_tunnels_utils
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.vpn_tunnels import flags
_VPN_TUNNEL_ARG = flags.VpnTunnelArgument()
class Describe(base.DescribeCommand):
"""Describe a Compute Engine VPN tunnel.
*{command}* displays all data associated with a Compute Engine
VPN tunnel in a project.
"""
@staticmethod
def Args(parser):
"""Adds arguments to the supplied parser."""
_VPN_TUNNEL_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
helper = vpn_tunnels_utils.VpnTunnelHelper(holder)
vpn_tunnel_ref = _VPN_TUNNEL_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client))
return helper.Describe(vpn_tunnel_ref)

View File

@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 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 VPN tunnels."""
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 filter_rewrite
from googlecloudsdk.api_lib.compute import lister
from googlecloudsdk.api_lib.compute.vpn_tunnels import vpn_tunnels_utils
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.vpn_tunnels import flags
from googlecloudsdk.core import properties
from googlecloudsdk.core.resource import resource_projection_spec
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
@base.UniverseCompatible
class ListBetaGA(base.ListCommand):
"""List VPN tunnels."""
# Placeholder to indicate that a detailed_help field exists and should
# be set outside the class definition.
detailed_help = None
@staticmethod
def Args(parser):
parser.display_info.AddFormat(flags.DEFAULT_LIST_FORMAT)
lister.AddRegionsArg(parser)
parser.display_info.AddCacheUpdater(flags.VpnTunnelsCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
helper = vpn_tunnels_utils.VpnTunnelHelper(holder)
project = properties.VALUES.core.project.GetOrFail()
display_info = args.GetDisplayInfo()
defaults = resource_projection_spec.ProjectionSpec(
symbols=display_info.transforms, aliases=display_info.aliases)
args.filter, filter_expr = filter_rewrite.Rewriter().Rewrite(
args.filter, defaults=defaults)
return helper.List(
project=project, filter_expr=filter_expr, regions=args.regions
)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListAlpha(ListBetaGA):
"""List VPN tunnels."""
@staticmethod
def Args(parser):
ListBetaGA.Args(parser)
parser.display_info.AddFormat(flags.HA_VPN_LIST_FORMAT)
ListBetaGA.detailed_help = base_classes.GetRegionalListerHelp('VPN tunnels')
ListAlpha.detailed_help = ListBetaGA.detailed_help

View File

@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 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 labels for VPN tunnels."""
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.vpn_tunnels import vpn_tunnels_utils
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions as calliope_exceptions
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.vpn_tunnels import flags as vpn_tunnel_flags
from googlecloudsdk.command_lib.util.args import labels_util
_VPN_TUNNEL_ARG = vpn_tunnel_flags.VpnTunnelArgument()
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA)
class Update(base.UpdateCommand):
r"""Update a Compute Engine VPN tunnel.
*{command}* updates labels for a Compute Engine VPN tunnel.
For example:
$ {command} example-tunnel --region us-central1 \
--update-labels=k0=value1,k1=value2 --remove-labels=k3
will add/update labels ``k0'' and ``k1'' and remove labels with key ``k3''.
Labels can be used to identify the VPN tunnel and to filter them as in
$ {parent_command} list --filter='labels.k1:value2'
To list existing labels
$ {parent_command} describe example-tunnel --format="default(labels)"
"""
@classmethod
def Args(cls, parser):
"""Adds arguments to the supplied parser.
Args:
parser: The argparse parser to add arguments to.
"""
_VPN_TUNNEL_ARG.AddArgument(parser, operation_type='update')
labels_util.AddUpdateLabelsFlags(parser)
def Run(self, args):
"""Issues API requests to update a VPN Tunnel.
Args:
args: argparse.Namespace, The arguments received by this command.
Returns:
[protorpc.messages.Message], A list of responses returned
by the compute API.
"""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
messages = holder.client.messages
helper = vpn_tunnels_utils.VpnTunnelHelper(holder)
vpn_tunnel_ref = _VPN_TUNNEL_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
labels_diff = labels_util.Diff.FromUpdateArgs(args)
if not labels_diff.MayHaveUpdates():
raise calliope_exceptions.RequiredArgumentException(
'LABELS', 'At least one of --update-labels or '
'--remove-labels must be specified.')
vpn_tunnel = helper.Describe(vpn_tunnel_ref)
labels_update = labels_diff.Apply(
messages.RegionSetLabelsRequest.LabelsValue, vpn_tunnel.labels)
if not labels_update.needs_update:
return vpn_tunnel
operation_ref = helper.SetLabels(
vpn_tunnel_ref, vpn_tunnel.labelFingerprint, labels_update.labels)
return helper.WaitForOperation(
vpn_tunnel_ref, operation_ref,
'Updating labels of VPN tunnel [{0}]'.format(vpn_tunnel_ref.Name()))