Skip to content
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

Change/local only medusaconfig #1267

Merged
merged 54 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
ced9dd2
Changelog.
Miles-Garnsey Mar 27, 2024
eff7500
Fix changelog.
Miles-Garnsey Apr 3, 2024
16cabda
Micke's requested changes inc. unit test, changelog and conditional p…
Miles-Garnsey Apr 3, 2024
29ef9f3
Add deprecation warning for MedusaConfig non-local ns.
Miles-Garnsey Apr 3, 2024
a2ace04
Add webhook failure on resource creation for MedusaConfig non-local ns.
Miles-Garnsey Apr 3, 2024
98c3711
Unit test for this functionality.
Miles-Garnsey Apr 3, 2024
6689fd4
Release notes, changelog.
Miles-Garnsey Apr 3, 2024
8763987
Scaffold out the planned changes and ensure deprecation comments are …
Miles-Garnsey Apr 3, 2024
47564ea
Juggle some ordering, move a constant.
Miles-Garnsey Apr 5, 2024
ed3b70a
Switch out the current medusa bucket secret copying logic for a Repli…
Miles-Garnsey Apr 5, 2024
5d79ee3
Ensure labels are added to the ReplicatedSecret.
Miles-Garnsey Apr 5, 2024
20e2949
Fix linter complaining at me.
Miles-Garnsey Apr 5, 2024
0e88389
Fix failing envtests.
Miles-Garnsey Apr 5, 2024
dd5e24c
Put an eventually in place since this update is failing on some optim…
Miles-Garnsey Apr 5, 2024
f3eb52a
Fix webhook test.
Miles-Garnsey Apr 5, 2024
20b784e
Update changelog for correct version.
Miles-Garnsey Apr 8, 2024
90c4ce1
Fix multi-dc-cluster-scoped e2e test.
Miles-Garnsey Apr 8, 2024
3ca2fa9
Fix another e2e test.
Miles-Garnsey Apr 8, 2024
6296040
Add purpose annotation.
Miles-Garnsey Apr 8, 2024
26a0c8b
Fix target definition in ReplicatedSecret.
Miles-Garnsey Apr 8, 2024
7bb6db9
Create new DropLabels field on ReplicatedSecret to ensure we don't en…
Miles-Garnsey Apr 8, 2024
76e138a
Make linter happy.
Miles-Garnsey Apr 8, 2024
809c5ef
Allow labels to be added when reconciling a ReplicatedSecret.
Miles-Garnsey Apr 8, 2024
012faf3
Additional label required for replication.
Miles-Garnsey Apr 8, 2024
cf37dfa
Fix ldflags variables for date and commit.
Miles-Garnsey Apr 8, 2024
cfdd508
Ensure the cluster name/namespace labels are applied correctly.
Miles-Garnsey Apr 8, 2024
67a379d
more trying to get ldflags working.
Miles-Garnsey Apr 9, 2024
63eb086
More informative error message for a failing call to .Get().
Miles-Garnsey Apr 10, 2024
34b0897
Still trying to fix -ldflags.
Miles-Garnsey Apr 10, 2024
61f305f
More informative error logging again.
Miles-Garnsey Apr 10, 2024
f848502
Straighten out what namespaces are which in MedusaReconciler.
Miles-Garnsey Apr 10, 2024
8814026
We want to ensure that the secret gets replicated to both the Kluster…
Miles-Garnsey Apr 10, 2024
48f85b8
Fix hash method.
Miles-Garnsey Apr 11, 2024
19962ad
Add owner reference so that ReplicatedSecret gets cleaned up.
Miles-Garnsey Apr 11, 2024
85100ec
Eliminate redundant if statement, add more deprecation info in Medusa…
Miles-Garnsey Apr 11, 2024
ea03952
Fix hash properly this time.
Miles-Garnsey Apr 11, 2024
77fe9d5
Need a longer timeout on Medusa restore, since this takes in excess o…
Miles-Garnsey Apr 11, 2024
4376893
Increase timeout.
Miles-Garnsey Apr 12, 2024
45cc714
Remove unused argument.
Miles-Garnsey Apr 12, 2024
3509c9f
Small refactor.
Miles-Garnsey Apr 12, 2024
05b7a89
Get a test going for the broken cleanup issues.
Miles-Garnsey Apr 12, 2024
28080a7
QOL tweaks.
Miles-Garnsey Apr 12, 2024
b29b800
Restore some envtests I'd commented out.
Miles-Garnsey Apr 15, 2024
4b48bc3
Test now failing in the right place...
Miles-Garnsey Apr 15, 2024
b0fe006
Fix issue where original secrets get deleted, and target secrets don't.
Miles-Garnsey Apr 15, 2024
ea0ac6a
Fix a bug where a ReplicatedSecret was going cluster-wide. They shoul…
Miles-Garnsey Apr 15, 2024
bf43fb0
Small rebase error fixed.
Miles-Garnsey Apr 15, 2024
a0c23c7
Ensure that the original secret isn't cleaned up if it was never repl…
Miles-Garnsey Apr 15, 2024
d9918bc
Add another TODO, cleanup here is still going to be broken under some…
Miles-Garnsey Apr 15, 2024
d58cc83
Fix issue where sometimes we'd try to cleanup a secret with no namesp…
Miles-Garnsey Apr 15, 2024
0417baf
Back out namespace scoping change. This needs to be in a separate PR.
Miles-Garnsey Apr 15, 2024
0646413
Line tests back up with current functionality.
Miles-Garnsey Apr 16, 2024
8b097cf
Update CHANGELOG/RELEASE-NOTES.md
Miles-Garnsey Apr 16, 2024
4e73cb4
Ensure changes in right CHANGELOG file.
Miles-Garnsey Apr 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG/CHANGELOG-1.15.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ Changelog for the K8ssandra Operator, new PRs should update the `unreleased` sec
When cutting a new release, update the `unreleased` heading to the tag being generated and date, like `## vX.Y.Z - YYYY-MM-DD` and create a new placeholder section for `unreleased` entries.

