Skip to content

Commit

Permalink
Implement annotation replicator.v1.mittwald.de/strip-labels (#155)
Browse files Browse the repository at this point in the history
* Add replicator.v1.mittwald.de/strip-labels

* Adjust condition in replicate/configmap/configmaps.go

* Remove keepOwnerReference and stripLabels logic in ReplicateFrom functions

* Remove duplicate test case.

* Remove additional data compare in tests
  • Loading branch information
jkroepke authored Nov 25, 2021
1 parent de67b13 commit 22a6795
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 35 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,25 @@ data:
.dockerconfigjson: e30K
```

#### Special case: Strip labels while replicate the resources.

Operators like [https://github.com/strimzi/strimzi-kafka-operator](strimzi-kafka-operator) implement an own garbage collection based on specific labels defined on resources. If mittwald replicator replicate secrets to different namespace, the strimzi-kafka-operator will remove the replicated secrets because from operators point of view the secret is a left-over. To mitigate the issue, set the annotation `replicator.v1.mittwald.de/strip-labels=true` to remove all labels on the replicated resource.

```yaml
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/managed-by: "strimzi-kafka-operator"
name: cluster-ca-certs
annotations:
replicator.v1.mittwald.de/strip-labels: "true"
type: kubernetes.io/tls
data:
tls.key: ""
tls.crt: ""
```

#### Special case: Resource with .metadata.ownerReferences

Sometimes, secrets are generated by external components. Such secrets are configured with an ownerReference. By default, the kubernetes-replicator will delete the
Expand Down
1 change: 1 addition & 0 deletions replicate/common/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ const (
ReplicateTo = "replicator.v1.mittwald.de/replicate-to"
ReplicateToMatching = "replicator.v1.mittwald.de/replicate-to-matching"
KeepOwnerReferences = "replicator.v1.mittwald.de/keep-owner-references"
StripLabels = "replicator.v1.mittwald.de/strip-labels"
)
16 changes: 7 additions & 9 deletions replicate/configmap/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,6 @@ func (r *Replicator) ReplicateDataFrom(sourceObj interface{}, targetObj interfac
}

targetCopy := target.DeepCopy()

keepOwnerReferences, ok := source.Annotations[common.KeepOwnerReferences]
if !ok || keepOwnerReferences != "true" {
targetCopy.OwnerReferences = nil
}

if targetCopy.Data == nil {
targetCopy.Data = make(map[string]string)
}
Expand Down Expand Up @@ -200,9 +194,13 @@ func (r *Replicator) ReplicateObjectTo(sourceObj interface{}, target *v1.Namespa
}

labelsCopy := make(map[string]string)
if source.Labels != nil {
for key, value := range source.Labels {
labelsCopy[key] = value

stripLabels, ok := source.Annotations[common.StripLabels]
if !ok && stripLabels != "true" {
if source.Labels != nil {
for key, value := range source.Labels {
labelsCopy[key] = value
}
}
}

Expand Down
16 changes: 7 additions & 9 deletions replicate/role/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,6 @@ func (r *Replicator) ReplicateDataFrom(sourceObj interface{}, targetObj interfac
}

targetCopy := target.DeepCopy()

keepOwnerReferences, ok := source.Annotations[common.KeepOwnerReferences]
if !ok || keepOwnerReferences != "true" {
targetCopy.OwnerReferences = nil
}

targetCopy.Rules = source.Rules

logger.Infof("updating target %s/%s", target.Namespace, target.Name)
Expand Down Expand Up @@ -141,9 +135,13 @@ func (r *Replicator) ReplicateObjectTo(sourceObj interface{}, target *v1.Namespa
}

labelsCopy := make(map[string]string)
if source.Labels != nil {
for key, value := range source.Labels {
labelsCopy[key] = value

stripLabels, ok := source.Annotations[common.StripLabels]
if !ok && stripLabels != "true" {
if source.Labels != nil {
for key, value := range source.Labels {
labelsCopy[key] = value
}
}
}

Expand Down
16 changes: 8 additions & 8 deletions replicate/rolebinding/rolebindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,6 @@ func (r *Replicator) ReplicateDataFrom(sourceObj interface{}, targetObj interfac
}

targetCopy := target.DeepCopy()
keepOwnerReferences, ok := source.Annotations[common.KeepOwnerReferences]
if !ok || keepOwnerReferences != "true" {
targetCopy.OwnerReferences = nil
}

targetCopy.Subjects = source.Subjects

log.Infof("updating target %s/%s", target.Namespace, target.Name)
Expand Down Expand Up @@ -139,10 +134,15 @@ func (r *Replicator) ReplicateObjectTo(sourceObj interface{}, target *v1.Namespa
}

labelsCopy := make(map[string]string)
if source.Labels != nil {
for key, value := range source.Labels {
labelsCopy[key] = value

stripLabels, ok := source.Annotations[common.StripLabels]
if !ok && stripLabels != "true" {
if source.Labels != nil {
for key, value := range source.Labels {
labelsCopy[key] = value
}
}

}

targetCopy.Name = source.Name
Expand Down
16 changes: 7 additions & 9 deletions replicate/secret/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,6 @@ func (r *Replicator) ReplicateDataFrom(sourceObj interface{}, targetObj interfac
}

targetCopy := target.DeepCopy()

keepOwnerReferences, ok := source.Annotations[common.KeepOwnerReferences]
if !ok || keepOwnerReferences != "true" {
targetCopy.OwnerReferences = nil
}

if targetCopy.Data == nil {
targetCopy.Data = make(map[string][]byte)
}
Expand Down Expand Up @@ -172,9 +166,13 @@ func (r *Replicator) ReplicateObjectTo(sourceObj interface{}, target *v1.Namespa
sort.Strings(replicatedKeys)

labelsCopy := make(map[string]string)
if source.Labels != nil {
for key, value := range source.Labels {
labelsCopy[key] = value

stripLabels, ok := source.Annotations[common.StripLabels]
if !ok && stripLabels != "true" {
if source.Labels != nil {
for key, value := range source.Labels {
labelsCopy[key] = value
}
}
}

Expand Down
56 changes: 56 additions & 0 deletions replicate/secret/secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,62 @@ func TestSecretReplicator(t *testing.T) {
require.Equal(t, []byte("Hello Bar"), updTarget.Data["bar"])
})

t.Run("replication is pushed to other namespaces and strip labels", func(t *testing.T) {
sourceLabels := map[string]string{
"foo": "bar",
"hello": "world",
}
source := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "source-pushed-to-other-with-strip-labels",
Namespace: ns.Name,
Annotations: map[string]string{
common.ReplicateTo: prefix + "test2",
common.StripLabels: "true",
},
Labels: sourceLabels,
OwnerReferences: []metav1.OwnerReference{{
APIVersion: "v1",
Kind: "Namespace",
Name: nsData.Name,
UID: nsData.UID,
}},
},
Type: corev1.SecretTypeOpaque,
Data: map[string][]byte{
"foo": []byte("Hello Foo"),
"bar": []byte("Hello Bar"),
},
}

wg, stop := waitForSecrets(client, 2, EventHandlerFuncs{
AddFunc: func(wg *sync.WaitGroup, obj interface{}) {
secret := obj.(*corev1.Secret)
if secret.Namespace == source.Namespace && secret.Name == source.Name {
log.Debugf("AddFunc %+v", obj)
wg.Done()
} else if secret.Namespace == prefix+"test2" && secret.Name == source.Name {
log.Debugf("AddFunc %+v", obj)
wg.Done()
}
},
})
_, err := secrets.Create(context.TODO(), &source, metav1.CreateOptions{})
require.NoError(t, err)

waitWithTimeout(wg, MaxWaitTime)
close(stop)

secrets2 := client.CoreV1().Secrets(prefix + "test2")
updTarget, err := secrets2.Get(context.TODO(), source.Name, metav1.GetOptions{})

require.NoError(t, err)
require.Equal(t, []byte("Hello Foo"), updTarget.Data["foo"])
require.False(t, reflect.DeepEqual(sourceLabels, updTarget.Labels))

require.Equal(t, map[string]string(nil), updTarget.Labels)
})

t.Run("replication is pushed to other namespaces by label selector", func(t *testing.T) {
source := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Expand Down

0 comments on commit 22a6795

Please sign in to comment.