Check non default services in the default namespace.

varsha/versions
Varsha Varadarajan 2019-06-13 13:06:23 -04:00
parent fee585542d
commit c9c34c2fee
1 changed files with 144 additions and 51 deletions

View File

@ -2,12 +2,13 @@ package basic
import ( import (
"fmt" "fmt"
"strings"
"sync" "sync"
"github.com/digitalocean/clusterlint/checks" "github.com/digitalocean/clusterlint/checks"
"github.com/digitalocean/clusterlint/kube" "github.com/digitalocean/clusterlint/kube"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"k8s.io/apimachinery/pkg/runtime" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
func init() { func init() {
@ -32,21 +33,12 @@ func (nc *check) Description() string {
return "Checks if there are any user created k8s objects in the default namespace." return "Checks if there are any user created k8s objects in the default namespace."
} }
func foo(name string, obj runtime.Object, w []error, e []error, mu *sync.Mutex) error { func checkNamespace(k8stype string, item metav1.ObjectMeta, w *[]error, mu *sync.Mutex) {
var r errgroup.Group if "default" == item.GetNamespace() {
for _, objects := range obj { mu.Lock()
objects := objects *w = append(*w, fmt.Errorf("%s '%s' is in the default namespace", k8stype, item.GetName()))
r.Go(func() error { mu.Unlock()
if "default" == objects.GetNamespace() {
mu.Lock()
w = append(w, fmt.Errorf("Pod '%s' is in the default namespace", objects.GetName()))
mu.Unlock()
}
return nil
})
} }
err1 := r.Wait()
return err1
} }
// Run runs this check on a set of Kubernetes objects. It can return warnings // Run runs this check on a set of Kubernetes objects. It can return warnings
@ -55,22 +47,91 @@ func foo(name string, obj runtime.Object, w []error, e []error, mu *sync.Mutex)
func (nc *check) Run(objects *kube.Objects) (warnings []error, errors []error, err error) { func (nc *check) Run(objects *kube.Objects) (warnings []error, errors []error, err error) {
var w, e []error var w, e []error
var g errgroup.Group var g errgroup.Group
var mu sync.Mutex var mu sync.Mutex
g.Go(func() (err error) { g.Go(func() (err error) {
foo("Pod", objects.Pods.Items, w, e, &mu) var r errgroup.Group
return nil for _, pod := range objects.Pods.Items {
pod := pod
r.Go(func() error {
checkNamespace("Pod", pod.ObjectMeta, &w, &mu)
return nil
})
}
err1 := r.Wait()
return err1
}) })
g.Go(func() (err error) { g.Go(func() (err error) {
var r errgroup.Group var r errgroup.Group
for _, podTemplate := range objects.PodTemplates.Items { for _, podTemplate := range objects.PodTemplates.Items {
podTemplate := podTemplate podTemplate := podTemplate
r.Go(func() error { r.Go(func() error {
if "default" == podTemplate.GetNamespace() { checkNamespace("Pod Template", podTemplate.ObjectMeta, &w, &mu)
mu.Lock() return nil
w = append(w, fmt.Errorf("Pod Template '%s' is in the default namespace", podTemplate.GetName())) })
mu.Unlock() }
err1 := r.Wait()
return err1
})
g.Go(func() (err error) {
var r errgroup.Group
for _, claim := range objects.PersistentVolumeClaims.Items {
claim := claim
r.Go(func() error {
checkNamespace("Persistent Volume Claim", claim.ObjectMeta, &w, &mu)
return nil
})
}
err1 := r.Wait()
return err1
})
g.Go(func() (err error) {
var r errgroup.Group
for _, configMap := range objects.ConfigMaps.Items {
configMap := configMap
r.Go(func() error {
checkNamespace("Config Map", configMap.ObjectMeta, &w, &mu)
return nil
})
}
err1 := r.Wait()
return err1
})
g.Go(func() (err error) {
var r errgroup.Group
for _, quota := range objects.ResourceQuotas.Items {
quota := quota
r.Go(func() error {
checkNamespace("Resource quota", quota.ObjectMeta, &w, &mu)
return nil
})
}
err1 := r.Wait()
return err1
})
g.Go(func() (err error) {
var r errgroup.Group
for _, limit := range objects.LimitRanges.Items {
limit := limit
r.Go(func() error {
checkNamespace("Limit Range", limit.ObjectMeta, &w, &mu)
return nil
})
}
err1 := r.Wait()
return err1
})
g.Go(func() (err error) {
var r errgroup.Group
var services []string
var serviceMu sync.Mutex
for _, service := range objects.Services.Items {
service := service
r.Go(func() error {
if "default" == service.GetNamespace() {
serviceMu.Lock()
services = append(services, service.GetName())
serviceMu.Unlock()
} }
return nil return nil
}) })
@ -79,36 +140,68 @@ func (nc *check) Run(objects *kube.Objects) (warnings []error, errors []error, e
if err1 != nil { if err1 != nil {
return err1 return err1
} }
if len(services) > 1 {
mu.Lock()
w = append(w, fmt.Errorf("There are non-default secrets defined in the default namespace: %s.", strings.Join(services, ",")))
mu.Unlock()
}
return nil
})
g.Go(func() (err error) {
var r errgroup.Group
var secrets []string
var secretMu sync.Mutex
for _, secret := range objects.Secrets.Items {
secret := secret
r.Go(func() error {
if "default" == secret.GetNamespace() {
secretMu.Lock()
secrets = append(secrets, secret.GetName())
secretMu.Unlock()
}
return nil
})
}
err1 := r.Wait()
if err1 != nil {
return err1
}
if len(secrets) > 1 {
mu.Lock()
w = append(w, fmt.Errorf("There are non-default secrets defined in the default namespace: %s.", strings.Join(secrets, ",")))
mu.Unlock()
}
return nil
})
g.Go(func() (err error) {
var r errgroup.Group
var sas []string
var saMu sync.Mutex
for _, sa := range objects.ServiceAccounts.Items {
sa := sa
r.Go(func() error {
if "default" == sa.GetNamespace() {
saMu.Lock()
sas = append(sas, sa.GetName())
saMu.Unlock()
}
return nil
})
}
err1 := r.Wait()
if err1 != nil {
return err1
}
if len(sas) > 1 {
mu.Lock()
w = append(w, fmt.Errorf("There are non-default service accounts defined in the default namespace: %s.", strings.Join(sas, ",")))
mu.Unlock()
}
return nil return nil
}) })
// g.Go(func() (err error) {
// objects.PersistentVolumeClaims, err = client.PersistentVolumeClaims(all).List(opts)
// return
// })
// g.Go(func() (err error) {
// objects.ConfigMaps, err = client.ConfigMaps(all).List(opts)
// return
// })
// g.Go(func() (err error) {
// objects.Secrets, err = client.Secrets(all).List(opts)
// return
// })
// g.Go(func() (err error) {
// objects.Services, err = client.Services(all).List(opts)
// return
// })
// g.Go(func() (err error) {
// objects.ServiceAccounts, err = client.ServiceAccounts(all).List(opts)
// return
// })
// g.Go(func() (err error) {
// objects.ResourceQuotas, err = client.ResourceQuotas(all).List(opts)
// return
// })
// g.Go(func() (err error) {
// objects.LimitRanges, err = client.LimitRanges(all).List(opts)
// return
// })
err2 := g.Wait() err2 := g.Wait()
return w, e, err2 return w, e, err2