feat: Add new gcloud commands, API clients, and third-party libraries across various services.

This commit is contained in:
2026-01-01 20:26:35 +01:00
parent 5e23cbece0
commit a19e592eb7
25221 changed files with 8324611 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*- #
# Copyright 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 security policies."""
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 SecurityPolicies(base.Group):
"""Read and manipulate Cloud Armor security policies."""
pass
SecurityPolicies.category = base.LOAD_BALANCING_CATEGORY
SecurityPolicies.detailed_help = {
'DESCRIPTION': """
Read and manipulate Cloud Armor security policies.
Security policies are used to control access to Google Cloud
HTTP/HTTPS load balancers.
For more information about security policies, see
[Security policies for HTTPS load balancing](https://cloud.google.com/armor/docs/security-policy-concepts#security_policies_for_https_load_balancing).
See also: [Security policies API](https://cloud.google.com/compute/docs/reference/rest/v1/securityPolicies).
""",
}

View File

@@ -0,0 +1,225 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for adding layer7 ddos defense threshold config to security policies."""
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.security_policies import client
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.security_policies import flags
from googlecloudsdk.command_lib.compute.security_policies import security_policies_utils
class AddLayer7DdosDefenseThresholdConfigHelper(object):
r"""Add a layer7 ddos defense threshold config to a Compute Engine security policy.
*{command}* is used to add layer7 ddos defense threshold configs to security policies.
## EXAMPLES
To add a layer7 ddos defense threshold config run the following command:
$ {command} NAME \
--threshold-config-name=my-threshold-config-name \
--auto-deploy-load-threshold=0.7 \
--auto-deploy-confidence-threshold=0.8 \
--auto-deploy-impacted-baseline-threshold=0.1 \
--auto-deploy-expiration-sec=4800
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser, support_granularity_config):
"""Adds the arguments for the command."""
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='update')
parser.add_argument(
'--threshold-config-name',
required=True,
help='The name for the threshold config.',
)
parser.add_argument(
'--auto-deploy-load-threshold',
type=float,
required=False,
help=(
"The threshold on backend's load, over which auto-deploy takes"
' action.'
),
)
parser.add_argument(
'--auto-deploy-confidence-threshold',
type=float,
required=False,
help=(
'The threshold of the confidence of an identified attack, over'
' which auto-deploy takes action.'
),
)
parser.add_argument(
'--auto-deploy-impacted-baseline-threshold',
type=float,
required=False,
help=(
'The threshold on the estimated impact to the baseline traffic of a'
' suggested mitigation, below which auto-deploy takes action.'
),
)
parser.add_argument(
'--auto-deploy-expiration-sec',
type=int,
required=False,
help='The duration of actions, if any, taken by auto-deploy.',
)
if support_granularity_config:
parser.add_argument(
'--detection-load-threshold',
type=float,
required=False,
help=(
"The threshold on backend's load, over which adaptive protection"
' detects an attack.'
),
)
parser.add_argument(
'--detection-absolute-qps',
type=float,
required=False,
help=(
'The absolute QPS of the incoming traffic, over which adaptive'
' protection detects an attack.'
),
)
parser.add_argument(
'--detection-relative-to-baseline-qps',
type=float,
required=False,
help=(
'The QPS of the incoming traffic relative to the average baseline'
' QPS, over which adaptive protection detects an attack.'
),
)
parser.add_argument(
'--traffic-granularity-configs',
type=arg_parsers.ArgList(
max_length=2,
custom_delim_char=';',
element_type=arg_parsers.ArgDict(
min_length=2,
max_length=3,
spec={
'type': str,
'value': str,
'enableEachUniqueValue': bool,
},
required_keys=['type'],
),
),
required=False,
metavar='type=TYPE[,value=VALUE][,enableEachUniqueValue=ENABLE_EACH_UNIQUE_VALUE];...',
help=(
'Specify up to 2 configs matching a specifc type/value of'
' traffic.'
),
)
@classmethod
def Run(cls, release_track, args, support_granularity_config):
"""Runs the command."""
holder = base_classes.ComputeApiHolder(release_track)
ref = cls.SECURITY_POLICY_ARG.ResolveAsResource(args, holder.resources)
security_policy = client.SecurityPolicy(
ref=ref, compute_client=holder.client
)
existing_security_policy = security_policy.Describe()[0]
adaptive_protection_config = (
existing_security_policy.adaptiveProtectionConfig
)
if (
adaptive_protection_config is None
or adaptive_protection_config.layer7DdosDefenseConfig is None
or not adaptive_protection_config.layer7DdosDefenseConfig.enable
):
raise exceptions.InvalidArgumentException(
'--threshold-config-name',
'Must enable adaptive protection layer 7 ddos defense before adding a'
' threshold config',
)
threshold_config = (
security_policies_utils.CreateLayer7DdosDefenseThresholdConfig(
holder.client,
args,
support_granularity_config=support_granularity_config,
)
)
adaptive_protection_config.layer7DdosDefenseConfig.thresholdConfigs.append(
threshold_config
)
updated_security_policy = holder.client.messages.SecurityPolicy(
adaptiveProtectionConfig=adaptive_protection_config,
fingerprint=existing_security_policy.fingerprint,
)
return security_policy.Patch(security_policy=updated_security_policy)
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class AddLayer7DdosDefenseThresholdConfigGA(base.UpdateCommand):
r"""Add a layer7 ddos defense threshold config to a Compute Engine security policy.
*{command}* is used to add layer7 ddos defense threshold configs to security policies.
## EXAMPLES
To add a layer7 ddos defense threshold config run the following command:
$ {command} NAME \
--threshold-config-name=my-threshold-config-name \
--auto-deploy-load-threshold=0.7 \
--auto-deploy-confidence-threshold=0.8 \
--auto-deploy-impacted-baseline-threshold=0.1 \
--auto-deploy-expiration-sec=4800
--detection-load-threshold=0.4
--detection-absolute-qps=1000
--detection-relative-to-baseline-qps=2.0
--traffic-granularity-configs=type=HTTP_HEADER_HOST,value=www.my-test-host.com;type=HTTP_PATH,enableEachUniqueValue=true
"""
_support_granularity_config = True
@classmethod
def Args(cls, parser):
AddLayer7DdosDefenseThresholdConfigHelper.Args(
parser, support_granularity_config=cls._support_granularity_config
)
def Run(self, args):
return AddLayer7DdosDefenseThresholdConfigHelper.Run(
self.ReleaseTrack(),
args,
support_granularity_config=self._support_granularity_config,
)

View File

