From 2c115a2c64c6cc8519df9e6ee66b4ac5474b32e9 Mon Sep 17 00:00:00 2001 From: mihhalj Date: Thu, 5 Sep 2024 21:26:46 +0200 Subject: [PATCH] Add new compute-network-firewall-policy-with-rules resource (#11524) Co-authored-by: Nick Elliot --- .../NetworkFirewallPolicyWithRules.yaml | 569 ++++++++++++++++++ ..._network_firewall_policy_with_rules.go.erb | 54 ++ ..._network_firewall_policy_with_rules.go.erb | 16 + ..._network_firewall_policy_with_rules.go.erb | 3 + ...ork_firewall_policy_with_rules_full.tf.erb | 116 ++++ ..._network_firewall_policy_with_rules.go.erb | 31 + ..._network_firewall_policy_with_rules.go.erb | 15 + ...ork_firewall_policy_with_rules_test.go.erb | 264 ++++++++ 8 files changed, 1068 insertions(+) create mode 100644 mmv1/products/compute/NetworkFirewallPolicyWithRules.yaml create mode 100644 mmv1/templates/terraform/constants/resource_compute_network_firewall_policy_with_rules.go.erb create mode 100644 mmv1/templates/terraform/decoders/resource_compute_network_firewall_policy_with_rules.go.erb create mode 100644 mmv1/templates/terraform/encoders/resource_compute_network_firewall_policy_with_rules.go.erb create mode 100644 mmv1/templates/terraform/examples/compute_network_firewall_policy_with_rules_full.tf.erb create mode 100644 mmv1/templates/terraform/post_create/resource_compute_network_firewall_policy_with_rules.go.erb create mode 100644 mmv1/templates/terraform/update_encoder/resource_compute_network_firewall_policy_with_rules.go.erb create mode 100644 mmv1/third_party/terraform/services/compute/resource_compute_network_firewall_policy_with_rules_test.go.erb diff --git a/mmv1/products/compute/NetworkFirewallPolicyWithRules.yaml b/mmv1/products/compute/NetworkFirewallPolicyWithRules.yaml new file mode 100644 index 000000000000..60df0a3589d7 --- /dev/null +++ b/mmv1/products/compute/NetworkFirewallPolicyWithRules.yaml @@ -0,0 +1,569 @@ +# Copyright 2023 Google Inc. +# 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. + +--- !ruby/object:Api::Resource +name: NetworkFirewallPolicyWithRules +min_version: beta +base_url: projects/{{project}}/global/firewallPolicies +create_url: projects/{{project}}/global/firewallPolicies +self_link: projects/{{project}}/global/firewallPolicies/{{name}} +update_verb: :PATCH +description: "The Compute NetworkFirewallPolicy with rules resource" +legacy_long_form_project: true +async: !ruby/object:Api::OpAsync + operation: !ruby/object:Api::OpAsync::Operation + kind: 'compute#operation' + path: 'name' + base_url: '{{op_id}}' + wait_ms: 1000 + result: !ruby/object:Api::OpAsync::Result + path: 'targetLink' + status: !ruby/object:Api::OpAsync::Status + path: 'status' + complete: 'DONE' + allowed: + - 'PENDING' + - 'RUNNING' + - 'DONE' + error: !ruby/object:Api::OpAsync::Error + path: 'error/errors' + message: 'message' +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'compute_network_firewall_policy_with_rules_full' + primary_resource_id: 'network-firewall-policy-with-rules' + vars: + policy_name: 'tf-fw-policy-with-rules' + address_group_name: 'tf-address-group' + tag_key_name: 'tf-tag-key' + tag_value_name: 'tf-tag-value' + security_profile_group_name: 'tf-security-profile-group' + security_profile_name: 'tf-security-profile' + test_env_vars: + org_id: :ORG_ID +custom_code: !ruby/object:Provider::Terraform::CustomCode + constants: templates/terraform/constants/resource_compute_network_firewall_policy_with_rules.go.erb + encoder: templates/terraform/encoders/resource_compute_network_firewall_policy_with_rules.go.erb + decoder: templates/terraform/decoders/resource_compute_network_firewall_policy_with_rules.go.erb + update_encoder: templates/terraform/update_encoder/resource_compute_network_firewall_policy_with_rules.go.erb + post_create: templates/terraform/post_create/resource_compute_network_firewall_policy_with_rules.go.erb +properties: + - !ruby/object:Api::Type::String + name: creationTimestamp + description: Creation timestamp in RFC3339 text format. + output: true + - !ruby/object:Api::Type::String + name: name + description: | + User-provided name of the Network firewall policy. + The name should be unique in the project in which the firewall policy is created. + The name must be 1-63 characters long, and comply with RFC1035. Specifically, + the name must be 1-63 characters long and match the regular expression [a-z]([-a-z0-9]*[a-z0-9])? + which means the first character must be a lowercase letter, and all following characters must be a dash, + lowercase letter, or digit, except the last character, which cannot be a dash. + required: true + immutable: true + - !ruby/object:Api::Type::String + name: networkFirewallPolicyId + description: The unique identifier for the resource. This identifier is defined by the server. + output: true + api_name: id + - !ruby/object:Api::Type::String + name: description + description: An optional description of this resource. + - !ruby/object:Api::Type::Array + name: 'rule' + api_name: 'rules' + description: A list of firewall policy rules. + required: true + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'description' + description: | + A description of the rule. + - !ruby/object:Api::Type::String + name: 'ruleName' + description: | + An optional name for the rule. This field is not a unique identifier + and can be updated. + - !ruby/object:Api::Type::Integer + name: 'priority' + description: | + An integer indicating the priority of a rule in the list. The priority must be a value + between 0 and 2147483647. Rules are evaluated from highest to lowest priority where 0 is the + highest priority and 2147483647 is the lowest priority. + required: true + - !ruby/object:Api::Type::NestedObject + name: 'match' + description: + A match condition that incoming traffic is evaluated against. If it + evaluates to true, the corresponding 'action' is enforced. + required: true + properties: + - !ruby/object:Api::Type::Array + name: 'srcIpRanges' + description: | + Source IP address range in CIDR format. Required for + INGRESS rules. + item_type: Api::Type::String + - !ruby/object:Api::Type::Array + name: 'destIpRanges' + description: | + Destination IP address range in CIDR format. Required for + EGRESS rules. + item_type: Api::Type::String + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'srcAddressGroups' + description: | + Address groups which should be matched against the traffic source. + Maximum number of source address groups is 10. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'destAddressGroups' + description: | + Address groups which should be matched against the traffic destination. + Maximum number of destination address groups is 10. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'srcFqdns' + description: | + Fully Qualified Domain Name (FQDN) which should be matched against + traffic source. Maximum number of source fqdn allowed is 100. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'destFqdns' + description: | + Fully Qualified Domain Name (FQDN) which should be matched against + traffic destination. Maximum number of destination fqdn allowed is 100. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'srcRegionCodes' + description: | + Region codes whose IP addresses will be used to match for source + of traffic. Should be specified as 2 letter country code defined as per + ISO 3166 alpha-2 country codes. ex."US" + Maximum number of source region codes allowed is 5000. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'destRegionCodes' + description: | + Region codes whose IP addresses will be used to match for destination + of traffic. Should be specified as 2 letter country code defined as per + ISO 3166 alpha-2 country codes. ex."US" + Maximum number of destination region codes allowed is 5000. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'srcThreatIntelligences' + description: | + Names of Network Threat Intelligence lists. + The IPs in these lists will be matched against traffic source. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'destThreatIntelligences' + description: | + Names of Network Threat Intelligence lists. + The IPs in these lists will be matched against traffic destination. + - !ruby/object:Api::Type::Array + name: 'layer4Config' + api_name: 'layer4Configs' + description: | + Pairs of IP protocols and ports that the rule should match. + required: true + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'ipProtocol' + description: | + The IP protocol to which this rule applies. The protocol + type is required when creating a firewall rule. + This value can either be one of the following well + known protocol strings (tcp, udp, icmp, esp, ah, ipip, sctp), + or the IP protocol number. + required: true + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'ports' + description: | + An optional list of ports to which this rule applies. This field + is only applicable for UDP or TCP protocol. Each entry must be + either an integer or a range. If not specified, this rule + applies to connections through any port. + Example inputs include: ["22"], ["80","443"], and + ["12345-12349"]. + - !ruby/object:Api::Type::Array + name: 'srcSecureTag' + api_name: 'srcSecureTags' + description: | + List of secure tag values, which should be matched at the source + of the traffic. + For INGRESS rule, if all the srcSecureTag are INEFFECTIVE, + and there is no srcIpRange, this rule will be ignored. + Maximum number of source tag values allowed is 256. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'name' + description: | + Name of the secure tag, created with TagManager's TagValue API. + @pattern tagValues/[0-9]+ + - !ruby/object:Api::Type::Enum + name: 'state' + output: true + description: | + [Output Only] State of the secure tag, either `EFFECTIVE` or + `INEFFECTIVE`. A secure tag is `INEFFECTIVE` when it is deleted + or its network is deleted. + values: + - :EFFECTIVE + - :INEFFECTIVE + - !ruby/object:Api::Type::Array + name: 'targetSecureTag' + api_name: 'targetSecureTags' + description: | + A list of secure tags that controls which instances the firewall rule + applies to. If targetSecureTag are specified, then the + firewall rule applies only to instances in the VPC network that have one + of those EFFECTIVE secure tags, if all the target_secure_tag are in + INEFFECTIVE state, then this rule will be ignored. + targetSecureTag may not be set at the same time as + targetServiceAccounts. + If neither targetServiceAccounts nor + targetSecureTag are specified, the firewall rule applies + to all instances on the specified network. + Maximum number of target label tags allowed is 256. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'name' + description: | + Name of the secure tag, created with TagManager's TagValue API. + @pattern tagValues/[0-9]+ + - !ruby/object:Api::Type::Enum + name: 'state' + output: true + description: | + [Output Only] State of the secure tag, either `EFFECTIVE` or + `INEFFECTIVE`. A secure tag is `INEFFECTIVE` when it is deleted + or its network is deleted. + values: + - :EFFECTIVE + - :INEFFECTIVE + - !ruby/object:Api::Type::String + name: 'action' + description: | + The Action to perform when the client connection triggers the rule. Can currently be either + "allow", "deny", "apply_security_profile_group" or "goto_next". + required: true + - !ruby/object:Api::Type::Enum + name: 'direction' + description: | + The direction in which this rule applies. If unspecified an INGRESS rule is created. + values: + - :INGRESS + - :EGRESS + - !ruby/object:Api::Type::Boolean + name: 'enableLogging' + description: | + Denotes whether to enable logging for a particular rule. + If logging is enabled, logs will be exported to the + configured export destination in Stackdriver. + send_empty_value: true + - !ruby/object:Api::Type::Array + name: 'targetServiceAccounts' + description: | + A list of service accounts indicating the sets of + instances that are applied with this rule. + item_type: Api::Type::String + - !ruby/object:Api::Type::String + name: 'securityProfileGroup' + description: | + A fully-qualified URL of a SecurityProfile resource instance. + Example: + https://networksecurity.googleapis.com/v1/projects/{project}/locations/{location}/securityProfileGroups/my-security-profile-group + Must be specified if action is 'apply_security_profile_group'. + - !ruby/object:Api::Type::Boolean + name: 'tlsInspect' + description: | + Boolean flag indicating if the traffic should be TLS decrypted. + It can be set only if action = 'apply_security_profile_group' and cannot be set for other actions. + - !ruby/object:Api::Type::Boolean + name: 'disabled' + description: | + Denotes whether the firewall policy rule is disabled. When set to true, + the firewall policy rule is not enforced and traffic behaves as if it did + not exist. If this is unspecified, the firewall policy rule will be + enabled. + - !ruby/object:Api::Type::Array + name: 'predefinedRules' + description: A list of firewall policy pre-defined rules. + output: true + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'description' + output: true + description: | + A description of the rule. + - !ruby/object:Api::Type::String + name: 'ruleName' + output: true + description: | + An optional name for the rule. This field is not a unique identifier + and can be updated. + - !ruby/object:Api::Type::Integer + name: 'priority' + output: true + description: | + An integer indicating the priority of a rule in the list. The priority must be a value + between 0 and 2147483647. Rules are evaluated from highest to lowest priority where 0 is the + highest priority and 2147483647 is the lowest priority. + - !ruby/object:Api::Type::NestedObject + name: 'match' + output: true + description: + A match condition that incoming traffic is evaluated against. If it + evaluates to true, the corresponding 'action' is enforced. + properties: + - !ruby/object:Api::Type::Array + name: 'srcIpRanges' + output: true + description: | + Source IP address range in CIDR format. Required for + INGRESS rules. + item_type: Api::Type::String + - !ruby/object:Api::Type::Array + name: 'destIpRanges' + output: true + description: | + Destination IP address range in CIDR format. Required for + EGRESS rules. + item_type: Api::Type::String + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + output: true + name: 'srcAddressGroups' + description: | + Address groups which should be matched against the traffic source. + Maximum number of source address groups is 10. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + output: true + name: 'destAddressGroups' + description: | + Address groups which should be matched against the traffic destination. + Maximum number of destination address groups is 10. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'srcFqdns' + output: true + description: | + Fully Qualified Domain Name (FQDN) which should be matched against + traffic source. Maximum number of source fqdn allowed is 100. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'destFqdns' + output: true + description: | + Fully Qualified Domain Name (FQDN) which should be matched against + traffic destination. Maximum number of destination fqdn allowed is 100. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'srcRegionCodes' + output: true + description: | + Region codes whose IP addresses will be used to match for source + of traffic. Should be specified as 2 letter country code defined as per + ISO 3166 alpha-2 country codes. ex."US" + Maximum number of source region codes allowed is 5000. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'destRegionCodes' + output: true + description: | + Region codes whose IP addresses will be used to match for destination + of traffic. Should be specified as 2 letter country code defined as per + ISO 3166 alpha-2 country codes. ex."US" + Maximum number of destination region codes allowed is 5000. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'srcThreatIntelligences' + output: true + description: | + Names of Network Threat Intelligence lists. + The IPs in these lists will be matched against traffic source. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'destThreatIntelligences' + output: true + description: | + Names of Network Threat Intelligence lists. + The IPs in these lists will be matched against traffic destination. + - !ruby/object:Api::Type::Array + name: 'layer4Config' + output: true + api_name: 'layer4Configs' + description: | + Pairs of IP protocols and ports that the rule should match. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'ipProtocol' + output: true + description: | + The IP protocol to which this rule applies. The protocol + type is required when creating a firewall rule. + This value can either be one of the following well + known protocol strings (tcp, udp, icmp, esp, ah, ipip, sctp), + or the IP protocol number. + - !ruby/object:Api::Type::Array + item_type: Api::Type::String + name: 'ports' + output: true + description: | + An optional list of ports to which this rule applies. This field + is only applicable for UDP or TCP protocol. Each entry must be + either an integer or a range. If not specified, this rule + applies to connections through any port. + Example inputs include: ["22"], ["80","443"], and + ["12345-12349"]. + - !ruby/object:Api::Type::Array + name: 'srcSecureTag' + api_name: 'srcSecureTags' + output: true + description: | + List of secure tag values, which should be matched at the source + of the traffic. + For INGRESS rule, if all the srcSecureTag are INEFFECTIVE, + and there is no srcIpRange, this rule will be ignored. + Maximum number of source tag values allowed is 256. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'name' + output: true + description: | + Name of the secure tag, created with TagManager's TagValue API. + @pattern tagValues/[0-9]+ + - !ruby/object:Api::Type::Enum + name: 'state' + output: true + description: | + [Output Only] State of the secure tag, either `EFFECTIVE` or + `INEFFECTIVE`. A secure tag is `INEFFECTIVE` when it is deleted + or its network is deleted. + values: + - :EFFECTIVE + - :INEFFECTIVE + - !ruby/object:Api::Type::Array + name: 'targetSecureTag' + api_name: 'targetSecureTags' + output: true + description: | + A list of secure tags that controls which instances the firewall rule + applies to. If targetSecureTag are specified, then the + firewall rule applies only to instances in the VPC network that have one + of those EFFECTIVE secure tags, if all the target_secure_tag are in + INEFFECTIVE state, then this rule will be ignored. + targetSecureTag may not be set at the same time as + targetServiceAccounts. + If neither targetServiceAccounts nor + targetSecureTag are specified, the firewall rule applies + to all instances on the specified network. + Maximum number of target label tags allowed is 256. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: 'name' + output: true + description: | + Name of the secure tag, created with TagManager's TagValue API. + @pattern tagValues/[0-9]+ + - !ruby/object:Api::Type::Enum + name: 'state' + output: true + description: | + [Output Only] State of the secure tag, either `EFFECTIVE` or + `INEFFECTIVE`. A secure tag is `INEFFECTIVE` when it is deleted + or its network is deleted. + values: + - :EFFECTIVE + - :INEFFECTIVE + - !ruby/object:Api::Type::String + name: 'action' + output: true + description: | + The Action to perform when the client connection triggers the rule. Can currently be either + "allow", "deny", "apply_security_profile_group" or "goto_next". + - !ruby/object:Api::Type::Enum + name: 'direction' + output: true + description: | + The direction in which this rule applies. If unspecified an INGRESS rule is created. + values: + - :INGRESS + - :EGRESS + - !ruby/object:Api::Type::Boolean + name: 'enableLogging' + output: true + description: | + Denotes whether to enable logging for a particular rule. + If logging is enabled, logs will be exported to the + configured export destination in Stackdriver. + send_empty_value: true + - !ruby/object:Api::Type::Array + name: 'targetServiceAccounts' + output: true + description: | + A list of service accounts indicating the sets of + instances that are applied with this rule. + item_type: Api::Type::String + - !ruby/object:Api::Type::String + name: 'securityProfileGroup' + output: true + description: | + A fully-qualified URL of a SecurityProfile resource instance. + Example: + https://networksecurity.googleapis.com/v1/projects/{project}/locations/{location}/securityProfileGroups/my-security-profile-group + Must be specified if action is 'apply_security_profile_group'. + - !ruby/object:Api::Type::Boolean + name: 'tlsInspect' + output: true + description: | + Boolean flag indicating if the traffic should be TLS decrypted. + It can be set only if action = 'apply_security_profile_group' and cannot be set for other actions. + - !ruby/object:Api::Type::Boolean + name: 'disabled' + output: true + description: | + Denotes whether the firewall policy rule is disabled. When set to true, + the firewall policy rule is not enforced and traffic behaves as if it did + not exist. If this is unspecified, the firewall policy rule will be + enabled. + - !ruby/object:Api::Type::Fingerprint + name: fingerprint + description: Fingerprint of the resource. This field is used internally during updates of this resource. + output: true + - !ruby/object:Api::Type::String + name: selfLink + description: Server-defined URL for the resource. + output: true + - !ruby/object:Api::Type::String + name: selfLinkWithId + description: Server-defined URL for this resource with the resource id. + output: true + - !ruby/object:Api::Type::Integer + name: ruleTupleCount + description: Total count of all firewall policy rule tuples. A firewall policy can not exceed a set number of tuples. + output: true diff --git a/mmv1/templates/terraform/constants/resource_compute_network_firewall_policy_with_rules.go.erb b/mmv1/templates/terraform/constants/resource_compute_network_firewall_policy_with_rules.go.erb new file mode 100644 index 000000000000..3a1f2c840e51 --- /dev/null +++ b/mmv1/templates/terraform/constants/resource_compute_network_firewall_policy_with_rules.go.erb @@ -0,0 +1,54 @@ +func networkFirewallPolicyWithRulesConvertPriorityToInt(v interface {}) (int64, error) { + if strVal, ok := v.(string); ok { + if intVal, err := tpgresource.StringToFixed64(strVal); err == nil { + return intVal, nil + } + } + + if intVal, ok := v.(int64); ok { + return intVal, nil + } + + if floatVal, ok := v.(float64); ok { + intVal := int64(floatVal) + return intVal, nil + } + + return 0, fmt.Errorf("Incorrect rule priority: %s. Priority must be a number", v) +} + +func networkFirewallPolicyWithRulesIsPredefinedRule(rule map[string]interface{}) (bool, error) { + // Priorities from 2147483548 to 2147483647 are reserved and cannot be modified by the user. + const ReservedPriorityStart = 2147483548 + + priority := rule["priority"] + priorityInt, err := networkFirewallPolicyWithRulesConvertPriorityToInt(priority) + + if err != nil { + return false, err + } + + return priorityInt >= ReservedPriorityStart, nil + +} + +func networkFirewallPolicyWithRulesSplitPredefinedRules(allRules []interface{}) ([]interface{}, []interface{}, error) { + predefinedRules := make([]interface{}, 0) + rules := make([]interface{}, 0) + + for _, rule := range allRules { + isPredefined, err := networkFirewallPolicyWithRulesIsPredefinedRule(rule.(map[string]interface{})) + if err != nil { + return nil, nil, err + } + + if isPredefined { + predefinedRules = append(predefinedRules, rule) + } else { + rules = append(rules, rule) + } + } + + return rules, predefinedRules, nil +} + diff --git a/mmv1/templates/terraform/decoders/resource_compute_network_firewall_policy_with_rules.go.erb b/mmv1/templates/terraform/decoders/resource_compute_network_firewall_policy_with_rules.go.erb new file mode 100644 index 000000000000..e702145fec61 --- /dev/null +++ b/mmv1/templates/terraform/decoders/resource_compute_network_firewall_policy_with_rules.go.erb @@ -0,0 +1,16 @@ +rules, predefinedRules, err := networkFirewallPolicyWithRulesSplitPredefinedRules(res["rules"].([]interface{})) + +if err != nil { + return nil, fmt.Errorf("Error occurred while splitting pre-defined rules: %s", err) +} + +res["rules"] = rules +res["predefinedRules"] = predefinedRules + +config := meta.(*transport_tpg.Config) + +if err := d.Set("predefined_rules", flattenComputeNetworkFirewallPolicyWithRulesPredefinedRules(predefinedRules, d, config)); err != nil { + return nil, fmt.Errorf("Error occurred while setting pre-defined rules: %s", err) +} + +return res, nil diff --git a/mmv1/templates/terraform/encoders/resource_compute_network_firewall_policy_with_rules.go.erb b/mmv1/templates/terraform/encoders/resource_compute_network_firewall_policy_with_rules.go.erb new file mode 100644 index 000000000000..939b22280811 --- /dev/null +++ b/mmv1/templates/terraform/encoders/resource_compute_network_firewall_policy_with_rules.go.erb @@ -0,0 +1,3 @@ +delete(obj, "rules") // Rules are not supported in the create API +return obj, nil + diff --git a/mmv1/templates/terraform/examples/compute_network_firewall_policy_with_rules_full.tf.erb b/mmv1/templates/terraform/examples/compute_network_firewall_policy_with_rules_full.tf.erb new file mode 100644 index 000000000000..13957d97b137 --- /dev/null +++ b/mmv1/templates/terraform/examples/compute_network_firewall_policy_with_rules_full.tf.erb @@ -0,0 +1,116 @@ +data "google_project" "project" { + provider = google-beta +} + +resource "google_compute_network_firewall_policy_with_rules" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['policy_name'] %>" + description = "Terraform test" + provider = google-beta + + rule { + description = "tcp rule" + priority = 1000 + enable_logging = true + action = "allow" + direction = "EGRESS" + match { + layer4_config { + ip_protocol = "tcp" + ports = [8080, 7070] + } + dest_ip_ranges = ["11.100.0.1/32"] + dest_fqdns = ["www.yyy.com", "www.zzz.com"] + dest_region_codes = ["HK", "IN"] + dest_threat_intelligences = ["iplist-search-engines-crawlers", "iplist-tor-exit-nodes"] + dest_address_groups = [google_network_security_address_group.address_group_1.id] + } + target_secure_tag { + name = "tagValues/${google_tags_tag_value.secure_tag_value_1.name}" + } + } + rule { + description = "udp rule" + priority = 2000 + enable_logging = false + action = "deny" + direction = "INGRESS" + match { + layer4_config { + ip_protocol = "udp" + } + src_ip_ranges = ["0.0.0.0/0"] + src_fqdns = ["www.abc.com", "www.def.com"] + src_region_codes = ["US", "CA"] + src_threat_intelligences = ["iplist-known-malicious-ips", "iplist-public-clouds"] + src_address_groups = [google_network_security_address_group.address_group_1.id] + src_secure_tag { + name = "tagValues/${google_tags_tag_value.secure_tag_value_1.name}" + } + } + disabled = true + } + + rule { + description = "security profile group rule" + rule_name = "tcp rule" + priority = 3000 + enable_logging = false + action = "apply_security_profile_group" + direction = "INGRESS" + match { + layer4_config { + ip_protocol = "tcp" + } + src_ip_ranges = ["0.0.0.0/0"] + } + target_service_accounts = ["test@google.com"] + security_profile_group = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.security_profile_group_1.id}" + tls_inspect = true + } +} + +resource "google_network_security_address_group" "address_group_1" { + provider = google-beta + name = "<%= ctx[:vars]['address_group_name'] %>" + parent = "projects/${data.google_project.project.name}" + description = "Global address group" + location = "global" + items = ["208.80.154.224/32"] + type = "IPV4" + capacity = 100 +} + +resource "google_tags_tag_key" "secure_tag_key_1" { + provider = google-beta + description = "Tag key" + parent = "projects/${data.google_project.project.name}" + purpose = "GCE_FIREWALL" + short_name = "<%= ctx[:vars]['tag_key_name'] %>" + purpose_data = { + network = "${data.google_project.project.name}/default" + } +} + +resource "google_tags_tag_value" "secure_tag_value_1" { + provider = google-beta + description = "Tag value" + parent = "tagKeys/${google_tags_tag_key.secure_tag_key_1.name}" + short_name = "<%= ctx[:vars]['tag_value_name'] %>" +} + +resource "google_network_security_security_profile_group" "security_profile_group_1" { + provider = google-beta + name = "<%= ctx[:vars]['security_profile_group_name'] %>" + parent = "organizations/<%= ctx[:test_env_vars]['org_id'] %>" + description = "my description" + threat_prevention_profile = google_network_security_security_profile.security_profile_1.id +} + +resource "google_network_security_security_profile" "security_profile_1" { + provider = google-beta + name = "<%= ctx[:vars]['security_profile_name'] %>" + type = "THREAT_PREVENTION" + parent = "organizations/<%= ctx[:test_env_vars]['org_id'] %>" + location = "global" +} + diff --git a/mmv1/templates/terraform/post_create/resource_compute_network_firewall_policy_with_rules.go.erb b/mmv1/templates/terraform/post_create/resource_compute_network_firewall_policy_with_rules.go.erb new file mode 100644 index 000000000000..ec4b1a1c5ce1 --- /dev/null +++ b/mmv1/templates/terraform/post_create/resource_compute_network_firewall_policy_with_rules.go.erb @@ -0,0 +1,31 @@ +log.Printf("[DEBUG] Post-create for NetworkFirewallPolicyWithRules %q", d.Id()) + +url, err = tpgresource.ReplaceVarsForId(d, config, "{{ComputeBasePath}}projects/{{project}}/global/firewallPolicies/{{name}}") +if err != nil { + return err +} + +headers = make(http.Header) +res, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Headers: headers, +}) +if err != nil { + return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("ComputeNetworkFirewallPolicyWithRules %q", d.Id())) +} + +if err := d.Set("fingerprint", flattenComputeNetworkFirewallPolicyWithRulesFingerprint(res["fingerprint"], d, config)); err != nil { + return fmt.Errorf("Error reading NetworkFirewallPolicyWithRules: %s", err) +} + +res, err = resourceComputeNetworkFirewallPolicyWithRulesDecoder(d, meta, res) +if err != nil { + return err +} + +log.Printf("[DEBUG] Updating NetworkFirewallPolicyWithRules %q", d.Id()) +return resourceComputeNetworkFirewallPolicyWithRulesUpdate(d, meta) diff --git a/mmv1/templates/terraform/update_encoder/resource_compute_network_firewall_policy_with_rules.go.erb b/mmv1/templates/terraform/update_encoder/resource_compute_network_firewall_policy_with_rules.go.erb new file mode 100644 index 000000000000..a503293a6f87 --- /dev/null +++ b/mmv1/templates/terraform/update_encoder/resource_compute_network_firewall_policy_with_rules.go.erb @@ -0,0 +1,15 @@ +config := meta.(*transport_tpg.Config) + +predefinedRulesProp, err := expandComputeNetworkFirewallPolicyWithRulesRule(d.Get("predefined_rules"), d, config) +if err != nil { + return nil, err +} + +rules := obj["rules"].([]interface{}) +obj["rules"] = append(rules, predefinedRulesProp) + +return obj, nil + + + + diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_network_firewall_policy_with_rules_test.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_network_firewall_policy_with_rules_test.go.erb new file mode 100644 index 000000000000..38e8017cebc5 --- /dev/null +++ b/mmv1/third_party/terraform/services/compute/resource_compute_network_firewall_policy_with_rules_test.go.erb @@ -0,0 +1,264 @@ +<% autogen_exception -%> +package compute_test +<% unless version == 'ga' -%> +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" + +) + +func TestAccComputeNetworkFirewallPolicyWithRules_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + "org_id": envvar.GetTestOrgFromEnv(t), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t), + CheckDestroy: testAccCheckComputeNetworkFirewallPolicyWithRulesDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeNetworkFirewallPolicyWithRules_full(context), + }, + { + ResourceName: "google_compute_network_firewall_policy_with_rules.network-firewall-policy-with-rules", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccComputeNetworkFirewallPolicyWithRules_update(context), + }, + { + ResourceName: "google_compute_network_firewall_policy_with_rules.network-firewall-policy-with-rules", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccComputeNetworkFirewallPolicyWithRules_full(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { + provider = google-beta +} + +resource "google_compute_network_firewall_policy_with_rules" "network-firewall-policy-with-rules" { + name = "tf-test-tf-fw-policy-with-rules%{random_suffix}" + description = "Terraform test" + provider = google-beta + + rule { + description = "tcp rule" + priority = 1000 + enable_logging = true + action = "allow" + direction = "EGRESS" + match { + layer4_config { + ip_protocol = "tcp" + ports = [8080, 7070] + } + dest_ip_ranges = ["11.100.0.1/32"] + dest_fqdns = ["www.yyy.com", "www.zzz.com"] + dest_region_codes = ["HK", "IN"] + dest_threat_intelligences = ["iplist-search-engines-crawlers", "iplist-tor-exit-nodes"] + dest_address_groups = [google_network_security_address_group.address_group_1.id] + } + target_secure_tag { + name = "tagValues/${google_tags_tag_value.secure_tag_value_1.name}" + } + } + rule { + description = "udp rule" + priority = 2000 + enable_logging = false + action = "deny" + direction = "INGRESS" + match { + layer4_config { + ip_protocol = "udp" + } + src_ip_ranges = ["0.0.0.0/0"] + src_fqdns = ["www.abc.com", "www.def.com"] + src_region_codes = ["US", "CA"] + src_threat_intelligences = ["iplist-known-malicious-ips", "iplist-public-clouds"] + src_address_groups = [google_network_security_address_group.address_group_1.id] + src_secure_tag { + name = "tagValues/${google_tags_tag_value.secure_tag_value_1.name}" + } + } + disabled = true + } + + rule { + description = "security profile group rule" + rule_name = "tcp rule" + priority = 3000 + enable_logging = false + action = "apply_security_profile_group" + direction = "INGRESS" + match { + layer4_config { + ip_protocol = "tcp" + } + src_ip_ranges = ["0.0.0.0/0"] + } + target_service_accounts = ["test@google.com"] + security_profile_group = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.security_profile_group_1.id}" + } +} + +resource "google_network_security_address_group" "address_group_1" { + provider = google-beta + name = "tf-test-tf-address-group%{random_suffix}" + parent = "projects/${data.google_project.project.name}" + description = "Global address group" + location = "global" + items = ["208.80.154.224/32"] + type = "IPV4" + capacity = 100 +} + +resource "google_tags_tag_key" "secure_tag_key_1" { + provider = google-beta + description = "Tag key" + parent = "projects/${data.google_project.project.name}" + purpose = "GCE_FIREWALL" + short_name = "tf-test-tf-tag-key%{random_suffix}" + purpose_data = { + network = "${data.google_project.project.name}/default" + } +} + +resource "google_tags_tag_value" "secure_tag_value_1" { + provider = google-beta + description = "Tag value" + parent = "tagKeys/${google_tags_tag_key.secure_tag_key_1.name}" + short_name = "tf-test-tf-tag-value%{random_suffix}" +} + +resource "google_network_security_security_profile_group" "security_profile_group_1" { + provider = google-beta + name = "tf-test-tf-security-profile-group%{random_suffix}" + parent = "organizations/%{org_id}" + description = "my description" + threat_prevention_profile = google_network_security_security_profile.security_profile_1.id +} + +resource "google_network_security_security_profile" "security_profile_1" { + provider = google-beta + name = "tf-test-tf-security-profile%{random_suffix}" + type = "THREAT_PREVENTION" + parent = "organizations/%{org_id}" + location = "global" +} +`, context) +} + +func testAccComputeNetworkFirewallPolicyWithRules_update(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_project" "project" { + provider = google-beta +} + +resource "google_compute_network_firewall_policy_with_rules" "network-firewall-policy-with-rules" { + name = "tf-test-tf-fw-policy-with-rules%{random_suffix}" + description = "Terraform test - update" + provider = google-beta + + rule { + description = "tcp rule - changed" + priority = 1000 + enable_logging = false + action = "apply_security_profile_group" + direction = "EGRESS" + match { + layer4_config { + ip_protocol = "tcp" + ports = [8080, 7070] + } + dest_ip_ranges = ["11.100.0.1/32"] + } + target_service_accounts = ["test@google.com"] + security_profile_group = "//networksecurity.googleapis.com/${google_network_security_security_profile_group.security_profile_group_1.id}" + tls_inspect = true + } + rule { + description = "new udp rule" + priority = 4000 + enable_logging = true + action = "deny" + direction = "INGRESS" + match { + layer4_config { + ip_protocol = "udp" + } + src_ip_ranges = ["0.0.0.0/0"] + src_fqdns = ["www.abc.com", "www.ghi.com"] + src_region_codes = ["IT", "FR"] + src_threat_intelligences = ["iplist-public-clouds"] + src_address_groups = [google_network_security_address_group.address_group_1.id] + src_secure_tag { + name = "tagValues/${google_tags_tag_value.secure_tag_value_1.name}" + } + } + disabled = false + } +} + +resource "google_network_security_address_group" "address_group_1" { + provider = google-beta + name = "tf-test-tf-address-group%{random_suffix}" + parent = "projects/${data.google_project.project.name}" + description = "Global address group" + location = "global" + items = ["208.80.154.224/32"] + type = "IPV4" + capacity = 100 +} + +resource "google_tags_tag_key" "secure_tag_key_1" { + provider = google-beta + description = "Tag key" + parent = "projects/${data.google_project.project.name}" + purpose = "GCE_FIREWALL" + short_name = "tf-test-tf-tag-key%{random_suffix}" + purpose_data = { + network = "${data.google_project.project.name}/default" + } +} + +resource "google_tags_tag_value" "secure_tag_value_1" { + provider = google-beta + description = "Tag value" + parent = "tagKeys/${google_tags_tag_key.secure_tag_key_1.name}" + short_name = "tf-test-tf-tag-value%{random_suffix}" +} + +resource "google_network_security_security_profile_group" "security_profile_group_1" { + provider = google-beta + name = "tf-test-tf-security-profile-group%{random_suffix}" + parent = "organizations/%{org_id}" + description = "my description" + threat_prevention_profile = google_network_security_security_profile.security_profile_1.id +} + +resource "google_network_security_security_profile" "security_profile_1" { + provider = google-beta + name = "tf-test-tf-security-profile%{random_suffix}" + type = "THREAT_PREVENTION" + parent = "organizations/%{org_id}" + location = "global" +} +`, context) +} +<% end -%> + +