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,41 @@
# -*- 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.
"""Commands for reading and manipulating interconnects."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class Interconnects(base.Group):
"""Read and manipulate Compute Engine interconnects."""
Interconnects.category = base.NETWORKING_CATEGORY
Interconnects.detailed_help = {
'DESCRIPTION': """
Read and manipulate Cloud Interconnect connections.
For more information about Cloud Interconnect, see the
[Cloud Interconnect documentation](https://cloud.google.com//network-connectivity/docs/interconnect/concepts/overview).
See also: [Interconnects API](https://cloud.google.com/compute/docs/reference/rest/v1/interconnects).
""",
}

View File

@@ -0,0 +1,29 @@
# -*- 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.
"""Commands for reading and manipulating interconnect MACsec configuration."""
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 InterconnectApplicationAwarenessConfig(base.Group):
"""Read and manipulate configuration for application awareness on Compute Engine interconnect."""

View File

@@ -0,0 +1,117 @@
# -*- 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 configuring bandwidth percentage policy for application awareness on interconnect."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to configure bandwidth percentage policy for using
application awareness on interconnect.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To configure bandwidth percentage policy for an interconnect
example-interconnect, run:
$ {command} example-interconnect
--bandwidth-percentages="TC1=5,TC2=5,TC3=75,TC4=5,TC5=5,TC6=5"
--enabled --profile-description="some string"
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class ConfigureBandwidthPercentagePolicy(base.UpdateCommand):
"""Configure bandwidth percentage policy for application awareness configuration of a Compute Engine interconnect.
*{command}* allows the user to configure bandwidth percentage policy for
application awareness configuration data associated with
Compute Engine interconnect in a project.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='patch')
flags.AddAaiEnabled(parser)
flags.AddAaiProfileDescription(parser)
flags.AddAaiBandwidthPercentages(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
messages = holder.client.messages
# Get the current object for application awareness
application_awareness = interconnect.Describe().applicationAwareInterconnect
if application_awareness is None:
application_awareness = (
messages.InterconnectApplicationAwareInterconnect()
)
aai_enabled = args.enabled
# Enable the policy by default if not explicity specified.
if aai_enabled is None:
aai_enabled = True
application_awareness.strictPriorityPolicy = None
application_awareness.profileDescription = args.profile_description
application_awareness.bandwidthPercentagePolicy = (
messages.InterconnectApplicationAwareInterconnectBandwidthPercentagePolicy()
)
aai_bandwidth_percentages = flags.GetAaiBandwidthPercentages(
messages, args.bandwidth_percentages
)
for traffic_class in aai_bandwidth_percentages:
application_awareness.bandwidthPercentagePolicy.bandwidthPercentages.append(
messages.InterconnectApplicationAwareInterconnectBandwidthPercentage(
percentage=aai_bandwidth_percentages[traffic_class],
trafficClass=traffic_class,
)
)
return interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
macsec_enabled=None,
macsec=None,
aai_enabled=aai_enabled,
application_aware_interconnect=application_awareness,
)
ConfigureBandwidthPercentagePolicy.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,125 @@
# -*- 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 configuring shaper average percentage for application awareness on interconnect."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to configure shaper average percentage for using
application awareness on interconnect. Note that an application awareness
policy (strict priority or bandwidth percentage) should be configure before
configuring traffic shaping.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To configure shaper average percentage for an interconnect
example-interconnect, run:
$ {command} example-interconnect
--bandwidth-percentages="TC1=30,TC2=90
--enabled --profile-description="some string"
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class ConfigureShaperAveragePercentage(base.UpdateCommand):
"""Configure shaper average percentage for application awareness configuration of a Compute Engine interconnect.
*{command}* allows the user to configure shaper average percentage for
application awareness configuration data associated with
Compute Engine interconnect in a project.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='patch')
flags.AddAaiEnabled(parser)
flags.AddAaiProfileDescription(parser)
flags.AddAaiBandwidthPercentages(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
messages = holder.client.messages
# Get the current object for application awareness
application_awareness = interconnect.Describe().applicationAwareInterconnect
# Raise an error.
if (
application_awareness is None
or application_awareness
== holder.client.messages.InterconnectApplicationAwareInterconnect()
):
raise exceptions.BadArgumentException(
'NAME',
"Interconnect '{}' does not have application awareness configured."
.format(ref.Name()),
)
aai_bandwidth_percentages = flags.GetAaiBandwidthPercentages(
messages, args.bandwidth_percentages
)
application_awareness.profileDescription = args.profile_description
application_awareness.shapeAveragePercentages = []
for traffic_class in aai_bandwidth_percentages:
application_awareness.shapeAveragePercentages.append(
messages.InterconnectApplicationAwareInterconnectBandwidthPercentage(
percentage=aai_bandwidth_percentages[traffic_class],
trafficClass=traffic_class,
)
)
enabled = args.enabled
# Enable the policy by default if not explicity specified.
if args.enabled is None:
enabled = True
return interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
macsec_enabled=None,
macsec=None,
aai_enabled=enabled,
application_aware_interconnect=application_awareness,
)
ConfigureShaperAveragePercentage.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,105 @@
# -*- 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 configuring strict priority policy for application awareness on interconnect."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to configure strict priority policy for using
application awareness on interconnect.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To configure strict priority policy for an interconnect
example-interconnect, run:
$ {command} example-interconnect
--enabled --profile-description="some string"
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class ConfigureStrictPriorityPolicy(base.UpdateCommand):
"""Configure strict priority policy for application awareness configuration of a Compute Engine interconnect.
*{command}* allows the user to configure strict priority policy for
application awareness configuration data associated with
Compute Engine interconnect in a project.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='patch')
flags.AddAaiEnabled(parser)
flags.AddAaiProfileDescription(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
# Get the current object for application awareness
application_awareness = interconnect.Describe().applicationAwareInterconnect
if application_awareness is None:
application_awareness = (
holder.client.messages.InterconnectApplicationAwareInterconnect()
)
if application_awareness.strictPriorityPolicy is None:
application_awareness.strictPriorityPolicy = (
holder.client.messages.InterconnectApplicationAwareInterconnectStrictPriorityPolicy()
)
application_awareness.bandwidthPercentagePolicy = None
application_awareness.profileDescription = args.profile_description
enabled = args.enabled
# Enable the policy by default if not explicity specified.
if args.enabled is None:
enabled = True
return interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
macsec_enabled=None,
macsec=None,
aai_enabled=enabled,
application_aware_interconnect=application_awareness,
)
ConfigureStrictPriorityPolicy.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,93 @@
# -*- 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 deleting configuration for application awareness on interconnect."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to delete all configuration state for
application awareness on interconnect.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To delete application awareness configuration for an interconnect
example-interconnect, run:
$ {command} example-interconnect
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.UpdateCommand):
"""Delete application awareness configuration of a Compute Engine interconnect.
*{command}* allows the user to delete application awareness configuration data
associated with
Compute Engine interconnect in a project.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='patch')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
messages = holder.client.messages
application_awareness = messages.InterconnectApplicationAwareInterconnect()
cleared_fields = [
'applicationAwareInterconnect.shapeAveragePercentages',
'applicationAwareInterconnect.bandwidthPercentagePolicy',
'applicationAwareInterconnect.strictPriorityPolicy',
]
application_awareness.strictPriorityPolicy = None
application_awareness.bandwidthPercentagePolicy = None
application_awareness.profileDescription = ''
application_awareness.shapeAveragePercentages = []
return interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
macsec_enabled=None,
macsec=None,
aai_enabled=False,
application_aware_interconnect=application_awareness,
cleared_fields=cleared_fields,
)
Delete.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,71 @@
# -*- 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 getting the config for application awareness on interconnect."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* displays configuration data associated with
application awareness on Compute Engine interconnect in a project.
For an example, refer to the *EXAMPLES* section below.
""",
# pylint: disable=line-too-long
'EXAMPLES': """\
To displays configuration data associated with application awareness on
Compute Engine interconnect in a project, run:
$ {command} example-interconnect
""",
# pylint: enable=line-too-long
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class GetConfig(base.DescribeCommand):
"""Get application awareness configuration of a Compute Engine interconnect.
*{command}* displays application awareness configuration data associated with
Compute
Engine interconnect in a project.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
return interconnect.GetApplicationAwarenessConfig()
GetConfig.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,106 @@
# -*- 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 enabling/disabling application awareness on interconnect and updating the profile description of the profile."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* allows the user to enable or disable application awareness on Interconnect,
as well as add/update the description of the application awareness on Interconnect profile.
For an example, refer to the *EXAMPLES* section below.""",
# pylint: disable=line-too-long
'EXAMPLES': """\
To update the application awareness config on
Compute Engine interconnect in a project, run:
$ {command} example-interconnect application-awareness update --enabled --profile-description="Some string"
""",
# pylint: enable=line-too-long
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class UpdateConfig(base.DescribeCommand):
"""Updates application awareness configuration of a Compute Engine interconnect.
*{command}* allows the user to enable or disable application awareness on
Interconnect,as well as add/update the description of the application
awareness on Interconnect profile..
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='patch')
flags.AddAaiEnabled(parser)
flags.AddAaiProfileDescription(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
application_aware_interconnect = (
interconnect.Describe().applicationAwareInterconnect
)
if args.enabled or args.profile_description:
if (
application_aware_interconnect is None
or application_aware_interconnect
== holder.client.messages.InterconnectApplicationAwareInterconnect()
):
raise exceptions.BadArgumentException(
'{}'.format('enabled' if args.enabled else 'profile-description'),
"Interconnect '{}' does not have application awareness"
' config.'.format(ref.Name()),
)
if args.profile_description:
application_aware_interconnect.profileDescription = (
args.profile_description
)
return (
interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
aai_enabled=args.enabled,
application_aware_interconnect=application_aware_interconnect,
),
)
UpdateConfig.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,27 @@
# -*- 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.
"""Commands for reading and manipulating interconnect attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class InterconnectAttachments(base.Group):
"""Read and manipulate Compute Engine interconnect attachments."""
pass

View File