@@ -0,0 +1,107 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for adding user defined fields to security policies."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.security_policies import flags
from googlecloudsdk.command_lib.compute.security_policies import security_policies_utils
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class AddUserDefinedField(base.UpdateCommand):
r"""Add a user defined field to a Compute Engine security policy.
*{command}* is used to add user defined fields to security policies.
## EXAMPLES
To add a user defined field run this:
$ {command} SECURITY_POLICY \
--user-defined-field-name=my-field \
--base=ipv6 \
--offset=10 \
--size=3
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyRegionalArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='update')
parser.add_argument(
'--user-defined-field-name',
required=True,
help='The name for the user defined field.'
)
parser.add_argument(
'--base',
choices=['ipv4', 'ipv6', 'tcp', 'udp'],
required=True,
help='The base relative to which offset is measured.',
)
parser.add_argument(
'--offset',
type=int,
required=True,
help=(
'Offset of the first byte of the field (in network byte order)'
' relative to base.'
),
)
parser.add_argument(
'--size',
type=int,
required=True,
help='Size of the field in bytes. Valid values: 1-4.',
)
parser.add_argument(
'--mask',
help=(
'If specified, apply this mask (bitwise AND) to the field to ignore'
' bits before matching. Encoded as a hexadecimal number (starting '
'with "0x").'
),
)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(args, holder.resources)
security_policy = client.SecurityPolicy(
ref=ref, compute_client=holder.client
)
existing_security_policy = security_policy.Describe()[0]
user_defined_field = security_policies_utils.CreateUserDefinedField(
holder.client, args
)
user_defined_fields = existing_security_policy.userDefinedFields
user_defined_fields.append(user_defined_field)
updated_security_policy = holder.client.messages.SecurityPolicy(
userDefinedFields=user_defined_fields,
fingerprint=existing_security_policy.fingerprint,
)
return security_policy.Patch(security_policy=updated_security_policy)

View File

@@ -0,0 +1,303 @@
# -*- 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 security policies."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import os
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags
from googlecloudsdk.command_lib.compute.security_policies import security_policies_utils
from googlecloudsdk.core.util import files
import six
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
r"""Create a Compute Engine security policy.
*{command}* is used to create security policies. A security policy policy is a
set of rules that controls access to various resources.
## EXAMPLES
To create a security policy with a given type and description, run:
$ {command} my-policy \
--type=CLOUD_ARMOR_EDGE \
--description="policy description"
To create a security from an input file, run:
$ {command} my-policy \
--file-name=my-file-name
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='create')
group = parser.add_group(mutex=True, help='Creation options.')
group.add_argument(
'--type',
choices=['CLOUD_ARMOR', 'CLOUD_ARMOR_EDGE', 'CLOUD_ARMOR_NETWORK'],
type=lambda x: x.upper(),
metavar='SECURITY_POLICY_TYPE',
help=('The type indicates the intended use of the security policy.'))
group.add_argument(
'--file-name',
help=('The name of the JSON or YAML file to create a security policy '
'config from.'))
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to create the security policy config from. '
'Specify either yaml or json. Defaults to yaml if not specified. '
'Will be ignored if --file-name is not specified.'))
parser.add_argument(
'--description',
help=('An optional, textual description for the security policy.'))
parser.display_info.AddCacheUpdater(flags.GlobalSecurityPoliciesCompleter)
def Collection(self):
return 'compute.securityPolicies'
def _GetTemplateFromFile(self, args, messages):
if not os.path.exists(args.file_name):
raise exceptions.BadFileException('No such file [{0}]'.format(
args.file_name))
if os.path.isdir(args.file_name):
raise exceptions.BadFileException('[{0}] is a directory'.format(
args.file_name))
try:
with files.FileReader(args.file_name) as import_file:
if args.file_format == 'json':
return security_policies_utils.SecurityPolicyFromFile(
import_file, messages, 'json')
return security_policies_utils.SecurityPolicyFromFile(
import_file, messages, 'yaml')
except Exception as exp:
exp_msg = getattr(exp, 'message', six.text_type(exp))
msg = ('Unable to read security policy config from specified file '
'[{0}] because [{1}]'.format(args.file_name, exp_msg))
raise exceptions.BadFileException(msg)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
if args.file_name:
template = self._GetTemplateFromFile(args, holder.client.messages)
template.name = ref.Name()
else:
if args.IsSpecified('type'):
template = holder.client.messages.SecurityPolicy(
name=ref.Name(),
description=args.description,
type=holder.client.messages.SecurityPolicy.TypeValueValuesEnum(
args.type))
else:
template = holder.client.messages.SecurityPolicy(
name=ref.Name(), description=args.description)
return security_policy.Create(template)
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
r"""Create a Compute Engine security policy.
*{command}* is used to create security policies. A security policy policy is a
set of rules that controls access to various resources.
## EXAMPLES
To create a security policy with a given type and description, run:
$ {command} my-policy \
--type=CLOUD_ARMOR_EDGE \
--description="policy description"
To create a security from an input file, run:
$ {command} my-policy \
--file-name=my-file-name
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='create')
group = parser.add_group(mutex=True, help='Creation options.')
group.add_argument(
'--type',
choices=[
'CLOUD_ARMOR',
'CLOUD_ARMOR_EDGE',
'CLOUD_ARMOR_NETWORK',
'CLOUD_ARMOR_INTERNAL_SERVICE',
],
type=lambda x: x.upper(),
metavar='SECURITY_POLICY_TYPE',
help='The type indicates the intended use of the security policy.',
)
group.add_argument(
'--file-name',
help=('The name of the JSON or YAML file to create a security policy '
'config from.'))
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to create the security policy config from. '
'Specify either yaml or json. Defaults to yaml if not specified. '
'Will be ignored if --file-name is not specified.'))
parser.add_argument(
'--description',
help=('An optional, textual description for the security policy.'))
parser.display_info.AddCacheUpdater(flags.SecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
if args.file_name:
template = self._GetTemplateFromFile(args, holder.client.messages)
template.name = ref.Name()
else:
if args.type is not None:
template = holder.client.messages.SecurityPolicy(
name=ref.Name(),
description=args.description,
type=holder.client.messages.SecurityPolicy.TypeValueValuesEnum(
args.type))
else:
template = holder.client.messages.SecurityPolicy(
name=ref.Name(), description=args.description)
return security_policy.Create(template)
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(Create):
r"""Create a Compute Engine security policy.
*{command}* is used to create security policies. A security policy policy is a
set of rules that controls access to various resources.
## EXAMPLES
To create a security policy with a given type and description, run:
$ {command} my-policy \
--type=CLOUD_ARMOR_EDGE \
--description="policy description"
To create a security from an input file, run:
$ {command} my-policy \
--file-name=my-file-name
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='create')
group = parser.add_group(mutex=True, help='Creation options.')
group.add_argument(
'--type',
choices=[
'CLOUD_ARMOR', 'CLOUD_ARMOR_EDGE', 'CLOUD_ARMOR_NETWORK',
'CLOUD_ARMOR_INTERNAL_SERVICE'
],
type=lambda x: x.upper(),
metavar='SECURITY_POLICY_TYPE',
help=('The type indicates the intended use of the security policy.'))
group.add_argument(
'--file-name',
help=('The name of the JSON or YAML file to create a security policy '
'config from.'))
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to create the security policy config from. '
'Specify either yaml or json. Defaults to yaml if not specified. '
'Will be ignored if --file-name is not specified.'))
parser.add_argument(
'--description',
help=('An optional, textual description for the security policy.'))
parser.display_info.AddCacheUpdater(flags.SecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
if args.file_name:
template = self._GetTemplateFromFile(args, holder.client.messages)
template.name = ref.Name()
else:
if args.type is not None:
template = holder.client.messages.SecurityPolicy(
name=ref.Name(),
description=args.description,
type=holder.client.messages.SecurityPolicy.TypeValueValuesEnum(
args.type))
else:
template = holder.client.messages.SecurityPolicy(
name=ref.Name(), description=args.description)
return security_policy.Create(template)

View File

@@ -0,0 +1,143 @@
# -*- 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 security policies."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Delete(base.DeleteCommand):
"""Delete security policies.
*{command}* deletes Compute Engine security policies. Security
policies can only be deleted when no other resources (e.g.,
backend services) refer to them.
## EXAMPLES
To delete a security policy, run:
$ {command} my-policy
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument(
plural=True)
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(flags.GlobalSecurityPoliciesCompleter)
def Collection(self):
return 'compute.securityPolicies'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
requests.extend(security_policy.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DeleteBeta(base.DeleteCommand):
"""Delete security policies.
*{command}* deletes Compute Engine security policies. Security
policies can only be deleted when no other resources (e.g.,
backend services) refer to them.
## EXAMPLES
To delete a security policy, run:
$ {command} my-policy
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument(
plural=True)
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(flags.SecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
requests.extend(security_policy.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DeleteAlpha(base.DeleteCommand):
"""Delete security policies.
*{command}* deletes Compute Engine security policies. Security
policies can only be deleted when no other resources (e.g.,
backend services) refer to them.
## EXAMPLES
To delete a security policy, run:
$ {command} my-policy
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument(
plural=True)
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='delete')
parser.display_info.AddCacheUpdater(flags.SecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
refs = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
requests.extend(security_policy.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)

View File

@@ -0,0 +1,118 @@
# -*- 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 security policies."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine security policy.
*{command}* displays all data associated with Compute Engine security
policy in a project.
## EXAMPLES
To describe a security policy, run:
$ {command} my-policy
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='describe')
def Collection(self):
return 'compute.securityPolicies'
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
return security_policy.Describe()
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DescribeBeta(base.DescribeCommand):
"""Describe a Compute Engine security policy.
*{command}* displays all data associated with Compute Engine security
policy in a project.
## EXAMPLES
To describe a security policy, run:
$ {command} my-policy
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
return security_policy.Describe()
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DescribeAlpha(base.DescribeCommand):
"""Describe a Compute Engine security policy.
*{command}* displays all data associated with Compute Engine security
policy in a project.
## EXAMPLES
To describe a security policy, run:
$ {command} my-policy
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='describe')
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
return security_policy.Describe()

View File

@@ -0,0 +1,216 @@
# -*- 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 exporting security policy configs to a file."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags
from googlecloudsdk.command_lib.compute.security_policies import (
security_policies_utils)
from googlecloudsdk.core import log
from googlecloudsdk.core.util import files
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Export(base.Command):
r"""Export security policy configs into YAML or JSON files.
*{command}* exports all data associated with Compute Engine security
policy into a local file.
## EXAMPLES
To export a security policy in JSON format to a given file, run:
$ {command} my-policy \
--file-name=my-file-name \
--file-format=json
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='export')
parser.add_argument(
'--file-name',
required=True,
help='The name of the file to export the security policy config to.')
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to export the security policy config to. '
'Specify either yaml or json. Defaults to yaml if not specified.'))
def Run(self, args):
# Get the security policy.
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
requests = []
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
requests.extend(security_policy.Describe(only_generate_request=True))
resources = holder.client.MakeRequests(requests)
# Export the security policy.
try:
with files.FileWriter(args.file_name) as export_file:
if args.file_format == 'json':
security_policies_utils.WriteToFile(export_file, resources[0], 'json')
else:
security_policies_utils.WriteToFile(export_file, resources[0], 'yaml')
except EnvironmentError as exp:
msg = 'Unable to export security policy to file [{0}]: {1}'.format(
args.file_name, exp)
raise exceptions.BadFileException(msg)
log.status.Print('Exported security policy to [{0}].'.format(
args.file_name))
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ExportBeta(base.Command):
r"""Export security policy configs into YAML or JSON files.
*{command}* exports all data associated with Compute Engine security
policy into a local file.
## EXAMPLES
To export a security policy in JSON format to a given file, run:
$ {command} my-policy \
--file-name=my-file-name \
--file-format=json
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='export')
parser.add_argument(
'--file-name',
required=True,
help='The name of the file to export the security policy config to.')
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to export the security policy config to. '
'Specify either yaml or json. Defaults to yaml if not specified.'))
def Run(self, args):
# Get the security policy.
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
requests = []
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
requests.extend(security_policy.Describe(only_generate_request=True))
resources = holder.client.MakeRequests(requests)
# Export the security policy.
try:
with files.FileWriter(args.file_name) as export_file:
if args.file_format == 'json':
security_policies_utils.WriteToFile(export_file, resources[0], 'json')
else:
security_policies_utils.WriteToFile(export_file, resources[0], 'yaml')
except EnvironmentError as exp:
msg = 'Unable to export security policy to file [{0}]: {1}'.format(
args.file_name, exp)
raise exceptions.BadFileException(msg)
log.status.Print('Exported security policy to [{0}].'.format(
args.file_name))
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ExportAlpha(base.Command):
r"""Export security policy configs into YAML or JSON files.
*{command}* exports all data associated with Compute Engine security
policy into a local file.
## EXAMPLES
To export a security policy in JSON format to a given file, run:
$ {command} my-policy \
--file-name=my-file-name \
--file-format=json
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='export')
parser.add_argument(
'--file-name',
required=True,
help='The name of the file to export the security policy config to.')
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to export the security policy config to. '
'Specify either yaml or json. Defaults to yaml if not specified.'))
def Run(self, args):
# Get the security policy.
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
requests = []
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
requests.extend(security_policy.Describe(only_generate_request=True))
resources = holder.client.MakeRequests(requests)
# Export the security policy.
try:
with files.FileWriter(args.file_name) as export_file:
if args.file_format == 'json':
security_policies_utils.WriteToFile(export_file, resources[0], 'json')
else:
security_policies_utils.WriteToFile(export_file, resources[0], 'yaml')
except EnvironmentError as exp:
msg = 'Unable to export security policy to file [{0}]: {1}'.format(
args.file_name, exp)
raise exceptions.BadFileException(msg)
log.status.Print('Exported security policy to [{0}].'.format(
args.file_name))

View File

