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,39 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""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.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class OrgSecurityPolicies(base.Group):
"""Manage Compute Engine organization security policies.
Manage Compute Engine organization security policies. Organization
security policies are used to control incoming/outgoing traffic.
"""
category = base.COMPUTE_CATEGORY
OrgSecurityPolicies.detailed_help = {
'brief': ('Manage Compute Engine organization security policies.'),
}

View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Commands for reading and manipulating organization security policies associations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class SecurityPolicyAssociations(base.Group):
"""Read and manipulate Compute Engine organization security policy associations."""

View File

@@ -0,0 +1,129 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for creating organization security policy associations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import sys
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
from googlecloudsdk.core import log
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Create(base.CreateCommand):
"""Create a new association between a security policy and an organization or folder resource.
*{command}* is used to create organization security policy associations. An
organization security policy is a set of rules that controls access to various
resources.
This command has billing implications. Projects in the hierarchy with
effective hierarchical security policies will be automatically enrolled into
Cloud Armor Enterprise if not already enrolled.
"""
@classmethod
def Args(cls, parser):
flags.AddArgsCreateAssociation(parser)
parser.display_info.AddCacheUpdater(flags.OrgSecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
org_security_policy = client.OrgSecurityPolicy(
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
name = None
attachment_id = None
replace_existing_association = False
excluded_projects = []
excluded_folders = []
if args.IsSpecified('name'):
name = args.name
if args.IsSpecified('project_number'):
attachment_id = 'projects/' + args.project_number
if name is None:
name = 'project-' + args.project_number
if args.IsSpecified('folder'):
attachment_id = 'folders/' + args.folder
if name is None:
name = 'folder-' + args.folder
if args.IsSpecified('organization') and attachment_id is None:
attachment_id = 'organizations/' + args.organization
if name is None:
name = 'organization-' + args.organization
if attachment_id is None:
log.error(
'Must specify attachment ID with --organization=ORGANIZATION or '
'--folder=FOLDER or --project-number=PROJECT.')
sys.exit()
if args.IsSpecified('excluded_projects'):
excluded_projects = args.excluded_projects
if args.IsSpecified('excluded_folders'):
excluded_folders = args.excluded_folders
if args.replace_association_on_target:
replace_existing_association = True
association = holder.client.messages.SecurityPolicyAssociation(
attachmentId=attachment_id,
name=name,
excludedProjects=excluded_projects,
excludedFolders=excluded_folders,
)
log.status.Print("""\
This command has billing implications. Projects in the hierarchy with
effective organization security policies will be automatically enrolled into
Cloud Armor Enterprise if not already enrolled.""")
security_policy_id = org_security_policies_utils.GetSecurityPolicyId(
org_security_policy,
args.security_policy,
organization=args.organization)
return org_security_policy.AddAssociation(
association=association,
security_policy_id=security_policy_id,
replace_existing_association=replace_existing_association,
only_generate_request=False)
Create.detailed_help = {
'EXAMPLES':
"""\
To associate an organization security policy under folder with ID
``123456789'' to folder ``987654321'', run:
$ {command} --security-policy=123456789 --folder=987654321
""",
}

View File

@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for deleting organization security policy association."""
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.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete a Compute Engine organization security policy association.
*{command}* is used to delete organization security policy association.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyAssociationsArgument(
required=True)
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='delete')
flags.AddArgsDeleteAssociation(parser)
parser.display_info.AddCacheUpdater(flags.OrgSecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
org_security_policy = client.OrgSecurityPolicy(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
security_policy_id = org_security_policies_utils.GetSecurityPolicyId(
org_security_policy,
args.security_policy,
organization=args.organization)
return org_security_policy.DeleteAssociation(
security_policy_id=security_policy_id, only_generate_request=False)
Delete.detailed_help = {
'EXAMPLES':
"""\
To delete an association with name ``example-association'' of an organization
security policy with ID ``123456789'', run:
$ {command} example-association --security-policy=123456789
""",
}

View File

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for listing the associations of an organization or folder resource."""
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.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
import six
DEFAULT_LIST_FORMAT = """\
table(
name,
displayName,
shortName,
securityPolicyId,
excludedProjects,
excludedFolders
)"""
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.DescribeCommand, base.ListCommand):
"""List the associations of an organization or folder resource.
*{command}* is used to list the associations of an organization or folder
resource.
"""
@classmethod
def Args(cls, parser):
flags.AddArgsListAssociation(parser)
parser.display_info.AddFormat(DEFAULT_LIST_FORMAT)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
org_security_policy = client.OrgSecurityPolicy(
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
target_resource = None
if args.IsSpecified('organization'):
target_resource = 'organizations/' + args.organization
elif args.IsSpecified('folder'):
target_resource = 'folders/' + args.folder
res = org_security_policy.ListAssociations(
target_resource=target_resource, only_generate_request=False)
if not res:
return None
return res[0].associations
List.detailed_help = {
'EXAMPLES':
"""\
To list the associations of the folder with ID ``987654321'', run:
$ {command} --folder=987654321
""",
}

View File

@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for replace rules of organization 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.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class CopyRules(base.UpdateCommand):
"""Replace the rules of a Compute Engine organization security policy with rules from another policy.
*{command}* is used to replace the rules of organization security policies. An
organization security policy is a set of rules that controls access to
various resources.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyArgument(
required=True, operation='copy the rules to')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='copy-rules')
flags.AddArgsCopyRules(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
org_security_policy = client.OrgSecurityPolicy(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
dest_sp_id = org_security_policies_utils.GetSecurityPolicyId(
org_security_policy, ref.Name(), organization=args.organization)
return org_security_policy.CopyRules(
only_generate_request=False,
dest_sp_id=dest_sp_id,
source_security_policy=args.source_security_policy)
CopyRules.detailed_help = {
'EXAMPLES':
"""\
To copy the rules of an organization security policy with ID ``123456789'',
from another organization security policy with ID ``987654321'', run:
$ {command} 123456789 --source-security-policy=987654321
""",
}

View File

@@ -0,0 +1,127 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for creating organization 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.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.security_policies import security_policies_utils
from googlecloudsdk.core.util import files
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Create(base.CreateCommand):
"""Create a Compute Engine organization security policy.
*{command}* is used to create organization security policies. An organization
security policy is a set of rules that controls access to various resources.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
flags.AddArgSpCreation(parser)
parser.display_info.AddCacheUpdater(flags.OrgSecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
org_security_policy = client.OrgSecurityPolicy(
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
if args.IsSpecified('organization'):
parent_id = 'organizations/' + args.organization
elif args.IsSpecified('folder'):
parent_id = 'folders/' + args.folder
if args.IsSpecified('file_name'):
security_policy = self._GetTemplateFromFile(args, holder.client.messages)
else:
if args.IsSpecified('type') and args.type == 'CLOUD_ARMOR':
security_policy = holder.client.messages.SecurityPolicy(
description=args.description,
shortName=args.short_name,
type=(
holder.client.messages.SecurityPolicy.TypeValueValuesEnum.CLOUD_ARMOR
),
)
else:
security_policy = holder.client.messages.SecurityPolicy(
description=args.description,
displayName=args.display_name,
type=(
holder.client.messages.SecurityPolicy.TypeValueValuesEnum.FIREWALL
),
)
return org_security_policy.Create(
security_policy=security_policy,
parent_id=parent_id,
only_generate_request=False)
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)
Create.detailed_help = {
'EXAMPLES': """\
To create an organization security policy under folder with ID ``123456789'',
run:
$ {command} --short-name=my-policy --folder=123456789
To create an organization security under organization with ID ``12345'' from
an input file, run:
$ {command} --file-name=my-file-name --organization=12345
""",
}

View File

@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for deleting organization 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.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete a Compute Engine organization security policy.
*{command}* is used to delete organization security policies. An organization
security policy is a set of rules that controls access to various resources.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyArgument(
required=True, operation='delete')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='delete')
parser.add_argument(
'--organization',
help=('Organization in which the organization security policy is to be'
' deleted. Must be set if SECURITY_POLICY is short name.'))
parser.display_info.AddCacheUpdater(flags.OrgSecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
org_security_policy = client.OrgSecurityPolicy(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
sp_id = org_security_policies_utils.GetSecurityPolicyId(
org_security_policy, ref.Name(), organization=args.organization)
return org_security_policy.Delete(sp_id=sp_id, only_generate_request=False)
Delete.detailed_help = {
'EXAMPLES':
"""\
To delete an organization security policy with ID ``123456789'', run:
$ {command} 123456789
""",
}

View File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for describing organization 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.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine organization security policy.
*{command}* is used to describe organization security policies. An
organization security policy is a set of rules that controls access to various
resources.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyArgument(
required=True, operation='describe')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='get')
parser.add_argument(
'--organization',
help=('Organization in which the organization security policy is to be'
' described. Must be set if SECURITY_POLICY is short name.'))
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
org_security_policy = client.OrgSecurityPolicy(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
sp_id = org_security_policies_utils.GetSecurityPolicyId(
org_security_policy, ref.Name(), organization=args.organization)
return org_security_policy.Describe(
sp_id=sp_id, only_generate_request=False)
Describe.detailed_help = {
'EXAMPLES':
"""\
To describe an organization security policy with ID ``123456789'', run:
$ {command} 123456789
""",
}

View File

@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for listing organization security policies."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import list_pager
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import lister
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class List(base.ListCommand):
"""List Compute Engine organization security policies.
*{command}* is used to list organization security policies. An organization
security policy is a set of rules that controls access to various resources.
"""
@classmethod
def Args(cls, parser):
flags.AddArgsListSp(parser)
parser.display_info.AddFormat(flags.DEFAULT_LIST_FORMAT)
lister.AddBaseListerArgs(parser)
parser.display_info.AddCacheUpdater(flags.OrgSecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client.apitools_client
messages = client.MESSAGES_MODULE
if args.organization:
parent_id = 'organizations/' + args.organization
elif args.folder:
parent_id = 'folders/' + args.folder
request = messages.ComputeOrganizationSecurityPoliciesListRequest(
parentId=parent_id)
return list_pager.YieldFromList(
client.organizationSecurityPolicies,
request,
field='items',
limit=args.limit,
batch_size=None)
List.detailed_help = {
'EXAMPLES':
"""\
To list organization security policies under folder with ID
``123456789'', run:
$ {command} --folder=123456789
""",
}

View File

@@ -0,0 +1,121 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for listing the rules of organization 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 firewalls_utils
from googlecloudsdk.api_lib.compute import lister
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
from googlecloudsdk.core import log
import six
LIST_NOTICE = """\
To show all fields of the organization security policy rules, please show in
JSON format: --format=json
To show more fields in table format, please see the examples in --help.
"""
DEFAULT_LIST_FORMAT = """\
table(
priority,
direction,
action,
preview,
match.expr.expression:label=EXPRESSION,
match.config.srcIpRanges.list():label=SRC_RANGES,
match.config.destIpRanges.list():label=DEST_RANGES,
match.config.layer4Configs.map().org_firewall_rule().list():label=PORT_RANGES
)"""
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class ListRules(base.DescribeCommand, base.ListCommand):
"""List the rules of a Compute Engine organization security policy.
*{command}* is used to list the rules of an organization security policy.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyArgument(
required=True, operation='list rules for')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='get')
parser.add_argument(
'--organization',
help=('Organization which the organization security policy belongs to. '
'Must be set if SECURITY_POLICY is display name.'))
parser.display_info.AddFormat(DEFAULT_LIST_FORMAT)
lister.AddBaseListerArgs(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
org_security_policy = client.OrgSecurityPolicy(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
sp_id = org_security_policies_utils.GetSecurityPolicyId(
org_security_policy, ref.Name(), organization=args.organization)
response = org_security_policy.Describe(
sp_id=sp_id, only_generate_request=False)
if not response:
return None
return firewalls_utils.SortOrgFirewallRules(holder.client,
response[0].rules)
def Epilog(self, resources_were_displayed):
del resources_were_displayed
log.status.Print('\n' + LIST_NOTICE)
ListRules.detailed_help = {
'EXAMPLES':
"""\
To list the rules of an organization security policy with ID
``123456789'', run:
$ {command} 123456789
To list all the fields of the rules of an organization security policy with
ID ``123456789'', run:
$ {command} list-rules 123456789 --format="table(
priority,
action,
direction,
match.config.srcIpRanges.list():label=SRC_RANGES,
match.config.destIpRanges.list():label=DEST_RANGES,
match.config.layer4Configs.map().org_firewall_rule().list():label=PORT_RANGES,
targetServiceAccounts.list():label=TARGET_SVC_ACCT,
targetResources:label=TARGET_RESOURCES,
ruleTupleCount,
enableLogging,
description)"
""",
}

View File

@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for moving organization security policies."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import sys
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
from googlecloudsdk.core import log
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Move(base.UpdateCommand):
"""Move a Compute Engine organization security policy.
*{command}* is used to move is used to move organization security policies to
new parent nodes.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyArgument(
required=True, operation='move')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='move')
flags.AddArgsMove(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
org_security_policy = client.OrgSecurityPolicy(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
parent_id = None
if args.IsSpecified('organization'):
parent_id = 'organizations/' + args.organization
if args.IsSpecified('folder'):
parent_id = 'folders/' + args.folder
if parent_id is None:
log.error('Must specify parent id with --organization=ORGANIZATION or'
'--folder=FOLDER')
sys.exit()
sp_id = org_security_policies_utils.GetSecurityPolicyId(
org_security_policy, ref.Name(), organization=args.organization)
return org_security_policy.Move(
only_generate_request=False, sp_id=sp_id, parent_id=parent_id)
Move.detailed_help = {
'EXAMPLES':
"""\
To move an organization security policy under folder with ID ``123456789'' to
folder ``987654321'', run:
$ {command} 123456789 --folder=987654321
""",
}

View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Commands for reading and manipulating organization security policy rules."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class SecurityPolicyAssociations(base.Group):
"""Read and manipulate Compute Engine organization security policy rules."""

View File

@@ -0,0 +1,346 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for adding exclusions for preconfigured WAF rule evaluation to organization 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 import org_security_policy_rule_utils as rule_utils
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
from googlecloudsdk.command_lib.compute.security_policies.rules import flags as rule_flags
import six
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=1234567890 \
--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=1234567890 \
--target-rule-set=sqli-stable \
--request-cookie-to-exclude='op=EQUALS_ANY'
"""
@classmethod
def Args(cls, parser):
"""Generates the flagset for an AddPreconfigWafExclusion command."""
flags.AddOrganization(parser, required=False)
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyRuleArgument(
required=True, operation='add preconfig WAF exclusion'
)
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddSecurityPolicyId(parser, operation='updated')
rule_flags.AddTargetRuleSet(parser=parser, is_add=True)
rule_flags.AddTargetRuleIds(parser=parser, is_add=True)
rule_flags.AddRequestHeader(parser=parser, is_add=True)
rule_flags.AddRequestCookie(parser=parser, is_add=True)
rule_flags.AddRequestQueryParam(parser=parser, is_add=True)
rule_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 = cls.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False
)
priority = rule_utils.ConvertPriorityToInt(ref.Name())
security_policy_rule_client = client.OrgSecurityPolicyRule(
ref=ref,
compute_client=compute_client,
resources=holder.resources,
version=six.text_type(release_track).lower(),
)
security_policy_id = org_security_policies_utils.GetSecurityPolicyId(
security_policy_rule_client,
args.security_policy,
organization=args.organization,
)
existing_rule = security_policy_rule_client.Describe(
priority=priority,
security_policy_id=security_policy_id,
batch_mode=True,
)[0]
new_preconfig_waf_config = cls._UpdatePreconfigWafConfig(
compute_client, existing_rule, args)
security_policy_rule = holder.client.messages.SecurityPolicyRule(
preconfiguredWafConfig=new_preconfig_waf_config
)
return security_policy_rule_client.Update(
priority=priority,
security_policy=security_policy_id,
security_policy_rule=security_policy_rule,
batch_mode=True,
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class AddPreconfigWafExclusionBeta(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=1234567890 \
--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=1234567890 \
--target-rule-set=sqli-stable \
--request-cookie-to-exclude='op=EQUALS_ANY'
"""
ORG_SECURITY_POLICY_ARG = None
NAME_ARG = None
@classmethod
def Args(cls, parser):
AddPreconfigWafExclusionHelper.Args(
parser,
)
def Run(self, args):
return AddPreconfigWafExclusionHelper.Run(
self.ReleaseTrack(),
args,
)
@base.UniverseCompatible
@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=1234567890 \
--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=1234567890 \
--target-rule-set=sqli-stable \
--request-cookie-to-exclude='op=EQUALS_ANY'
"""

View File

@@ -0,0 +1,220 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for 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 import org_security_policy_rule_utils as rule_utils
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
from googlecloudsdk.command_lib.compute.security_policies.rules import flags as rule_flags
import six
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class Create(base.CreateCommand):
r"""Create a Compute Engine organizationsecurity policy rule.
*{command}* is used to create organization security policy rules.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyRuleArgument(
required=True, operation='create')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='create')
flags.AddAction(parser)
flags.AddSecurityPolicyId(parser, operation='inserted')
flags.AddDestIpRanges(parser)
flags.AddLayer4Configs(parser)
flags.AddDirection(parser)
flags.AddEnableLogging(parser)
flags.AddTargetResources(parser)
flags.AddTargetServiceAccounts(parser)
flags.AddDescription(parser)
flags.AddOrganization(parser, required=False)
rule_flags.AddMatcher(parser, required=False)
rule_flags.AddPreview(parser)
parser.add_argument(
'--cloud-armor',
action='store_true',
default=False,
help='Specified for Hierarchical Cloud Armor rules.',
)
parser.display_info.AddCacheUpdater(flags.OrgSecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
security_policy_rule_client = client.OrgSecurityPolicyRule(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
src_ip_ranges = []
dest_ip_ranges = []
dest_ports = []
layer4_configs = []
target_resources = []
target_service_accounts = []
enable_logging = None
preview = None
if args.IsSpecified('src_ip_ranges'):
src_ip_ranges = args.src_ip_ranges
if args.IsSpecified('dest_ip_ranges'):
dest_ip_ranges = args.dest_ip_ranges
if self.ReleaseTrack() == base.ReleaseTrack.ALPHA and args.IsSpecified(
'dest_ports'):
dest_ports = args.dest_ports
if args.IsSpecified('layer4_configs'):
layer4_configs = args.layer4_configs
if args.IsSpecified('target_resources'):
target_resources = args.target_resources
if args.IsSpecified('target_service_accounts'):
target_service_accounts = args.target_service_accounts
if args.IsSpecified('enable_logging'):
enable_logging = True
if args.IsSpecified('preview'):
preview = True
dest_ports_list = rule_utils.ParseDestPorts(dest_ports,
holder.client.messages)
layer4_config_list = rule_utils.ParseLayer4Configs(layer4_configs,
holder.client.messages)
traffic_direct = None
if args.IsSpecified('cloud_armor'):
if args.IsSpecified('expression'):
matcher = holder.client.messages.SecurityPolicyRuleMatcher(
expr=holder.client.messages.Expr(expression=args.expression)
)
else:
matcher = holder.client.messages.SecurityPolicyRuleMatcher(
versionedExpr=holder.client.messages.SecurityPolicyRuleMatcher.VersionedExprValueValuesEnum.SRC_IPS_V1,
config=holder.client.messages.SecurityPolicyRuleMatcherConfig(
srcIpRanges=src_ip_ranges
),
)
else:
if self.ReleaseTrack() == base.ReleaseTrack.ALPHA:
matcher = holder.client.messages.SecurityPolicyRuleMatcher(
versionedExpr=holder.client.messages.SecurityPolicyRuleMatcher.VersionedExprValueValuesEnum.FIREWALL,
config=holder.client.messages.SecurityPolicyRuleMatcherConfig(
srcIpRanges=src_ip_ranges,
destIpRanges=dest_ip_ranges,
destPorts=dest_ports_list,
layer4Configs=layer4_config_list,
),
)
else:
matcher = holder.client.messages.SecurityPolicyRuleMatcher(
versionedExpr=holder.client.messages.SecurityPolicyRuleMatcher.VersionedExprValueValuesEnum.FIREWALL,
config=holder.client.messages.SecurityPolicyRuleMatcherConfig(
srcIpRanges=src_ip_ranges,
destIpRanges=dest_ip_ranges,
layer4Configs=layer4_config_list,
),
)
traffic_direct = (
holder.client.messages.SecurityPolicyRule.DirectionValueValuesEnum.INGRESS
)
if args.IsSpecified('direction'):
if args.direction == 'INGRESS':
traffic_direct = (
holder.client.messages.SecurityPolicyRule.DirectionValueValuesEnum.INGRESS
)
else:
traffic_direct = (
holder.client.messages.SecurityPolicyRule.DirectionValueValuesEnum.EGRESS
)
security_policy_rule = holder.client.messages.SecurityPolicyRule(
priority=rule_utils.ConvertPriorityToInt(ref.Name()),
action=rule_utils.ConvertAction(args.action),
match=matcher,
description=args.description,
preview=preview)
if traffic_direct:
security_policy_rule.direction = traffic_direct
if target_resources:
security_policy_rule.targetResources = target_resources
if target_service_accounts:
security_policy_rule.targetServiceAccounts = target_service_accounts,
if enable_logging:
security_policy_rule.enableLogging = enable_logging
security_policy_id = org_security_policies_utils.GetSecurityPolicyId(
security_policy_rule_client,
args.security_policy,
organization=args.organization)
return security_policy_rule_client.Create(
security_policy=security_policy_id,
security_policy_rule=security_policy_rule)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(Create):
r"""Create a Compute Engine security policy rule.
*{command}* is used to create organization security policy rules.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyRuleArgument(
required=True, operation='create')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='create')
flags.AddAction(parser)
flags.AddSecurityPolicyId(parser, operation='inserted')
flags.AddDestIpRanges(parser)
flags.AddDestPorts(parser)
flags.AddLayer4Configs(parser)
flags.AddDirection(parser)
flags.AddEnableLogging(parser)
flags.AddTargetResources(parser)
flags.AddTargetServiceAccounts(parser)
flags.AddDescription(parser)
flags.AddOrganization(parser, required=False)
rule_flags.AddMatcher(parser, required=False)
rule_flags.AddPreview(parser)
parser.add_argument(
'--cloud-armor',
action='store_true',
default=False,
help='Specified for Hierarchical Cloud Armor rules.',
)
parser.display_info.AddCacheUpdater(flags.OrgSecurityPoliciesCompleter)
Create.detailed_help = {
'EXAMPLES': """\
To create a rule with priority ``10'' in an organization security policy with
ID ``123456789'', run:
$ {command} 10 --security-policy=123456789 --action=allow
--description=example-rule --cloud-armor
""",
}

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for deleting organization 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 import org_security_policy_rule_utils as rule_utils
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete a Compute Engine organization security policy rule.
*{command}* is used to delete organization security policy rule.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyRuleArgument(
required=True, operation="delete")
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddSecurityPolicyId(parser, operation="deleted")
flags.AddOrganization(parser, required=False)
parser.display_info.AddCacheUpdater(flags.OrgSecurityPoliciesCompleter)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
security_policy_rule_client = client.OrgSecurityPolicyRule(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
security_policy_id = org_security_policies_utils.GetSecurityPolicyId(
security_policy_rule_client,
args.security_policy,
organization=args.organization)
return security_policy_rule_client.Delete(
priority=rule_utils.ConvertPriorityToInt(ref.Name()),
security_policy_id=security_policy_id,
only_generate_request=False)
Delete.detailed_help = {
"EXAMPLES":
"""\
To delete a rule with priority ``10'' in an organization security policy with
ID ``123456789'', run:
$ {command} 10 --security-policy=123456789
""",
}

View File

@@ -0,0 +1,77 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for describing organization 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 import org_security_policy_rule_utils as rule_utils
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Describe(base.DescribeCommand):
"""Describe a Compute Engine organization security policy rule.
*{command}* is used to describe organization security policy rule.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyRuleArgument(
required=True, operation="describe")
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddOrganization(parser, required=False)
flags.AddSecurityPolicyId(parser, operation="described")
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
security_policy_rule_client = client.OrgSecurityPolicyRule(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
security_policy_id = org_security_policies_utils.GetSecurityPolicyId(
security_policy_rule_client,
args.security_policy,
organization=args.organization)
return security_policy_rule_client.Describe(
priority=rule_utils.ConvertPriorityToInt(ref.Name()),
security_policy_id=security_policy_id,
only_generate_request=False)
Describe.detailed_help = {
"EXAMPLES":
"""\
To describe a rule with priority ``10'' in an organization security policy
with ID ``123456789'', run:
$ {command} 10 --security-policy=123456789
""",
}

View File

@@ -0,0 +1,429 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for removing exclusions for preconfigured WAF rule evaluation from organization 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 import org_security_policy_rule_utils as rule_utils
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
from googlecloudsdk.command_lib.compute.security_policies.rules import flags as rule_flags
import six
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=1234567890 \
--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=1234567890 \
--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=1234567890 \
--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=1234567890 \
--target-rule-set=*
"""
@classmethod
def Args(cls, parser):
"""Generates the flagset for a RemovePreconfigWafExclusion command."""
flags.AddOrganization(parser, required=False)
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyRuleArgument(
required=True, operation='remove preconfig WAF exclusion')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddSecurityPolicyId(parser, operation='updated')
rule_flags.AddTargetRuleSet(parser=parser, is_add=False)
rule_flags.AddTargetRuleIds(parser=parser, is_add=False)
rule_flags.AddRequestHeader(parser=parser, is_add=False)
rule_flags.AddRequestCookie(parser=parser, is_add=False)
rule_flags.AddRequestQueryParam(parser=parser, is_add=False)
rule_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 = cls.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False
)
priority = rule_utils.ConvertPriorityToInt(ref.Name())
security_policy_rule_client = client.OrgSecurityPolicyRule(
ref=ref,
compute_client=compute_client,
resources=holder.resources,
version=six.text_type(release_track).lower(),
)
security_policy_id = org_security_policies_utils.GetSecurityPolicyId(
security_policy_rule_client,
args.security_policy,
organization=args.organization,
)
existing_rule = security_policy_rule_client.Describe(
priority=priority,
security_policy_id=security_policy_id,
batch_mode=True,
)[0]
new_preconfig_waf_config = cls._UpdatePreconfigWafConfig(
compute_client, existing_rule, args)
security_policy_rule = holder.client.messages.SecurityPolicyRule(
preconfiguredWafConfig=new_preconfig_waf_config
)
return security_policy_rule_client.Update(
priority=priority,
security_policy=security_policy_id,
security_policy_rule=security_policy_rule,
batch_mode=True,)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class RemovePreconfigWafExclusionBeta(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=1234567890 \
--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=1234567890 \
--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=1234567890 \
--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=1234567890 \
--target-rule-set=*
"""
ORG_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.UniverseCompatible
@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=1234567890 \
--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=1234567890 \
--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=1234567890 \
--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=1234567890 \
--target-rule-set=*
"""

View File

@@ -0,0 +1,251 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for 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 import org_security_policy_rule_utils as rule_utils
from googlecloudsdk.api_lib.compute.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
from googlecloudsdk.command_lib.compute.security_policies.rules import flags as rule_flags
import six
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
r"""Update a Compute Engine security policy rule.
*{command}* is used to update organization security policy rules.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyRuleArgument(
required=True, operation='update')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddAction(parser, required=False)
flags.AddSecurityPolicyId(parser, operation='updated')
flags.AddDestIpRanges(parser)
flags.AddLayer4Configs(parser)
flags.AddDirection(parser)
flags.AddEnableLogging(parser)
flags.AddTargetResources(parser)
flags.AddTargetServiceAccounts(parser)
flags.AddDescription(parser)
flags.AddNewPriority(parser, operation='update')
flags.AddOrganization(parser, required=False)
rule_flags.AddMatcher(parser, required=False)
rule_flags.AddPreview(parser, for_update=True)
parser.add_argument(
'--cloud-armor',
action='store_true',
default=False,
help='Specified for Hierarchical Cloud Armor rules.',
)
def _SetupCloudArmorMatch(self, args, holder, expression, src_ip_ranges):
if args.IsSpecified('expression'):
return holder.client.messages.SecurityPolicyRuleMatcher(
expr=holder.client.messages.Expr(expression=expression)
)
else:
return holder.client.messages.SecurityPolicyRuleMatcher(
versionedExpr=holder.client.messages.SecurityPolicyRuleMatcher.VersionedExprValueValuesEnum.SRC_IPS_V1,
config=holder.client.messages.SecurityPolicyRuleMatcherConfig(
srcIpRanges=src_ip_ranges
),
)
def _SetupFirewallMatch(
self,
holder,
src_ip_ranges,
dest_ip_ranges,
dest_ports_list,
layer4_config_list,
):
if self.ReleaseTrack() == base.ReleaseTrack.ALPHA:
return holder.client.messages.SecurityPolicyRuleMatcher(
versionedExpr=holder.client.messages.SecurityPolicyRuleMatcher.VersionedExprValueValuesEnum.FIREWALL,
config=holder.client.messages.SecurityPolicyRuleMatcherConfig(
srcIpRanges=src_ip_ranges,
destIpRanges=dest_ip_ranges,
destPorts=dest_ports_list,
layer4Configs=layer4_config_list,
),
)
else:
return holder.client.messages.SecurityPolicyRuleMatcher(
versionedExpr=holder.client.messages.SecurityPolicyRuleMatcher.VersionedExprValueValuesEnum.FIREWALL,
config=holder.client.messages.SecurityPolicyRuleMatcherConfig(
srcIpRanges=src_ip_ranges,
destIpRanges=dest_ip_ranges,
layer4Configs=layer4_config_list,
),
)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
security_policy_rule_client = client.OrgSecurityPolicyRule(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
priority = rule_utils.ConvertPriorityToInt(ref.Name())
expression = None
src_ip_ranges = []
dest_ip_ranges = []
dest_ports_list = []
layer4_config_list = []
preview = None
should_setup_match = False
matcher = None
if args.IsSpecified('expression'):
expression = args.expression
should_setup_match = True
if args.IsSpecified('src_ip_ranges'):
src_ip_ranges = args.src_ip_ranges
should_setup_match = True
if args.IsSpecified('dest_ip_ranges'):
dest_ip_ranges = args.dest_ip_ranges
should_setup_match = True
if self.ReleaseTrack() == base.ReleaseTrack.ALPHA and args.IsSpecified(
'dest_ports'):
should_setup_match = True
dest_ports_list = rule_utils.ParseDestPorts(args.dest_ports,
holder.client.messages)
if args.IsSpecified('layer4_configs'):
should_setup_match = True
layer4_config_list = rule_utils.ParseLayer4Configs(
args.layer4_configs, holder.client.messages)
if args.IsSpecified('preview'):
preview = args.preview
if args.IsSpecified('new_priority'):
new_priority = rule_utils.ConvertPriorityToInt(args.new_priority)
else:
new_priority = priority
# If need to construct a new matcher.
if should_setup_match:
if args.IsSpecified('cloud_armor'):
matcher = self._SetupCloudArmorMatch(
args, holder, expression, src_ip_ranges
)
else:
matcher = self._SetupFirewallMatch(
holder,
src_ip_ranges,
dest_ip_ranges,
dest_ports_list,
layer4_config_list,
)
security_policy_rule = holder.client.messages.SecurityPolicyRule(
priority=new_priority,
action=rule_utils.ConvertAction(args.action),
match=matcher,
description=args.description,
preview=preview,
)
# only support firewall fields in Alpha/Beta
if self.ReleaseTrack() != base.ReleaseTrack.GA:
if args.IsSpecified('target_resources'):
security_policy_rule.targetResources = args.target_resources
if args.IsSpecified('target_service_accounts'):
security_policy_rule.targetServiceAccounts = (
args.target_service_accounts
)
if args.IsSpecified('enable_logging'):
security_policy_rule.enableLogging = True
if args.IsSpecified('direction'):
if args.direction == 'INGRESS':
security_policy_rule.direction = (
holder.client.messages.SecurityPolicyRule.DirectionValueValuesEnum.INGRESS
)
else:
security_policy_rule.direction = (
holder.client.messages.SecurityPolicyRule.DirectionValueValuesEnum.EGRESS
)
security_policy_id = org_security_policies_utils.GetSecurityPolicyId(
security_policy_rule_client,
args.security_policy,
organization=args.organization)
return security_policy_rule_client.Update(
priority=priority,
security_policy=security_policy_id,
security_policy_rule=security_policy_rule)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(Update):
r"""Update a Compute Engine security policy rule.
*{command}* is used to update organization security policy rules.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyRuleArgument(
required=True, operation='update')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser)
flags.AddAction(parser, required=False)
flags.AddSecurityPolicyId(parser, operation='updated')
flags.AddDestIpRanges(parser)
flags.AddDestPorts(parser)
flags.AddLayer4Configs(parser)
flags.AddDirection(parser)
flags.AddEnableLogging(parser)
flags.AddTargetResources(parser)
flags.AddTargetServiceAccounts(parser)
flags.AddDescription(parser)
flags.AddNewPriority(parser, operation='update')
flags.AddOrganization(parser, required=False)
rule_flags.AddMatcher(parser, required=False)
rule_flags.AddPreview(parser, for_update=True)
parser.add_argument(
'--cloud-armor',
action='store_true',
default=False,
help='Specified for Hierarchical Cloud Armor rules.',
)
Update.detailed_help = {
'EXAMPLES':
"""\
To update a rule with priority ``10'' in an organization security policy
with ID ``123456789'' to change the action to ``allow'' and description to
``new-example-rule'', run:
$ {command} 10 --security-policy=123456789 --action=allow
--description=new-example-rule
""",
}

View File

@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*- #
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command for updating organization 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.org_security_policies import client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute.org_security_policies import flags
from googlecloudsdk.command_lib.compute.org_security_policies import org_security_policies_utils
from googlecloudsdk.command_lib.compute.security_policies import flags as sp_flags
from googlecloudsdk.command_lib.compute.security_policies import security_policies_utils
import six
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Update(base.UpdateCommand):
"""Update a Compute Engine organization security policy.
*{command}* is used to update organization security policies. An organization
security policy is a set of rules that controls access to various resources.
"""
ORG_SECURITY_POLICY_ARG = None
@classmethod
def Args(cls, parser):
cls.ORG_SECURITY_POLICY_ARG = flags.OrgSecurityPolicyArgument(
required=True, operation='update')
cls.ORG_SECURITY_POLICY_ARG.AddArgument(parser, operation_type='update')
flags.AddArgsUpdateSp(parser)
sp_flags.AddAdvancedOptions(parser)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
ref = self.ORG_SECURITY_POLICY_ARG.ResolveAsResource(
args, holder.resources, with_project=False)
org_security_policy = client.OrgSecurityPolicy(
ref=ref,
compute_client=holder.client,
resources=holder.resources,
version=six.text_type(self.ReleaseTrack()).lower())
sp_id = org_security_policies_utils.GetSecurityPolicyId(
org_security_policy, ref.Name(), organization=args.organization)
existing_security_policy = org_security_policy.Describe(
sp_id=sp_id, only_generate_request=False)[0]
description = existing_security_policy.description
advanced_options_config = existing_security_policy.advancedOptionsConfig
if args.description is not None:
description = args.description
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))
security_policy = holder.client.messages.SecurityPolicy(
description=description,
advancedOptionsConfig=advanced_options_config,
fingerprint=existing_security_policy.fingerprint)
return org_security_policy.Update(
sp_id=sp_id,
only_generate_request=False,
security_policy=security_policy)
Update.detailed_help = {
'EXAMPLES':
"""\
To update an organization security policy with ID ``123456789'' to change the
description to ``New description'', run:
$ {command} 123456789 --description='New description'
""",
}