Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changelog/16373.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
```release-note:enhancement
compute: added `dest_network_context`, `src_network_context` and `src_networks` fields to `google_compute_firewall_policy_rule` resource
```
```release-note:enhancement
compute: added `dest_network_context`, `src_network_context` and `src_networks` fields to `google_compute_network_firewall_policy_rule` resource
```
```release-note:enhancement
compute: added `dest_network_context`, `src_network_context` and `src_networks` fields to `google_compute_region_network_firewall_policy_rule` resource
```
77 changes: 77 additions & 0 deletions google-beta/services/compute/firewall_policy_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** Type: Handwritten ***
//
// ----------------------------------------------------------------------------
//
// This code is generated by Magic Modules using the following:
//
// Source file: https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/third_party/terraform/services/compute/firewall_policy_utils.go
//
// DO NOT EDIT this file directly. Any changes made to this file will be
// overwritten during the next generation cycle.
//
// ----------------------------------------------------------------------------
package compute

import "fmt"

// It adjusts obj in case network scope/context fields are used - in beta API both network scope/context fields are available.
// The GET method returns both of them with the same value (you can think of network scope field as an alias for the network context field).
// Terraform allows only one of them to be used (using 'conflicts' annotation) but because the terraform state has both of them we have
// to remove one of them if there's a change so that it's obvious what is the new value and to prevent terraform to report differences
// after the changes are applied.
func adjustFirewallPolicyRuleNetworkContextFields(obj map[string]interface{}, oldMatch interface{}, newMatch interface{}) error {

match, exists := obj["match"]

if !exists {
return nil
}

err := adjustFields(match.(map[string]interface{}), oldMatch, newMatch, "src_network_scope", "src_network_context")
if err != nil {
return err
}
err = adjustFields(match.(map[string]interface{}), oldMatch, newMatch, "dest_network_scope", "dest_network_context")
if err != nil {
return err
}
return nil
}

func adjustFields(match map[string]interface{}, oldMatch interface{}, newMatch interface{}, fieldName1 string, fieldName2 string) error {
oldField1 := getFieldValue(oldMatch, fieldName1)
newField1 := getFieldValue(newMatch, fieldName1)
oldField2 := getFieldValue(oldMatch, fieldName2)
newField2 := getFieldValue(newMatch, fieldName2)

field1Changed := newField1 != oldField1
field2Changed := newField2 != oldField2

if field1Changed && field2Changed {
// it should not be possible because one cannot use both fields at the same time (using 'conflicts' in schema)
return fmt.Errorf("Cannot change both %s and %s at the same time", fieldName1, fieldName2)
}

if field1Changed {
delete(match, fieldName2)
} else if field2Changed {
delete(match, fieldName1)
}
return nil
}