@@ -0,0 +1,249 @@
# -*- 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 importing security policy configs from a file."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import os
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags
from googlecloudsdk.command_lib.compute.security_policies import (
security_policies_utils)
from googlecloudsdk.core import log
from googlecloudsdk.core.util import files
import six
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.UnicodeIsSupported
class Import(base.SilentCommand):
"""Import security policy configs into your project.
*{command}* imports a security policy to update an existing policy. To create
a new policy from a file please use the create command instead.
## EXAMPLES
To import a security policy from a YAML file run this:
$ {command} --file-name=myFile
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='import')
parser.add_argument(
'--file-name',
required=True,
help=('The name of the JSON or YAML file to import the security policy '
'config from.'))
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to import the security policy config from. '
'Specify either yaml or json. Defaults to yaml if not specified.'))
def Run(self, args):
if not os.path.exists(args.file_name):
raise exceptions.BadFileException('No such file [{0}]'.format(
args.file_name))
if os.path.isdir(args.file_name):
raise exceptions.BadFileException('[{0}] is a directory'.format(
args.file_name))
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
# Get the imported security policy config.
try:
with files.FileReader(args.file_name) as import_file:
if args.file_format == 'json':
imported = security_policies_utils.SecurityPolicyFromFile(
import_file, holder.client.messages, 'json')
else:
imported = security_policies_utils.SecurityPolicyFromFile(
import_file, holder.client.messages, 'yaml')
except Exception as exp:
exp_msg = getattr(exp, 'message', six.text_type(exp))
msg = ('Unable to read security policy config from specified file [{0}] '
'because [{1}]'.format(args.file_name, exp_msg))
raise exceptions.BadFileException(msg)
# Send the change to the service.
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
security_policy.Patch(security_policy=imported)
msg = 'Updated [{0}] with config from [{1}].'.format(
ref.Name(), args.file_name)
log.status.Print(msg)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@base.UnicodeIsSupported
class ImportBeta(base.SilentCommand):
"""Import security policy configs into your project.
*{command}* imports a security policy to update an existing policy. To create
a new policy from a file please use the create command instead.
## EXAMPLES
To import a security policy from a YAML file run this:
$ {command} --file-name=myFile
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='import')
parser.add_argument(
'--file-name',
required=True,
help=('The name of the JSON or YAML file to import the security policy '
'config from.'))
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to import the security policy config from. '
'Specify either yaml or json. Defaults to yaml if not specified.'))
def Run(self, args):
if not os.path.exists(args.file_name):
raise exceptions.BadFileException('No such file [{0}]'.format(
args.file_name))
if os.path.isdir(args.file_name):
raise exceptions.BadFileException('[{0}] is a directory'.format(
args.file_name))
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
# Get the imported security policy config.
try:
with files.FileReader(args.file_name) as import_file:
if args.file_format == 'json':
imported = security_policies_utils.SecurityPolicyFromFile(
import_file, holder.client.messages, 'json')
else:
imported = security_policies_utils.SecurityPolicyFromFile(
import_file, holder.client.messages, 'yaml')
except Exception as exp:
exp_msg = getattr(exp, 'message', six.text_type(exp))
msg = ('Unable to read security policy config from specified file [{0}] '
'because [{1}]'.format(args.file_name, exp_msg))
raise exceptions.BadFileException(msg)
# Send the change to the service.
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
security_policy.Patch(security_policy=imported)
msg = 'Updated [{0}] with config from [{1}].'.format(
ref.Name(), args.file_name)
log.status.Print(msg)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@base.UnicodeIsSupported
class ImportAlpha(base.SilentCommand):
"""Import security policy configs into your project.
*{command}* imports a security policy to update an existing policy. To create
a new policy from a file please use the create command instead.
## EXAMPLES
To import a security policy from a YAML file run this:
$ {command} --file-name=myFile
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='import')
parser.add_argument(
'--file-name',
required=True,
help=('The name of the JSON or YAML file to import the security policy '
'config from.'))
parser.add_argument(
'--file-format',
choices=['json', 'yaml'],
help=(
'The format of the file to import the security policy config from. '
'Specify either yaml or json. Defaults to yaml if not specified.'))
def Run(self, args):
if not os.path.exists(args.file_name):
raise exceptions.BadFileException('No such file [{0}]'.format(
args.file_name))
if os.path.isdir(args.file_name):
raise exceptions.BadFileException('[{0}] is a directory'.format(
args.file_name))
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
# Get the imported security policy config.
try:
with files.FileReader(args.file_name) as import_file:
if args.file_format == 'json':
imported = security_policies_utils.SecurityPolicyFromFile(
import_file, holder.client.messages, 'json')
else:
imported = security_policies_utils.SecurityPolicyFromFile(
import_file, holder.client.messages, 'yaml')
except Exception as exp:
exp_msg = getattr(exp, 'message', six.text_type(exp))
msg = ('Unable to read security policy config from specified file [{0}] '
'because [{1}]'.format(args.file_name, exp_msg))
raise exceptions.BadFileException(msg)
# Send the change to the service.
security_policy = client.SecurityPolicy(ref, compute_client=holder.client)
security_policy.Patch(security_policy=imported)
msg = 'Updated [{0}] with config from [{1}].'.format(
ref.Name(), args.file_name)
log.status.Print(msg)

View File

@@ -0,0 +1,133 @@
# -*- 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 security policies."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import lister
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.GA)
class List(base.ListCommand):
"""List security policies.
## EXAMPLES
To list security policies run this:
$ {command}
"""
@staticmethod
def Args(parser):
parser.display_info.AddFormat("""\
table(
name,
region.basename()
)""")
lister.AddMultiScopeListerFlags(parser, regional=True, global_=True)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request_data = lister.ParseMultiScopeFlags(args, holder.resources)
list_implementation = lister.MultiScopeLister(
client,
regional_service=client.apitools_client.regionSecurityPolicies,
global_service=client.apitools_client.securityPolicies,
aggregation_service=client.apitools_client.securityPolicies)
return lister.Invoke(request_data, list_implementation)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ListBeta(base.ListCommand):
"""List security policies.
## EXAMPLES
To list security policies in all scopes run this:
$ {command}
"""
@staticmethod
def Args(parser):
parser.display_info.AddFormat("""\
table(
name,
region.basename()
)""")
lister.AddMultiScopeListerFlags(parser, regional=True, global_=True)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request_data = lister.ParseMultiScopeFlags(args, holder.resources)
list_implementation = lister.MultiScopeLister(
client,
regional_service=client.apitools_client.regionSecurityPolicies,
global_service=client.apitools_client.securityPolicies,
aggregation_service=client.apitools_client.securityPolicies)
return lister.Invoke(request_data, list_implementation)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListAlpha(base.ListCommand):
"""List security policies.
## EXAMPLES
To list security policies in all scopes run this:
$ {command}
"""
@staticmethod
def Args(parser):
parser.display_info.AddFormat("""\
table(
name,
region.basename()
)""")
lister.AddMultiScopeListerFlags(parser, regional=True, global_=True)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
request_data = lister.ParseMultiScopeFlags(args, holder.resources)
list_implementation = lister.MultiScopeLister(
client,
regional_service=client.apitools_client.regionSecurityPolicies,
global_service=client.apitools_client.securityPolicies,
aggregation_service=client.apitools_client.securityPolicies)
return lister.Invoke(request_data, list_implementation)
List.detailed_help = base_classes.GetGlobalListerHelp('security policies')
ListAlpha.detailed_help = base_classes.GetGlobalRegionalListerHelp(
'security policies')

View File

@@ -0,0 +1,67 @@
# -*- 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 to list all available preconfigured expression sets."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
class ListPreconfiguredExpressionSets(base.ListCommand):
"""List all available preconfigured expression sets.
*{command}* lists all available preconfigured expression sets that can be used
with the Cloud Armor rules language.
## EXAMPLES
To list all current preconfigured expressions sets run this:
$ {command}
"""
@staticmethod
def Args(parser):
"""Set up arguments for this command."""
base.URI_FLAG.RemoveFromParser(parser)
parser.display_info.AddFormat(
"""
table(id:label=EXPRESSION_SET,
aliases:format="get([])",
expressions:format="table(id:label=RULE_ID,
sensitivity:label=SENSITIVITY)")
"""
)
def Run(self, args):
"""Issues the request to list available preconfigured expression sets."""
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client.apitools_client
messages = client.MESSAGES_MODULE
project = properties.VALUES.core.project.Get(required=True)
request = (
messages.ComputeSecurityPoliciesListPreconfiguredExpressionSetsRequest(
project=project))
response = client.securityPolicies.ListPreconfiguredExpressionSets(request)
if response.preconfiguredExpressionSets is not None:
return response.preconfiguredExpressionSets.wafRules.expressionSets
return response.preconfiguredExpressionSets

View File

@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for removing layer7 ddos defense threshold config from security policies."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.security_policies import flags
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RemoveLayer7DdosDefenseThresholdConfig(base.UpdateCommand):
r"""Remove a layer7 ddos defense threshold config from a Compute Engine security policy.
*{command}* is used to remove layer7 ddos defense threshold configs from security policies.
## EXAMPLES
To remove a layer7 ddos defense threshold config run the following command:
$ {command} NAME \
--threshold-config-name=my-threshold-config-name
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='update')
parser.add_argument(
'--threshold-config-name',
required=True,
help='The name for the threshold config.',
)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(args, holder.resources)
security_policy = client.SecurityPolicy(
ref=ref, compute_client=holder.client
)
existing_security_policy = security_policy.Describe()[0]
adaptive_protection_config = (
existing_security_policy.adaptiveProtectionConfig
)
if (
adaptive_protection_config is None
or adaptive_protection_config.layer7DdosDefenseConfig is None
or not adaptive_protection_config.layer7DdosDefenseConfig.thresholdConfigs
):
raise exceptions.InvalidArgumentException(
'--threshold-config-name',
"There's no existing layer 7 ddos defense threshold config to remove",
)
existing_threshold_configs = (
adaptive_protection_config.layer7DdosDefenseConfig.thresholdConfigs
)
new_threshold_configs = [
threshold_config
for threshold_config in existing_threshold_configs
if threshold_config.name != args.threshold_config_name
]
if len(existing_threshold_configs) == len(new_threshold_configs):
raise exceptions.InvalidArgumentException(
'--threshold-config-name',
'layer 7 ddos defense threshold config "%s" does not exist in this'
' policy.'
% args.threshold_config_name,
)
adaptive_protection_config.layer7DdosDefenseConfig.thresholdConfigs = (
new_threshold_configs
)
updated_security_policy = holder.client.messages.SecurityPolicy(
adaptiveProtectionConfig=adaptive_protection_config,
fingerprint=existing_security_policy.fingerprint,
)
return security_policy.Patch(security_policy=updated_security_policy)

View File