## unreleased
* [BUGFIX] [#1266](https://github.com/k8ssandra/k8ssandra-operator/issues/1266) MedusaConfigurations must now be namespace local to the K8ssandraCluster they are attached to, a webhook error will be thrown otherwise (for new clusters only). Additionally, ReplicatedSecrets should only pick up secrets from their local namespace to replicate.
* [BUGFIX] [#1217](https://github.com/k8ssandra/k8ssandra-operator/issues/1217) Medusa storage secrets now use a ReplicatedSecret for synchronization, fixing an issue where changes to the secrets were not propagating. Additionally, fix a number of issues with local testing on ARM Macs.
* [BUGFIX] [#1253](https://github.com/k8ssandra/k8ssandra-operator/issues/1253) Medusa storage secrets are now labelled with a unique label.
* [FEATURE] [#1260](https://github.com/k8ssandra/k8ssandra-operator/issues/1260) Update controller-gen to version 0.14.0.
11 changes: 11 additions & 0 deletions CHANGELOG/RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# k8ssandra-operator - Release Notes

## v1.15.0

### Deprecation of non-namespace-local MedusaConfigRef
Miles-Garnsey marked this conversation as resolved.
Show resolved Hide resolved

The previous version introduced functionality whereby a K8ssandraCluster could reference a MedusaConfiguration (via MedusaConfigRef) in a remote namespace within the same k8s cluster. This functionality is deprecated. Existing clusters will continue to reconcile, but new clusters (or updates to existing clusters) will be rejected at the webhook.

To update an existing cluster, or create a new one, ensure that the `namespace` field is left unset in the `medusaConfigRef`, and ensure that the MedusaConfiguration you are referencing exists within the K8ssandraCluster's local namespace.

If this functionality is critical to your use case, please raise an issue on Github and describe why it is important to you.


## v1.12.0

It is now possible to disable Reaper front end authentication by adding either `spec.reaper.uiUserSecretRef: {}` or `spec.reaper.uiUserSecretRef: ""`.
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ DATE ?= $(shell date)
COMMIT ?= $(shell git rev-parse --short HEAD)

build: generate fmt vet ## Build manager binary.
go build --ldflags "-X \"main.version=${VERSION}\" -X \"main.date=${DATE}\" -X \"main.commit=${COMMIT}\"" -o bin/manager main.go
echo "\"main.version=${VERSION}\" -X \"main.date=$(DATE)\" -X \"main.commit=$(COMMIT)\""
go build -ldflags "-X \"main.version=${VERSION}\" -X \"main.date=$(DATE)\" -X \"main.commit=$(COMMIT)\"" -o bin/manager main.go

run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go
Expand Down
3 changes: 3 additions & 0 deletions apis/k8ssandra/v1alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ const (
DatacenterLabel = "k8ssandra.io/datacenter"
// Forces refresh of secrets which relate to roles and authn in Cassandra.
RefreshAnnotation = "k8ssandra.io/refresh"

// Annotation to indicate the purpose of a given resource.
PurposeAnnotation = "k8ssandra.io/purpose"
)

var (
Expand Down
2 changes: 1 addition & 1 deletion apis/k8ssandra/v1alpha1/k8ssandracluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,6 @@ func (kc *K8ssandraCluster) DefaultNumTokens(serverVersion *semver.Version) floa
// this is to be used to name resources that are cluster specific in preference of concatenations
// of the namespaced name, as the latter are becoming too long and causing issues due to DNS name length
// constraints within k8s
func (kc *K8ssandraCluster) GetClusterIdHash(nchars int) string {
func (kc *K8ssandraCluster) GetClusterIdHash() string {
return utils.HashNameNamespace(kc.Name, kc.Namespace)
}
40 changes: 31 additions & 9 deletions apis/k8ssandra/v1alpha1/k8ssandracluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ package v1alpha1

import (
"fmt"
"k8s.io/apimachinery/pkg/util/validation"
"strings"

"k8s.io/apimachinery/pkg/util/validation"

"github.com/Masterminds/semver/v3"
"github.com/k8ssandra/k8ssandra-operator/pkg/clientcache"
"github.com/pkg/errors"
Expand Down Expand Up @@ -98,14 +99,8 @@ func (r *K8ssandraCluster) validateK8ssandraCluster() error {
}
}

// Verify the Medusa storage prefix is explicitly set
// only relevant if Medusa is enabled and the MedusaConfiguration object is referenced
if r.Spec.Medusa != nil {
if r.Spec.Medusa.MedusaConfigurationRef.Name != "" {
if r.Spec.Medusa.StorageProperties.Prefix == "" {
return ErrNoStoragePrefix
}
}
if err := r.ValidateMedusa(); err != nil {
return err
}

if err := r.validateStatefulsetNameSize(); err != nil {
Expand Down Expand Up @@ -201,3 +196,30 @@ func (r *K8ssandraCluster) ValidateDelete() error {
webhookLog.Info("validate K8ssandraCluster delete", "name", r.Name)
return nil
}

func (r *K8ssandraCluster) ValidateMedusa() error {
if r.Spec.Medusa == nil {
return nil
}

// Verify the Medusa storage prefix is explicitly set
// only relevant if Medusa is enabled and the MedusaConfiguration object is referenced
if r.Spec.Medusa.MedusaConfigurationRef.Name != "" {
if r.Spec.Medusa.StorageProperties.Prefix == "" {
return ErrNoStoragePrefix
}
// Verify that any referenced MedusaConfig is NS-local
if r.Spec.Medusa.MedusaConfigurationRef.Namespace != "" {
return errors.New("Medusa config must be namespace local")
}
if r.Spec.Medusa.MedusaConfigurationRef.APIVersion != "" ||
r.Spec.Medusa.MedusaConfigurationRef.Kind != "" ||
r.Spec.Medusa.MedusaConfigurationRef.FieldPath != "" ||
r.Spec.Medusa.MedusaConfigurationRef.ResourceVersion != "" ||
r.Spec.Medusa.MedusaConfigurationRef.UID != "" {
return errors.New("Medusa config invalid, invalid field used")
}
}

return nil
}
18 changes: 18 additions & 0 deletions apis/k8ssandra/v1alpha1/k8ssandracluster_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ func TestWebhook(t *testing.T) {
t.Run("StsNameTooLong", testStsNameTooLong)
t.Run("MedusaPrefixMissing", testMedusaPrefixMissing)
t.Run("InvalidDcName", testInvalidDcName)
t.Run("MedusaConfigNonLocalNamespace", testMedusaNonLocalNamespace)
}

func testContextValidation(t *testing.T) {
Expand Down Expand Up @@ -465,3 +466,20 @@ func testInvalidDcName(t *testing.T) {
required.Error(err)
required.Contains(err.Error(), "invalid DC name")
}

func testMedusaNonLocalNamespace(t *testing.T) {
required := require.New(t)
badCluster := createMinimalClusterObj("medusaconfig-nonlocal", "ns")
badCluster.Spec.Medusa = &medusaapi.MedusaClusterTemplate{
MedusaConfigurationRef: corev1.ObjectReference{
Namespace: "nonlocal-ns",
Name: "medusa-config",
},
StorageProperties: medusaapi.Storage{
Prefix: "some-prefix",
},
}
err := badCluster.validateK8ssandraCluster()
required.Error(err)
required.Contains(err.Error(), "Medusa config must be namespace local")
}
4 changes: 4 additions & 0 deletions apis/medusa/v1alpha1/medusaconfiguration_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
MedusaStorageSecretIdentifierLabel = "k8ssandra.io/medusa-storage-secret"
)

// MedusaConfigurationSpec defines the desired state of MedusaConfiguration
type MedusaConfigurationSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Expand Down
6 changes: 6 additions & 0 deletions apis/replication/v1alpha1/replicatedsecret_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ type ReplicationTarget struct {
// as the original secret.
// +optional
TargetPrefix string `json:"targetPrefix,omitempty"`

// DropLabels defines the labels to be dropped from the secret before replication, this is sometimes neccessary to avoid infinite replication.
DropLabels []string `json:"dropLabels,omitempty"`

// AddLabels adds labels to the target secret.
AddLabels map[string]string `json:"addLabels,omitempty"`
}

// ReplicatedSecretStatus defines the observed state of ReplicatedSecret
Expand Down
16 changes: 15 additions & 1 deletion apis/replication/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions charts/k8ssandra-operator/crds/k8ssandra-operator-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33387,6 +33387,18 @@ spec:
the secrets are replicated to. If empty, no clusters are targeted
items:
properties:
addLabels:
additionalProperties:
type: string
description: AddLabels adds labels to the target secret.
type: object
dropLabels:
description: DropLabels defines the labels to be dropped from
the secret before replication, this is sometimes neccessary
to avoid infinite replication.
items:
type: string
type: array
k8sContextName:
description: K8sContextName defines the target cluster name
as set in the ClientConfig. If left empty, current cluster
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ spec:
the secrets are replicated to. If empty, no clusters are targeted
items:
properties:
addLabels:
additionalProperties:
type: string
description: AddLabels adds labels to the target secret.
type: object
dropLabels:
description: DropLabels defines the labels to be dropped from
the secret before replication, this is sometimes neccessary
to avoid infinite replication.
items:
type: string
type: array
k8sContextName:
description: K8sContextName defines the target cluster name
as set in the ClientConfig. If left empty, current cluster
Expand Down
49 changes: 28 additions & 21 deletions controllers/k8ssandra/add_dc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,32 +744,39 @@ func addStargateAndReaperToCluster(ctx context.Context, t *testing.T, f *framewo
}

func addDcToCluster(ctx context.Context, t *testing.T, f *framework.Framework, kc *api.K8ssandraCluster, dcKey framework.ClusterKey) {
t.Logf("add %s to cluster", dcKey.Name)
require.Eventually(t, func() bool {
t.Logf("add %s to cluster", dcKey.Name)

key := utils.GetKey(kc)
err := f.Client.Get(ctx, key, kc)
require.NoError(t, err, "failed to get K8ssandraCluster")
key := utils.GetKey(kc)
err := f.Client.Get(ctx, key, kc)
require.NoError(t, err, "failed to get K8ssandraCluster")

kc.Spec.Cassandra.Datacenters = append(kc.Spec.Cassandra.Datacenters, api.CassandraDatacenterTemplate{
Meta: api.EmbeddedObjectMeta{
Name: dcKey.Name,
Namespace: dcKey.Namespace,
},
K8sContext: dcKey.K8sContext,
Size: 3,
DatacenterOptions: api.DatacenterOptions{
ServerVersion: "4.0.1",
StorageConfig: &cassdcapi.StorageConfig{
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: &defaultStorageClass,
kc.Spec.Cassandra.Datacenters = append(kc.Spec.Cassandra.Datacenters, api.CassandraDatacenterTemplate{
Meta: api.EmbeddedObjectMeta{
Name: dcKey.Name,
Namespace: dcKey.Namespace,
},
K8sContext: dcKey.K8sContext,
Size: 3,
DatacenterOptions: api.DatacenterOptions{
ServerVersion: "4.0.1",
StorageConfig: &cassdcapi.StorageConfig{
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: &defaultStorageClass,
},
},
},
},
})
annotations.AddAnnotation(kc, api.DcReplicationAnnotation, fmt.Sprintf(`{"%s": {"ks1": 3, "ks2": 3}}`, dcKey.Name))
})
annotations.AddAnnotation(kc, api.DcReplicationAnnotation, fmt.Sprintf(`{"%s": {"ks1": 3, "ks2": 3}}`, dcKey.Name))

err = f.Client.Update(ctx, kc)
if err != nil {
t.Logf("failed to add %s to cluster: %v", dcKey.Name, err)
return false
}
return err == nil
}, timeout, interval)

err = f.Client.Update(ctx, kc)
require.NoError(t, err, "failed to add dc to K8ssandraCluster")
}

func verifyReplicationOfSystemKeyspacesUpdated(t *testing.T, mockMgmtApi *testutils.FakeManagementApiFacade, replication, updatedReplication map[string]int) {
Expand Down
Loading
Loading