Skip to content

Commit 1cd421a

Browse files
IvanTvardovskyИван Старцев
andauthored
init exclude repo feature (#387)
Co-authored-by: Иван Старцев <ivan.startsev@mediascope.net>
1 parent 967dd13 commit 1cd421a

7 files changed

Lines changed: 71 additions & 14 deletions

File tree

config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ type flags struct {
1616
ReplicateRoleBindings bool
1717
ReplicateServiceAccounts bool
1818
SyncByContent bool
19+
ExcludeNamespaces string
1920
}

main.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func init() {
3737
flag.BoolVar(&f.ReplicateRoleBindings, "replicate-role-bindings", true, "Enable replication of role bindings")
3838
flag.BoolVar(&f.ReplicateServiceAccounts, "replicate-service-accounts", true, "Enable replication of service accounts")
3939
flag.BoolVar(&f.SyncByContent, "sync-by-content", false, "Always compare the contents of source and target resources and force them to be the same")
40+
flag.StringVar(&f.ExcludeNamespaces, "exclude-namespaces", "", "Comma-separated list of regex patterns for namespaces to exclude from replication")
4041
flag.Parse()
4142

4243
switch strings.ToUpper(strings.TrimSpace(f.LogLevel)) {
@@ -88,14 +89,17 @@ func main() {
8889

8990
client = kubernetes.NewForConfigOrDie(config)
9091

92+
excludePatterns := strings.Split(f.ExcludeNamespaces, ",")
93+
filter := common.NewNamespaceFilter(excludePatterns)
94+
9195
if f.ReplicateSecrets {
92-
secretRepl := secret.NewReplicator(client, f.ResyncPeriod, f.AllowAll, f.SyncByContent)
96+
secretRepl := secret.NewReplicator(client, f.ResyncPeriod, f.AllowAll, f.SyncByContent, filter)
9397
go secretRepl.Run()
9498
enabledReplicators = append(enabledReplicators, secretRepl)
9599
}
96100

97101
if f.ReplicateConfigMaps {
98-
configMapRepl := configmap.NewReplicator(client, f.ResyncPeriod, f.AllowAll, f.SyncByContent)
102+
configMapRepl := configmap.NewReplicator(client, f.ResyncPeriod, f.AllowAll, f.SyncByContent, filter)
99103
go configMapRepl.Run()
100104
enabledReplicators = append(enabledReplicators, configMapRepl)
101105
}

replicate/common/exclude.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package common
2+
3+
import (
4+
"regexp"
5+
)
6+
7+
type NamespaceFilter struct {
8+
ExcludePatterns []string
9+
compiled []*regexp.Regexp
10+
}
11+
12+
func NewNamespaceFilter(patterns []string) *NamespaceFilter {
13+
var compiled []*regexp.Regexp
14+
for _, pat := range patterns {
15+
if pat == "" {
16+
continue
17+
}
18+
re, err := regexp.Compile(pat)
19+
if err == nil {
20+
compiled = append(compiled, re)
21+
}
22+
}
23+
return &NamespaceFilter{
24+
ExcludePatterns: patterns,
25+
compiled: compiled,
26+
}
27+
}
28+
29+
func (f *NamespaceFilter) ShouldExclude(namespace string) bool {
30+
for _, re := range f.compiled {
31+
if re.MatchString(namespace) {
32+
return true
33+
}
34+
}
35+
return false
36+
}

replicate/common/generic-replicator.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ import (
2323
)
2424

2525
type ReplicatorConfig struct {
26-
Kind string
27-
Client kubernetes.Interface
28-
ResyncPeriod time.Duration
29-
AllowAll bool
30-
SyncByContent bool
31-
ListFunc cache.ListFunc
32-
WatchFunc cache.WatchFunc
33-
ObjType runtime.Object
26+
Kind string
27+
Client kubernetes.Interface
28+
ResyncPeriod time.Duration
29+
AllowAll bool
30+
SyncByContent bool
31+
ListFunc cache.ListFunc
32+
WatchFunc cache.WatchFunc
33+
ObjType runtime.Object
34+
NamespaceFilter *NamespaceFilter
3435
}
3536

3637
type UpdateFuncs struct {
@@ -88,6 +89,8 @@ func NewGenericReplicator(config ReplicatorConfig) *GenericReplicator {
8889
repl.Store = store
8990
repl.Controller = controller
9091

92+
repl.NamespaceFilter = config.NamespaceFilter
93+
9194
return &repl
9295
}
9396

@@ -427,6 +430,14 @@ func (r *GenericReplicator) replicateResourceToNamespaces(obj interface{}, targe
427430
cacheKey := MustGetKey(obj)
428431

429432
for _, namespace := range targets {
433+
if r.NamespaceFilter != nil && r.NamespaceFilter.ShouldExclude(namespace.Name) {
434+
log.WithFields(log.Fields{
435+
"kind": r.Kind,
436+
"namespace": namespace.Name,
437+
}).Info("Skipping excluded namespace")
438+
continue
439+
}
440+
430441
if innerErr := r.UpdateFuncs.ReplicateObjectTo(obj, &namespace); innerErr != nil {
431442
err = multierror.Append(err, errors.Wrapf(innerErr, "Failed to replicate %s %s -> %s: %v",
432443
r.Kind, cacheKey, namespace.Name, innerErr,

replicate/configmap/configmaps.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type Replicator struct {
2626
}
2727

2828
// NewReplicator creates a new config map replicator
29-
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll, syncByContent bool) common.Replicator {
29+
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll, syncByContent bool, namespaceFilter *common.NamespaceFilter) common.Replicator {
3030
repl := Replicator{
3131
GenericReplicator: common.NewGenericReplicator(common.ReplicatorConfig{
3232
Kind: "ConfigMap",
@@ -41,6 +41,7 @@ func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allo
4141
WatchFunc: func(lo metav1.ListOptions) (watch.Interface, error) {
4242
return client.CoreV1().ConfigMaps("").Watch(context.TODO(), lo)
4343
},
44+
NamespaceFilter: namespaceFilter,
4445
}),
4546
}
4647
repl.UpdateFuncs = common.UpdateFuncs{

replicate/secret/secrets.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type Replicator struct {
2626
}
2727

2828
// NewReplicator creates a new secret replicator
29-
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll, syncByContent bool) common.Replicator {
29+
func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allowAll, syncByContent bool, namespaceFilter *common.NamespaceFilter) common.Replicator {
3030
repl := Replicator{
3131
GenericReplicator: common.NewGenericReplicator(common.ReplicatorConfig{
3232
Kind: "Secret",
@@ -41,6 +41,7 @@ func NewReplicator(client kubernetes.Interface, resyncPeriod time.Duration, allo
4141
WatchFunc: func(lo metav1.ListOptions) (watch.Interface, error) {
4242
return client.CoreV1().Secrets("").Watch(context.TODO(), lo)
4343
},
44+
NamespaceFilter: namespaceFilter,
4445
}),
4546
}
4647
repl.UpdateFuncs = common.UpdateFuncs{

replicate/secret/secrets_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ func TestSecretReplicator(t *testing.T) {
8282
log.SetFormatter(&PlainFormatter{})
8383

8484
client := setupRealClientSet(t)
85+
filter := common.NewNamespaceFilter([]string{})
8586

86-
repl := NewReplicator(client, 60*time.Second, false, false)
87+
repl := NewReplicator(client, 60*time.Second, false, false, filter)
8788
go repl.Run()
8889

8990
time.Sleep(200 * time.Millisecond)
@@ -1293,7 +1294,9 @@ func TestSecretReplicatorSyncByContent(t *testing.T) {
12931294
client := setupRealClientSet(t)
12941295
ctx := context.TODO()
12951296

1296-
repl := NewReplicator(client, 60*time.Second, false, true)
1297+
filter := common.NewNamespaceFilter([]string{})
1298+
1299+
repl := NewReplicator(client, 60*time.Second, false, true, filter)
12971300
go repl.Run()
12981301

12991302
time.Sleep(200 * time.Millisecond)

0 commit comments

Comments
 (0)