Skip to content

Commit

Permalink
Completion of a restore triggers secrets refresh.
Browse files Browse the repository at this point in the history
  • Loading branch information
Miles-Garnsey committed Dec 11, 2023
1 parent be45e84 commit e43825d
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 0 deletions.
2 changes: 2 additions & 0 deletions apis/k8ssandra/v1alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ const (
K8ssandraClusterNamespaceLabel = "k8ssandra.io/cluster-namespace"

DatacenterLabel = "k8ssandra.io/datacenter"
// Forces refresh of secrets which relate to roles and authn in Cassandra.
RefreshAnnotation = "k8ssandra.io/refresh"
)

var (
Expand Down
2 changes: 2 additions & 0 deletions controllers/medusa/medusarestorejob_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ func (r *MedusaRestoreJobReconciler) Reconcile(ctx context.Context, req ctrl.Req
}

request.Log.Info("The restore operation is complete")
medusa.RefreshSecrets(request.Datacenter, ctx, r.Client, request.Log, r.DefaultDelay)

Check failure on line 180 in controllers/medusa/medusarestorejob_controller.go

View workflow job for this annotation

GitHub Actions / Run unit/integration tests

Error return value of `medusa.RefreshSecrets` is not checked (errcheck)

return ctrl.Result{}, nil
}

Expand Down
49 changes: 49 additions & 0 deletions pkg/medusa/refresh_secrets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package medusa

import (
"context"
"fmt"
"time"

"github.com/go-logr/logr"
cassdcapi "github.com/k8ssandra/cass-operator/apis/cassandra/v1beta1"
k8ssandraapi "github.com/k8ssandra/k8ssandra-operator/apis/k8ssandra/v1alpha1"
"github.com/k8ssandra/k8ssandra-operator/pkg/reconciliation"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
defaultSUSecretName = "cass-superuser"
)

func RefreshSecrets(dc *cassdcapi.CassandraDatacenter, ctx context.Context, client client.Client, logger logr.Logger, requeueDelay time.Duration) error {
logger.Info(fmt.Sprintf("Restore complete for DC %#v, Refreshing secrets", dc.ObjectMeta))
userSecrets := []string{}

for _, user := range dc.Spec.Users {
userSecrets = append(userSecrets, user.SecretName)
}
if dc.Spec.SuperuserSecretName == "" {
userSecrets = append(userSecrets, defaultSUSecretName) //default SU secret
} else {
userSecrets = append(userSecrets, dc.Spec.SuperuserSecretName)
}
// Both Reaper and medusa secrets go into the userSecrets, so they don't need special handling.
for _, i := range userSecrets {
secret := &corev1.Secret{}
err := client.Get(ctx, types.NamespacedName{Name: i, Namespace: dc.Namespace}, secret)
if err != nil {
logger.Error(err, fmt.Sprintf("Failed to get secret %s", i))
return err
}
if secret.ObjectMeta.Annotations == nil {
secret.ObjectMeta.Annotations = make(map[string]string)
}
secret.ObjectMeta.Annotations[k8ssandraapi.RefreshAnnotation] = time.Now().String()
reconciliation.ReconcileObject(ctx, client, requeueDelay, *secret)
}
return nil

}
68 changes: 68 additions & 0 deletions pkg/medusa/refresh_secrets_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package medusa

import (
"context"
"testing"

"github.com/go-logr/logr"
cassdcapi "github.com/k8ssandra/cass-operator/apis/cassandra/v1beta1"
"github.com/k8ssandra/k8ssandra-operator/pkg/test"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

func TestRefreshSecrets_defaultSUSecret(t *testing.T) {
fakeClient := test.NewFakeClientWRestMapper()
cassDC := test.NewCassandraDatacenter("dc1", "test")
cassDC.Spec.Users = []cassdcapi.CassandraUser{
{SecretName: "custom-user"},
}
assert.NoError(t, fakeClient.Create(context.Background(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test"}}))
assert.NoError(t, fakeClient.Create(context.Background(), &cassDC))
secrets := []corev1.Secret{
{ObjectMeta: metav1.ObjectMeta{Name: "custom-user", Namespace: "test"}, Data: map[string][]byte{"username": []byte("test")}},
{ObjectMeta: metav1.ObjectMeta{Name: "cass-superuser", Namespace: "test"}, Data: map[string][]byte{"username": []byte("test")}},
}
for _, i := range secrets {
assert.NoError(t, fakeClient.Create(context.Background(), &i))
}
assert.NoError(t, RefreshSecrets(&cassDC, context.Background(), fakeClient, logr.Logger{}, 0))
suSecret := &corev1.Secret{}
assert.NoError(t, fakeClient.Get(context.Background(), types.NamespacedName{Name: "cass-superuser", Namespace: "test"}, suSecret))
_, exists := suSecret.ObjectMeta.Annotations["k8ssandra.io/refresh"]
assert.True(t, exists)
userSecret := &corev1.Secret{}
assert.NoError(t, fakeClient.Get(context.Background(), types.NamespacedName{Name: "custom-user", Namespace: "test"}, userSecret))
_, exists = userSecret.ObjectMeta.Annotations["k8ssandra.io/refresh"]
assert.True(t, exists)
}

func TestRefreshSecrets_customSecrets(t *testing.T) {
fakeClient := test.NewFakeClientWRestMapper()
cassDC := test.NewCassandraDatacenter("dc1", "test")
cassDC.Spec.Users = []cassdcapi.CassandraUser{
{SecretName: "custom-user"},
}
cassDC.Spec.SuperuserSecretName = "cass-custom-superuser"
assert.NoError(t, fakeClient.Create(context.Background(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test"}}))
assert.NoError(t, fakeClient.Create(context.Background(), &cassDC))
secrets := []corev1.Secret{
{ObjectMeta: metav1.ObjectMeta{Name: "custom-user", Namespace: "test"}},
{ObjectMeta: metav1.ObjectMeta{Name: "cass-custom-superuser", Namespace: "test"}},
}
for _, i := range secrets {
assert.NoError(t, fakeClient.Create(context.Background(), &i))
}
assert.NoError(t, RefreshSecrets(&cassDC, context.Background(), fakeClient, logr.Logger{}, 0))
suSecret := &corev1.Secret{}
assert.NoError(t, fakeClient.Get(context.Background(), types.NamespacedName{Name: "cass-custom-superuser", Namespace: "test"}, suSecret))
_, exists := suSecret.ObjectMeta.Annotations["k8ssandra.io/refresh"]
assert.True(t, exists)
userSecret := &corev1.Secret{}
assert.NoError(t, fakeClient.Get(context.Background(), types.NamespacedName{Name: "custom-user", Namespace: "test"}, userSecret))
_, exists = userSecret.ObjectMeta.Annotations["k8ssandra.io/refresh"]
assert.True(t, exists)

}

0 comments on commit e43825d

Please sign in to comment.