From 0d6900b110161d93625ba4fc6ac8fe7f0e8fe781 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Wed, 16 Oct 2019 20:02:58 +0200 Subject: [PATCH] Handle the case when listing namespaces is forbidden (#42) * Handle the case when listing namespaces is forbidden Ignore a forbidden error as that means we can connect to the api server Do not try to watch at cluster level when we only need one namespace Fixes #12 * Use the namespace if set for deployments, daemonsets,... * If we can't get the namespace then revert to watch all to keep existing behavior if the namespace does not exist we watch namespaces to wait for it --- cmd/kail/main.go | 5 ++++- ds_builder.go | 29 +++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/cmd/kail/main.go b/cmd/kail/main.go index 878814e..3bc4f15 100644 --- a/cmd/kail/main.go +++ b/cmd/kail/main.go @@ -15,6 +15,7 @@ import ( "github.com/boz/kcache/nsname" "github.com/sirupsen/logrus" kingpin "gopkg.in/alecthomas/kingpin.v2" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/kubernetes" @@ -194,7 +195,9 @@ func createKubeClient() (kubernetes.Interface, *rest.Config) { kingpin.FatalIfError(err, "Error building kubernetes config") _, err = cs.CoreV1().Namespaces().List(metav1.ListOptions{}) - kingpin.FatalIfError(err, "Can't connnect to kubernetes") + if err != nil && !apierrors.IsForbidden(err) { + kingpin.FatalIfError(err, "Can't connnect to kubernetes") + } return cs, rc } diff --git a/ds_builder.go b/ds_builder.go index 5c0f943..b417e8f 100644 --- a/ds_builder.go +++ b/ds_builder.go @@ -14,6 +14,7 @@ import ( "github.com/boz/kcache/types/replicaset" "github.com/boz/kcache/types/replicationcontroller" "github.com/boz/kcache/types/service" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/kubernetes" ) @@ -125,7 +126,19 @@ func (b *dsBuilder) Create(ctx context.Context, cs kubernetes.Interface) (DS, er log = log.WithComponent("kail.ds.builder") - base, err := pod.NewController(ctx, log, cs, "") + namespace := "" + // if we only ask for one namespace do not try to get resources at cluster level + // we may not have permissions + // but if the namespace does not exist (or any other problem) we watch namespaces to wait for it + if len(b.namespaces) == 1 { + namespace = b.namespaces[0] + _, err := cs.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) + if err != nil { + log.Warnf("could not tail the namespace %s: %v", namespace, err) + namespace = "" + } + } + base, err := pod.NewController(ctx, log, cs, namespace) if err != nil { return nil, log.Err(err, "base pod controller") } @@ -209,7 +222,7 @@ func (b *dsBuilder) Create(ctx context.Context, cs kubernetes.Interface) (DS, er } if len(b.services) != 0 { - ds.servicesBase, err = service.NewController(ctx, log, cs, "") + ds.servicesBase, err = service.NewController(ctx, log, cs, namespace) if err != nil { ds.closeAll() return nil, log.Err(err, "service base controller") @@ -229,7 +242,7 @@ func (b *dsBuilder) Create(ctx context.Context, cs kubernetes.Interface) (DS, er } if len(b.rcs) != 0 { - ds.rcsBase, err = replicationcontroller.NewController(ctx, log, cs, "") + ds.rcsBase, err = replicationcontroller.NewController(ctx, log, cs, namespace) if err != nil { ds.closeAll() return nil, log.Err(err, "rc base controller") @@ -249,7 +262,7 @@ func (b *dsBuilder) Create(ctx context.Context, cs kubernetes.Interface) (DS, er } if len(b.rss) != 0 { - ds.rssBase, err = replicaset.NewController(ctx, log, cs, "") + ds.rssBase, err = replicaset.NewController(ctx, log, cs, namespace) if err != nil { ds.closeAll() return nil, log.Err(err, "rs base controller") @@ -269,7 +282,7 @@ func (b *dsBuilder) Create(ctx context.Context, cs kubernetes.Interface) (DS, er } if len(b.dss) != 0 { - ds.dssBase, err = daemonset.NewController(ctx, log, cs, "") + ds.dssBase, err = daemonset.NewController(ctx, log, cs, namespace) if err != nil { ds.closeAll() return nil, log.Err(err, "ds base controller") @@ -289,7 +302,7 @@ func (b *dsBuilder) Create(ctx context.Context, cs kubernetes.Interface) (DS, er } if len(b.deployments) != 0 { - ds.deploymentsBase, err = deployment.NewController(ctx, log, cs, "") + ds.deploymentsBase, err = deployment.NewController(ctx, log, cs, namespace) if err != nil { ds.closeAll() return nil, log.Err(err, "deployment base controller") @@ -309,14 +322,14 @@ func (b *dsBuilder) Create(ctx context.Context, cs kubernetes.Interface) (DS, er } if len(b.ingresses) != 0 { - ds.ingressesBase, err = ingress.NewController(ctx, log, cs, "") + ds.ingressesBase, err = ingress.NewController(ctx, log, cs, namespace) if err != nil { ds.closeAll() return nil, log.Err(err, "ingress base controller") } if ds.servicesBase == nil { - ds.servicesBase, err = service.NewController(ctx, log, cs, "") + ds.servicesBase, err = service.NewController(ctx, log, cs, namespace) if err != nil { ds.closeAll() return nil, log.Err(err, "service base controller")