Fix tests

This commit is contained in:
Bader Boland
2020-03-17 09:19:33 -04:00
parent 0d3fe6130a
commit 7fdebfc4db
18 changed files with 58 additions and 135 deletions

View File

@@ -43,6 +43,10 @@
<span>Pods:</span>
<strong>{{.AuditData.ClusterInfo.Pods}}</strong>
</span>
<span class="kubernetes-stat">
<span>Controllers:</span>
<strong>{{.AuditData.ClusterInfo.Controllers}}</strong>
</span>
<span class="kubernetes-stat">
<span>Namespaces:</span>
<strong>{{.AuditData.ClusterInfo.Namespaces}}</strong>

View File

@@ -21,7 +21,6 @@ import (
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth" // Required for other auth providers like GKE.
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
"sigs.k8s.io/controller-runtime/pkg/client/config"
)
@@ -120,11 +119,16 @@ func CreateResourceProviderFromCluster() (*ResourceProvider, error) {
logrus.Errorf("Error creating Kubernetes client: %v", err)
return nil, err
}
return CreateResourceProviderFromAPI(api, kubeConf.Host, kubeConf)
dynamicInterface, err := dynamic.NewForConfig(kubeConf)
if err != nil {
logrus.Errorf("Error connecting to dynamic interface: %v", err)
return nil, err
}
return CreateResourceProviderFromAPI(api, kubeConf.Host, &dynamicInterface)
}
// CreateResourceProviderFromAPI creates a new ResourceProvider from an existing k8s interface
func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string, kubeConf *rest.Config) (*ResourceProvider, error) {
func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string, dynamic *dynamic.Interface) (*ResourceProvider, error) {
listOpts := metav1.ListOptions{}
serverVersion, err := kube.Discovery().ServerVersion()
if err != nil {
@@ -151,11 +155,7 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string
logrus.Errorf("Error fetching Pods: %v", err)
return nil, err
}
dynamicInterface, err := dynamic.NewForConfig(kubeConf)
if err != nil {
logrus.Errorf("Error connecting to dynamic interface: %v", err)
return nil, err
}
resources, err := restmapper.GetAPIGroupResources(kube.Discovery())
if err != nil {
logrus.Errorf("Error getting API Group resources: %v", err)
@@ -172,7 +172,7 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string
Nodes: nodes.Items,
Namespaces: namespaces.Items,
Pods: pods.Items,
DynamicClient: &dynamicInterface,
DynamicClient: dynamic,
RestMapper: &restMapper,
}
return &api, nil

View File

@@ -62,7 +62,7 @@ func TestGetMultipleResourceFromBadFile(t *testing.T) {
func TestGetResourceFromAPI(t *testing.T) {
k8s := test.SetupTestAPI()
k8s = test.SetupAddControllers(k8s, "test")
resources, err := CreateResourceProviderFromAPI(k8s, "test")
resources, err := CreateResourceProviderFromAPI(k8s, "test", nil)
assert.Equal(t, nil, err, "Error should be nil")
assert.Equal(t, "Cluster", resources.SourceType, "Should have type Path")
@@ -70,9 +70,6 @@ func TestGetResourceFromAPI(t *testing.T) {
assert.IsType(t, time.Now(), resources.CreationTime, "Creation time should be set")
assert.Equal(t, 0, len(resources.Nodes), "Should not have any nodes")
assert.Equal(t, 1, len(resources.Deployments), "Should have a deployment")
assert.Equal(t, 1, len(resources.StatefulSets), "Should have a stateful set")
assert.Equal(t, 0, len(resources.Pods), "Should have a pod")
assert.Equal(t, "", resources.Deployments[0].ObjectMeta.Name)
}

View File

@@ -103,11 +103,9 @@ func deduplicateControllers(controllerResults []ControllerResult) []ControllerRe
// builds a list of ResourceResults organized by namespace.
func ValidateControllers(config *conf.Configuration, kubeResources *kube.ResourceProvider) ([]ControllerResult, error) {
var controllersToAudit []controller.Interface
loadedControllers, err := controllers.LoadControllersByKind(conf.NakedPods, kubeResources)
if err != nil {
logrus.Warn(err)
}
loadedControllers := controllers.LoadControllers(kubeResources)
controllersToAudit = append(controllersToAudit, loadedControllers...)
results := []ControllerResult{}
for _, controller := range controllersToAudit {
if !config.DisallowExemptions && hasExemptionAnnotation(controller) {
@@ -115,10 +113,12 @@ func ValidateControllers(config *conf.Configuration, kubeResources *kube.Resourc
}
result, err := ValidateController(config, controller, kubeResources)
if err != nil {
logrus.Warn("An error occured validating controller:", err)
return nil, err
}
results = append(results, result)
}
return deduplicateControllers(results), nil
}

View File

@@ -18,7 +18,6 @@ import (
"testing"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
conf "github.com/fairwindsops/polaris/pkg/config"
@@ -46,7 +45,7 @@ func TestValidateController(t *testing.T) {
"hostPIDSet": {ID: "hostPIDSet", Message: "Host PID is not configured", Success: true, Severity: "error", Category: "Security"},
}
actualResult, err := ValidateController(&c, deployment)
actualResult, err := ValidateController(&c, deployment, &kube.ResourceProvider{})
if err != nil {
panic(err)
}
@@ -84,7 +83,7 @@ func TestSkipHealthChecks(t *testing.T) {
"readinessProbeMissing": {ID: "readinessProbeMissing", Message: "Readiness probe should be configured", Success: false, Severity: "error", Category: "Health Checks"},
"livenessProbeMissing": {ID: "livenessProbeMissing", Message: "Liveness probe should be configured", Success: false, Severity: "warning", Category: "Health Checks"},
}
actualResult, err := ValidateController(&c, deployment)
actualResult, err := ValidateController(&c, deployment, &kube.ResourceProvider{})
if err != nil {
panic(err)
}
@@ -101,7 +100,7 @@ func TestSkipHealthChecks(t *testing.T) {
Errors: uint(0),
}
expectedResults = ResultSet{}
actualResult, err = ValidateController(&c, job)
actualResult, err = ValidateController(&c, job, &kube.ResourceProvider{})
if err != nil {
panic(err)
}
@@ -117,7 +116,7 @@ func TestSkipHealthChecks(t *testing.T) {
Errors: uint(0),
}
expectedResults = ResultSet{}
actualResult, err = ValidateController(&c, cronjob)
actualResult, err = ValidateController(&c, cronjob, &kube.ResourceProvider{})
if err != nil {
panic(err)
}
@@ -138,7 +137,7 @@ func TestControllerExemptions(t *testing.T) {
},
}
resources := &kube.ResourceProvider{
Deployments: []appsv1.Deployment{test.MockDeploy()},
Pods: []corev1.Pod{test.MockNakedPod()},
}
expectedSum := CountSummary{
@@ -151,10 +150,10 @@ func TestControllerExemptions(t *testing.T) {
panic(err)
}
assert.Equal(t, 1, len(actualResults))
assert.Equal(t, "Deployment", actualResults[0].Kind)
assert.Equal(t, "NakedPod", actualResults[0].Kind)
assert.EqualValues(t, expectedSum, actualResults[0].GetSummary())
resources.Deployments[0].ObjectMeta.Annotations = map[string]string{
resources.Pods[0].ObjectMeta.Annotations = map[string]string{
exemptionAnnotationKey: "true",
}
actualResults, err = ValidateControllers(&c, resources)

View File

@@ -13,11 +13,6 @@ type CronJobController struct {
K8SResource kubeAPIBatchV1beta1.CronJob
}
// GetPodTemplate returns the original template spec
func (c CronJobController) GetPodTemplate() *kubeAPICoreV1.PodTemplateSpec {
return &c.K8SResource.Spec.JobTemplate.Spec.Template
}
// GetPodSpec returns the original kubernetes template pod spec
func (c CronJobController) GetPodSpec() *kubeAPICoreV1.PodSpec {
return &c.K8SResource.Spec.JobTemplate.Spec.Template.Spec

View File

@@ -13,11 +13,6 @@ type DaemonSetController struct {
K8SResource kubeAPIAppsV1.DaemonSet
}
// GetPodTemplate returns the original template spec
func (d DaemonSetController) GetPodTemplate() *kubeAPICoreV1.PodTemplateSpec {
return &d.K8SResource.Spec.Template
}
// GetPodSpec returns the original kubernetes template pod spec
func (d DaemonSetController) GetPodSpec() *kubeAPICoreV1.PodSpec {
return &d.K8SResource.Spec.Template.Spec

View File

@@ -13,11 +13,6 @@ type DeploymentController struct {
K8SResource kubeAPIAppsV1.Deployment
}
// GetPodTemplate returns the original template spec
func (d DeploymentController) GetPodTemplate() *kubeAPICoreV1.PodTemplateSpec {
return &d.K8SResource.Spec.Template
}
// GetPodSpec returns the original kubernetes template pod spec
func (d DeploymentController) GetPodSpec() *kubeAPICoreV1.PodSpec {
return &d.K8SResource.Spec.Template.Spec

View File

@@ -1,8 +1,6 @@
package controllers
import (
"fmt"
"github.com/fairwindsops/polaris/pkg/config"
"github.com/fairwindsops/polaris/pkg/kube"
kubeAPICoreV1 "k8s.io/api/core/v1"
@@ -13,7 +11,6 @@ import (
type Interface interface {
GetName() string
GetNamespace() string
GetPodTemplate() *kubeAPICoreV1.PodTemplateSpec
GetPodSpec() *kubeAPICoreV1.PodSpec
GetKind() config.SupportedController
GetObjectMeta() kubeAPIMetaV1.ObjectMeta
@@ -35,41 +32,11 @@ func (g GenericController) GetNamespace() string {
return g.Namespace
}
// LoadControllersByKind loads a list of controllers from the kubeResources by detecting their type
func LoadControllersByKind(controllerKind config.SupportedController, kubeResources *kube.ResourceProvider) ([]Interface, error) {
// LoadControllers loads a list of controllers from the kubeResources Pods
func LoadControllers(kubeResources *kube.ResourceProvider) []Interface {
interfaces := []Interface{}
switch controllerKind {
case config.NakedPods:
for _, pod := range kubeResources.Pods {
interfaces = append(interfaces, NewNakedPodController(pod))
}
case config.Deployments:
for _, deploy := range kubeResources.Deployments {
interfaces = append(interfaces, NewDeploymentController(deploy))
}
case config.StatefulSets:
for _, statefulSet := range kubeResources.StatefulSets {
interfaces = append(interfaces, NewStatefulSetController(statefulSet))
}
case config.DaemonSets:
for _, daemonSet := range kubeResources.DaemonSets {
interfaces = append(interfaces, NewDaemonSetController(daemonSet))
}
case config.Jobs:
for _, job := range kubeResources.Jobs {
interfaces = append(interfaces, NewJobController(job))
}
case config.CronJobs:
for _, cronJob := range kubeResources.CronJobs {
interfaces = append(interfaces, NewCronJobController(cronJob))
}
case config.ReplicationControllers:
for _, replicationController := range kubeResources.ReplicationControllers {
interfaces = append(interfaces, NewReplicationControllerController(replicationController))
}
for _, pod := range kubeResources.Pods {
interfaces = append(interfaces, NewNakedPodController(pod))
}
if len(interfaces) > 0 {
return interfaces, nil
}
return nil, fmt.Errorf("Controller type (%s) does not have a generator", controllerKind)
return interfaces
}

View File

@@ -13,11 +13,6 @@ type JobController struct {
K8SResource kubeAPIBatchV1.Job
}
// GetPodTemplate returns the original template spec
func (j JobController) GetPodTemplate() *kubeAPICoreV1.PodTemplateSpec {
return &j.K8SResource.Spec.Template
}
// GetPodSpec returns the original kubernetes template pod spec
func (j JobController) GetPodSpec() *kubeAPICoreV1.PodSpec {
return &j.K8SResource.Spec.Template.Spec

View File

@@ -12,11 +12,6 @@ type NakedPodController struct {
K8SResource kubeAPICoreV1.Pod
}
// GetPodTemplate returns the original template spec
func (n NakedPodController) GetPodTemplate() *kubeAPICoreV1.PodTemplateSpec {
return nil
}
// GetPodSpec returns the original kubernetes template pod spec
func (n NakedPodController) GetPodSpec() *kubeAPICoreV1.PodSpec {
return &n.K8SResource.Spec

View File

@@ -15,11 +15,6 @@ type ReplicationControllerController struct {
K8SResource kubeAPICoreV1.ReplicationController
}
// GetPodTemplate returns the original template spec
func (r ReplicationControllerController) GetPodTemplate() *kubeAPICoreV1.PodTemplateSpec {
return r.K8SResource.Spec.Template
}
// GetPodSpec returns the original kubernetes template pod spec
func (r ReplicationControllerController) GetPodSpec() *kubeAPICoreV1.PodSpec {
return &r.K8SResource.Spec.Template.Spec

View File

@@ -13,11 +13,6 @@ type StatefulSetController struct {
K8SResource kubeAPIAppsV1.StatefulSet
}
// GetPodTemplate returns the kubernetes template spec
func (s StatefulSetController) GetPodTemplate() *kubeAPICoreV1.PodTemplateSpec {
return &s.K8SResource.Spec.Template
}
// GetPodSpec returns the podspec from the original kubernetes resource
func (s StatefulSetController) GetPodSpec() *kubeAPICoreV1.PodSpec {
return &s.K8SResource.Spec.Template.Spec

View File

@@ -34,16 +34,11 @@ func RunAudit(config conf.Configuration, kubeResources *kube.ResourceProvider) (
SourceName: kubeResources.SourceName,
DisplayName: displayName,
ClusterInfo: ClusterInfo{
Version: kubeResources.ServerVersion,
Nodes: len(kubeResources.Nodes),
Pods: len(kubeResources.Pods),
Namespaces: len(kubeResources.Namespaces),
Deployments: len(kubeResources.Deployments),
StatefulSets: len(kubeResources.StatefulSets),
DaemonSets: len(kubeResources.DaemonSets),
Jobs: len(kubeResources.Jobs),
CronJobs: len(kubeResources.CronJobs),
ReplicationControllers: len(kubeResources.ReplicationControllers),
Version: kubeResources.ServerVersion,
Nodes: len(kubeResources.Nodes),
Pods: len(kubeResources.Pods),
Namespaces: len(kubeResources.Namespaces),
Controllers: len(results),
},
Results: results,
}

View File

@@ -13,7 +13,7 @@ func TestGetTemplateData(t *testing.T) {
k8s := test.SetupTestAPI()
k8s = test.SetupAddControllers(k8s, "test")
k8s = test.SetupAddExtraControllerVersions(k8s, "test-extra")
resources, err := kube.CreateResourceProviderFromAPI(k8s, "test")
resources, err := kube.CreateResourceProviderFromAPI(k8s, "test", nil)
assert.Equal(t, err, nil, "error should be nil")
c := conf.Configuration{
@@ -33,8 +33,8 @@ func TestGetTemplateData(t *testing.T) {
sum := CountSummary{
Successes: uint(0),
Warnings: uint(9),
Errors: uint(9),
Warnings: uint(1),
Errors: uint(1),
}
actualAudit, err := RunAudit(c, resources)
@@ -48,17 +48,7 @@ func TestGetTemplateData(t *testing.T) {
kind string
results int
}{
{kind: "Deployment", results: 2},
{kind: "Deployment", results: 2},
{kind: "Deployment", results: 2},
{kind: "StatefulSet", results: 2},
{kind: "StatefulSet", results: 2},
{kind: "StatefulSet", results: 2},
{kind: "DaemonSet", results: 2},
{kind: "DaemonSet", results: 2},
{kind: "Job", results: 0},
{kind: "CronJob", results: 0},
{kind: "ReplicationController", results: 2},
{kind: "NakedPod", results: 2},
}
assert.Equal(t, len(expected), len(actualAudit.Results))

View File

@@ -15,8 +15,9 @@
package validator
import (
"github.com/fairwindsops/polaris/pkg/config"
"time"
"github.com/fairwindsops/polaris/pkg/config"
)
const (
@@ -37,16 +38,11 @@ type AuditData struct {
// ClusterInfo contains Polaris results as well as some high-level stats
type ClusterInfo struct {
Version string
Nodes int
Pods int
Namespaces int
Deployments int
StatefulSets int
DaemonSets int
Jobs int
CronJobs int
ReplicationControllers int
Version string
Nodes int
Pods int
Namespaces int
Controllers int
}
// ResultMessage is the result of a given check

View File

@@ -25,7 +25,6 @@ func ValidatePod(conf *config.Configuration, controller controllers.Interface) (
if err != nil {
return PodResult{}, err
}
pRes := PodResult{
Results: podResults,
ContainerResults: []ContainerResult{},
@@ -35,6 +34,5 @@ func ValidatePod(conf *config.Configuration, controller controllers.Interface) (
if err != nil {
return pRes, err
}
return pRes, nil
}

View File

@@ -32,6 +32,13 @@ func MockPod() corev1.PodTemplateSpec {
return p
}
// MockNakedPod created a pod object.
func MockNakedPod() corev1.Pod {
return corev1.Pod{
Spec: MockPod().Spec,
}
}
// MockDeploy creates a Deployment object.
func MockDeploy() appsv1.Deployment {
p := MockPod()
@@ -132,6 +139,11 @@ func SetupAddControllers(k kubernetes.Interface, namespace string) kubernetes.In
panic(err)
}
p1 := MockNakedPod()
if _, err := k.CoreV1().Pods(namespace).Create(&p1); err != nil {
panic(err)
}
return k
}