@@ -0,0 +1,40 @@
# -*- 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.
"""Commands for creating or manipulating dedicated interconnect attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class InterconnectAttachments(base.Group):
"""Create or manipulate dedicated interconnect attachments."""
pass
InterconnectAttachments.detailed_help = {
'DESCRIPTION': """
Create or manipulate Dedicated Interconnect attachments.
For more information about about interconnect attachments for Dedicated
Interconnect, see the documentation for
[Dedicated interconnect attachments](https://cloud.google.com/network-connectivity/docs/interconnect/how-to/dedicated/creating-vlan-attachments).
See also: [Interconnect attachments API](https://cloud.google.com/compute/docs/reference/rest/v1/interconnectAttachments).
""",
}

View File

@@ -0,0 +1,190 @@
# -*- 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 creating dedicated interconnect attachments."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import parser_errors
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects import flags as interconnect_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.command_lib.compute.routers import flags as router_flags
from googlecloudsdk.core import log
_DOCUMENTATION_LINK = 'https://cloud.google.com/interconnect/docs/how-to/dedicated/creating-vlan-attachments'
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a Compute Engine dedicated interconnect attachment.
*{command}* is used to create a dedicated interconnect attachments. An
interconnect attachment is what binds the underlying connectivity of an
interconnect to a path into and out of the customer's cloud network.
"""
INTERCONNECT_ATTACHMENT_ARG = None
INTERCONNECT_ARG = None
ROUTER_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = (
interconnect_flags.InterconnectArgumentForOtherResource(
'The interconnect for the interconnect attachment'))
cls.INTERCONNECT_ARG.AddArgument(parser)
cls.ROUTER_ARG = router_flags.RouterArgumentForOtherResources()
cls.ROUTER_ARG.AddArgument(parser)
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='create')
attachment_flags.AddDescription(parser)
attachment_flags.AddAdminEnabled(parser, default_behavior=True)
attachment_flags.AddVlan(parser)
attachment_flags.AddCandidateSubnets(parser)
attachment_flags.AddBandwidth(
parser, required=False, release_track=cls.ReleaseTrack()
)
attachment_flags.AddMtu(parser)
attachment_flags.AddEncryption(parser)
attachment_flags.GetIpsecInternalAddressesFlag().AddToParser(parser)
attachment_flags.AddStackType(parser)
attachment_flags.AddCandidateIpv6Subnets(parser)
attachment_flags.AddCloudRouterIpv6InterfaceId(parser)
attachment_flags.AddCustomerRouterIpv6InterfaceId(parser)
attachment_flags.AddSubnetLength(parser)
attachment_flags.AddResourceManagerTags(parser)
attachment_flags.AddCandidateCloudRouterIpAddress(parser)
attachment_flags.AddCandidateCustomerRouterIpAddress(parser)
attachment_flags.AddCandidateCloudRouterIpv6Address(parser)
attachment_flags.AddCandidateCustomerRouterIpv6Address(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
interconnect_ref = None
if args.interconnect is not None:
interconnect_ref = self.INTERCONNECT_ARG.ResolveAsResource(
args, holder.resources)
if args.router_region is None:
args.router_region = attachment_ref.region
if args.router_region != attachment_ref.region:
raise parser_errors.ArgumentException(
'router-region must be same as the attachment region.')
router_ref = None
if args.router is not None:
router_ref = self.ROUTER_ARG.ResolveAsResource(args, holder.resources)
admin_enabled = attachment_flags.GetAdminEnabledFlag(args)
ipsec_internal_addresses_urls = None
region = attachment_ref.region
if args.ipsec_internal_addresses is not None:
ipsec_internal_addresses_urls = [
attachment_flags.GetAddressRef(
holder.resources, name, region, attachment_ref.project
).SelfLink()
for name in args.ipsec_internal_addresses
]
return interconnect_attachment.Create(
description=args.description,
interconnect=interconnect_ref,
attachment_type='DEDICATED',
router=router_ref,
vlan_tag_802_1q=args.vlan,
admin_enabled=admin_enabled,
candidate_subnets=args.candidate_subnets,
bandwidth=getattr(args, 'bandwidth', None),
validate_only=getattr(args, 'dry_run', None),
mtu=getattr(args, 'mtu', None),
encryption=getattr(args, 'encryption', None),
ipsec_internal_addresses=ipsec_internal_addresses_urls,
stack_type=getattr(args, 'stack_type', None),
candidate_ipv6_subnets=args.candidate_ipv6_subnets,
cloud_router_ipv6_interface_id=getattr(
args, 'cloud_router_ipv6_interface_id', None
),
customer_router_ipv6_interface_id=getattr(
args, 'customer_router_ipv6_interface_id', None
),
subnet_length=getattr(args, 'subnet_length', None),
multicast_enabled=getattr(args, 'enable_multicast', None),
candidate_cloud_router_ip_address=getattr(
args, 'candidate_cloud_router_ip_address', None
),
candidate_customer_router_ip_address=getattr(
args, 'candidate_customer_router_ip_address', None
),
candidate_cloud_router_ipv6_address=getattr(
args, 'candidate_cloud_router_ipv6_address', None
),
candidate_customer_router_ipv6_address=getattr(
args, 'candidate_customer_router_ipv6_address', None
),
supports_400g=self.ReleaseTrack() == base.ReleaseTrack.ALPHA,
resource_manager_tags=args.resource_manager_tags,
)
def Epilog(self, resources_were_displayed):
message = ('You must configure your Cloud Router with an interface '
'and BGP peer for your created VLAN attachment. See also {} for '
'more detailed help.'.format(_DOCUMENTATION_LINK))
log.status.Print(message)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a Compute Engine dedicated interconnect attachment.
*{command}* is used to create a dedicated interconnect attachments. An
interconnect attachment is what binds the underlying connectivity of an
interconnect to a path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Create a Compute Engine dedicated interconnect attachment.
*{command}* is used to create a dedicated interconnect attachments. An
interconnect attachment is what binds the underlying connectivity of an
interconnect to a path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
attachment_flags.AddEnableMulticast(parser)
attachment_flags.AddDryRun(parser)

View File

@@ -0,0 +1,162 @@
# -*- 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 dedicated interconnect attachments."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.command_lib.util.args import labels_util
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Compute Engine dedicated interconnect attachment.
*{command}* is used to update interconnect attachments. An interconnect
attachment is what binds the underlying connectivity of an interconnect to a
path into and out of the customer's cloud network.
"""
INTERCONNECT_ATTACHMENT_ARG = None
INTERCONNECT_ARG = None
ROUTER_ARG = None
def _get_attachment(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
return client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='patch')
attachment_flags.AddDescription(parser)
attachment_flags.AddAdminEnabled(parser, update=True)
attachment_flags.AddBandwidth(
parser, required=False, release_track=cls.ReleaseTrack()
)
attachment_flags.AddMtu(parser)
attachment_flags.AddStackType(parser)
attachment_flags.AddCandidateIpv6Subnets(parser)
attachment_flags.AddCloudRouterIpv6InterfaceId(parser)
attachment_flags.AddCustomerRouterIpv6InterfaceId(parser)
attachment_flags.AddCandidateCloudRouterIpv6Address(parser)
attachment_flags.AddCandidateCustomerRouterIpv6Address(parser)
def Run(self, args):
interconnect_attachment = self._get_attachment(args)
admin_enabled = attachment_flags.GetAdminEnabledFlag(args)
return interconnect_attachment.Patch(
description=args.description,
admin_enabled=admin_enabled,
bandwidth=getattr(args, 'bandwidth', None),
mtu=getattr(args, 'mtu', None),
stack_type=getattr(args, 'stack_type', None),
candidate_ipv6_subnets=getattr(args, 'candidate_ipv6_subnets', None),
cloud_router_ipv6_interface_id=getattr(
args, 'cloud_router_ipv6_interface_id', None
),
customer_router_ipv6_interface_id=getattr(
args, 'customer_router_ipv6_interface_id', None
),
multicast_enabled=getattr(args, 'enable_multicast', None),
candidate_cloud_router_ipv6_address=getattr(
args, 'candidate_cloud_router_ipv6_address', None
),
candidate_customer_router_ipv6_address=getattr(
args, 'candidate_customer_router_ipv6_address', None
),
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Compute Engine dedicated interconnect attachment.
*{command}* is used to update interconnect attachments. An interconnect
attachment is what binds the underlying connectivity of an interconnect to a
path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
labels_util.AddUpdateLabelsFlags(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
interconnect_attachment = self._get_attachment(args)
labels = None
label_fingerprint = None
labels_diff = labels_util.Diff.FromUpdateArgs(args)
if labels_diff.MayHaveUpdates():
old_attachment = interconnect_attachment.Describe()
labels_cls = holder.client.messages.InterconnectAttachment.LabelsValue
labels = labels_diff.Apply(
labels_cls, labels=old_attachment.labels).GetOrNone()
if labels is not None:
label_fingerprint = old_attachment.labelFingerprint
admin_enabled = attachment_flags.GetAdminEnabledFlag(args)
return interconnect_attachment.Patch(
description=args.description,
admin_enabled=admin_enabled,
labels=labels,
label_fingerprint=label_fingerprint,
bandwidth=getattr(args, 'bandwidth', None),
mtu=getattr(args, 'mtu', None),
stack_type=getattr(args, 'stack_type', None),
candidate_ipv6_subnets=getattr(args, 'candidate_ipv6_subnets', None),
cloud_router_ipv6_interface_id=getattr(
args, 'cloud_router_ipv6_interface_id', None
),
customer_router_ipv6_interface_id=getattr(
args, 'customer_router_ipv6_interface_id', None
),
multicast_enabled=getattr(args, 'enable_multicast', None),
candidate_cloud_router_ipv6_address=getattr(
args, 'candidate_cloud_router_ipv6_address', None
),
candidate_customer_router_ipv6_address=getattr(
args, 'candidate_customer_router_ipv6_address', None
),
supports_400g=self.ReleaseTrack() == base.ReleaseTrack.ALPHA,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Compute Engine dedicated interconnect attachment.
*{command}* is used to update interconnect attachments. An interconnect
attachment is what binds the underlying connectivity of an interconnect to a
path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
attachment_flags.AddEnableMulticast(parser, update=True)

View File

@@ -0,0 +1,63 @@
# -*- 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 deleting interconnects attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import utils
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects import flags as interconnects_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags
@base.UniverseCompatible
class Delete(base.DeleteCommand):
"""Delete Compute Engine interconnect attachments.
*{command}* deletes Compute Engine interconnect attachments.
"""
INTERCONNECT_ATTACHMENT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = flags.InterconnectAttachmentArgument(
plural=True)
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(
interconnects_flags.InterconnectsCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
interconnect_attachment = client.InterconnectAttachment(
ref, compute_client=holder.client)
requests.extend(
interconnect_attachment.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)

View File

@@ -0,0 +1,53 @@
# -*- 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 describing interconnects attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags
class Describe(base.DescribeCommand):
"""Describe a Compute Engine interconnect attachment.
*{command}* displays all data associated with Compute Engine
interconnect attachment in a project.
"""
INTERCONNECT_ATTACHMENT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = flags.InterconnectAttachmentArgument()
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(
parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
ref, compute_client=holder.client)
return interconnect_attachment.Describe()

View File

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 creating or manipulating interconnect attachment groups."""
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 InterconnectAttachmentGroups(base.Group):
"""Create or manipulate interconnect attachment groups."""
pass
InterconnectAttachmentGroups.detailed_help = {
'DESCRIPTION': """
Create or manipulate interconnect attachment groups.
""",
}

View File

@@ -0,0 +1,92 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 adding interconnect attachments to an interconnect attachment group."""
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.interconnects.attachments.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.attachments.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to add member interconnect attachments to an
interconnect attachment group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To add attachment-1 and attachment-2 to interconnect attachment group
example-attachment-group, run:
$ {command} example-attachment-group
--attachments=region-1/attachment-1,region-2/attachment-2
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class AddMembers(base.UpdateCommand):
"""Add member interconnect attachments to a Compute Engine interconnect attachment group.
*{command}* adds member interconnect attachments to a Compute Engine
interconnect attachment group.
"""
ATTACHMENT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.ATTACHMENT_GROUP_ARG = flags.InterconnectAttachmentGroupArgument(
plural=False
)
cls.ATTACHMENT_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.GetMemberInterconnectAttachments(parser)
def Collection(self):
return 'compute.interconnectAttachmentGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ATTACHMENT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
attachment_group = client.InterconnectAttachmentGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
attachments = set()
attachment_group_attachments = attachment_group.Describe().attachments
if attachment_group_attachments is not None:
attachments = set(
property.key
for property in attachment_group_attachments.additionalProperties
)
attachments |= set(args.attachments)
return attachment_group.Patch(
attachments=flags.ParseAttachments(sorted(list(attachments))),
)
AddMembers.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,102 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect attachment groups."""
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.interconnects.attachments.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.attachments.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to create interconnect attachment groups. An
interconnect attachment group connects a set of redundant interconnect
attachments between Google and the customer.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To create an interconnect attachment group capable of
PRODUCTION_CRITICAL, run:
$ {command} example-attachment-group
--intended-availability-sla=PRODUCTION_CRITICAL
--description="Example interconnect attachment group"
It is easy to add members to an existing interconnect attachment group
after creation using the *add-members* command.
To create an interconnect attachment group capable of
PRODUCTION_NON_CRITICAL, with two members at creation time, run:
$ {command} example-attachment-group
--intended-availability-sla=PRODUCTION_NON_CRITICAL
--attachments=region-1/attachment-1,region-2/attachment-2
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Create(base.CreateCommand):
"""Create a Compute Engine interconnect attachment group.
*{command}* is used to create interconnect attachment groups. An interconnect
attachment group connects a set of redundant interconnect attachments between
Google and the customer.
"""
ATTACHMENT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.ATTACHMENT_GROUP_ARG = flags.InterconnectAttachmentGroupArgument(
plural=False
)
cls.ATTACHMENT_GROUP_ARG.AddArgument(parser, operation_type='create')
flags.AddDescription(parser)
flags.AddIntendedAvailabilitySlaForCreate(parser)
flags.GetMemberInterconnectAttachmentsForCreate(parser)
def Collection(self):
return 'compute.interconnectAttachmentGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ATTACHMENT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
attachment_group = client.InterconnectAttachmentGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
availability_sla = flags.GetIntendedAvailabilitySla(
holder.client.messages, args.intended_availability_sla
)
attachments = flags.ParseAttachments(args.attachments)
return attachment_group.Create(
description=args.description,
availability_sla=availability_sla,
attachments=attachments,
)
Create.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect attachment groups."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import utils
from googlecloudsdk.api_lib.compute.interconnects.attachments.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.attachments.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to delete interconnect attachment groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To delete an interconnect attachment group, run:
$ {command} example-attachment-group"
Although not shown in this example, you can delete multiple interconnect
attachment groups in a single command.
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete Compute Engine interconnect attachment groups.
*{command}* deletes Compute Engine interconnect attachment groups.
Interconnect attachment groups can be deleted even if they are referenced by
interconnect attachments. Each interconnect attachment in the group will be
updated to remove its reference to this group.
"""
ATTACHMENT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.ATTACHMENT_GROUP_ARG = flags.InterconnectAttachmentGroupArgument(
plural=True
)
cls.ATTACHMENT_GROUP_ARG.AddArgument(parser, operation_type='delete')
def Collection(self):
return 'compute.interconnectAttachmentGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.ATTACHMENT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
attachment_group = client.InterconnectAttachmentGroup(
ref, project, compute_client=holder.client
)
requests.extend(attachment_group.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)
Delete.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect attachment groups."""
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.interconnects.attachments.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.attachments.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to describe interconnect attachment groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To describe an interconnect attachment group, run:
$ {command} example-attachment-group
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine interconnect attachment group.
*{command}* displays all data associated with Compute Engine
interconnect attachment group in a project.
"""
ATTACHMENT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.ATTACHMENT_GROUP_ARG = flags.InterconnectAttachmentGroupArgument()
cls.ATTACHMENT_GROUP_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ATTACHMENT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
attachment_group = client.InterconnectAttachmentGroup(
ref, project, compute_client=holder.client
)
return attachment_group.Describe()
Describe.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,74 @@
# -*- 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 getting interconnect attachment group operational status."""
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.interconnects.attachments.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.attachments.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to get the operational status of interconnect
attachment groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To get the operational status of interconnect attachment group
example-attachment-group, run:
$ {command} example-attachment-group
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class GetOperationalStatus(base.DescribeCommand):
"""Get the operational status of a Compute Engine interconnect attachment group.
*{command}* gets the operational status of a Compute Engine
interconnect attachment group in a project.
"""
ATTACHMENT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.ATTACHMENT_GROUP_ARG = flags.InterconnectAttachmentGroupArgument()
cls.ATTACHMENT_GROUP_ARG.AddArgument(
parser, operation_type='get operational status'
)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ATTACHMENT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
attachment_group = client.InterconnectAttachmentGroup(
ref, project, compute_client=holder.client
)
return attachment_group.GetOperationalStatus()
GetOperationalStatus.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect attachment groups."""
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
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to list interconnect attachment groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To list interconnect attachment groups, run:
$ {command}
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.ListCommand):
"""List interconnect attachment groups."""
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat("""
table(
name,
attachments.flatten(show='keys', separator='\n'),
intent.availabilitySla:label=INTENDED_SLA,
configured.availabilitySla.effectiveSla:label=CONFIGURED_SLA
)
""")
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.ComputeInterconnectAttachmentGroupsListRequest(
project=project, filter=filter_expr
)
return list_pager.YieldFromList(
client.interconnectAttachmentGroups,
request,
field='items',
limit=args.limit,
batch_size=None,
)
List.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 removing interconnect attachments from an interconnect attachment group."""
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.interconnects.attachments.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.attachments.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to remove member interconnect attachments from an
interconnect attachment group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To remove attachment-1 and attachment-2 from interconnect attachment
group example-attachment-group, run:
$ {command} example-attachment-group
--attachments=region-1/attachment-1,region-2/attachment-2
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RemoveMembers(base.UpdateCommand):
"""Remove member interconnect attachments from a Compute Engine interconnect attachment group.
*{command}* removes member interconnect attachments from a Compute Engine
interconnect attachment group.
"""
ATTACHMENT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.ATTACHMENT_GROUP_ARG = flags.InterconnectAttachmentGroupArgument(
plural=False
)
cls.ATTACHMENT_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.GetMemberInterconnectAttachments(parser)
def Collection(self):
return 'compute.interconnectAttachmentGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ATTACHMENT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
attachment_group = client.InterconnectAttachmentGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
attachments = set()
attachment_group_attachments = attachment_group.Describe().attachments
if attachment_group_attachments is not None:
attachments = set(
property.key
for property in attachment_group_attachments.additionalProperties
)
attachments -= set(args.attachments)
return attachment_group.Patch(
attachments=flags.ParseAttachments(sorted(list(attachments))),
update_mask='attachments',
)
RemoveMembers.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,117 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect attachment groups."""
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.interconnects.attachments.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.interconnects.attachments.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to update interconnect attachment groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To update an interconnect attachment group example-attachment-group's
intended availability SLA to PRODUCTION_CRITICAL, run:
$ {command} example-attachment-group
--intended-availability-sla=PRODUCTION_CRITICAL
To update an interconnect attachment group example-attachment-group's
description to "example attachment group description", run:
$ {command} example-attachment-group
--description="example attachment group description"
To update an interconnect attachment group example-attachment-group's
member attachments to attachment-1 and attachment-2, run:
$ {command} example-attachment-group
--attachments=region-1/attachment-1,region-2/attachment-2
--update-mask=attachments
Although you can add or remove member attachments using this command, it
is recommended to add or remove member attachments using the
*add-members* and *remove-members* commands.
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Update(base.UpdateCommand):
"""Update a Compute Engine interconnect attachment group.
*{command}* is used to update interconnect attachment groups. An interconnect
attachment group connects a set of redundant interconnect attachments between
Google and the customer.
"""
ATTACHMENT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.ATTACHMENT_GROUP_ARG = flags.InterconnectAttachmentGroupArgument(
plural=False
)
cls.ATTACHMENT_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.AddDescription(parser)
flags.AddIntendedAvailabilitySlaForUpdate(parser)
flags.GetMemberInterconnectAttachmentsForCreate(parser)
flags.AddUpdateMask(parser)
def Collection(self):
return 'compute.interconnectAttachmentGroups'
def Run(self, args):
if (
args.description is None
and args.intended_availability_sla is None
and not args.attachments
):
raise exceptions.MinimumArgumentException(
['--description', '--intended-availability-sla', '--attachments']
)
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ATTACHMENT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
attachment_group = client.InterconnectAttachmentGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
availability_sla = flags.GetIntendedAvailabilitySla(
holder.client.messages, args.intended_availability_sla
)
attachments = flags.ParseAttachments(args.attachments)
return attachment_group.Patch(
description=args.description,
availability_sla=availability_sla,
attachments=attachments,
update_mask=args.update_mask,
)
Update.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,43 @@
# -*- 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.
"""Commands for creating or manipulating dedicated L2 forwarding attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
@base.DefaultUniverseOnly
class InterconnectAttachments(base.Group):
"""Create or manipulate dedicated interconnect attachments."""
pass
InterconnectAttachments.detailed_help = {
'DESCRIPTION': """
Create or manipulate L2 Forwarding Interconnect attachments.
For more information about about interconnect attachments for L2
Forwaring Interconnect, see the documentation for
[L2 Forwarding interconnect attachments](https://cloud.google.com/network-connectivity/docs/interconnect/how-to/l2-forwarding/creating-l2-attachments).
See also: [Interconnect attachments API](https://cloud.google.com/compute/docs/reference/rest/v1/interconnectAttachments).
""",
}

View File

@@ -0,0 +1,76 @@
# -*- 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 adding member interconnects to an interconnect L2-forwarding attachment innner vlan to appliance mappings."""
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.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class AddMapping(base.UpdateCommand):
"""Add new vlan to ip mapping rule to an L2-forwarding attachment.
*{command}* add new vlan to ip mapping rule to an L2-forwarding attachment.
"""
INTERCONNECT_ATTACHMENT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='patch')
attachment_flags.AddVlanKey(parser, required=True)
attachment_flags.AddApplianceIpAddress(parser)
attachment_flags.AddApplianceName(parser)
attachment_flags.AddInnerVlanToApplianceMappings(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
old_mapping = interconnect_attachment.DescribeMapping(args.vlan_key)
if old_mapping:
log.status.Print(
'Mapping with vlan key {} already exists'.format(args.vlan_key)
)
return None
return interconnect_attachment.UpdateMapping(
vlan_key=args.vlan_key,
appliance_name=getattr(args, 'appliance_name', None),
appliance_ip_address=getattr(args, 'appliance_ip_address', None),
inner_vlan_to_appliance_mappings=getattr(
args, 'inner_vlan_to_appliance_mappings', None
),
)

View File

@@ -0,0 +1,145 @@
# -*- 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 L2 forwarding interconnect attachments."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects import flags as interconnect_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.command_lib.compute.networks import flags as network_flags
from googlecloudsdk.core import log
_DOCUMENTATION_LINK = 'https://cloud.google.com/interconnect/docs/how-to/l2-forwarding/creating-l2-attachments'
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.DefaultUniverseOnly
class Create(base.CreateCommand):
"""Create a Compute Engine L2 forwarding interconnect attachment.
*{command}* is used to create a L2 forwarding interconnect attachments. An
interconnect attachment is what binds the underlying connectivity of an
interconnect to a path into and out of the customer's cloud network.
"""
INTERCONNECT_ATTACHMENT_ARG = None
INTERCONNECT_ARG = None
NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = (
interconnect_flags.InterconnectArgumentForOtherResource(
'The interconnect for the interconnect attachment'))
cls.INTERCONNECT_ARG.AddArgument(parser)
cls.NETWORK_ARG = network_flags.NetworkArgumentForOtherResource(
'The Google Network to use for L2 forwarding.'
)
cls.NETWORK_ARG.AddArgument(parser)
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='create')
attachment_flags.AddDescription(parser)
attachment_flags.AddEnableAdmin(parser)
attachment_flags.AddBandwidth(parser, required=False)
attachment_flags.AddMtu(parser)
attachment_flags.AddGeneveVni(parser)
attachment_flags.AddDefaultApplianceIpAddress(parser)
attachment_flags.AddTunnelEndpointIpAddress(parser)
attachment_flags.AddZ2zVlan(parser)
attachment_flags.AddResourceManagerTags(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
interconnect_ref = None
if args.interconnect is not None:
interconnect_ref = self.INTERCONNECT_ARG.ResolveAsResource(
args, holder.resources)
if args.network is not None:
network_ref = self.NETWORK_ARG.ResolveAsResource(args, holder.resources)
else:
network_ref = None
return interconnect_attachment.Create(
description=args.description,
interconnect=interconnect_ref,
attachment_type='L2_DEDICATED',
admin_enabled=args.enable_admin,
bandwidth=getattr(args, 'bandwidth', None),
validate_only=getattr(args, 'dry_run', None),
mtu=getattr(args, 'mtu', None),
network=network_ref,
geneve_vni=getattr(args, 'geneve_vni', None),
default_appliance_ip_address=getattr(
args, 'default_appliance_ip_address', None
),
tunnel_endpoint_ip_address=getattr(
args, 'tunnel_endpoint_ip_address', None
),
vlan_tag_802_1q=getattr(args, 'z2z_vlan', None),
resource_manager_tags=args.resource_manager_tags,
)
def Epilog(self, resources_were_displayed):
message = (
'You must ensure that there is at least one valid Appliance IP '
'(default or within the mapping) and that firewall rules allow '
'traffic between the tunnel endpoint IP and your appliance(s). '
'See also {} for more detailed help.'.format(_DOCUMENTATION_LINK)
)
log.status.Print(message)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@base.DefaultUniverseOnly
class CreateBeta(Create):
"""Create a Compute Engine L2 forwarding interconnect attachment.
*{command}* is used to create a L2 forwarding interconnect attachments. An
interconnect attachment is what binds the underlying connectivity of an
interconnect to a path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@base.DefaultUniverseOnly
class CreateAlpha(CreateBeta):
"""Create a Compute Engine L2 forwarding interconnect attachment.
*{command}* is used to create a L2 forwarding interconnect attachments. An
interconnect attachment is what binds the underlying connectivity of an
interconnect to a path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
attachment_flags.AddDryRun(parser)

View File

@@ -0,0 +1,63 @@
# -*- 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 describing L2 forwarding interconnects attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine L2 forwarding interconnect attachment.
*{command}* displays all data associated with Compute Engine
interconnect attachment in a project.
"""
INTERCONNECT_ATTACHMENT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = flags.InterconnectAttachmentArgument()
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(
parser, operation_type='describe'
)
flags.AddVlanKey(parser, required=True)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client),
)
interconnect_attachment = client.InterconnectAttachment(
ref, compute_client=holder.client
)
return interconnect_attachment.DescribeMapping(
vlan_key=args.vlan_key,
)

View File

@@ -0,0 +1,71 @@
# -*- 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 listing L2 forwarding interconnect attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.ListCommand):
"""List InterconnectAttachments."""
INTERCONNECT_ATTACHMENT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = flags.InterconnectAttachmentArgument()
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(
parser, operation_type='describe'
)
parser.display_info.AddFormat("""
table(
key,
name,
innerApplianceIpAddress
)
""")
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client),
)
interconnect_attachment = client.InterconnectAttachment(
ref, compute_client=holder.client
)
if args.IsSpecified('format') and args.format == 'json':
is_json = True
else:
is_json = False
return interconnect_attachment.ListMapping(is_json=is_json)
List.detailed_help = base_classes.GetRegionalListerHelp(
'interconnect attachments')

View File

@@ -0,0 +1,68 @@
# -*- 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 updating member interconnects to an interconnect L2-forwarding attachment innner vlan to appliance mappings."""
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.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RemoveMapping(base.UpdateCommand):
"""Remove vlan to ip mapping rule to an L2-forwarding attachment.
*{command}* remove vlan to ip mapping rule to an L2-forwarding attachment.
"""
INTERCONNECT_ATTACHMENT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='create')
attachment_flags.AddVlanKey(parser, required=True)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
old_mapping = interconnect_attachment.DescribeMapping(args.vlan_key)
if not old_mapping:
log.status.Print(
'Mapping with vlan key {} does not exists'.format(args.vlan_key)
)
return None
return interconnect_attachment.RemoveMapping(
vlan_key=args.vlan_key,
)

View File

@@ -0,0 +1,117 @@
# -*- 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 updating L2 forwarding interconnect attachments."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.command_lib.util.args import labels_util
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Compute Engine L2 forwarding interconnect attachment.
*{command}* is used to update interconnect attachments. An interconnect
attachment is what binds the underlying connectivity of an interconnect to a
path into and out of the customer's cloud network.
"""
INTERCONNECT_ATTACHMENT_ARG = None
INTERCONNECT_ARG = None
ROUTER_ARG = None
def _get_attachment(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
return client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='patch')
attachment_flags.AddDescription(parser)
attachment_flags.AddEnableAdmin(parser)
attachment_flags.AddBandwidth(parser, required=False)
attachment_flags.AddMtu(parser)
attachment_flags.AddGeneveVni(parser, required=False)
attachment_flags.AddDefaultApplianceIpAddress(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
interconnect_attachment = self._get_attachment(args)
labels = None
label_fingerprint = None
labels_diff = labels_util.Diff.FromUpdateArgs(args)
if labels_diff.MayHaveUpdates():
old_attachment = interconnect_attachment.Describe()
labels_cls = holder.client.messages.InterconnectAttachment.LabelsValue
labels = labels_diff.Apply(
labels_cls, labels=old_attachment.labels).GetOrNone()
if labels is not None:
label_fingerprint = old_attachment.labelFingerprint
return interconnect_attachment.Patch(
description=args.description,
admin_enabled=args.enable_admin,
labels=labels,
label_fingerprint=label_fingerprint,
bandwidth=getattr(args, 'bandwidth', None),
mtu=getattr(args, 'mtu', None),
geneve_vni=getattr(args, 'geneve_vni', None),
default_appliance_ip_address=getattr(
args, 'default_appliance_ip_address', None
),
)
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Compute Engine L2 forwarding interconnect attachment.
*{command}* is used to update interconnect attachments. An interconnect
attachment is what binds the underlying connectivity of an interconnect to a
path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
labels_util.AddUpdateLabelsFlags(parser)
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Compute Engine L2 forwarding interconnect attachment.
*{command}* is used to update interconnect attachments. An interconnect
attachment is what binds the underlying connectivity of an interconnect to a
path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)

View File

@@ -0,0 +1,76 @@
# -*- 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 updating member interconnects to an interconnect L2-forwarding attachment innner vlan to appliance mappings."""
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.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class UpdateMapping(base.UpdateCommand):
"""Update vlan to ip mapping rule to an L2-forwarding attachment.
*{command}* update vlan to ip mapping rule to an L2-forwarding attachment.
"""
INTERCONNECT_ATTACHMENT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='create')
attachment_flags.AddVlanKey(parser, required=True)
attachment_flags.AddApplianceIpAddress(parser)
attachment_flags.AddApplianceName(parser)
attachment_flags.AddInnerVlanToApplianceMappings(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
old_mapping = interconnect_attachment.DescribeMapping(args.vlan_key)
if not old_mapping:
log.status.Print(
'Mapping with vlan key {} does not exist'.format(args.vlan_key)
)
return None
return interconnect_attachment.UpdateMapping(
vlan_key=args.vlan_key,
appliance_name=getattr(args, 'appliance_name', None),
appliance_ip_address=getattr(args, 'appliance_ip_address', None),
inner_vlan_to_appliance_mappings=getattr(
args, 'inner_vlan_to_appliance_mappings', None
),
)

View File

@@ -0,0 +1,89 @@
# -*- 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 listing interconnect attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import filter_rewrite
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
from googlecloudsdk.core.resource import resource_projection_spec
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.ListCommand):
"""List InterconnectAttachments."""
INTERCONNECT_ATTACHMENT_ARG = None
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat("""
table(
name,
region.basename(),
type.basename(),
interconnect.basename(),
router.basename(),
attachmentGroup.basename()
)
""")
def _GetListPage(self, compute_interconnect_attachments, request):
response = compute_interconnect_attachments.AggregatedList(request)
interconnect_attachments_lists = []
for attachment_in_scope in response.items.additionalProperties:
interconnect_attachments_lists += (
attachment_in_scope.value.interconnectAttachments)
return interconnect_attachments_lists, response.nextPageToken
def Run(self, args):
client = base_classes.ComputeApiHolder(
self.ReleaseTrack()).client.apitools_client
compute_interconnect_attachments = client.interconnectAttachments
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.ComputeInterconnectAttachmentsAggregatedListRequest(
project=project, filter=filter_expr)
if hasattr(request, 'returnPartialSuccess'):
request.returnPartialSuccess = True
# TODO(b/34871930): Write and use helper for handling listing.
interconnect_attachments_lists, next_page_token = self._GetListPage(
compute_interconnect_attachments, request)
while next_page_token:
request.pageToken = next_page_token
interconnect_attachments_list_page, next_page_token = self._GetListPage(
compute_interconnect_attachments, request)
interconnect_attachments_lists += interconnect_attachments_list_page
return interconnect_attachments_lists
List.detailed_help = base_classes.GetRegionalListerHelp(
'interconnect attachments')