@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for removing user defined fields from security policies."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.security_policies import flags
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class RemoveUserDefinedFieldAlpha(base.UpdateCommand):
"""Remove a user defined field from a Compute Engine security policy.
*{command}* is used to remove user defined fields from security policies.
## EXAMPLES
To remove a user defined field run this:
$ {command} SECURITY_POLICY --user-defined-field-name=my-field
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyRegionalArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='update')
parser.add_argument(
'--user-defined-field-name',
required=True,
help='The name of the user defined field to remove.',
)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(args, holder.resources)
security_policy = client.SecurityPolicy(
ref=ref, compute_client=holder.client
)
existing_security_policy = security_policy.Describe()[0]
existing_user_defined_fields = existing_security_policy.userDefinedFields
new_user_defined_fields = []
for user_defined_field in existing_user_defined_fields:
if user_defined_field.name != args.user_defined_field_name:
new_user_defined_fields.append(user_defined_field)
if len(existing_user_defined_fields) == len(new_user_defined_fields):
raise exceptions.InvalidArgumentException(
'--user-defined-field-name',
'user defined field does not exist in this policy.',
)
updated_security_policy = holder.client.messages.SecurityPolicy(
userDefinedFields=new_user_defined_fields,
fingerprint=existing_security_policy.fingerprint,
)
field_mask = 'user_defined_fields' if not new_user_defined_fields else None
return security_policy.Patch(
security_policy=updated_security_policy, field_mask=field_mask
)

View File

@@ -0,0 +1,25 @@
# -*- 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 security policies rules."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class SecurityPolicyRules(base.Group):
"""Read and manipulate Compute Engine security policies rules."""

View File

@@ -0,0 +1,408 @@
# -*- 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 adding exclusions for preconfigured WAF rule evaluation to security policy rules."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import encoding
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags as security_policy_flags
from googlecloudsdk.command_lib.compute.security_policies.rules import flags
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
class AddPreconfigWafExclusionHelper(object):
r"""Add an exclusion configuration for preconfigured WAF evaluation into a security policy rule.
*{command}* is used to add an exclusion configuration for preconfigured WAF
evaluation into a security policy rule.
Note that request field exclusions are associated with a target, which can be
a single rule set, or a rule set plus a list of rule IDs under the rule set.
## EXAMPLES
To add specific request field exclusions that are associated with the target
of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
\
--request-header-to-exclude=op=EQUALS,val=abc \
--request-header-to-exclude=op=STARTS_WITH,val=xyz \
--request-uri-to-exclude=op=EQUALS_ANY
To add specific request field exclusions that are associated with the target
of 'sqli-stable': [], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--request-cookie-to-exclude=op=EQUALS_ANY
"""
@classmethod
def Args(cls, parser):
"""Generates the flagset for an AddPreconfigWafExclusion command."""
cls.NAME_ARG = flags.PriorityArgument(
'add the exclusion configuration for preconfigured WAF evaluation'
)
cls.NAME_ARG.AddArgument(
parser,
operation_type=(
'add the exclusion configuration for preconfigured WAF evaluation'
),
cust_metavar='PRIORITY',
)
flags.AddRegionFlag(
parser,
'add the exclusion configuration for preconfigured WAF evaluation')
cls.SECURITY_POLICY_ARG = (
security_policy_flags.SecurityPolicyMultiScopeArgumentForRules())
cls.SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddTargetRuleSet(parser=parser, is_add=True)
flags.AddTargetRuleIds(parser=parser, is_add=True)
flags.AddRequestHeader(parser=parser, is_add=True)
flags.AddRequestCookie(parser=parser, is_add=True)
flags.AddRequestQueryParam(parser=parser, is_add=True)
flags.AddRequestUri(parser=parser, is_add=True)
@classmethod
def _IsIdenticalTarget(cls,
existing_exclusion,
target_rule_set,
target_rule_ids=None):
return target_rule_set == existing_exclusion.targetRuleSet and set(
target_rule_ids) == set(existing_exclusion.targetRuleIds)
@classmethod
def _ConvertRequestFieldToAdd(cls, compute_client, request_field_to_add):
"""Converts RequestFieldToAdd."""
request_field = (
compute_client.messages
.SecurityPolicyRulePreconfiguredWafConfigExclusionFieldParams())
op = request_field_to_add.get('op') or ''
if op:
request_field.op = (
compute_client.messages
.SecurityPolicyRulePreconfiguredWafConfigExclusionFieldParams
.OpValueValuesEnum(op))
val = request_field_to_add.get('val') or ''
if val:
request_field.val = val
return request_field
@classmethod
def _AddRequestField(cls, compute_client, existing_request_fields,
request_field_to_add):
"""Adds Request Field."""
new_request_field = cls._ConvertRequestFieldToAdd(compute_client,
request_field_to_add)
for existing_request_field in existing_request_fields:
if existing_request_field == new_request_field:
return
existing_request_fields.append(new_request_field)
@classmethod
def _UpdateExclusion(cls,
compute_client,
existing_exclusion,
request_headers=None,
request_cookies=None,
request_query_params=None,
request_uris=None):
"""Updates Exclusion."""
for request_header in request_headers or []:
cls._AddRequestField(compute_client,
existing_exclusion.requestHeadersToExclude,
request_header)
for request_cookie in request_cookies or []:
cls._AddRequestField(compute_client,
existing_exclusion.requestCookiesToExclude,
request_cookie)
for request_query_param in request_query_params or []:
cls._AddRequestField(compute_client,
existing_exclusion.requestQueryParamsToExclude,
request_query_param)
for request_uri in request_uris or []:
cls._AddRequestField(compute_client,
existing_exclusion.requestUrisToExclude, request_uri)
@classmethod
def _CreateExclusion(cls,
compute_client,
target_rule_set,
target_rule_ids=None,
request_headers=None,
request_cookies=None,
request_query_params=None,
request_uris=None):
"""Creates Exclusion."""
new_exclusion = (
compute_client.messages
.SecurityPolicyRulePreconfiguredWafConfigExclusion())
new_exclusion.targetRuleSet = target_rule_set
for target_rule_id in target_rule_ids or []:
new_exclusion.targetRuleIds.append(target_rule_id)
cls._UpdateExclusion(compute_client, new_exclusion, request_headers,
request_cookies, request_query_params, request_uris)
return new_exclusion
@classmethod
def _UpdatePreconfigWafConfig(cls, compute_client, existing_rule, args):
"""Updates Preconfig WafConfig."""
if existing_rule.preconfiguredWafConfig:
new_preconfig_waf_config = encoding.CopyProtoMessage(
existing_rule.preconfiguredWafConfig)
else:
new_preconfig_waf_config = (
compute_client.messages.SecurityPolicyRulePreconfiguredWafConfig())
for exclusion in new_preconfig_waf_config.exclusions:
if cls._IsIdenticalTarget(exclusion, args.target_rule_set,
args.target_rule_ids or []):
cls._UpdateExclusion(compute_client, exclusion,
args.request_header_to_exclude,
args.request_cookie_to_exclude,
args.request_query_param_to_exclude,
args.request_uri_to_exclude)
return new_preconfig_waf_config
new_exclusion = cls._CreateExclusion(compute_client, args.target_rule_set,
args.target_rule_ids,
args.request_header_to_exclude,
args.request_cookie_to_exclude,
args.request_query_param_to_exclude,
args.request_uri_to_exclude)
new_preconfig_waf_config.exclusions.append(new_exclusion)
return new_preconfig_waf_config
@classmethod
def Run(cls, release_track, args):
"""Validates arguments and patches a security policy rule."""
if not (args.IsSpecified('request_header_to_exclude') or
args.IsSpecified('request_cookie_to_exclude') or
args.IsSpecified('request_query_param_to_exclude') or
args.IsSpecified('request_uri_to_exclude')):
request_field_names = [
'--request-header-to-exclude', '--request-cookie-to-exclude',
'--request-query-param-to-exclude', '--request-uri-to-exclude'
]
raise exceptions.MinimumArgumentException(
request_field_names, 'At least one request field must be specified.')
for request_fields in [
args.request_header_to_exclude or [], args.request_cookie_to_exclude or
[], args.request_query_param_to_exclude or [],
args.request_uri_to_exclude or []
]:
for request_field in request_fields:
op = request_field.get('op') or ''
if not op or op not in [
'EQUALS', 'STARTS_WITH', 'ENDS_WITH', 'CONTAINS', 'EQUALS_ANY'
]:
raise exceptions.InvalidArgumentException(
'op',
'A request field operator must be one of [EQUALS, STARTS_WITH, '
'ENDS_WITH, CONTAINS, EQUALS_ANY].')
holder = base_classes.ComputeApiHolder(release_track)
compute_client = holder.client
ref = None
if args.security_policy:
security_policy_ref = cls.SECURITY_POLICY_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL)
if getattr(security_policy_ref, 'region', None) is not None:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': security_policy_ref.region,
'securityPolicy': args.security_policy,
})
else:
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'securityPolicy': args.security_policy,
},
)
else:
try:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': getattr(args, 'region', None),
},
)
except (
resources.RequiredFieldOmittedException,
resources.WrongResourceCollectionException,
):
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
},
)
security_policy_rule = client.SecurityPolicyRule(
ref, compute_client=compute_client)
existing_rule = security_policy_rule.Describe()[0]
new_preconfig_waf_config = cls._UpdatePreconfigWafConfig(
compute_client, existing_rule, args)
return security_policy_rule.Patch(
preconfig_waf_config=new_preconfig_waf_config)
@base.ReleaseTracks(base.ReleaseTrack.GA)
class AddPreconfigWafExclusionGA(base.UpdateCommand):
r"""Add an exclusion configuration for preconfigured WAF evaluation into a security policy rule.
*{command}* is used to add an exclusion configuration for preconfigured WAF
evaluation into a security policy rule.
Note that request field exclusions are associated with a target, which can be
a single rule set, or a rule set plus a list of rule IDs under the rule set.
## EXAMPLES
To add specific request field exclusions that are associated with the target
of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
\
--request-header-to-exclude=op=EQUALS,val=abc \
--request-header-to-exclude=op=STARTS_WITH,val=xyz \
--request-uri-to-exclude=op=EQUALS_ANY
To add specific request field exclusions that are associated with the target
of 'sqli-stable': [], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--request-cookie-to-exclude=op=EQUALS_ANY
"""
NAME_ARG = None
@classmethod
def Args(cls, parser):
AddPreconfigWafExclusionHelper.Args(
parser,
)
def Run(self, args):
return AddPreconfigWafExclusionHelper.Run(
self.ReleaseTrack(),
args,
)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class AddPreconfigWafExclusionBeta(AddPreconfigWafExclusionGA):
r"""Add an exclusion configuration for preconfigured WAF evaluation into a security policy rule.
*{command}* is used to add an exclusion configuration for preconfigured WAF
evaluation into a security policy rule.
Note that request field exclusions are associated with a target, which can be
a single rule set, or a rule set plus a list of rule IDs under the rule set.
## EXAMPLES
To add specific request field exclusions that are associated with the target
of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
\
--request-header-to-exclude=op=EQUALS,val=abc \
--request-header-to-exclude=op=STARTS_WITH,val=xyz \
--request-uri-to-exclude=op=EQUALS_ANY
To add specific request field exclusions that are associated with the target
of 'sqli-stable': [], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--request-cookie-to-exclude=op=EQUALS_ANY
"""
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class AddPreconfigWafExclusionAlpha(AddPreconfigWafExclusionBeta):
r"""Add an exclusion configuration for preconfigured WAF evaluation into a security policy rule.
*{command}* is used to add an exclusion configuration for preconfigured WAF
evaluation into a security policy rule.
Note that request field exclusions are associated with a target, which can be
a single rule set, or a rule set plus a list of rule IDs under the rule set.
## EXAMPLES
To add specific request field exclusions that are associated with the target
of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
\
--request-header-to-exclude=op=EQUALS,val=abc \
--request-header-to-exclude=op=STARTS_WITH,val=xyz \
--request-uri-to-exclude=op=EQUALS_ANY
To add specific request field exclusions that are associated with the target
of 'sqli-stable': [], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--request-cookie-to-exclude=op=EQUALS_ANY
"""

View File

@@ -0,0 +1,284 @@
# -*- 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 security policies rules."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags as security_policies_flags
from googlecloudsdk.command_lib.compute.security_policies import security_policies_utils
from googlecloudsdk.command_lib.compute.security_policies.rules import flags
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
class CreateHelper(object):
r"""Create a Compute Engine security policy rule.
*{command}* is used to create security policy rules.
## EXAMPLES
To create a rule at priority 1000 to block the IP range
1.2.3.0/24, run:
$ {command} 1000 \
--action=deny-403 \
--security-policy=my-policy \
--description="block 1.2.3.0/24" \
--src-ip-ranges=1.2.3.0/24
"""
@classmethod
def Args(
cls,
parser,
support_fairshare=False,
support_rpc_status=False,
):
"""Generates the flagset for a Create command."""
cls.NAME_ARG = (flags.PriorityArgument('add'))
cls.NAME_ARG.AddArgument(
parser, operation_type='add', cust_metavar='PRIORITY')
flags.AddRegionFlag(parser, 'add')
cls.SECURITY_POLICY_ARG = (
security_policies_flags.SecurityPolicyMultiScopeArgumentForRules())
cls.SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddMatcherAndNetworkMatcher(parser)
flags.AddAction(
parser,
support_fairshare=support_fairshare)
flags.AddDescription(parser)
flags.AddPreview(parser)
flags.AddRedirectOptions(parser)
flags.AddRateLimitOptions(
parser,
support_rpc_status=support_rpc_status,
)
flags.AddRequestHeadersToAdd(parser)
flags.AddRecaptchaOptions(parser)
parser.display_info.AddCacheUpdater(
security_policies_flags.SecurityPoliciesCompleter)
@classmethod
def Run(
cls,
release_track,
args,
support_rpc_status,
):
"""Validates arguments and creates a security policy rule."""
holder = base_classes.ComputeApiHolder(release_track)
if args.security_policy:
security_policy_ref = cls.SECURITY_POLICY_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL)
if getattr(security_policy_ref, 'region', None) is not None:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': security_policy_ref.region,
'securityPolicy': args.security_policy,
})
else:
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'securityPolicy': args.security_policy,
},
)
else:
try:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': getattr(args, 'region', None),
},
)
except (
resources.RequiredFieldOmittedException,
resources.WrongResourceCollectionException,
):
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
},
)
security_policy_rule = client.SecurityPolicyRule(
ref, compute_client=holder.client)
redirect_options = security_policies_utils.CreateRedirectOptions(
holder.client, args
)
rate_limit_options = security_policies_utils.CreateRateLimitOptions(
holder.client,
args,
support_rpc_status,
)
request_headers_to_add = args.request_headers_to_add
expression_options = security_policies_utils.CreateExpressionOptions(
holder.client, args
)
network_matcher = security_policies_utils.CreateNetworkMatcher(
holder.client, args
)[0]
return security_policy_rule.Create(
src_ip_ranges=args.src_ip_ranges,
expression=args.expression,
expression_options=expression_options,
network_matcher=network_matcher,
action=args.action,
description=args.description,
preview=args.preview,
redirect_options=redirect_options,
rate_limit_options=rate_limit_options,
request_headers_to_add=request_headers_to_add,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class CreateGA(base.CreateCommand):
r"""Create a Compute Engine security policy rule.
*{command}* is used to create security policy rules.
## EXAMPLES
To create a rule at priority 1000 to block the IP range
1.2.3.0/24, run:
$ {command} 1000 \
--action=deny-403 \
--security-policy=my-policy \
--description="block 1.2.3.0/24" \
--src-ip-ranges=1.2.3.0/24
"""
SECURITY_POLICY_ARG = None
NAME_ARG = None
_support_rpc_status = False
@classmethod
def Args(cls, parser):
CreateHelper.Args(
parser,
support_rpc_status=cls._support_rpc_status,
)
def Run(self, args):
return CreateHelper.Run(
self.ReleaseTrack(),
args,
support_rpc_status=self._support_rpc_status,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(base.CreateCommand):
r"""Create a Compute Engine security policy rule.
*{command}* is used to create security policy rules.
## EXAMPLES
To create a rule at priority 1000 to block the IP range
1.2.3.0/24, run:
$ {command} 1000 \
--action=deny-403 \
--security-policy=my-policy \
--description="block 1.2.3.0/24" \
--src-ip-ranges=1.2.3.0/24
"""
SECURITY_POLICY_ARG = None
_support_rpc_status = False
@classmethod
def Args(cls, parser):
CreateHelper.Args(
parser,
support_fairshare=True,
support_rpc_status=cls._support_rpc_status,
)
def Run(self, args):
return CreateHelper.Run(
self.ReleaseTrack(),
args,
support_rpc_status=self._support_rpc_status,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(base.CreateCommand):
r"""Create a Compute Engine security policy rule.
*{command}* is used to create security policy rules.
## EXAMPLES
To create a rule at priority 1000 to block the IP range
1.2.3.0/24, run:
$ {command} 1000 \
--action=deny-403 \
--security-policy=my-policy \
--description="block 1.2.3.0/24" \
--src-ip-ranges=1.2.3.0/24
"""
SECURITY_POLICY_ARG = None
_support_rpc_status = True
@classmethod
def Args(cls, parser):
CreateHelper.Args(
parser,
support_fairshare=True,
support_rpc_status=cls._support_rpc_status,
)
def Run(self, args):
return CreateHelper.Run(
self.ReleaseTrack(),
args,
support_rpc_status=self._support_rpc_status,
)

View File

@@ -0,0 +1,178 @@
# -*- 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 security policies rules."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags as security_policies_flags
from googlecloudsdk.command_lib.compute.security_policies.rules import flags
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
class DeleteHelper(object):
r"""Delete Compute Engine security policy rules.
*{command}* is used to delete security policy rules.
## EXAMPLES
To delete the rule at priority 1000, run:
$ {command} 1000 \
--security-policy=my-policy
"""
SECURITY_POLICY_ARG = None
NAME_ARG = None
@classmethod
def Args(cls, parser):
"""Generates the flagset for a Delete command."""
cls.NAME_ARG = (flags.PriorityArgument('delete', is_plural=True))
cls.NAME_ARG.AddArgument(
parser, operation_type='delete', cust_metavar='PRIORITY')
flags.AddRegionFlag(parser, 'delete')
cls.SECURITY_POLICY_ARG = (
security_policies_flags.SecurityPolicyMultiScopeArgumentForRules()
)
cls.SECURITY_POLICY_ARG.AddArgument(parser)
parser.display_info.AddCacheUpdater(
security_policies_flags.SecurityPoliciesCompleter
)
@classmethod
def Run(cls, release_track, args):
"""Validates arguments and deletes security policy rule(s)."""
holder = base_classes.ComputeApiHolder(release_track)
refs = []
if args.security_policy:
security_policy_ref = cls.SECURITY_POLICY_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL)
if getattr(security_policy_ref, 'region', None) is not None:
for name in args.names:
refs.append(holder.resources.Parse(
name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': security_policy_ref.region,
'securityPolicy': args.security_policy,
}))
else:
for name in args.names:
refs.append(holder.resources.Parse(
name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'securityPolicy': args.security_policy,
},
))
else:
for name in args.names:
try:
refs.append(holder.resources.Parse(
name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': getattr(args, 'region', None),
},
))
except (
resources.RequiredFieldOmittedException,
resources.WrongResourceCollectionException,
):
refs.append(holder.resources.Parse(
name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
},
))
utils.PromptForDeletion(refs)
requests = []
for ref in refs:
security_policy_rule = client.SecurityPolicyRule(
ref, compute_client=holder.client)
requests.extend(security_policy_rule.Delete(only_generate_request=True))
return holder.client.MakeRequests(requests)
@base.ReleaseTracks(base.ReleaseTrack.GA)
class DeleteGA(base.DeleteCommand):
r"""Delete Compute Engine security policy rules.
*{command}* is used to delete security policy rules.
## EXAMPLES
To delete the rule at priority 1000, run:
$ {command} 1000 \
--security-policy=my-policy
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
DeleteHelper.Args(parser)
def Run(self, args):
return DeleteHelper.Run(self.ReleaseTrack(), args)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DeleteBeta(DeleteGA):
r"""Delete Compute Engine security policy rules.
*{command}* is used to delete security policy rules.
## EXAMPLES
To delete the rule at priority 1000, run:
$ {command} 1000 \
--security-policy=my-policy
"""
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DeleteAlpha(DeleteBeta):
r"""Delete Compute Engine security policy rules.
*{command}* is used to delete security policy rules.
## EXAMPLES
To delete the rule at priority 1000, run:
$ {command} 1000 \
--security-policy=my-policy
"""

