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,42 @@
# -*- 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 networks."""
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 Networks(base.Group):
"""List, create, and delete Compute Engine networks."""
Networks.category = base.NETWORKING_CATEGORY
Networks.detailed_help = {
'DESCRIPTION': """
Read and manipulate VPC networks.
For more information about networks, see the
[networks documentation](https://cloud.google.com/vpc/docs/vpc).
See also: [Networks API](https://cloud.google.com/compute/docs/reference/rest/v1/networks).
""",
}

View File

@@ -0,0 +1,212 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for creating networks."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import textwrap
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import networks_utils
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.network_profiles import flags as network_profile_flags
from googlecloudsdk.command_lib.compute.networks import flags
from googlecloudsdk.command_lib.compute.networks import network_utils
from googlecloudsdk.core import log
from googlecloudsdk.core.resource import resource_projector
def EpilogText(network_name):
"""Text for firewall warning."""
message = """\
Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network {0} --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network {0} --allow tcp:22,tcp:3389,icmp
""".format(network_name)
log.status.Print(textwrap.dedent(message))
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.UniverseCompatible
class Create(base.CreateCommand):
r"""Create a Compute Engine network.
*{command}* is used to create virtual networks. A network
performs the same function that a router does in a home
network: it describes the network range and gateway IP
address, handles communication between instances, and serves
as a gateway between instances and callers outside the
network.
## EXAMPLES
To create a regional auto subnet mode network with the name 'network-name',
run:
$ {command} network-name
To create a global custom subnet mode network with the name 'network-name',
run:
$ {command} network-name \
--bgp-routing-mode=global \
--subnet-mode=custom
"""
NETWORK_ARG = None
NETWORK_PROFILE_ARG = None
_support_firewall_order = True
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat(flags.LIST_FORMAT_WITH_ULA_IPV6)
cls.NETWORK_ARG = flags.NetworkArgument()
cls.NETWORK_ARG.AddArgument(parser, operation_type='create')
network_utils.AddCreateBaseArgs(parser)
network_utils.AddCreateSubnetModeArg(parser)
network_utils.AddCreateBgpRoutingModeArg(parser)
network_utils.AddMtuArg(parser)
network_utils.AddInternalIpv6RangeArg(parser)
network_utils.AddEnableUlaInternalIpv6Arg(parser)
network_utils.AddNetworkFirewallPolicyEnforcementOrderArg(parser)
network_utils.AddBgpBestPathSelectionArgGroup(parser)
network_utils.AddTagsArg(parser)
cls.NETWORK_PROFILE_ARG = (
network_profile_flags.NetworkProfileArgumentForOtherResource(
'The network profile to apply to this network.'
)
)
cls.NETWORK_PROFILE_ARG.AddArgument(parser)
parser.display_info.AddCacheUpdater(flags.NetworksCompleter)
def Run(self, args):
"""Issues the request necessary for adding the network."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
messages = client.messages
network_utils.CheckRangeLegacyModeOrRaise(args)
network_ref = self.NETWORK_ARG.ResolveAsResource(args, holder.resources)
self._network_name = network_ref.Name()
network_profile_ref = self.NETWORK_PROFILE_ARG.ResolveAsResource(
args, holder.resources
)
network_resource = networks_utils.CreateNetworkResourceFromArgs(
messages=messages,
network_ref=network_ref,
network_args=args,
network_profile_ref=network_profile_ref,
support_firewall_order=self._support_firewall_order,
)
request = (
client.apitools_client.networks,
'Insert',
client.messages.ComputeNetworksInsertRequest(
network=network_resource, project=network_ref.project
),
)
response = client.MakeRequests([request])
resource_dict = resource_projector.MakeSerializable(response[0])
return networks_utils.AddModesForListFormat(resource_dict)
def Epilog(self, resources_were_displayed=True):
EpilogText(self._network_name)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@base.UniverseCompatible
class CreateBeta(Create):
r"""Create a Compute Engine network.
*{command}* is used to create virtual networks. A network
performs the same function that a router does in a home
network: it describes the network range and gateway IP
address, handles communication between instances, and serves
as a gateway between instances and callers outside the
network.
## EXAMPLES
To create a regional auto subnet mode network with the name 'network-name',
run:
$ {command} network-name
To create a global custom subnet mode network with the name 'network-name',
run:
$ {command} network-name \
--bgp-routing-mode=global \
--subnet-mode=custom
"""
@classmethod
def Args(cls, parser):
super(CreateBeta, cls).Args(parser)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@base.UniverseCompatible
class CreateAlpha(CreateBeta):
"""Create a Compute Engine network.
*{command}* is used to create virtual networks. A network
performs the same function that a router does in a home
network: it describes the network range and gateway IP
address, handles communication between instances, and serves
as a gateway between instances and callers outside the
network.
"""
_support_firewall_order = True
NETWORK_PROFILE_ARG = None
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat(flags.LIST_FORMAT_WITH_ULA_IPV6)
cls.NETWORK_ARG = flags.NetworkArgument()
cls.NETWORK_ARG.AddArgument(parser, operation_type='create')
cls.NETWORK_PROFILE_ARG = (
network_profile_flags.NetworkProfileArgumentForOtherResource(
'The network profile to apply to this network.'
)
)
cls.NETWORK_PROFILE_ARG.AddArgument(parser)
network_utils.AddCreateBaseArgs(parser)
network_utils.AddCreateSubnetModeArg(parser)
network_utils.AddCreateBgpRoutingModeArg(parser)
network_utils.AddMtuArg(parser)
network_utils.AddInternalIpv6RangeArg(parser)
network_utils.AddEnableUlaInternalIpv6Arg(parser)
network_utils.AddNetworkFirewallPolicyEnforcementOrderArg(parser)
network_utils.AddBgpBestPathSelectionArgGroup(parser)
network_utils.AddTagsArg(parser)
parser.display_info.AddCacheUpdater(flags.NetworksCompleter)

View File

@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for deleting networks."""
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 flags as compute_flags
from googlecloudsdk.command_lib.compute.networks import flags
class Delete(base.DeleteCommand):
r"""Delete Compute Engine networks.
*{command}* deletes one or more Compute Engine
networks. Networks can only be deleted when no other resources
(e.g., virtual machine instances) refer to them.
## EXAMPLES
To delete a network with the name 'network-name', run:
$ {command} network-name
To delete two networks with the names 'network-name1' and 'network-name2',
run:
$ {command} network-name1 network-name2
"""
NETWORK_ARG = None
@staticmethod
def Args(parser):
Delete.NETWORK_ARG = flags.NetworkArgument(plural=True)
Delete.NETWORK_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(flags.NetworksCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
network_refs = Delete.NETWORK_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client))
utils.PromptForDeletion(network_refs)
requests = []
for network_ref in network_refs:
requests.append((client.apitools_client.networks, 'Delete',
client.messages.ComputeNetworksDeleteRequest(
**network_ref.AsDict())))
return client.MakeRequests(requests)

View File

@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for describing networks."""
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 networks_utils
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.networks import flags
from googlecloudsdk.core.resource import resource_projector
class Describe(base.DescribeCommand):
r"""Describe a Compute Engine network.
*{command}* displays all data associated with Compute Engine
network in a project.
## EXAMPLES
To describe a network with the name 'network-name', run:
$ {command} network-name
"""
NETWORK_ARG = None
@staticmethod
def Args(parser):
Describe.NETWORK_ARG = flags.NetworkArgument()
Describe.NETWORK_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
network_ref = self.NETWORK_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client))
request = client.messages.ComputeNetworksGetRequest(**network_ref.AsDict())
response = client.MakeRequests(
[(client.apitools_client.networks, 'Get', request)])
resource_dict = resource_projector.MakeSerializable(response[0])
return networks_utils.AddModesForListFormat(resource_dict)

View File

@@ -0,0 +1,182 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for getting effective firewalls of GCP networks."""
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 firewalls_utils
from googlecloudsdk.api_lib.compute import lister
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.networks import flags
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.GA, base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA
)
class GetEffectiveFirewalls(base.DescribeCommand, base.ListCommand):
"""Get the effective firewalls of a Compute Engine network.
*{command}* is used to get the effective firewalls applied to the network.
## EXAMPLES
To get the effective firewalls for a network, run:
$ {command} example-network
gets the effective firewalls applied on the network 'example-network'.
"""
@staticmethod
def Args(parser):
flags.NetworkArgument().AddArgument(
parser, operation_type='get effective firewalls'
)
parser.display_info.AddFormat(
firewalls_utils.EFFECTIVE_FIREWALL_LIST_FORMAT
)
lister.AddBaseListerArgs(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
network_ref = flags.NetworkArgument().ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client),
)
request = client.messages.ComputeNetworksGetEffectiveFirewallsRequest(
**network_ref.AsDict()
)
responses = client.MakeRequests(
[(client.apitools_client.networks, 'GetEffectiveFirewalls', request)]
)
res = responses[0]
org_firewall = []
network_firewall = []
all_firewall_policy = []
if hasattr(res, 'firewalls'):
network_firewall = firewalls_utils.SortNetworkFirewallRules(
client, res.firewalls
)
if hasattr(res, 'firewallPolicys') and res.firewallPolicys:
all_unsorted_firewall_policy = []
for fp in res.firewallPolicys:
firewall_policy_rule = firewalls_utils.SortFirewallPolicyRules(
client, fp.rules
)
packet_mirroring_rule = firewalls_utils.SortFirewallPolicyRules(
client, fp.packetMirroringRules
)
fp_response = client.messages.NetworksGetEffectiveFirewallsResponseEffectiveFirewallPolicy(
name=fp.name,
rules=firewall_policy_rule,
packetMirroringRules=packet_mirroring_rule,
type=fp.type,
priority=fp.priority,
)
all_unsorted_firewall_policy.append(fp_response)
all_firewall_policy = firewalls_utils.SortFirewallPolicies(
client, all_unsorted_firewall_policy
)
elif hasattr(res, 'organizationFirewalls'):
for sp in res.organizationFirewalls:
org_firewall_rule = firewalls_utils.SortOrgFirewallRules(
client, sp.rules
)
org_firewall.append(
client.messages.NetworksGetEffectiveFirewallsResponseOrganizationFirewallPolicy(
id=sp.id, rules=org_firewall_rule
)
)
if args.IsSpecified('format') and args.format == 'json':
if org_firewall:
return client.messages.NetworksGetEffectiveFirewallsResponse(
organizationFirewalls=org_firewall,
firewalls=network_firewall,
firewallPolicys=all_firewall_policy,
)
else:
return client.messages.NetworksGetEffectiveFirewallsResponse(
firewalls=network_firewall, firewallPolicys=all_firewall_policy
)
result = []
for fp in all_firewall_policy:
result.extend(
firewalls_utils.ConvertFirewallPolicyRulesToEffectiveFwRules(
client, fp
)
)
for sp in org_firewall:
result.extend(
firewalls_utils.ConvertOrgSecurityPolicyRulesToEffectiveFwRules(sp)
)
result.extend(
firewalls_utils.ConvertNetworkFirewallRulesToEffectiveFwRules(
network_firewall
)
)
return result
def Epilog(self, resources_were_displayed):
del resources_were_displayed
log.status.Print('\n' + firewalls_utils.LIST_NOTICE)
GetEffectiveFirewalls.detailed_help = {
'EXAMPLES': """\
To get the effective firewalls of network with name example-network, run:
$ {command} example-network
To show all fields of the firewall rules, please show in JSON format with
option --format=json
To list more the fields of the rules of network example-network in table
format, run:
$ {command} example-network --format="table(
type,
firewall_policy_name,
rule_type,
priority,
action,
direction,
ip_ranges.list():label=IP_RANGES,
target_svc_acct,
enableLogging,
description,
name,
disabled,
target_tags,
src_svc_acct,
src_tags,
ruleTupleCount,
targetResources:label=TARGET_RESOURCES)"
""",
}

View File

