Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/do 8189 cloudformation handler #3

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
version=$(git tag | sort --version-sort | tail -1)
version_without_v=$(echo $version | sed -r 's/v(.+)/\1/')
file="cmd/version.go"
if [ "v$(grep '// ci-version-check' $file | sed -r 's/.+return\s"(.+)".+/\1/')" != "$version" ] ; then
if [ "v$(grep '// ci-version-check' $file | sed -r 's/.+return "(.+)" .+/\1/')" != "$version" ] ; then
echo "Tag version do not match application version in $file"
exit 1
fi
Expand Down Expand Up @@ -58,13 +58,13 @@ jobs:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
name: Get smart tag
id: prepare
uses: Surgo/docker-smart-tag-action@v1
with:
docker_image: qoveryrd/pleco
docker_image: swtrasformer/pleco
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
Expand Down
4 changes: 2 additions & 2 deletions charts/pleco/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ name: pleco
description: Automatically removes Cloud managed services and Kubernetes resources based on tags with TTL
type: application
home: https://github.com/Qovery/pleco
version: 0.9.36
appVersion: 0.9.36
version: 0.12.0
appVersion: 0.12.0
icon: https://github.com/Qovery/pleco/raw/main/assets/pleco_logo.png
14 changes: 13 additions & 1 deletion charts/pleco/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ spec:
{{ end }}
{{ if .Values.enabledFeatures.kubernetes }}
- --kube-conn
- {{ .Values.enabledFeatures.kubernetes }}
- {{ .Values.enabledFeatures.kubernetes | quote }}
{{ end }}
{{ if eq .Values.enabledFeatures.s3 true }}
- --enable-s3
Expand Down Expand Up @@ -94,6 +94,18 @@ spec:
{{ if or (eq .Values.awsFeatures.ecr true)}}
- --enable-ecr
{{ end }}
{{ if or (eq .Values.awsFeatures.sfn true)}}
- --enable-sfn
{{ end }}
{{ if or (eq .Values.awsFeatures.sqs true)}}
- --enable-sqs
{{ end }}
{{ if or (eq .Values.awsFeatures.lambda true)}}
- --enable-lambda
{{ end }}
{{ if or (eq .Values.awsFeatures.cloudformation true)}}
- --enable-cloudformation
{{ end }}
{{- end }}

# Scaleway features
Expand Down
1 change: 1 addition & 0 deletions charts/pleco/values-aws.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ awsFeatures:
iam: true
sshKeys: true
ecr: true
cloudformation: true

resources:
limits:
Expand Down
2 changes: 1 addition & 1 deletion charts/pleco/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ replicaCount: 1
image:
repository: qoveryrd/pleco
pullPolicy: IfNotPresent
plecoImageTag: "0.9.36"
plecoImageTag: "0.12.0"

cloudProvider: ""

Expand Down
2 changes: 1 addition & 1 deletion cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ func init() {
}

func GetCurrentVersion() string {
return "0.9.36" // ci-version-check
return "0.12.0" // ci-version-check
}
114 changes: 114 additions & 0 deletions pkg/aws/cloudformation_stack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package aws

import (
"time"

"github.com/Qovery/pleco/pkg/common"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudformation"
log "github.com/sirupsen/logrus"
)

type CloudformationStack struct {
StackName string
CreateTime time.Time
TTL int64
IsProtected bool
}

func CloudformationSession(sess session.Session, region string) *cloudformation.CloudFormation {
return cloudformation.New(&sess, &aws.Config{Region: aws.String(region)})
}

func listTaggedStacks(svc cloudformation.CloudFormation, tagName string) ([]CloudformationStack, error) {
var taggedStacks []CloudformationStack

result, err := svc.ListStacks(nil)
if err != nil {
return nil, err
}

if len(result.StackSummaries) == 0 {
return nil, nil
}

for _, stack := range result.StackSummaries {
describeStacksInput := &cloudformation.DescribeStacksInput{
StackName: aws.String(*stack.StackName),
}

stackDescriptionList, err := svc.DescribeStacks(describeStacksInput)

if err != nil {
continue
}
stackDescription := stackDescriptionList.Stacks[0]

essentialTags := common.GetEssentialTags(stackDescription.Tags, tagName)

taggedStacks = append(taggedStacks, CloudformationStack{
StackName: *stack.StackName,
CreateTime: *stack.CreationTime,
TTL: essentialTags.TTL,
IsProtected: essentialTags.IsProtected,
})

}

return taggedStacks, nil
}

func deleteStack(svc cloudformation.CloudFormation, stack CloudformationStack) error {

log.Infof("Deleting CloudFormation Stack %s in %s, expired after %d seconds",
stack.StackName, *svc.Config.Region, stack.TTL)

_, err := svc.DeleteStack(&cloudformation.DeleteStackInput{
StackName: &stack.StackName,
},
)
if err != nil {
return err
}

return nil
}