View File

@@ -0,0 +1,39 @@
# -*- 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.
"""Commands for creating or manipulating partner interconnect attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class InterconnectAttachments(base.Group):
"""Create or manipulate partner interconnect attachments."""
pass
InterconnectAttachments.detailed_help = {
'DESCRIPTION': """
Create or manipulate Partner Interconnect attachments.
For more information about interconnect attachments for Partner
Interconnect, see the documentation for
[Partner interconnect attachments](https://cloud.google.com/network-connectivity/docs/interconnect/how-to/dedicated/creating-vlan-attachments).
See also: [Interconnect attachments API](https://cloud.google.com/compute/docs/reference/rest/v1/interconnectAttachments).
""",
}

View File

@@ -0,0 +1,164 @@
# -*- 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 creating partner customer interconnect attachments."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import parser_errors
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.command_lib.compute.routers import flags as router_flags
from googlecloudsdk.core import log
def PrintPairingKeyEpilog(pairing_key):
"""Prints the pairing key help text upon command completion."""
message = """\
Please use the pairing key to provision the attachment with your partner:
{0}
""".format(pairing_key)
log.status.Print(message)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a Compute Engine partner interconnect attachment.
*{command}* is used to create partner interconnect attachments. A partner
interconnect attachment binds the underlying connectivity of a provider's
Interconnect to a path into and out of the customer's cloud network.
"""
INTERCONNECT_ATTACHMENT_ARG = None
INTERCONNECT_ARG = None
ROUTER_ARG = None
@classmethod
def Args(cls, parser):
cls.ROUTER_ARG = router_flags.RouterArgumentForOtherResources()
cls.ROUTER_ARG.AddArgument(parser)
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='create')
attachment_flags.AddAdminEnabled(parser, default_behavior=False)
attachment_flags.AddEdgeAvailabilityDomain(parser)
attachment_flags.AddDescription(parser)
attachment_flags.AddMtu(parser)
attachment_flags.AddEncryption(parser)
attachment_flags.GetIpsecInternalAddressesFlag().AddToParser(parser)
attachment_flags.AddStackType(parser)
attachment_flags.AddResourceManagerTags(parser)
attachment_flags.AddCandidateCloudRouterIpAddress(parser)
attachment_flags.AddCandidateCustomerRouterIpAddress(parser)
attachment_flags.AddCandidateCloudRouterIpv6Address(parser)
attachment_flags.AddCandidateCustomerRouterIpv6Address(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
if args.router_region is None:
args.router_region = attachment_ref.region
if args.router_region != attachment_ref.region:
raise parser_errors.ArgumentException(
'router-region must be same as the attachment region.')
router_ref = None
if args.router is not None:
router_ref = self.ROUTER_ARG.ResolveAsResource(args, holder.resources)
ipsec_internal_addresses_urls = None
region = attachment_ref.region
if args.ipsec_internal_addresses is not None:
ipsec_internal_addresses_urls = [
attachment_flags.GetAddressRef(holder.resources, name, region,
attachment_ref.project).SelfLink()
for name in args.ipsec_internal_addresses
]
admin_enabled = attachment_flags.GetAdminEnabledFlag(args)
attachment = interconnect_attachment.Create(
description=args.description,
router=router_ref,
attachment_type='PARTNER',
edge_availability_domain=args.edge_availability_domain,
admin_enabled=admin_enabled,
validate_only=getattr(args, 'dry_run', None),
mtu=getattr(args, 'mtu', None),
encryption=getattr(args, 'encryption', None),
ipsec_internal_addresses=ipsec_internal_addresses_urls,
stack_type=getattr(args, 'stack_type', None),
candidate_cloud_router_ip_address=getattr(
args, 'candidate_cloud_router_ip_address', None
),
candidate_customer_router_ip_address=getattr(
args, 'candidate_customer_router_ip_address', None
),
candidate_cloud_router_ipv6_address=getattr(
args, 'candidate_cloud_router_ipv6_address', None
),
candidate_customer_router_ipv6_address=getattr(
args, 'candidate_customer_router_ipv6_address', None
),
resource_manager_tags=args.resource_manager_tags,
)
self._pairing_key = attachment.pairingKey
return attachment
def Epilog(self, resources_were_displayed=True):
PrintPairingKeyEpilog(self._pairing_key)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a Compute Engine partner interconnect attachment.
*{command}* is used to create partner interconnect attachments. A partner
interconnect attachment binds the underlying connectivity of a provider's
Interconnect to a path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Create a Compute Engine partner interconnect attachment.
*{command}* is used to create partner interconnect attachments. A partner
interconnect attachment binds the underlying connectivity of a provider's
Interconnect to a path into and out of the customer's cloud network.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
attachment_flags.AddDryRun(parser)

View File

@@ -0,0 +1,120 @@
# -*- 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 interconnects."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.command_lib.util.args import labels_util
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Compute Engine partner interconnect attachment.
*{command}* is used to update partner interconnect attachments. A partner
interconnect attachment binds the underlying connectivity of a provider's
Interconnect to a path into and out of the customer's cloud network.
"""
_support_label = False
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='patch')
attachment_flags.AddDescription(parser)
attachment_flags.AddAdminEnabled(parser, update=True)
attachment_flags.AddMtu(parser)
attachment_flags.AddStackType(parser)
attachment_flags.AddCandidateCloudRouterIpv6Address(parser)
attachment_flags.AddCandidateCustomerRouterIpv6Address(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
admin_enabled = attachment_flags.GetAdminEnabledFlag(args)
labels = None
label_fingerprint = None
if self._support_label:
labels_diff = labels_util.Diff.FromUpdateArgs(args)
if labels_diff.MayHaveUpdates():
old_attachment = interconnect_attachment.Describe()
labels_cls = holder.client.messages.InterconnectAttachment.LabelsValue
labels = labels_diff.Apply(
labels_cls, labels=old_attachment.labels
).GetOrNone()
if labels is not None:
label_fingerprint = old_attachment.labelFingerprint
return interconnect_attachment.Patch(
description=args.description,
admin_enabled=admin_enabled,
labels=labels,
label_fingerprint=label_fingerprint,
mtu=getattr(args, 'mtu', None),
stack_type=getattr(args, 'stack_type', None),
candidate_cloud_router_ipv6_address=getattr(
args, 'candidate_cloud_router_ipv6_address', None
),
candidate_customer_router_ipv6_address=getattr(
args, 'candidate_customer_router_ipv6_address', None
),
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Compute Engine partner interconnect attachment.
*{command}* is used to update partner interconnect attachments. A partner
interconnect attachment binds the underlying connectivity of a provider's
Interconnect to a path into and out of the customer's cloud network.
"""
_support_label = True
@classmethod
def Args(cls, parser):
super().Args(parser)
labels_util.AddUpdateLabelsFlags(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Compute Engine partner interconnect attachment.
*{command}* is used to update partner interconnect attachments. A partner
interconnect attachment binds the underlying connectivity of a provider's
Interconnect to a path into and out of the customer's cloud network.
"""
_support_label = True
@classmethod
def Args(cls, parser):
super().Args(parser)

View File

@@ -0,0 +1,41 @@
# -*- 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.
"""Commands for creating or manipulating partner provider attachments."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.Hidden
class InterconnectAttachments(base.Group):
"""Create or manipulate partner provider interconnect attachments."""
pass
InterconnectAttachments.detailed_help = {
'DESCRIPTION': """
Create or manipulate provider interconnect attachments.
For more information about provider interconnect attachments,
as configured by providers, see the
[interconnect attachments documentation](https://cloud.google.com//network-connectivity/docs/interconnect/how-to/dedicated/creating-vlan-attachments).
See also: [Interconnect attachments API](https://cloud.google.com/compute/docs/reference/rest/v1/interconnectAttachments).
""",
}

View File

@@ -0,0 +1,160 @@
# -*- 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 creating partner provider interconnect attachments."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects import flags as interconnect_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a Compute Engine partner provider interconnect attachment.
*{command}* is used to create partner provider interconnect attachments. An
interconnect attachment binds the underlying connectivity of an Interconnect
to a path into and out of the customer's cloud network. Partner provider
attachments can only be created by approved network partners.
"""
INTERCONNECT_ATTACHMENT_ARG = None
INTERCONNECT_ARG = None
ROUTER_ARG = None
_support_partner_ipv6_byoip = False
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = (
interconnect_flags.InterconnectArgumentForOtherResource(
'The interconnect for the interconnect attachment'))
cls.INTERCONNECT_ARG.AddArgument(parser)
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='create')
attachment_flags.AddBandwidth(parser, required=True)
attachment_flags.AddVlan(parser)
attachment_flags.AddPartnerAsn(parser)
attachment_flags.AddPartnerMetadata(parser, required=True)
attachment_flags.AddPairingKey(parser)
attachment_flags.AddDescription(parser)
attachment_flags.AddCandidateSubnets(parser)
attachment_flags.AddSubnetLength(parser)
attachment_flags.AddResourceManagerTags(parser)
attachment_flags.AddCandidateCloudRouterIpAddress(parser)
attachment_flags.AddCandidateCustomerRouterIpAddress(parser)
attachment_flags.AddCandidateCloudRouterIpv6Address(parser)
attachment_flags.AddCandidateCustomerRouterIpv6Address(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client)
interconnect_ref = None
if args.interconnect is not None:
interconnect_ref = self.INTERCONNECT_ARG.ResolveAsResource(
args, holder.resources)
candidate_ipv6_subnets = None
cloud_router_ipv6_interface_id = None
customer_router_ipv6_interface_id = None
if self._support_partner_ipv6_byoip:
candidate_ipv6_subnets = args.candidate_ipv6_subnets
cloud_router_ipv6_interface_id = getattr(
args, 'cloud_router_ipv6_interface_id', None
)
customer_router_ipv6_interface_id = getattr(
args, 'customer_router_ipv6_interface_id', None
)
return interconnect_attachment.Create(
description=args.description,
interconnect=interconnect_ref,
vlan_tag_802_1q=args.vlan,
attachment_type='PARTNER_PROVIDER',
bandwidth=args.bandwidth,
pairing_key=args.pairing_key,
candidate_subnets=args.candidate_subnets,
partner_asn=args.partner_asn,
partner_name=args.partner_name,
partner_interconnect=args.partner_interconnect_name,
partner_portal_url=args.partner_portal_url,
subnet_length=getattr(args, 'subnet_length', None),
validate_only=getattr(args, 'dry_run', None),
candidate_ipv6_subnets=candidate_ipv6_subnets,
cloud_router_ipv6_interface_id=cloud_router_ipv6_interface_id,
customer_router_ipv6_interface_id=customer_router_ipv6_interface_id,
candidate_cloud_router_ip_address=getattr(
args, 'candidate_cloud_router_ip_address', None
),
candidate_customer_router_ip_address=getattr(
args, 'candidate_customer_router_ip_address', None
),
candidate_cloud_router_ipv6_address=getattr(
args, 'candidate_cloud_router_ipv6_address', None
),
candidate_customer_router_ipv6_address=getattr(
args, 'candidate_customer_router_ipv6_address', None
),
resource_manager_tags=args.resource_manager_tags,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a Compute Engine partner provider interconnect attachment.
*{command}* is used to create partner provider interconnect attachments. An
interconnect attachment binds the underlying connectivity of an Interconnect
to a path into and out of the customer's cloud network. Partner provider
attachments can only be created by approved network partners.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Create a Compute Engine partner provider interconnect attachment.
*{command}* is used to create partner provider interconnect attachments. An
interconnect attachment binds the underlying connectivity of an Interconnect
to a path into and out of the customer's cloud network. Partner provider
attachments can only be created by approved network partners.
"""
_support_partner_ipv6_byoip = True
@classmethod
def Args(cls, parser):
super().Args(parser)
attachment_flags.AddDryRun(parser)
attachment_flags.AddCandidateIpv6Subnets(parser)
attachment_flags.AddCloudRouterIpv6InterfaceId(parser)
attachment_flags.AddCustomerRouterIpv6InterfaceId(parser)

View File

@@ -0,0 +1,142 @@
# -*- 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 partner provider interconnect attachments."""
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.interconnects.attachments import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.interconnects.attachments import flags as attachment_flags
from googlecloudsdk.command_lib.util.args import labels_util
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Compute Engine partner provider interconnect attachment.
*{command}* is used to update partner provider interconnect attachments. An
interconnect attachment binds the underlying connectivity of an Interconnect
to a path into and out of the customer's cloud network.
"""
_support_label = False
_support_partner_ipv6_byoip = False
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ATTACHMENT_ARG = (
attachment_flags.InterconnectAttachmentArgument())
cls.INTERCONNECT_ATTACHMENT_ARG.AddArgument(parser, operation_type='patch')
attachment_flags.AddBandwidth(parser, required=False)
attachment_flags.AddPartnerMetadata(parser, required=False)
attachment_flags.AddDescription(parser)
attachment_flags.AddCandidateCloudRouterIpv6Address(parser)
attachment_flags.AddCandidateCustomerRouterIpv6Address(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
attachment_ref = self.INTERCONNECT_ATTACHMENT_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client),
)
interconnect_attachment = client.InterconnectAttachment(
attachment_ref, compute_client=holder.client
)
labels = None
label_fingerprint = None
if self._support_label:
labels_diff = labels_util.Diff.FromUpdateArgs(args)
if labels_diff.MayHaveUpdates():
old_attachment = interconnect_attachment.Describe()
labels_cls = holder.client.messages.InterconnectAttachment.LabelsValue
labels = labels_diff.Apply(
labels_cls, labels=old_attachment.labels
).GetOrNone()
if labels is not None:
label_fingerprint = old_attachment.labelFingerprint
candidate_ipv6_subnets = None
cloud_router_ipv6_interface_id = None
customer_router_ipv6_interface_id = None
if self._support_partner_ipv6_byoip:
candidate_ipv6_subnets = getattr(args, 'candidate_ipv6_subnets', None)
cloud_router_ipv6_interface_id = getattr(
args, 'cloud_router_ipv6_interface_id', None
)
customer_router_ipv6_interface_id = getattr(
args, 'customer_router_ipv6_interface_id', None
)
return interconnect_attachment.Patch(
description=args.description,
bandwidth=args.bandwidth,
partner_name=args.partner_name,
partner_interconnect=args.partner_interconnect_name,
partner_portal_url=args.partner_portal_url,
labels=labels,
label_fingerprint=label_fingerprint,
candidate_ipv6_subnets=candidate_ipv6_subnets,
cloud_router_ipv6_interface_id=cloud_router_ipv6_interface_id,
customer_router_ipv6_interface_id=customer_router_ipv6_interface_id,
candidate_cloud_router_ipv6_address=getattr(
args, 'candidate_cloud_router_ipv6_address', None
),
candidate_customer_router_ipv6_address=getattr(
args, 'candidate_customer_router_ipv6_address', None
),
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Compute Engine partner provider interconnect attachment.
*{command}* is used to update partner provider interconnect attachments. An
interconnect attachment binds the underlying connectivity of an Interconnect
to a path into and out of the customer's cloud network.
"""
_support_label = True
_support_partner_ipv6_byoip = False
@classmethod
def Args(cls, parser):
super().Args(parser)
labels_util.AddUpdateLabelsFlags(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Compute Engine partner provider interconnect attachment.
*{command}* is used to update partner provider interconnect attachments. An
interconnect attachment binds the underlying connectivity of an Interconnect
to a path into and out of the customer's cloud network.
"""
_support_label = True
_support_partner_ipv6_byoip = True
@classmethod
def Args(cls, parser):
super().Args(parser)
attachment_flags.AddCandidateIpv6Subnets(parser)
attachment_flags.AddCloudRouterIpv6InterfaceId(parser)
attachment_flags.AddCustomerRouterIpv6InterfaceId(parser)

View File

@@ -0,0 +1,151 @@
# -*- 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 interconnects."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
from googlecloudsdk.command_lib.compute.interconnects.locations import flags as location_flags
from googlecloudsdk.command_lib.compute.interconnects.remote_locations import flags as remote_location_flags
from googlecloudsdk.core import log
DETAILED_HELP = {
'DESCRIPTION':
"""\
*{command}* is used to create interconnects. An interconnect represents
a single specific connection between Google and the customer.
For an example, refer to the *EXAMPLES* section below.
""",
# pylint: disable=line-too-long
'EXAMPLES':
"""\
To create an interconnect of type DEDICATED, run:
$ {command} example-interconnect --customer-name="Example Customer Name" --interconnect-type=DEDICATED --link-type=LINK_TYPE_ETHERNET_10G_LR --location=example-zone1-1 --requested-link-count=1 --noc-contact-email=noc@example.com --description="Example interconnect"
To create a Cross-Cloud Interconnect, run:
$ {command} example-cc-interconnect --interconnect-type=DEDICATED --link-type=LINK_TYPE_ETHERNET_10G_LR --location=example-zone1-1 --requested-link-count=1 --remote-location=example-remote-location --noc-contact-email=noc@example.com --description="Example Cross-Cloud Interconnect"
""",
# pylint: enable=line-too-long
}
_LOCATION_FLAG_MSG = (
'The location for the interconnect. The locations can be listed by using '
'the `{parent_command} locations list` command to find '
'the appropriate location to use when creating an interconnect.')
_REMOTE_LOCATION_FLAG_MSG = (
'The remote location for a Cross-Cloud Interconnect. The remote locations '
'can be listed by using the `{parent_command} remote-locations list` '
'command to find the appropriate remote location to use when creating a '
'Cross-Cloud Interconnect.')
_DOCUMENTATION_LINK = 'https://cloud.google.com/interconnect/docs/how-to/dedicated/retrieving-loas'
_CCI_DOCUMENTATION_LINK = 'https://cloud.google.com/network-connectivity/docs/interconnect/concepts/cci-overview'
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Create(base.CreateCommand):
"""Create a Compute Engine interconnect.
*{command}* is used to create interconnects. An interconnect represents a
single specific connection between Google and the customer.
"""
INTERCONNECT_ARG = None
LOCATION_ARG = None
REMOTE_LOCATION_ARG = None
is_cci = False
@classmethod
def Args(cls, parser):
cls.LOCATION_ARG = (
location_flags.InterconnectLocationArgumentForOtherResource(
_LOCATION_FLAG_MSG))
cls.LOCATION_ARG.AddArgument(parser)
cls.REMOTE_LOCATION_ARG = remote_location_flags.InterconnectRemoteLocationArgumentForOtherResource(
_REMOTE_LOCATION_FLAG_MSG
)
cls.REMOTE_LOCATION_ARG.AddArgument(parser)
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='create')
flags.AddCreateArgs(parser, cls.ReleaseTrack())
parser.display_info.AddCacheUpdater(flags.InterconnectsCompleter)
def Collection(self):
return 'compute.interconnects'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
location_ref = self.LOCATION_ARG.ResolveAsResource(args, holder.resources)
remote_location_ref = self.REMOTE_LOCATION_ARG.ResolveAsResource(
args, holder.resources
)
messages = holder.client.messages
interconnect_type = flags.GetInterconnectType(
messages, args.interconnect_type
)
link_type = flags.GetLinkType(messages, args.link_type)
remote_location = None
if remote_location_ref:
remote_location = remote_location_ref.SelfLink()
self.is_cci = True
return interconnect.Create(
description=args.description,
interconnect_type=interconnect_type,
requested_link_count=args.requested_link_count,
link_type=link_type,
admin_enabled=args.admin_enabled,
noc_contact_email=args.noc_contact_email,
location=location_ref.SelfLink(),
subzone=flags.GetSubzone(messages, args.subzone),
customer_name=args.customer_name,
remote_location=remote_location,
requested_features=flags.GetRequestedFeatures(
messages, args.requested_features
),
resource_manager_tags=args.resource_manager_tags,
)
def Epilog(self, resources_were_displayed):
documentation_link = (
_CCI_DOCUMENTATION_LINK if self.is_cci else _DOCUMENTATION_LINK
)
message = (
'Please check the provided contact email for further '
'instructions on how to activate your Interconnect. See also '
'{} for more detailed help.'.format(documentation_link)
)
log.status.Print(message)
Create.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 creating or manipulating cross site 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 CrossSiteNetworks(base.Group):
"""Create or manipulate cross site networks."""
CrossSiteNetworks.detailed_help = {
'DESCRIPTION': """
Create or manipulate cross site networks.
""",
}

View File

@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 cross site 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.interconnects.cross_site_networks import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to create cross site networks. A cross site network
contains wire groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To create a cross site network, run:
$ {command} example-csn --description="Example cross site network"
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Create(base.CreateCommand):
"""Create a Compute Engine cross site network.
*{command}* is used to cross site networks. A cross site network
contains wire groups.
"""
# Framework override.
detailed_help = _DETAILED_HELP
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = flags.CrossSiteNetworkArgument(plural=False)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser, operation_type='create')
flags.AddDescription(parser)
def Collection(self):
return 'compute.crossSiteNetworks'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.CROSS_SITE_NETWORK_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
cross_site_network = client.CrossSiteNetwork(
ref,
project,
compute_client=holder.client,
resources=holder.resources,
)
return cross_site_network.Create(
description=args.description,
)

View File

@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 cross site 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.api_lib.compute.interconnects.cross_site_networks import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to delete cross site networks.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To delete a cross site network, run:
$ {command} example-csn
Although not shown in this example, you can delete multiple cross site
networks in a single command.
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete Compute Engine cross site networks.
*{command}* deletes Compute Engine cross site networks.
"""
# Framework override.
detailed_help = _DETAILED_HELP
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = flags.CrossSiteNetworkArgument(plural=True)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser, operation_type='delete')
def Collection(self):
return 'compute.crossSiteNetworks'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.CROSS_SITE_NETWORK_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
cross_site_network = client.CrossSiteNetwork(
ref, project=project, compute_client=holder.client
)
requests.extend(
cross_site_network.Delete(only_generate_request=True)
)
return holder.client.MakeRequests(requests)

View File

@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 cross site 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.interconnects.cross_site_networks import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to describe a cross site network.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To describe a cross site network, run:
$ {command} example-csn
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine cross site network.
*{command}* displays all data associated with Compute Engine
cross site network in a project.
"""
# Framework override.
detailed_help = _DETAILED_HELP
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = flags.CrossSiteNetworkArgument()
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.CROSS_SITE_NETWORK_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
cross_site_network = client.CrossSiteNetwork(
ref, project=project, compute_client=holder.client
)
return cross_site_network.Describe()

View File

@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 cross site networks."""
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
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.ListCommand):
"""List cross site networks."""
# Framework override.
detailed_help = base_classes.GetGlobalListerHelp('cross site networks')
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat("""
table(
name
)
""")
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.ComputeCrossSiteNetworksListRequest(
project=project, filter=filter_expr
)
return list_pager.YieldFromList(
client.crossSiteNetworks,
request,
field='items',
limit=args.limit,
batch_size=None,
)

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 cross site 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.interconnects.cross_site_networks import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to update cross site networks.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To update a cross site network's description, run:
$ {command} example-csn --description="New description"
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Update(base.UpdateCommand):
"""Update a Compute Engine cross site network.
*{command}* is used to update cross site networks. A cross site network
encapsulates wire groups.
"""
# Framework override.
detailed_help = _DETAILED_HELP
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = flags.CrossSiteNetworkArgument(plural=False)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser, operation_type='update')
flags.AddDescription(parser)
def Collection(self):
return 'compute.crossSiteNetworks'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.CROSS_SITE_NETWORK_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
cross_site_network = client.CrossSiteNetwork(
ref,
project,
compute_client=holder.client,
resources=holder.resources,
)
return cross_site_network.Patch(description=args.description)

View File

@@ -0,0 +1,62 @@
# -*- 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 deleting interconnects."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import utils
from googlecloudsdk.api_lib.compute.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete Compute Engine interconnects.
*{command}* deletes Compute Engine interconnects. Interconnects
can only be deleted when no other resources (e.g.,
InterconnectAttachments) refer to them.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument(plural=True)
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(flags.InterconnectsCompleter)
def Collection(self):
return 'compute.interconnects'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
interconnect = client.Interconnect(ref, compute_client=holder.client)
requests.extend(interconnect.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)

View File

@@ -0,0 +1,46 @@
# -*- 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 describing interconnects."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
class Describe(base.DescribeCommand):
"""Describe a Compute Engine interconnect.
*{command}* displays all data associated with Compute Engine
interconnect in a project.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
return interconnect.Describe()

View File

@@ -0,0 +1,46 @@
# -*- 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 getting the diagnostics of interconnects."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
class GetDiagnostics(base.DescribeCommand):
"""Get diagnostics of a Compute Engine interconnect.
*{command}* displays all runtime data associated with Compute Engine
interconnect in a project.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
return interconnect.GetDiagnostics()

View File

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 creating or manipulating interconnect groups."""
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 InterconnectGroups(base.Group):
"""Create or manipulate interconnect groups."""
pass
InterconnectGroups.detailed_help = {
'DESCRIPTION': """
Create or manipulate interconnect groups.
""",
}

View File

@@ -0,0 +1,91 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 adding member interconnects to an interconnect group."""
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.interconnects.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to add member interconnects to an interconnect
group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To add interconnects interconnect1 and interconnect2 to interconnect
group example-interconnect-group, run:
$ {command} example-interconnect-group
--interconnects=interconnect1,interconnect2
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class AddMembers(base.UpdateCommand):
"""Add member interconnects to a Compute Engine interconnect group.
*{command}* adds member interconnects to a Compute Engine interconnect group.
"""
INTERCONNECT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_GROUP_ARG = flags.InterconnectGroupArgument(plural=False)
cls.INTERCONNECT_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.GetMemberInterconnects(parser)
def Collection(self):
return 'compute.interconnectGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
interconnect_group = client.InterconnectGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
interconnects = set()
interconnect_group_interconnects = (
interconnect_group.Describe().interconnects
)
if interconnect_group_interconnects is not None:
interconnects = set(
property.key
for property in interconnect_group_interconnects.additionalProperties
)
interconnects |= set(args.interconnects)
return interconnect_group.Patch(
interconnects=sorted(list(interconnects)),
)
AddMembers.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect groups."""
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.interconnects.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to create interconnect groups. An interconnect group
connects a set of redundant interconnects between Google and the
customer.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To create an interconnect group capable of PRODUCTION_CRITICAL, run:
$ {command} example-interconnect-group
--intended-topology-capability=PRODUCTION_CRITICAL
--description="Example interconnect group"
It is easy to add members to an existing interconnect group after
creation using the *add-members* command.
To create an interconnect group capable of PRODUCTION_NON_CRITICAL, with
two members at creation time, run:
$ {command} example-interconnect-group
--intended-topology-capability=PRODUCTION_NON_CRITICAL
--interconnects=interconnect-1,interconnect-2
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Create(base.CreateCommand):
"""Create a Compute Engine interconnect group.
*{command}* is used to create interconnect groups. An interconnect group
connects a set of redundant interconnects between Google and the customer.
"""
INTERCONNECT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_GROUP_ARG = flags.InterconnectGroupArgument(plural=False)
cls.INTERCONNECT_GROUP_ARG.AddArgument(parser, operation_type='create')
flags.AddDescription(parser)
flags.AddIntendedTopologyCapabilityForCreate(parser)
flags.GetMemberInterconnectsForCreate(parser)
def Collection(self):
return 'compute.interconnectGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
interconnect_group = client.InterconnectGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
topology_capability = flags.GetTopologyCapability(
holder.client.messages, args.intended_topology_capability
)
return interconnect_group.Create(
description=args.description,
topology_capability=topology_capability,
interconnects=args.interconnects,
)
Create.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,159 @@
# -*- 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 new member interconnects in an interconnect group."""
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.interconnects.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags as interconnect_flags
from googlecloudsdk.command_lib.compute.interconnects.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to create new member interconnects in an
interconnect group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To create interconnects interconnect1 and interconnect2 in interconnect
group example-interconnect-group, run:
$ {command} example-interconnect-group --interconnect-type=DEDICATED
--link-type=LINK_TYPE_ETHERNET_10G_LR --requested-link-count=1
--facility=iad-1 --interconnect="name=interconnect1"
--interconnect="name=interconnect2"
""",
}
# Interconnect Flags
_FACILITY = 'facility'
_DESCRIPTION = 'description'
_NAME = 'name'
_LINK_TYPE = 'link-type'
_REQUESTED_LINK_COUNT = 'requested-link-count'
_INTERCONNECT_TYPE = 'interconnect-type'
_ADMIN_ENABLED = 'admin-enabled'
_NO_ADMIN_ENABLED = 'no-admin-enabled'
_NOC_CONTACT_EMAIL = 'noc-contact-email'
_CUSTOMER_NAME = 'customer-name'
_REMOTE_LOCATION = 'remote-location'
_REQUESTED_FEATURES = 'requested-features'
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class CreateMembers(base.UpdateCommand):
"""Create new member interconnects in a Compute Engine interconnect group.
*{command}* creates new member interconnects in a Compute Engine interconnect
group.
"""
INTERCONNECT_GROUP_ARG = None
REMOTE_LOCATION_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_GROUP_ARG = flags.InterconnectGroupArgument(plural=False)
cls.INTERCONNECT_GROUP_ARG.AddArgument(
parser, operation_type='create members'
)
flags.AddMemberInterconnectsForCreateMembers(parser)
flags.AddFacility(parser)
flags.AddRemoteLocation(parser)
flags.AddIntentMismatchBehavior(parser)
interconnect_flags.AddCreateArgsForInterconnectGroupsCreateMembers(
parser, required=False
)
def Collection(self):
return 'compute.interconnectGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
interconnect_group = client.InterconnectGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
messages = holder.client.messages
template_interconnect = (
interconnect_group.MakeInterconnectGroupsCreateMembersInterconnectInput(
facility=args.facility,
description=args.description,
name=None,
link_type=flags.GetLinkType(messages, args.link_type),
requested_link_count=args.requested_link_count,
interconnect_type=flags.GetInterconnectType(
messages, args.interconnect_type
),
admin_enabled=args.admin_enabled,
noc_contact_email=args.noc_contact_email,
customer_name=args.customer_name,
remote_location=args.remote_location,
requested_features=flags.GetRequestedFeatures(
messages, args.requested_features
),
)
)
member_interconnects = []
for ic_args in args.interconnect:
if _ADMIN_ENABLED in ic_args:
admin_enabled = True
elif _NO_ADMIN_ENABLED in ic_args:
admin_enabled = False
else:
admin_enabled = None
member_interconnects.append(
interconnect_group.MakeInterconnectGroupsCreateMembersInterconnectInput(
facility=ic_args.get(_FACILITY),
description=ic_args.get(_DESCRIPTION),
name=ic_args.get(_NAME),
link_type=flags.GetLinkType(messages, ic_args.get(_LINK_TYPE)),
requested_link_count=ic_args.get(_REQUESTED_LINK_COUNT),
interconnect_type=flags.GetInterconnectType(
messages, ic_args.get(_INTERCONNECT_TYPE)
),
admin_enabled=admin_enabled,
noc_contact_email=ic_args.get(_NOC_CONTACT_EMAIL),
customer_name=ic_args.get(_CUSTOMER_NAME),
remote_location=ic_args.get(_REMOTE_LOCATION),
requested_features=flags.GetRequestedFeatures(
messages, ic_args.get(_REQUESTED_FEATURES)
),
)
)
return interconnect_group.CreateMembers(
intent_mismatch_behavior=flags.GetIntentMismatchBehavior(
messages, args.intent_mismatch_behavior
),
template_interconnect=template_interconnect,
member_interconnects=member_interconnects,
)
CreateMembers.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect groups."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import utils
from googlecloudsdk.api_lib.compute.interconnects.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to delete interconnect groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To delete an interconnect group, run:
$ {command} example-interconnect-group"
Although not shown in this example, you can delete multiple interconnect
groups in a single command.
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete Compute Engine interconnect groups.
*{command}* deletes Compute Engine interconnect groups. Interconnect groups
can be deleted even if they are referenced by interconnects. Each
interconnect in the group will be updated to remove its reference to this
group.
"""
INTERCONNECT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_GROUP_ARG = flags.InterconnectGroupArgument(plural=True)
cls.INTERCONNECT_GROUP_ARG.AddArgument(parser, operation_type='delete')
def Collection(self):
return 'compute.interconnectGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.INTERCONNECT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
interconnect_group = client.InterconnectGroup(
ref, project, compute_client=holder.client
)
requests.extend(interconnect_group.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)
Delete.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect groups."""
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.interconnects.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to describe an interconnect group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To describe interconnect group example-interconnect-group, run:
$ {command} example-interconnect-group
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine interconnect group.
*{command}* displays all data associated with Compute Engine
interconnect group in a project.
"""
INTERCONNECT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_GROUP_ARG = flags.InterconnectGroupArgument()
cls.INTERCONNECT_GROUP_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
interconnect_group = client.InterconnectGroup(
ref, project, compute_client=holder.client
)
return interconnect_group.Describe()
Describe.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,74 @@
# -*- 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 getting interconnect group operational status."""
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.interconnects.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to get the operational status of an interconnect
group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To get the operational status of interconnect group
example-interconnect-group, run:
$ {command} example-interconnect-group
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class GetOperationalStatus(base.DescribeCommand):
"""Get the operational status of a Compute Engine interconnect group.
*{command}* gets the operational status of a Compute Engine
interconnect group in a project.
"""
INTERCONNECT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_GROUP_ARG = flags.InterconnectGroupArgument()
cls.INTERCONNECT_GROUP_ARG.AddArgument(
parser, operation_type='get operational status'
)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
interconnect_group = client.InterconnectGroup(
ref, project, compute_client=holder.client
)
return interconnect_group.GetOperationalStatus()
GetOperationalStatus.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect groups."""
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
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to list interconnect groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To list interconnect groups, run:
$ {command}
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.ListCommand):
"""List interconnect groups."""
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat("""
table(
name,
interconnects.flatten(show='keys', separator='\n'),
intent.topologyCapability:label=INTENDED_CAPABILITY,
configured.topologyCapability.supportedSla:label=CONFIGURED_CAPABILITY
)
""")
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.ComputeInterconnectGroupsListRequest(
project=project, filter=filter_expr
)
return list_pager.YieldFromList(
client.interconnectGroups,
request,
field='items',
limit=args.limit,
batch_size=None,
)
List.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 removing member interconnects from an interconnect group."""
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.interconnects.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to remove member interconnects from an interconnect
group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To remove interconnects interconnect1 and interconnect2 from
interconnect group example-interconnect-group, run:
$ {command} example-interconnect-group
--interconnects=interconnect1,interconnect2
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RemoveMembers(base.UpdateCommand):
"""Remove member interconnects from a Compute Engine interconnect group.
*{command}* removes member interconnects from a Compute Engine interconnect
group.
"""
INTERCONNECT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_GROUP_ARG = flags.InterconnectGroupArgument(plural=False)
cls.INTERCONNECT_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.GetMemberInterconnects(parser)
def Collection(self):
return 'compute.interconnectGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
interconnect_group = client.InterconnectGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
interconnects = set()
interconnect_group_interconnects = (
interconnect_group.Describe().interconnects
)
if interconnect_group_interconnects is not None:
interconnects = set(
property.key
for property in interconnect_group_interconnects.additionalProperties
)
interconnects -= set(args.interconnects)
return interconnect_group.Patch(
interconnects=sorted(list(interconnects)),
update_mask='interconnects',
)
RemoveMembers.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,114 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 interconnect groups."""
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.interconnects.groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.interconnects.groups import flags
from googlecloudsdk.core import properties
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to update interconnect groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To update an interconnect group example-interconnect-group's intended
topology capability to PRODUCTION_CRITICAL, run:
$ {command} example-interconnect-group
--intended-topology-capability=PRODUCTION_CRITICAL
To update an interconnect group example-interconnect-group's description
to "example interconnect group description", run:
$ {command} example-interconnect-group
--description="example interconnect group description"
To update an interconnect group example-interconnect-group's member
interconnects to interconnect-1 and interconnect-2, run:
$ {command} example-interconnect-group
--interconnects=interconnect-1,interconnect-2
--update-mask=interconnects
Although you can add or remove member interconnects using this command,
it is recommended to add or remove member interconnects using the
*add-members* and *remove-members* commands.
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Update(base.UpdateCommand):
"""Update a Compute Engine interconnect group.
*{command}* is used to update interconnect groups. An interconnect group
represents a set of redundant interconnects between Google and the customer.
"""
INTERCONNECT_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_GROUP_ARG = flags.InterconnectGroupArgument(plural=False)
cls.INTERCONNECT_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.AddDescription(parser)
flags.AddIntendedTopologyCapabilityForUpdate(parser)
flags.GetMemberInterconnectsForUpdate(parser)
flags.AddUpdateMask(parser)
def Collection(self):
return 'compute.interconnectGroups'
def Run(self, args):
if (
args.description is None
and args.intended_topology_capability is None
and not args.interconnects
):
raise exceptions.MinimumArgumentException(
['--description', '--intended-topology-capability', '--interconnects']
)
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_GROUP_ARG.ResolveAsResource(args, holder.resources)
project = properties.VALUES.core.project.GetOrFail()
interconnect_group = client.InterconnectGroup(
ref, project, compute_client=holder.client, resources=holder.resources
)
topology_capability = None
if args.intended_topology_capability is not None:
topology_capability = flags.GetTopologyCapability(
holder.client.messages, args.intended_topology_capability
)
return interconnect_group.Patch(
description=args.description,
topology_capability=topology_capability,
interconnects=args.interconnects,
update_mask=args.update_mask,
)
Update.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,73 @@
# -*- 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 listing interconnects."""
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
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.ListCommand):
"""List interconnects."""
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat("""
table(
name,
location.basename(),
operationalStatus,
adminEnabled,
interconnectGroups.basename().join(sep="\n")
)
""")
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.ComputeInterconnectsListRequest(
project=project, filter=filter_expr)
return list_pager.YieldFromList(
client.interconnects,
request,
field='items',
limit=args.limit,
batch_size=None)
List.detailed_help = base_classes.GetGlobalListerHelp('interconnects')