View File

@@ -0,0 +1,166 @@
# -*- 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 security policies rules."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags as security_policy_flags
from googlecloudsdk.command_lib.compute.security_policies.rules import flags
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
class DescribeHelper(object):
r"""Describe a Compute Engine security policy rule.
*{command}* displays all data associated with a security policy rule.
## EXAMPLES
To describe the rule at priority 1000, run:
$ {command} 1000 \
--security-policy=my-policy
"""
SECURITY_POLICY_ARG = None
NAME_ARG = None
@classmethod
def Args(cls, parser):
"""Generates the flagset for a Describe command."""
cls.NAME_ARG = (flags.PriorityArgument('describe'))
cls.NAME_ARG.AddArgument(
parser, operation_type='describe', cust_metavar='PRIORITY')
flags.AddRegionFlag(parser, 'describe')
cls.SECURITY_POLICY_ARG = (
security_policy_flags.SecurityPolicyMultiScopeArgumentForRules()
)
cls.SECURITY_POLICY_ARG.AddArgument(parser)
@classmethod
def Run(cls, release_track, args):
"""Validates arguments and describes a security policy rule."""
holder = base_classes.ComputeApiHolder(release_track)
if args.security_policy:
security_policy_ref = cls.SECURITY_POLICY_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL)
if getattr(security_policy_ref, 'region', None) is not None:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': security_policy_ref.region,
'securityPolicy': args.security_policy,
})
else:
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'securityPolicy': args.security_policy,
},
)
else:
try:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': getattr(args, 'region', None),
},
)
except (
resources.RequiredFieldOmittedException,
resources.WrongResourceCollectionException,
):
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
},
)
security_policy_rule = client.SecurityPolicyRule(
ref, compute_client=holder.client)
return security_policy_rule.Describe()
@base.ReleaseTracks(base.ReleaseTrack.GA)
class DescribeGA(base.DescribeCommand):
r"""Describe a Compute Engine security policy rule.
*{command}* displays all data associated with a security policy rule.
## EXAMPLES
To describe the rule at priority 1000, run:
$ {command} 1000 \
--security-policy=my-policy
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
DescribeHelper.Args(parser)
def Run(self, args):
return DescribeHelper.Run(self.ReleaseTrack(), args)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DescribeBeta(DescribeGA):
r"""Describe a Compute Engine security policy rule.
*{command}* displays all data associated with a security policy rule.
## EXAMPLES
To describe the rule at priority 1000, run:
$ {command} 1000 \
--security-policy=my-policy
"""
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DescribeAlpha(DescribeBeta):
r"""Describe a Compute Engine security policy rule.
*{command}* displays all data associated with a security policy rule.
## EXAMPLES
To describe the rule at priority 1000, run:
$ {command} 1000 \
--security-policy=my-policy
"""

View File

@@ -0,0 +1,491 @@
# -*- 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 removing exclusions for preconfigured WAF rule evaluation from security policy rules."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags as security_policy_flags
from googlecloudsdk.command_lib.compute.security_policies.rules import flags
from googlecloudsdk.core import properties
class RemovePreconfigWafExclusionHelper(object):
r"""Remove an exclusion configuration for preconfigured WAF evaluation from a security policy rule.
*{command}* is used to remove an exclusion configuration for preconfigured WAF
evaluation from a security policy rule.
Note that request field exclusions are associated with a target, which can be
a single rule set, or a rule set plus a list of rule IDs under the rule set.
It is possible to remove request field exclusions at 3 levels:
- Remove specific request field exclusions that are associated with a matching
target.
- Remove all the request field exclusions that are associated with a matching
target.
- Remove all the request field exclusions that are configured under the
security policy rule, regardless of the target.
## EXAMPLES
To remove specific request field exclusions that are associated with the
target of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
\
--request-header-to-exclude=op=EQUALS,val=abc \
--request-header-to-exclude=op=STARTS_WITH,val=xyz \
--request-uri-to-exclude=op=EQUALS_ANY
To remove all the request field exclusions that are associated with the target
of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
To remove all the request field exclusions that are associated with the target
of 'sqli-stable': [], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable
To remove all the request field exclusions that are configured under the
security policy rule, regardless of the target, run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=*
"""
@classmethod
def Args(cls, parser):
"""Generates the flagset for a RemovePreconfigWafExclusion command."""
cls.NAME_ARG = flags.PriorityArgument(
'remove the exclusion configuration for preconfigured WAF evaluation'
)
cls.NAME_ARG.AddArgument(
parser,
operation_type=(
'remove the exclusion configuration for preconfigured WAF'
' evaluation'
),
cust_metavar='PRIORITY',
)
flags.AddRegionFlag(
parser,
'remove the exclusion configuration for preconfigured WAF evaluation')
cls.SECURITY_POLICY_ARG = (
security_policy_flags.SecurityPolicyMultiScopeArgumentForRules())
cls.SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddTargetRuleSet(parser=parser, is_add=False)
flags.AddTargetRuleIds(parser=parser, is_add=False)
flags.AddRequestHeader(parser=parser, is_add=False)
flags.AddRequestCookie(parser=parser, is_add=False)
flags.AddRequestQueryParam(parser=parser, is_add=False)
flags.AddRequestUri(parser=parser, is_add=False)
@classmethod
def _IsIdenticalTarget(cls,
existing_exclusion,
target_rule_set,
target_rule_ids=None):
return target_rule_set == existing_exclusion.targetRuleSet and set(
target_rule_ids) == set(existing_exclusion.targetRuleIds)
@classmethod
def _ConvertRequestFieldToAdd(cls, compute_client, request_field_to_remove):
"""Converts RequestFieldToAdd."""
request_field = (
compute_client.messages
.SecurityPolicyRulePreconfiguredWafConfigExclusionFieldParams())
op = request_field_to_remove.get('op') or ''
if op:
request_field.op = (
compute_client.messages
.SecurityPolicyRulePreconfiguredWafConfigExclusionFieldParams
.OpValueValuesEnum(op))
val = request_field_to_remove.get('val') or ''
if val:
request_field.val = val
return request_field
@classmethod
def _RemoveRequestFields(cls, existing_request_fields,
request_fields_to_remove):
new_request_fields = []
for existing_request_field in existing_request_fields:
if existing_request_field not in request_fields_to_remove:
new_request_fields.append(existing_request_field)
return new_request_fields
@classmethod
def _UpdateExclusion(cls,
compute_client,
existing_exclusion,
request_headers=None,
request_cookies=None,
request_query_params=None,
request_uris=None):
"""Updates Exclusion."""
new_exclusion = (
compute_client.messages
.SecurityPolicyRulePreconfiguredWafConfigExclusion())
new_exclusion.targetRuleSet = existing_exclusion.targetRuleSet
for target_rule_id in existing_exclusion.targetRuleIds or []:
new_exclusion.targetRuleIds.append(target_rule_id)
request_headers_to_remove = []
for request_header in request_headers or []:
request_headers_to_remove.append(
cls._ConvertRequestFieldToAdd(compute_client, request_header))
new_exclusion.requestHeadersToExclude.extend(
cls._RemoveRequestFields(existing_exclusion.requestHeadersToExclude,
request_headers_to_remove))
request_cookies_to_remove = []
for request_cookie in request_cookies or []:
request_cookies_to_remove.append(
cls._ConvertRequestFieldToAdd(compute_client, request_cookie))
new_exclusion.requestCookiesToExclude.extend(
cls._RemoveRequestFields(existing_exclusion.requestCookiesToExclude,
request_cookies_to_remove))
request_query_params_to_remove = []
for request_query_param in request_query_params or []:
request_query_params_to_remove.append(
cls._ConvertRequestFieldToAdd(compute_client, request_query_param))
new_exclusion.requestQueryParamsToExclude.extend(
cls._RemoveRequestFields(
existing_exclusion.requestQueryParamsToExclude,
request_query_params_to_remove))
request_uris_to_remove = []
for request_uri in request_uris or []:
request_uris_to_remove.append(
cls._ConvertRequestFieldToAdd(compute_client, request_uri))
new_exclusion.requestUrisToExclude.extend(
cls._RemoveRequestFields(existing_exclusion.requestUrisToExclude,
request_uris_to_remove))
if not (new_exclusion.requestHeadersToExclude or
new_exclusion.requestCookiesToExclude or
new_exclusion.requestQueryParamsToExclude or
new_exclusion.requestUrisToExclude):
return None
return new_exclusion
@classmethod
def _UpdatePreconfigWafConfig(cls, compute_client, existing_rule, args):
"""Updates Preconfig WafConfig."""
new_preconfig_waf_config = (
compute_client.messages.SecurityPolicyRulePreconfiguredWafConfig())
if args.target_rule_set == '*':
return new_preconfig_waf_config
has_request_field_args = False
if (args.IsSpecified('request_header_to_exclude') or
args.IsSpecified('request_cookie_to_exclude') or
args.IsSpecified('request_query_param_to_exclude') or
args.IsSpecified('request_uri_to_exclude')):
has_request_field_args = True
if existing_rule.preconfiguredWafConfig:
exclusions = existing_rule.preconfiguredWafConfig.exclusions
else:
exclusions = []
for exclusion in exclusions:
if cls._IsIdenticalTarget(exclusion, args.target_rule_set,
args.target_rule_ids or []):
if has_request_field_args:
new_exclusion = cls._UpdateExclusion(
compute_client, exclusion, args.request_header_to_exclude,
args.request_cookie_to_exclude,
args.request_query_param_to_exclude, args.request_uri_to_exclude)
if new_exclusion:
new_preconfig_waf_config.exclusions.append(new_exclusion)
else:
new_preconfig_waf_config.exclusions.append(exclusion)
return new_preconfig_waf_config
@classmethod
def Run(cls, release_track, args):
"""Validates arguments and patches a security policy rule."""
if args.target_rule_set == '*':
if (args.IsSpecified('target_rule_ids') or
args.IsSpecified('request_header_to_exclude') or
args.IsSpecified('request_cookie_to_exclude') or
args.IsSpecified('request_query_param_to_exclude') or
args.IsSpecified('request_uri_to_exclude')):
raise exceptions.InvalidArgumentException(
'target-rule-set',
'Arguments in [--target-rule-ids, --request-header-to-exclude, '
'--request-cookie-to-exclude, --request-query-param-to-exclude, '
'--request-uri-to-exclude] cannot be specified when '
'--target-rule-set is set to *.')
for request_fields in [
args.request_header_to_exclude or [], args.request_cookie_to_exclude or
[], args.request_query_param_to_exclude or [],
args.request_uri_to_exclude or []
]:
for request_field in request_fields:
op = request_field.get('op') or ''
if not op or op not in [
'EQUALS', 'STARTS_WITH', 'ENDS_WITH', 'CONTAINS', 'EQUALS_ANY'
]:
raise exceptions.InvalidArgumentException(
'op',
'A request field operator must be one of [EQUALS, STARTS_WITH, '
'ENDS_WITH, CONTAINS, EQUALS_ANY].')
holder = base_classes.ComputeApiHolder(release_track)
compute_client = holder.client
ref = None
security_policy_ref = cls.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
if getattr(security_policy_ref, 'region', None) is not None:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': security_policy_ref.region,
'securityPolicy': args.security_policy,
})
else:
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'securityPolicy': args.security_policy
})
security_policy_rule = client.SecurityPolicyRule(
ref, compute_client=compute_client)
existing_rule = security_policy_rule.Describe()[0]
new_preconfig_waf_config = cls._UpdatePreconfigWafConfig(
compute_client, existing_rule, args)
return security_policy_rule.Patch(
preconfig_waf_config=new_preconfig_waf_config)
@base.ReleaseTracks(base.ReleaseTrack.GA)
class RemovePreconfigWafExclusionGA(base.UpdateCommand):
r"""Remove an exclusion configuration for preconfigured WAF evaluation from a security policy rule.
*{command}* is used to remove an exclusion configuration for preconfigured WAF
evaluation from a security policy rule.
Note that request field exclusions are associated with a target, which can be
a single rule set, or a rule set plus a list of rule IDs under the rule set.
It is possible to remove request field exclusions at 3 levels:
- Remove specific request field exclusions that are associated with a matching
target.
- Remove all the request field exclusions that are associated with a matching
target.
- Remove all the request field exclusions that are configured under the
security policy rule, regardless of the target.
## EXAMPLES
To remove specific request field exclusions that are associated with the
target of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
\
--request-header-to-exclude=op=EQUALS,val=abc \
--request-header-to-exclude=op=STARTS_WITH,val=xyz \
--request-uri-to-exclude=op=EQUALS_ANY
To remove all the request field exclusions that are associated with the target
of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
To remove all the request field exclusions that are associated with the target
of 'sqli-stable': [], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable
To remove all the request field exclusions that are configured under the
security policy rule, regardless of the target, run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=*
"""
SECURITY_POLICY_ARG = None
NAME_ARG = None
@classmethod
def Args(cls, parser):
RemovePreconfigWafExclusionHelper.Args(
parser,
)
def Run(self, args):
return RemovePreconfigWafExclusionHelper.Run(
self.ReleaseTrack(),
args,
)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class RemovePreconfigWafExclusionBeta(RemovePreconfigWafExclusionGA):
r"""Remove an exclusion configuration for preconfigured WAF evaluation from a security policy rule.
*{command}* is used to remove an exclusion configuration for preconfigured WAF
evaluation from a security policy rule.
Note that request field exclusions are associated with a target, which can be
a single rule set, or a rule set plus a list of rule IDs under the rule set.
It is possible to remove request field exclusions at 3 levels:
- Remove specific request field exclusions that are associated with a matching
target.
- Remove all the request field exclusions that are associated with a matching
target.
- Remove all the request field exclusions that are configured under the
security policy rule, regardless of the target.
## EXAMPLES
To remove specific request field exclusions that are associated with the
target of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
\
--request-header-to-exclude=op=EQUALS,val=abc \
--request-header-to-exclude=op=STARTS_WITH,val=xyz \
--request-uri-to-exclude=op=EQUALS_ANY
To remove all the request field exclusions that are associated with the target
of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
To remove all the request field exclusions that are associated with the target
of 'sqli-stable': [], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable
To remove all the request field exclusions that are configured under the
security policy rule, regardless of the target, run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=*
"""
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class RemovePreconfigWafExclusionAlpha(RemovePreconfigWafExclusionBeta):
r"""Remove an exclusion configuration for preconfigured WAF evaluation from a security policy rule.
*{command}* is used to remove an exclusion configuration for preconfigured WAF
evaluation from a security policy rule.
Note that request field exclusions are associated with a target, which can be
a single rule set, or a rule set plus a list of rule IDs under the rule set.
It is possible to remove request field exclusions at 3 levels:
- Remove specific request field exclusions that are associated with a matching
target.
- Remove all the request field exclusions that are associated with a matching
target.
- Remove all the request field exclusions that are configured under the
security policy rule, regardless of the target.
## EXAMPLES
To remove specific request field exclusions that are associated with the
target of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
\
--request-header-to-exclude=op=EQUALS,val=abc \
--request-header-to-exclude=op=STARTS_WITH,val=xyz \
--request-uri-to-exclude=op=EQUALS_ANY
To remove all the request field exclusions that are associated with the target
of 'sqli-stable': ['owasp-crs-v030001-id942110-sqli',
'owasp-crs-v030001-id942120-sqli'], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable \
--target-rule-ids=owasp-crs-v030001-id942110-sqli,owasp-crs-v030001-id942120-sqli
To remove all the request field exclusions that are associated with the target
of 'sqli-stable': [], run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=sqli-stable
To remove all the request field exclusions that are configured under the
security policy rule, regardless of the target, run:
$ {command} 1000 \
--security-policy=my-policy \
--target-rule-set=*
"""

View File

@@ -0,0 +1,367 @@
# -*- 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 security policies rules."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags as security_policy_flags
from googlecloudsdk.command_lib.compute.security_policies import security_policies_utils
from googlecloudsdk.command_lib.compute.security_policies.rules import flags
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
class UpdateHelper(object):
r"""Update a Compute Engine security policy rule.
*{command}* is used to update security policy rules.
## EXAMPLES
To update the description and IP ranges of a rule at priority
1000, run:
$ {command} 1000 \
--security-policy=my-policy \
--description="block 1.2.3.4/32" \
--src-ip-ranges=1.2.3.4/32
"""
@classmethod
def Args(
cls,
parser,
support_fairshare=False,
support_rpc_status=False,
):
"""Generates the flagset for an Update command."""
cls.NAME_ARG = (flags.PriorityArgument('update'))
cls.NAME_ARG.AddArgument(
parser, operation_type='update', cust_metavar='PRIORITY')
flags.AddRegionFlag(parser, 'update')
cls.SECURITY_POLICY_ARG = (
security_policy_flags.SecurityPolicyMultiScopeArgumentForRules()
)
cls.SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddMatcherAndNetworkMatcher(parser, required=False)
flags.AddAction(
parser,
required=False,
support_fairshare=support_fairshare)
flags.AddDescription(parser)
flags.AddPreview(parser, for_update=True)
flags.AddRedirectOptions(parser)
flags.AddRateLimitOptions(
parser,
support_rpc_status=support_rpc_status,
)
flags.AddRequestHeadersToAdd(parser)
flags.AddRecaptchaOptions(parser)
@classmethod
def Run(
cls,
release_track,
args,
support_rpc_status,
):
"""Validates arguments and patches a security policy rule."""
modified_fields = [
args.description,
args.src_ip_ranges,
args.action,
args.preview is not None,
args.network_user_defined_fields,
args.network_src_ip_ranges,
args.network_dest_ip_ranges,
args.network_ip_protocols,
args.network_src_ports,
args.network_dest_ports,
args.network_src_region_codes,
args.network_src_asns,
args.redirect_type,
args.redirect_target,
args.request_headers_to_add,
args.rate_limit_threshold_count,
args.rate_limit_threshold_interval_sec,
args.conform_action,
args.exceed_action,
args.enforce_on_key,
args.enforce_on_key_name,
args.ban_threshold_count,
args.ban_threshold_interval_sec,
args.ban_duration_sec,
args.recaptcha_action_site_keys,
args.recaptcha_session_site_keys,
]
min_args = [
'--description',
'--src-ip-ranges',
'--expression',
'--action',
'--preview',
'--network-user-defined-fields',
'--network-src-ip-ranges',
'--network-dest-ip-ranges',
'--network-ip-protocols',
'--network-src-ports',
'--network-dest-ports',
'--network-src-region-codes',
'--redirect-type',
'--redirect-target',
'--request-headers-to-add',
'--rate-limit-threshold-count',
'--rate-limit-threshold-interval-sec',
'--conform-action',
'--exceed-action',
'--enforce-on-key',
'--enforce-on-key-name',
'--ban-threshold-count',
'--ban-threshold-interval-sec',
'--ban-duration-sec',
'--recaptcha_action_site_keys',
'--recaptcha_session_site_keys',
]
if support_rpc_status:
modified_fields.extend([
args.exceed_action_rpc_status_code,
args.exceed_action_rpc_status_message,
])
min_args.extend([
'--exceed-action-rpc-status-code',
'--exceed-action-rpc-status-message',
])
if not any(
[args.IsSpecified(field[2:].replace('-', '_')) for field in min_args]):
raise exceptions.MinimumArgumentException(
min_args, 'At least one property must be modified.')
holder = base_classes.ComputeApiHolder(release_track)
if args.security_policy:
security_policy_ref = cls.SECURITY_POLICY_ARG.ResolveAsResource(
args,
holder.resources,
default_scope=compute_scope.ScopeEnum.GLOBAL)
if getattr(security_policy_ref, 'region', None) is not None:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': security_policy_ref.region,
'securityPolicy': args.security_policy,
})
else:
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'securityPolicy': args.security_policy,
},
)
else:
try:
ref = holder.resources.Parse(
args.name,
collection='compute.regionSecurityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
'region': getattr(args, 'region', None),
},
)
except (
resources.RequiredFieldOmittedException,
resources.WrongResourceCollectionException,
):
ref = holder.resources.Parse(
args.name,
collection='compute.securityPolicyRules',
params={
'project': properties.VALUES.core.project.GetOrFail,
},
)
security_policy_rule = client.SecurityPolicyRule(
ref, compute_client=holder.client)
redirect_options = security_policies_utils.CreateRedirectOptions(
holder.client, args
)
rate_limit_options = security_policies_utils.CreateRateLimitOptions(
holder.client, args, support_rpc_status
)
request_headers_to_add = args.request_headers_to_add
expression_options = security_policies_utils.CreateExpressionOptions(
holder.client, args
)
result = security_policies_utils.CreateNetworkMatcher(
holder.client, args
)
network_matcher = result[0]
update_mask = result[1]
if args.IsSpecified('action') and args.action not in ['redirect']:
update_mask.append('redirect_options')
if args.IsSpecified('action') and args.action not in [
'throttle',
'rate-based-ban',
'fairshare',
]:
update_mask.append('rate_limit_options')
elif args.IsSpecified('exceed_action') and args.exceed_action not in [
'redirect'
]:
update_mask.append('rate_limit_options.exceed_redirect_options')
update_mask_str = ','.join(update_mask)
return security_policy_rule.Patch(
src_ip_ranges=args.src_ip_ranges,
expression=args.expression,
expression_options=expression_options,
network_matcher=network_matcher,
action=args.action,
description=args.description,
preview=args.preview,
redirect_options=redirect_options,
rate_limit_options=rate_limit_options,
request_headers_to_add=request_headers_to_add,
update_mask=update_mask_str if update_mask_str else None,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class UpdateGA(base.UpdateCommand):
r"""Update a Compute Engine security policy rule.
*{command}* is used to update security policy rules.
## EXAMPLES
To update the description and IP ranges of a rule at priority
1000, run:
$ {command} 1000 \
--security-policy=my-policy \
--description="block 1.2.3.4/32" \
--src-ip-ranges=1.2.3.4/32
"""
SECURITY_POLICY_ARG = None
NAME_ARG = None
_support_rpc_status = False
@classmethod
def Args(cls, parser):
UpdateHelper.Args(
parser,
support_rpc_status=cls._support_rpc_status,
)
def Run(self, args):
return UpdateHelper.Run(
self.ReleaseTrack(),
args,
self._support_rpc_status,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(base.UpdateCommand):
r"""Update a Compute Engine security policy rule.
*{command}* is used to update security policy rules.
## EXAMPLES
To update the description and IP ranges of a rule at priority
1000, run:
$ {command} 1000 \
--security-policy=my-policy \
--description="block 1.2.3.4/32" \
--src-ip-ranges=1.2.3.4/32
"""
SECURITY_POLICY_ARG = None
_support_rpc_status = False
@classmethod
def Args(cls, parser):
UpdateHelper.Args(
parser,
support_fairshare=True,
support_rpc_status=cls._support_rpc_status,
)
def Run(self, args):
return UpdateHelper.Run(
self.ReleaseTrack(),
args,
self._support_rpc_status,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(base.UpdateCommand):
r"""Update a Compute Engine security policy rule.
*{command}* is used to update security policy rules.
## EXAMPLES
To update the description and IP ranges of a rule at priority
1000, run:
$ {command} 1000 \
--security-policy=my-policy \
--description="block 1.2.3.4/32" \
--src-ip-ranges=1.2.3.4/32
"""
SECURITY_POLICY_ARG = None
_support_rpc_status = True
@classmethod
def Args(cls, parser):
UpdateHelper.Args(
parser,
support_fairshare=True,
support_rpc_status=cls._support_rpc_status,
)
def Run(self, args):
return UpdateHelper.Run(
self.ReleaseTrack(),
args,
self._support_rpc_status,
)

View File

@@ -0,0 +1,473 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for updating security policies."""
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.security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute import scope as compute_scope
from googlecloudsdk.command_lib.compute.security_policies import flags
from googlecloudsdk.command_lib.compute.security_policies import security_policies_utils
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.DefaultUniverseOnly
class UpdateGa(base.UpdateCommand):
"""Update a Compute Engine security policy.
*{command}* is used to update security policies.
## EXAMPLES
To update the description run this:
$ {command} SECURITY_POLICY --description='new description'
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='update')
parser.add_argument(
'--description',
help=('An optional, textual description for the security policy.'))
flags.AddCloudArmorAdaptiveProtection(parser)
flags.AddAdvancedOptions(parser)
flags.AddRecaptchaOptions(parser)
flags.AddDdosProtectionConfigWithAdvancedPreview(parser)
def _ValidateArgs(self, args):
"""Validates that at least one field to update is specified.
Args:
args: The arguments given to the update command.
"""
if not (args.IsSpecified('description') or
args.IsSpecified('enable_layer7_ddos_defense') or
args.IsSpecified('layer7_ddos_defense_rule_visibility') or
args.IsSpecified('json_parsing') or
args.IsSpecified('json_custom_content_types') or
args.IsSpecified('log_level') or
args.IsSpecified('recaptcha_redirect_site_key') or
args.IsSpecified('network_ddos_protection') or
args.IsSpecified('user_ip_request_headers')):
parameter_names = [
'--description', '--enable-layer7-ddos-defense',
'--layer7-ddos-defense-rule-visibility', '--json-parsing',
'--json-custom-content-types', '--log-level',
'--recaptcha-redirect-site-key', '--network-ddos-protection',
'--user-ip-request-headers'
]
raise exceptions.MinimumArgumentException(
parameter_names, 'Please specify at least one property to update')
def Run(self, args):
self._ValidateArgs(args)
field_mask = []
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(
ref=ref, compute_client=holder.client)
existing_security_policy = security_policy.Describe()[0]
description = existing_security_policy.description
adaptive_protection_config = (
existing_security_policy.adaptiveProtectionConfig)
advanced_options_config = existing_security_policy.advancedOptionsConfig
recaptcha_options_config = existing_security_policy.recaptchaOptionsConfig
ddos_protection_config = existing_security_policy.ddosProtectionConfig
if args.description is not None:
description = args.description
if (args.IsSpecified('enable_layer7_ddos_defense') or
args.IsSpecified('layer7_ddos_defense_rule_visibility')):
adaptive_protection_config = (
security_policies_utils.CreateAdaptiveProtectionConfig(
holder.client, args, adaptive_protection_config))
if (args.IsSpecified('json_parsing') or
args.IsSpecified('json_custom_content_types') or
args.IsSpecified('log_level') or
args.IsSpecified('user_ip_request_headers')):
advanced_options_config = (
security_policies_utils.CreateAdvancedOptionsConfig(
holder.client,
args,
advanced_options_config,
enable_large_body_size=False,
)
)
if args.IsSpecified('recaptcha_redirect_site_key'):
recaptcha_options_config = (
security_policies_utils.CreateRecaptchaOptionsConfig(
holder.client, args, recaptcha_options_config))
if args.IsSpecified('network_ddos_protection'):
ddos_protection_config = (
security_policies_utils.CreateDdosProtectionConfig(
holder.client, args, ddos_protection_config))
field_mask.append('ddos_protection_config')
updated_security_policy = holder.client.messages.SecurityPolicy(
description=description,
adaptiveProtectionConfig=adaptive_protection_config,
advancedOptionsConfig=advanced_options_config,
recaptchaOptionsConfig=recaptcha_options_config,
ddosProtectionConfig=ddos_protection_config,
fingerprint=existing_security_policy.fingerprint)
return security_policy.Patch(
security_policy=updated_security_policy,
field_mask=','.join(field_mask))
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@base.DefaultUniverseOnly
class UpdateBeta(UpdateGa):
"""Update a Compute Engine security policy.
*{command}* is used to update security policies.
## EXAMPLES
To update the description run this:
$ {command} SECURITY_POLICY --description='new description'
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='update')
parser.add_argument(
'--description',
help=('An optional, textual description for the security policy.'))
flags.AddCloudArmorAdaptiveProtection(parser)
flags.AddCloudArmorAdaptiveProtectionAutoDeploy(parser)
flags.AddAdvancedOptions(parser, enable_large_body_size=True)
flags.AddRecaptchaOptions(parser)
flags.AddDdosProtectionConfigWithAdvancedPreview(parser)
def _ValidateArgs(self, args):
"""Validates that at least one field to update is specified.
Args:
args: The arguments given to the update command.
"""
if not (
args.IsSpecified('description')
or args.IsSpecified('enable_layer7_ddos_defense')
or args.IsSpecified('layer7_ddos_defense_rule_visibility')
or args.IsSpecified('json_parsing')
or args.IsSpecified('json_custom_content_types')
or args.IsSpecified('log_level')
or args.IsSpecified('request_body_inspection_size')
or args.IsSpecified('user_ip_request_headers')
or args.IsSpecified('recaptcha_redirect_site_key')
or args.IsSpecified('network_ddos_protection')
or args.IsSpecified('layer7_ddos_defense_auto_deploy_load_threshold')
or args.IsSpecified(
'layer7_ddos_defense_auto_deploy_confidence_threshold'
)
or args.IsSpecified(
'layer7_ddos_defense_auto_deploy_impacted_baseline_threshold'
)
or args.IsSpecified('layer7_ddos_defense_auto_deploy_expiration_sec')
):
parameter_names = [
'--description',
'--enable-layer7-ddos-defense',
'--layer7-ddos-defense-rule-visibility',
'--json-parsing',
'--json-custom-content-types',
'--log-level',
'--user-ip-request-headers',
'--request-body-inspection-size',
'--recaptcha-redirect-site-key',
'--network-ddos-protection',
'--layer7-ddos-defense-auto-deploy-load-threshold',
'--layer7-ddos-defense-auto-deploy-confidence-threshold',
'--layer7-ddos-defense-auto-deploy-impacted-baseline-threshold',
'--layer7-ddos-defense-auto-deploy-expiration-sec',
]
raise exceptions.MinimumArgumentException(
parameter_names, 'Please specify at least one property to update')
def Run(self, args):
self._ValidateArgs(args)
field_mask = []
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(
ref=ref, compute_client=holder.client)
existing_security_policy = security_policy.Describe()[0]
description = existing_security_policy.description
adaptive_protection_config = (
existing_security_policy.adaptiveProtectionConfig)
advanced_options_config = existing_security_policy.advancedOptionsConfig
recaptcha_options_config = existing_security_policy.recaptchaOptionsConfig
ddos_protection_config = existing_security_policy.ddosProtectionConfig
if args.description is not None:
description = args.description
if (args.IsSpecified('enable_layer7_ddos_defense') or
args.IsSpecified('layer7_ddos_defense_rule_visibility') or
args.IsSpecified('layer7_ddos_defense_auto_deploy_load_threshold') or
args.IsSpecified('layer7_ddos_defense_auto_deploy_confidence_threshold')
or args.IsSpecified(
'layer7_ddos_defense_auto_deploy_impacted_baseline_threshold') or
args.IsSpecified('layer7_ddos_defense_auto_deploy_expiration_sec')):
adaptive_protection_config = (
security_policies_utils
.CreateAdaptiveProtectionConfigWithAutoDeployConfig(
holder.client, args, adaptive_protection_config))
if (
args.IsSpecified('json_parsing')
or args.IsSpecified('json_custom_content_types')
or args.IsSpecified('log_level')
or args.IsSpecified('request_body_inspection_size')
or args.IsSpecified('user_ip_request_headers')
):
advanced_options_config = (
security_policies_utils.CreateAdvancedOptionsConfig(
holder.client,
args,
advanced_options_config,
enable_large_body_size=True,
)
)
if args.IsSpecified('recaptcha_redirect_site_key'):
recaptcha_options_config = (
security_policies_utils.CreateRecaptchaOptionsConfig(
holder.client, args, recaptcha_options_config))
if args.IsSpecified('network_ddos_protection'):
ddos_protection_config = (
security_policies_utils.CreateDdosProtectionConfig(
holder.client, args, ddos_protection_config))
field_mask.append('ddos_protection_config')
updated_security_policy = holder.client.messages.SecurityPolicy(
description=description,
adaptiveProtectionConfig=adaptive_protection_config,
advancedOptionsConfig=advanced_options_config,
recaptchaOptionsConfig=recaptcha_options_config,
ddosProtectionConfig=ddos_protection_config,
fingerprint=existing_security_policy.fingerprint)
return security_policy.Patch(
security_policy=updated_security_policy,
field_mask=','.join(field_mask))
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@base.DefaultUniverseOnly
class UpdateAlpha(UpdateBeta):
"""Update a Compute Engine security policy.
*{command}* is used to update security policies.
## EXAMPLES
To update the description run this:
$ {command} SECURITY_POLICY --description='new description'
"""
SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.SECURITY_POLICY_ARG = flags.SecurityPolicyMultiScopeArgument()
cls.SECURITY_POLICY_ARG.AddArgument(parser, operation_type='update')
parser.add_argument(
'--description',
help=('An optional, textual description for the security policy.'))
flags.AddCloudArmorAdaptiveProtection(parser)
flags.AddCloudArmorAdaptiveProtectionAutoDeploy(parser)
flags.AddAdvancedOptions(parser, enable_large_body_size=True)
flags.AddRecaptchaOptions(parser)
flags.AddDdosProtectionConfigWithAdvancedPreview(parser)
flags.AddDdosProtectionConfigOld(parser)
flags.AddNetworkDdosAdaptiveProtection(parser)
flags.AddNetworkDdosImpactedBaselineThreshold(parser)
parser.add_argument(
'--enable-ml',
action='store_true',
default=None,
help=('Whether to enable Cloud Armor Adaptive Protection'))
def _ValidateArgs(self, args):
"""Validates that at least one field to update is specified.
Args:
args: The arguments given to the update command.
"""
if not (
args.IsSpecified('description')
or args.IsSpecified('enable_ml')
or args.IsSpecified('enable_layer7_ddos_defense')
or args.IsSpecified('layer7_ddos_defense_rule_visibility')
or args.IsSpecified('json_parsing')
or args.IsSpecified('json_custom_content_types')
or args.IsSpecified('log_level')
or args.IsSpecified('request_body_inspection_size')
or args.IsSpecified('user_ip_request_headers')
or args.IsSpecified('recaptcha_redirect_site_key')
or args.IsSpecified('network_ddos_protection')
or args.IsSpecified('network_ddos_adaptive_protection')
or args.IsSpecified('network_ddos_impacted_baseline_threshold')
or args.IsSpecified('clear_network_ddos_impacted_baseline_threshold')
or args.IsSpecified('ddos_protection')
):
parameter_names = [
'--description',
'--enable-ml',
'--enable-layer7-ddos-defense',
'--layer7-ddos-defense-rule-visibility',
'--json-parsing',
'--json-custom-content-types',
'--log-level',
'--request-body-inspection-size',
'--user-ip-request-headers',
'--recaptcha-redirect-site-key',
'--network-ddos-protection',
'--network-ddos-adaptive-protection',
'--network-ddos-impacted-baseline-threshold',
'--clear-network-ddos-impacted-baseline-threshold',
'--ddos-protection',
]
raise exceptions.MinimumArgumentException(
parameter_names, 'Please specify at least one property to update')
def Run(self, args):
self._ValidateArgs(args)
field_mask = []
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, default_scope=compute_scope.ScopeEnum.GLOBAL)
security_policy = client.SecurityPolicy(
ref=ref, compute_client=holder.client)
existing_security_policy = security_policy.Describe()[0]
description = existing_security_policy.description
cloud_armor_config = existing_security_policy.cloudArmorConfig
adaptive_protection_config = (
existing_security_policy.adaptiveProtectionConfig)
advanced_options_config = existing_security_policy.advancedOptionsConfig
recaptcha_options_config = existing_security_policy.recaptchaOptionsConfig
ddos_protection_config = existing_security_policy.ddosProtectionConfig
if args.description is not None:
description = args.description
if args.enable_ml is not None:
cloud_armor_config = security_policies_utils.CreateCloudArmorConfig(
holder.client, args)
if (args.IsSpecified('enable_layer7_ddos_defense') or
args.IsSpecified('layer7_ddos_defense_rule_visibility') or
args.IsSpecified('layer7_ddos_defense_auto_deploy_load_threshold') or
args.IsSpecified('layer7_ddos_defense_auto_deploy_confidence_threshold')
or args.IsSpecified(
'layer7_ddos_defense_auto_deploy_impacted_baseline_threshold') or
args.IsSpecified('layer7_ddos_defense_auto_deploy_expiration_sec')):
adaptive_protection_config = (
security_policies_utils
.CreateAdaptiveProtectionConfigWithAutoDeployConfig(
holder.client, args, adaptive_protection_config))
if (
args.IsSpecified('json_parsing')
or args.IsSpecified('json_custom_content_types')
or args.IsSpecified('log_level')
or args.IsSpecified('request_body_inspection_size')
or args.IsSpecified('user_ip_request_headers')
):
advanced_options_config = (
security_policies_utils.CreateAdvancedOptionsConfig(
holder.client,
args,
advanced_options_config,
enable_large_body_size=True,
)
)
if args.IsSpecified('recaptcha_redirect_site_key'):
recaptcha_options_config = (
security_policies_utils.CreateRecaptchaOptionsConfig(
holder.client, args, recaptcha_options_config))
if args.IsSpecified('ddos_protection'):
ddos_protection_config = (
security_policies_utils.CreateDdosProtectionConfigOld(
holder.client, args, ddos_protection_config))
if 'ddos_protection_config' not in field_mask:
field_mask.append('ddos_protection_config')
if args.IsSpecified('network_ddos_protection'):
ddos_protection_config = (
security_policies_utils.CreateDdosProtectionConfig(
holder.client, args, ddos_protection_config))
if 'ddos_protection_config' not in field_mask:
field_mask.append('ddos_protection_config')
if args.IsSpecified('network_ddos_adaptive_protection'):
ddos_protection_config = security_policies_utils.CreateDdosProtectionConfigWithDdosAdaptiveProtection(
holder.client, args, ddos_protection_config
)
if 'ddos_protection_config' not in field_mask:
field_mask.append('ddos_protection_config')
if args.IsSpecified('network_ddos_impacted_baseline_threshold'):
ddos_protection_config = security_policies_utils.CreateDdosProtectionConfigWithNetworkDdosImpactedBaselineThreshold(
holder.client, args, ddos_protection_config
)
if 'ddos_protection_config' not in field_mask:
field_mask.append('ddos_protection_config')
field_mask.append(
'ddos_protection_config.ddos_impacted_baseline_threshold'
)
elif args.IsSpecified('clear_network_ddos_impacted_baseline_threshold'):
if ddos_protection_config is None:
ddos_protection_config = (
holder.client.messages.SecurityPolicyDdosProtectionConfig()
)
ddos_protection_config.ddosImpactedBaselineThreshold = None
if 'ddos_protection_config' not in field_mask:
field_mask.append('ddos_protection_config')
field_mask.append(
'ddos_protection_config.ddos_impacted_baseline_threshold'
)
updated_security_policy = holder.client.messages.SecurityPolicy(
description=description,
cloudArmorConfig=cloud_armor_config,
adaptiveProtectionConfig=adaptive_protection_config,
advancedOptionsConfig=advanced_options_config,
recaptchaOptionsConfig=recaptcha_options_config,
ddosProtectionConfig=ddos_protection_config,
fingerprint=existing_security_policy.fingerprint)
return security_policy.Patch(
security_policy=updated_security_policy,
field_mask=','.join(field_mask))