Skip to content

Commit 8b60bc0

Browse files
Merge pull request #42 from AthenZ/exclude-list
Support exclusion list to ignore namespaces
2 parents cf172b2 + d8e8d5b commit 8b60bc0

File tree

7 files changed

+141
-16
lines changed

7 files changed

+141
-16
lines changed

main.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ func main() {
125125
secretName := flag.String("secret-name", "k8s-athenz-syncer", "secret name that contains private key")
126126
header := flag.String("auth-header", "", "Authentication header field")
127127
nTokenExpireTime := flag.String("ntoken-expiry", "1h0m0s", "Custom nToken expiration duration")
128+
excludeNamespaces := flag.String("exclude-namespaces", "", "Namespaces to exclude from processing ex: 'kube-system,kube-public,acceptance-test'")
128129

129130
klog.InitFlags(nil)
130131
flag.Set("logtostderr", "false")
@@ -190,7 +191,17 @@ func main() {
190191
processList = append(processList, item)
191192
}
192193
}
193-
util := util.NewUtil(*adminDomain, processList)
194+
195+
// process skip namespaces input string
196+
excludeNSList := strings.Split(*excludeNamespaces, ",")
197+
exclusionList := []string{}
198+
for _, item := range excludeNSList {
199+
item := strings.TrimSpace(item)
200+
if item != "" {
201+
exclusionList = append(exclusionList, item)
202+
}
203+
}
204+
util := util.NewUtil(*adminDomain, processList, exclusionList)
194205

195206
// construct the Controller object which has all of the necessary components to
196207
// handle logging, connections, informing (listing and watching), the queue,

pkg/controller/controller.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
66
You may obtain a copy of the License at
77
8-
http://www.apache.org/licenses/LICENSE-2.0
8+
http://www.apache.org/licenses/LICENSE-2.0
99
1010
Unless required by applicable law or agreed to in writing, software
1111
distributed under the License is distributed on an "AS IS" BASIS,
@@ -122,6 +122,10 @@ func (c *Controller) nsinformerhandler(fn cache.KeyFunc, obj interface{}) string
122122
log.Errorf("Error returned from Key Func in nsInformerHandler. Error: %v", err)
123123
return ""
124124
}
125+
if c.util.IsNamespaceExcluded(key) {
126+
log.Infof("Skip processing excluded namespace: %s", key)
127+
return key
128+
}
125129
domain := c.util.NamespaceToDomain(key)
126130
c.queue.AddRateLimited(domain)
127131
return key