func getFieldValue(match any, fieldName string) string {
// Extract the nested field value from the old match
if valuesList := match.([]interface{}); len(valuesList) > 0 {
if data := valuesList[0].(map[string]interface{}); data != nil {
if val, ok := data[fieldName].(string); ok {
return val
}
}
}
return ""
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,21 @@ Example inputs include: ["22"], ["80","443"], and ["12345-12349"].`,
Type: schema.TypeString,
},
},
"dest_network_context": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"UNSPECIFIED", "INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS", ""}),
Description: `Network context of the traffic destination. Possible values: ["UNSPECIFIED", "INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS"]`,
ConflictsWith: []string{"match.0.src_network_scope"},
},
"dest_network_scope": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS", ""}),
Description: `Network scope of the traffic destination. Possible values: ["INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS"]`,
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"UNSPECIFIED", "INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS", ""}),
Description: `Network scope of the traffic destination. Possible values: ["UNSPECIFIED", "INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS"]`,
ConflictsWith: []string{"match.0.src_network_context"},
},
"dest_region_codes": {
Type: schema.TypeList,
Expand Down Expand Up @@ -237,11 +247,21 @@ Example inputs include: ["22"], ["80","443"], and ["12345-12349"].`,
Type: schema.TypeString,
},
},
"src_network_context": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"UNSPECIFIED", "INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS", ""}),
Description: `Network context of the traffic source. Possible values: ["UNSPECIFIED", "INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS"]`,
ConflictsWith: []string{"match.0.src_network_scope"},
},
"src_network_scope": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS", ""}),
Description: `Network scope of the traffic source. Possible values: ["INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS"]`,
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: verify.ValidateEnum([]string{"UNSPECIFIED", "INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS", ""}),
Description: `Network scope of the traffic source. Possible values: ["UNSPECIFIED", "INTERNET", "INTRA_VPC", "NON_INTERNET", "VPC_NETWORKS"]`,
ConflictsWith: []string{"match.0.src_network_context"},
},
"src_networks": {
Type: schema.TypeList,
Expand Down Expand Up @@ -701,6 +721,11 @@ func resourceComputeFirewallPolicyRuleUpdate(d *schema.ResourceData, meta interf
obj["firewallPolicy"] = firewallPolicyProp
}

obj, err = resourceComputeFirewallPolicyRuleUpdateEncoder(d, meta, obj)
if err != nil {
return err
}

url, err := tpgresource.ReplaceVarsForId(d, config, "{{ComputeBasePath}}locations/global/firewallPolicies/{{firewall_policy}}/patchRule?priority={{priority}}")
if err != nil {
return err
Expand Down Expand Up @@ -862,10 +887,14 @@ func flattenComputeFirewallPolicyRuleMatch(v interface{}, d *schema.ResourceData
flattenComputeFirewallPolicyRuleMatchDestIpRanges(original["destIpRanges"], d, config)
transformed["src_network_scope"] =
flattenComputeFirewallPolicyRuleMatchSrcNetworkScope(original["srcNetworkScope"], d, config)
transformed["src_network_context"] =
flattenComputeFirewallPolicyRuleMatchSrcNetworkContext(original["srcNetworkContext"], d, config)
transformed["src_networks"] =
flattenComputeFirewallPolicyRuleMatchSrcNetworks(original["srcNetworks"], d, config)
transformed["dest_network_scope"] =
flattenComputeFirewallPolicyRuleMatchDestNetworkScope(original["destNetworkScope"], d, config)
transformed["dest_network_context"] =
flattenComputeFirewallPolicyRuleMatchDestNetworkContext(original["destNetworkContext"], d, config)
transformed["layer4_configs"] =
flattenComputeFirewallPolicyRuleMatchLayer4Configs(original["layer4Configs"], d, config)
transformed["dest_address_groups"] =
Expand Down Expand Up @@ -900,6 +929,10 @@ func flattenComputeFirewallPolicyRuleMatchSrcNetworkScope(v interface{}, d *sche
return v
}

func flattenComputeFirewallPolicyRuleMatchSrcNetworkContext(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenComputeFirewallPolicyRuleMatchSrcNetworks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
Expand All @@ -908,6 +941,10 @@ func flattenComputeFirewallPolicyRuleMatchDestNetworkScope(v interface{}, d *sch
return v
}

func flattenComputeFirewallPolicyRuleMatchDestNetworkContext(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenComputeFirewallPolicyRuleMatchLayer4Configs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
Expand Down Expand Up @@ -1111,6 +1148,13 @@ func expandComputeFirewallPolicyRuleMatch(v interface{}, d tpgresource.Terraform
transformed["srcNetworkScope"] = transformedSrcNetworkScope
}

transformedSrcNetworkContext, err := expandComputeFirewallPolicyRuleMatchSrcNetworkContext(original["src_network_context"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedSrcNetworkContext); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["srcNetworkContext"] = transformedSrcNetworkContext
}

transformedSrcNetworks, err := expandComputeFirewallPolicyRuleMatchSrcNetworks(original["src_networks"], d, config)
if err != nil {
return nil, err
Expand All @@ -1125,6 +1169,13 @@ func expandComputeFirewallPolicyRuleMatch(v interface{}, d tpgresource.Terraform
transformed["destNetworkScope"] = transformedDestNetworkScope
}

transformedDestNetworkContext, err := expandComputeFirewallPolicyRuleMatchDestNetworkContext(original["dest_network_context"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedDestNetworkContext); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["destNetworkContext"] = transformedDestNetworkContext
}

transformedLayer4Configs, err := expandComputeFirewallPolicyRuleMatchLayer4Configs(original["layer4_configs"], d, config)
if err != nil {
return nil, err
Expand Down Expand Up @@ -1210,6 +1261,10 @@ func expandComputeFirewallPolicyRuleMatchSrcNetworkScope(v interface{}, d tpgres
return v, nil
}

func expandComputeFirewallPolicyRuleMatchSrcNetworkContext(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandComputeFirewallPolicyRuleMatchSrcNetworks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
Expand All @@ -1218,6 +1273,10 @@ func expandComputeFirewallPolicyRuleMatchDestNetworkScope(v interface{}, d tpgre
return v, nil
}

func expandComputeFirewallPolicyRuleMatchDestNetworkContext(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandComputeFirewallPolicyRuleMatchLayer4Configs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
if v == nil {
return nil, nil
Expand Down Expand Up @@ -1409,3 +1468,17 @@ func expandComputeFirewallPolicyRuleFirewallPolicy(v interface{}, d tpgresource.
}
return firewallPolicyId, nil
}

func resourceComputeFirewallPolicyRuleUpdateEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
if !d.HasChange("match") {
return obj, nil
}
oldMatch, newMatch := d.GetChange("match")

err := adjustFirewallPolicyRuleNetworkContextFields(obj, oldMatch, newMatch)
if err != nil {
return obj, err
}

return obj, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ fields:
field: match.dest_fqdns
- api_field: rules.match.destIpRanges
field: match.dest_ip_ranges
- api_field: rules.match.destNetworkContext
field: match.dest_network_context
- api_field: rules.match.destNetworkScope
field: match.dest_network_scope
- api_field: rules.match.destRegionCodes
Expand All @@ -43,6 +45,8 @@ fields:
field: match.src_fqdns
- api_field: rules.match.srcIpRanges
field: match.src_ip_ranges
- api_field: rules.match.srcNetworkContext
field: match.src_network_context
- api_field: rules.match.srcNetworkScope
field: match.src_network_scope
- api_field: rules.match.srcNetworks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,109 @@ resource "google_compute_network" "network" {
`, context)
}

func TestAccComputeFirewallPolicyRule_firewallPolicyRuleNetworkContextExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"org_id": envvar.GetTestOrgFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckComputeFirewallPolicyRuleDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccComputeFirewallPolicyRule_firewallPolicyRuleNetworkContextExample(context),
},
{
ResourceName: "google_compute_firewall_policy_rule.primary",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"firewall_policy"},
},
},
})
}

func testAccComputeFirewallPolicyRule_firewallPolicyRuleNetworkContextExample(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_folder" "folder" {
display_name = "folder%{random_suffix}"
parent = "organizations/%{org_id}"
deletion_protection = false
}

resource "google_compute_firewall_policy" "default" {
parent = google_folder.folder.id
short_name = "tf-test-fw-policy%{random_suffix}"
description = "Firewall policy"
}

resource "google_compute_firewall_policy_rule" "primary" {
firewall_policy = google_compute_firewall_policy.default.name
description = "Firewall policy rule with network context"
priority = 8000
action = "allow"
direction = "INGRESS"
disabled = false

match {
src_ip_ranges = ["11.100.0.1/32"]
src_network_context = "INTERNET"

layer4_configs {
ip_protocol = "tcp"
ports = [8080]
}

layer4_configs {
ip_protocol = "udp"
ports = [22]
}
}
}

resource "google_compute_firewall_policy_rule" "egress-primary" {
firewall_policy = google_compute_firewall_policy.default.name
description = "Firewall policy rule with network context"
priority = 9000
action = "allow"
direction = "EGRESS"
disabled = false

match {
dest_ip_ranges = ["11.100.0.1/32"]
dest_network_context = "NON_INTERNET"

layer4_configs {
ip_protocol = "tcp"
}
}
}

resource "google_compute_firewall_policy_rule" "unset-primary" {
firewall_policy = google_compute_firewall_policy.default.name
description = "Firewall policy rule with network context"
priority = 10000
action = "allow"
direction = "EGRESS"
disabled = false

match {
dest_ip_ranges = ["11.100.0.1/32"]
dest_network_context = "UNSPECIFIED"

layer4_configs {
ip_protocol = "tcp"
}
}
}

`, context)
}

func TestAccComputeFirewallPolicyRule_firewallPolicyRuleSecureTagsExample(t *testing.T) {
t.Parallel()

Expand Down
Loading
Loading