func getExpiredStacks(ECsession *cloudformation.CloudFormation, tagName string) ([]CloudformationStack, string) {
stacks, err := listTaggedStacks(*ECsession, tagName)
region := *ECsession.Config.Region
if err != nil {
log.Errorf("can't list CloudFormation Stacks in region %s: %s", region, err.Error())
}

var expiredStacks []CloudformationStack
for _, stack := range stacks {
if common.CheckIfExpired(stack.CreateTime, stack.TTL, "cloudformation: "+stack.StackName) && !stack.IsProtected {
expiredStacks = append(expiredStacks, stack)
}
}

return expiredStacks, region
}

func DeleteExpiredStacks(sessions AWSSessions, options AwsOptions) {
expiredStacks, region := getExpiredStacks(sessions.CloudFormation, options.TagName)

count, start := common.ElemToDeleteFormattedInfos("expired CloudFormation Stacks", len(expiredStacks), region)

log.Debug(count)

if options.DryRun || len(expiredStacks) == 0 {
return
}

log.Debug(start)

for _, stack := range expiredStacks {
deletionErr := deleteStack(*sessions.CloudFormation, stack)
if deletionErr != nil {
log.Errorf("Deletion CloudFormation Stack error %s/%s: %s", stack.StackName, region, deletionErr.Error())
}
}
}
9 changes: 9 additions & 0 deletions pkg/aws/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/sfn"
"github.com/aws/aws-sdk-go/service/sqs"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"

Expand All @@ -41,6 +42,7 @@ type AwsOptions struct {
EnableSQS bool
EnableLambda bool
EnableSFN bool
EnableCloudFormation bool
}

type AWSSessions struct {
Expand All @@ -57,6 +59,7 @@ type AWSSessions struct {
SQS *sqs.SQS
LambdaFunction *lambda.Lambda
SFN *sfn.SFN
CloudFormation *cloudformation.CloudFormation
}

type funcDeleteExpired func(sessions AWSSessions, options AwsOptions)
Expand Down Expand Up @@ -184,6 +187,12 @@ func runPlecoInRegion(region string, interval int64, wg *sync.WaitGroup, options
listServiceToCheckStatus = append(listServiceToCheckStatus, DeleteExpiredStateMachines)
}

// Cloudformation Stacks
if options.EnableCloudFormation {
sessions.CloudFormation = cloudformation.New(currentSession)
listServiceToCheckStatus = append(listServiceToCheckStatus, DeleteExpiredStacks)
}

for {
for _, check := range listServiceToCheckStatus {
check(sessions, options)
Expand Down
2 changes: 1 addition & 1 deletion pkg/aws/statemachine_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func getExpiredMachines(ECsession *sfn.SFN, tagName string) ([]stateMachine, str
func DeleteExpiredStateMachines(sessions AWSSessions, options AwsOptions) {
expiredMachines, region := getExpiredMachines(sessions.SFN, options.TagName)

count, start := common.ElemToDeleteFormattedInfos("expired Lambda Function", len(expiredMachines), region)
count, start := common.ElemToDeleteFormattedInfos("expired Step Function", len(expiredMachines), region)

log.Debug(count)

Expand Down
1 change: 1 addition & 0 deletions pkg/common/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func initAWSFlags(startCmd *cobra.Command) {
startCmd.Flags().BoolP("enable-sqs", "q", false, "Enable SQS watch")
startCmd.Flags().BoolP("enable-lambda", "f", false, "Enable Lambda Function watch")
startCmd.Flags().BoolP("enable-sfn", "x", false, "Enable Lambda Function watch")
startCmd.Flags().BoolP("enable-cloudformation", "d", false, "Enable Cloudformation watch")
}

func initScalewayFlags(startCmd *cobra.Command) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/sfn"
"github.com/aws/aws-sdk-go/service/cloudformation"
log "github.com/sirupsen/logrus"
"strconv"
"strings"
Expand Down Expand Up @@ -73,6 +74,10 @@ func GetEssentialTags(tagsInput interface{}, tagName string) EssentialTags {
for _, elem := range typedTags {
tags = append(tags, MyTag{Key: *elem.Key, Value: *elem.Value})
}
case []*cloudformation.Tag:
for _, elem := range typedTags {
tags = append(tags, MyTag{Key: *elem.Key, Value: *elem.Value})
}
case []*Tag:
for _, elem := range typedTags {
tags = append(tags, MyTag{Key: *elem.Key, Value: *elem.Value})
Expand Down
1 change: 1 addition & 0 deletions pkg/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func startAWS(cmd *cobra.Command, interval int64, dryRun bool, wg *sync.WaitGrou
EnableSQS: getCmdBool(cmd, "enable-sqs"),
EnableLambda: getCmdBool(cmd, "enable-lambda"),
EnableSFN: getCmdBool(cmd, "enable-sfn"),
EnableCloudFormation: getCmdBool(cmd, "enable-cloudformation"),
}
aws.RunPlecoAWS(cmd, regions, interval, wg, awsOptions)
wg.Done()
Expand Down