@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for listing networks."""
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.api_lib.compute import networks_utils
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.networks import flags
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class List(base.ListCommand):
"""List Compute Engine networks."""
@staticmethod
def Args(parser):
lister.AddBaseListerArgs(parser)
parser.display_info.AddFormat(flags.LIST_FORMAT_WITH_ULA_IPV6)
parser.display_info.AddCacheUpdater(flags.NetworksCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request_data = lister.ParseNamesAndRegexpFlags(args, holder.resources)
list_implementation = lister.GlobalLister(
client, client.apitools_client.networks)
return (networks_utils.AddModesForListFormat(resource)
for resource in lister.Invoke(request_data, list_implementation))
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListAlpha(List):
"""List Compute Engine networks."""
@staticmethod
def Args(parser):
lister.AddBaseListerArgs(parser)
parser.display_info.AddFormat(flags.LIST_FORMAT_WITH_ULA_IPV6)
parser.display_info.AddCacheUpdater(flags.NetworksCompleter)
List.detailed_help = base_classes.GetGlobalListerHelp('networks')

View File

@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 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 internal IP addresses in a network."""
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.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListIpAddresses(base.ListCommand):
"""List internal IP addresses/ranges related a network."""
example = """\
List all internal IP addresses in a network:
$ {command} my-network
List IP addresses only for given types:
$ {command} my-network \
--types=SUBNETWORK,PEER_USED,REMOTE_USED
"""
detailed_help = {
'brief':
'List internal IP addresses in a network.',
'DESCRIPTION': """\
*{command}* is used to list internal IP addresses in a network.
""",
'EXAMPLES': example
}
@staticmethod
def Args(parser):
base.URI_FLAG.RemoveFromParser(parser)
parser.add_argument('name', help='The name of the network.')
parser.add_argument(
'--types',
type=lambda x: x.replace('-', '_').upper(),
help="""\
Optional comma separate list of ip address types to filter on. Valid
values are `SUBNETWORK`, `RESERVED`, `PEER_USED`, `PEER_RESERVED`,
`REMOTE_USED` and `REMOTE_RESERVED`.
""")
parser.display_info.AddFormat("""\
table(
type,
cidr:label=IP_RANGE,
region,
owner,
purpose)
""")
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client.apitools_client
messages = client.MESSAGES_MODULE
project = properties.VALUES.core.project.Get(required=True)
request = messages.ComputeNetworksListIpAddressesRequest(
project=project, network=args.name, types=args.types)
items = list_pager.YieldFromList(
client.networks,
request,
method='ListIpAddresses',
field='items',
limit=args.limit,
batch_size=None)
return items

View File

@@ -0,0 +1,116 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for listing IP owners in a network."""
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.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListIpOwners(base.ListCommand):
"""List IP owners with optional filters in a network."""
example = """
List all IP owners in a network:
$ {command} my-network
List IP owners only for given owner types:
$ {command} my-network \
--owner-types=instance,address,forwardingRule
List IP owners only for given owner projects:
$ {command} my-network \
--owner-projects=p1,p2
List IP owners only for given subnet:
$ {command} my-network \
--subnet-name=subnet-1 --subnet-region=us-central1
List IP owners whose IP ranges overlap with the given IP CIDR range:
$ {command} my-network \
--ip-cidr-range=10.128.10.130/30
"""
detailed_help = {
'brief': 'List IP owners in a network.',
'DESCRIPTION': '*{command}* is used to list IP owners in a network.',
'EXAMPLES': example
}
@staticmethod
def Args(parser):
parser.add_argument('name', help='The name of the network.')
parser.add_argument(
'--subnet-name',
help=('Only return IP owners in the subnets with the name. '
'Not applicable for legacy networks.'))
parser.add_argument(
'--subnet-region',
help=('Only return IP owners in the subnets of the region. '
'Not applicable for legacy networks.'))
parser.add_argument(
'--ip-cidr-range',
help=
'Only return IP owners whose IP ranges overlap with the IP CIDR range.')
parser.add_argument(
'--owner-projects',
help=('Only return IP owners in the projects. Multiple projects are '
'separated by comma, e.g., "project-1,project-2".'))
parser.add_argument(
'--owner-types',
help=('Only return IP owners of the types, which can be any '
'combination of instance, address, forwardingRule, subnetwork, '
'or network. Multiple types are separated by comma, e.g., '
'"instance,forwardingRule,address"'))
parser.display_info.AddFormat("""
table(
ipCidrRange:label=IP_CIDR_RANGE,
systemOwned:label=SYSTEM_OWNED,
owners.join(','):label=OWNERS)
""")
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client.apitools_client
messages = client.MESSAGES_MODULE
project = properties.VALUES.core.project.Get(required=True)
request = messages.ComputeNetworksListIpOwnersRequest(
project=project,
network=args.name,
subnetName=args.subnet_name,
subnetRegion=args.subnet_region,
ipCidrRange=args.ip_cidr_range,
ownerProjects=args.owner_projects,
ownerTypes=args.owner_types)
items = list_pager.YieldFromList(
client.networks,
request,
method='ListIpOwners',
field='items',
limit=args.limit,
batch_size=None)
return items

View File

@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Commands for reading and manipulating network peerings."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class Peerings(base.Group):
"""List, create, and delete, and update VPC Network Peering."""
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class PeeringsAlpha(base.Group):
"""List, create, delete, and update VPC Network Peering."""
Peerings.detailed_help = {
'DESCRIPTION': """
Read and manipulate VPC Network Peering connections.
For more information about VPC Network Peering, see the
[VPC Network Peering documentation](https://cloud.google.com/vpc/docs/vpc-peering).
See also: [Network API](https://cloud.google.com/compute/docs/reference/rest/v1/networks).
""",
}

View File

@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 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 cancelling a network peering deletion request."""
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.core import properties
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CancelRequestDelete(base.Command):
r"""Cancel deletion request of a Compute Engine network peering.
*{command}* is used to cancel a request to delete a consensus network peering
connection between two networks.
## EXAMPLES
To cancel a deletion request of a consensus peering with the name
'peering-name' between the network 'local-network' and the network
'peer-network', run:
$ {command} peering-name --network=local-network
$ {command} peering-name --network=peer-network
"""
@classmethod
def ArgsCommon(cls, parser):
parser.add_argument('name', help='The name of the peering.')
parser.add_argument(
'--network',
required=True,
help=(
'The name of the network in the current project containing the '
'peering.'
),
)
base.ASYNC_FLAG.AddToParser(parser)
@classmethod
def Args(cls, parser):
cls.ArgsCommon(parser)
def Run(self, args):
"""Issues the request necessary for cancelling deletion request of the peering."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request = client.messages.ComputeNetworksCancelRequestRemovePeeringRequest(
network=args.network,
networksCancelRequestRemovePeeringRequest=(
client.messages.NetworksCancelRequestRemovePeeringRequest(
name=args.name
)
),
project=properties.VALUES.core.project.GetOrFail(),
)
return client.MakeRequests([(
client.apitools_client.networks,
'CancelRequestRemovePeering',
request,
)])

View File

@@ -0,0 +1,193 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for creating network peerings."""
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 batch_helper
from googlecloudsdk.api_lib.compute import utils
from googlecloudsdk.calliope import actions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.networks.peerings import flags
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
def _MakeRequests(client, requests, is_async):
"""Helper for making asynchronous or synchronous peering creation requests."""
if is_async:
responses, errors = batch_helper.MakeRequests(
requests=requests,
http=client.apitools_client.http,
batch_url=client.batch_url)
if not errors:
for operation in responses:
log.status.write('Creating network peering for [{0}]\n'.format(
operation.targetLink))
log.status.write('Monitor its progress at [{0}]\n'.format(
operation.selfLink))
else:
utils.RaiseToolException(errors)
else:
# We want to run through the generator that MakeRequests returns in order
# to actually make the requests.
responses = client.MakeRequests(requests)
return responses
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.GA, base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA
)
class Create(base.Command):
r"""Create a Compute Engine network peering.
*{command}* is used to create peerings between virtual networks. Each side of
a peering association is set up independently. Peering will be active only
when the configuration from both sides matches.
## EXAMPLES
To create a network peering with the name 'peering-name' between the network
'local-network' and the network 'peer-network' which exports and imports
custom routes and subnet routes with public IPs, run:
$ {command} peering-name \
--network=local-network \
--peer-network=peer-network \
--export-custom-routes \
--import-custom-routes \
--export-subnet-routes-with-public-ip \
--import-subnet-routes-with-public-ip
"""
_support_stack_type = False
@classmethod
def ArgsCommon(cls, parser):
parser.add_argument('name', help='The name of the peering.')
parser.add_argument(
'--network',
required=True,
help='The name of the network in the current project to be peered '
'with the peer network.')
parser.add_argument(
'--peer-network',
required=True,
help='The name of the network to be peered with the current network.')
parser.add_argument(
'--peer-project',
required=False,
help='The name of the project for the peer network. If not specified, '
'defaults to current project.')
base.ASYNC_FLAG.AddToParser(parser)
flags.AddImportCustomRoutesFlag(parser)
flags.AddExportCustomRoutesFlag(parser)
flags.AddImportSubnetRoutesWithPublicIpFlag(parser)
flags.AddExportSubnetRoutesWithPublicIpFlag(parser)
flags.AddStackType(parser)
flags.AddUpdateStrategy(parser)
@classmethod
def Args(cls, parser):
cls.ArgsCommon(parser)
action = actions.DeprecationAction(
'auto-create-routes',
warn=(
'Flag --auto-create-routes is deprecated and will '
'be removed in a future release.'
),
action='store_true',
)
parser.add_argument(
'--auto-create-routes',
action=action,
default=False,
required=False,
help=(
'If set, will automatically create routes for the network peering.'
' Flag auto-create-routes is deprecated. Peer network subnet routes'
' are always created in a network when peered.'
),
)
def _CreateNetworkPeeringForRequest(self, client, args):
peer_network_ref = resources.REGISTRY.Parse(
args.peer_network,
params={
'project': (
args.peer_project or properties.VALUES.core.project.GetOrFail
)
},
collection='compute.networks',
)
network_peering = client.messages.NetworkPeering(
name=args.name,
network=peer_network_ref.RelativeName(),
exchangeSubnetRoutes=True,
)
network_peering.exportCustomRoutes = args.export_custom_routes
network_peering.importCustomRoutes = args.import_custom_routes
network_peering.exportSubnetRoutesWithPublicIp = (
args.export_subnet_routes_with_public_ip
)
network_peering.importSubnetRoutesWithPublicIp = (
args.import_subnet_routes_with_public_ip
)
if getattr(args, 'stack_type'):
network_peering.stackType = (
client.messages.NetworkPeering.StackTypeValueValuesEnum(
args.stack_type
)
)
if getattr(args, 'update_strategy'):
network_peering.updateStrategy = (
client.messages.NetworkPeering.UpdateStrategyValueValuesEnum(
args.update_strategy
)
)
return network_peering
def Run(self, args):
"""Issues the request necessary for adding the peering."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request = client.messages.ComputeNetworksAddPeeringRequest(
network=args.network,
networksAddPeeringRequest=client.messages.NetworksAddPeeringRequest(
networkPeering=self._CreateNetworkPeeringForRequest(client, args)),
project=properties.VALUES.core.project.GetOrFail())
requests = [(client.apitools_client.networks, 'AddPeering', request)]
return _MakeRequests(client, requests, args.async_)

View File

@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for deleting network peerings."""
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.core import properties
class Delete(base.DeleteCommand):
r"""Delete a Compute Engine network peering.
*{command}* deletes a Compute Engine network peering.
## EXAMPLES
To delete a network peering with the name 'peering-name' on the network
'local-network', run:
$ {command} peering-name \
--network=local-network
"""
@staticmethod
def Args(parser):
parser.add_argument('name', help='The name of the peering to delete.')
parser.add_argument(
'--network',
required=True,
help='The name of the network in the current project containing the '
'peering.')
def Run(self, args):
"""Issues the request necessary for deleting the peering."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request = client.messages.ComputeNetworksRemovePeeringRequest(
network=args.network,
networksRemovePeeringRequest=(
client.messages.NetworksRemovePeeringRequest(name=args.name)),
project=properties.VALUES.core.project.GetOrFail())
return client.MakeRequests([(client.apitools_client.networks,
'RemovePeering', request)])

View File

@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for listing network peerings."""
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.compute import base_classes
from googlecloudsdk.api_lib.compute import filter_rewrite
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
from googlecloudsdk.core.resource import resource_projection_spec
from googlecloudsdk.core.resource import resource_projector
@base.ReleaseTracks(
base.ReleaseTrack.GA, base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA
)
@base.DefaultUniverseOnly
class List(base.ListCommand):
"""List Compute Engine network peerings."""
@staticmethod
def Args(parser):
parser.display_info.AddFormat("""
table(peerings:format="table(
name,
source_network.basename():label=NETWORK,
network.map().scope(projects).segment(0):label=PEER_PROJECT,
network.basename():label=PEER_NETWORK,
stackType,
peerMtu,
importCustomRoutes,
exportCustomRoutes,
updateStrategy,
state,
stateDetails
)")
""")
parser.add_argument(
'--network', help='Only show peerings of a specific network.')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client.apitools_client
messages = client.MESSAGES_MODULE
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)
request = messages.ComputeNetworksListRequest(
project=project, filter=filter_expr)
for network in list_pager.YieldFromList(
client.networks,
request,
field='items',
limit=args.limit,
batch_size=None):
if network.peerings and (args.network is None or
args.network == network.name):
# Network is synthesized for legacy reasons to maintain prior format.
# In general, synthesized output should not be done.
synthesized_network = resource_projector.MakeSerializable(network)
for peering in synthesized_network['peerings']:
peering['source_network'] = network.selfLink
yield synthesized_network
List.detailed_help = base_classes.GetGlobalListerHelp('peerings')

