@@ -493,6 +493,66 @@ func TestAccComputeSubnetwork_internal_ipv6(t *testing.T) {
493
493
})
494
494
}
495
495
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
+
496
556
func testAccCheckComputeSubnetworkExists (t * testing.T , n string , subnetwork * compute.Subnetwork ) resource.TestCheckFunc {
497
557
return func (s * terraform.State ) error {
498
558
rs , ok := s .RootModule ().Resources [n ]
@@ -553,6 +613,111 @@ func testAccCheckComputeSubnetworkHasNotSecondaryIpRange(subnetwork *compute.Sub
553
613
}
554
614
}
555
615
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
+
556
721
func testAccComputeSubnetwork_basic (cnName , subnetwork1Name , subnetwork2Name , subnetwork3Name string ) string {
557
722
return fmt .Sprintf (`
558
723
resource "google_compute_network" "custom-test" {
@@ -1030,3 +1195,42 @@ resource "google_compute_subnetwork" "subnetwork" {
1030
1195
}
1031
1196
` , cnName , subnetworkName )
1032
1197
}
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
+ }
0 commit comments