-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Make DataStore Schema (prefix) Configurable #554
Merged
prometherion
merged 16 commits into
clastix:master
from
SimonKienzler:disc-548/configurable-schema
Oct 2, 2024
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
58810ad
feat: Add DataStoreSchema field to TCP spec
SimonKienzler 1ed6767
feat: Read DB_SCHEMA from TCP spec field
SimonKienzler 54b4e8c
feat: Default DataStoreSchema in webhook
SimonKienzler 6fa6862
fix: Catch unsetting the dataStore via CEL
SimonKienzler efdd951
fix: Apply all patches, not only the first
SimonKienzler dbe5fef
test: Add tests for defaulting webhook
SimonKienzler cf32e27
fix: typo
SimonKienzler 5f8dbda
fix: Linter issues
SimonKienzler 12779f7
fix: make apidoc
SimonKienzler d02c580
Update TCP CRD in charts folder
SimonKienzler edd6a3e
fix: Don't run E2E tests during `make test`
SimonKienzler 8a0d469
fix: Use proper `metav1` import name
SimonKienzler 007be8e
feat: Handle updates of TCPs without dataStoreSchema (+ tests)
SimonKienzler be15eb7
fix: Prioritize Status over Spec
SimonKienzler 912c0c0
Update goDoc on DataStore field
SimonKienzler bbadc70
make apidoc
SimonKienzler File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
internal/resources/datastore/datastore_storage_config_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// Copyright 2022 Clastix Labs | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package datastore_test | ||
|
||
import ( | ||
"context" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/client/fake" | ||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" | ||
|
||
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1" | ||
"github.com/clastix/kamaji/internal/resources" | ||
"github.com/clastix/kamaji/internal/resources/datastore" | ||
) | ||
|
||
var _ = Describe("DatastoreStorageConfig", func() { | ||
var ( | ||
ctx context.Context | ||
dsc *datastore.Config | ||
tcp *kamajiv1alpha1.TenantControlPlane | ||
ds *kamajiv1alpha1.DataStore | ||
) | ||
|
||
BeforeEach(func() { | ||
ctx = context.Background() | ||
|
||
tcp = &kamajiv1alpha1.TenantControlPlane{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "tcp", | ||
Namespace: "default", | ||
}, | ||
Spec: kamajiv1alpha1.TenantControlPlaneSpec{}, | ||
} | ||
|
||
ds = &kamajiv1alpha1.DataStore{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "datastore", | ||
Namespace: "default", | ||
}, | ||
} | ||
|
||
Expect(kamajiv1alpha1.AddToScheme(scheme)).To(Succeed()) | ||
Expect(corev1.AddToScheme(scheme)).To(Succeed()) | ||
}) | ||
|
||
JustBeforeEach(func() { | ||
fakeClient = fake.NewClientBuilder(). | ||
WithScheme(scheme).WithObjects(tcp).WithStatusSubresource(tcp).Build() | ||
|
||
dsc = &datastore.Config{ | ||
Client: fakeClient, | ||
ConnString: "", | ||
DataStore: *ds, | ||
} | ||
}) | ||
|
||
When("TCP has no dataStoreSchema defined", func() { | ||
It("should return an error", func() { | ||
_, err := resources.Handle(ctx, dsc, tcp) | ||
Expect(err).To(HaveOccurred()) | ||
}) | ||
}) | ||
|
||
When("TCP has dataStoreSchema set in spec", func() { | ||
BeforeEach(func() { | ||
tcp.Spec.DataStoreSchema = "custom-prefix" | ||
}) | ||
|
||
It("should create the datastore secret with the schema name from the spec", func() { | ||
op, err := resources.Handle(ctx, dsc, tcp) | ||
Expect(err).ToNot(HaveOccurred()) | ||
Expect(op).To(Equal(controllerutil.OperationResultCreated)) | ||
|
||
secrets := &corev1.SecretList{} | ||
Expect(fakeClient.List(ctx, secrets)).To(Succeed()) | ||
Expect(secrets.Items).To(HaveLen(1)) | ||
Expect(secrets.Items[0].Data["DB_SCHEMA"]).To(Equal([]byte("custom-prefix"))) | ||
}) | ||
}) | ||
|
||
When("TCP has dataStoreSchema set in status, but not in spec", func() { | ||
// this test case ensures that existing TCPs (created in a CRD version without | ||
// the dataStoreSchema field) correctly adopt the spec field from the status. | ||
|
||
It("should create the datastore secret with the correct schema name and update the TCP spec", func() { | ||
By("updating the TCP status") | ||
Expect(fakeClient.Get(ctx, client.ObjectKeyFromObject(tcp), tcp)).To(Succeed()) | ||
tcp.Status.Storage.Setup.Schema = "existing-schema-name" | ||
Expect(fakeClient.Status().Update(ctx, tcp)).To(Succeed()) | ||
|
||
By("handling the resource") | ||
op, err := resources.Handle(ctx, dsc, tcp) | ||
Expect(err).ToNot(HaveOccurred()) | ||
Expect(op).To(Equal(controllerutil.OperationResultCreated)) | ||
|
||
By("checking the secret") | ||
secrets := &corev1.SecretList{} | ||
Expect(fakeClient.List(ctx, secrets)).To(Succeed()) | ||
Expect(secrets.Items).To(HaveLen(1)) | ||
Expect(secrets.Items[0].Data["DB_SCHEMA"]).To(Equal([]byte("existing-schema-name"))) | ||
|
||
By("checking the TCP spec") | ||
// we have to check the modified struct here (instead of retrieving the object | ||
// via the fakeClient), as the TCP resource update is not done by the resources. | ||
// Instead, the TCP controller will handle TCP updates after handling all resources | ||
tcp.Spec.DataStoreSchema = "existing-schema-name" | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright 2022 Clastix Labs | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package datastore_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
) | ||
|
||
var ( | ||
fakeClient client.Client | ||
scheme *runtime.Scheme = runtime.NewScheme() | ||
) | ||
|
||
func TestDatastore(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Datastore Suite") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2022 Clastix Labs | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package handlers_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestHandlers(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Handlers Suite") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A CEL policy here would create a breaking change since it requires Kubernetes >= 1.25, and Kamaji has a loose requirement of +1.22 (https://kamaji.clastix.io/reference/versioning/)
@bsctl WDYT here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About version, frankly I don’t care. 1.22 is a very old release and we can move to 1.25 as baseline for support. If CEL usage provides benefits over webhook and if we want push in this direction for the future, I think it is a good idea, but I would avoid a mix and match of different techniques unless it provides clear benefits, just for sake of maintenance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my experience, it's convenient to handle as many validation/defaulting tasks as possible using the kubebuilder annotations, i.e. letting the K8s API Server handle that for you. Except for the things that need a more sophisticated logic, then resort to webhooks