/
delete.go
144 lines (128 loc) · 4.32 KB
/
delete.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package nodegroup
import (
"context"
"fmt"
"github.com/kris-nova/logger"
api "github.com/weaveworks/eksctl/pkg/apis/eksctl.io/v1alpha5"
"github.com/weaveworks/eksctl/pkg/cfn/manager"
"github.com/weaveworks/eksctl/pkg/ctl/cmdutils"
"github.com/weaveworks/eksctl/pkg/utils/tasks"
)
// StackHelper is a helper for managing nodegroup stacks.
//
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
//counterfeiter:generate -o fakes/fake_stack_helper.go . StackHelper
type StackHelper interface {
NewTasksToDeleteNodeGroups(stacks []manager.NodeGroupStack, shouldDelete func(_ string) bool, wait bool, cleanup func(chan error, string) error) (*tasks.TaskTree, error)
ListNodeGroupStacksWithStatuses(ctx context.Context) ([]manager.NodeGroupStack, error)
NewTaskToDeleteUnownedNodeGroup(ctx context.Context, clusterName, nodegroup string, nodeGroupDeleter manager.NodeGroupDeleter, waitCondition *manager.DeleteWaitCondition) tasks.Task
}
// AuthConfigMapUpdater updates the aws-auth ConfigMap.
//
//counterfeiter:generate -o fakes/fake_auth_configmap_updater.go . AuthConfigMapUpdater
type AuthConfigMapUpdater interface {
// RemoveNodeGroup removes the specified nodegroup.
RemoveNodeGroup(*api.NodeGroup) error
}
// A Deleter deletes nodegroups.
type Deleter struct {
StackHelper StackHelper
NodeGroupDeleter manager.NodeGroupDeleter
ClusterName string
AuthConfigMapUpdater AuthConfigMapUpdater
}
// DeleteOptions represents the options for deleting nodegroups.
type DeleteOptions struct {
Wait bool
Plan bool
UpdateAuthConfigMap bool
}
// Delete deletes the specified nodegroups.
func (d *Deleter) Delete(ctx context.Context, nodeGroups []*api.NodeGroup, managedNodeGroups []*api.ManagedNodeGroup, options DeleteOptions) error {
nodeGroupsWithStacks := map[string]struct{}{}
for _, n := range nodeGroups {
nodeGroupsWithStacks[n.NameString()] = struct{}{}
}
stacks, err := d.StackHelper.ListNodeGroupStacksWithStatuses(ctx)
if err != nil {
return err
}
taskTree := &tasks.TaskTree{
Parallel: true,
PlanMode: options.Plan,
}
for _, n := range managedNodeGroups {
if findStack(stacks, n.Name) != nil {
nodeGroupsWithStacks[n.NameString()] = struct{}{}
} else {
taskTree.Append(d.StackHelper.NewTaskToDeleteUnownedNodeGroup(ctx, d.ClusterName, n.Name, d.NodeGroupDeleter, nil))
}
}
var deleteTasks tasks.Task
if len(stacks) > 0 {
shouldDelete := func(ngName string) bool {
_, ok := nodeGroupsWithStacks[ngName]
return ok
}
deleteTasks, err = d.StackHelper.NewTasksToDeleteNodeGroups(stacks, shouldDelete, options.Wait, nil)
if err != nil {
return err
}
}
if authTask := d.updateAuthConfigMapTask(nodeGroups, stacks, options); authTask != nil {
if deleteTasks != nil {
var subTasks tasks.TaskTree
subTasks.Append(
deleteTasks,
authTask,
)
deleteTasks = &subTasks
} else {
deleteTasks = authTask
}
}
if deleteTasks != nil {
taskTree.Append(deleteTasks)
}
logger.Info(taskTree.Describe())
if errs := taskTree.DoAllSync(); len(errs) > 0 {
return handleErrors(errs, "nodegroup(s)")
}
return nil
}
func (d *Deleter) updateAuthConfigMapTask(nodeGroups []*api.NodeGroup, stacks []manager.NodeGroupStack, options DeleteOptions) tasks.Task {
if !options.UpdateAuthConfigMap {
return nil
}
var nodeGroupsWithoutAccessEntry []*api.NodeGroup
for _, ng := range nodeGroups {
if stack := findStack(stacks, ng.NameString()); stack == nil || !stack.UsesAccessEntry {
nodeGroupsWithoutAccessEntry = append(nodeGroupsWithoutAccessEntry, ng)
}
}
if len(nodeGroupsWithoutAccessEntry) == 0 {
return nil
}
return &tasks.GenericTask{
Description: "update auth ConfigMap",
Doer: func() error {
cmdutils.LogIntendedAction(options.Plan, "delete %d nodegroups from auth ConfigMap in cluster %q", len(nodeGroupsWithoutAccessEntry), d.ClusterName)
if options.Plan {
return nil
}
for _, ng := range nodeGroupsWithoutAccessEntry {
if err := d.AuthConfigMapUpdater.RemoveNodeGroup(ng); err != nil {
logger.Warning(err.Error())
}
}
return nil
},
}
}
func handleErrors(errs []error, subject string) error {
logger.Info("%d error(s) occurred while deleting %s", len(errs), subject)
for _, err := range errs {
logger.Critical("%s\n", err.Error())
}
return fmt.Errorf("failed to delete %s", subject)
}