Skip to content

Commit 6683af0

Browse files
Re-deprecate enable_flow_logs (#13485) (#22111)
[upstream:644ea10a2b33f2863a1edcdc2fb3986bf8ca0518] Signed-off-by: Modular Magician <[email protected]>
1 parent d5232ab commit 6683af0

File tree

4 files changed

+24
-224
lines changed

4 files changed

+24
-224
lines changed

.changelog/13485.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
```release-note:deprecation
2+
compute: deprecated `enable_flow_logs` in favor of `log_config`. If `log_config` is present, flow logs are enabled and `enable_flow_logs` can be safely removed.
3+
```
4+
```release-note:bug
5+
compute: fixed a regression in `google_compute_subnetwork` where setting `log_config` would not enable flow logs without `enable_flow_logs` also being set to true. To enable or disable flow logs, please use `log_config`. `enable_flow_logs` is now deprecated and will be removed in the next major release.
6+
```

google/services/compute/resource_compute_subnetwork.go

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,13 @@ func sendSecondaryIpRangeIfEmptyDiff(_ context.Context, diff *schema.ResourceDif
8888
return nil
8989
}
9090

91-
// DiffSuppressFunc for fields inside `log_config`.
91+
// DiffSuppressFunc for `log_config`.
9292
func subnetworkLogConfigDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
93-
// If the enable_flow_logs is not enabled, we don't need to check for differences.
94-
if enable_flow_logs := d.Get("enable_flow_logs"); !enable_flow_logs.(bool) {
95-
return true
93+
// If enable_flow_logs is enabled and log_config is not set, ignore the diff
94+
if enable_flow_logs := d.Get("enable_flow_logs"); enable_flow_logs.(bool) {
95+
logConfig := d.GetRawConfig().GetAttr("log_config")
96+
logConfigIsEmpty := logConfig.IsNull() || logConfig.LengthInt() == 0
97+
return logConfigIsEmpty
9698
}
9799

98100
return false
@@ -153,9 +155,11 @@ you create the resource. This field can be set only at resource
153155
creation time.`,
154156
},
155157
"enable_flow_logs": {
156-
Type: schema.TypeBool,
157-
Computed: true,
158-
Optional: true,
158+
Type: schema.TypeBool,
159+
Computed: true,
160+
Optional: true,
161+
Deprecated: "This field is being removed in favor of log_config. If log_config is present, flow logs are enabled.",
162+
ForceNew: true,
159163
Description: `Whether to enable flow logging for this subnetwork. If this field is not explicitly set,
160164
it will not appear in get listings. If not set the default behavior is determined by the
161165
org policy, if there is no org policy specified, then it will default to disabled.
@@ -203,7 +207,6 @@ cannot enable direct path. Possible values: ["EXTERNAL", "INTERNAL"]`,
203207
},
204208
"log_config": {
205209
Type: schema.TypeList,
206-
Computed: true,
207210
Optional: true,
208211
DiffSuppressFunc: subnetworkLogConfigDiffSuppress,
209212
Description: `This field denotes the VPC flow logging options for this subnetwork. If
@@ -594,7 +597,7 @@ func resourceComputeSubnetworkCreate(d *schema.ResourceData, meta interface{}) e
594597
enableFlowLogsProp, err := expandComputeSubnetworkEnableFlowLogs(d.Get("enable_flow_logs"), d, config)
595598
if err != nil {
596599
return err
597-
} else if v, ok := d.GetOkExists("enable_flow_logs"); ok || !reflect.DeepEqual(v, enableFlowLogsProp) {
600+
} else if v, ok := d.GetOkExists("enable_flow_logs"); !tpgresource.IsEmptyValue(reflect.ValueOf(enableFlowLogsProp)) && (ok || !reflect.DeepEqual(v, enableFlowLogsProp)) {
598601
obj["enableFlowLogs"] = enableFlowLogsProp
599602
}
600603

@@ -880,7 +883,7 @@ func resourceComputeSubnetworkUpdate(d *schema.ResourceData, meta interface{}) e
880883
return err
881884
}
882885
}
883-
if d.HasChange("private_ipv6_google_access") || d.HasChange("stack_type") || d.HasChange("ipv6_access_type") || d.HasChange("enable_flow_logs") {
886+
if d.HasChange("private_ipv6_google_access") || d.HasChange("stack_type") || d.HasChange("ipv6_access_type") {
884887
obj := make(map[string]interface{})
885888

886889
getUrl, err := tpgresource.ReplaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/subnetworks/{{name}}")
@@ -924,12 +927,6 @@ func resourceComputeSubnetworkUpdate(d *schema.ResourceData, meta interface{}) e
924927
} else if v, ok := d.GetOkExists("ipv6_access_type"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, ipv6AccessTypeProp)) {
925928
obj["ipv6AccessType"] = ipv6AccessTypeProp
926929
}
927-
enableFlowLogsProp, err := expandComputeSubnetworkEnableFlowLogs(d.Get("enable_flow_logs"), d, config)
928-
if err != nil {
929-
return err
930-
} else if v, ok := d.GetOkExists("enable_flow_logs"); ok || !reflect.DeepEqual(v, enableFlowLogsProp) {
931-
obj["enableFlowLogs"] = enableFlowLogsProp
932-
}
933930

