Skip to content

Commit

Permalink
refactor ValidateContainers
Browse files Browse the repository at this point in the history
  • Loading branch information
rbren committed Jan 14, 2020
1 parent 23bf4c8 commit 7637108
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 37 deletions.
21 changes: 15 additions & 6 deletions pkg/validator/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ package validator

import (
"github.com/fairwindsops/polaris/pkg/config"
"github.com/fairwindsops/polaris/pkg/validator/controllers"

corev1 "k8s.io/api/core/v1"
)

func ValidateContainer(conf *config.Configuration, basePod *corev1.PodSpec, container *corev1.Container, controllerName string, controllerKind config.SupportedController, isInit bool) ContainerResult {
results, err := applyContainerSchemaChecks(conf, basePod, container, controllerName, controllerKind, isInit)
// ValidateContainer validates a single container from a given controller
func ValidateContainer(conf *config.Configuration, controller controllers.Interface, container *corev1.Container, isInit bool) ContainerResult {
results, err := applyContainerSchemaChecks(conf, controller, container, isInit)
// FIXME: don't panic
if err != nil {
panic(err)
Expand All @@ -34,11 +37,17 @@ func ValidateContainer(conf *config.Configuration, basePod *corev1.PodSpec, cont
return cRes
}

func ValidateContainers(conf *config.Configuration, basePod *corev1.PodSpec, containers []corev1.Container, controllerName string, controllerKind config.SupportedController, isInit bool) []ContainerResult {
// ValidateAllContainers validates both init and regular containers
func ValidateAllContainers(conf *config.Configuration, controller controllers.Interface) []ContainerResult {
results := []ContainerResult{}
for _, container := range containers {
cRes := ValidateContainer(conf, basePod, &container, controllerName, controllerKind, isInit)
results = append(results, cRes)
pod := controller.GetPodSpec()
for _, container := range pod.InitContainers {
result := ValidateContainer(conf, controller, &container, true)
results = append(results, result)
}
for _, container := range pod.Containers {
result := ValidateContainer(conf, controller, &container, false)
results = append(results, result)
}
return results
}
52 changes: 45 additions & 7 deletions pkg/validator/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ import (
"testing"

conf "github.com/fairwindsops/polaris/pkg/config"
"github.com/fairwindsops/polaris/pkg/validator/controllers"

"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var resourceConfMinimal = `---
Expand All @@ -47,11 +51,22 @@ exemptions:
- foo
`

func getEmptyController(name string) controllers.Interface {
return controllers.NewDeploymentController(appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{},
},
})
}

func testValidate(t *testing.T, container *corev1.Container, resourceConf *string, controllerName string, expectedErrors []ResultMessage, expectedWarnings []ResultMessage, expectedSuccesses []ResultMessage) {
parsedConf, err := conf.Parse([]byte(*resourceConf))
assert.NoError(t, err, "Expected no error when parsing config")

results, err := applyContainerSchemaChecks(&parsedConf, &corev1.PodSpec{}, container, controllerName, conf.Deployments, false)
results, err := applyContainerSchemaChecks(&parsedConf, getEmptyController(controllerName), container, false)
if err != nil {
panic(err)
}
Expand All @@ -72,7 +87,7 @@ func TestValidateResourcesEmptyConfig(t *testing.T) {
Name: "Empty",
}

results, err := applyContainerSchemaChecks(&conf.Configuration{}, &corev1.PodSpec{}, container, "", conf.Deployments, false)
results, err := applyContainerSchemaChecks(&conf.Configuration{}, getEmptyController(""), container, false)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -170,7 +185,8 @@ func TestValidateHealthChecks(t *testing.T) {

for idx, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
results, err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.probes}, &corev1.PodSpec{}, tt.container, "", conf.Deployments, tt.isInit)
controller := getEmptyController("")
results, err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.probes}, controller, tt.container, tt.isInit)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -283,7 +299,8 @@ func TestValidateImage(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
results, err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.image}, &corev1.PodSpec{}, tt.container, "", conf.Deployments, false)
controller := getEmptyController("")
results, err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.image}, controller, tt.container, false)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -399,7 +416,8 @@ func TestValidateNetworking(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
results, err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.networkConf}, &corev1.PodSpec{}, tt.container, "", conf.Deployments, false)
controller := getEmptyController("")
results, err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.networkConf}, controller, tt.container, false)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -902,7 +920,17 @@ func TestValidateSecurity(t *testing.T) {

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
results, err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.securityConf}, tt.pod, tt.container, "", conf.Deployments, false)
controller := controllers.NewDeploymentController(appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "",
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: *tt.pod,
},
},
})
results, err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.securityConf}, controller, tt.container, false)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -1045,7 +1073,17 @@ func TestValidateRunAsRoot(t *testing.T) {
}
for idx, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
results, err := applyContainerSchemaChecks(&config, tt.pod, tt.container, "", conf.Deployments, false)
controller := controllers.NewDeploymentController(appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "",
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: *tt.pod,
},
},
})
results, err := applyContainerSchemaChecks(&config, controller, tt.container, false)
if err != nil {
panic(err)
}
Expand Down
16 changes: 2 additions & 14 deletions pkg/validator/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,13 @@
package validator

import (
corev1 "k8s.io/api/core/v1"

"github.com/fairwindsops/polaris/pkg/config"
"github.com/fairwindsops/polaris/pkg/validator/controllers"
)

// ValidatePod validates that each pod conforms to the Polaris config, returns a ResourceResult.
func ValidatePod(conf *config.Configuration, controller controllers.Interface) PodResult {
pod := controller.GetPodSpec()
controllerName := controller.GetName()
controllerKind := controller.GetKind()
podResults, err := applyPodSchemaChecks(conf, pod, controllerName, controllerKind)
podResults, err := applyPodSchemaChecks(conf, controller)
// FIXME: don't panic
if err != nil {
panic(err)
Expand All @@ -37,14 +32,7 @@ func ValidatePod(conf *config.Configuration, controller controllers.Interface) P
ContainerResults: []ContainerResult{},
}

podCopy := *pod
podCopy.InitContainers = []corev1.Container{}
podCopy.Containers = []corev1.Container{}

containerResults := ValidateContainers(conf, &podCopy, pod.InitContainers, controllerName, controllerKind, true)
pRes.ContainerResults = append(pRes.ContainerResults, containerResults...)
containerResults = ValidateContainers(conf, &podCopy, pod.Containers, controllerName, controllerKind, false)
pRes.ContainerResults = append(pRes.ContainerResults, containerResults...)
pRes.ContainerResults = ValidateAllContainers(conf, controller)

return pRes
}
18 changes: 10 additions & 8 deletions pkg/validator/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"k8s.io/apimachinery/pkg/util/yaml"

"github.com/fairwindsops/polaris/pkg/config"
"github.com/fairwindsops/polaris/pkg/validator/controllers"
)

var (
Expand Down Expand Up @@ -104,11 +105,11 @@ func makeResult(conf *config.Configuration, check *config.SchemaCheck, passes bo
return result
}

func applyPodSchemaChecks(conf *config.Configuration, pod *corev1.PodSpec, controllerName string, controllerKind config.SupportedController) (ResultSet, error) {
func applyPodSchemaChecks(conf *config.Configuration, controller controllers.Interface) (ResultSet, error) {
results := ResultSet{}
checkIDs := getSortedKeys(conf.Checks)
for _, checkID := range checkIDs {
check, err := resolveCheck(conf, checkID, controllerName, controllerKind, config.TargetPod, false)
check, err := resolveCheck(conf, checkID, controller.GetName(), controller.GetKind(), config.TargetPod, false)
if err != nil {
return nil, err
}
Expand All @@ -117,7 +118,7 @@ func applyPodSchemaChecks(conf *config.Configuration, pod *corev1.PodSpec, contr
} else if check == nil {
continue
}
passes, err := check.CheckPod(pod)
passes, err := check.CheckPod(controller.GetPodSpec())
if err != nil {
return nil, err
}
Expand All @@ -126,21 +127,22 @@ func applyPodSchemaChecks(conf *config.Configuration, pod *corev1.PodSpec, contr
return results, nil
}

func applyContainerSchemaChecks(conf *config.Configuration, basePod *corev1.PodSpec, container *corev1.Container, controllerName string, controllerKind config.SupportedController, isInit bool) (ResultSet, error) {
func applyContainerSchemaChecks(conf *config.Configuration, controller controllers.Interface, container *corev1.Container, isInit bool) (ResultSet, error) {
results := ResultSet{}
checkIDs := getSortedKeys(conf.Checks)
for _, checkID := range checkIDs {
check, err := resolveCheck(conf, checkID, controllerName, controllerKind, config.TargetContainer, isInit)
check, err := resolveCheck(conf, checkID, controller.GetName(), controller.GetKind(), config.TargetContainer, isInit)
if err != nil {
return nil, err
} else if check == nil {
continue
}
var passes bool
if check.SchemaTarget == config.TargetPod {
basePod.Containers = []corev1.Container{*container}
passes, err = check.CheckPod(basePod)
basePod.Containers = []corev1.Container{}
podCopy := *controller.GetPodSpec()
podCopy.InitContainers = []corev1.Container{}
podCopy.Containers = []corev1.Container{*container}
passes, err = check.CheckPod(&podCopy)
} else {
passes, err = check.CheckContainer(container)
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/validator/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

conf "github.com/fairwindsops/polaris/pkg/config"

"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -137,18 +138,19 @@ func TestValidateResourcesPartiallyValid(t *testing.T) {

func TestValidateResourcesInit(t *testing.T) {
emptyContainer := &corev1.Container{}
controller := getEmptyController("")

parsedConf, err := conf.Parse([]byte(resourceConfRanges))
assert.NoError(t, err, "Expected no error when parsing config")

results, err := applyContainerSchemaChecks(&parsedConf, &corev1.PodSpec{}, emptyContainer, "", conf.Deployments, false)
results, err := applyContainerSchemaChecks(&parsedConf, controller, emptyContainer, false)
if err != nil {
panic(err)
}
assert.Equal(t, uint(1), results.GetSummary().Errors)
assert.Equal(t, uint(1), results.GetSummary().Warnings)

results, err = applyContainerSchemaChecks(&parsedConf, &corev1.PodSpec{}, emptyContainer, "", conf.Deployments, true)
results, err = applyContainerSchemaChecks(&parsedConf, controller, emptyContainer, true)
if err != nil {
panic(err)
}
Expand Down

0 comments on commit 7637108

Please sign in to comment.