Skip to content

Commit 2f94bf7

Browse files
authored
CLOUDP-361448: Manage serverless as flex cluster (#2926)
* Manage serverless instance through flex api * update next release version * add CEL ratcheting rule for serverless spec * bump controller-tools on devbox * update api docs * add migration serverless to flex unit-test
1 parent 233ab75 commit 2f94bf7

18 files changed

+302
-3048
lines changed

api/v1/atlasdeployment_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const (
4343
// Only one of DeploymentSpec, AdvancedDeploymentSpec and ServerlessSpec should be defined.
4444
// +kubebuilder:validation:XValidation:rule="(has(self.externalProjectRef) && !has(self.projectRef)) || (!has(self.externalProjectRef) && has(self.projectRef))",message="must define only one project reference through externalProjectRef or projectRef"
4545
// +kubebuilder:validation:XValidation:rule="(has(self.externalProjectRef) && has(self.connectionSecret)) || !has(self.externalProjectRef)",message="must define a local connection secret when referencing an external project"
46+
// +kubebuilder:validation:XValidation:rule="!has(self.serverlessSpec) || (oldSelf.hasValue() && oldSelf.value().serverlessSpec != null)",optionalOldSelf=true,message="serverlessSpec cannot be added - serverless instances are deprecated",fieldPath=.serverlessSpec
4647
type AtlasDeploymentSpec struct {
4748
// ProjectReference is the dual external or kubernetes reference with access credentials
4849
ProjectDualReference `json:",inline"`

api/v1/atlasdeployment_types_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,74 @@ func TestDeploymentCELChecks(t *testing.T) {
4949
},
5050
expectedErrors: []string{"spec.deploymentSpec.name: Invalid value: \"string\": Name cannot be modified after deployment creation"},
5151
},
52+
{
53+
title: "Cannot add a serverless deployment",
54+
old: nil,
55+
obj: &AtlasDeployment{
56+
Spec: AtlasDeploymentSpec{
57+
ServerlessSpec: &ServerlessSpec{
58+
Name: "my-serverless",
59+
},
60+
},
61+
},
62+
expectedErrors: []string{"spec.serverlessSpec: Invalid value: \"object\": serverlessSpec cannot be added - serverless instances are deprecated"},
63+
},
64+
{
65+
title: "Can modify to a serverless deployment",
66+
old: &AtlasDeployment{
67+
Spec: AtlasDeploymentSpec{
68+
ServerlessSpec: &ServerlessSpec{
69+
Name: "my-serverless",
70+
TerminationProtectionEnabled: false,
71+
},
72+
},
73+
},
74+
obj: &AtlasDeployment{
75+
Spec: AtlasDeploymentSpec{
76+
ServerlessSpec: &ServerlessSpec{
77+
Name: "my-serverless",
78+
TerminationProtectionEnabled: true,
79+
},
80+
},
81+
},
82+
},
83+
{
84+
title: "Existing serverless deployment can continue existing when not modified",
85+
old: &AtlasDeployment{
86+
Spec: AtlasDeploymentSpec{
87+
ServerlessSpec: &ServerlessSpec{
88+
Name: "my-serverless",
89+
TerminationProtectionEnabled: false,
90+
},
91+
},
92+
},
93+
obj: &AtlasDeployment{
94+
Spec: AtlasDeploymentSpec{
95+
BackupScheduleRef: common.ResourceRefNamespaced{},
96+
ServerlessSpec: &ServerlessSpec{
97+
Name: "my-serverless",
98+
TerminationProtectionEnabled: false,
99+
},
100+
},
101+
},
102+
},
103+
{
104+
title: "can migrate from serverless to flex cluster",
105+
old: &AtlasDeployment{
106+
Spec: AtlasDeploymentSpec{
107+
ServerlessSpec: &ServerlessSpec{
108+
Name: "my-serverless",
109+
},
110+
},
111+
},
112+
obj: &AtlasDeployment{
113+
Spec: AtlasDeploymentSpec{
114+
FlexSpec: &FlexSpec{
115+
Name: "my-serverless",
116+
},
117+
},
118+
},
119+
},
52120
} {
53121
t.Run(tc.title, func(t *testing.T) {
54122
// inject a project to avoid other CEL validations being hit

devbox.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"operator-sdk": "1.36.1",
2020
"shellcheck": "latest",
2121
"golangci-lint": "2",
22-
"kubernetes-controller-tools": "0.17.2",
22+
"kubernetes-controller-tools": "0.19.0",
2323
"setup-envtest": "0.19.0",
2424
"awscli2": "latest",
2525
"docker-sbom": "latest",

devbox.lock

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,51 +1189,51 @@
11891189
}
11901190
}
11911191
},
1192-
"kubernetes-controller-tools@0.17.2": {
1193-
"last_modified": "2025-03-23T05:31:05Z",
1194-
"resolved": "github:NixOS/nixpkgs/dd613136ee91f67e5dba3f3f41ac99ae89c5406b#kubernetes-controller-tools",
1192+
"kubernetes-controller-tools@0.19.0": {
1193+
"last_modified": "2025-11-23T21:50:36Z",
1194+
"resolved": "github:NixOS/nixpkgs/ee09932cedcef15aaf476f9343d1dea2cb77e261#kubernetes-controller-tools",
11951195
"source": "devbox-search",
1196-
"version": "0.17.2",
1196+
"version": "0.19.0",
11971197
"systems": {
11981198
"aarch64-darwin": {
11991199
"outputs": [
12001200
{
12011201
"name": "out",
1202-
"path": "/nix/store/x2g121jdk7fdxb7vx964rrhbiwd0g0rm-controller-tools-0.17.2",
1202+
"path": "/nix/store/brz84pzrcnll7i85bpgil58ldlkwrngp-controller-tools-0.19.0",
12031203
"default": true
12041204
}
12051205
],
1206-
"store_path": "/nix/store/x2g121jdk7fdxb7vx964rrhbiwd0g0rm-controller-tools-0.17.2"
1206+
"store_path": "/nix/store/brz84pzrcnll7i85bpgil58ldlkwrngp-controller-tools-0.19.0"
12071207
},
12081208
"aarch64-linux": {
12091209
"outputs": [
12101210
{
12111211
"name": "out",
1212-
"path": "/nix/store/jaz48mw3pinfdw9gd8fng63gn7wwzmxy-controller-tools-0.17.2",
1212+
"path": "/nix/store/anb3mpv9m3dklylhqbsjh04iv70gn8vj-controller-tools-0.19.0",
12131213
"default": true
12141214
}
12151215
],
1216-
"store_path": "/nix/store/jaz48mw3pinfdw9gd8fng63gn7wwzmxy-controller-tools-0.17.2"
1216+
"store_path": "/nix/store/anb3mpv9m3dklylhqbsjh04iv70gn8vj-controller-tools-0.19.0"
12171217
},
12181218
"x86_64-darwin": {
12191219
"outputs": [
12201220
{
12211221
"name": "out",
1222-
"path": "/nix/store/3wdf34xlpff7m01ggzr7pb9f3w3cl95f-controller-tools-0.17.2",
1222+
"path": "/nix/store/jjm90vri9j4j2zacasrfkhny98vsh10n-controller-tools-0.19.0",
12231223
"default": true
12241224
}
12251225
],
1226-
"store_path": "/nix/store/3wdf34xlpff7m01ggzr7pb9f3w3cl95f-controller-tools-0.17.2"
1226+
"store_path": "/nix/store/jjm90vri9j4j2zacasrfkhny98vsh10n-controller-tools-0.19.0"
12271227
},
12281228
"x86_64-linux": {
12291229
"outputs": [
12301230
{
12311231
"name": "out",
1232-
"path": "/nix/store/xgppkdij5f73igwfp5as058fmh21wn9p-controller-tools-0.17.2",
1232+
"path": "/nix/store/mldi6bp7a0bdq5vjyfahay8h19f0wwch-controller-tools-0.19.0",
12331233
"default": true
12341234
}
12351235
],
1236-
"store_path": "/nix/store/xgppkdij5f73igwfp5as058fmh21wn9p-controller-tools-0.17.2"
1236+
"store_path": "/nix/store/mldi6bp7a0bdq5vjyfahay8h19f0wwch-controller-tools-0.19.0"
12371237
}
12381238
}
12391239
},

docs/api-docs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2755,7 +2755,7 @@ AtlasDeployment is the Schema for the atlasdeployments API
27552755
AtlasDeploymentSpec defines the desired state of AtlasDeployment.
27562756
Only one of DeploymentSpec, AdvancedDeploymentSpec and ServerlessSpec should be defined.<br/>
27572757
<br/>
2758-
<i>Validations</i>:<li>(has(self.externalProjectRef) && !has(self.projectRef)) || (!has(self.externalProjectRef) && has(self.projectRef)): must define only one project reference through externalProjectRef or projectRef</li><li>(has(self.externalProjectRef) && has(self.connectionSecret)) || !has(self.externalProjectRef): must define a local connection secret when referencing an external project</li>
2758+
<i>Validations</i>:<li>(has(self.externalProjectRef) && !has(self.projectRef)) || (!has(self.externalProjectRef) && has(self.projectRef)): must define only one project reference through externalProjectRef or projectRef</li><li>(has(self.externalProjectRef) && has(self.connectionSecret)) || !has(self.externalProjectRef): must define a local connection secret when referencing an external project</li><li>!has(self.serverlessSpec) || (oldSelf.hasValue() && oldSelf.value().serverlessSpec != null): serverlessSpec cannot be added - serverless instances are deprecated</li>
27592759
</td>
27602760
<td>false</td>
27612761
</tr><tr>

internal/controller/atlasdatabaseuser/databaseuser.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func (r *AtlasDatabaseUserReconciler) handleDatabaseUser(ctx *workflow.Context,
6666
return r.terminate(ctx, atlasDatabaseUser, api.DatabaseUserReadyType, workflow.AtlasAPIAccessNotConfigured, true, err)
6767
}
6868
dbUserService := dbuser.NewAtlasUsers(sdkClientSet.SdkClient20250312006.DatabaseUsersApi)
69-
deploymentService := deployment.NewAtlasDeployments(sdkClientSet.SdkClient20250312006.ClustersApi, sdkClientSet.SdkClient20250312006.ServerlessInstancesApi, sdkClientSet.SdkClient20250312006.GlobalClustersApi, sdkClientSet.SdkClient20250312006.FlexClustersApi, r.AtlasProvider.IsCloudGov())
69+
deploymentService := deployment.NewAtlasDeployments(sdkClientSet.SdkClient20250312006.ClustersApi, sdkClientSet.SdkClient20250312006.GlobalClustersApi, sdkClientSet.SdkClient20250312006.FlexClustersApi, r.AtlasProvider.IsCloudGov())
7070
atlasProject, err := r.ResolveProject(ctx.Context, sdkClientSet.SdkClient20250312006, atlasDatabaseUser)
7171
if err != nil {
7272
return r.terminate(ctx, atlasDatabaseUser, api.DatabaseUserReadyType, workflow.AtlasAPIAccessNotConfigured, true, err)

internal/controller/atlasdeployment/atlasdeployment_controller.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func (r *AtlasDeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Requ
141141
}
142142
workflowCtx.SdkClientSet = sdkClientSet
143143
projectService := project.NewProjectAPIService(sdkClientSet.SdkClient20250312006.ProjectsApi)
144-
deploymentService := deployment.NewAtlasDeployments(sdkClientSet.SdkClient20250312006.ClustersApi, sdkClientSet.SdkClient20250312006.ServerlessInstancesApi, sdkClientSet.SdkClient20250312006.GlobalClustersApi, sdkClientSet.SdkClient20250312006.FlexClustersApi, r.AtlasProvider.IsCloudGov())
144+
deploymentService := deployment.NewAtlasDeployments(sdkClientSet.SdkClient20250312006.ClustersApi, sdkClientSet.SdkClient20250312006.GlobalClustersApi, sdkClientSet.SdkClient20250312006.FlexClustersApi, r.AtlasProvider.IsCloudGov())
145145
atlasProject, err := r.ResolveProject(workflowCtx.Context, sdkClientSet.SdkClient20250312006, atlasDeployment)
146146
if err != nil {
147147
return r.terminate(workflowCtx, workflow.AtlasAPIAccessNotConfigured, err)
@@ -176,10 +176,7 @@ func (r *AtlasDeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Requ
176176
}
177177

178178
switch {
179-
case atlasDeployment.IsServerless():
180-
return r.handleServerlessInstance(workflowCtx, projectService, deploymentService, deploymentInAKO, deploymentInAtlas)
181-
182-
case atlasDeployment.IsFlex():
179+
case atlasDeployment.IsServerless(), atlasDeployment.IsFlex():
183180
return r.handleFlexInstance(workflowCtx, projectService, deploymentService, deploymentInAKO, deploymentInAtlas)
184181

185182
case atlasDeployment.IsAdvancedDeployment():

0 commit comments

Comments
 (0)