View File

@@ -0,0 +1,38 @@
# -*- 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.
"""Commands for reading and manipulating interconnect locations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class InterconnectLocations(base.Group):
"""Read and manipulate Compute Engine interconnect locations."""
pass
InterconnectLocations.detailed_help = {
'DESCRIPTION': """
Read and manipulate Cloud Interconnect locations.
For more information about interconnect locations, see the
[interconnect locations documentation](https://cloud.google.com//network-connectivity/docs/interconnect/concepts/colocation-facilities).
See also: [Interconnect locations API](https://cloud.google.com/compute/docs/reference/rest/v1/interconnectLocations).
""",
}

View File

@@ -0,0 +1,54 @@
# -*- 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 describing interconnect locations."""
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.interconnects.locations import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.locations import flags
class Describe(base.DescribeCommand):
"""Describe a Compute Engine interconnect location.
Displays all data associated with Compute Engine
interconnect location in a project.
Example of usage:
$ {command} my-location
"""
INTERCONNECT_LOCATION_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_LOCATION_ARG = flags.InterconnectLocationArgument()
cls.INTERCONNECT_LOCATION_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_LOCATION_ARG.ResolveAsResource(
args, holder.resources)
interconnect_location = client.InterconnectLocation(
ref, compute_client=holder.client)
return interconnect_location.Describe()

View File

@@ -0,0 +1,70 @@
# -*- 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 listing interconnect locations."""
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
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.ListCommand):
"""List Compute Engine interconnect locations."""
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat("""
table(
name,
description,
facilityProvider,
singleRegionProductionCriticalPeerLocations.basename().join(sep="\n"):label=99.99%_PEER_LOCATIONS
)
""")
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()
args.filter, filter_expr = filter_rewrite.Rewriter().Rewrite(args.filter)
request = messages.ComputeInterconnectLocationsListRequest(
project=project, filter=filter_expr)
results = list_pager.YieldFromList(
client.interconnectLocations,
request,
field='items',
limit=args.limit,
batch_size=None)
for item in results:
yield item
List.detailed_help = base_classes.GetGlobalListerHelp('interconnect locations')

View File

@@ -0,0 +1,28 @@
# -*- 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.
"""Commands for reading and manipulating interconnect MACsec configuration."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class InterconnectMacsecConfig(base.Group):
"""Read and manipulate Compute Engine interconnect MACsec configuration."""

View File

@@ -0,0 +1,96 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for updating the MACsec configuration of interconnect."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION':
"""\
*{command}* is used to add a pre-shared key to MACsec configuration of
interconnect.
For an example, refer to the *EXAMPLES* section below.
""",
# pylint: disable=line-too-long
'EXAMPLES':
"""\
To add a pre-shared key to MACsec configuration, run:
$ {command} example-interconnect --key-name=default-key --start-time=2021-02-01T12:12:12Z
""",
# pylint: enable=line-too-long
}
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class AddKey(base.UpdateCommand):
"""Add pre-shared key to a Compute Engine interconnect MACsec configuration.
*{command}* is used to add pre-shared key to MACsec configuration of
interconnect.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='update')
flags.AddMacsecPreSharedKeyNameForAddOrUpdateKey(parser)
flags.AddMacsecPreSharedKeyStartTimeForAddOrUpdateKey(parser)
def Collection(self):
return 'compute.interconnects'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
macsec = interconnect.Describe().macsec
if macsec is None:
macsec = holder.client.messages.InterconnectMacsec()
if all(key.name != args.key_name for key in macsec.preSharedKeys):
macsec.preSharedKeys.append(
holder.client.messages.InterconnectMacsecPreSharedKey(
name=args.key_name, startTime=args.start_time))
return interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
macsec_enabled=None,
macsec=macsec)
AddKey.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for getting the MACsec configuration of interconnect."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION':
"""\
*{command}* displays all MACsec configuration data associated with
Compute Engine interconnect in a project.
For an example, refer to the *EXAMPLES* section below.
""",
# pylint: disable=line-too-long
'EXAMPLES':
"""\
To displays all MACsec configuration data associated with Compute Engine
interconnect in a project, run:
$ {command} example-interconnect
""",
# pylint: enable=line-too-long
}
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class GetConfig(base.DescribeCommand):
"""Get MACsec configuration of a Compute Engine interconnect.
*{command}* displays all MACsec configuration data associated with Compute
Engine interconnect in a project.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
return interconnect.GetMacsecConfig()
GetConfig.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for removing pre-shared key from the MACsec configuration of interconnect."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION':
"""\
*{command}* is used to remove pre-shared key from MACsec configuration of
interconnect.
For an example, refer to the *EXAMPLES* section below.
""",
# pylint: disable=line-too-long
'EXAMPLES':
"""\
To remove a pre-shared key from MACsec configuration, run:
$ {command} example-interconnect --key-name=default-key
""",
# pylint: enable=line-too-long
}
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RemoveKey(base.UpdateCommand):
"""Remove pre-shared key from a Compute Engine interconnect MACsec configuration.
*{command}* is used to remove pre-shared key from MACsec configuration of
interconnect.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='update')
flags.AddMacsecPreSharedKeyNameForRomoveKey(parser)
def Collection(self):
return 'compute.interconnects'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
macsec = interconnect.Describe().macsec
keys = macsec.preSharedKeys
macsec.preSharedKeys = [key for key in keys if key.name != args.key_name]
return interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
macsec_enabled=None,
macsec=macsec)
RemoveKey.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,94 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for updating the MACsec configuration of interconnect."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION':
"""\
*{command}* is used to update MACsec configuration of interconnect. An
interconnect represents a single specific connection between Google and
the customer.
For an example, refer to the *EXAMPLES* section below.
""",
# pylint: disable=line-too-long
'EXAMPLES':
"""\
To enable MACsec on an interconnect, run:
$ {command} example-interconnect --enabled
""",
# pylint: enable=line-too-long
}
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Update(base.UpdateCommand):
"""Update a Compute Engine interconnect MACsec configuration.
*{command}* is used to update MACsec configuration of interconnect. An
interconnect represents a single specific connection between Google and the
customer.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='update')
flags.AddMacsecEnabledForUpdate(parser)
flags.AddFailOpenForUpdate(parser)
def Collection(self):
return 'compute.interconnects'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
macsec = None
if args.fail_open is not None:
macsec = interconnect.Describe().macsec
macsec.failOpen = args.fail_open
return interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
macsec_enabled=args.enabled,
macsec=macsec)
Update.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,105 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for updating the MACsec key configuration of interconnect."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.interconnects import flags
DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to update a pre-shared key in MACsec configuration
of interconnect.
For an example, refer to the *EXAMPLES* section below.
""",
# pylint: disable=line-too-long
'EXAMPLES': """\
To update a pre-shared key in MACsec configuration, run:
$ {command} example-interconnect --key-name=default-key --start-time=2021-02-01T12:12:12Z
""",
# pylint: enable=line-too-long
}
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class UpdateKey(base.UpdateCommand):
"""Update pre-shared key in a Compute Engine interconnect MACsec configuration.
*{command}* is used to update pre-shared key in MACsec configuration of
interconnect.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='update')
flags.AddMacsecPreSharedKeyNameForAddOrUpdateKey(parser)
flags.AddMacsecPreSharedKeyStartTimeForAddOrUpdateKey(parser)
def Collection(self):
return 'compute.interconnects'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
macsec = interconnect.Describe().macsec
if macsec is None:
raise exceptions.BadArgumentException(
'key-name',
"Interconnect '{}' does not have MACsec config.".format(ref.Name()),
)
try:
preshared_key = next(
key for key in macsec.preSharedKeys if key.name == args.key_name
)
except StopIteration:
raise exceptions.BadArgumentException(
'key-name', "Key '{}' was not found.".format(args.key_name)
)
preshared_key.startTime = args.start_time
return interconnect.Patch(
description=None,
interconnect_type=None,
requested_link_count=None,
link_type=None,
admin_enabled=None,
noc_contact_email=None,
location=None,
labels=None,
label_fingerprint=None,
macsec_enabled=None,
macsec=macsec,
)
UpdateKey.detailed_help = DETAILED_HELP

View File

@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Commands for reading and manipulating interconnect locations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class InterconnectRemoteLocations(base.Group):
"""Read and manipulate Google Compute Engine interconnect remote locations."""
pass
InterconnectRemoteLocations.detailed_help = {
'DESCRIPTION':
"""
Read and manipulate Cloud Interconnect remote locations.
""",
}

View File

@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for describing interconnect remote locations."""
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.interconnects.remote_locations import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects.remote_locations import flags
class Describe(base.DescribeCommand):
"""Describe a Google Compute Engine interconnect remote location."""
detailed_help = {
'DESCRIPTION': """\
Displays all data associated with Google Compute Engine interconnect remote location in a project.
""",
'EXAMPLES': """\
Example of usage:
$ {command} my-remote-location
""",
}
INTERCONNECT_REMOTE_LOCATION_ARG = None
@classmethod
def Args(cls, parser):
cls.INTERCONNECT_REMOTE_LOCATION_ARG = flags.InterconnectRemoteLocationArgument(
)
cls.INTERCONNECT_REMOTE_LOCATION_ARG.AddArgument(
parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_REMOTE_LOCATION_ARG.ResolveAsResource(
args, holder.resources)
interconnect_remote_location = client.InterconnectRemoteLocation(
ref, compute_client=holder.client)
return interconnect_remote_location.Describe()

View File

@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for listing interconnect locations."""
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
class List(base.ListCommand):
"""List Google Compute Engine Cloud Interconnect remote locations."""
@classmethod
def Args(cls, parser):
parser.display_info.AddFormat("""
table(
name,
description
)
""")
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()
args.filter, filter_expr = filter_rewrite.Rewriter().Rewrite(args.filter)
request = messages.ComputeInterconnectRemoteLocationsListRequest(
project=project, filter=filter_expr)
results = list_pager.YieldFromList(
client.interconnectRemoteLocations,
request,
field='items',
limit=args.limit,
batch_size=None)
for item in results:
yield item
List.detailed_help = base_classes.GetGlobalListerHelp(
'Cloud Interconnect remote locations')

View File

@@ -0,0 +1,108 @@
# -*- 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 interconnects."""
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.interconnects import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.interconnects import flags
from googlecloudsdk.command_lib.util.args import labels_util
def _ArgsCommon(cls, parser, support_labels=False):
"""Shared arguments for update commands."""
cls.INTERCONNECT_ARG = flags.InterconnectArgument()
cls.INTERCONNECT_ARG.AddArgument(parser, operation_type='update')
parser.add_argument(
'--description',
help='An optional, textual description for the interconnect.')
flags.AddAdminEnabledForUpdate(parser)
flags.AddNocContactEmail(parser)
flags.AddRequestedLinkCountForUpdate(parser)
if support_labels:
labels_util.AddUpdateLabelsFlags(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Compute Engine interconnect.
*{command}* is used to update interconnects. An interconnect represents a
single specific connection between Google and the customer.
"""
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
_ArgsCommon(cls, parser)
def Collection(self):
return 'compute.interconnects'
def _DoRun(self, args, support_labels=False):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.INTERCONNECT_ARG.ResolveAsResource(args, holder.resources)
interconnect = client.Interconnect(ref, compute_client=holder.client)
labels = None
label_fingerprint = None
if support_labels:
labels_diff = labels_util.Diff.FromUpdateArgs(args)
if labels_diff.MayHaveUpdates():
old_interconnect = interconnect.Describe()
labels = labels_diff.Apply(
holder.client.messages.Interconnect.LabelsValue,
old_interconnect.labels).GetOrNone()
if labels is not None:
label_fingerprint = old_interconnect.labelFingerprint
return interconnect.Patch(
description=args.description,
interconnect_type=None,
requested_link_count=args.requested_link_count,
link_type=None,
admin_enabled=args.admin_enabled,
noc_contact_email=args.noc_contact_email,
location=None,
labels=labels,
label_fingerprint=label_fingerprint,
)
def Run(self, args):
self._DoRun(args)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA)
class UpdateLabels(Update):
"""Update a Compute Engine interconnect.
*{command}* is used to update interconnects. An interconnect represents a
single specific connection between Google and the customer.
"""
@classmethod
def Args(cls, parser):
_ArgsCommon(cls, parser, support_labels=True)
def Run(self, args):
self._DoRun(args, support_labels=True)

View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 creating or manipulating wire groups."""
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 WireGroups(base.Group):
"""Create or manipulate wire groups."""
WireGroups.detailed_help = {
'DESCRIPTION': """
Create or manipulate wire groups.
""",
}

View File

@@ -0,0 +1,157 @@
# -*- 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 adding endpoints to a wire group."""
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.interconnects.wire_groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.command_lib.compute.interconnects.wire_groups import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to add endpoints to a wire group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To add an endpoint to a wire group, run:
$ {command} example-wg \
--cross-site-network=example-csn \
--endpoint-label=endpoint-1
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class AddEndpoint(base.UpdateCommand):
"""Add endpoint to a Compute Engine wire group.
*{command}* adds endpoint to a Compute Engine wire group.
"""
# Framework override.
detailed_help = _DETAILED_HELP
WIRE_GROUP_ARG = None
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
cls.WIRE_GROUP_ARG = flags.WireGroupArgument(plural=False)
cls.WIRE_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.AddEndpointLabel(parser)
def Collection(self):
return 'compute.wireGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.WIRE_GROUP_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL,
additional_params={'crossSiteNetwork': args.cross_site_network},
)
project = properties.VALUES.core.project.GetOrFail()
self._messages = holder.client.messages
wire_group = client.WireGroup(
ref=ref,
project=project,
cross_site_network=args.cross_site_network,
compute_client=holder.client,
resources=holder.resources,
)
endpoint_label = args.endpoint_label
endpoints = wire_group.Describe().endpoints
endpoints_map = convert_endpoints_to_dict(endpoints)
endpoints_map[endpoint_label] = holder.client.messages.WireGroupEndpoint()
endpoints = _build_endpoint_messages(self._messages, endpoints_map)
return wire_group.Patch(
endpoints=endpoints,
)
def convert_endpoints_to_dict(endpoints):
"""Extracts the key,value pairs from the additionalProperties attribute.
Creates a python dict to be able to pass them into the client.
Args:
endpoints: the list of additionalProperties messages
Returns:
Python dictionary containing the key value pairs.
"""
endpoints_map = {}
if not endpoints or not endpoints.additionalProperties:
return endpoints_map
for endpoint_property in endpoints.additionalProperties:
key, value = endpoint_property.key, endpoint_property.value
endpoints_map[key] = value
return endpoints_map
def _build_endpoint_messages(messages, endpoints_map):
"""Builds a WireGroup.EndpointValue message.
This is so we can re-assign them to the additionalProperties attribute on
the WireGroup.EndpointsValue message.
Args:
messages: the messages module
endpoints_map: map of endpoints with label as the key and the
endpoint message as the value
Returns:
WireGroup.EndpointsValue message
"""
endpoint_properties_list = []
for endpoint_label, endpoints_message in endpoints_map.items():
endpoint_properties_list.append(
messages.WireGroup.EndpointsValue.AdditionalProperty(
key=endpoint_label,
value=endpoints_message,
)
)
return messages.WireGroup.EndpointsValue(
additionalProperties=endpoint_properties_list
)

View File

@@ -0,0 +1,274 @@
# -*- 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 adding interconnects to a wire group."""
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.interconnects.wire_groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.interconnects import flags as interconnect_flags
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.command_lib.compute.interconnects.wire_groups import flags
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to add interconnects to a wire group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To add an interconnect to a wire group, run:
$ {command} example-wg \
--cross-site-network=example-csn \
--endpoint-label=endpoint-1 \
--interconnect-label=interconnect-1 \
--interconnect=example-interconnect \
--vlan-tags=111
""",
}
class InvalidEndpointError(exceptions.Error):
"""Raised when the endpoint label does not exist."""
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class AddInterconnect(base.UpdateCommand):
"""Add interconnect to a Compute Engine wire group.
*{command}* adds interconnect to a Compute Engine wire group.
"""
# Framework override.
detailed_help = _DETAILED_HELP
WIRE_GROUP_ARG = None
CROSS_SITE_NETWORK_ARG = None
INTERCONNECT_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
cls.INTERCONNECT_ARG = (
interconnect_flags.InterconnectArgumentForOtherResource(
'The interconnect for the wire group endpoint.'
)
)
cls.WIRE_GROUP_ARG = flags.WireGroupArgument(plural=False)
cls.WIRE_GROUP_ARG.AddArgument(parser, operation_type='update')
cls.INTERCONNECT_ARG.AddArgument(parser)
flags.AddEndpointLabel(parser)
flags.AddInterconnectLabel(parser)
flags.AddVlanTags(parser)
def Collection(self):
return 'compute.wireGroups'
def Run(self, args):
"""Runs the add-interconnect command.
Modifies the existing endpoints and their interconnects. We need to break
down the endpoints and interconnects to make it easier to add or update the
interconnects. Since they are nested resources of a WireGroup, it can get
tricky to do modifications.
Args:
args: Object containing CLI parameter values
Returns:
Result of running the request.
Raises:
InvalidEndpointError: If the endpoint does not exist.
"""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.WIRE_GROUP_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL,
additional_params={'crossSiteNetwork': args.cross_site_network},
)
project = properties.VALUES.core.project.GetOrFail()
self._messages = holder.client.messages
wire_group = client.WireGroup(
ref=ref,
project=project,
cross_site_network=args.cross_site_network,
compute_client=holder.client,
resources=holder.resources,
)
endpoint_label = args.endpoint_label
interconnect_label = args.interconnect_label
vlan_tags = args.vlan_tags.split(',')
endpoints = wire_group.Describe().endpoints
interconnect_ref = self.INTERCONNECT_ARG.ResolveAsResource(
args, holder.resources)
# Convert the endpoints into a map for easier access to the interconnets.
endpoints_map = _convert_endpoints_to_dict(endpoints)
if endpoint_label not in endpoints_map:
raise InvalidEndpointError(
'Not a valid endpoint. Found the following endpoints: '
+ ', '.join(endpoints_map.keys())
)
interconnects = endpoints_map[endpoint_label].interconnects
# Convert the interconnects into a map for easier access to the
# attributes.
interconnects_map = _convert_interconnects_to_dict(interconnects)
# Create a new interconnect message and assign it to the corresponding
# label in the map.
interconnects_map[interconnect_label] = (
holder.client.messages.WireGroupEndpointInterconnect(
interconnect=interconnect_ref.SelfLink(),
vlanTags=[int(vlan_tag) for vlan_tag in vlan_tags],
)
)
# Rebuild the Interconnect messages
interconnects = _build_interconnect_messages(
self._messages, interconnects_map
)
endpoints_map[endpoint_label] = self._messages.WireGroupEndpoint(
interconnects=interconnects
)
endpoints = _build_endpoint_messages(self._messages, endpoints_map)
return wire_group.Patch(
endpoints=endpoints,
)
def _convert_interconnects_to_dict(interconnects):
"""Extracts key value pairs from additionalProperties attribute.
Creates a dict to be able to pass them into the client.
Args:
interconnects: the list of interconnect additionalProperties messages
Returns:
dictionary containing key value pairs
"""
interconnects_map = {}
if not interconnects or not interconnects.additionalProperties:
return interconnects_map
for interconnect_property in interconnects.additionalProperties:
key, value = interconnect_property.key, interconnect_property.value
interconnects_map[key] = value
return interconnects_map
def _convert_endpoints_to_dict(endpoints):
"""Extracts the key,value pairs from the additionalProperties attribute.
Creates a python dict to be able to pass them into the client.
Args:
endpoints: the list of additionalProperties messages
Returns:
Python dictionary containing the key value pairs.
"""
endpoints_map = {}
if not endpoints or not endpoints.additionalProperties:
return endpoints_map
for endpoint_property in endpoints.additionalProperties:
key, value = endpoint_property.key, endpoint_property.value
endpoints_map[key] = value
return endpoints_map
def _build_interconnect_messages(messages, interconnects_map):
"""Builds a WireGroupEndpoint.InterconnectsValue message.
Args:
messages: the messages module
interconnects_map: map of interconnects with label as the key and the
interconnect message as the value
Returns:
WireGroupEndpoint.InterconnectsValue message
"""
interconnect_properties_list = []
for (interconnect_label, interconnect_message) in interconnects_map.items():
interconnect_properties_list.append(
messages.WireGroupEndpoint.InterconnectsValue.AdditionalProperty(
key=interconnect_label,
value=interconnect_message,
)
)
return messages.WireGroupEndpoint.InterconnectsValue(
additionalProperties=interconnect_properties_list
)
def _build_endpoint_messages(messages, endpoints_map):
"""Builds a WireGroup.EndpointValue message.
This is so we can re-assign them to the additionalProperties attribute on
the WireGroup.EndpointsValue message.
Args:
messages: the messages module
endpoints_map: map of endpoints with label as the key and the
endpoint message as the value
Returns:
WireGroup.EndpointsValue message
"""
endpoint_properties_list = []
for (endpoint_label, endpoints_message) in endpoints_map.items():
endpoint_properties_list.append(
messages.WireGroup.EndpointsValue.AdditionalProperty(
key=endpoint_label,
value=endpoints_message,
)
)
return messages.WireGroup.EndpointsValue(
additionalProperties=endpoint_properties_list
)

View File

@@ -0,0 +1,136 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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 wire groups."""
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.interconnects.wire_groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.command_lib.compute.interconnects.wire_groups import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to create wire groups. A wire group represents a
group of redundant wires between interconnects in two different metros.
Each WireGroup belongs to a CrossSiteNetwork.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To create a wire group, run:
$ {command} example-wg \
--cross-site-network=example-csn
--bandwidth-unmetered=1
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a Compute Engine wire group.
*{command}* is used to create wire groups. A wire group represents a
group of redundant wires between interconnects in two different metros.
Each WireGroup belongs to a CrossSiteNetwork.
"""
# Framework override.
detailed_help = _DETAILED_HELP
WIRE_GROUP_ARG = None
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
cls.WIRE_GROUP_ARG = flags.WireGroupArgument(plural=False)
cls.WIRE_GROUP_ARG.AddArgument(parser, operation_type='create')
flags.AddDescription(parser)
flags.AddBandwidthUnmetered(parser)
flags.AddBandwidthAllocation(parser)
flags.AddFaultResponse(parser)
flags.AddAdminEnabled(parser)
flags.AddValidateOnly(parser)
def Collection(self):
return 'compute.wireGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.WIRE_GROUP_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL,
additional_params={'crossSiteNetwork': args.cross_site_network},
)
project = properties.VALUES.core.project.GetOrFail()
wire_group = client.WireGroup(
ref, project, args.cross_site_network, compute_client=holder.client
)
return wire_group.Create(
description=args.description,
# Need to rename type as it conflicts with python built in type()
wire_group_type=getattr(args, 'type', None),
bandwidth_unmetered=args.bandwidth_unmetered,
bandwidth_metered=getattr(args, 'bandwidth_metered', None),
fault_response=args.fault_response,
admin_enabled=args.admin_enabled,
network_service_class=getattr(args, 'network_service_class', None),
bandwidth_allocation=getattr(args, 'bandwidth_allocation', None),
validate_only=args.validate_only,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a Compute Engine wire group."""
@classmethod
def Args(cls, parser):
super().Args(parser)
flags.AddType(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Create a Compute Engine wire group.
*{command}* is used to create wire groups. A wire group represents a
group of redundant wires between interconnects in two different metros.
Each WireGroup belongs to a CrossSiteNetwork.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
flags.AddBandwidthMetered(parser)
flags.AddNetworkServiceClass(parser)

View File

@@ -0,0 +1,95 @@
# -*- 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 deleting cross site 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.api_lib.compute.interconnects.wire_groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.command_lib.compute.interconnects.wire_groups import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to delete wire groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To delete a wire group, run:
$ {command} example-wg --cross-site-network=example-csn
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete Compute Engine wire groups.
*{command}* deletes Compute Engine wire groups.
"""
# Framework override.
detailed_help = _DETAILED_HELP
WIRE_GROUPS_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
cls.WIRE_GROUPS_ARG = flags.WireGroupArgument(plural=True)
cls.WIRE_GROUPS_ARG.AddArgument(parser, operation_type='delete')
def Collection(self):
return 'compute.wireGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.WIRE_GROUPS_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL,
additional_params={'crossSiteNetwork': args.cross_site_network},
)
project = properties.VALUES.core.project.GetOrFail()
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
wire_group = client.WireGroup(
ref,
project=project,
cross_site_network=args.cross_site_network,
compute_client=holder.client,
)
requests.extend(wire_group.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)

View File

@@ -0,0 +1,86 @@
# -*- 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 describing wire groups."""
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.interconnects.wire_groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.command_lib.compute.interconnects.wire_groups import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to describe a wire group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To describe a wire group, run:
$ {command} example-wg --cross-site-network=example-csn
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine wire group.
*{command}* displays all data associated with Compute Engine
wire group in a project.
"""
# Framework override.
detailed_help = _DETAILED_HELP
WIRE_GROUP_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
cls.WIRE_GROUP_ARG = flags.WireGroupArgument(plural=False)
cls.WIRE_GROUP_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.WIRE_GROUP_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL,
additional_params={'crossSiteNetwork': args.cross_site_network},
)
project = properties.VALUES.core.project.GetOrFail()
wire_group = client.WireGroup(
ref,
project=project,
cross_site_network=args.cross_site_network,
compute_client=holder.client,
)
return wire_group.Describe()

View File

@@ -0,0 +1,142 @@
# -*- 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 listing wire groups."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from typing import Any
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.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.core import properties
from googlecloudsdk.core.resource import resource_projection_spec
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class List(base.ListCommand):
"""List wire groups."""
# Framework override.
detailed_help = base_classes.GetGlobalListerHelp('wire groups')
CROSS_SITE_NETWORK_ARG = None
@classmethod
def _SetDisplayInfoFormat(cls, parser):
parser.display_info.AddFormat("""
table(
name,
description,
crossSiteNetwork,
wireProperties.bandwidthUnmetered,
wireProperties.faultResponse,
adminEnabled
)
""")
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
cls._SetDisplayInfoFormat(parser)
def Run(self, args: Any):
"""Run the list command.
Args:
args: The arguments of the command.
Returns:
Result of wire groups list requests.
"""
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.ComputeWireGroupsListRequest(
project=project,
crossSiteNetwork=args.cross_site_network,
filter=filter_expr,
)
return list_pager.YieldFromList(
client.wireGroups,
request,
field='items',
limit=args.limit,
batch_size=None,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ListBeta(List):
"""List wire groups."""
@classmethod
def _SetDisplayInfoFormat(cls, parser):
parser.display_info.AddFormat("""
table(
name,
description,
crossSiteNetwork,
wireGroupProperties.type,
wireProperties.bandwidthUnmetered,
wireProperties.faultResponse,
adminEnabled
)
""")
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListAlpha(ListBeta):
"""List wire groups."""
@classmethod
def _SetDisplayInfoFormat(cls, parser):
parser.display_info.AddFormat("""
table(
name,
description,
crossSiteNetwork,
wireGroupProperties.type,
wireProperties.bandwidthUnmetered,
wireProperties.bandwidthMetered,
wireProperties.networkServiceClass,
wireProperties.bandwidthAllocation,
wireProperties.faultResponse,
adminEnabled
)
""")

View File

@@ -0,0 +1,168 @@
# -*- 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 removing endpoints from a wire-group."""
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.interconnects.wire_groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.command_lib.compute.interconnects.wire_groups import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to remove endpoints from a wire group.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To remove an endpoint from a wire group, run:
$ {command} example-wg \
--cross-site-network=example-csn \
--endpoint-label=endpoint-1
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RemoveEndpoint(base.UpdateCommand):
"""Remove endpoint from a Compute Engine wire group.
*{command}* remove endpoint from a Compute Engine wire group.
"""
# Framework override.
detailed_help = _DETAILED_HELP
WIRE_GROUP_ARG = None
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
cls.WIRE_GROUP_ARG = flags.WireGroupArgument(plural=False)
cls.WIRE_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.AddEndpointLabel(parser)
def Collection(self):
return 'compute.wireGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.WIRE_GROUP_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL,
additional_params={'crossSiteNetwork': args.cross_site_network},
)
project = properties.VALUES.core.project.GetOrFail()
self._messages = holder.client.messages
wire_group = client.WireGroup(
ref=ref,
project=project,
cross_site_network=args.cross_site_network,
compute_client=holder.client,
resources=holder.resources,
)
endpoint_label = args.endpoint_label
endpoints = wire_group.Describe().endpoints
endpoints_map = convert_endpoints_to_dict(endpoints)
if endpoint_label in endpoints_map:
del endpoints_map[endpoint_label]
endpoints = _build_endpoint_messages(self._messages, endpoints_map)
update_mask = None
if not endpoints:
# Pass in this value to let client know a change was made. Otherwise, it
# won't pick up the case where all endpoints have been deleted.
update_mask = ['endpoints']
return wire_group.Patch(
endpoints=endpoints,
update_mask=update_mask,
)
def convert_endpoints_to_dict(endpoints):
"""Extracts the key,value pairs from the additionalProperties attribute.
Creates a python dict to be able to pass them into the client.
Args:
endpoints: the list of additionalProperties messages
Returns:
Python dictionary containing the key value pairs.
"""
endpoints_map = {}
if not endpoints or not endpoints.additionalProperties:
return endpoints_map
for endpoint_property in endpoints.additionalProperties:
key, value = endpoint_property.key, endpoint_property.value
endpoints_map[key] = value
return endpoints_map
def _build_endpoint_messages(messages, endpoints_map):
"""Builds a WireGroup.EndpointValue message.
This is so we can re-assign them to the additionalProperties attribute on
the WireGroup.EndpointsValue message.
Args:
messages: the messages module
endpoints_map: map of endpoints with label as the key and the
endpoint message as the value
Returns:
WireGroup.EndpointsValue message
"""
if not endpoints_map:
return None
endpoint_properties_list = []
for (endpoint_label, endpoints_message) in endpoints_map.items():
endpoint_properties_list.append(
messages.WireGroup.EndpointsValue.AdditionalProperty(
key=endpoint_label,
value=endpoints_message,
)
)
return messages.WireGroup.EndpointsValue(
additionalProperties=endpoint_properties_list
)

View File

@@ -0,0 +1,249 @@
# -*- 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 adding interconnects to a wire group."""
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.interconnects.wire_groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.command_lib.compute.interconnects.wire_groups import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to remove interconnects from a wire group endpoint.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To remove an interconnect from a wire group endpoint, run:
$ {command} example-wg --cross-site-network=example-csn \
--endpoint-label=endpoint-1 \
--interconnect-label=example-interconnect
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RemoveInterconnect(base.UpdateCommand):
"""Remove interconnect from a wire group.
*{command}* removes interconnect from a wire group endpoint.
"""
# Framework override.
detailed_help = _DETAILED_HELP
WIRE_GROUP_ARG = None
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
cls.WIRE_GROUP_ARG = flags.WireGroupArgument(plural=False)
cls.WIRE_GROUP_ARG.AddArgument(parser, operation_type='update')
flags.AddEndpointLabel(parser)
flags.AddInterconnectLabel(parser)
def Collection(self):
return 'compute.wireGroups'
def Run(self, args):
"""Runs the remove-interconnect command.
Modifies the existing endpoints and their interconnects. We need to break
down the endpoints and interconnects to make it easier to add or update the
interconnects. Since they are nested resources of a WireGroup, it can get
tricky to do modifications.
Args:
args: Object containing CLI parameter values
Returns:
Result of running the request.
"""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.WIRE_GROUP_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL,
additional_params={'crossSiteNetwork': args.cross_site_network},
)
project = properties.VALUES.core.project.GetOrFail()
self._messages = holder.client.messages
wire_group = client.WireGroup(
ref=ref,
project=project,
cross_site_network=args.cross_site_network,
compute_client=holder.client,
resources=holder.resources,
)
endpoint_label = args.endpoint_label
interconnect_label = args.interconnect_label
endpoints = wire_group.Describe().endpoints
# Convert the endpoints into a map for easier access to the interconnets.
endpoints_map = _convert_endpoints_to_dict(endpoints)
if endpoint_label not in endpoints_map:
return AttributeError('Endpoint not found.')
if endpoint_label in endpoints_map:
interconnects = endpoints_map[endpoint_label].interconnects
# Convert the interconnects into a map for easier access to the
# attributes.
interconnects_map = _convert_interconnects_to_dict(interconnects)
# Delete interconnect from the map if it exists.
if interconnect_label in interconnects_map:
del interconnects_map[interconnect_label]
# Rebuild the Interconnect messages
interconnects = _build_interconnect_messages(
self._messages, interconnects_map
)
endpoints_map[endpoint_label] = self._messages.WireGroupEndpoint(
interconnects=interconnects
)
endpoints = _build_endpoint_messages(self._messages, endpoints_map)
return wire_group.Patch(
endpoints=endpoints,
)
def _convert_interconnects_to_dict(interconnects):
"""Extracts key value pairs from additionalProperties attribute.
Creates a dict to be able to pass them into the client.
Args:
interconnects: the list of interconnect additionalProperties messages
Returns:
dictionary containing key value pairs
"""
interconnects_map = {}
if not interconnects or not interconnects.additionalProperties:
return interconnects_map
for interconnect_property in interconnects.additionalProperties:
key, value = interconnect_property.key, interconnect_property.value
interconnects_map[key] = value
return interconnects_map
def _convert_endpoints_to_dict(endpoints):
"""Extracts the key,value pairs from the additionalProperties attribute.
Creates a python dict to be able to pass them into the client.
Args:
endpoints: the list of additionalProperties messages
Returns:
Python dictionary containing the key value pairs.
"""
endpoints_map = {}
if not endpoints or not endpoints.additionalProperties:
return endpoints_map
for endpoint_property in endpoints.additionalProperties:
key, value = endpoint_property.key, endpoint_property.value
endpoints_map[key] = value
return endpoints_map
def _build_interconnect_messages(messages, interconnects_map):
"""Builds a WireGroupEndpoint.InterconnectsValue message.
Args:
messages: the messages module
interconnects_map: map of interconnects with label as the key and the
interconnect message as the value
Returns:
WireGroupEndpoint.InterconnectsValue message
"""
if not interconnects_map:
return None
interconnect_properties_list = []
for (interconnect_label, interconnect_message) in interconnects_map.items():
interconnect_properties_list.append(
messages.WireGroupEndpoint.InterconnectsValue.AdditionalProperty(
key=interconnect_label,
value=interconnect_message,
)
)
return messages.WireGroupEndpoint.InterconnectsValue(
additionalProperties=interconnect_properties_list
)
def _build_endpoint_messages(messages, endpoints_map):
"""Builds a WireGroup.EndpointValue message.
This is so we can re-assign them to the additionalProperties attribute on
the WireGroup.EndpointsValue message.
Args:
messages: the messages module
endpoints_map: map of endpoints with label as the key and the
endpoint message as the value
Returns:
WireGroup.EndpointsValue message
"""
if not endpoints_map:
return None
endpoint_properties_list = []
for (endpoint_label, endpoints_message) in endpoints_map.items():
endpoint_properties_list.append(
messages.WireGroup.EndpointsValue.AdditionalProperty(
key=endpoint_label,
value=endpoints_message,
)
)
return messages.WireGroup.EndpointsValue(
additionalProperties=endpoint_properties_list
)

