Check non default services in the default namespace.
parent
fee585542d
commit
c9c34c2fee
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue