735 lines
27 KiB
Python
735 lines
27 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2014 Google LLC. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""Common classes and functions for firewall rules."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
import enum
|
|
import re
|
|
|
|
from googlecloudsdk.api_lib.compute import exceptions
|
|
from googlecloudsdk.calliope import arg_parsers
|
|
from googlecloudsdk.command_lib.compute import exceptions as compute_exceptions
|
|
|
|
ALLOWED_METAVAR = 'PROTOCOL[:PORT[-PORT]]'
|
|
LEGAL_SPECS = re.compile(
|
|
r"""
|
|
|
|
(?P<protocol>[a-zA-Z0-9+.-]+) # The protocol group.
|
|
|
|
(:(?P<ports>\d+(-\d+)?))? # The optional ports group.
|
|
# May specify a range.
|
|
|
|
$ # End of input marker.
|
|
""", re.VERBOSE)
|
|
EFFECTIVE_FIREWALL_LIST_FORMAT = """\
|
|
table(
|
|
type,
|
|
firewall_policy_name,
|
|
firewall_policy_priority,
|
|
priority,
|
|
action,
|
|
direction,
|
|
disabled,
|
|
ip_ranges.list():label=IP_RANGES
|
|
)"""
|
|
EFFECTIVE_SECURITY_POLICY_LIST_FORMAT = """\
|
|
table(
|
|
type,
|
|
security_policy_name,
|
|
priority,
|
|
action,
|
|
preview,
|
|
expression,
|
|
src_ip_ranges.list():label=SRC_IP_RANGES
|
|
)"""
|
|
|
|
LIST_NOTICE = """\
|
|
To show all fields of the firewall, please show in JSON format: --format=json
|
|
To show more fields in table format, please see the examples in --help.
|
|
"""
|
|
LIST_NOTICE_SECURITY_POLICY = """\
|
|
To show all fields of the security policy, please show in JSON format: --format=json
|
|
To show more fields in table format, please see the examples in --help.
|
|
"""
|
|
|
|
|
|
class ArgumentValidationError(exceptions.Error):
|
|
"""Raised when a user specifies --rules and --allow parameters together."""
|
|
|
|
|
|
class ActionType(enum.Enum):
|
|
"""Firewall Action type."""
|
|
ALLOW = 1
|
|
DENY = 2
|
|
|
|
|
|
def AddCommonArgs(parser,
|
|
for_update=False,
|
|
with_egress_support=False,
|
|
with_service_account=False):
|
|
"""Adds common arguments for firewall create or update subcommands."""
|
|
|
|
min_length = 0 if for_update else 1
|
|
if not for_update:
|
|
parser.add_argument(
|
|
'--network',
|
|
default='default',
|
|
help="""\
|
|
The network to which this rule is attached. If omitted, the
|
|
rule is attached to the ``default'' network.
|
|
""")
|
|
parser.add_argument(
|
|
'--resource-manager-tags',
|
|
type=arg_parsers.ArgDict(),
|
|
metavar='KEY=VALUE',
|
|
help="""\
|
|
A comma-separated list of Resource Manager tags to apply to the firewall.
|
|
""")
|
|
|
|
ruleset_parser = parser
|
|
if with_egress_support:
|
|
ruleset_parser = parser.add_mutually_exclusive_group(
|
|
required=not for_update)
|
|
ruleset_parser.add_argument(
|
|
'--allow',
|
|
metavar=ALLOWED_METAVAR,
|
|
type=arg_parsers.ArgList(min_length=min_length),
|
|
required=(not for_update) and (not with_egress_support),
|
|
help="""\
|
|
A list of protocols and ports whose traffic will be allowed.
|
|
|
|
The protocols allowed over this connection. This can be the
|
|
(case-sensitive) string values `tcp`, `udp`, `icmp`, `esp`, `ah`, `sctp`,
|
|
or any IP protocol number. An IP-based protocol must be specified for each
|
|
rule. The rule applies only to specified protocol.
|
|
|
|
For port-based protocols - `tcp`, `udp`, and `sctp` - a list of
|
|
destination ports or port ranges to which the rule applies may optionally
|
|
be specified. If no port or port range is specified, the rule applies to
|
|
all destination ports.
|
|
|
|
The ICMP protocol is supported, but there is no support for configuring
|
|
ICMP packet filtering by ICMP code.
|
|
|
|
For example, to create a rule that allows TCP traffic through port 80 and
|
|
ICMP traffic:
|
|
|
|
$ {command} MY-RULE --allow tcp:80,icmp
|
|
|
|
To create a rule that allows TCP traffic from port 20000 to 25000:
|
|
|
|
$ {command} MY-RULE --allow tcp:20000-25000
|
|
|
|
To create a rule that allows all TCP traffic:
|
|
|
|
$ {command} MY-RULE --allow tcp
|
|
|
|
""" + ("""
|
|
Setting this will override the current values.
|
|
""" if for_update else ''))
|
|
|
|
parser.add_argument(
|
|
'--description',
|
|
help='A textual description for the firewall rule.{0}'.format(
|
|
' Set to an empty string to clear existing.' if for_update else ''))
|
|
|
|
source_ranges_help = """\
|
|
A list of IP address blocks that are allowed to make inbound
|
|
connections that match the firewall rule to the instances on
|
|
the network. The IP address blocks must be specified in CIDR
|
|
format:
|
|
link:http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing[].
|
|
|
|
If neither --source-ranges nor --source-tags are specified,
|
|
--source-ranges defaults to `0.0.0.0/0`, which means that the rule applies
|
|
to all incoming IPv4 connections from inside or outside the network. If
|
|
both --source-ranges and --source-tags are specified, the rule matches if
|
|
either the range of the source matches --source-ranges or the tag of the
|
|
source matches --source-tags.
|
|
"""
|
|
if for_update:
|
|
source_ranges_help += """
|
|
Setting this will override the existing source ranges for the firewall.
|
|
The following will clear the existing source ranges:
|
|
|
|
$ {command} MY-RULE --source-ranges
|
|
"""
|
|
else:
|
|
source_ranges_help += """
|
|
Multiple IP address blocks can be specified if they are separated by
|
|
commas.
|
|
"""
|
|
parser.add_argument(
|
|
'--source-ranges',
|
|
default=None if for_update else [],
|
|
metavar='CIDR_RANGE',
|
|
type=arg_parsers.ArgList(min_length=min_length),
|
|
help=source_ranges_help)
|
|
|
|
source_tags_help = """\
|
|
A list of instance tags indicating the set of instances on the network to
|
|
which the rule applies if all other fields match. If neither
|
|
--source-ranges nor --source-tags are specified, --source-ranges
|
|
defaults to `0.0.0.0/0`, which means that the rule applies to all
|
|
incoming IPv4 connections from inside or outside the network.
|
|
|
|
If both --source-ranges and --source-tags are specified, an inbound
|
|
connection is allowed if either the range of the source matches
|
|
--source-ranges or the tag of the source matches --source-tags.
|
|
|
|
Tags can be assigned to instances during instance creation.
|
|
"""
|
|
if with_service_account:
|
|
source_tags_help += """
|
|
If source tags are specified then neither a source nor target service
|
|
account can also be specified.
|
|
"""
|
|
if for_update:
|
|
source_tags_help += """
|
|
Setting this will override the existing source tags for the firewall.
|
|
The following will clear the existing source tags:
|
|
|
|
$ {command} MY-RULE --source-tags
|
|
"""
|
|
parser.add_argument(
|
|
'--source-tags',
|
|
default=None if for_update else [],
|
|
metavar='TAG',
|
|
type=arg_parsers.ArgList(min_length=min_length),
|
|
help=source_tags_help)
|
|
|
|
target_tags_help = """\
|
|
A list of instance tags indicating which instances the rule is applied to.
|
|
If the field is set, the rule applies to only instances with a matching
|
|
tag. If omitted, the rule applies to all instances in the network.
|
|
|
|
Tags can be assigned to instances during instance creation.
|
|
"""
|
|
if with_service_account:
|
|
target_tags_help = """\
|
|
|
|
List of instance tags indicating the set of instances on the
|
|
network which may accept connections that match the
|
|
firewall rule.
|
|
Note that tags can be assigned to instances during instance creation.
|
|
|
|
If target tags are specified, then neither a source nor target
|
|
service account can also be specified.
|
|
|
|
If both target tags and target service account
|
|
are omitted, all instances on the network can receive
|
|
connections that match the rule.
|
|
"""
|
|
if for_update:
|
|
target_tags_help += """
|
|
Setting this will override the existing target tags for the firewall.
|
|
The following will clear the existing target tags:
|
|
|
|
$ {command} MY-RULE --target-tags
|
|
"""
|
|
parser.add_argument(
|
|
'--target-tags',
|
|
default=None if for_update else [],
|
|
metavar='TAG',
|
|
type=arg_parsers.ArgList(min_length=min_length),
|
|
help=target_tags_help)
|
|
|
|
disabled_help = """\
|
|
Disable a firewall rule and stop it from being enforced in the network.
|
|
If a firewall rule is disabled, the associated network behaves as if the
|
|
rule did not exist. To enable a disabled rule, use:
|
|
|
|
$ {parent_command} update MY-RULE --no-disabled
|
|
|
|
"""
|
|
if not for_update:
|
|
disabled_help += """Firewall rules are enabled by default."""
|
|
parser.add_argument(
|
|
'--disabled', action='store_true', default=None, help=disabled_help)
|
|
|
|
# Add egress deny firewall cli support.
|
|
if with_egress_support:
|
|
AddArgsForEgress(parser, ruleset_parser, for_update)
|
|
|
|
|
|
def AddArgsForEgress(parser, ruleset_parser, for_update=False):
|
|
"""Adds arguments for egress firewall create or update subcommands."""
|
|
min_length = 0 if for_update else 1
|
|
|
|
if not for_update:
|
|
ruleset_parser.add_argument(
|
|
'--action',
|
|
choices=['ALLOW', 'DENY'],
|
|
type=lambda x: x.upper(),
|
|
help="""\
|
|
The action for the firewall rule: whether to allow or deny matching
|
|
traffic. If specified, the flag `--rules` must also be specified.
|
|
""")
|
|
|
|
rules_help = """\
|
|
A list of protocols and ports to which the firewall rule will apply.
|
|
|
|
PROTOCOL is the IP protocol whose traffic will be checked.
|
|
PROTOCOL can be either the name of a well-known protocol
|
|
(e.g., tcp or icmp) or the IP protocol number.
|
|
A list of IP protocols can be found at
|
|
http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
|
|
|
|
A port or port range can be specified after PROTOCOL to which the
|
|
firewall rule apply on traffic through specific ports. If no port
|
|
or port range is specified, connections through all ranges are applied.
|
|
TCP and UDP rules must include a port or port range.
|
|
"""
|
|
if for_update:
|
|
rules_help += """
|
|
Setting this will override the current values.
|
|
"""
|
|
else:
|
|
rules_help += """
|
|
If specified, the flag --action must also be specified.
|
|
|
|
For example, the following will create a rule that blocks TCP
|
|
traffic through port 80 and ICMP traffic:
|
|
|
|
$ {command} MY-RULE --action deny --rules tcp:80,icmp
|
|
"""
|
|
parser.add_argument(
|
|
'--rules',
|
|
metavar=ALLOWED_METAVAR,
|
|
type=arg_parsers.ArgList(min_length=min_length),
|
|
help=rules_help,
|
|
required=False)
|
|
|
|
# Do NOT allow change direction in update case.
|
|
if not for_update:
|
|
parser.add_argument(
|
|
'--direction',
|
|
choices=['INGRESS', 'EGRESS', 'IN', 'OUT'],
|
|
type=lambda x: x.upper(),
|
|
help="""\
|
|
If direction is NOT specified, then default is to apply on incoming
|
|
traffic. For outbound traffic, it is NOT supported to specify
|
|
source-tags.
|
|
|
|
For convenience, 'IN' can be used to represent ingress direction and
|
|
'OUT' can be used to represent egress direction.
|
|
""")
|
|
|
|
parser.add_argument(
|
|
'--priority',
|
|
type=int,
|
|
help="""\
|
|
This is an integer between 0 and 65535, both inclusive. When NOT
|
|
specified, the value assumed is 1000. Relative priority determines
|
|
precedence of conflicting rules: lower priority values imply higher
|
|
precedence. DENY rules take precedence over ALLOW rules having equal
|
|
priority.
|
|
""")
|
|
|
|
destination_ranges_help = """\
|
|
The firewall rule will apply to traffic that has destination IP address
|
|
in these IP address block list. The IP address blocks must be specified
|
|
in CIDR format:
|
|
link:http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing[].
|
|
"""
|
|
if for_update:
|
|
destination_ranges_help += """
|
|
Setting this will override the existing destination ranges for the
|
|
firewall. The following will clear the existing destination ranges:
|
|
|
|
$ {command} MY-RULE --destination-ranges
|
|
"""
|
|
else:
|
|
destination_ranges_help += """
|
|
If --destination-ranges is NOT provided, then this
|
|
flag will default to 0.0.0.0/0, allowing all IPv4 destinations. Multiple
|
|
IP address blocks can be specified if they are separated by commas.
|
|
"""
|
|
parser.add_argument(
|
|
'--destination-ranges',
|
|
default=None if for_update else [],
|
|
metavar='CIDR_RANGE',
|
|
type=arg_parsers.ArgList(min_length=min_length),
|
|
help=destination_ranges_help)
|
|
|
|
|
|
def AddArgsForServiceAccount(parser, for_update=False):
|
|
"""Adds arguments for secure firewall create or update subcommands."""
|
|
min_length = 0 if for_update else 1
|
|
source_service_accounts_help = """\
|
|
The email of a service account indicating the set of instances on the
|
|
network which match a traffic source in the firewall rule.
|
|
|
|
If a source service account is specified then neither source tags nor
|
|
target tags can also be specified.
|
|
"""
|
|
if for_update:
|
|
source_service_accounts_help += """
|
|
Setting this will override the existing source service accounts for the
|
|
firewall.
|
|
The following will clear the existing source service accounts:
|
|
|
|
$ {command} MY-RULE --source-service-accounts
|
|
"""
|
|
parser.add_argument(
|
|
'--source-service-accounts',
|
|
default=None if for_update else [],
|
|
metavar='EMAIL',
|
|
type=arg_parsers.ArgList(min_length=min_length),
|
|
help=source_service_accounts_help)
|
|
|
|
target_service_accounts_help = """\
|
|
The email of a service account indicating the set of instances to which
|
|
firewall rules apply. If both target tags and target service account are
|
|
omitted, the firewall rule is applied to all instances on the network.
|
|
|
|
If a target service account is specified then neither source tag nor
|
|
target tags can also be specified.
|
|
"""
|
|
if for_update:
|
|
target_service_accounts_help += """
|
|
Setting this will override the existing target service accounts for the
|
|
firewall.
|
|
The following will clear the existing target service accounts:
|
|
|
|
$ {command} MY-RULE --target-service-accounts
|
|
"""
|
|
parser.add_argument(
|
|
'--target-service-accounts',
|
|
default=None if for_update else [],
|
|
metavar='EMAIL',
|
|
type=arg_parsers.ArgList(min_length=min_length),
|
|
help=target_service_accounts_help)
|
|
|
|
|
|
def ParseRules(rules, message_classes, action=ActionType.ALLOW):
|
|
"""Parses protocol:port mappings from --allow or --rules command line."""
|
|
rule_value_list = []
|
|
for spec in rules or []:
|
|
match = LEGAL_SPECS.match(spec)
|
|
if not match:
|
|
raise compute_exceptions.ArgumentError(
|
|
'Firewall rules must be of the form {0}; received [{1}].'.format(
|
|
ALLOWED_METAVAR, spec))
|
|
if match.group('ports'):
|
|
ports = [match.group('ports')]
|
|
else:
|
|
ports = []
|
|
|
|
if action == ActionType.ALLOW:
|
|
rule = message_classes.Firewall.AllowedValueListEntry(
|
|
IPProtocol=match.group('protocol'), ports=ports)
|
|
else:
|
|
rule = message_classes.Firewall.DeniedValueListEntry(
|
|
IPProtocol=match.group('protocol'), ports=ports)
|
|
rule_value_list.append(rule)
|
|
return rule_value_list
|
|
|
|
|
|
def SortNetworkFirewallRules(client, rules):
|
|
"""Sort the network firewall rules by direction and priority."""
|
|
ingress_network_firewall = [
|
|
item for item in rules if item.direction ==
|
|
client.messages.Firewall.DirectionValueValuesEnum.INGRESS
|
|
]
|
|
ingress_network_firewall.sort(key=lambda x: x.priority, reverse=False)
|
|
egress_network_firewall = [
|
|
item for item in rules if item.direction ==
|
|
client.messages.Firewall.DirectionValueValuesEnum.EGRESS
|
|
]
|
|
egress_network_firewall.sort(key=lambda x: x.priority, reverse=False)
|
|
return ingress_network_firewall + egress_network_firewall
|
|
|
|
|
|
def SortOrgFirewallRules(client, rules):
|
|
"""Sort the organization firewall rules by optional direction and priority."""
|
|
ingress_rule, egress_rule, cloud_armor_rule = [], [], []
|
|
for item in rules:
|
|
direction = getattr(item, 'direction', None)
|
|
if direction is None:
|
|
cloud_armor_rule.append(item)
|
|
elif (
|
|
direction
|
|
== client.messages.SecurityPolicyRule.DirectionValueValuesEnum.INGRESS
|
|
):
|
|
ingress_rule.append(item)
|
|
elif (
|
|
direction
|
|
== client.messages.SecurityPolicyRule.DirectionValueValuesEnum.EGRESS
|
|
):
|
|
egress_rule.append(item)
|
|
for rule_list in [ingress_rule, egress_rule, cloud_armor_rule]:
|
|
rule_list.sort(key=lambda x: x.priority, reverse=False)
|
|
return ingress_rule + egress_rule + cloud_armor_rule
|
|
|
|
|
|
def SortFirewallPolicyRules(client, rules):
|
|
"""Sort the organization firewall rules by direction and priority."""
|
|
ingress_org_firewall_rule = [
|
|
item for item in rules if item.direction ==
|
|
client.messages.FirewallPolicyRule.DirectionValueValuesEnum.INGRESS
|
|
]
|
|
ingress_org_firewall_rule.sort(key=lambda x: x.priority, reverse=False)
|
|
egress_org_firewall_rule = [
|
|
item for item in rules if item.direction ==
|
|
client.messages.FirewallPolicyRule.DirectionValueValuesEnum.EGRESS
|
|
]
|
|
egress_org_firewall_rule.sort(key=lambda x: x.priority, reverse=False)
|
|
return ingress_org_firewall_rule + egress_org_firewall_rule
|
|
|
|
|
|
def _FirewallPolicyTypeOrder(client, fp_type):
|
|
"""Defines Firewall evaluation order.
|
|
|
|
Args:
|
|
client: API client.
|
|
fp_type: Firewall Policy type.
|
|
|
|
Returns:
|
|
int representing type ordering
|
|
"""
|
|
if (
|
|
fp_type
|
|
== client.messages.NetworksGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.HIERARCHY
|
|
or fp_type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.HIERARCHY
|
|
or fp_type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.HIERARCHY
|
|
):
|
|
return 0
|
|
if (
|
|
fp_type
|
|
== client.messages.NetworksGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM
|
|
or fp_type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM_GLOBAL
|
|
or fp_type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM_GLOBAL
|
|
):
|
|
return 1
|
|
if (
|
|
fp_type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM_REGIONAL
|
|
or fp_type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM_REGIONAL
|
|
):
|
|
return 2
|
|
if (
|
|
fp_type
|
|
== client.messages.NetworksGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK
|
|
or fp_type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK
|
|
or fp_type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK
|
|
):
|
|
return 3
|
|
if (
|
|
fp_type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK_REGIONAL
|
|
or fp_type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK_REGIONAL
|
|
):
|
|
return 4
|
|
return -1
|
|
|
|
|
|
def SortFirewallPolicies(client, fps):
|
|
"""Sort Firewall Policies in their evaluation order."""
|
|
return sorted(
|
|
fps,
|
|
key=lambda fp: (
|
|
_FirewallPolicyTypeOrder(client, fp.type),
|
|
0 if fp.priority is None else fp.priority,
|
|
),
|
|
)
|
|
|
|
|
|
def ConvertFirewallPolicyRulesToEffectiveFwRules(client, firewall_policy):
|
|
"""Convert organization firewall policy rules to effective firewall rules."""
|
|
result = []
|
|
for rule in firewall_policy.rules:
|
|
item = ConvertFirewallPolicyRule(client, firewall_policy, rule)
|
|
item.update({'rule_type': 'FIREWALL_RULE'})
|
|
result.append(item)
|
|
|
|
for rule in firewall_policy.packetMirroringRules:
|
|
item = ConvertFirewallPolicyRule(client, firewall_policy, rule)
|
|
item.update({'rule_type': 'PACKET_MIRRORING_RULE'})
|
|
result.append(item)
|
|
|
|
return result
|
|
|
|
|
|
def ConvertFirewallPolicyRule(client, firewall_policy, rule):
|
|
"""Convert rule to effective firewall rule output."""
|
|
item = {}
|
|
if (
|
|
firewall_policy.type
|
|
== client.messages.NetworksGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.HIERARCHY
|
|
or firewall_policy.type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.HIERARCHY
|
|
or firewall_policy.type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.HIERARCHY
|
|
):
|
|
item.update({'type': 'org-firewall'})
|
|
elif (
|
|
firewall_policy.type
|
|
== client.messages.NetworksGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK
|
|
or firewall_policy.type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK
|
|
or firewall_policy.type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK
|
|
):
|
|
item.update({'type': 'network-firewall-policy'})
|
|
elif (
|
|
firewall_policy.type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK_REGIONAL
|
|
or firewall_policy.type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.NETWORK_REGIONAL
|
|
):
|
|
item.update({'type': 'network-regional-firewall-policy'})
|
|
elif (
|
|
firewall_policy.type
|
|
== client.messages.NetworksGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM
|
|
or firewall_policy.type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM_GLOBAL
|
|
or firewall_policy.type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM_GLOBAL
|
|
):
|
|
item.update({'type': 'system-network-firewall-policy'})
|
|
elif (
|
|
firewall_policy.type
|
|
== client.messages.InstancesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM_REGIONAL
|
|
or firewall_policy.type
|
|
== client.messages.RegionNetworkFirewallPoliciesGetEffectiveFirewallsResponseEffectiveFirewallPolicy.TypeValueValuesEnum.SYSTEM_REGIONAL
|
|
):
|
|
item.update({'type': 'system-network-regional-firewall-policy'})
|
|
else:
|
|
item.update({'type': 'unknown'})
|
|
item.update({'firewall_policy_priority': firewall_policy.priority})
|
|
item.update({'description': rule.description})
|
|
item.update({'firewall_policy_name': firewall_policy.name})
|
|
item.update({'priority': rule.priority})
|
|
item.update({'direction': rule.direction})
|
|
item.update({'action': rule.action.upper()})
|
|
item.update({'disabled': bool(rule.disabled)})
|
|
if rule.match.srcIpRanges:
|
|
item.update({'ip_ranges': rule.match.srcIpRanges})
|
|
if rule.match.destIpRanges:
|
|
item.update({'ip_ranges': rule.match.destIpRanges})
|
|
if rule.targetServiceAccounts:
|
|
item.update({'target_svc_acct': rule.targetServiceAccounts})
|
|
if rule.targetResources:
|
|
item.update({'target_resources': rule.targetResources})
|
|
return item
|
|
|
|
|
|
def ConvertOrgSecurityPolicyRulesToEffectiveFwRules(security_policy):
|
|
"""Convert organization security policy rules to effective firewall rules."""
|
|
result = []
|
|
for rule in security_policy.rules:
|
|
item = {}
|
|
item.update({'type': 'org-firewall'})
|
|
item.update({'description': rule.description})
|
|
item.update({'firewall_policy_name': security_policy.id})
|
|
item.update({'priority': rule.priority})
|
|
item.update({'direction': rule.direction})
|
|
item.update({'action': rule.action.upper()})
|
|
item.update({'disabled': 'False'})
|
|
if rule.match.config.srcIpRanges:
|
|
item.update({'ip_ranges': rule.match.config.srcIpRanges})
|
|
if rule.match.config.destIpRanges:
|
|
item.update({'ip_ranges': rule.match.config.destIpRanges})
|
|
if rule.targetServiceAccounts:
|
|
item.update({'target_svc_acct': rule.targetServiceAccounts})
|
|
if rule.targetResources:
|
|
item.update({'target_resources': rule.targetResources})
|
|
result.append(item)
|
|
return result
|
|
|
|
|
|
def ConvertNetworkFirewallRulesToEffectiveFwRules(network_firewalls):
|
|
"""Convert network firewall rules to effective firewall rules."""
|
|
result = []
|
|
for rule in network_firewalls:
|
|
item = {}
|
|
item.update({'type': 'network-firewall'})
|
|
item.update({'description': rule.description})
|
|
item.update({'priority': rule.priority})
|
|
item.update({'direction': rule.direction})
|
|
if rule.allowed:
|
|
item.update({'action': 'ALLOW'})
|
|
else:
|
|
item.update({'action': 'DENY'})
|
|
if rule.sourceRanges:
|
|
item.update({'ip_ranges': rule.sourceRanges})
|
|
if rule.destinationRanges:
|
|
item.update({'ip_ranges': rule.destinationRanges})
|
|
if rule.targetServiceAccounts:
|
|
item.update({'target_svc_acct': rule.targetServiceAccounts})
|
|
if rule.targetTags:
|
|
item.update({'target_tags': rule.targetTags})
|
|
if rule.sourceTags:
|
|
item.update({'src_tags': rule.sourceTags})
|
|
if rule.sourceServiceAccounts:
|
|
item.update({'src_svc_acct': rule.sourceTags})
|
|
if rule.disabled:
|
|
item.update({'disabled': True})
|
|
else:
|
|
item.update({'disabled': False})
|
|
item.update({'name': rule.name})
|
|
result.append(item)
|
|
return result
|
|
|
|
|
|
def ConvertOrgSecurityPolicyRulesToEffectiveSpRules(security_policy):
|
|
"""Convert org security policy rules to effective security policy rules."""
|
|
result = []
|
|
for rule in security_policy.rules:
|
|
item = {}
|
|
item.update({'type': 'org-security-policy'})
|
|
item.update({'description': rule.description})
|
|
item.update({'security_policy_name': security_policy.shortName})
|
|
item.update({'priority': rule.priority})
|
|
item.update({'action': rule.action.upper()})
|
|
item.update({'preview': rule.preview})
|
|
if rule.match.expr and rule.match.expr.expression:
|
|
item.update({'expression': rule.match.expr.expression})
|
|
if rule.match.config and rule.match.config.srcIpRanges:
|
|
item.update({'src_ip_ranges': rule.match.config.srcIpRanges})
|
|
result.append(item)
|
|
return result
|
|
|
|
|
|
def ConvertSecurityPolicyRulesToEffectiveSpRules(security_policy):
|
|
"""Convert security policy rules to effective security policy rules."""
|
|
result = []
|
|
for rule in security_policy.rules:
|
|
item = {}
|
|
item.update({'type': 'security-policy'})
|
|
item.update({'description': rule.description})
|
|
item.update({'security_policy_name': security_policy.name})
|
|
item.update({'priority': rule.priority})
|
|
item.update({'action': rule.action.upper()})
|
|
item.update({'preview': rule.preview})
|
|
if rule.match.expr and rule.match.expr.expression:
|
|
item.update({'expression': rule.match.expr.expression})
|
|
if rule.match.config and rule.match.config.srcIpRanges:
|
|
item.update({'src_ip_ranges': rule.match.config.srcIpRanges})
|
|
result.append(item)
|
|
return result
|