...
1
16
17 package systemnamespaces
18
19 import (
20 "context"
21 "fmt"
22 "time"
23
24 v1 "k8s.io/api/core/v1"
25 "k8s.io/apimachinery/pkg/api/errors"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
28 "k8s.io/apimachinery/pkg/util/wait"
29 coreinformers "k8s.io/client-go/informers/core/v1"
30 "k8s.io/client-go/kubernetes"
31 listers "k8s.io/client-go/listers/core/v1"
32 "k8s.io/client-go/tools/cache"
33
34 "k8s.io/klog/v2"
35 )
36
37
38 type Controller struct {
39 client kubernetes.Interface
40
41 namespaceLister listers.NamespaceLister
42 namespaceSynced cache.InformerSynced
43
44 systemNamespaces []string
45 interval time.Duration
46 }
47
48
49 func NewController(clientset kubernetes.Interface, namespaceInformer coreinformers.NamespaceInformer) *Controller {
50 systemNamespaces := []string{metav1.NamespaceSystem, metav1.NamespacePublic, v1.NamespaceNodeLease, metav1.NamespaceDefault}
51 interval := 1 * time.Minute
52
53 return &Controller{
54 client: clientset,
55 namespaceLister: namespaceInformer.Lister(),
56 namespaceSynced: namespaceInformer.Informer().HasSynced,
57 systemNamespaces: systemNamespaces,
58 interval: interval,
59 }
60 }
61
62
63 func (c *Controller) Run(stopCh <-chan struct{}) {
64 defer utilruntime.HandleCrash()
65 defer klog.Infof("Shutting down system namespaces controller")
66
67 klog.Infof("Starting system namespaces controller")
68
69 if !cache.WaitForCacheSync(stopCh, c.namespaceSynced) {
70 utilruntime.HandleError(fmt.Errorf("timed out waiting for caches to sync"))
71 return
72 }
73
74 go wait.Until(c.sync, c.interval, stopCh)
75
76 <-stopCh
77 }
78
79 func (c *Controller) sync() {
80
81 for _, ns := range c.systemNamespaces {
82 if err := c.createNamespaceIfNeeded(ns); err != nil {
83 utilruntime.HandleError(fmt.Errorf("unable to create required kubernetes system Namespace %s: %v", ns, err))
84 }
85 }
86 }
87
88 func (c *Controller) createNamespaceIfNeeded(ns string) error {
89 if _, err := c.namespaceLister.Get(ns); err == nil {
90
91 return nil
92 }
93 newNs := &v1.Namespace{
94 ObjectMeta: metav1.ObjectMeta{
95 Name: ns,
96 Namespace: "",
97 },
98 }
99 _, err := c.client.CoreV1().Namespaces().Create(context.TODO(), newNs, metav1.CreateOptions{})
100 if err != nil && errors.IsAlreadyExists(err) {
101 err = nil
102 }
103 return err
104 }
105
View as plain text