View File

@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 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 internal IP addresses in a network."""
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.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
from googlecloudsdk.core.resource import resource_projector
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class ListRoutes(base.ListCommand):
"""List received or advertised routes for a VPC network peering."""
example = """\
List received routes for VPC network peering in us-central1:
$ {command} peering-name \
--network=network-name --region=us-central1 --direction=INCOMING
"""
detailed_help = {
'brief':
'List received or advertised routes for a VPC network peering.',
'DESCRIPTION':
"""\
*{command}* is used to list received or advertised routes for a VPC
network peering. This includes subnetwork routes, static custom routes,
and dynamic custom routes.
""",
'EXAMPLES':
example
}
@staticmethod
def Args(parser):
parser.add_argument('name', help='Name of the peering to list routes for.')
parser.add_argument(
'--network', required=True, help='Network of the peering.')
parser.add_argument(
'--region', required=True, help='Region to list the routes for.')
parser.add_argument(
'--direction',
required=True,
choices={
'INCOMING': 'To list received routes.',
'OUTGOING': 'To list advertised routes.',
},
type=lambda x: x.upper(),
help="""\
Direction of the routes to list. To list received routes, use
`INCOMING`. To list advertised routes, use `OUTGOING`.
""")
parser.display_info.AddFormat("""\
table(
dest_range,
type,
next_hop_region,
priority,
status)
""")
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client.apitools_client
messages = client.MESSAGES_MODULE
project = properties.VALUES.core.project.Get(required=True)
list_request = messages.ComputeNetworksListPeeringRoutesRequest
request = list_request(
project=project,
network=args.network,
peeringName=args.name,
region=args.region)
directions = list_request.DirectionValueValuesEnum
if args.direction == 'INCOMING':
request.direction = directions.INCOMING
else:
request.direction = directions.OUTGOING
items = list_pager.YieldFromList(
client.networks,
request,
method='ListPeeringRoutes',
field='items',
limit=args.limit,
batch_size=None)
def _TransformStatus(direction, imported):
"""Create customized status field based on direction and imported."""
if imported:
if direction == 'INCOMING':
return 'accepted'
else:
return 'accepted by peer'
else:
if direction == 'INCOMING':
return 'rejected by config'
else:
return 'rejected by peer config'
for item in items:
route = resource_projector.MakeSerializable(item)
# Set "status" to "Imported" or "Imported by peer" based on direction.
route['status'] = _TransformStatus(args.direction, route['imported'])
yield route

View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 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 network peerings."""
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.core import properties
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RequestDelete(base.Command):
r"""Request deletion of a Compute Engine network peering.
*{command}* is used to request deletion of a consensus peering between virtual
networks. The peering can be deleted if both sides request deletion.
## EXAMPLES
To request deletion of a consensus peering with the name 'peering-name'
between the network 'local-network' and the network 'peer-network', run:
$ {command} peering-name --network=local-network
$ {command} peering-name --network=peer-network
To complete the deletion, run gcloud compute networks peerings delete
for each side of the peering.
"""
@classmethod
def ArgsCommon(cls, parser):
parser.add_argument('name', help='The name of the peering.')
parser.add_argument(
'--network',
required=True,
help=(
'The name of the network in the current project containing the '
'peering.'
),
)
base.ASYNC_FLAG.AddToParser(parser)
@classmethod
def Args(cls, parser):
cls.ArgsCommon(parser)
def Run(self, args):
"""Issues the request necessary for requesting deletion of the peering."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request = client.messages.ComputeNetworksRequestRemovePeeringRequest(
network=args.network,
networksRequestRemovePeeringRequest=(
client.messages.NetworksRequestRemovePeeringRequest(name=args.name)
),
project=properties.VALUES.core.project.GetOrFail(),
)
return client.MakeRequests(
[(client.apitools_client.networks, 'RequestRemovePeering', request)]
)

View File

@@ -0,0 +1,139 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for updating network peerings."""
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 exceptions
from googlecloudsdk.command_lib.compute.networks.peerings import flags
from googlecloudsdk.core import properties
@base.ReleaseTracks(
base.ReleaseTrack.GA, base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA
)
@base.DefaultUniverseOnly
class Update(base.Command):
r"""Update a Compute Engine network peering.
## EXAMPLES
To update the peering named peering-name to both export and import custom
routes, run:
$ {command} peering-name \
--export-custom-routes \
--import-custom-routes
To update the peering named peering-name to both export and import subnet
routes with public ip, run:
$ {command} peering-name \
--export-subnet-routes-with-public-ip \
--import-subnet-routes-with-public-ip
"""
_support_stack_type = False
@classmethod
def Args(cls, parser):
parser.add_argument('name', help='The name of the peering.')
parser.add_argument(
'--network',
required=True,
help=(
'The name of the network in the current project to be peered '
'with the peer network.'
),
)
flags.AddImportCustomRoutesFlag(parser)
flags.AddExportCustomRoutesFlag(parser)
flags.AddImportSubnetRoutesWithPublicIpFlag(parser)
flags.AddExportSubnetRoutesWithPublicIpFlag(parser)
flags.AddStackType(parser)
flags.AddUpdateStrategy(parser)
def Run(self, args):
"""Issues the request necessary for updating the peering."""
self.ValidateArgs(args)
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
network_peering = self._CreateNetworkPeeringForRequest(client, args)
request = client.messages.ComputeNetworksUpdatePeeringRequest(
network=args.network,
networksUpdatePeeringRequest=client.messages.NetworksUpdatePeeringRequest(
networkPeering=network_peering
),
project=properties.VALUES.core.project.GetOrFail(),
)
return client.MakeRequests(
[(client.apitools_client.networks, 'UpdatePeering', request)]
)
def _CreateNetworkPeeringForRequest(self, client, args):
network_peering = client.messages.NetworkPeering(
name=args.name,
exportCustomRoutes=args.export_custom_routes,
importCustomRoutes=args.import_custom_routes,
exportSubnetRoutesWithPublicIp=args.export_subnet_routes_with_public_ip,
importSubnetRoutesWithPublicIp=args.import_subnet_routes_with_public_ip,
)
if getattr(args, 'stack_type'):
network_peering.stackType = (
client.messages.NetworkPeering.StackTypeValueValuesEnum(
args.stack_type
)
)
if getattr(args, 'update_strategy'):
network_peering.updateStrategy = (
client.messages.NetworkPeering.UpdateStrategyValueValuesEnum(
args.update_strategy
)
)
return network_peering
def ValidateArgs(self, args):
"""Validate arguments."""
check_args = [
args.export_custom_routes is None,
args.import_custom_routes is None,
]
check_args.extend([
args.export_subnet_routes_with_public_ip is None,
args.import_subnet_routes_with_public_ip is None,
])
check_args.append(args.stack_type is None)
check_args.append(args.update_strategy is None)
if all(check_args):
raise exceptions.UpdatePropertyError(
'At least one property must be modified.'
)

View File

@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Commands for reading and manipulating subnetworks."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Subnetworks(base.Group):
"""List, describe, and delete, and update Compute Engine subnetworks."""
Subnetworks.detailed_help = {
'DESCRIPTION': """
Read and manipulate VPC subnetworks.
For more information about VPC, see the
[VPC documentation](https://cloud.google.com/vpc/docs/vpc).
See also: [Subnetworks API](https://cloud.google.com/compute/docs/reference/rest/v1/subnetworks).
""",
}

View File

