Skip to content

Commit 9c1a418

Browse files
authored
fix: Handle multiple meta mutators cleanly (#159)
1 parent 88f59a9 commit 9c1a418

File tree

18 files changed

+766
-643
lines changed

18 files changed

+766
-643
lines changed

.golangci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,7 @@ issues:
8585
- path: "api/*"
8686
linters:
8787
- gochecknoinits
88+
# Idiomatic to use init functions to register APIs with scheme
89+
- text: "hugeParam: holderRef is heavy"
90+
linters:
91+
- gocritic

cmd/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func main() {
136136
}
137137
// This metaPatchHandlers combines all other patch and variable handlers under a single handler.
138138
// It allows to specify configuration under a single variable.
139-
metaPatchHandlers := []mutation.GeneratePatches{
139+
metaPatchHandlers := []mutation.MetaMutater{
140140
httpproxy.NewMetaPatch(mgr.GetClient()),
141141
extraapiservercertsans.NewMetaPatch(),
142142
auditpolicy.NewPatch(),
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2023 D2iQ, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package handlers
5+
6+
import (
7+
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
8+
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
9+
"sigs.k8s.io/controller-runtime/pkg/client"
10+
)
11+
12+
func ClusterKeyFromReq(req *runtimehooksv1.GeneratePatchesRequest) client.ObjectKey {
13+
for i := range req.Items {
14+
item := req.Items[i]
15+
if item.HolderReference.Kind == "Cluster" &&
16+
item.HolderReference.APIVersion == capiv1.GroupVersion.String() {
17+
return client.ObjectKey{
18+
Namespace: item.HolderReference.Namespace,
19+
Name: item.HolderReference.Name,
20+
}
21+
}
22+
}
23+
24+
return client.ObjectKey{}
25+
}

common/pkg/capi/clustertopology/handlers/mutation/meta.go

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,46 @@ package mutation
55

66
import (
77
"context"
8-
"strings"
98

9+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
10+
"k8s.io/apimachinery/pkg/runtime"
11+
"k8s.io/apimachinery/pkg/runtime/serializer"
12+
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
13+
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
1014
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
15+
"sigs.k8s.io/cluster-api/exp/runtime/topologymutation"
16+
"sigs.k8s.io/controller-runtime/pkg/client"
1117

1218
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/handlers"
1319
)
1420

21+
type MetaMutater interface {
22+
Mutate(
23+
ctx context.Context,
24+
obj runtime.Object,
25+
vars map[string]apiextensionsv1.JSON,
26+
holderRef runtimehooksv1.HolderReference,
27+
clusterKey client.ObjectKey,
28+
) error
29+
}
30+
1531
type metaGeneratePatches struct {
16-
name string
17-
wrappedHandlers []GeneratePatches
32+
name string
33+
decoder runtime.Decoder
34+
mutaters []MetaMutater
1835
}
1936

20-
func NewMetaGeneratePatchesHandler(name string, gp ...GeneratePatches) handlers.Named {
37+
func NewMetaGeneratePatchesHandler(name string, m ...MetaMutater) handlers.Named {
38+
scheme := runtime.NewScheme()
39+
_ = bootstrapv1.AddToScheme(scheme)
40+
_ = controlplanev1.AddToScheme(scheme)
2141
return metaGeneratePatches{
22-
name: name,
23-
wrappedHandlers: gp,
42+
name: name,
43+
decoder: serializer.NewCodecFactory(scheme).UniversalDecoder(
44+
controlplanev1.GroupVersion,
45+
bootstrapv1.GroupVersion,
46+
),
47+
mutaters: m,
2448
}
2549
}
2650

@@ -33,20 +57,26 @@ func (mgp metaGeneratePatches) GeneratePatches(
3357
req *runtimehooksv1.GeneratePatchesRequest,
3458
resp *runtimehooksv1.GeneratePatchesResponse,
3559
) {
36-
for _, h := range mgp.wrappedHandlers {
37-
wrappedResp := &runtimehooksv1.GeneratePatchesResponse{}
38-
h.GeneratePatches(ctx, req, wrappedResp)
39-
resp.Items = append(resp.Items, wrappedResp.Items...)
40-
if wrappedResp.Message != "" {
41-
resp.Message = strings.TrimPrefix(resp.Message+"\n"+wrappedResp.Message, "\n")
42-
}
43-
resp.Status = wrappedResp.Status
44-
if resp.Status == runtimehooksv1.ResponseStatusFailure {
45-
return
46-
}
47-
}
60+
clusterKey := handlers.ClusterKeyFromReq(req)
4861

49-
if resp.Status == "" {
50-
resp.Status = runtimehooksv1.ResponseStatusSuccess
51-
}
62+
topologymutation.WalkTemplates(
63+
ctx,
64+
mgp.decoder,
65+
req,
66+
resp,
67+
func(
68+
ctx context.Context,
69+
obj runtime.Object,
70+
vars map[string]apiextensionsv1.JSON,
71+
holderRef runtimehooksv1.HolderReference,
72+
) error {
73+
for _, h := range mgp.mutaters {
74+
if err := h.Mutate(ctx, obj, vars, holderRef, clusterKey); err != nil {
75+
return err
76+
}
77+
}
78+
79+
return nil
80+
},
81+
)
5282
}

0 commit comments

Comments
 (0)