pkg/controller/controller_test.go

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
66
You may obtain a copy of the License at
77
8-
http://www.apache.org/licenses/LICENSE-2.0
8+
http://www.apache.org/licenses/LICENSE-2.0
99
1010
Unless required by applicable law or agreed to in writing, software
1111
distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,6 +19,7 @@ import (
1919
"context"
2020
"crypto/tls"
2121
"encoding/json"
22+
"fmt"
2223
"net"
2324
"net/http"
2425
"net/http/httptest"
@@ -30,10 +31,12 @@ import (
3031
athenz_domain "github.com/AthenZ/k8s-athenz-syncer/pkg/apis/athenz/v1"
3132
"github.com/AthenZ/k8s-athenz-syncer/pkg/client/clientset/versioned/fake"
3233
"github.com/AthenZ/k8s-athenz-syncer/pkg/cron"
34+
"github.com/AthenZ/k8s-athenz-syncer/pkg/log"
3335
"github.com/AthenZ/k8s-athenz-syncer/pkg/util"
3436
"github.com/ardielle/ardielle-go/rdl"
3537
"github.com/google/go-cmp/cmp"
3638
k8sfake "k8s.io/client-go/kubernetes/fake"
39+
"k8s.io/client-go/util/workqueue"
3740
)
3841

3942
const (
@@ -45,7 +48,7 @@ func newController() *Controller {
4548
athenzclientset := fake.NewSimpleClientset()
4649
clientset := k8sfake.NewSimpleClientset()
4750
zmsclient := zms.NewClient("https://zms.athenz.com", &http.Transport{})
48-
util := util.NewUtil("admin.domain", []string{"kube-system", "kube-public", "kube-test"})
51+
util := util.NewUtil("admin.domain", []string{"kube-system", "kube-public", "kube-test"}, []string{"acceptance-test"})
4952
cm := &cron.AthenzContactTimeConfigMap{
5053
Namespace: "kube-yahoo",
5154
Name: "athenzcall-config",
@@ -161,7 +164,7 @@ func TestDeepCopy(t *testing.T) {
161164
}
162165
}
163166

164-
//TestZmsGetSignedDomains - test zms API call to get signed domains
167+
// TestZmsGetSignedDomains - test zms API call to get signed domains
165168
func TestZmsGetSignedDomains(t *testing.T) {
166169
d := getFakeDomain()
167170
signedDomain := zms.SignedDomains{
@@ -204,3 +207,76 @@ func testingHTTPClient(handler http.Handler) (*http.Client, func()) {
204207

205208
return cli, s.Close
206209
}
210+
func TestNsinformerhandler(t *testing.T) {
211+
log.InitLogger("/tmp/log/test.log", "info")
212+
213+
tests := []struct {
214+
name string
215+
keyFunc func(obj interface{}) (string, error)
216+
excludedNS []string
217+
expectedResult string
218+
expectedQueueLen int
219+
shouldAddToQueue bool
220+
}{
221+
{
222+
name: "Error from key function",
223+
keyFunc: func(obj interface{}) (string, error) {
224+
return "", fmt.Errorf("mock key function error")
225+
},
226+
excludedNS: []string{},
227+
expectedResult: "",
228+
expectedQueueLen: 0,
229+
shouldAddToQueue: false,
230+
},
231+
{
232+
name: "Excluded namespace",
233+
keyFunc: func(obj interface{}) (string, error) {
234+
return "test-excluded", nil
235+
},
236+
excludedNS: []string{"test-excluded"},
237+
expectedResult: "test-excluded",
238+
expectedQueueLen: 0,
239+
shouldAddToQueue: false,
240+
},
241+
{
242+
name: "Non-excluded namespace gets added to queue",
243+
keyFunc: func(obj interface{}) (string, error) {
244+
return "test-namespace", nil
245+
},
246+
excludedNS: []string{},
247+
expectedResult: "test-namespace",
248+
expectedQueueLen: 1,
249+
shouldAddToQueue: true,
250+
},
251+
}
252+
253+
for _, tt := range tests {
254+
t.Run(tt.name, func(t *testing.T) {
255+
c := newController()
256+
c.util = util.NewUtil("admin.domain", []string{"kube-system"}, tt.excludedNS)
257+
mockQueue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
258+
c.queue = mockQueue
259+
260+
result := c.nsinformerhandler(tt.keyFunc, &athenz_domain.AthenzDomain{})
261+
262+
if result != tt.expectedResult {
263+
t.Errorf("Expected result '%s', got: '%s'", tt.expectedResult, result)
264+
}
265+
266+
// Sleep to allow item to be queued
267+
time.Sleep(2 * time.Second)
268+
269+
if mockQueue.Len() != tt.expectedQueueLen {
270+
t.Errorf("Expected queue length to be %d, got %d", tt.expectedQueueLen, mockQueue.Len())
271+
}
272+
273+
if tt.shouldAddToQueue && mockQueue.Len() > 0 {
274+
expectedDomain := c.util.NamespaceToDomain(tt.expectedResult)
275+
item, _ := mockQueue.Get()
276+
if item != expectedDomain {
277+
t.Errorf("Expected %s in queue, got %s", expectedDomain, item)
278+
}
279+
}
280+
})
281+
}
282+
}

pkg/cron/cron.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
66
You may obtain a copy of the License at
77
8-
http://www.apache.org/licenses/LICENSE-2.0
8+
http://www.apache.org/licenses/LICENSE-2.0
99
1010
Unless required by applicable law or agreed to in writing, software
1111
distributed under the License is distributed on an "AS IS" BASIS,
@@ -150,6 +150,10 @@ func (c *Cron) FullResync(stopCh <-chan struct{}) {
150150
log.Error("Error occurred when casting namespace into string")
151151
continue
152152
}
153+
if c.util.IsNamespaceExcluded(namespace.ObjectMeta.Name) {
154+
log.Infof("Skip processing excluded namespace: %s", namespace.ObjectMeta.Name)
155+
continue
156+
}
153157
domainName := c.util.NamespaceToDomain(namespace.ObjectMeta.Name)
154158
c.queue.AddRateLimited(domainName)
155159
}

pkg/cron/cron_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
66
You may obtain a copy of the License at
77
8-
http://www.apache.org/licenses/LICENSE-2.0
8+
http://www.apache.org/licenses/LICENSE-2.0
99
1010
Unless required by applicable law or agreed to in writing, software
1111
distributed under the License is distributed on an "AS IS" BASIS,
@@ -48,7 +48,7 @@ func newCron() *Cron {
4848
clientset := k8sfake.NewSimpleClientset()
4949
rateLimiter := ratelimiter.NewRateLimiter(250 * time.Millisecond)
5050
queue := workqueue.NewRateLimitingQueue(rateLimiter)
51-
util := util.NewUtil("test.domain", []string{"kube-system"})
51+
util := util.NewUtil("test.domain", []string{"kube-system"}, []string{"acceptance-test"})
5252
athenzclientset := fake.NewSimpleClientset()
5353
informer := athenzInformer.NewAthenzDomainInformer(athenzclientset, 0, cache.Indexers{
5454
"trustDomain": cr.TrustDomainIndexFunc,

pkg/util/util.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
66
You may obtain a copy of the License at
77
8-
http://www.apache.org/licenses/LICENSE-2.0
8+
http://www.apache.org/licenses/LICENSE-2.0
99
1010
Unless required by applicable law or agreed to in writing, software
1111
distributed under the License is distributed on an "AS IS" BASIS,
@@ -23,15 +23,22 @@ import (
2323

2424
// Util - struct with 2 fields adminDomain and list of system namespaces
2525
type Util struct {
26-
adminDomain string
27-
systemNamespaces []string
26+
adminDomain string
27+
systemNamespaces []string
28+
excludeNamespaces map[string]bool
2829
}
2930

3031
// NewUtil - create new Util object
31-
func NewUtil(adminDomain string, systemNamespaces []string) *Util {
32+
func NewUtil(adminDomain string, systemNamespaces []string, excludeNamespaces []string) *Util {
33+
excludedNamespaceMap := make(map[string]bool)
34+
for _, ns := range excludeNamespaces {
35+
excludedNamespaceMap[ns] = true
36+
}
37+
3238
return &Util{
33-
adminDomain: adminDomain,
34-
systemNamespaces: systemNamespaces,
39+
adminDomain: adminDomain,
40+
systemNamespaces: systemNamespaces,
41+
excludeNamespaces: excludedNamespaceMap,
3542
}
3643
}
3744

@@ -78,6 +85,14 @@ func (u *Util) IsSystemDomain(domain string) bool {
7885
return false
7986
}
8087

88+
// IsNamespaceExcluded - check if the current namespace is in the skip namespaces list
89+
func (u *Util) IsNamespaceExcluded(ns string) bool {
90+
if _, ok := u.excludeNamespaces[ns]; ok {
91+
return true
92+
}
93+
return false
94+
}
95+
8196
// IsAdminDomain - check if domain is admin domain
8297
func (u *Util) IsAdminDomain(domain string) bool {
8398
if domain == u.adminDomain {

pkg/util/util_test.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
66
You may obtain a copy of the License at
77
8-
http://www.apache.org/licenses/LICENSE-2.0
8+
http://www.apache.org/licenses/LICENSE-2.0
99
1010
Unless required by applicable law or agreed to in writing, software
1111
distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,7 +20,7 @@ import (
2020
)
2121

2222
func newUtil() *Util {
23-
return NewUtil("admin.domain", []string{"kube-system", "kube-public", "kube-test"})
23+
return NewUtil("admin.domain", []string{"kube-system", "kube-public", "kube-test"}, []string{"acceptance-test"})
2424
}
2525

2626
// TestNamespaceConversion - test conversion function
@@ -113,3 +113,18 @@ func TestGetSystemNSDomains(t *testing.T) {
113113
}
114114
}
115115
}
116+
117+
// TestIsNamespaceExcluded - test whether certain namespace is in the skip namespaces list
118+
func TestIsNamespaceExcluded(t *testing.T) {
119+
u := newUtil()
120+
test1 := "acceptance-test"
121+
result1 := u.IsNamespaceExcluded(test1)
122+
if !result1 {
123+
t.Error("test1 failed. acceptance-test is in the skip namespaces list!")
124+
}
125+
test2 := "kube-system"
126+
result2 := u.IsNamespaceExcluded(test2)
127+
if result2 {
128+
t.Error("test2 failed. kube-system is not in the skip namespaces list!")
129+
}
130+
}

0 commit comments

Comments
 (0)