@@ -0,0 +1,62 @@
release_tracks: [GA, BETA, ALPHA]
help_text:
brief: Add an IAM policy binding to a Compute Engine subnetwork.
description: |
Add an IAM policy binding to a Compute Engine subnetwork.
examples: |
To add an IAM policy binding for the role of 'roles/compute.securityAdmin' for the user 'test-user@gmail.com'
with subnetwork 'my-subnet' and region 'REGION', run:
$ {command} my-subnet --region=REGION --member='user:test-user@gmail.com' --role='roles/compute.securityAdmin'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
request:
collection: compute.subnetworks
use_relative_name: false
api_version: v1
BETA:
api_version: beta
ALPHA:
api_version: alpha
iam:
set_iam_policy_request_path: regionSetPolicyRequest
message_type_overrides:
policy: Policy
set_iam_policy_request: ComputeSubnetworksSetIamPolicyRequest
ALPHA:
enable_condition: true
policy_version: 3
get_iam_policy_version_path: optionsRequestedPolicyVersion
BETA:
policy_version: 3
get_iam_policy_version_path: optionsRequestedPolicyVersion
arguments:
resource:
help_text: The subnetwork for which to add the IAM policy to.
spec: !REF googlecloudsdk.command_lib.compute.resources:subnet
ALPHA:
help_text:
brief: Add IAM policy binding to a Compute Engine subnetwork.
description: |
Add an IAM policy binding to the IAM policy of a Compute Engine subnetwork. One binding consists of a member,
a role, and an optional condition.
examples: |
To add an IAM policy binding for the role of 'roles/compute.securityAdmin' for the user 'test-user@gmail.com'
with subnetwork 'my-subnet' and region 'REGION', run:
$ {command} my-subnet --region=REGION --member='user:test-user@gmail.com' --role='roles/compute.securityAdmin'
To add an IAM policy binding which expires at the end of the year 2018 for the role of
'roles/compute.securityAdmin' and the user 'test-user@gmail.com' with subnetwork 'my-subnet' and region 'REGION', run:
$ {command} my-subnet --region=REGION --member='user:test-user@gmail.com' --role='roles/compute.securityAdmin' --condition='expression=request.time < timestamp("2019-01-01T00:00:00Z"),title=expires_end_of_2018,description=Expires at midnight on 2018-12-31'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.

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 subnetwork 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 subnetwork configurations."""

View File

@@ -0,0 +1,38 @@
release_tracks: [ALPHA]
command_type: CONFIG_EXPORT
help_text:
brief: Export the configuration for a Compute Engine subnetwork.
description: |
*{command}* exports the configuration for a Compute Engine subnetwork.
Subnetwork 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
subnetworks within the project.
Specifying `--path` allows you to export the configuration(s) to
a local directory.
examples: |
To export the configuration for a subnetwork, run:
$ {command} my-subnetwork
To export the configuration for a subnetwork to a file, run:
$ {command} my-subnetwork --path=/path/to/dir/
To export the configuration for a subnetwork in Terraform
HCL format, run:
$ {command} my-subnetwork --resource-format=terraform
To export the configurations for all subnetworks within a
project, run:
$ {command} --all
arguments:
resource:
help_text: Subnetwork to export the configuration for.
spec: !REF googlecloudsdk.command_lib.compute.resources:subnet

View File

@@ -0,0 +1,660 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for creating subnetworks."""
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 subnets_utils
from googlecloudsdk.api_lib.compute import utils as compute_api
from googlecloudsdk.api_lib.util import apis
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
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.networks import flags as network_flags
from googlecloudsdk.command_lib.compute.networks.subnets import flags
from googlecloudsdk.command_lib.util.apis import arg_utils
import six
def _DetailedHelp():
return {
'brief':
'Define a subnet for a network in custom subnet mode.',
'DESCRIPTION':
"""\
*{command}* define a subnetwork for a network in custom subnet mode.
Subnets must be uniquely named per region.
""",
'EXAMPLES':
"""\
To create the subnetwork ``subnet-1'' with address range ``10.10.0.0/24'' in the network ``network-0'', run:
$ {command} subnet-1 --network=network-0 --range=10.10.0.0/24 --region=us-central1
"""
}
def _AddArgs(
parser,
include_alpha_logging,
include_aggregate_purpose,
include_l2,
include_custom_hardware_link,
api_version,
include_peer_migration_purpose,
include_resolve_subnet_mask,
):
"""Add subnetwork create arguments to parser."""
parser.display_info.AddFormat(flags.DEFAULT_LIST_FORMAT_WITH_IPV6_FIELD)
flags.SubnetworkArgument().AddArgument(parser, operation_type='create')
network_flags.NetworkArgumentForOtherResource(
'The network to which the subnetwork belongs.').AddArgument(parser)
messages = apis.GetMessagesModule('compute',
compute_api.COMPUTE_GA_API_VERSION)
parser.add_argument(
'--description', help='An optional description of this subnetwork.')
parser.add_argument(
'--range',
help='The IP space allocated to this subnetwork in CIDR format.')
parser.add_argument(
'--enable-private-ip-google-access',
action='store_true',
default=False,
help=('Enable/disable access to Google Cloud APIs from this subnet for '
'instances without a public ip address.'))
parser.add_argument(
'--secondary-range',
type=arg_parsers.ArgDict(min_length=1),
action='append',
metavar='PROPERTY=VALUE',
help="""\
Adds a secondary IP range to the subnetwork for use in IP aliasing.
For example, `--secondary-range range1=192.168.64.0/24` adds
a secondary range 192.168.64.0/24 with name range1.
* `RANGE_NAME` - Name of the secondary range.
* `RANGE` - `IP range in CIDR format.`
""")
parser.add_argument(
'--enable-flow-logs',
action='store_true',
default=None,
help=('Enable/disable VPC Flow Logs for this subnet. More information '
'for VPC Flow Logs can be found at '
'https://cloud.google.com/vpc/docs/using-flow-logs.'))
flags.AddLoggingAggregationInterval(parser, messages)
parser.add_argument(
'--logging-flow-sampling',
type=arg_parsers.BoundedFloat(lower_bound=0.0, upper_bound=1.0),
help="""\
Can only be specified if VPC Flow Logs for this subnetwork is
enabled. The value of the field must be in [0, 1]. Set the sampling rate
of VPC flow logs within the subnetwork where 1.0 means all collected
logs are reported and 0.0 means no logs are reported. Default is 0.5
which means half of all collected logs are reported.
""")
parser.add_argument(
'--logging-filter-expr',
help="""\
Can only be specified if VPC Flow Logs for this subnetwork is enabled.
Export filter used to define which logs should be generated.
""")
flags.AddLoggingMetadata(parser, messages)
parser.add_argument(
'--logging-metadata-fields',
type=arg_parsers.ArgList(),
metavar='METADATA_FIELD',
default=None,
help="""\
Can only be specified if VPC Flow Logs for this subnetwork is enabled
and "metadata" is set to CUSTOM_METADATA. The comma-separated list of
metadata fields that should be added to reported logs.
""")
if include_alpha_logging:
messages = apis.GetMessagesModule('compute',
compute_api.COMPUTE_ALPHA_API_VERSION)
flags.AddLoggingAggregationIntervalDeprecated(parser, messages)
parser.add_argument(
'--flow-sampling',
type=arg_parsers.BoundedFloat(lower_bound=0.0, upper_bound=1.0),
help="""\
Can only be specified if VPC flow logging for this subnetwork is
enabled. The value of the field must be in [0, 1]. Set the sampling rate
of VPC flow logs within the subnetwork where 1.0 means all collected
logs are reported and 0.0 means no logs are reported. Default is 0.5
which means half of all collected logs are reported.
""")
flags.AddLoggingMetadataDeprecated(parser, messages)
purpose_choices = {
'PRIVATE': 'Regular user created or automatically created subnet.',
'INTERNAL_HTTPS_LOAD_BALANCER': (
'Reserved for Internal HTTP(S) Load Balancing.'
),
'REGIONAL_MANAGED_PROXY': (
'Reserved for Regional Envoy-based Load Balancing.'
),
'GLOBAL_MANAGED_PROXY': (
'Reserved for Global Envoy-based Load Balancing.'
),
'PRIVATE_SERVICE_CONNECT': (
'Reserved for Private Service Connect Internal Load Balancing.'
),
'PRIVATE_NAT': 'Reserved for use as source range for Private NAT.',
'PEER_MIGRATION': 'Reserved for subnet migration between peered VPCs.',
}
if include_aggregate_purpose:
purpose_choices['AGGREGATE'] = (
'Reserved for Aggregate Ranges used for aggregating '
'private subnetworks.'
)
if include_custom_hardware_link:
purpose_choices['CUSTOM_HARDWARE_LINK'] = (
'Reserved for Custom Hardware Link.'
)
if include_peer_migration_purpose:
purpose_choices['PEER_MIGRATION'] = (
'Reserved for subnet migration between peered VPCs.'
)
# Subnetwork purpose is introduced with L7ILB feature. Aggregate purpose
# will have to be enabled for a given release track only after L7ILB feature
# is enabled for that release track. Hence if include_aggregate_purpose
# true, this code assumes that L7ILB purpose is enabled.
parser.add_argument(
'--purpose',
choices=purpose_choices,
type=arg_utils.ChoiceToEnumName,
help='The purpose of this subnetwork.')
parser.add_argument(
'--role',
choices={
'ACTIVE': 'The ACTIVE subnet that is currently used.',
'BACKUP': 'The BACKUP subnet that could be promoted to ACTIVE.',
},
type=lambda x: x.replace('-', '_').upper(),
help=(
'The role of subnetwork. This field is required when the purpose is'
' set to GLOBAL_MANAGED_PROXY, REGIONAL_MANAGED_PROXY or'
' INTERNAL_HTTPS_LOAD_BALANCER.'
),
)
# Add private ipv6 google access enum based on api version.
messages = apis.GetMessagesModule('compute', api_version)
GetPrivateIpv6GoogleAccessTypeFlagMapper(messages).choice_arg.AddToParser(
parser)
stack_type_choices = {
'IPV4_ONLY': (
'New VMs in this subnet will only be assigned IPv4 addresses'
),
'IPV4_IPV6': (
'New VMs in this subnet can have both IPv4 and IPv6 addresses'
),
'IPV6_ONLY': (
'New VMs in this subnet will only be assigned IPv6 addresses'
)
}
parser.add_argument(
'--stack-type',
choices=stack_type_choices,
type=arg_utils.ChoiceToEnumName,
help=(
'The stack type for this subnet. Determines if IPv6 is enabled '
'on the subnet. If not specified IPV4_ONLY will be used.'
),
)
ipv6_access_type_choices = {
'EXTERNAL': 'VMs in this subnet can have external IPv6.',
'INTERNAL': 'VMs in this subnet can have internal IPv6.'
}
parser.add_argument(
'--ipv6-access-type',
choices=ipv6_access_type_choices,
type=arg_utils.ChoiceToEnumName,
help=(
'IPv6 access type can be specified only when the subnet is '
'created, or when the subnet is first updated to have a stack '
'type of IPV4_IPV6. Once set, the access type is immutable.'
),
)
parser.display_info.AddCacheUpdater(network_flags.NetworksCompleter)
if include_l2:
l2_args = parser.add_group(help='L2 networking specifications.')
l2_args.add_argument(
'--enable-l2',
action='store_true',
required=True,
help="""\
If set to true, enables l2 networking capability on subnetwork.
""")
l2_args.add_argument(
'--vlan',
type=int,
metavar='VLAN',
help="""\
Specifies ID of the vlan to tag the subnetwork.
""")
parser.add_argument(
'--reserved-internal-range',
help=("""
If set, the primary IP range of the subnetwork will be
associated with the given internal range resource.
If --range is set, the subnetwork will only use the given IP range,
which must be contained by the IP range defined by the internal range resource.
For example,
--range=10.0.0.0/24
--reserved-internal-range //networkconnectivity.googleapis.com/projects/PROJECT/locations/global/internalRanges/RANGE
If --range is not set, the subnetwork will use the entire IP range
defined by the internal range resource.
For example, `--reserved-internal-range //networkconnectivity.googleapis.com/projects/PROJECT/locations/global/internalRanges/RANGE`
"""),
)
parser.add_argument(
'--secondary-range-with-reserved-internal-range',
type=arg_parsers.ArgDict(min_length=1),
action='append',
metavar='RANGE_NAME=INTERNAL_RANGE_URL',
help="""\
Adds secondary IP ranges that are associated with internal range
resources.
For example, `--secondary-range-with-reserved-internal-range
range1=//networkconnectivity.googleapis.com/projects/PROJECT/locations/global/internalRanges/RANGE`
adds a secondary range with the reserved internal range resource.
* `RANGE_NAME` - Name of the secondary range.
* `INTERNAL_RANGE_URL` - `URL of an internal range resource.`
""",
)
parser.add_argument(
'--external-ipv6-prefix',
help=("""
The /64 external IPv6 CIDR range to assign to this subnet. The range must
be associated with an IPv6 BYOIP sub-prefix that is defined by the
--ip-collection flag. If you specify --ip-collection but not
--external-ipv6-prefix, a random /64 range is allocated from
the sub-prefix.
For example, `--external-ipv6-prefix=2600:1901:0:0:0:0:0:0/64`
"""),
)
parser.add_argument(
'--internal-ipv6-prefix',
help=("""
The /64 internal IPv6 CIDR range to assign to this subnet. The range must
be associated with an IPv6 BYOIP sub-prefix that is defined by the
--ip-collection flag. If you specify --ip-collection but not
--internal-ipv6-prefix, a random /64 range is allocated from the
sub-prefix.
For example, `--internal-ipv6-prefix 2600:1901:0:0:0:0:0:0/64`
"""),
)
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 subnetwork.
""",
)
if include_resolve_subnet_mask:
resolve_subnet_mask_choices = {
'ARP_ALL_RANGES': """
VMs connected to this subnet receive ARP responses for IPv4
addresses from any ranges of the subnet that are assigned to the VM's
NIC. The DHCP responses contain the netmask of the subnet, instead of
/32.
""",
'ARP_PRIMARY_RANGE': """
VMs connected to this subnet receive ARP responses only for IP
addresses in the primary IPv4 range of the subnet. DHCP responses
contain the netmask of the subnet, instead of /32.
""",
}
parser.add_argument(
'--resolve-subnet-mask',
choices=resolve_subnet_mask_choices,
type=arg_utils.ChoiceToEnumName,
help='Resolve subnet mask can only be set when subnet is created.',
)
flags.IpCollectionArgument().AddArgument(parser)
def GetPrivateIpv6GoogleAccessTypeFlagMapper(messages):
return arg_utils.ChoiceEnumMapper(
'--private-ipv6-google-access-type',
messages.Subnetwork.PrivateIpv6GoogleAccessValueValuesEnum,
custom_mappings={
'DISABLE_GOOGLE_ACCESS':
'disable',
'ENABLE_BIDIRECTIONAL_ACCESS_TO_GOOGLE':
'enable-bidirectional-access',
'ENABLE_OUTBOUND_VM_ACCESS_TO_GOOGLE':
'enable-outbound-vm-access'
},
help_str='The private IPv6 google access type for the VMs in this subnet.'
)
def _CreateSubnetwork(
messages,
subnet_ref,
network_ref,
args,
include_alpha_logging,
include_aggregate_purpose,
include_l2,
include_custom_hardware_link,
ip_collection_ref,
include_peer_migration_purpose,
include_resolve_subnet_mask,
):
"""Create the subnet resource."""
subnetwork = messages.Subnetwork(
name=subnet_ref.Name(),
description=args.description,
network=network_ref.SelfLink(),
privateIpGoogleAccess=args.enable_private_ip_google_access)
if args.range:
subnetwork.ipCidrRange = args.range
if (args.enable_flow_logs is not None or
args.logging_aggregation_interval is not None or
args.logging_flow_sampling is not None or
args.logging_metadata is not None or
args.logging_filter_expr is not None or
args.logging_metadata_fields is not None):
log_config = messages.SubnetworkLogConfig(enable=args.enable_flow_logs)
if args.logging_aggregation_interval:
log_config.aggregationInterval = flags.GetLoggingAggregationIntervalArg(
messages).GetEnumForChoice(args.logging_aggregation_interval)
if args.logging_flow_sampling is not None:
log_config.flowSampling = args.logging_flow_sampling
if args.logging_metadata:
log_config.metadata = flags.GetLoggingMetadataArg(
messages).GetEnumForChoice(args.logging_metadata)
if args.logging_filter_expr is not None:
log_config.filterExpr = args.logging_filter_expr
if args.logging_metadata_fields is not None:
log_config.metadataFields = args.logging_metadata_fields
subnetwork.logConfig = log_config
if include_alpha_logging:
if (args.enable_flow_logs is not None or
args.aggregation_interval is not None or
args.flow_sampling is not None or args.metadata is not None):
log_config = (
subnetwork.logConfig if subnetwork.logConfig is not None else
messages.SubnetworkLogConfig(enable=args.enable_flow_logs))
if args.aggregation_interval:
log_config.aggregationInterval = (
flags.GetLoggingAggregationIntervalArgDeprecated(
messages).GetEnumForChoice(args.aggregation_interval))
if args.flow_sampling is not None:
log_config.flowSampling = args.flow_sampling
if args.metadata:
log_config.metadata = flags.GetLoggingMetadataArgDeprecated(
messages).GetEnumForChoice(args.metadata)
if args.logging_filter_expr is not None:
log_config.filterExpr = args.logging_filter_expr
if args.logging_metadata_fields is not None:
log_config.metadataFields = args.logging_metadata_fields
subnetwork.logConfig = log_config
if args.purpose:
subnetwork.purpose = messages.Subnetwork.PurposeValueValuesEnum(
args.purpose)
if (
subnetwork.purpose
== messages.Subnetwork.PurposeValueValuesEnum.INTERNAL_HTTPS_LOAD_BALANCER
or subnetwork.purpose
== messages.Subnetwork.PurposeValueValuesEnum.REGIONAL_MANAGED_PROXY
or subnetwork.purpose
== messages.Subnetwork.PurposeValueValuesEnum.GLOBAL_MANAGED_PROXY
or subnetwork.purpose
== messages.Subnetwork.PurposeValueValuesEnum.PRIVATE_SERVICE_CONNECT
or (
include_peer_migration_purpose
and subnetwork.purpose
== messages.Subnetwork.PurposeValueValuesEnum.PEER_MIGRATION
)
or (
include_aggregate_purpose
and subnetwork.purpose
== messages.Subnetwork.PurposeValueValuesEnum.AGGREGATE
)
or (
include_custom_hardware_link
and subnetwork.purpose
== messages.Subnetwork.PurposeValueValuesEnum.CUSTOM_HARDWARE_LINK
)
):
# Clear unsupported fields in the subnet resource
subnetwork.privateIpGoogleAccess = None
subnetwork.enableFlowLogs = None
subnetwork.logConfig = None
if getattr(args, 'role', None):
subnetwork.role = messages.Subnetwork.RoleValueValuesEnum(args.role)
if args.private_ipv6_google_access_type is not None:
subnetwork.privateIpv6GoogleAccess = (
flags.GetPrivateIpv6GoogleAccessTypeFlagMapper(
messages).GetEnumForChoice(args.private_ipv6_google_access_type))
if args.stack_type:
subnetwork.stackType = messages.Subnetwork.StackTypeValueValuesEnum(
args.stack_type)
if args.ipv6_access_type:
subnetwork.ipv6AccessType = (
messages.Subnetwork.Ipv6AccessTypeValueValuesEnum(
args.ipv6_access_type))
if include_l2 and args.enable_l2:
subnetwork.enableL2 = True
if args.vlan is not None:
subnetwork.vlans.append(args.vlan)
if args.reserved_internal_range:
subnetwork.reservedInternalRange = args.reserved_internal_range
if args.external_ipv6_prefix:
subnetwork.externalIpv6Prefix = args.external_ipv6_prefix
if args.internal_ipv6_prefix:
subnetwork.internalIpv6Prefix = args.internal_ipv6_prefix
if ip_collection_ref:
subnetwork.ipCollection = ip_collection_ref.SelfLink()
if args.resource_manager_tags is not None:
subnetwork.params = _CreateSubnetworkParams(
messages, args.resource_manager_tags
)
if include_resolve_subnet_mask:
if args.resolve_subnet_mask:
subnetwork.resolveSubnetMask = (
messages.Subnetwork.ResolveSubnetMaskValueValuesEnum(
args.resolve_subnet_mask
)
)
return subnetwork
def _CreateSubnetworkParams(messages, resource_manager_tags):
resource_manager_tags_map = (
resource_manager_tags_utils.GetResourceManagerTags(resource_manager_tags)
)
params = messages.SubnetworkParams
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
)
)
def _Run(
args,
holder,
include_alpha_logging,
include_aggregate_purpose,
include_l2,
include_custom_hardware_link,
include_peer_migration_purpose,
include_resolve_subnet_mask,
):
"""Issues a list of requests necessary for adding a subnetwork."""
client = holder.client
network_ref = network_flags.NetworkArgumentForOtherResource(
'The network to which the subnetwork belongs.').ResolveAsResource(
args, holder.resources)
subnet_ref = flags.SubnetworkArgument().ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client))
ip_collection_ref = None
if args.ip_collection:
ip_collection_ref = flags.IpCollectionArgument().ResolveAsResource(
args, holder.resources)
subnetwork = _CreateSubnetwork(
client.messages,
subnet_ref,
network_ref,
args,
include_alpha_logging,
include_aggregate_purpose,
include_l2,
include_custom_hardware_link,
ip_collection_ref,
include_peer_migration_purpose,
include_resolve_subnet_mask,
)
request = client.messages.ComputeSubnetworksInsertRequest(
subnetwork=subnetwork,
region=subnet_ref.region,
project=subnet_ref.project)
secondary_ranges = subnets_utils.CreateSecondaryRanges(
client,
args.secondary_range,
args.secondary_range_with_reserved_internal_range,
)
request.subnetwork.secondaryIpRanges = secondary_ranges
return client.MakeRequests([(client.apitools_client.subnetworks, 'Insert',
request)])
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a GA subnet."""
_include_alpha_logging = False
_include_aggregate_purpose = False
_include_l2 = False
_api_version = compute_api.COMPUTE_GA_API_VERSION
_include_custom_hardware_link = False
_include_peer_migration_purpose = True
_include_resolve_subnet_mask = False
detailed_help = _DetailedHelp()
@classmethod
def Args(cls, parser):
_AddArgs(
parser,
cls._include_alpha_logging,
cls._include_aggregate_purpose,
cls._include_l2,
cls._include_custom_hardware_link,
cls._api_version,
cls._include_peer_migration_purpose,
cls._include_resolve_subnet_mask,
)
def Run(self, args):
"""Issues a list of requests necessary for adding a subnetwork."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
return _Run(
args,
holder,
self._include_alpha_logging,
self._include_aggregate_purpose,
self._include_l2,
self._include_custom_hardware_link,
self._include_peer_migration_purpose,
self._include_resolve_subnet_mask,
)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a subnet in the Beta release track."""
_api_version = compute_api.COMPUTE_BETA_API_VERSION
_include_resolve_subnet_mask = True
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Create a subnet in the Alpha release track."""
_include_alpha_logging = True
_include_aggregate_purpose = True
_include_l2 = True
_api_version = compute_api.COMPUTE_ALPHA_API_VERSION
_include_custom_hardware_link = True
_include_peer_migration_purpose = True
_include_resolve_subnet_mask = True

View File

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for deleting subnetworks."""
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 flags as compute_flags
from googlecloudsdk.command_lib.compute.networks.subnets import flags
def _DetailedHelp():
return {
'brief':
'Delete Google Cloud subnetworks.',
'DESCRIPTION':
"""\
*{command}* deletes one or more Google Cloud subnetworks.
Subnetworks can only be deleted when no other resources,
such as VM instances, refer to them.".
""",
'EXAMPLES':
"""\
To delete the subnetwork subnet-1 in the us-central1,
run:
$ {command} subnet-1 --region=us-central1
"""
}
class Delete(base.DeleteCommand):
"""Delete Compute Engine subnetworks.
*{command}* deletes one or more Compute Engine
subnetworks. Subnetworks can only be deleted when no other resources
(e.g., virtual machine instances) refer to them.
"""
SUBNET_ARG = None
detailed_help = _DetailedHelp()
@staticmethod
def Args(parser):
Delete.SUBNET_ARG = flags.SubnetworkArgument(plural=True)
Delete.SUBNET_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(flags.SubnetworksCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
subnet_refs = Delete.SUBNET_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client))
utils.PromptForDeletion(subnet_refs, 'region')
requests = []
for subnet_ref in subnet_refs:
requests.append((client.apitools_client.subnetworks, 'Delete',
client.messages.ComputeSubnetworksDeleteRequest(
**subnet_ref.AsDict())))
return client.MakeRequests(requests)

