-
Notifications
You must be signed in to change notification settings - Fork 584
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3632 from richardcase/1718_gc_new_service_1-5
[release-1.5] feat: external load balancer garbage collection (part 2) - new gc service
- Loading branch information
Showing
23 changed files
with
37,141 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
Copyright 2022 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package v1beta1 | ||
|
||
const ( | ||
// FargateProfileFinalizer allows the controller to clean up resources on delete. | ||
FargateProfileFinalizer = "awsfargateprofile.infrastructure.cluster.x-k8s.io" | ||
|
||
// MachinePoolFinalizer is the finalizer for the machine pool. | ||
MachinePoolFinalizer = "awsmachinepool.infrastructure.cluster.x-k8s.io" | ||
|
||
// ManagedMachinePoolFinalizer allows the controller to clean up resources on delete. | ||
ManagedMachinePoolFinalizer = "awsmanagedmachinepools.infrastructure.cluster.x-k8s.io" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
Copyright 2022 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package annotations | ||
|
||
import ( | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
// Set will set the value of an annotation on the supplied object. If there is no annotation it will be created. | ||
func Set(obj metav1.Object, name, value string) { | ||
annotations := obj.GetAnnotations() | ||
if annotations == nil { | ||
annotations = map[string]string{} | ||
} | ||
annotations[name] = value | ||
obj.SetAnnotations(annotations) | ||
} | ||
|
||
// Get will get the value of the supplied annotation. | ||
func Get(obj metav1.Object, name string) (value string, found bool) { | ||
annotations := obj.GetAnnotations() | ||
if len(annotations) == 0 { | ||
return "", false | ||
} | ||
|
||
value, found = annotations[name] | ||
|
||
return | ||
} | ||
|
||
// Has returns true if the supplied object has the supplied annotation. | ||
func Has(obj metav1.Object, name string) bool { | ||
annotations := obj.GetAnnotations() | ||
if len(annotations) == 0 { | ||
return false | ||
} | ||
|
||
_, found := annotations[name] | ||
|
||
return found | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
Copyright 2022 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package gc | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/arn" | ||
rgapi "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi" | ||
|
||
infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1" | ||
expinfrav1 "sigs.k8s.io/cluster-api-provider-aws/exp/api/v1beta1" | ||
"sigs.k8s.io/cluster-api-provider-aws/pkg/annotations" | ||
) | ||
|
||
const ( | ||
serviceNameTag = "kubernetes.io/service-name" | ||
eksClusterNameTag = "aws:eks:cluster-name" | ||
) | ||
|
||
// ReconcileDelete is responsible for determining if the infra cluster needs to be garbage collected. If | ||
// does then it will perform garbage collection. For example, it will delete the ELB/NLBs that where created | ||
// as a result of Services of type load balancer. | ||
func (s *Service) ReconcileDelete(ctx context.Context) error { | ||
s.scope.Info("reconciling deletion for garbage collection") | ||
|
||
val, found := annotations.Get(s.scope.InfraCluster(), expinfrav1.ExternalResourceGCAnnotation) | ||
if !found { | ||
val = "true" | ||
} | ||
|
||
shouldGC, err := strconv.ParseBool(val) | ||
if err != nil { | ||
return fmt.Errorf("converting value %s of annotation %s to bool: %w", val, expinfrav1.ExternalResourceGCAnnotation, err) | ||
} | ||
|
||
if !shouldGC { | ||
s.scope.Info("cluster opted-out of garbage collection") | ||
|
||
return nil | ||
} | ||
|
||
return s.deleteResources(ctx) | ||
} | ||
|
||
func (s *Service) deleteResources(ctx context.Context) error { | ||
s.scope.Info("deleting aws resources created by tenant cluster") | ||
|
||
serviceTag := infrav1.ClusterAWSCloudProviderTagKey(s.scope.KubernetesClusterName()) | ||
awsInput := rgapi.GetResourcesInput{ | ||
ResourceTypeFilters: nil, | ||
TagFilters: []*rgapi.TagFilter{ | ||
{ | ||
Key: aws.String(serviceTag), | ||
Values: []*string{aws.String(string(infrav1.ResourceLifecycleOwned))}, | ||
}, | ||
}, | ||
} | ||
|
||
awsOutput, err := s.resourceTaggingClient.GetResourcesWithContext(ctx, &awsInput) | ||
if err != nil { | ||
return fmt.Errorf("getting tagged resources: %w", err) | ||
} | ||
|
||
resources := []*AWSResource{} | ||
|
||
for i := range awsOutput.ResourceTagMappingList { | ||
mapping := awsOutput.ResourceTagMappingList[i] | ||
parsedArn, err := arn.Parse(*mapping.ResourceARN) | ||
if err != nil { | ||
return fmt.Errorf("parsing resource arn %s: %w", *mapping.ResourceARN, err) | ||
} | ||
|
||
tags := map[string]string{} | ||
for _, rgTag := range mapping.Tags { | ||
tags[*rgTag.Key] = *rgTag.Value | ||
} | ||
|
||
resources = append(resources, &AWSResource{ | ||
ARN: &parsedArn, | ||
Tags: tags, | ||
}) | ||
} | ||
|
||
if deleteErr := s.cleanupFuncs.Execute(ctx, resources); deleteErr != nil { | ||
return fmt.Errorf("deleting resources: %w", deleteErr) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (s *Service) isMatchingResource(resource *AWSResource, serviceName, resourceName string) bool { | ||
if resource.ARN.Service != serviceName { | ||
s.scope.V(5).Info("Resource not for service", "arn", resource.ARN.String(), "service_name", serviceName, "resource_name", resourceName) | ||
return false | ||
} | ||
if !strings.HasPrefix(resource.ARN.Resource, resourceName+"/") { | ||
s.scope.V(5).Info("Resource type does not match", "arn", resource.ARN.String(), "service_name", serviceName, "resource_name", resourceName) | ||
return false | ||
} | ||
|
||
return true | ||
} |
Oops, something went wrong.