1
1
/*
2
- Copyright 2019 Google LLC
2
+ Copyright 2019-2024 Google LLC
3
3
4
4
Licensed under the Apache License, Version 2.0 (the "License");
5
5
you may not use this file except in compliance with the License.
@@ -29,6 +29,8 @@ import (
29
29
30
30
asset "cloud.google.com/go/asset/apiv1"
31
31
"cloud.google.com/go/asset/apiv1/assetpb"
32
+ container "cloud.google.com/go/container/apiv1"
33
+ "cloud.google.com/go/container/apiv1/containerpb"
32
34
securitycenter "cloud.google.com/go/securitycenter/apiv1"
33
35
"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
34
36
"golang.org/x/net/context"
@@ -240,7 +242,7 @@ func getRegexListFromEnv(envVariableName string) []*regexp.Regexp {
240
242
logger .Printf ("Got Regex list [%s] from [%s] env variable" , regexList , envVariableName )
241
243
}
242
244
243
- //build Regexes
245
+ // build Regexes
244
246
for _ , r := range regexList {
245
247
result , err := regexp .Compile (r )
246
248
if err != nil {
@@ -381,7 +383,7 @@ func getBillingAccountSinkServiceOrTerminateExecution(ctx context.Context, clien
381
383
return loggingService .BillingAccounts .Sinks
382
384
}
383
385
384
- func getSCCNotificationServiceOrTerminateExecution (ctx context.Context , client * http. Client ) * securitycenter.Client {
386
+ func getSCCNotificationServiceOrTerminateExecution (ctx context.Context ) * securitycenter.Client {
385
387
logger .Println ("Try to get SCC Notification Service" )
386
388
securitycenterClient , err := securitycenter .NewClient (ctx )
387
389
if err != nil {
@@ -391,7 +393,7 @@ func getSCCNotificationServiceOrTerminateExecution(ctx context.Context, client *
391
393
return securitycenterClient
392
394
}
393
395
394
- func getAssetServiceOrTerminateExecution (ctx context.Context , client * http. Client ) * asset.Client {
396
+ func getAssetServiceOrTerminateExecution (ctx context.Context ) * asset.Client {
395
397
logger .Println ("Try to get Asset Service" )
396
398
assetService , err := asset .NewClient (ctx )
397
399
if err != nil {
@@ -401,6 +403,16 @@ func getAssetServiceOrTerminateExecution(ctx context.Context, client *http.Clien
401
403
return assetService
402
404
}
403
405
406
+ func getContainerServiceOrTerminateExecution (ctx context.Context ) * container.ClusterManagerClient {
407
+ logger .Println ("Try to get Container Service" )
408
+ containerService , err := container .NewClusterManagerClient (ctx )
409
+ if err != nil {
410
+ logger .Fatalf ("Failed to get Container Service with error [%s], terminate execution" , err .Error ())
411
+ }
412
+ logger .Println ("Got Container Service" )
413
+ return containerService
414
+ }
415
+
404
416
func getFirewallPoliciesServiceOrTerminateExecution (ctx context.Context , client * http.Client ) * compute.FirewallPoliciesService {
405
417
logger .Println ("Try to get Firewall Policies Service" )
406
418
computeService , err := compute .NewService (ctx , option .WithHTTPClient (client ))
@@ -426,12 +438,13 @@ func invoke(ctx context.Context) {
426
438
cloudResourceManagerService := getResourceManagerServiceOrTerminateExecution (ctx , client )
427
439
folderService := getFolderServiceOrTerminateExecution (ctx , client )
428
440
tagKeyService := getTagKeysServiceOrTerminateExecution (ctx , client )
429
- sccService := getSCCNotificationServiceOrTerminateExecution (ctx , client )
441
+ sccService := getSCCNotificationServiceOrTerminateExecution (ctx )
430
442
tagValuesService := getTagValuesServiceOrTerminateExecution (ctx , client )
431
- feedsService := getAssetServiceOrTerminateExecution (ctx , client )
443
+ feedsService := getAssetServiceOrTerminateExecution (ctx )
432
444
billingSinkService := getBillingAccountSinkServiceOrTerminateExecution (ctx , client )
433
445
firewallPoliciesService := getFirewallPoliciesServiceOrTerminateExecution (ctx , client )
434
446
endpointService := getServiceManagementServiceOrTerminateExecution (ctx , client )
447
+ containerService := getContainerServiceOrTerminateExecution (ctx )
435
448
436
449
removeLien := func (name string ) {
437
450
logger .Printf ("Try to remove lien [%s]" , name )
@@ -576,7 +589,7 @@ func invoke(ctx context.Context) {
576
589
return
577
590
}
578
591
for _ , sink := range sinkList .Sinks {
579
- if sink .Name != "_Required" && sink .Name != "_Default" && billingSinkAgeFilter (sink ) && checkIfNameIncluded (sink .ResourceName , targetBillingSinks ) {
592
+ if sink .Name != "_Required" && sink .Name != "_Default" && billingSinkAgeFilter (sink ) && checkIfNameIncluded (sink .ResourceName , targetBillingSinks ) {
580
593
_ , err = billingSinkService .Delete (sink .ResourceName ).Context (ctx ).Do ()
581
594
if err != nil {
582
595
logger .Printf ("Failed to delete billing account log sink [%s] from billing account [%s], error [%s]" , sink .ResourceName , billing , err .Error ())
@@ -611,6 +624,48 @@ func invoke(ctx context.Context) {
611
624
return err
612
625
}
613
626
627
+ removeProjectClusters := func (projectId string ) int {
628
+ logger .Printf ("Try to remove clusters for [%s]" , projectId )
629
+ reqLCR := & containerpb.ListClustersRequest {Parent : fmt .Sprintf ("projects/%s/locations/*" , projectId )}
630
+ listResponse , err := containerService .ListClusters (ctx , reqLCR )
631
+ if err != nil {
632
+ logger .Printf ("Failed to list clusters for [%s], error [%s]" , projectId , err .Error ())
633
+ return 0
634
+ }
635
+
636
+ logger .Printf ("Got [%d] clusters for project [%s]" , len (listResponse .Clusters ), projectId )
637
+ if len (listResponse .Clusters ) == 0 {
638
+ return 0
639
+ }
640
+
641
+ var pendingDeletion int = 0
642
+ for _ , cluster := range listResponse .Clusters {
643
+ switch clusterStatus := cluster .Status .String (); clusterStatus {
644
+ case "DEGRADED" :
645
+ fallthrough
646
+ case "RUNNING" :
647
+ logger .Printf ("Deleting cluster %s status: %s" , cluster .Name , clusterStatus )
648
+ reqDCR := & containerpb.DeleteClusterRequest {Name : fmt .Sprintf ("projects/%s/locations/%s/clusters/%s" , projectId , cluster .Location , cluster .Name )}
649
+ _ , err := containerService .DeleteCluster (ctx , reqDCR )
650
+ if err != nil {
651
+ logger .Printf ("Failed to delete cluster [%s] for [%s], error [%s]" , cluster .Name , projectId , err .Error ())
652
+ } else {
653
+ pendingDeletion ++
654
+ }
655
+ case "PROVISIONING" :
656
+ fallthrough
657
+ case "RECONCILING" :
658
+ fallthrough
659
+ case "STOPPING" :
660
+ logger .Printf ("Deferring cluster %s status: %s" , cluster .Name , clusterStatus )
661
+ pendingDeletion ++
662
+ default :
663
+ logger .Printf ("Ignoring cluster %s status: %s" , cluster .Name , clusterStatus )
664
+ }
665
+ }
666
+ return pendingDeletion
667
+ }
668
+
614
669
removeProjectEndpoints := func (projectId string ) {
615
670
logger .Printf ("Try to remove endpoints for [%s]" , projectId )
616
671
listResponse , err := endpointService .Services .List ().ProducerProjectId (projectId ).Do ()
@@ -638,6 +693,9 @@ func invoke(ctx context.Context) {
638
693
639
694
cleanupProjectById := func (projectId string ) {
640
695
logger .Printf ("Try to remove project [%s]" , projectId )
696
+ if clusters := removeProjectClusters (projectId ); clusters != 0 {
697
+ logger .Printf ("Defer removing project [%s], %d clusters marked for deletion" , projectId , clusters )
698
+ }
641
699
err := removeProjectById (projectId )
642
700
if err != nil {
643
701
removeProjectEndpoints (projectId )
@@ -738,7 +796,7 @@ func invoke(ctx context.Context) {
738
796
removeSCCNotifications (organizationId )
739
797
}
740
798
741
- //Only delete Feeds from deleted projects
799
+ // Only delete Feeds from deleted projects
742
800
if cleanUpCaiFeeds {
743
801
removeFeedsByName (organizationId )
744
802
}
0 commit comments