Skip to content

Commit e7d44bb

Browse files
authored
feature-generation: add getDependencies for resolving groupRef and groupId (#2982)
* fix iterating over crds * use dependencies in flex cluster * remove references.go * fix unit test
1 parent 34cc6bd commit e7d44bb

File tree

5 files changed

+101
-111
lines changed

5 files changed

+101
-111
lines changed

internal/generated/controller/flexcluster/handler_v20250312.go

Lines changed: 78 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828

2929
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/controller/customresource"
3030
crapi "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/crapi"
31-
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/generated/references"
3231
akov2generated "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/nextapi/generated/v1"
3332
ctrlstate "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/state"
3433
result "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/result"
@@ -51,35 +50,48 @@ func NewHandlerv20250312(kubeClient client.Client, atlasClient *v20250312sdk.API
5150
}
5251
}
5352

54-
// TODO: Autogenerate with Scaffolder
55-
func (h *Handlerv20250312) getGroupId(ctx context.Context, flexcluster *akov2generated.FlexCluster) (string, error) {
56-
groupID := ""
53+
func (h *Handlerv20250312) getDependencies(ctx context.Context, flexcluster *akov2generated.FlexCluster) ([]client.Object, error) {
54+
var result []client.Object
55+
56+
if flexcluster.Spec.V20250312.GroupRef != nil {
57+
group := &akov2generated.Group{}
58+
59+
err := h.kubeClient.Get(ctx, client.ObjectKey{
60+
Name: flexcluster.Spec.V20250312.GroupRef.Name,
61+
Namespace: flexcluster.GetNamespace(),
62+
}, group)
5763

58-
if flexcluster.Spec.V20250312.GroupId != nil {
59-
groupID = *flexcluster.Spec.V20250312.GroupId
60-
} else {
61-
var err error
62-
groupID, err = references.GetGroupID(
63-
ctx, h.kubeClient, flexcluster.Spec.V20250312.GroupRef, flexcluster.GetNamespace())
6464
if err != nil {
65-
return "", err
65+
return nil, fmt.Errorf("failed to get group %w", err)
6666
}
67+
68+
result = append(result, group)
6769
}
6870

69-
return groupID, nil
71+
return result, nil
7072
}
7173

7274
// HandleInitial handles the initial state for version v20250312
7375
func (h *Handlerv20250312) HandleInitial(ctx context.Context, flexcluster *akov2generated.FlexCluster) (ctrlstate.Result, error) {
74-
groupID, err := h.getGroupId(ctx, flexcluster)
76+
deps, err := h.getDependencies(ctx, flexcluster)
7577
if err != nil {
76-
return result.Error(state.StateInitial, reconcile.TerminalError(err))
78+
return result.Error(state.StateInitial, fmt.Errorf("failed to get dependencies: %w", err))
7779
}
78-
flexClusterRequest := v20250312sdk.FlexClusterDescriptionCreate20241113{}
79-
if err := h.translator.ToAPI(&flexClusterRequest, flexcluster); err != nil {
80-
return result.Error(state.StateInitial, fmt.Errorf("failed to translate flex create request: %w", err))
80+
81+
body := &v20250312sdk.FlexClusterDescriptionCreate20241113{}
82+
params := &v20250312sdk.CreateFlexClusterApiParams{
83+
FlexClusterDescriptionCreate20241113: body,
8184
}
82-
atlasFlexCluster, _, err := h.atlasClient.FlexClustersApi.CreateFlexCluster(ctx, groupID, &flexClusterRequest).Execute()
85+
86+
if err := h.translator.ToAPI(params, flexcluster, deps...); err != nil {
87+
return result.Error(state.StateInitial, fmt.Errorf("failed to translate flex api params: %w", err))
88+
}
89+
90+
if err := h.translator.ToAPI(body, flexcluster, deps...); err != nil {
91+
return result.Error(state.StateInitial, fmt.Errorf("failed to translate flex create description: %w", err))
92+
}
93+
94+
atlasFlexCluster, _, err := h.atlasClient.FlexClustersApi.CreateFlexClusterWithParams(ctx, params).Execute()
8395
if err != nil {
8496
return result.Error(state.StateInitial, fmt.Errorf("failed to create flex cluster: %w", err))
8597
}
@@ -109,7 +121,7 @@ func (h *Handlerv20250312) HandleImportRequested(ctx context.Context, flexcluste
109121
flexClusterCopy := flexcluster.DeepCopy()
110122
flexClusterCopy.Spec.V20250312.Entry.Name = externalName
111123
flexClusterCopy.Spec.V20250312.GroupId = &externalGroupID
112-
_, err := h.getToPatchStatus(ctx, flexClusterCopy)
124+
_, err := h.patchStatus(ctx, flexClusterCopy)
113125
if err != nil {
114126
return result.Error(state.StateImportRequested, err)
115127
}
@@ -151,12 +163,17 @@ func (h *Handlerv20250312) HandleDeletionRequested(ctx context.Context, flexclus
151163
return result.NextState(state.StateDeleted, "Flex Cluster is unamanged.")
152164
}
153165

154-
groupID, err := h.getGroupId(ctx, flexcluster)
166+
deps, err := h.getDependencies(ctx, flexcluster)
155167
if err != nil {
156-
return result.Error(state.StateInitial, reconcile.TerminalError(err))
168+
return result.Error(state.StateDeletionRequested, fmt.Errorf("failed to get dependencies: %w", err))
169+
}
170+
171+
params := &v20250312sdk.DeleteFlexClusterApiParams{}
172+
if err := h.translator.ToAPI(params, flexcluster, deps...); err != nil {
173+
return result.Error(state.StateDeletionRequested, fmt.Errorf("failed to translate flex api params: %w", err))
157174
}
158-
_, err = h.atlasClient.FlexClustersApi.DeleteFlexCluster(
159-
ctx, groupID, flexcluster.Spec.V20250312.Entry.Name).Execute()
175+
176+
_, err = h.atlasClient.FlexClustersApi.DeleteFlexClusterWithParams(ctx, params).Execute()
160177

161178
switch {
162179
case v20250312sdk.IsErrorCode(err, "CLUSTER_NOT_FOUND"):
@@ -170,12 +187,17 @@ func (h *Handlerv20250312) HandleDeletionRequested(ctx context.Context, flexclus
170187

171188
// HandleDeleting handles the deleting state for version v20250312
172189
func (h *Handlerv20250312) HandleDeleting(ctx context.Context, flexcluster *akov2generated.FlexCluster) (ctrlstate.Result, error) {
173-
groupID, err := h.getGroupId(ctx, flexcluster)
190+
deps, err := h.getDependencies(ctx, flexcluster)
174191
if err != nil {
175-
return result.Error(state.StateInitial, reconcile.TerminalError(err))
192+
return result.Error(state.StateDeleting, fmt.Errorf("failed to get dependencies: %w", err))
176193
}
177-
_, _, err = h.atlasClient.FlexClustersApi.GetFlexCluster(
178-
ctx, groupID, flexcluster.Spec.V20250312.Entry.Name).Execute()
194+
195+
params := &v20250312sdk.GetFlexClusterApiParams{}
196+
if err := h.translator.ToAPI(params, flexcluster, deps...); err != nil {
197+
return result.Error(state.StateDeleting, fmt.Errorf("failed to translate flex api params: %w", err))
198+
}
199+
200+
_, _, err = h.atlasClient.FlexClustersApi.GetFlexClusterWithParams(ctx, params).Execute()
179201
switch {
180202
case v20250312sdk.IsErrorCode(err, "CLUSTER_NOT_FOUND"):
181203
return result.NextState(state.StateDeleted, "Deleted")
@@ -197,7 +219,7 @@ func (h *Handlerv20250312) SetupWithManager(mgr controllerruntime.Manager, rec r
197219

198220
// HandleUpserting handles the creating and updating state for flex version v20250312
199221
func (h *Handlerv20250312) handleUpserting(ctx context.Context, flexcluster *akov2generated.FlexCluster, currentState, finalState state.ResourceState) (ctrlstate.Result, error) {
200-
atlasFlexCluster, err := h.getToPatchStatus(ctx, flexcluster)
222+
atlasFlexCluster, err := h.patchStatus(ctx, flexcluster)
201223
if err != nil {
202224
return result.Error(currentState, err)
203225
}
@@ -218,16 +240,27 @@ func (h *Handlerv20250312) handleIdle(ctx context.Context, flexcluster *akov2gen
218240
return result.NextState(currentState, "Flex cluster up to date. No update required.")
219241
}
220242

221-
groupID, err := h.getGroupId(ctx, flexcluster)
243+
deps, err := h.getDependencies(ctx, flexcluster)
222244
if err != nil {
223-
return result.Error(state.StateInitial, reconcile.TerminalError(err))
245+
return result.Error(currentState, fmt.Errorf("failed to get dependencies: %w", err))
246+
}
247+
248+
body := &v20250312sdk.FlexClusterDescriptionUpdate20241113{}
249+
params := &v20250312sdk.UpdateFlexClusterApiParams{
250+
FlexClusterDescriptionUpdate20241113: body,
251+
}
252+
253+
// translate parameters
254+
if err := h.translator.ToAPI(params, flexcluster, deps...); err != nil {
255+
return result.Error(currentState, fmt.Errorf("failed to translate update flex cluster parameters: %w", err))
224256
}
225-
flexClusterUpdate := v20250312sdk.FlexClusterDescriptionUpdate20241113{}
226-
if err := h.translator.ToAPI(&flexClusterUpdate, flexcluster); err != nil {
227-
return result.Error(state.StateInitial, fmt.Errorf("failed to translate update flex cluster request: %w", err))
257+
258+
// translate body
259+
if err := h.translator.ToAPI(body, flexcluster, deps...); err != nil {
260+
return result.Error(currentState, fmt.Errorf("failed to translate update flex cluster description: %w", err))
228261
}
229-
atlasFlexCluster, _, err := h.atlasClient.FlexClustersApi.UpdateFlexCluster(
230-
ctx, groupID, flexcluster.Spec.V20250312.Entry.Name, &flexClusterUpdate).Execute()
262+
263+
atlasFlexCluster, _, err := h.atlasClient.FlexClustersApi.UpdateFlexClusterWithParams(ctx, params).Execute()
231264
if err != nil {
232265
return result.Error(currentState, fmt.Errorf("failed to get update cluster: %w", err))
233266
}
@@ -243,18 +276,23 @@ func (h *Handlerv20250312) handleIdle(ctx context.Context, flexcluster *akov2gen
243276
return result.NextState(finalState, "Updating Flex Cluster.")
244277
}
245278

246-
func (h *Handlerv20250312) getToPatchStatus(ctx context.Context, flexcluster *akov2generated.FlexCluster) (*v20250312sdk.FlexClusterDescription20241113, error) {
247-
groupID, err := h.getGroupId(ctx, flexcluster)
279+
func (h *Handlerv20250312) patchStatus(ctx context.Context, flexcluster *akov2generated.FlexCluster) (*v20250312sdk.FlexClusterDescription20241113, error) {
280+
deps, err := h.getDependencies(ctx, flexcluster)
248281
if err != nil {
249282
return nil, err
250283
}
251-
atlasFlexCluster, _, err := h.atlasClient.FlexClustersApi.GetFlexCluster(
252-
ctx, groupID, flexcluster.Spec.V20250312.Entry.Name).Execute()
284+
params := &v20250312sdk.GetFlexClusterApiParams{}
285+
if err := h.translator.ToAPI(params, flexcluster, deps...); err != nil {
286+
return nil, fmt.Errorf("failed to translate update flex cluster parameters: %w", err)
287+
}
288+
289+
atlasFlexCluster, _, err := h.atlasClient.FlexClustersApi.GetFlexClusterWithParams(ctx, params).Execute()
253290
if err != nil {
254291
return nil, fmt.Errorf("failed to get cluster: %w", err)
255292
}
293+
256294
flexclusterCopy := flexcluster.DeepCopy()
257-
if _, err := h.translator.FromAPI(flexclusterCopy, atlasFlexCluster); err != nil {
295+
if _, err := h.translator.FromAPI(flexclusterCopy, atlasFlexCluster, deps...); err != nil {
258296
return nil, fmt.Errorf("failed to translate get cluster response: %w", err)
259297
}
260298

internal/generated/crds/crds.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,16 @@ var crdsYAML []byte
2828

2929
// EmbeddedCRD tried to load the given kind from a set of embedded CRDs
3030
func EmbeddedCRD(kind string) (*apiextensionsv1.CustomResourceDefinition, error) {
31-
for {
32-
crd, err := ParseCRD(bufio.NewScanner(bytes.NewBuffer(crdsYAML)))
33-
if err != nil {
34-
return nil, fmt.Errorf("failed to parse CRDs YAML for %q: %w", kind, err)
35-
}
31+
crds, err := ParseCRDs(bufio.NewScanner(bytes.NewBuffer(crdsYAML)))
32+
if err != nil {
33+
return nil, fmt.Errorf("failed to parse CRDs YAML for %q: %w", kind, err)
34+
}
35+
36+
for _, crd := range crds {
3637
if crd.Spec.Names.Kind == kind {
3738
return crd, nil
3839
}
3940
}
41+
42+
return nil, fmt.Errorf("failed to find CRD %q", kind)
4043
}

internal/generated/crds/parse.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"bytes"
2020
"errors"
2121
"fmt"
22-
"io"
2322
"strings"
2423

2524
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
@@ -35,11 +34,14 @@ var (
3534
ErrNoCRD = errors.New("not a CRD")
3635
)
3736

38-
// ParseCRD scans a YAML stream and returns the next CRD found.
37+
// ParseCRDs scans a YAML stream and returns the next CRD found.
3938
// If more than one CRD is present in the stream, calling again
4039
// on the same stream will return the next CRD found.
41-
func ParseCRD(scanner *bufio.Scanner) (*apiextensionsv1.CustomResourceDefinition, error) {
42-
var buffer bytes.Buffer
40+
func ParseCRDs(scanner *bufio.Scanner) ([]*apiextensionsv1.CustomResourceDefinition, error) {
41+
var (
42+
buffer bytes.Buffer
43+
result []*apiextensionsv1.CustomResourceDefinition
44+
)
4345

4446
for scanner.Scan() {
4547
line := scanner.Text()
@@ -54,7 +56,7 @@ func ParseCRD(scanner *bufio.Scanner) (*apiextensionsv1.CustomResourceDefinition
5456
if err != nil {
5557
return nil, err
5658
}
57-
return crd, nil
59+
result = append(result, crd)
5860
}
5961
continue
6062
}
@@ -73,10 +75,10 @@ func ParseCRD(scanner *bufio.Scanner) (*apiextensionsv1.CustomResourceDefinition
7375
if err != nil && !errors.Is(err, ErrNoCRD) {
7476
return nil, err
7577
}
76-
return crd, nil
78+
result = append(result, crd)
7779
}
7880

79-
return nil, io.EOF
81+
return result, nil
8082
}
8183

8284
func DecodeCRD(content []byte) (*apiextensionsv1.CustomResourceDefinition, error) {

internal/generated/crds/parse_test.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,31 @@ import (
2828
func TestParseCRD(t *testing.T) {
2929
tests := map[string]struct {
3030
scanner *bufio.Scanner
31-
expectedCrd *apiextensionsv1.CustomResourceDefinition
31+
expectedCrd []*apiextensionsv1.CustomResourceDefinition
3232
expectedErr string
3333
}{
3434
"valid CRD": {
3535
scanner: bufio.NewScanner(strings.NewReader(validCRDManifest(t))),
36-
expectedCrd: validCRDObject(t),
36+
expectedCrd: []*apiextensionsv1.CustomResourceDefinition{validCRDObject(t)},
3737
},
3838
"not a CRD": {
3939
scanner: bufio.NewScanner(strings.NewReader("apiVersion: autoscaling/__internal\nkind: Scale\nmetadata:\n name: test-scale\n")),
4040
expectedErr: "failed to decode YAML: no kind \"Scale\" is registered for the internal version of group \"autoscaling\" in scheme \"pkg/runtime/scheme.go:110\"",
4141
},
4242
"empty input": {
43-
scanner: bufio.NewScanner(strings.NewReader("")),
44-
expectedErr: "EOF",
43+
scanner: bufio.NewScanner(strings.NewReader("")),
4544
},
4645
"only comments": {
47-
scanner: bufio.NewScanner(strings.NewReader("# This is a comment\n# Another comment line\n")),
48-
expectedErr: "EOF",
46+
scanner: bufio.NewScanner(strings.NewReader("# This is a comment\n# Another comment line\n")),
4947
},
5048
"multiple CRDs, returns first": {
5149
scanner: bufio.NewScanner(strings.NewReader(validCRDManifest(t) + "---\n" + validCRDManifest(t))),
52-
expectedCrd: validCRDObject(t),
50+
expectedCrd: []*apiextensionsv1.CustomResourceDefinition{validCRDObject(t), validCRDObject(t)},
5351
},
5452
}
5553
for name, tt := range tests {
5654
t.Run(name, func(t *testing.T) {
57-
got, err := ParseCRD(tt.scanner)
55+
got, err := ParseCRDs(tt.scanner)
5856
gotErr := ""
5957
if err != nil {
6058
gotErr = err.Error()

internal/generated/references/references.go

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)