View File

@@ -0,0 +1,123 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for describing subnetworks."""
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.networks.subnets import flags
from googlecloudsdk.command_lib.util.apis import arg_utils
def _DetailedHelp():
return {
'brief': 'Describe a Compute Engine subnetwork.',
'DESCRIPTION': """\
*{command}* displays all data associated with a Compute Engine
subnetwork.
""",
'EXAMPLES': """\
To display all data associated with subnetwork subnet-1, run:
$ {command} subnet-1
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine subnetwork.
*{command}* displays all data associated with a Compute Engine
subnetwork.
"""
_include_view = True
SUBNETWORK_ARG = None
detailed_help = _DetailedHelp()
@classmethod
def Args(cls, parser):
Describe.SUBNETWORK_ARG = flags.SubnetworkArgument()
Describe.SUBNETWORK_ARG.AddArgument(parser, operation_type='describe')
if cls._include_view:
parser.add_argument(
'--view',
choices={
'WITH_UTILIZATION': (
'Output includes the IP address utilization data of all'
' subnetwork ranges, showing total allocated and free IPv4'
' and IPv6 IP addresses.'
),
},
type=arg_utils.ChoiceToEnumName,
action='append',
help=(
'Specifies the information to include in the output.'
),
)
def _GetSubnetworkViews(self, view, request_message):
views = []
for v in view:
if v == 'WITH_UTILIZATION':
views.append(request_message.ViewsValueValuesEnum.WITH_UTILIZATION)
return views
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
subnetwork_ref = Describe.SUBNETWORK_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(client),
)
request = client.messages.ComputeSubnetworksGetRequest(
**subnetwork_ref.AsDict()
)
if self._include_view and args.view:
request.views = self._GetSubnetworkViews(
args.view, client.messages.ComputeSubnetworksGetRequest
)
return client.MakeRequests(
[(client.apitools_client.subnetworks, 'Get', request)]
)[0]
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@base.UniverseCompatible
class DescribeBeta(Describe):
"""Create a subnet in the Beta release track."""
_include_view = True
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@base.UniverseCompatible
class DescribeAlpha(DescribeBeta):
"""Describe a subnet in the Alpha release track."""
_include_view = True

View File

@@ -0,0 +1,149 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for expanding IP range of a subnetwork."""
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.calliope import exceptions as exceptions
from googlecloudsdk.command_lib.compute import exceptions as compute_exceptions
from googlecloudsdk.command_lib.compute.networks.subnets import flags
from googlecloudsdk.core.console import console_io
import ipaddress
import six
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA)
class ExpandIpRange(base.SilentCommand):
"""Expand IP range of a subnetwork."""
SUBNETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.SUBNETWORK_ARG = flags.SubnetworkArgument()
cls.SUBNETWORK_ARG.AddArgument(parser)
parser.add_argument(
'--prefix-length',
type=int,
help=(
'The new prefix length of the subnet. It must be smaller than the '
'original and in the private address space 10.0.0.0/8, '
'172.16.0.0/12 or 192.168.0.0/16 defined in RFC 1918.'),
required=True)
def Run(self, args):
"""Issues requests for expanding IP CIDR range."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
new_prefix_length = self._ValidatePrefixLength(args.prefix_length)
subnetwork_ref = self.SUBNETWORK_ARG.ResolveAsResource(
args, holder.resources)
original_ip_cidr_range = self._GetOriginalIpCidrRange(
client, subnetwork_ref)
new_ip_cidr_range = self._InferNewIpCidrRange(
subnetwork_ref.Name(), original_ip_cidr_range, new_prefix_length)
self._PromptToConfirm(
subnetwork_ref.Name(), original_ip_cidr_range, new_ip_cidr_range)
request = self._CreateExpandIpCidrRangeRequest(client, subnetwork_ref,
new_ip_cidr_range)
return client.MakeRequests([(client.apitools_client.subnetworks,
'ExpandIpCidrRange', request)])
def _ValidatePrefixLength(self, new_prefix_length):
if not 0 <= new_prefix_length <= 29:
raise exceptions.InvalidArgumentException(
'--prefix-length',
'Prefix length must be in the range [0, 29].')
return new_prefix_length
def _GetOriginalIpCidrRange(self, client, subnetwork_ref):
subnetwork = self._GetSubnetwork(client, subnetwork_ref)
if not subnetwork:
raise compute_exceptions.ArgumentError(
'Subnet [{subnet}] was not found in region {region}.'.format(
subnet=subnetwork_ref.Name(), region=subnetwork_ref.region))
return subnetwork.ipCidrRange
def _InferNewIpCidrRange(
self, subnet_name, original_ip_cidr_range, new_prefix_length):
unmasked_new_ip_range = '{0}/{1}'.format(
original_ip_cidr_range.split('/')[0],
new_prefix_length)
# ipaddress only allows unicode input
network = ipaddress.IPv4Network(six.text_type(unmasked_new_ip_range),
strict=False)
return six.text_type(network)
def _PromptToConfirm(
self, subnetwork_name, original_ip_cidr_range, new_ip_cidr_range):
prompt_message_template = (
'The IP range of subnetwork [{0}] will be expanded from {1} to {2}. '
'This operation may take several minutes to complete '
'and cannot be undone.')
prompt_message = prompt_message_template.format(
subnetwork_name, original_ip_cidr_range, new_ip_cidr_range)
if not console_io.PromptContinue(message=prompt_message, default=True):
raise compute_exceptions.AbortedError('Operation aborted by user.')
def _CreateExpandIpCidrRangeRequest(self, client, subnetwork_ref,
new_ip_cidr_range):
request_body = client.messages.SubnetworksExpandIpCidrRangeRequest(
ipCidrRange=new_ip_cidr_range)
return client.messages.ComputeSubnetworksExpandIpCidrRangeRequest(
subnetwork=subnetwork_ref.Name(),
subnetworksExpandIpCidrRangeRequest=request_body,
project=subnetwork_ref.project,
region=subnetwork_ref.region)
def _GetSubnetwork(self, client, subnetwork_ref):
get_request = (
client.apitools_client.subnetworks,
'Get',
client.messages.ComputeSubnetworksGetRequest(
project=subnetwork_ref.project,
region=subnetwork_ref.region,
subnetwork=subnetwork_ref.Name()))
objects = client.MakeRequests([get_request])
return objects[0] if objects else None
ExpandIpRange.detailed_help = {
'brief': 'Expand the IP range of a Compute Engine subnetwork',
'DESCRIPTION': """
*{command}* expands the IP range of a VPC subnetwork.
For more information about expanding a subnet, see [Expanding a primary IP
range](https://cloud.google.com/vpc/docs/using-vpc#expand-subnet).
This command doesn't work for secondary subnets or for subnets that are used
exclusively for load balancer proxies. For more information, see [Proxy-only
subnets for load balancers](https://cloud.google.com/load-balancing/docs/l7-internal/proxy-only-subnets).
""",
'EXAMPLES': """
To expand the IP range of ``SUBNET'' to /16, run:
$ {command} SUBNET --region=us-central1 --prefix-length=16
""",
}

View File

@@ -0,0 +1,34 @@
- release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Get the IAM policy for a Compute Engine subnetwork.
description: |
*{command}* displays the IAM policy associated with a
Compute Engine subnetwork in a project. If formatted as JSON,
the output can be edited and used as a policy file for
set-iam-policy. The output includes an "etag" field
identifying the version emitted and allowing detection of
concurrent policy updates; see
$ {parent} set-iam-policy for additional details.
examples: |
To print the IAM policy for a given subnetwork, run:
$ {command} my-subnet --region=REGION
request:
collection: compute.subnetworks
use_relative_name: false
api_version: v1
BETA:
api_version: beta
modify_request_hooks:
- googlecloudsdk.command_lib.iam.hooks:UseMaxRequestedPolicyVersion:api_field=optionsRequestedPolicyVersion
ALPHA:
api_version: alpha
modify_request_hooks:
- googlecloudsdk.command_lib.iam.hooks:UseMaxRequestedPolicyVersion:api_field=optionsRequestedPolicyVersion
arguments:
resource:
help_text: The network to display the IAM policy for.
spec: !REF googlecloudsdk.command_lib.compute.resources:subnet

View File

@@ -0,0 +1,128 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for listing subnetworks."""
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.networks.subnets import flags
from googlecloudsdk.command_lib.util.apis import arg_utils
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.UniverseCompatible
class List(base.ListCommand):
"""List subnetworks."""
_include_view = True
_default_list_format = flags.DEFAULT_LIST_FORMAT_WITH_IPV6_FIELD
_utilization_details_list_format = (
flags.DEFAULT_LIST_FORMAT_WITH_UTILIZATION_FIELD
)
@classmethod
def Args(cls, parser):
if cls._include_view:
parser.display_info.AddFormat(cls._utilization_details_list_format)
else:
parser.display_info.AddFormat(cls._default_list_format)
lister.AddRegionsArg(parser)
parser.display_info.AddCacheUpdater(flags.SubnetworksCompleter)
parser.add_argument(
'--network',
help='Only show subnetworks of a specific network.')
if cls._include_view:
parser.add_argument(
'--view',
choices={
'WITH_UTILIZATION': (
'Output includes the IP address utilization data of all'
' subnetwork ranges, showing total allocated and free IPv4'
' and IPv6 IP addresses.'
),
},
type=arg_utils.ChoiceToEnumName,
action='append',
help=(
'Specifies the information to include in the output.'
),
)
def _GetSubnetworkViews(self, view, request_message):
views = []
if view is None:
return views
for v in view:
if v == 'WITH_UTILIZATION':
views.append(request_message.ViewsValueValuesEnum.WITH_UTILIZATION)
return views
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request_data = lister.ParseMultiScopeFlags(args, holder.resources)
if self._include_view:
list_implementation = lister.MultiScopeLister(
client=client,
regional_service=client.apitools_client.subnetworks,
aggregation_service=client.apitools_client.subnetworks,
subnetwork_views_flag=self._GetSubnetworkViews(
args.view, client.messages.ComputeSubnetworksListRequest
),
)
else:
list_implementation = lister.MultiScopeLister(
client=client,
regional_service=client.apitools_client.subnetworks,
aggregation_service=client.apitools_client.subnetworks,
)
for resource in lister.Invoke(request_data, list_implementation):
if args.network is None:
yield resource
elif 'network' in resource:
network_ref = holder.resources.Parse(resource['network'])
if network_ref.Name() == args.network:
yield resource
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@base.UniverseCompatible
class ListBeta(List):
"""Create a subnet in the Beta release track."""
_include_view = True
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@base.UniverseCompatible
class ListAlpha(ListBeta):
"""Describe a subnet in the Alpha release track."""
_include_view = True
List.detailed_help = base_classes.GetRegionalListerHelp('subnetworks')

View File

@@ -0,0 +1,127 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for list subnetworks which the current user has permission to use."""
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.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.GA, base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA
)
class ListUsableSubnets(base.ListCommand):
"""List subnetworks which the current user has permission to use."""
detailed_help = {
'brief': """\
List Compute Engine subnetworks permitted for use.
""",
'DESCRIPTION': """\
*{command}* is used to list Compute Engine subnetworks in a
project that the user has permission to use.
By default, usable subnetworks are listed for the default Google Cloud
project and user account. These values can be overridden by
setting the global flags: `--project=PROJECT_ID` and/or
`--account=ACCOUNT`.
""",
'EXAMPLES': """\
To list all subnetworks in the default project that are usable by the
default user:
$ {command}
To list all subnetworks in the host project ``HOST_PROJECT_ID'' of
Shared VPC that are usable in the service project ``SERVICE_PROJECT_ID''
(see [Shared VPC documentation](https://cloud.google.com/vpc/docs/shared-vpc/))
by the default user:
$ {command} --project=HOST_PROJECT_ID --service-project=SERVICE_PROJECT_ID
To list all subnetworks in the project ``PROJECT_ID'' that are usable
by the user ``ACCOUNT'':
$ {command} --project=PROJECT_ID --account=ACCOUNT
""",
}
@staticmethod
def _EnableComputeApi():
return properties.VALUES.compute.use_new_list_usable_subnets_api.GetBool()
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat("""\
table(
subnetwork.segment(-5):label=PROJECT,
subnetwork.segment(-3):label=REGION,
network.segment(-1):label=NETWORK,
subnetwork.segment(-1):label=SUBNET,
ipCidrRange:label=RANGE,
secondaryIpRanges.map().format("{0} {1}", rangeName, ipCidrRange).list(separator="\n"):label=SECONDARY_RANGES,
purpose,
role,
stackType,
ipv6AccessType,
internalIpv6Prefix,
externalIpv6Prefix
)""")
parser.add_argument(
'--service-project',
required=False,
help="""\
The project id or project number in which the subnetwork is intended to be
used. Only applied for Shared VPC.
See [Shared VPC documentation](https://cloud.google.com/vpc/docs/shared-vpc/).
""",
)
def Collection(self):
return 'compute.subnetworks'
def GetUriFunc(self):
def _GetUri(search_result):
return ''.join([
p.value.string_value
for p
in search_result.resource.additionalProperties
if p.key == 'selfLink'])
return _GetUri
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
messages = holder.client.messages
request = messages.ComputeSubnetworksListUsableRequest(
project=properties.VALUES.core.project.Get(required=True))
if args.service_project:
request.serviceProject = args.service_project
return list_pager.YieldFromList(
client.apitools_client.subnetworks,
request,
method='ListUsable',
batch_size_attribute='maxResults',
batch_size=500,
field='items')

View File

@@ -0,0 +1,62 @@
release_tracks: [GA, BETA, ALPHA]
help_text:
brief: Remove an IAM policy binding from a Compute Engine subnetwork.
description: |
Remove an IAM policy binding from a Compute Engine subnetwork.
examples: |
To remove an IAM policy binding for the role of 'roles/compute.securityAdmin' for the user 'test-user@gmail.com'
with subnetwork 'my-subnet' and region 'REGION', run:
$ {command} my-subnet --region=REGION --member='user:test-user@gmail.com' --role='roles/compute.securityAdmin'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
request:
collection: compute.subnetworks
use_relative_name: false
api_version: v1
BETA:
api_version: beta
ALPHA:
api_version: alpha
iam:
set_iam_policy_request_path: regionSetPolicyRequest
message_type_overrides:
policy: Policy
set_iam_policy_request: ComputeSubnetworksSetIamPolicyRequest
ALPHA:
enable_condition: true
policy_version: 3
get_iam_policy_version_path: optionsRequestedPolicyVersion
BETA:
policy_version: 3
get_iam_policy_version_path: optionsRequestedPolicyVersion
arguments:
resource:
help_text: The subnetwork for which to remove the IAM policy from.
spec: !REF googlecloudsdk.command_lib.compute.resources:subnet
ALPHA:
help_text:
brief: Remove IAM policy binding from a Compute Engine subnetwork.
description: |
Remove an IAM policy binding from the IAM policy of a Compute Engine subnetwork. One binding consists of a member,
a role, and an optional condition.
examples: |
To remove an IAM policy binding for the role of 'roles/compute.securityAdmin' for the user 'test-user@gmail.com'
with subnetwork 'my-subnet' and region 'REGION', run:
$ {command} my-subnet --region=REGION --member='user:test-user@gmail.com' --role='roles/compute.securityAdmin'
To remove an IAM policy binding which expires at the end of the year 2018 for the role of
'roles/compute.securityAdmin' and the user 'test-user@gmail.com' with subnetwork 'my-subnet' and region 'REGION', run:
$ {command} my-subnet --region=REGION --member='user:test-user@gmail.com' --role='roles/compute.securityAdmin' --condition='expression=request.time < timestamp("2019-01-01T00:00:00Z"),title=expires_end_of_2018,description=Expires at midnight on 2018-12-31'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.

View File

@@ -0,0 +1,37 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Set the IAM policy for a Compute Engine subnetwork.
description: |
Sets the IAM policy for the given subnetwork as defined in a JSON or YAML file.
examples: |
The following command will read am IAM policy defined in a JSON file
'policy.json' and set it for the subnetwork `my-subnet`:
$ {command} my-subnet policy.json --region=REGION
See https://cloud.google.com/iam/docs/managing-policies for details of the
policy file format and contents.
request:
collection: compute.subnetworks
use_relative_name: false
modify_request_hooks:
- googlecloudsdk.command_lib.iam.hooks:UseMaxRequestedPolicyVersion:api_field=regionSetPolicyRequest.policy.version
api_version: v1
BETA:
api_version: beta
ALPHA:
api_version: alpha
iam:
set_iam_policy_request_path: regionSetPolicyRequest
message_type_overrides:
policy: Policy
set_iam_policy_request: ComputeSubnetworksSetIamPolicyRequest
arguments:
resource:
help_text: The subnetwork to set the IAM policy for.
spec: !REF googlecloudsdk.command_lib.compute.resources:subnet

View File

@@ -0,0 +1,171 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for modifying the properties of a subnetwork."""
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 subnets_utils
from googlecloudsdk.api_lib.compute import utils as compute_api
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.networks.subnets import flags
def _DetailedHelp():
return {
'brief':
'Updates properties of an existing Compute Engine subnetwork.',
'DESCRIPTION':
"""\
*{command}* is used to update properties of an existing Compute Engine
subnetwork.
""",
'EXAMPLES':
"""\
To enable external IPv6 addresses on the subnetwork example-subnet-1 in
network-1, run
$ {command} example-subnet-1 --stack-type=IPV4_IPV6 \
--ipv6-access-type=EXTERNAL \
--region=REGION
"""
}
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Updates properties of an existing Compute Engine subnetwork."""
_include_alpha_logging = False
_include_allow_cidr_routes_overlap = False
_api_version = compute_api.COMPUTE_GA_API_VERSION
_update_purpose_to_private = True
detailed_help = _DetailedHelp()
@classmethod
def Args(cls, parser):
"""The command arguments handler.
Args:
parser: An argparse.ArgumentParser instance.
"""
cls.SUBNETWORK_ARG = flags.SubnetworkArgument()
cls.SUBNETWORK_ARG.AddArgument(parser, operation_type='update')
flags.IpCollectionArgument().AddArgument(parser, operation_type='update')
flags.AddUpdateArgs(
parser,
cls._include_alpha_logging,
cls._include_allow_cidr_routes_overlap,
cls._api_version,
cls._update_purpose_to_private,
)
def Run(self, args):
"""Issues requests necessary to update Subnetworks."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
subnet_ref = self.SUBNETWORK_ARG.ResolveAsResource(args, holder.resources)
aggregation_interval = args.logging_aggregation_interval
flow_sampling = args.logging_flow_sampling
metadata = args.logging_metadata
filter_expr = args.logging_filter_expr
metadata_fields = args.logging_metadata_fields
if self._include_alpha_logging:
if args.aggregation_interval is not None:
aggregation_interval = args.aggregation_interval
if args.flow_sampling is not None:
flow_sampling = args.flow_sampling
if args.metadata is not None:
metadata = args.metadata
set_role_active = None
drain_timeout_seconds = args.drain_timeout
if args.role is not None:
set_role_active = getattr(args, 'role', None) == 'ACTIVE'
set_new_purpose = None
if args.purpose is not None:
set_new_purpose = getattr(args, 'purpose', None)
private_ipv6_google_access_type = args.private_ipv6_google_access_type
allow_cidr_routes_overlap = None
if self._include_allow_cidr_routes_overlap:
allow_cidr_routes_overlap = args.allow_cidr_routes_overlap
stack_type = getattr(args, 'stack_type', None)
ipv6_access_type = getattr(args, 'ipv6_access_type', None)
reserved_internal_ranges = getattr(
args, 'add_secondary_ranges_with_reserved_internal_range', None)
external_ipv6_prefix = getattr(args, 'external_ipv6_prefix', None)
internal_ipv6_prefix = getattr(args, 'internal_ipv6_prefix', None)
ip_collection = None
if args.ip_collection:
ip_collection = flags.IpCollectionArgument().ResolveAsResource(
args, holder.resources
).SelfLink()
return subnets_utils.MakeSubnetworkUpdateRequest(
client,
subnet_ref,
enable_private_ip_google_access=args.enable_private_ip_google_access,
add_secondary_ranges=args.add_secondary_ranges,
add_secondary_ranges_with_reserved_internal_range=reserved_internal_ranges,
remove_secondary_ranges=args.remove_secondary_ranges,
enable_flow_logs=args.enable_flow_logs,
aggregation_interval=aggregation_interval,
flow_sampling=flow_sampling,
metadata=metadata,
filter_expr=filter_expr,
metadata_fields=metadata_fields,
set_role_active=set_role_active,
set_new_purpose=set_new_purpose,
drain_timeout_seconds=drain_timeout_seconds,
private_ipv6_google_access_type=private_ipv6_google_access_type,
allow_cidr_routes_overlap=allow_cidr_routes_overlap,
stack_type=stack_type,
ipv6_access_type=ipv6_access_type,
external_ipv6_prefix=external_ipv6_prefix,
internal_ipv6_prefix=internal_ipv6_prefix,
ip_collection=ip_collection,
)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Updates properties of an existing Compute Engine subnetwork."""
_include_allow_cidr_routes_overlap = True
_api_version = compute_api.COMPUTE_BETA_API_VERSION
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Updates properties of an existing Compute Engine subnetwork."""
_include_alpha_logging = True
_include_allow_cidr_routes_overlap = True
_api_version = compute_api.COMPUTE_ALPHA_API_VERSION
_update_purpose_to_private = True

View File

@@ -0,0 +1,315 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 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 networks."""
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.operations import poller
from googlecloudsdk.api_lib.util import waiter
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.networks import flags
from googlecloudsdk.command_lib.compute.networks import network_utils
from googlecloudsdk.core import log
from googlecloudsdk.core import resources
from googlecloudsdk.core.console import console_io
from googlecloudsdk.core.console import progress_tracker
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.UniverseCompatible
class Update(base.UpdateCommand):
r"""Update a Compute Engine Network.
*{command}* is used to update virtual networks. The updates that
cabe be performed on a network are changing the BGP routing mode
and switching from auto subnet mode to custom subnet mode. Switching
from auto subnet mode to custom subnet mode cannot be undone.
## EXAMPLES
To update regional network with the name 'network-name' to global, run:
$ {command} network-name \
--bgp-routing-mode=global
To update an auto subnet mode network with the name 'network-name' to custom
subnet mode, run:
$ {command} network-name \
--switch-to-custom-subnet-mode
"""
NETWORK_ARG = None
_support_firewall_order = True
MIGRATION_STAGES = dict(
VALIDATING_NETWORK='Validating Network',
CREATING_SUBNETWORK='Creating Subnetwork',
UPDATING_INSTANCES='Updating Instances',
UPDATING_INSTANCE_GROUPS='Updating Instance Groups',
UPDATING_FORWARDING_RULES='Updating Forwarding Rules',
CONVERTING_NETWORK_TO_SUBNET_MODE='Converting Network to Subnet Mode',
)
@classmethod
def Args(cls, parser):
cls.NETWORK_ARG = flags.NetworkArgument()
cls.NETWORK_ARG.AddArgument(parser)
base.ASYNC_FLAG.AddToParser(parser)
network_utils.AddUpdateArgs(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
messages = holder.client.messages
service = holder.client.apitools_client.networks
cleared_fields = []
network_ref = self.NETWORK_ARG.ResolveAsResource(args, holder.resources)
if args.switch_to_custom_subnet_mode:
prompt_msg = (
'Network [{0}] will be switched to custom mode. '.format(
network_ref.Name()
)
+ 'This operation cannot be undone.'
)
console_io.PromptContinue(
message=prompt_msg, default=True, cancel_on_no=True
)
result = service.SwitchToCustomMode(
messages.ComputeNetworksSwitchToCustomModeRequest(
project=network_ref.project, network=network_ref.Name()
)
)
operation_ref = resources.REGISTRY.Parse(
result.name,
params={'project': network_ref.project},
collection='compute.globalOperations',
)
if args.async_:
log.UpdatedResource(
operation_ref,
kind='network {0}'.format(network_ref.Name()),
is_async=True,
details=(
'Run the [gcloud compute operations describe] command '
'to check the status of this operation.'
),
)
return result
operation_poller = poller.Poller(service, network_ref)
if result.operationType == 'switchLegacyToCustomModeBeta':
return self._WaitForLegacyNetworkMigration(
operation_poller, operation_ref
)
return waiter.WaitFor(
poller=operation_poller,
operation_ref=operation_ref,
message='Switching network to custom-mode',
)
network_resource = messages.Network()
should_patch = False
if getattr(args, 'mtu', None) is not None:
msg = (
'This might cause connectivity issues when '
+ 'there are running VMs attached.'
)
console_io.PromptContinue(message=msg, default=False, cancel_on_no=True)
network_resource.mtu = args.mtu
should_patch = True
if hasattr(args, 'enable_ula_internal_ipv6'):
network_resource.enableUlaInternalIpv6 = args.enable_ula_internal_ipv6
should_patch = True
if hasattr(args, 'internal_ipv6_range'):
network_resource.internalIpv6Range = args.internal_ipv6_range
should_patch = True
if args.bgp_routing_mode:
should_patch = True
network_resource.routingConfig = messages.NetworkRoutingConfig()
network_resource.routingConfig.routingMode = (
messages.NetworkRoutingConfig.RoutingModeValueValuesEnum(
args.bgp_routing_mode.upper()
)
)
if getattr(args, 'bgp_best_path_selection_mode', None) is not None:
bps_change_warning_message = (
'Updating the best path selection mode can cause routing changes for'
' egress traffic. No new routes are learned or deleted, and data'
" plane traffic isn't dropped or interrupted."
)
console_io.PromptContinue(
message=bps_change_warning_message, default=True, cancel_on_no=True
)
should_patch = True
if getattr(network_resource, 'routingConfig', None) is None:
network_resource.routingConfig = messages.NetworkRoutingConfig()
network_resource.routingConfig.bgpBestPathSelectionMode = (
messages.NetworkRoutingConfig.BgpBestPathSelectionModeValueValuesEnum(
args.bgp_best_path_selection_mode
)
)
# In case the customer set the BGP BPS mode to LEGACY, we need to clear
# any STANDARD mode-only fields.
if args.bgp_best_path_selection_mode == 'LEGACY':
cleared_fields.append('routingConfig.bgpAlwaysCompareMed')
cleared_fields.append('routingConfig.bgpInterRegionCost')
if getattr(args, 'bgp_bps_always_compare_med', None) is not None:
should_patch = True
if getattr(network_resource, 'routingConfig', None) is None:
network_resource.routingConfig = messages.NetworkRoutingConfig()
network_resource.routingConfig.bgpAlwaysCompareMed = (
args.bgp_bps_always_compare_med
)
if getattr(args, 'bgp_bps_inter_region_cost', None) is not None:
should_patch = True
if getattr(network_resource, 'routingConfig', None) is None:
network_resource.routingConfig = messages.NetworkRoutingConfig()
network_resource.routingConfig.bgpInterRegionCost = (
messages.NetworkRoutingConfig.BgpInterRegionCostValueValuesEnum(
args.bgp_bps_inter_region_cost
)
)
if (
self._support_firewall_order
and args.network_firewall_policy_enforcement_order
):
should_patch = True
network_resource.networkFirewallPolicyEnforcementOrder = (
messages.Network.NetworkFirewallPolicyEnforcementOrderValueValuesEnum(
args.network_firewall_policy_enforcement_order
)
)
if should_patch:
with holder.client.apitools_client.IncludeFields(cleared_fields):
resource = service.Patch(
messages.ComputeNetworksPatchRequest(
project=network_ref.project,
network=network_ref.Name(),
networkResource=network_resource,
)
)
return resource
def _WaitForLegacyNetworkMigration(self, operation_poller, operation_ref):
progress_stages = []
for key, label in self.MIGRATION_STAGES.items():
progress_stages.append(progress_tracker.Stage(label, key=key))
tracker = progress_tracker.StagedProgressTracker(
message='Migrating Network from Legacy to Custom Mode',
stages=progress_stages,
)
first_status_message = list(self.MIGRATION_STAGES.keys())[0]
tracker.last_status_message = first_status_message
return waiter.WaitFor(
poller=operation_poller,
operation_ref=operation_ref,
custom_tracker=tracker,
tracker_update_func=self._LegacyNetworkMigrationTrackerUpdateFunc,
)
def _LegacyNetworkMigrationTrackerUpdateFunc(
self, tracker, operation, unused_status
):
latest_status_message = operation.statusMessage
self._MarkStagesCompleted(tracker, latest_status_message)
tracker.StartStage(latest_status_message)
tracker.last_status_message = latest_status_message
# Mark all stages between last and latest status messages as completed
def _MarkStagesCompleted(self, tracker, latest_status_message):
ordered_stages = list(self.MIGRATION_STAGES.keys())
last_status_message_idx = ordered_stages.index(tracker.last_status_message)
latest_status_message_idx = ordered_stages.index(latest_status_message)
stages_to_update = list(self.MIGRATION_STAGES.keys())[
last_status_message_idx:latest_status_message_idx
]
for stage_to_update in stages_to_update:
tracker.CompleteStage(stage_to_update)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@base.UniverseCompatible
class UpdateBeta(Update):
r"""Update a Compute Engine Network.
*{command}* is used to update virtual networks. The updates that
cabe be performed on a network are changing the BGP routing mode
and switching from auto subnet mode to custom subnet mode. Switching
from auto subnet mode to custom subnet mode cannot be undone.
## EXAMPLES
To update regional network with the name 'network-name' to global, run:
$ {command} network-name \
--bgp-routing-mode=global
To update an auto subnet mode network with the name 'network-name' to custom
subnet mode, run:
$ {command} network-name \
--switch-to-custom-subnet-mode
"""
_support_firewall_order = True
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@base.UniverseCompatible
class UpdateAlpha(UpdateBeta):
"""Update a Compute Engine Network."""
_support_firewall_order = True
@classmethod
def Args(cls, parser):
cls.NETWORK_ARG = flags.NetworkArgument()
cls.NETWORK_ARG.AddArgument(parser)
base.ASYNC_FLAG.AddToParser(parser)
network_utils.AddUpdateArgs(parser)
Update.detailed_help = {
'brief': 'Update a Compute Engine network',
'DESCRIPTION': """\
*{command}* is used to update Compute Engine networks.""",
}

View File

@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The command group for the Cloud VPC Access Service."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class VpcAccess(base.Group):
"""Manage VPC Access Service resources.
Commands for managing Google VPC Access Service resources.
"""
def Filter(self, context, args):
del context, args
# Explicitly enables user-project-override as it's disabled at compute
# level.
base.EnableUserProjectQuota()
@base.Hidden
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class VpcAccessAlpha(base.Group):
"""Manage VPC Access Service resources.
Commands for managing Google VPC Access Service resources.
"""
def Filter(self, context, args):
del context, args
# Explicitly enables user-project-override as it's disabled at compute
# level.
base.EnableUserProjectQuota()

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The command group for connectors of Google VPC Access Service."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Connectors(base.Group):
"""Manage Serverless VPC Access Service connectors.
Commands for managing connectors resource for VPC Access Service.
"""

View File

@@ -0,0 +1,142 @@
- release_tracks: [GA, BETA, ALPHA]
help_text:
brief: |
Create a VPC Access connector.
description: |
Create a new VPC Access connector with the given name.
This command can fail for the following reasons:
* An instance with the same name already exists.
* The active account does not have permission to create instances.
examples: |
The following command creates a VPC Access connector with name 'my-vpc-connector'
in region 'us-central1' in network 'my-network' with IP CIDR range of '10.132.0.0/28'.
$ {command} my-vpc-connector --region=us-central1 --network=my-network
--range=10.132.0.0/28
async:
collection: vpcaccess.projects.locations.operations
request:
collection: vpcaccess.projects.locations.connectors
api_version: v1
BETA:
api_version: v1beta1
ALPHA:
api_version: v1alpha1
arguments:
resource:
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:connector_v1
ALPHA:
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:connector
help_text: |
Arguments and flags that specify the VPC Access connector you want to create.
params:
- group:
mutex: true
params:
- group:
help_text: |
The Serverless VPC Access API can internally manage the creation
of a subnet to house the VPC connector. To create this
subnet, the network ID (--network) and an IP CIDR range (--range)
for the subnet must be provided.
params:
- arg_name: network
api_field: connector.network
required: false
help_text: |
Name of the Compute Engine network to which the connector
will be connected. If left unspecified, the default network will be
used.
default: default
- arg_name: range
api_field: connector.ipCidrRange
required: false
help_text: |
CIDR range of internal addresses that are reserved for this
connector. For example, 10.132.0.0/28. Range must be unique and
non-overlapping with existing ranges in the network.
- group:
help_text: |
You can specify a subnet in which to place the connector rather than
using an internally managed subnet. If you wish to use this
connector to attach your Serverless application to a Shared VPC,
first share a subnet to the project to which you are deploying your connector.
Then, supply the name of the subnet (--subnet) and the
project ID (--subnet-project) from which the subnet is hosted to
connect to this VPC.
params:
- arg_name: subnet
api_field: connector.subnet.name
required: false
help_text: |
User-provided subnet to house the connector. This field can be used in
favor of specifying the `network` and `range` fields.
e.g. "my-subnet"
- arg_name: subnet-project
api_field: connector.subnet.projectId
required: false
help_text: |
Project ID of the provided subnet. The default is the project of the connector.
- group:
release_tracks: [ALPHA, BETA, GA]
mutex: true
params:
- group:
help_text: |
Scaling settings of a VPC Access Connector can be specified in terms of
throughput.
params:
- arg_name: min-throughput
api_field: connector.minThroughput
required: false
help_text: |
Minimum throughput of the connector in Mbps. Refers to the expected throughput when
using an `e2-micro` machine type. Value must be a multiple of 100 from 200 through
900. Must be lower than the value specified by `--max-throughput`. If both
min-throughput and min-instances are provided, min-instances takes precedence over
min-throughput. The use of `min-throughput` is discouraged in favor of
`min-instances`.
- arg_name: max-throughput
api_field: connector.maxThroughput
required: false
help_text: |
Maximum throughput of the connector in Mbps. Refers to the expected throughput when
using an `e2-micro` machine type. Value must be a multiple of 100 from 300 through
1000. Must be higher than the value specified by `--min-throughput`. If both
max-throughput and max-instances are provided, max-instances takes precedence over
max-throughput. The use of `max-throughput` is discouraged in favor of
`max-instances`.
- group:
help_text: |
Scaling settings of a VPC Access Connector can be specified in terms of number
of Google Compute Engine VM instances underlying the connector autoscaling group.
params:
- arg_name: min-instances
api_field: connector.minInstances
default: 2
required: false
help_text: |
Minimum number of instances within an autoscaling group underlying the connector.
Value must be between 2 and 9, inclusive. Must be lower than the value specified by
`--max-instances`.
- arg_name: max-instances
api_field: connector.maxInstances
default: 10
required: false
help_text: |
Maximum number of instances within an autoscaling group underlying the connector.
Value must be between 3 and 10, inclusive. Must be higher than the value specified by
`--min-instances`.
- arg_name: machine-type
api_field: connector.machineType
release_tracks: [ALPHA, BETA, GA]
required: false
help_text: |
Machine type of VMs underlying the VPC Access connector. Accepted values are ``e2-micro'',
``f1-micro'', and ``e2-standard-4''. If left unspecified, the ``e2-micro'' machine type is
used.

View File

@@ -0,0 +1,38 @@
- release_tracks: [GA, BETA, ALPHA]
help_text:
brief: |
Delete a VPC Access connector.
description: |
Delete a new VPC Access connector with the given name.
This command can fail for the following reasons:
* An instance with the same name already exists.
* The active account does not have permission to delete instances.
examples: |
The following command deletes a VPC Access connector with name
`my-vpc-connector` in region `us-central1`:
$ {command} my-vpc-connector --region=us-central1
async:
collection: vpcaccess.projects.locations.operations
request:
collection: vpcaccess.projects.locations.connectors
api_version: v1
BETA:
api_version: v1beta1
ALPHA:
api_version: v1alpha1
input:
confirmation_prompt: |
You are about to delete connector [{__name__}] in [{locationsId}].
Any associated data will be lost.
arguments:
resource:
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:connector
help_text: |
Arguments and flags that specify the VPC Access connector you want
to delete.

View File

@@ -0,0 +1,49 @@
- release_tracks: [GA, BETA, ALPHA]
help_text:
brief: |
Show metadata for a VPC Access connector.
description: |
Display all metadata associated with a VPC Access connector
given a valid connector name.
This command can fail for the following reasons:
* The connector specified does not exist.
* The active account does not have permission to access the given
operation.
examples: |
The following command prints metadata for a connector with name
`my-vpcaccesss-connector` in region `us-central1`:
$ {command} my-vpcaccess-connector --region=us-central
request:
collection: vpcaccess.projects.locations.connectors
api_version: v1
BETA:
api_version: v1beta1
ALPHA:
api_version: v1alpha1
response:
id_field: name
arguments:
resource:
help_text: The connector to describe.
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:connector
BETA:
output:
format: |
table(
name.basename():label=CONNECTOR_ID:sort=1,
name.segment(3):label=REGION,
network,
ipCidrRange,
subnet.name:label=SUBNET,
subnet.projectId:label=SUBNET_PROJECT,
machineType,
minInstances,
maxInstances,
state
)

View File

@@ -0,0 +1,77 @@
- release_tracks: [GA, BETA, ALPHA]
help_text:
brief: |
List VPC Access connectors.
description: |
List all VPC Access connectors under the specified project and region.
You can specify the maximum number of connectors to list using the
`--limit` flag.
examples: |
The following command lists a maximum of five instances in us-central1:
$ {command} --region=us-central1 --limit=5
request:
collection: vpcaccess.projects.locations.connectors
api_version: v1
BETA:
api_version: v1beta1
ALPHA:
api_version: v1alpha1
response:
id_field: name
arguments:
resource:
help_text: The region of the connectors to list.
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:region
ALPHA:
output:
format: |
table(
name.basename():label=CONNECTOR_ID:sort=1,
name.segment(3):label=REGION,
network,
ipCidrRange,
subnet.name:label=SUBNET,
subnet.projectId:label=SUBNET_PROJECT,
machineType,
minInstances,
maxInstances,
status
)
BETA:
output:
format: |
table(
name.basename():label=CONNECTOR_ID:sort=1,
name.segment(3):label=REGION,
network,
ipCidrRange,
subnet.name:label=SUBNET,
subnet.projectId:label=SUBNET_PROJECT,
machineType,
minInstances,
maxInstances,
state
)
GA:
output:
format: |
table(
name.basename():label=CONNECTOR_ID:sort=1,
name.segment(3):label=REGION,
network,
ipCidrRange,
subnet.name:label=SUBNET,
subnet.projectId:label=SUBNET_PROJECT,
machineType,
minInstances,
maxInstances,
minThroughput,
maxThroughput,
state
)

View File

@@ -0,0 +1,60 @@
- release_tracks: [ALPHA, BETA, GA]
help_text:
brief: |
Update a VPC Access connector.
description: |
Update an existing VPC Access connector with the given name.
This command can fail for the following reasons:
* Invalid parameters are passed to this command.
* The active account does not have permission to update instances.
examples: |
The following command updates a VPC Access connector with name
`my-vpc-connector` in region `us-central1`:
$ {command} my-vpc-connector --region=us-central1 --min-instances=3 --max-instances=5
async:
collection: vpcaccess.projects.locations.operations
request:
collection: vpcaccess.projects.locations.connectors
api_version: v1
BETA:
api_version: v1beta1
ALPHA:
api_version: v1alpha1
arguments:
resource:
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:connector_v1
ALPHA:
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:connector
help_text: |
Arguments and flags that specify the VPC Access connector you want to update.
params:
- arg_name: min-instances
release_tracks: [ALPHA, BETA, GA]
api_field: connector.minInstances
required: false
help_text: |
If set, updates the minimum number of instances within an autoscaling group underlying the
connector. Value must be between 2 and 9, inclusive, greater than or equal to the currently
set minimum number of instances, and less than the value specified by --max-instances`.
`--max-instances` must be provided
- arg_name: max-instances
release_tracks: [ALPHA, BETA, GA]
api_field: connector.maxInstances
required: false
help_text: |
If set, updates the maximum number of instances within an autoscaling group underlying the
connector. Value must be between 3 and 10, inclusive, greater than or equal to the currently
set maximum number of instances, and greater than the value specified by `--min-instances`.
`--min-instances` must be provided.
- arg_name: machine-type
release_tracks: [ALPHA, BETA, GA]
api_field: connector.machineType
required: false
help_text: |
If set, updates the machine type of VMs underlying the connector. Accepted values are
"e2-micro", "f1-micro", and "e2-standard-4".

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The command group for locations of Google VPC Access Service."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Locations(base.Group):
"""Manage locations resource for VPC Access Service.
Commands for managing locations resource for VPC Access Service.
"""

View File

@@ -0,0 +1,30 @@
- release_tracks: [GA, BETA, ALPHA]
help_text:
brief: |
List VPC Access Service regions
description: |
List all regions where VPC Access Service API is available.
examples: |
The following command lists all the regions where you can create VPC
Access connectors:
$ {command}
request:
collection: vpcaccess.projects.locations
api_version: v1
BETA:
api_version: v1beta1
ALPHA:
api_version: v1alpha1
response:
id_field: name
arguments:
resource:
help_text: The project of the locations to list.
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:project
output:
format: table(name.scope("locations").segment(0):label=REGION:sort=1)

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The command group for operations of Google VPC Access Service."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Operations(base.Group):
"""Manage operations resource for VPC Access Service.
Commands for managing operations resource for VPC Access Service.
"""

View File

@@ -0,0 +1,34 @@
- release_tracks: [GA, BETA, ALPHA]
help_text:
brief: |
Show metadata for a VPC Access Service operation.
description: |
Display all metadata associated with a VPC Access Service operation
given a valid operation name.
This command can fail for the following reasons:
* The operation specified does not exist.
* The active account does not have permission to access the given
operation.
examples: |
The following command prints metadata for an operation with the name
in region `us-central1`:
$ {command} operation-1564112342235-435a134f8c3f8-81bb4b49-0830c1f8
--region=us-central
request:
collection: vpcaccess.projects.locations.operations
api_version: v1
BETA:
api_version: v1beta1
ALPHA:
api_version: v1alpha1
response:
id_field: name
arguments:
resource:
help_text: The operation to describe.
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:operation

View File

@@ -0,0 +1,43 @@
- release_tracks: [GA, BETA, ALPHA]
help_text:
brief: |
List VPC Access Service operations.
description: |
List all VPC Access Service operations under the specified project and
region.
You can specify the maximum number of operations to list using the
`--limit` flag.
examples: |
The following command lists a maximum of five operations in region
`us-central1`:
$ {command} --region=us-central1 --limit=5
request:
collection: vpcaccess.projects.locations.operations
api_version: v1
BETA:
api_version: v1beta1
ALPHA:
api_version: v1alpha1
response:
id_field: name
arguments:
resource:
help_text: The region of the operations to list.
spec: !REF googlecloudsdk.command_lib.compute.networks.vpc_access.resources:region
output:
format: |
table(
name.basename():label=OPERATION_ID,
name.segment(3):label=REGION,
metadata.target.basename(),
metadata.method:label=METHOD,
done,
metadata.firstof(createTime, insertTime).date():label=START_TIME:sort=1:reverse,
metadata.endTime.date().yesno(no="-")
)