934931
url, err := tpgresource.ReplaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/subnetworks/{{name}}")
935932
if err != nil {
@@ -1676,9 +1673,8 @@ func expandComputeSubnetworkLogConfig(v interface{}, d tpgresource.TerraformReso
16761673
return nil, nil
16771674
}
16781675

1679-
// set enable field basing on the enable_flow_logs field. It's needed for case when enable_flow_logs
1680-
// is set to true to avoid conflict with the API. In that case API will return default values for log_config
1681-
transformed["enable"] = d.Get("enable_flow_logs")
1676+
// send enable = false to ensure logging is disabled if there is no config
1677+
transformed["enable"] = false
16821678
return transformed, nil
16831679
}
16841680

google/services/compute/resource_compute_subnetwork_test.go

Lines changed: 0 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -493,66 +493,6 @@ func TestAccComputeSubnetwork_internal_ipv6(t *testing.T) {
493493
})
494494
}
495495

496-
func TestAccComputeSubnetwork_enableFlowLogs(t *testing.T) {
497-
t.Parallel()
498-
var subnetwork compute.Subnetwork
499-
500-
cnName := fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
501-
subnetworkName := fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
502-
503-
acctest.VcrTest(t, resource.TestCase{
504-
PreCheck: func() { acctest.AccTestPreCheck(t) },
505-
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
506-
CheckDestroy: testAccCheckComputeSubnetworkDestroyProducer(t),
507-
Steps: []resource.TestStep{
508-
{
509-
Config: testAccComputeSubnetwork_enableFlowLogs(cnName, subnetworkName, true),
510-
Check: resource.ComposeTestCheckFunc(
511-
testAccCheckComputeSubnetworkExists(t, "google_compute_subnetwork.subnetwork", &subnetwork),
512-
testAccCheckComputeSubnetworkIfLogConfigExists(&subnetwork, "google_compute_subnetwork.subnetwork"),
513-
testAccCheckComputeSubnetworkLogConfig(&subnetwork, "log_config.0.enable", "true"),
514-
resource.TestCheckResourceAttr("google_compute_subnetwork.subnetwork", "enable_flow_logs", "true"),
515-
),
516-
},
517-
{
518-
ResourceName: "google_compute_subnetwork.subnetwork",
519-
ImportState: true,
520-
ImportStateVerify: true,
521-
},
522-
{
523-
Config: testAccComputeSubnetwork_enableFlowLogs_with_logConfig(cnName, subnetworkName, true),
524-
Check: resource.ComposeTestCheckFunc(
525-
testAccCheckComputeSubnetworkExists(t, "google_compute_subnetwork.subnetwork", &subnetwork),
526-
resource.TestCheckResourceAttr("google_compute_subnetwork.subnetwork", "enable_flow_logs", "true"),
527-
testAccCheckComputeSubnetworkLogConfig(&subnetwork, "log_config.0.enable", "true"),
528-
testAccCheckComputeSubnetworkLogConfig(&subnetwork, "log_config.0.aggregation_interval", "INTERVAL_1_MIN"),
529-
testAccCheckComputeSubnetworkLogConfig(&subnetwork, "log_config.0.metadata", "INCLUDE_ALL_METADATA"),
530-
),
531-
},
532-
{
533-
ResourceName: "google_compute_subnetwork.subnetwork",
534-
ImportState: true,
535-
ImportStateVerify: true,
536-
},
537-
{
538-
Config: testAccComputeSubnetwork_enableFlowLogs(cnName, subnetworkName, false),
539-
Check: resource.ComposeTestCheckFunc(
540-
testAccCheckComputeSubnetworkExists(t, "google_compute_subnetwork.subnetwork", &subnetwork),
541-
resource.TestCheckResourceAttr("google_compute_subnetwork.subnetwork", "enable_flow_logs", "false"),
542-
testAccCheckComputeSubnetworkLogConfig(&subnetwork, "log_config.0.enable", "false"),
543-
testAccCheckComputeSubnetworkLogConfig(&subnetwork, "log_config.0.aggregation_interval", "INTERVAL_1_MIN"),
544-
testAccCheckComputeSubnetworkLogConfig(&subnetwork, "log_config.0.metadata", "INCLUDE_ALL_METADATA"),
545-
),
546-
},
547-
{
548-
ResourceName: "google_compute_subnetwork.subnetwork",
549-
ImportState: true,
550-
ImportStateVerify: true,
551-
},
552-
},
553-
})
554-
}
555-
556496
func testAccCheckComputeSubnetworkExists(t *testing.T, n string, subnetwork *compute.Subnetwork) resource.TestCheckFunc {
557497
return func(s *terraform.State) error {
558498
rs, ok := s.RootModule().Resources[n]
@@ -613,111 +553,6 @@ func testAccCheckComputeSubnetworkHasNotSecondaryIpRange(subnetwork *compute.Sub
613553
}
614554
}
615555

616-
func testAccCheckComputeSubnetworkIfLogConfigExists(subnetwork *compute.Subnetwork, resourceName string) resource.TestCheckFunc {
617-
return func(s *terraform.State) error {
618-
// Retrieve the resource state using a fixed resource name
619-
rs, ok := s.RootModule().Resources[resourceName]
620-
if !ok {
621-
return fmt.Errorf("resource google_compute_subnetwork.subnetwork not found in state")
622-
}
623-
624-
if rs.Primary.ID == "" {
625-
return fmt.Errorf("resource ID is not set")
626-
}
627-
628-
// Ensure that the log_config exists in the API response.
629-
if subnetwork.LogConfig == nil {
630-
return fmt.Errorf("no log_config exists in subnetwork")
631-
}
632-
633-
stateAttrs := rs.Primary.Attributes
634-
635-
// Check aggregation_interval.
636-
aggInterval, ok := stateAttrs["log_config.0.aggregation_interval"]
637-
if !ok {
638-
return fmt.Errorf("aggregation_interval not found in state")
639-
}
640-
if subnetwork.LogConfig.AggregationInterval != aggInterval {
641-
return fmt.Errorf("aggregation_interval mismatch: expected %s, got %s", aggInterval, subnetwork.LogConfig.AggregationInterval)
642-
}
643-
644-
// Check flow_sampling.
645-
fsState, ok := stateAttrs["log_config.0.flow_sampling"]
646-
if !ok {
647-
return fmt.Errorf("flow_sampling not found in state")
648-
}
649-
actualFS := fmt.Sprintf("%g", subnetwork.LogConfig.FlowSampling)
650-
if actualFS != fsState {
651-
return fmt.Errorf("flow_sampling mismatch: expected %s, got %s", fsState, actualFS)
652-
}
653-
654-
// Check metadata.
655-
metadata, ok := stateAttrs["log_config.0.metadata"]
656-
if !ok {
657-
return fmt.Errorf("metadata not found in state")
658-
}
659-
if subnetwork.LogConfig.Metadata != metadata {
660-
return fmt.Errorf("metadata mismatch: expected %s, got %s", metadata, subnetwork.LogConfig.Metadata)
661-
}
662-
663-
// Optionally, check filter_expr if it exists.
664-
if subnetwork.LogConfig.FilterExpr != "" {
665-
filterExpr, ok := stateAttrs["log_config.0.filter_expr"]
666-
if !ok {
667-
return fmt.Errorf("filter_expr is set in API but not found in state")
668-
}
669-
if subnetwork.LogConfig.FilterExpr != filterExpr {
670-
return fmt.Errorf("filter_expr mismatch: expected %s, got %s", filterExpr, subnetwork.LogConfig.FilterExpr)
671-
}
672-
}
673-
674-
// Optionally, check metadata_fields if present.
675-
if len(subnetwork.LogConfig.MetadataFields) > 0 {
676-
if _, ok := stateAttrs["log_config.0.metadata_fields"]; !ok {
677-
return fmt.Errorf("metadata_fields are set in API but not found in state")
678-
}
679-
}
680-
681-
return nil
682-
}
683-
}
684-
685-
func testAccCheckComputeSubnetworkLogConfig(subnetwork *compute.Subnetwork, key, value string) resource.TestCheckFunc {
686-
return func(s *terraform.State) error {
687-
if subnetwork.LogConfig == nil {
688-
return fmt.Errorf("no log_config found")
689-
}
690-
691-
switch key {
692-
case "log_config.0.enable":
693-
if subnetwork.LogConfig.Enable != (value == "true") {
694-
return fmt.Errorf("expected %s to be '%s', got '%t'", key, value, subnetwork.LogConfig.Enable)
695-
}
696-
case "log_config.0.aggregation_interval":
697-
if subnetwork.LogConfig.AggregationInterval != value {
698-
return fmt.Errorf("expected %s to be '%s', got '%s'", key, value, subnetwork.LogConfig.AggregationInterval)
699-
}
700-
case "log_config.0.metadata":
701-
if subnetwork.LogConfig.Metadata != value {
702-
return fmt.Errorf("expected %s to be '%s', got '%s'", key, value, subnetwork.LogConfig.Metadata)
703-
}
704-
case "log_config.0.flow_sampling":
705-
flowSamplingStr := fmt.Sprintf("%g", subnetwork.LogConfig.FlowSampling)
706-
if flowSamplingStr != value {
707-
return fmt.Errorf("expected %s to be '%s', got '%s'", key, value, flowSamplingStr)
708-
}
709-
case "log_config.0.filterExpr":
710-
if subnetwork.LogConfig.FilterExpr != value {
711-
return fmt.Errorf("expected %s to be '%s', got '%s'", key, value, subnetwork.LogConfig.FilterExpr)
712-
}
713-
default:
714-
return fmt.Errorf("unknown log_config key: %s", key)
715-
}
716-
717-
return nil
718-
}
719-
}
720-
721556
func testAccComputeSubnetwork_basic(cnName, subnetwork1Name, subnetwork2Name, subnetwork3Name string) string {
722557
return fmt.Sprintf(`
723558
resource "google_compute_network" "custom-test" {
@@ -1195,42 +1030,3 @@ resource "google_compute_subnetwork" "subnetwork" {
11951030
}
11961031
`, cnName, subnetworkName)
11971032
}
1198-
1199-
func testAccComputeSubnetwork_enableFlowLogs(cnName, subnetworkName string, enableFlowLogs bool) string {
1200-
return fmt.Sprintf(`
1201-
resource "google_compute_network" "custom-test" {
1202-
name = "%s"
1203-
auto_create_subnetworks = false
1204-
}
1205-
1206-
resource "google_compute_subnetwork" "subnetwork" {
1207-
name = "%s"
1208-
ip_cidr_range = "10.0.0.0/16"
1209-
region = "us-central1"
1210-
network = google_compute_network.custom-test.self_link
1211-
enable_flow_logs = %t
1212-
}
1213-
`, cnName, subnetworkName, enableFlowLogs)
1214-
}
1215-
1216-
func testAccComputeSubnetwork_enableFlowLogs_with_logConfig(cnName, subnetworkName string, enableFlowLogs bool) string {
1217-
return fmt.Sprintf(`
1218-
resource "google_compute_network" "custom-test" {
1219-
name = "%s"
1220-
auto_create_subnetworks = false
1221-
}
1222-
1223-
resource "google_compute_subnetwork" "subnetwork" {
1224-
name = "%s"
1225-
ip_cidr_range = "10.0.0.0/16"
1226-
region = "us-central1"
1227-
network = google_compute_network.custom-test.self_link
1228-
enable_flow_logs = %t
1229-
1230-
log_config {
1231-
aggregation_interval = "INTERVAL_1_MIN"
1232-
metadata = "INCLUDE_ALL_METADATA"
1233-
}
1234-
}
1235-
`, cnName, subnetworkName, enableFlowLogs)
1236-
}

website/docs/r/compute_subnetwork.html.markdown

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,12 +457,14 @@ The following arguments are supported:
457457
via BGP even if their destinations match existing subnet ranges.
458458

459459
* `enable_flow_logs` -
460-
(Optional)
460+
(Optional, Deprecated)
461461
Whether to enable flow logging for this subnetwork. If this field is not explicitly set,
462462
it will not appear in get listings. If not set the default behavior is determined by the
463463
org policy, if there is no org policy specified, then it will default to disabled.
464464
This field isn't supported if the subnet purpose field is set to REGIONAL_MANAGED_PROXY.
465465

466+
~> **Warning:** This field is being removed in favor of log_config. If log_config is present, flow logs are enabled.
467+
466468
* `project` - (Optional) The ID of the project in which the resource belongs.
467469
If it is not provided, the provider project is used.
468470

0 commit comments

Comments
 (0)