Skip to content

Commit b41c48e

Browse files
authored
Fix address group ordering for network firewall policy rule (#12182)
1 parent 198e6d5 commit b41c48e

4 files changed

+158
-1
lines changed

mmv1/products/compute/NetworkFirewallPolicyRule.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,16 @@ properties:
166166
- 'INEFFECTIVE'
167167
- name: 'destAddressGroups'
168168
type: Array
169-
send_empty_value: true
170169
description: |
171170
Address groups which should be matched against the traffic destination. Maximum number of destination address groups is 10.
172171
item_type:
173172
type: String
173+
send_empty_value: true
174+
custom_flatten: 'templates/terraform/custom_flatten/compute_network_firewall_policy_rule_dest_address_group_order.go.tmpl'
174175
- name: 'srcAddressGroups'
175176
type: Array
176177
send_empty_value: true
178+
custom_flatten: 'templates/terraform/custom_flatten/compute_network_firewall_policy_rule_src_address_group_order.go.tmpl'
177179
description: |
178180
Address groups which should be matched against the traffic source. Maximum number of source address groups is 10.
179181
item_type:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
func flatten{{$.GetPrefix}}{{$.TitlelizeProperty}}(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2+
rawConfigValue := d.Get("match.0.dest_address_groups")
3+
4+
// Convert config value to []string
5+
configValue, err := tpgresource.InterfaceSliceToStringSlice(rawConfigValue)
6+
if err != nil {
7+
log.Printf("[ERROR] Failed to convert config value: %s", err)
8+
return v
9+
}
10+
11+
// Convert v to []string
12+
apiStringValue, err := tpgresource.InterfaceSliceToStringSlice(v)
13+
if err != nil {
14+
log.Printf("[ERROR] Failed to convert API value: %s", err)
15+
return v
16+
}
17+
18+
sortedStrings, err := tpgresource.SortStringsByConfigOrder(configValue, apiStringValue)
19+
if err != nil {
20+
log.Printf("[ERROR] Could not sort API response value: %s", err)
21+
return v
22+
}
23+
24+
return sortedStrings
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
func flatten{{$.GetPrefix}}{{$.TitlelizeProperty}}(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
2+
rawConfigValue := d.Get("match.0.src_address_groups")
3+
4+
// Convert config value to []string
5+
configValue, err := tpgresource.InterfaceSliceToStringSlice(rawConfigValue)
6+
if err != nil {
7+
log.Printf("[ERROR] Failed to convert config value: %s", err)
8+
return v
9+
}
10+
11+
// Convert v to []string
12+
apiStringValue, err := tpgresource.InterfaceSliceToStringSlice(v)
13+
if err != nil {
14+
log.Printf("[ERROR] Failed to convert API value: %s", err)
15+
return v
16+
}
17+
18+
sortedStrings, err := tpgresource.SortStringsByConfigOrder(configValue, apiStringValue)
19+
if err != nil {
20+
log.Printf("[ERROR] Could not sort API response value: %s", err)
21+
return v
22+
}
23+
24+
return sortedStrings
25+
}

mmv1/third_party/terraform/services/compute/resource_compute_network_firewall_policy_rule_test.go.tmpl

+105
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,41 @@ func TestAccComputeNetworkFirewallPolicyRule_multipleRules(t *testing.T) {
140140
})
141141
}
142142

