Skip to content

Commit 71a75be

Browse files
committed
Implement .metadata.ownerReferences handling
1 parent 99b738c commit 71a75be

File tree

12 files changed

+201
-45
lines changed

12 files changed

+201
-45
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,14 @@ type: kubernetes.io/dockerconfigjson
193193
data:
194194
.dockerconfigjson: e30K
195195
```
196+
197+
#### Special case: Resource with .metadata.ownerReferences
198+
199+
Sometimes, secrets are generated by external components. Such secrets are configured with an ownerReference. By default, the kubernetes-replicator will copy the
200+
ownerReference to the target namespace, too.
201+
202+
ownerReference won't work [across different namespaces](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents) and the secret at the destination will be removed by the kubernetes garbage collection.
203+
204+
By set `-strip-owner-reference=true` as CLI argument, kubernetes-replicator will strip the ownerReference fields to avoid deletion of the secrets in the destination.
205+
206+
See also: https://github.com/mittwald/kubernetes-replicator/issues/120

config.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ package main
33
import "time"
44

55
type flags struct {
6-
Kubeconfig string
7-
ResyncPeriodS string
8-
ResyncPeriod time.Duration
9-
StatusAddr string
10-
AllowAll bool
11-
LogLevel string
12-
LogFormat string
6+
Kubeconfig string
7+
ResyncPeriodS string
8+
ResyncPeriod time.Duration
9+
StatusAddr string
10+
AllowAll bool
11+
StripOwnerReference bool
12+
LogLevel string
13+
LogFormat string
1314
}

deploy/helm-chart/kubernetes-replicator/values.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ grantClusterAdmin: false
99
args: []
1010
# - -resync-period=30m
1111
# - -allow-all=false
12+
# - -strip-owner-reference=true
1213

1314
serviceAccount:
1415
create: true

main.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func init() {
3030
flag.StringVar(&f.LogLevel, "log-level", "info", "Log level (trace, debug, info, warn, error)")
3131
flag.StringVar(&f.LogFormat, "log-format", "plain", "Log format (plain, json)")
3232
flag.BoolVar(&f.AllowAll, "allow-all", false, "allow replication of all secrets (CAUTION: only use when you know what you're doing)")
33+
flag.BoolVar(&f.StripOwnerReference, "strip-owner-reference", false, "strip metadata.ownerReference while copy resources")
3334
flag.Parse()
3435

3536
switch strings.ToUpper(strings.TrimSpace(f.LogLevel)) {
@@ -80,10 +81,10 @@ func main() {
8081

8182
client = kubernetes.NewForConfigOrDie(config)
8283

83-
secretRepl := secret.NewReplicator(client, f.ResyncPeriod, f.AllowAll)
84-
configMapRepl := configmap.NewReplicator(client, f.ResyncPeriod, f.AllowAll)
85-
roleRepl := role.NewReplicator(client, f.ResyncPeriod, f.AllowAll)
86-
roleBindingRepl := rolebinding.NewReplicator(client, f.ResyncPeriod, f.AllowAll)
84+
secretRepl := secret.NewReplicator(client, f.ResyncPeriod, f.AllowAll, f.StripOwnerReference)
85+
configMapRepl := configmap.NewReplicator(client, f.ResyncPeriod, f.AllowAll, f.StripOwnerReference)
86+
roleRepl := role.NewReplicator(client, f.ResyncPeriod, f.AllowAll, f.StripOwnerReference)
87+
roleBindingRepl := rolebinding.NewReplicator(client, f.ResyncPeriod, f.AllowAll, f.StripOwnerReference)
8788

8889
go secretRepl.Run()
8990

replicate/common/generic-replicator.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ import (
2222
)
2323

2424
type ReplicatorConfig struct {
25-
Kind string
26-
Client kubernetes.Interface
27-
ResyncPeriod time.Duration
28-
AllowAll bool
29-
ListFunc cache.ListFunc
30-
WatchFunc cache.WatchFunc
31-
ObjType runtime.Object
25+
Kind string
26+
Client kubernetes.Interface
27+
ResyncPeriod time.Duration
28+
AllowAll bool
29+
StripOwnerReference bool
30+
ListFunc cache.ListFunc
31+
WatchFunc cache.WatchFunc
32+
ObjType runtime.Object
3233
}
3334

3435
type UpdateFuncs struct {

replicate/common/namespaces.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (nw *NamespaceWatcher) create(client kubernetes.Interface, resyncPeriod tim
6161
&v1.Namespace{},
6262
resyncPeriod,
6363
cache.ResourceEventHandlerFuncs{
64-
AddFunc: namespaceAdded,
64+
AddFunc: namespaceAdded,
6565
UpdateFunc: namespaceUpdated,
6666
},
6767
)

replicate/configmap/configmaps.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ type Replicator struct {
2525
}
2626

2727
// NewReplicator creates a new config map replicator
28-
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll bool) common.Replicator {
28+
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll bool, stripOwnerReference bool) common.Replicator {
2929
repl := Replicator{
3030
GenericReplicator: common.NewGenericReplicator(common.ReplicatorConfig{
31-
Kind: "ConfigMap",
32-
ObjType: &v1.ConfigMap{},
33-
AllowAll: allowAll,
34-
ResyncPeriod: resyncPeriod,
35-
Client: client,
31+
Kind: "ConfigMap",
32+
ObjType: &v1.ConfigMap{},
33+
AllowAll: allowAll,
34+
StripOwnerReference: stripOwnerReference,
35+
ResyncPeriod: resyncPeriod,
36+
Client: client,
3637
ListFunc: func(lo metav1.ListOptions) (runtime.Object, error) {
3738
return client.CoreV1().ConfigMaps("").List(context.TODO(), lo)
3839
},
@@ -72,6 +73,10 @@ func (r *Replicator) ReplicateDataFrom(sourceObj interface{}, targetObj interfac
7273

7374
targetCopy := target.DeepCopy()
7475

76+
if r.StripOwnerReference {
77+
targetCopy.OwnerReferences = nil
78+
}
79+
7580
if targetCopy.Data == nil {
7681
targetCopy.Data = make(map[string]string)
7782
}

replicate/role/roles.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@ type Replicator struct {
2424
}
2525

2626
// NewReplicator creates a new role replicator
27-
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll bool) common.Replicator {
27+
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll bool, stripOwnerReference bool) common.Replicator {
2828
repl := Replicator{
2929
GenericReplicator: common.NewGenericReplicator(common.ReplicatorConfig{
30-
Kind: "Role",
31-
ObjType: &rbacv1.Role{},
32-
AllowAll: allowAll,
33-
ResyncPeriod: resyncPeriod,
34-
Client: client,
30+
Kind: "Role",
31+
ObjType: &rbacv1.Role{},
32+
AllowAll: allowAll,
33+
StripOwnerReference: stripOwnerReference,
34+
ResyncPeriod: resyncPeriod,
35+
Client: client,
3536
ListFunc: func(lo metav1.ListOptions) (runtime.Object, error) {
3637
return client.RbacV1().Roles("").List(context.TODO(), lo)
3738
},
@@ -74,6 +75,10 @@ func (r *Replicator) ReplicateDataFrom(sourceObj interface{}, targetObj interfac
7475

7576
targetCopy := target.DeepCopy()
7677

78+
if r.StripOwnerReference {
79+
targetCopy.OwnerReferences = nil
80+
}
81+
7782
targetCopy.Rules = source.Rules
7883

7984
logger.Infof("updating target %s/%s", target.Namespace, target.Name)

replicate/role/roles_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func TestRoleReplicator(t *testing.T) {
7979
prefix := namespacePrefix()
8080
client := kubernetes.NewForConfigOrDie(config)
8181

82-
repl := NewReplicator(client, 60*time.Second, false)
82+
repl := NewReplicator(client, 60*time.Second, false, false)
8383
go repl.Run()
8484

8585
time.Sleep(200 * time.Millisecond)

replicate/rolebinding/rolebindings.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ type Replicator struct {
2626
const sleepTime = 100 * time.Millisecond
2727

2828
// NewReplicator creates a new secret replicator
29-
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll bool) common.Replicator {
29+
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll bool, stripOwnerReference bool) common.Replicator {
3030
repl := Replicator{
3131
GenericReplicator: common.NewGenericReplicator(common.ReplicatorConfig{
32-
Kind: "RoleBinding",
33-
ObjType: &rbacv1.RoleBinding{},
34-
AllowAll: allowAll,
35-
ResyncPeriod: resyncPeriod,
36-
Client: client,
32+
Kind: "RoleBinding",
33+
ObjType: &rbacv1.RoleBinding{},
34+
AllowAll: allowAll,
35+
StripOwnerReference: stripOwnerReference,
36+
ResyncPeriod: resyncPeriod,
37+
Client: client,
3738
ListFunc: func(lo metav1.ListOptions) (runtime.Object, error) {
3839
return client.RbacV1().RoleBindings("").List(context.TODO(), lo)
3940
},
@@ -75,6 +76,11 @@ func (r *Replicator) ReplicateDataFrom(sourceObj interface{}, targetObj interfac
7576
}
7677

7778
targetCopy := target.DeepCopy()
79+
80+
if r.StripOwnerReference {
81+
targetCopy.OwnerReferences = nil
82+
}
83+
7884
targetCopy.Subjects = source.Subjects
7985

8086
log.Infof("updating target %s/%s", target.Namespace, target.Name)

0 commit comments

Comments
 (0)