Skip to content

Commit

Permalink
feat(operation): check all stacks for TerminationProtection before st…
Browse files Browse the repository at this point in the history
…arting deletion when multiple stacks (#345)

* change test orders

* TerminationProtectionIsEnabled in GetSortedStackNames

* add tests for some errors

* change err msgs

* change TerminationProtectionIsEnabled error name

* TerminationProtectionError
  • Loading branch information
go-to-k authored Mar 27, 2024
1 parent 51d6bb4 commit 2a4a5ef
Show file tree
Hide file tree
Showing 2 changed files with 384 additions and 24 deletions.
21 changes: 17 additions & 4 deletions internal/operation/cloudformation_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ func (o *CloudFormationStackOperator) deleteStackNormally(ctx context.Context, s
return false, err
}
if len(stacksBeforeDelete) == 0 && isRootStack {
errMsg := fmt.Sprintf("%s stack not found.", *stackName)
errMsg := fmt.Sprintf("%s not found", *stackName)
return false, fmt.Errorf("NotExistsError: %v", errMsg)
}
if len(stacksBeforeDelete) == 0 {
return true, nil
}

if stacksBeforeDelete[0].EnableTerminationProtection != nil && *stacksBeforeDelete[0].EnableTerminationProtection {
return false, fmt.Errorf("TerminationProtectionIsEnabled: %v", *stackName)
return false, fmt.Errorf("TerminationProtectionError: %v", *stackName)
}
if o.isExceptedByStackStatus(stacksBeforeDelete[0].StackStatus) {
return false, fmt.Errorf("OperationInProgressError: Stacks with XxxInProgress cannot be deleted, but %v: %v", stacksBeforeDelete[0].StackStatus, *stackName)
Expand Down Expand Up @@ -160,6 +160,7 @@ func (o *CloudFormationStackOperator) GetSortedStackNames(ctx context.Context, s
sortedStackNames := []string{}
gotStacks := []types.Stack{}
notFoundStackNames := []string{}
terminationProtectionStackNames := []string{}

type stackNameInProgress struct {
stackName string
Expand All @@ -177,20 +178,32 @@ func (o *CloudFormationStackOperator) GetSortedStackNames(ctx context.Context, s
notFoundStackNames = append(notFoundStackNames, stackName)
continue
}

// except the stacks with EnableTerminationProtection
if stack[0].EnableTerminationProtection != nil && *stack[0].EnableTerminationProtection {
terminationProtectionStackNames = append(terminationProtectionStackNames, stackName)
continue
}

// except the stacks that are in the exception list
if o.isExceptedByStackStatus(stack[0].StackStatus) {
stackNamesInProgress = append(stackNamesInProgress, stackNameInProgress{
stackName: stackName,
stackStatus: stack[0].StackStatus,
})
continue
}

gotStacks = append(gotStacks, stack[0]) // DescribeStacks returns a stack with a single element
}

if len(notFoundStackNames) > 0 {
errMsg := fmt.Sprintf("%s stack not found.", strings.Join(notFoundStackNames, ", "))
errMsg := fmt.Sprintf("%s not found", strings.Join(notFoundStackNames, ", "))
return sortedStackNames, fmt.Errorf("NotExistsError: %v", errMsg)
}
if len(terminationProtectionStackNames) > 0 {
return sortedStackNames, fmt.Errorf("TerminationProtectionError: %v", strings.Join(terminationProtectionStackNames, ", "))
}
if len(stackNamesInProgress) > 0 {
var stackNamesWithStatus []string
for _, stack := range stackNamesInProgress {
Expand Down Expand Up @@ -245,7 +258,7 @@ func (o *CloudFormationStackOperator) ListStacksFilteredByKeyword(ctx context.Co
}

if len(filteredStacks) == 0 {
errMsg := fmt.Sprintf("No stacks matching the keyword (%s).", *keyword)
errMsg := fmt.Sprintf("No stacks matching the keyword (%s)", *keyword)
return filteredStacks, fmt.Errorf("NotExistsError: %v", errMsg)
}

Expand Down
Loading

0 comments on commit 2a4a5ef

Please sign in to comment.