Skip to content

Commit a8134fc

Browse files
author
Alan Clucas
committed
Exclude namespaces by regex
1 parent 0182cc5 commit a8134fc

File tree

5 files changed

+100
-73
lines changed

5 files changed

+100
-73
lines changed

README.md

+21-20
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,27 @@ Available Commands:
5959
version Print the version number
6060
6161
Flags:
62-
-s, --api-server string Kubernetes api-server url
63-
-c, --config string Configuration file (default "/etc/katafygio/katafygio.yaml")
64-
-q, --context string Kubernetes configuration context
65-
-d, --dry-run Dry-run mode: don't store anything
66-
-m, --dump-only Dump mode: dump everything once and exit
67-
-x, --exclude-kind strings Ressource kind to exclude. Eg. 'deployment'
68-
-y, --exclude-object strings Object to exclude. Eg. 'configmap:kube-system/kube-dns'
69-
-l, --filter string Label filter. Select only objects matching the label
70-
-t, --git-timeout duration Git operations timeout (default 5m0s)
71-
-g, --git-url string Git repository URL
72-
-p, --healthcheck-port int Port for answering healthchecks on /health url
73-
-h, --help help for katafygio
74-
-k, --kube-config string Kubernetes configuration path
75-
-e, --local-dir string Where to dump yaml files (default "./kubernetes-backup")
76-
-v, --log-level string Log level (default "info")
77-
-o, --log-output string Log output (default "stderr")
78-
-r, --log-server string Log server (if using syslog)
79-
-a, --namespace string Only dump objects from this namespace
80-
-n, --no-git Don't version with git
81-
-i, --resync-interval int Full resync interval in seconds (0 to disable) (default 900)
62+
-s, --api-server string Kubernetes api-server url
63+
-c, --config string Configuration file (default "/etc/katafygio/katafygio.yaml")
64+
-q, --context string Kubernetes configuration context
65+
-d, --dry-run Dry-run mode: don't store anything
66+
-m, --dump-only Dump mode: dump everything once and exit
67+
-x, --exclude-kind strings Ressource kind to exclude. Eg. 'deployment'
68+
-z, --exclude-namespaces strings Namespaces to exclude. Eg. 'temp.*' as regexes. This collects all namespaces and then filters them. Don't use it with the namespace flag.
69+
-y, --exclude-object strings Object to exclude. Eg. 'configmap:kube-system/kube-dns'
70+
-l, --filter string Label filter. Select only objects matching the label
71+
-t, --git-timeout duration Git operations timeout (default 5m0s)
72+
-g, --git-url string Git repository URL
73+
-p, --healthcheck-port int Port for answering healthchecks on /health url
74+
-h, --help help for katafygio
75+
-k, --kube-config string Kubernetes configuration path
76+
-e, --local-dir string Where to dump yaml files (default "./kubernetes-backup")
77+
-v, --log-level string Log level (default "info")
78+
-o, --log-output string Log output (default "stderr")
79+
-r, --log-server string Log server (if using syslog)
80+
-a, --namespace string Only dump objects from this namespace
81+
-n, --no-git Don't version with git
82+
-i, --resync-interval int Full resync interval in seconds (0 to disable) (default 900)
8283
```
8384

8485
## Configuration file and env variables

cmd/execute.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func runE(cmd *cobra.Command, args []string) (err error) {
7070
}
7171

7272
evts := event.New()
73-
fact := controller.NewFactory(logger, filter, resyncInt, exclobj)
73+
fact := controller.NewFactory(logger, filter, resyncInt, exclobj, exclnamespaces)
7474
reco := recorder.New(logger, evts, localDir, resyncInt*2, dryRun).Start()
7575
obsv := observer.New(logger, restcfg, evts, fact, exclkind, namespace).Start()
7676

cmd/flags.go

+24-19
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,26 @@ import (
99
)
1010

1111
var (
12-
cfgFile string
13-
apiServer string
14-
context string
15-
namespace string
16-
kubeConf string
17-
dryRun bool
18-
dumpMode bool
19-
logLevel string
20-
logOutput string
21-
logServer string
22-
filter string
23-
localDir string
24-
gitURL string
25-
gitTimeout time.Duration
26-
healthP int
27-
resyncInt int
28-
exclkind []string
29-
exclobj []string
30-
noGit bool
12+
cfgFile string
13+
apiServer string
14+
context string
15+
namespace string
16+
exclnamespaces []string
17+
kubeConf string
18+
dryRun bool
19+
dumpMode bool
20+
logLevel string
21+
logOutput string
22+
logServer string
23+
filter string
24+
localDir string
25+
gitURL string
26+
gitTimeout time.Duration
27+
healthP int
28+
resyncInt int
29+
exclkind []string
30+
exclobj []string
31+
noGit bool
3132
)
3233

3334
func bindPFlag(key string, cmd string) {
@@ -52,6 +53,9 @@ func init() {
5253
RootCmd.PersistentFlags().StringVarP(&namespace, "namespace", "a", "", "Only dump objects from this namespace")
5354
bindPFlag("namespace", "namespace")
5455

56+
RootCmd.PersistentFlags().StringSliceVarP(&exclnamespaces, "exclude-namespaces", "z", nil, "Namespaces to exclude. Eg. 'temp.*' as regexes. This collects all namespaces and then filters them. Don't use it with the namespace flag.")
57+
bindPFlag("exclude-namespaces", "exclude-namespaces")
58+
5559
RootCmd.PersistentFlags().StringVarP(&kubeConf, "kube-config", "k", "", "Kubernetes configuration path")
5660
bindPFlag("kube-config", "kube-config")
5761

@@ -103,6 +107,7 @@ func bindConf(cmd *cobra.Command, args []string) {
103107
apiServer = viper.GetString("api-server")
104108
context = viper.GetString("context")
105109
namespace = viper.GetString("namespace")
110+
exclnamespaces = viper.GetStringSlice("exclude-namespaces")
106111
kubeConf = viper.GetString("kube-config")
107112
dryRun = viper.GetBool("dry-run")
108113
dumpMode = viper.GetBool("dump-only")

pkg/controller/controller.go

+53-32
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package controller
77

88
import (
99
"fmt"
10+
"regexp"
1011
"strings"
1112
"time"
1213

@@ -43,24 +44,26 @@ type logger interface {
4344

4445
// Factory generate controllers
4546
type Factory struct {
46-
logger logger
47-
filter string
48-
resyncIntv time.Duration
49-
excluded []string
47+
logger logger
48+
filter string
49+
resyncIntv time.Duration
50+
excludedobj []string
51+
excludedns []string
5052
}
5153

5254
// Controller is a generic kubernetes controller
5355
type Controller struct {
54-
name string
55-
stopCh chan struct{}
56-
doneCh chan struct{}
57-
syncCh chan struct{}
58-
notifier event.Notifier
59-
queue workqueue.RateLimitingInterface
60-
informer cache.SharedIndexInformer
61-
logger logger
62-
resyncIntv time.Duration
63-
excluded []string
56+
name string
57+
stopCh chan struct{}
58+
doneCh chan struct{}
59+
syncCh chan struct{}
60+
notifier event.Notifier
61+
queue workqueue.RateLimitingInterface
62+
informer cache.SharedIndexInformer
63+
logger logger
64+
resyncIntv time.Duration
65+
excludedobj []string
66+
excludedns []*regexp.Regexp
6467
}
6568

6669
// New return a kubernetes controller using the provided client
@@ -70,7 +73,8 @@ func New(client cache.ListerWatcher,
7073
name string,
7174
filter string,
7275
resync time.Duration,
73-
excluded []string,
76+
excludedobj []string,
77+
excludednamespace []string,
7478
) *Controller {
7579

7680
selector := metav1.ListOptions{LabelSelector: filter, ResourceVersion: "0"}
@@ -113,17 +117,23 @@ func New(client cache.ListerWatcher,
113117
},
114118
})
115119

120+
exclnsre := make([]*regexp.Regexp, 0)
121+
for _, ns := range excludednamespace {
122+
exclnsre = append(exclnsre, regexp.MustCompile(ns))
123+
}
124+
116125
return &Controller{
117-
stopCh: make(chan struct{}),
118-
doneCh: make(chan struct{}),
119-
syncCh: make(chan struct{}, 1),
120-
notifier: notifier,
121-
name: name,
122-
queue: queue,
123-
informer: informer,
124-
logger: log,
125-
resyncIntv: resync,
126-
excluded: excluded,
126+
stopCh: make(chan struct{}),
127+
doneCh: make(chan struct{}),
128+
syncCh: make(chan struct{}, 1),
129+
notifier: notifier,
130+
name: name,
131+
queue: queue,
132+
informer: informer,
133+
logger: log,
134+
resyncIntv: resync,
135+
excludedobj: excludedobj,
136+
excludedns: exclnsre,
127137
}
128138
}
129139

@@ -198,7 +208,7 @@ func (c *Controller) processItem(key string) error {
198208
return fmt.Errorf("error fetching %s from store: %v", key, err)
199209
}
200210

201-
for _, obj := range c.excluded {
211+
for _, obj := range c.excludedobj {
202212
if strings.Compare(strings.ToLower(obj), strings.ToLower(c.name+":"+key)) == 0 {
203213
return nil
204214
}
@@ -220,6 +230,16 @@ func (c *Controller) processItem(key string) error {
220230
delete(md, attr)
221231
}
222232

233+
if namespace, ok := md["namespace"].(string); ok {
234+
for _, nsre := range c.excludedns {
235+
if nsre.MatchString(namespace) {
236+
// Rely on the background sync to delete these excluded files if
237+
// we previously had aquired them
238+
return nil
239+
}
240+
}
241+
}
242+
223243
yml, err := yaml.Marshal(obj)
224244
if err != nil {
225245
return fmt.Errorf("failed to marshal %s: %v", key, err)
@@ -234,16 +254,17 @@ func (c *Controller) enqueue(notif *event.Notification) {
234254
}
235255

236256
// NewFactory create a controller factory
237-
func NewFactory(logger logger, filter string, resync int, excluded []string) *Factory {
257+
func NewFactory(logger logger, filter string, resync int, excludedobj []string, excludedns []string) *Factory {
238258
return &Factory{
239-
logger: logger,
240-
filter: filter,
241-
resyncIntv: time.Duration(resync) * time.Second,
242-
excluded: excluded,
259+
logger: logger,
260+
filter: filter,
261+
resyncIntv: time.Duration(resync) * time.Second,
262+
excludedobj: excludedobj,
263+
excludedns: excludedns,
243264
}
244265
}
245266

246267
// NewController create a controller.Controller
247268
func (f *Factory) NewController(client cache.ListerWatcher, notifier event.Notifier, name string) Interface {
248-
return New(client, notifier, f.logger, name, f.filter, f.resyncIntv, f.excluded)
269+
return New(client, notifier, f.logger, name, f.filter, f.resyncIntv, f.excludedobj, f.excludedns)
249270
}

pkg/controller/controller_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func TestController(t *testing.T) {
121121

122122
evt := new(mockNotifier)
123123
log := new(mockLog)
124-
f := NewFactory(log, "label1=something", 60, []string{"pod:ns3/Bar3"})
124+
f := NewFactory(log, "label1=something", 60, []string{"pod:ns3/Bar3"}, []string{})
125125
ctrl := f.NewController(client, evt, "pod")
126126

127127
// this will trigger a deletion event

0 commit comments

Comments
 (0)