Skip to content

Commit 5f2a170

Browse files
authored
chore: separate actions from the controller service (#203)
the controller constructor takes dependencies which are only used to initialize the default actions even if those are not used anywhere else in the implementation. Extract the actions to simplify the controller constructor and inject them instead.
1 parent 854dc78 commit 5f2a170

File tree

4 files changed

+80
-44
lines changed

4 files changed

+80
-44
lines changed

cmd/controller/run.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
"github.com/castai/cluster-controller/cmd/utils"
2727
"github.com/castai/cluster-controller/health"
28+
"github.com/castai/cluster-controller/internal/actions"
2829
"github.com/castai/cluster-controller/internal/actions/csr"
2930
"github.com/castai/cluster-controller/internal/castai"
3031
"github.com/castai/cluster-controller/internal/config"
@@ -131,6 +132,15 @@ func runController(
131132

132133
log.Infof("running castai-cluster-controller version %v, log-level: %v", binVersion, logger.Level)
133134

135+
actionHandlers := actions.NewDefaultActionHandlers(
136+
k8sVer.Full(),
137+
cfg.SelfPod.Namespace,
138+
log,
139+
clientset,
140+
dynamicClient,
141+
helmClient,
142+
)
143+
134144
actionsConfig := controller.Config{
135145
PollWaitInterval: 5 * time.Second,
136146
PollTimeout: maxRequestTimeout,
@@ -148,11 +158,9 @@ func runController(
148158
log,
149159
actionsConfig,
150160
k8sVer.Full(),
151-
clientset,
152-
dynamicClient,
153161
client,
154-
helmClient,
155162
healthzAction,
163+
actionHandlers,
156164
)
157165
defer func() {
158166
if err := svc.Close(); err != nil {

internal/actions/actions.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package actions
2+
3+
import (
4+
"reflect"
5+
6+
"github.com/sirupsen/logrus"
7+
"k8s.io/client-go/dynamic"
8+
"k8s.io/client-go/kubernetes"
9+
10+
"github.com/castai/cluster-controller/internal/castai"
11+
"github.com/castai/cluster-controller/internal/helm"
12+
)
13+
14+
type ActionHandlers map[reflect.Type]ActionHandler
15+
16+
func NewDefaultActionHandlers(
17+
k8sVersion string,
18+
castNamespace string,
19+
log logrus.FieldLogger,
20+
clientset *kubernetes.Clientset,
21+
dynamicClient dynamic.Interface,
22+
helmClient helm.Client,
23+
) ActionHandlers {
24+
return ActionHandlers{
25+
reflect.TypeOf(&castai.ActionDeleteNode{}): NewDeleteNodeHandler(log, clientset),
26+
reflect.TypeOf(&castai.ActionDrainNode{}): NewDrainNodeHandler(log, clientset, castNamespace),
27+
reflect.TypeOf(&castai.ActionPatchNode{}): NewPatchNodeHandler(log, clientset),
28+
reflect.TypeOf(&castai.ActionCreateEvent{}): NewCreateEventHandler(log, clientset),
29+
reflect.TypeOf(&castai.ActionChartUpsert{}): NewChartUpsertHandler(log, helmClient),
30+
reflect.TypeOf(&castai.ActionChartUninstall{}): NewChartUninstallHandler(log, helmClient),
31+
reflect.TypeOf(&castai.ActionChartRollback{}): NewChartRollbackHandler(log, helmClient, k8sVersion),
32+
reflect.TypeOf(&castai.ActionDisconnectCluster{}): NewDisconnectClusterHandler(log, clientset),
33+
reflect.TypeOf(&castai.ActionCheckNodeDeleted{}): NewCheckNodeDeletedHandler(log, clientset),
34+
reflect.TypeOf(&castai.ActionCheckNodeStatus{}): NewCheckNodeStatusHandler(log, clientset),
35+
reflect.TypeOf(&castai.ActionEvictPod{}): NewEvictPodHandler(log, clientset),
36+
reflect.TypeOf(&castai.ActionPatch{}): NewPatchHandler(log, dynamicClient),
37+
reflect.TypeOf(&castai.ActionCreate{}): NewCreateHandler(log, dynamicClient),
38+
reflect.TypeOf(&castai.ActionDelete{}): NewDeleteHandler(log, dynamicClient),
39+
}
40+
}
41+
42+
func (h ActionHandlers) Close() error {
43+
return h[reflect.TypeOf(&castai.ActionCreateEvent{})].(*CreateEventHandler).Close()
44+
}

internal/controller/controller.go

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,10 @@ import (
1111
"time"
1212

1313
"github.com/sirupsen/logrus"
14-
"k8s.io/client-go/dynamic"
15-
"k8s.io/client-go/kubernetes"
1614

1715
"github.com/castai/cluster-controller/health"
1816
"github.com/castai/cluster-controller/internal/actions"
1917
"github.com/castai/cluster-controller/internal/castai"
20-
"github.com/castai/cluster-controller/internal/helm"
2118
"github.com/castai/cluster-controller/internal/metrics"
2219
"github.com/castai/cluster-controller/internal/waitext"
2320
)
@@ -38,35 +35,18 @@ func NewService(
3835
log logrus.FieldLogger,
3936
cfg Config,
4037
k8sVersion string,
41-
clientset *kubernetes.Clientset,
42-
dynamicClient dynamic.Interface,
4338
castaiClient castai.CastAIClient,
44-
helmClient helm.Client,
4539
healthCheck *health.HealthzProvider,
40+
actionHandlers actions.ActionHandlers,
4641
) *Controller {
4742
return &Controller{
4843
log: log,
4944
cfg: cfg,
5045
k8sVersion: k8sVersion,
5146
castAIClient: castaiClient,
5247
startedActions: map[string]struct{}{},
53-
actionHandlers: map[reflect.Type]actions.ActionHandler{
54-
reflect.TypeOf(&castai.ActionDeleteNode{}): actions.NewDeleteNodeHandler(log, clientset),
55-
reflect.TypeOf(&castai.ActionDrainNode{}): actions.NewDrainNodeHandler(log, clientset, cfg.Namespace),
56-
reflect.TypeOf(&castai.ActionPatchNode{}): actions.NewPatchNodeHandler(log, clientset),
57-
reflect.TypeOf(&castai.ActionCreateEvent{}): actions.NewCreateEventHandler(log, clientset),
58-
reflect.TypeOf(&castai.ActionChartUpsert{}): actions.NewChartUpsertHandler(log, helmClient),
59-
reflect.TypeOf(&castai.ActionChartUninstall{}): actions.NewChartUninstallHandler(log, helmClient),
60-
reflect.TypeOf(&castai.ActionChartRollback{}): actions.NewChartRollbackHandler(log, helmClient, cfg.Version),
61-
reflect.TypeOf(&castai.ActionDisconnectCluster{}): actions.NewDisconnectClusterHandler(log, clientset),
62-
reflect.TypeOf(&castai.ActionCheckNodeDeleted{}): actions.NewCheckNodeDeletedHandler(log, clientset),
63-
reflect.TypeOf(&castai.ActionCheckNodeStatus{}): actions.NewCheckNodeStatusHandler(log, clientset),
64-
reflect.TypeOf(&castai.ActionEvictPod{}): actions.NewEvictPodHandler(log, clientset),
65-
reflect.TypeOf(&castai.ActionPatch{}): actions.NewPatchHandler(log, dynamicClient),
66-
reflect.TypeOf(&castai.ActionCreate{}): actions.NewCreateHandler(log, dynamicClient),
67-
reflect.TypeOf(&castai.ActionDelete{}): actions.NewDeleteHandler(log, dynamicClient),
68-
},
69-
healthCheck: healthCheck,
48+
actionHandlers: actionHandlers,
49+
healthCheck: healthCheck,
7050
}
7151
}
7252

@@ -77,7 +57,7 @@ type Controller struct {
7757

7858
k8sVersion string
7959

80-
actionHandlers map[reflect.Type]actions.ActionHandler
60+
actionHandlers actions.ActionHandlers
8161

8262
startedActionsWg sync.WaitGroup
8363
startedActions map[string]struct{}
@@ -273,5 +253,5 @@ func getHandlerError(err error) *string {
273253
}
274254

275255
func (s *Controller) Close() error {
276-
return s.actionHandlers[reflect.TypeOf(&castai.ActionCreateEvent{})].(*actions.CreateEventHandler).Close()
256+
return s.actionHandlers.Close()
277257
}

internal/controller/controller_test.go

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package controller
33
import (
44
"context"
55
"fmt"
6+
"reflect"
67
"testing"
78
"time"
89

@@ -11,12 +12,12 @@ import (
1112
"github.com/sirupsen/logrus"
1213
"github.com/stretchr/testify/require"
1314
"go.uber.org/goleak"
14-
"k8s.io/client-go/kubernetes"
1515

1616
"github.com/castai/cluster-controller/health"
17+
"github.com/castai/cluster-controller/internal/actions"
1718
mock_actions "github.com/castai/cluster-controller/internal/actions/mock"
1819
"github.com/castai/cluster-controller/internal/castai"
19-
"github.com/castai/cluster-controller/internal/castai/mock"
20+
mock_castai "github.com/castai/cluster-controller/internal/castai/mock"
2021
)
2122

2223
// nolint: govet
@@ -99,9 +100,9 @@ func TestController_Run(t *testing.T) {
99100
},
100101
},
101102
}, nil).Times(1).MinTimes(1)
102-
m.EXPECT().AckAction(gomock.Any(), "a1", gomock.Any()).Return(nil).MinTimes(1)
103-
m.EXPECT().AckAction(gomock.Any(), "a2", gomock.Any()).Return(nil).MinTimes(1)
104-
m.EXPECT().AckAction(gomock.Any(), "a3", gomock.Any()).Return(nil).MinTimes(1)
103+
m.EXPECT().AckAction(gomock.Any(), "a1", &castai.AckClusterActionRequest{}).Return(nil).MinTimes(1)
104+
m.EXPECT().AckAction(gomock.Any(), "a2", &castai.AckClusterActionRequest{}).Return(nil).MinTimes(1)
105+
m.EXPECT().AckAction(gomock.Any(), "a3", &castai.AckClusterActionRequest{}).Return(nil).MinTimes(1)
105106
},
106107
},
107108
},
@@ -240,22 +241,25 @@ func TestController_Run(t *testing.T) {
240241
if tt.fields.tuneMockCastAIClient != nil {
241242
tt.fields.tuneMockCastAIClient(client)
242243
}
243-
s := NewService(
244-
logrus.New(),
245-
tt.fields.cfg,
246-
tt.fields.k8sVersion,
247-
kubernetes.New(nil),
248-
nil,
249-
client,
250-
nil,
251-
health.NewHealthzProvider(health.HealthzCfg{HealthyPollIntervalLimit: pollTimeout}, logrus.New()))
244+
252245
handler := mock_actions.NewMockActionHandler(m)
253246
if tt.fields.tuneMockHandler != nil {
254247
tt.fields.tuneMockHandler(handler)
255248
}
256-
for k := range s.actionHandlers {
257-
s.actionHandlers[k] = handler
249+
testActionHandlers := map[reflect.Type]actions.ActionHandler{
250+
reflect.TypeOf(&castai.ActionDeleteNode{}): handler,
251+
reflect.TypeOf(&castai.ActionDrainNode{}): handler,
252+
reflect.TypeOf(&castai.ActionPatchNode{}): handler,
258253
}
254+
255+
s := NewService(
256+
logrus.New(),
257+
tt.fields.cfg,
258+
tt.fields.k8sVersion,
259+
client,
260+
health.NewHealthzProvider(health.HealthzCfg{HealthyPollIntervalLimit: pollTimeout}, logrus.New()),
261+
testActionHandlers)
262+
259263
s.Run(tt.args.ctx())
260264
})
261265
}

0 commit comments

Comments
 (0)