Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion liveness/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (h *Handler) notReadyComponents() []string {
return notReady
}

//noinspection GoUnusedParameter
// noinspection GoUnusedParameter
func (h *Handler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/healthz" {
res.WriteHeader(http.StatusOK)
Expand Down
2 changes: 1 addition & 1 deletion liveness/handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (r *MockReplicator) Synced() bool {
return r.synced
}

//noinspection GoUnusedParameter
// noinspection GoUnusedParameter
func (r *MockReplicator) NamespaceAdded(ns *v1.Namespace) {
// Do nothing
}
Expand Down
4 changes: 1 addition & 3 deletions replicate/common/generic-replicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,7 @@ func (r *GenericReplicator) resourceAddedReplicateFrom(sourceLocation string, ta

r.DependencyMap[sourceLocation][cacheKey] = nil

if _, ok := r.DependentMap[cacheKey]; !ok {
r.DependentMap[cacheKey] = sourceLocation
}
r.DependentMap[cacheKey] = sourceLocation

sourceObject, exists, err := r.Store.GetByKey(sourceLocation)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion replicate/rolebinding/rolebindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (r *Replicator) ReplicateObjectTo(sourceObj interface{}, target *v1.Namespa
return nil
}

//Checks if Role required for RoleBinding exists. Retries a few times before returning error to allow replication to catch up
// Checks if Role required for RoleBinding exists. Retries a few times before returning error to allow replication to catch up
func (r *Replicator) canReplicate(targetNameSpace string, roleRef string) (err error) {
for i := 0; i < 5; i++ {
_, err = r.Client.RbacV1().Roles(targetNameSpace).Get(context.TODO(), roleRef, metav1.GetOptions{})
Expand Down
127 changes: 126 additions & 1 deletion replicate/secret/secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"context"
"fmt"
"k8s.io/client-go/tools/clientcmd"
"os"
"path/filepath"
"reflect"
Expand All @@ -13,6 +12,8 @@ import (
"testing"
"time"

"k8s.io/client-go/tools/clientcmd"

"github.com/mittwald/kubernetes-replicator/replicate/common"
pkgerrors "github.com/pkg/errors"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -1283,6 +1284,130 @@ func TestSecretReplicator(t *testing.T) {

})

t.Run("target switches to replicate from a different secret with same name", func(t *testing.T) {
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "switchable-source",
Namespace: ns.Name,
Annotations: map[string]string{
common.ReplicationAllowed: "true",
common.ReplicationAllowedNamespaces: ns.Name + "," + ns2.Name,
},
},
Type: corev1.SecretTypeOpaque,
Data: map[string][]byte{
"value": []byte("original-secret-value"),
},
}

target := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "switchable-target",
Namespace: ns.Name,
Annotations: map[string]string{
common.ReplicateFromAnnotation: common.MustGetKey(&secret),
},
},
Type: corev1.SecretTypeOpaque,
}

wg, stop := waitForSecrets(client, 3, EventHandlerFuncs{
AddFunc: func(wg *sync.WaitGroup, obj any) {
s := obj.(*corev1.Secret)
if s.Namespace == secret.Namespace && s.Name == secret.Name {
log.Debugf("AddFunc secret %+v", obj)
wg.Done()
} else if s.Namespace == target.Namespace && s.Name == target.Name {
log.Debugf("AddFunc target %+v", obj)
wg.Done()
}
},
UpdateFunc: func(wg *sync.WaitGroup, oldObj, newObj any) {
s := oldObj.(*corev1.Secret)
if s.Namespace == target.Namespace && s.Name == target.Name {
log.Debugf("UpdateFunc target %+v -> %+v", oldObj, newObj)
wg.Done()
}
},
})

_, err := secrets.Create(context.TODO(), &secret, metav1.CreateOptions{})
require.NoError(t, err)

_, err = secrets.Create(context.TODO(), &target, metav1.CreateOptions{})
require.NoError(t, err)

waitWithTimeout(wg, MaxWaitTime)
close(stop)

updTarget, err := secrets.Get(context.TODO(), target.Name, metav1.GetOptions{})
require.NoError(t, err)
require.Equal(t, []byte("original-secret-value"), updTarget.Data["value"])

// Create newsecret with same name but in different namespace (ns2)
newsecret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "switchable-source",
Namespace: ns2.Name,
Annotations: map[string]string{
common.ReplicationAllowed: "true",
common.ReplicationAllowedNamespaces: ns.Name + "," + ns2.Name,
},
},
Type: corev1.SecretTypeOpaque,
Data: map[string][]byte{
"value": []byte("new-secret-value"),
},
}

secrets2 := client.CoreV1().Secrets(prefix + "test2")

wg, stop = waitForSecrets(client, 1, EventHandlerFuncs{
AddFunc: func(wg *sync.WaitGroup, obj any) {
s := obj.(*corev1.Secret)
if s.Namespace == newsecret.Namespace && s.Name == newsecret.Name {
log.Debugf("AddFunc newsecret %+v", obj)
wg.Done()
}
},
})

_, err = secrets2.Create(context.TODO(), &newsecret, metav1.CreateOptions{})
require.NoError(t, err)

waitWithTimeout(wg, MaxWaitTime)
close(stop)

createdNewSecret, err := secrets2.Get(context.TODO(), newsecret.Name, metav1.GetOptions{})
require.NoError(t, err)
require.Equal(t, []byte("new-secret-value"), createdNewSecret.Data["value"])

wg, stop = waitForSecrets(client, 1, EventHandlerFuncs{
UpdateFunc: func(wg *sync.WaitGroup, oldObj, newObj any) {
s := oldObj.(*corev1.Secret)
if s.Namespace == target.Namespace && s.Name == target.Name {
log.Debugf("UpdateFunc target after switch %+v -> %+v", oldObj, newObj)
wg.Done()
}
},
})

// Update target's annotation to point to newsecret
patchData := fmt.Sprintf(`{"metadata":{"annotations":{"%s":"%s"}}}`,
common.ReplicateFromAnnotation,
common.MustGetKey(&newsecret))
_, err = secrets.Patch(context.TODO(), target.Name, types.MergePatchType,
[]byte(patchData), metav1.PatchOptions{})
require.NoError(t, err)

waitWithTimeout(wg, MaxWaitTime)
close(stop)

updTarget, err = secrets.Get(context.TODO(), target.Name, metav1.GetOptions{})
require.NoError(t, err)
require.Equal(t, []byte("new-secret-value"), updTarget.Data["value"])
})

}

func TestSecretReplicatorSyncByContent(t *testing.T) {
Expand Down