View File

@@ -0,0 +1,151 @@
# -*- 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 updating wire groups."""
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.interconnects.wire_groups import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.interconnects.cross_site_networks import flags as cross_site_network_flags
from googlecloudsdk.command_lib.compute.interconnects.wire_groups import flags
from googlecloudsdk.core import properties
_DETAILED_HELP = {
'DESCRIPTION': """\
*{command}* is used to update wire groups.
For an example, refer to the *EXAMPLES* section below.
""",
'EXAMPLES': """\
To disable a wire group, run:
$ {command} example-wg --cross-site-network=example-csn --no-admin-enabled
To change a wire group's unmetered bandwidth, run:
$ {command} example-wg --cross-site-network=example-csn --bandwidth-unmetered=5
To enable automatic failure detection for a wire group, run:
$ {command} example-wg --cross-site-network=example-csn --fault-response=DISABLE_PORT
To enable bandwidth sharing for a wire group, run:
$ {command} example-wg --cross-site-network=example-csn --bandwidth-allocation=SHARED_WITH_WIRE_GROUP
To update a wire group's description, run:
$ {command} example-wg --cross-site-network=example-csn --description="new description"
""",
}
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Compute Engine wire group.
*{command}* is used to update wire groups. A wire group represents a group of
redundant wires.
"""
# Framework override.
detailed_help = _DETAILED_HELP
WIRE_GROUP_ARG = None
CROSS_SITE_NETWORK_ARG = None
@classmethod
def Args(cls, parser):
cls.WIRE_GROUP_ARG = flags.WireGroupArgument(plural=False)
cls.WIRE_GROUP_ARG.AddArgument(parser, operation_type='update')
cls.CROSS_SITE_NETWORK_ARG = (
cross_site_network_flags.CrossSiteNetworkArgumentForOtherResource()
)
cls.CROSS_SITE_NETWORK_ARG.AddArgument(parser)
flags.AddDescription(parser)
flags.AddBandwidthUnmetered(parser, required=False)
flags.AddBandwidthAllocation(parser, required=False)
flags.AddFaultResponse(parser)
flags.AddAdminEnabled(parser, update=True)
flags.AddValidateOnly(parser)
def Collection(self):
return 'compute.wireGroups'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.WIRE_GROUP_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL,
additional_params={'crossSiteNetwork': args.cross_site_network},
)
project = properties.VALUES.core.project.GetOrFail()
wire_group = client.WireGroup(
ref,
project,
args.cross_site_network,
compute_client=holder.client
)
return wire_group.Patch(
description=args.description,
wire_group_type=getattr(args, 'type', None),
bandwidth_unmetered=args.bandwidth_unmetered,
bandwidth_metered=getattr(args, 'bandwidth_metered', None),
fault_response=args.fault_response,
admin_enabled=args.admin_enabled,
network_service_class=getattr(args, 'network_service_class', None),
bandwidth_allocation=getattr(args, 'bandwidth_allocation', None),
validate_only=args.validate_only,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Compute Engine wire group.
*{command}* is used to update wire groups. A wire group represents a group of
redundant wires.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
flags.AddType(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Compute Engine wire group.
*{command}* is used to update wire groups. A wire group represents a group of
redundant wires.
"""
@classmethod
def Args(cls, parser):
super().Args(parser)
flags.AddBandwidthMetered(parser)
flags.AddNetworkServiceClass(parser)