File: //snap/google-cloud-cli/396/lib/surface/compute/forwarding_rules/update.py
# -*- 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 to update forwarding-rules."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.protorpclite import messages as message_proto
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import constants
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions as calliope_exceptions
from googlecloudsdk.command_lib.compute import flags as compute_flags
from googlecloudsdk.command_lib.compute.forwarding_rules import exceptions as fw_exceptions
from googlecloudsdk.command_lib.compute.forwarding_rules import flags
from googlecloudsdk.command_lib.util.args import labels_util
def _Args(
cls,
parser,
support_network_tier,
):
"""Add the flags to create a forwarding rule."""
cls.FORWARDING_RULE_ARG = flags.ForwardingRuleArgument()
cls.FORWARDING_RULE_ARG.AddArgument(parser)
labels_util.AddUpdateLabelsFlags(parser)
if support_network_tier:
flags.AddNetworkTier(parser, for_update=True)
flags.AddSourceIpRanges(parser)
flags.AddAllowGlobalAccess(parser)
flags.AddAllowPscGlobalAccess(parser)
flags.AddExternalMigration(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class UpdateGA(base.UpdateCommand):
"""Update a Compute Engine forwarding rule."""
FORWARDING_RULE_ARG = None
_support_network_tier = False
@classmethod
def Args(cls, parser):
_Args(
cls,
parser,
support_network_tier=cls._support_network_tier,
)
def _CreateGlobalSetLabelsRequest(self, messages, forwarding_rule_ref,
forwarding_rule, replacement):
return messages.ComputeGlobalForwardingRulesSetLabelsRequest(
project=forwarding_rule_ref.project,
resource=forwarding_rule_ref.Name(),
globalSetLabelsRequest=messages.GlobalSetLabelsRequest(
labelFingerprint=forwarding_rule.labelFingerprint,
labels=replacement))
def _CreateRegionalSetLabelsRequest(self, messages, forwarding_rule_ref,
forwarding_rule, replacement):
return messages.ComputeForwardingRulesSetLabelsRequest(
project=forwarding_rule_ref.project,
resource=forwarding_rule_ref.Name(),
region=forwarding_rule_ref.region,
regionSetLabelsRequest=messages.RegionSetLabelsRequest(
labelFingerprint=forwarding_rule.labelFingerprint,
labels=replacement))
def ConstructNetworkTier(self, messages, network_tier):
if network_tier:
network_tier = network_tier.upper()
if network_tier in constants.NETWORK_TIER_CHOICES_FOR_INSTANCE:
return messages.ForwardingRule.NetworkTierValueValuesEnum(network_tier)
else:
raise calliope_exceptions.InvalidArgumentException(
'--network-tier',
'Invalid network tier [{tier}]'.format(tier=network_tier))
else:
return
def _HasNextTierChange(self, args):
return self._support_network_tier and args.network_tier is not None
def _HasSourceIpRangeChange(self, args):
return args.IsSpecified('source_ip_ranges')
def _HasGlobalAccessChange(self, args):
return args.IsSpecified('allow_global_access')
def _HasPscGlobalAccessChange(self, args):
return args.IsSpecified('allow_psc_global_access')
def _HasExternalMigrationChange(self, args):
return (
args.IsSpecified(
'external_managed_backend_bucket_migration_testing_percentage'
)
or args.IsSpecified('external_managed_backend_bucket_migration_state')
or args.IsSpecified(
'clear_external_managed_backend_bucket_migration_state'
)
or args.IsSpecified('load_balancing_scheme')
)
def Modify(
self, messages: message_proto, args, existing, cleared_fields
) -> message_proto.Message:
"""Returns a modified forwarding rule message and included fields."""
has_change = False
forwarding_rule = messages.ForwardingRule(name=existing.name)
if self._HasNextTierChange(args):
forwarding_rule.networkTier = self.ConstructNetworkTier(
messages, args.network_tier)
has_change = True
if self._HasSourceIpRangeChange(args):
forwarding_rule.sourceIpRanges = args.source_ip_ranges
has_change = True
if self._HasGlobalAccessChange(args):
forwarding_rule.allowGlobalAccess = args.allow_global_access
has_change = True
if self._HasPscGlobalAccessChange(args):
forwarding_rule.allowPscGlobalAccess = args.allow_psc_global_access
forwarding_rule.fingerprint = existing.fingerprint
has_change = True
if args.IsSpecified('external_managed_backend_bucket_migration_state'):
forwarding_rule.externalManagedBackendBucketMigrationState = messages.ForwardingRule.ExternalManagedBackendBucketMigrationStateValueValuesEnum(
args.external_managed_backend_bucket_migration_state
)
has_change = True
if args.IsSpecified(
'external_managed_backend_bucket_migration_testing_percentage'
):
forwarding_rule.externalManagedBackendBucketMigrationTestingPercentage = (
args.external_managed_backend_bucket_migration_testing_percentage
)
has_change = True
if args.IsSpecified('load_balancing_scheme'):
forwarding_rule.loadBalancingScheme = (
messages.ForwardingRule.LoadBalancingSchemeValueValuesEnum(
args.load_balancing_scheme
)
)
has_change = True
if args.IsSpecified(
'clear_external_managed_backend_bucket_migration_state'
):
cleared_fields.append('externalManagedBackendBucketMigrationState')
cleared_fields.append(
'externalManagedBackendBucketMigrationTestingPercentage'
)
has_change = True
if not has_change:
return None
return forwarding_rule
def Run(self, args):
"""Returns a list of requests necessary for updating forwarding rules."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client.apitools_client
messages = holder.client.messages
forwarding_rule_ref = self.FORWARDING_RULE_ARG.ResolveAsResource(
args,
holder.resources,
scope_lister=compute_flags.GetDefaultScopeLister(holder.client))
labels_diff = labels_util.Diff.FromUpdateArgs(args)
has_labels_updates = labels_diff.MayHaveUpdates()
has_change = any([
has_labels_updates,
self._HasNextTierChange(args),
self._HasGlobalAccessChange(args),
self._HasPscGlobalAccessChange(args),
self._HasSourceIpRangeChange(args),
self._HasExternalMigrationChange(args),
])
if not has_change:
raise fw_exceptions.ArgumentError(
'At least one property must be specified.')
# Get replacement.
if forwarding_rule_ref.Collection() == 'compute.globalForwardingRules':
get_request = (client.globalForwardingRules, 'Get',
messages.ComputeGlobalForwardingRulesGetRequest(
forwardingRule=forwarding_rule_ref.Name(),
project=forwarding_rule_ref.project))
labels_value = messages.GlobalSetLabelsRequest.LabelsValue
else:
get_request = (client.forwardingRules, 'Get',
messages.ComputeForwardingRulesGetRequest(
forwardingRule=forwarding_rule_ref.Name(),
project=forwarding_rule_ref.project,
region=forwarding_rule_ref.region))
labels_value = messages.RegionSetLabelsRequest.LabelsValue
objects = holder.client.MakeRequests([get_request])
forwarding_rule = objects[0]
cleared_fields = []
forwarding_rule_replacement = self.Modify(
messages, args, forwarding_rule, cleared_fields
)
label_update = labels_diff.Apply(labels_value, forwarding_rule.labels)
# Create requests.
requests = []
if forwarding_rule_ref.Collection() == 'compute.globalForwardingRules':
if forwarding_rule_replacement:
request = messages.ComputeGlobalForwardingRulesPatchRequest(
forwardingRule=forwarding_rule_ref.Name(),
forwardingRuleResource=forwarding_rule_replacement,
project=forwarding_rule_ref.project)
requests.append((client.globalForwardingRules, 'Patch', request))
if label_update.needs_update:
request = self._CreateGlobalSetLabelsRequest(messages,
forwarding_rule_ref,
forwarding_rule,
label_update.labels)
requests.append((client.globalForwardingRules, 'SetLabels', request))
else:
if forwarding_rule_replacement:
request = messages.ComputeForwardingRulesPatchRequest(
forwardingRule=forwarding_rule_ref.Name(),
forwardingRuleResource=forwarding_rule_replacement,
project=forwarding_rule_ref.project,
region=forwarding_rule_ref.region)
requests.append((client.forwardingRules, 'Patch', request))
if label_update.needs_update:
request = self._CreateRegionalSetLabelsRequest(messages,
forwarding_rule_ref,
forwarding_rule,
label_update.labels)
requests.append((client.forwardingRules, 'SetLabels', request))
with client.IncludeFields(cleared_fields):
return holder.client.MakeRequests(requests)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(UpdateGA):
"""Update a Compute Engine forwarding rule."""
_support_network_tier = False
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Compute Engine forwarding rule."""
_support_network_tier = True
UpdateGA.detailed_help = {
'brief':
'Update a Compute Engine forwarding rule.',
'DESCRIPTION':
"""\
*{command}* updates global access for a Compute Engine forwarding rule.
""",
'EXAMPLES':
"""\
To update the forwarding rule to allow global access, run:
$ {command} example-fr --allow-global-access --region=us-central1
To add/update labels ``k0'' and ``k1'' and remove labels with key ``k3'',
run:
$ {command} example-fr --region=us-central1 \
--update-labels=k0=value1,k1=value2 --remove-labels=k3
Labels can be used to identify the forwarding rule and to filter them as
in
$ {parent_command} list --filter='labels.k1:value2'
To list existing labels, run:
$ {parent_command} describe example-fr --format="default(labels)"
"""
}
UpdateBeta.detailed_help = {
'brief':
'Update a Compute Engine forwarding rule.',
'DESCRIPTION':
"""\
*{command}* updates labels and global access for a Compute
Engine forwarding rule.
""",
'EXAMPLES':
"""\
To update the forwarding rule to allow global access, run:
$ {command} example-fr --allow-global-access --region=us-central1
To add/update labels ``k0'' and ``k1'' and remove labels with key ``k3'',
run:
$ {command} example-fr --region=us-central1 \
--update-labels=k0=value1,k1=value2 --remove-labels=k3
Labels can be used to identify the forwarding rule and to filter them as
in
$ {parent_command} list --filter='labels.k1:value2'
To list existing labels, run:
$ {parent_command} describe example-fr --format="default(labels)"
"""
}
UpdateAlpha.detailed_help = {
'brief':
'Update a Compute Engine forwarding rule.',
'DESCRIPTION':
"""\
*{command}* updates labels, global access and network tier for a Compute
Engine forwarding rule.
""",
'EXAMPLES':
"""\
To update the forwarding rule to allow global access, run:
$ {command} example-fr --allow-global-access --region=us-central1
To add/update labels ``k0'' and ``k1'' and remove labels with key ``k3''
, run:
$ {command} example-fr --region=us-central1 \
--update-labels=k0=value1,k1=value2 --remove-labels=k3
Labels can be used to identify the forwarding rule and to filter them as
in
$ {parent_command} list --filter='labels.k1:value2'
To list existing labels, run:
$ {parent_command} describe example-fr --format="default(labels)"
"""
}