143+
func TestAccComputeNetworkFirewallPolicyRule_addressGroupOrder(t *testing.T) {
144+
t.Parallel()
145+
146+
context := map[string]interface{}{
147+
"random_suffix": acctest.RandString(t, 10),
148+
"project": envvar.GetTestProjectFromEnv(),
149+
}
150+
151+
acctest.VcrTest(t, resource.TestCase{
152+
PreCheck: func() { acctest.AccTestPreCheck(t) },
153+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
154+
Steps: []resource.TestStep{
155+
{
156+
Config: testAccComputeNetworkFirewallPolicyRule_addressGroupOrder(context),
157+
},
158+
{
159+
ResourceName: "google_compute_network_firewall_policy_rule.src_test",
160+
ImportState: true,
161+
ImportStateVerify: true,
162+
// Referencing using ID causes import to fail
163+
// Client-side reordering doesn't work with no state, so ignore on import
164+
ImportStateVerifyIgnore: []string{"firewall_policy", "match.0.src_address_groups"},
165+
},
166+
{
167+
ResourceName: "google_compute_network_firewall_policy_rule.dest_test",
168+
ImportState: true,
169+
ImportStateVerify: true,
170+
// Referencing using ID causes import to fail
171+
// Client-side reordering doesn't work with no state, so ignore on import
172+
ImportStateVerifyIgnore: []string{"firewall_policy", "match.0.dest_address_groups"},
173+
},
174+
},
175+
})
176+
}
177+
143178
func TestAccComputeNetworkFirewallPolicyRule_securityProfileGroup_update(t *testing.T) {
144179
t.Parallel()
145180

@@ -896,3 +931,73 @@ resource "google_compute_network_firewall_policy_rule" "fw_policy_rule3" {
896931
}
897932
`, context)
898933
}
934+
935+
936+
func testAccComputeNetworkFirewallPolicyRule_addressGroupOrder(context map[string]interface{}) string {
937+
return acctest.Nprintf(`
938+
resource "google_compute_network_firewall_policy" "policy" {
939+
name = "tf-test-policy-%{random_suffix}"
940+
description = "Resource created for Terraform acceptance testing"
941+
}
942+
943+
resource "google_network_security_address_group" "add-group1" {
944+
name = "tf-test-group-1-%{random_suffix}"
945+
parent = "projects/%{project}"
946+
location = "global"
947+
type = "IPV4"
948+
capacity = "10"
949+
items = ["10.0.1.1/32"]
950+
}
951+
resource "google_network_security_address_group" "add-group2" {
952+
name = "tf-test-group-2-%{random_suffix}"
953+
parent = "projects/%{project}"
954+
location = "global"
955+
type = "IPV4"
956+
capacity = "10"
957+
items = ["10.0.2.2/32"]
958+
}
959+
resource "google_network_security_address_group" "add-group3" {
960+
name = "tf-test-group-3-%{random_suffix}"
961+
parent = "projects/%{project}"
962+
location = "global"
963+
type = "IPV4"
964+
capacity = "10"
965+
items = ["10.0.3.3/32"]
966+
}
967+
968+
resource "google_compute_network_firewall_policy_rule" "src_test" {
969+
firewall_policy = google_compute_network_firewall_policy.policy.id
970+
action = "allow"
971+
priority = 1000
972+
description = "Testing address group order issue"
973+
direction = "INGRESS"
974+
enable_logging = true
975+
match {
976+
src_address_groups = [google_network_security_address_group.add-group2.id,
977+
google_network_security_address_group.add-group1.id]
978+
dest_ip_ranges = ["192.168.2.0/24", "10.0.3.4/32"]
979+
layer4_configs {
980+
ip_protocol = "all"
981+
}
982+
}
983+
}
984+
985+
resource "google_compute_network_firewall_policy_rule" "dest_test" {
986+
firewall_policy = google_compute_network_firewall_policy.policy.id
987+
action = "allow"
988+
priority = 1100
989+
description = "Testing address group order issue"
990+
direction = "EGRESS"
991+
enable_logging = true
992+
match {
993+
dest_address_groups = [google_network_security_address_group.add-group3.id,
994+
google_network_security_address_group.add-group2.id]
995+
src_ip_ranges = ["192.168.2.0/24", "10.0.3.4/32"]
996+
layer4_configs {
997+
ip_protocol = "all"
998+
}
999+
}
1000+
}
1001+
1002+
`, context)
1003+
}

0 commit comments

Comments
 (0)