gopa
gopa

Reputation: 73

Kubernetes: need notification if a new namespace is created

So Kubernetes events seems to have options for watch for all kinds of things like pod up/down creation/deletion etc.. - but I want to watch for a namespace creation/deletion itself - and I can't find an option to do that.

I want to know if someone created a namespace or deleted one. Is this possible?

Rgds, Gopa.

Upvotes: 0

Views: 946

Answers (3)

gopa
gopa

Reputation: 73

So I got it working, pasting the entire code below for anyone's future reference

package main

import (
    "os"
    "os/exec"
    "os/signal"
    "strings"
    "syscall"
    "time"

    "github.com/golang/glog"
    v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/runtime"
    "k8s.io/client-go/informers"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/cache"
    "k8s.io/client-go/tools/clientcmd"
)

func newNamespace(obj interface{}) {
    ns := obj.(v1.Object)
    glog.Error("New Namespace ", ns.GetName())
}

func modNamespace(objOld interface{}, objNew interface{}) {
}

func delNamespace(obj interface{}) {
    ns := obj.(v1.Object)
    glog.Error("Del Namespace ", ns.GetName())
}

func watchNamespace(k8s *kubernetes.Clientset) {
    // Add watcher for the Namespace.
    factory := informers.NewSharedInformerFactory(k8s, 5*time.Second)
    nsInformer := factory.Core().V1().Namespaces().Informer()
    nsInformerChan := make(chan struct{})
    //defer close(nsInformerChan)
    defer runtime.HandleCrash()

    // Namespace informer state change handler
    nsInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
        // When a new namespace gets created
        AddFunc: func(obj interface{}) {
            newNamespace(obj)
        },
        // When a namespace gets updated
        UpdateFunc: func(oldObj interface{}, newObj interface{}) {
            modNamespace(oldObj, newObj)
        },
        // When a namespace gets deleted
        DeleteFunc: func(obj interface{}) {
            delNamespace(obj)
        },
    })
    factory.Start(nsInformerChan)
    //go nsInformer.GetController().Run(nsInformerChan)
    go nsInformer.Run(nsInformerChan)
}

func main() {
    kconfig := os.Getenv("KUBECONFIG")
    glog.Error("KCONFIG", kconfig)
    var config *rest.Config
    var clientset *kubernetes.Clientset
    var err error
    for {
        if config == nil {
            config, err = clientcmd.BuildConfigFromFlags("", kconfig)
            if err != nil {
                glog.Error("Cant create  kubernetes config")
                time.Sleep(time.Second)
                continue
            }
        }
        // creates the clientset
        clientset, err = kubernetes.NewForConfig(config)
        if err != nil {
            glog.Error("Cannot create kubernetes client")
            time.Sleep(time.Second)
            continue
        }
        break
    }
    watchNamespace(clientset)
    glog.Error("Watch started")

    term := make(chan os.Signal, 1)
    signal.Notify(term, os.Interrupt)
    signal.Notify(term, syscall.SIGTERM)
    select {
    case <-term:
    }
}

Upvotes: 2

BogdanL
BogdanL

Reputation: 691

$ kubectl get ns --watch-only
# run "kubectl create ns test" from another terminal
test   Active   0s
# run "kubectl delete ns test"
test   Terminating   23s
test   Terminating   28s
test   Terminating   28s

Upvotes: 0

P....
P....

Reputation: 18381

Events are namespaced, they show the events happening in a particular namespace. However -A|--all-namespaces would show events from all the namespaces.

If you want to track the lifecycle(creation|deletion|etc) of the namespaces,then audit.logs are simplest option if not the only option.

Example: Creation of namespace called my-ns:

kubectl create  ns my-ns
kubectl get events -n my-ns 
No resources found in my-ns namespace.

kubectl describe ns my-ns   
Name:         my-ns
Labels:       <none>
Annotations:  <none>
Status:       Active

No resource quota.

No LimitRange resource.

Now Here is the output of audit.log at metadata level, this would tell the following:

  1. who created
  2. what created
  3. when created
  4. and lot more.

Example output:

{
   "kind":"Event",
   "apiVersion":"audit.k8s.io/v1",
   "level":"Metadata",
   "auditID":"d28619be-0cb7-4d3e-b195-51fb93ae6de4",
   "stage":"ResponseComplete",
   "requestURI":"/api/v1/namespaces?fieldManager=kubectl-create",
   "verb":"create", #<------operation type
   "user":{
      "username":"kubernetes-admin", #<--------who created
      "groups":[
         "system:masters",
         "system:authenticated"
      ]
   },
   "sourceIPs":[
      "1.2.3.4"
   ],
   "userAgent":"kubectl/v1.20.0 (linux/amd64) kubernetes/af46c47",
   "objectRef":{
      "resource":"namespaces", #<---what created
      "name":"my-ns", #<---name of resource
      "apiVersion":"v1"
   },
   "responseStatus":{
      "metadata":{
         
      },
      "code":201
   },
   "requestReceivedTimestamp":"2021-09-24T16:44:28.094213Z", #<---when created.
   "stageTimestamp":"2021-09-24T16:44:28.270294Z",
   "annotations":{
      "authorization.k8s.io/decision":"allow",
      "authorization.k8s.io/reason":""
   }
}

Upvotes: 1

Related Questions