From 56bba70ef368cf98dc697d4c9d19e4bf1aa17c8a Mon Sep 17 00:00:00 2001 From: Bader Boland Date: Fri, 24 Jan 2020 08:53:34 -0500 Subject: [PATCH 1/7] Add ability to exclude individual tests --- pkg/validator/container_test.go | 55 ++++++++++++++++++++++++++++++++- pkg/validator/schema.go | 20 ++++++++++++ pkg/validator/schema_test.go | 29 +++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/pkg/validator/container_test.go b/pkg/validator/container_test.go index 60997cb1..18862efa 100644 --- a/pkg/validator/container_test.go +++ b/pkg/validator/container_test.go @@ -63,10 +63,14 @@ func getEmptyController(name string) controllers.Interface { } func testValidate(t *testing.T, container *corev1.Container, resourceConf *string, controllerName string, expectedErrors []ResultMessage, expectedWarnings []ResultMessage, expectedSuccesses []ResultMessage) { + testValidateWithController(t, container, resourceConf, getEmptyController(controllerName), expectedErrors, expectedWarnings, expectedSuccesses) +} + +func testValidateWithController(t *testing.T, container *corev1.Container, resourceConf *string, controller controllers.Interface, 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, getEmptyController(controllerName), container, false) + results, err := applyContainerSchemaChecks(&parsedConf, controller, container, false) if err != nil { panic(err) } @@ -1146,3 +1150,52 @@ func TestValidateResourcesExemption(t *testing.T) { testValidate(t, &container, &disallowExemptionsConf, "foo", expectedErrors, expectedWarnings, expectedSuccesses) } + +func TestValidateResourcesEmptyContainerCPURequestsExempt(t *testing.T) { + container := corev1.Container{ + Name: "Empty", + } + + expectedWarnings := []ResultMessage{ + { + ID: "memoryRequestsMissing", + Success: false, + Severity: "warning", + Message: "Memory requests should be set", + Category: "Resources", + }, + } + + expectedErrors := []ResultMessage{ + { + ID: "cpuLimitsMissing", + Success: false, + Severity: "error", + Message: "CPU limits should be set", + Category: "Resources", + }, + { + ID: "memoryLimitsMissing", + Success: false, + Severity: "error", + Message: "Memory limits should be set", + Category: "Resources", + }, + } + + expectedSuccesses := []ResultMessage{} + + controller := controllers.NewDeploymentController(appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Annotations: map[string]string { + "polaris.fairwinds.com/cpu-requests-missing-exempt": "true", // Exempt this controller from cpuRequestsMissing + "polaris.fairwinds.com/memory-requests-missing-exempt": "truthy", // Don't actually exempt this controller from memoryRequestsMissing + } , + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{}, + }, + }) + testValidateWithController(t, &container, &resourceConfMinimal, controller, expectedErrors, expectedWarnings, expectedSuccesses) +} \ No newline at end of file diff --git a/pkg/validator/schema.go b/pkg/validator/schema.go index a18f19df..b560c226 100644 --- a/pkg/validator/schema.go +++ b/pkg/validator/schema.go @@ -5,6 +5,8 @@ import ( "fmt" "io" "sort" + "regexp" + "strings" packr "github.com/gobuffalo/packr/v2" corev1 "k8s.io/api/core/v1" @@ -105,10 +107,23 @@ func makeResult(conf *config.Configuration, check *config.SchemaCheck, passes bo return result } +func getExemptKey(checkID string) string { + matchWordBoundary := regexp.MustCompile("([a-z])([A-Z])") + matchAcronymWordBoundary := regexp.MustCompile("([A-Z])([A-Z][a-z])") + wordSplitString := matchWordBoundary.ReplaceAllString(checkID, "${1}-${2}") + kebabCase := strings.ToLower(matchAcronymWordBoundary.ReplaceAllString(wordSplitString, "${1}-${2}")) + return fmt.Sprintf("polaris.fairwinds.com/%s-exempt", kebabCase) +} + func applyPodSchemaChecks(conf *config.Configuration, controller controllers.Interface) (ResultSet, error) { results := ResultSet{} checkIDs := getSortedKeys(conf.Checks) + objectAnnotations := controller.GetObjectMeta().Annotations for _, checkID := range checkIDs { + exemptValue := objectAnnotations[getExemptKey(checkID)] + if strings.ToLower(exemptValue) == "true" { + continue + } check, err := resolveCheck(conf, checkID, controller, config.TargetPod, false) if err != nil { return nil, err @@ -130,7 +145,12 @@ func applyPodSchemaChecks(conf *config.Configuration, controller controllers.Int func applyContainerSchemaChecks(conf *config.Configuration, controller controllers.Interface, container *corev1.Container, isInit bool) (ResultSet, error) { results := ResultSet{} checkIDs := getSortedKeys(conf.Checks) + objectAnnotations := controller.GetObjectMeta().Annotations for _, checkID := range checkIDs { + exemptValue := objectAnnotations[getExemptKey(checkID)] + if strings.ToLower(exemptValue) == "true" { + continue + } check, err := resolveCheck(conf, checkID, controller, config.TargetContainer, isInit) if err != nil { return nil, err diff --git a/pkg/validator/schema_test.go b/pkg/validator/schema_test.go index 0db08d2b..72f05cca 100644 --- a/pkg/validator/schema_test.go +++ b/pkg/validator/schema_test.go @@ -260,3 +260,32 @@ func TestValidateCustomCheckExemptions(t *testing.T) { } testValidate(t, &container, &customCheckExemptions, "notexempt", expectedErrors, expectedWarnings, expectedSuccesses) } + +func TestGetExemptKey(t *testing.T) { + keyMap := map[string]string { + "hostIPCSet": "polaris.fairwinds.com/host-ipc-set-exempt", + "hostPIDSet": "polaris.fairwinds.com/host-pid-set-exempt", + "hostNetworkSet": "polaris.fairwinds.com/host-network-set-exempt", + "memoryLimitsMissing": "polaris.fairwinds.com/memory-limits-missing-exempt", + "memoryRequestsMissing": "polaris.fairwinds.com/memory-requests-missing-exempt", + "cpuLimitsMissing": "polaris.fairwinds.com/cpu-limits-missing-exempt", + "cpuRequestsMissing": "polaris.fairwinds.com/cpu-requests-missing-exempt", + "readinessProbeMissing": "polaris.fairwinds.com/readiness-probe-missing-exempt", + "livenessProbeMissing": "polaris.fairwinds.com/liveness-probe-missing-exempt", + "pullPolicyNotAlways": "polaris.fairwinds.com/pull-policy-not-always-exempt", + "tagNotSpecified": "polaris.fairwinds.com/tag-not-specified-exempt", + "hostPortSet": "polaris.fairwinds.com/host-port-set-exempt", + "runAsRootAllowed": "polaris.fairwinds.com/run-as-root-allowed-exempt", + "runAsPrivileged": "polaris.fairwinds.com/run-as-privileged-exempt", + "notReadOnlyRootFileSystem": "polaris.fairwinds.com/not-read-only-root-file-system-exempt", + "privilegeEscalationAllowed": "polaris.fairwinds.com/privilege-escalation-allowed-exempt", + "dangerousCapabilities": "polaris.fairwinds.com/dangerous-capabilities-exempt", + "insecureCapabilities": "polaris.fairwinds.com/insecure-capabilities-exempt", + } + for id, key := range keyMap { + exemptKey := getExemptKey(id) + assert.Equal(t, key, exemptKey) + } + + +} \ No newline at end of file From 36876072f267b554813020c8a27b598104369232 Mon Sep 17 00:00:00 2001 From: Bader Boland Date: Tue, 28 Jan 2020 08:30:50 -0500 Subject: [PATCH 2/7] Bumping version and adding documentation. --- CHANGELOG.md | 3 +++ README.md | 2 +- docs/usage.md | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1e243da..e79b7bab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # x.x.x (next release) +# 0.6.1 +* Added the ability to exempt a particular controller from a particular check. + # 0.6.0 * Fixed webhook support in Kubernetes 1.16 * this also removes support for 1.8 diff --git a/README.md b/README.md index b45de386..74acb712 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Version][version-image]][version-link] [![CircleCI][circleci-image]][circleci-link] [![Go Report Card][goreport-image]][goreport-link] -[version-image]: https://img.shields.io/static/v1.svg?label=Version&message=0.6.0&color=239922 +[version-image]: https://img.shields.io/static/v1.svg?label=Version&message=0.6.1&color=239922 [version-link]: https://github.com/FairwindsOps/polaris [goreport-image]: https://goreportcard.com/badge/github.com/FairwindsOps/polaris diff --git a/docs/usage.md b/docs/usage.md index 610f63e0..6adeebb1 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -62,7 +62,7 @@ There are additional examples in the [checks folder](/checks). ### Exemptions Exemptions can be added two ways: by annotating a controller, or editing the Polaris config. -To exempt a controller via annotations, use the annotation `polaris.fairwinds.com/exempt=true`, e.g. +To exempt a controller from all checks via annotations, use the annotation `polaris.fairwinds.com/exempt=true`, e.g. ``` kubectl annotate deployment my-deployment polaris.fairwinds.com/exempt=true ``` @@ -76,6 +76,11 @@ exemptions: - hostNetworkSet ``` +To exempt a controller from a particular check via annotations, use an annotation in the form of `polaris.fairwinds.com/-exempt=true`, e.g. +``` +kubectl annotate deployment my-deployment polaris.fairwinds.com/cpu-requests-missing-exempt=true +``` + # Installing There are several ways to install and use Polaris. Below outline ways to install using `kubectl`, `helm` and `local binary`. From 7b0817202c8c14f8110121e7d433bde2bfa8c0a6 Mon Sep 17 00:00:00 2001 From: Bader Boland Date: Tue, 28 Jan 2020 08:31:05 -0500 Subject: [PATCH 3/7] Bumping version in main.go --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 124847ba..295cd1a3 100644 --- a/main.go +++ b/main.go @@ -41,7 +41,7 @@ import ( const ( // Version represents the current release version of Polaris - Version = "0.6.0" + Version = "0.6.1" ) func main() { From ba412ab407781941167c83a01d8af40279101e53 Mon Sep 17 00:00:00 2001 From: Bader Boland Date: Tue, 28 Jan 2020 09:32:02 -0500 Subject: [PATCH 4/7] Undoing version bump --- CHANGELOG.md | 2 -- README.md | 2 +- main.go | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e79b7bab..40817857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,4 @@ # x.x.x (next release) - -# 0.6.1 * Added the ability to exempt a particular controller from a particular check. # 0.6.0 diff --git a/README.md b/README.md index 74acb712..b45de386 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Version][version-image]][version-link] [![CircleCI][circleci-image]][circleci-link] [![Go Report Card][goreport-image]][goreport-link] -[version-image]: https://img.shields.io/static/v1.svg?label=Version&message=0.6.1&color=239922 +[version-image]: https://img.shields.io/static/v1.svg?label=Version&message=0.6.0&color=239922 [version-link]: https://github.com/FairwindsOps/polaris [goreport-image]: https://goreportcard.com/badge/github.com/FairwindsOps/polaris diff --git a/main.go b/main.go index 295cd1a3..124847ba 100644 --- a/main.go +++ b/main.go @@ -41,7 +41,7 @@ import ( const ( // Version represents the current release version of Polaris - Version = "0.6.1" + Version = "0.6.0" ) func main() { From 7f71a352a7d8c2fbf839c5140777368a0d2c81d5 Mon Sep 17 00:00:00 2001 From: Bader Boland Date: Tue, 28 Jan 2020 09:34:52 -0500 Subject: [PATCH 5/7] Remove kebab case --- pkg/validator/container_test.go | 4 ++-- pkg/validator/schema.go | 7 +------ pkg/validator/schema_test.go | 29 ----------------------------- 3 files changed, 3 insertions(+), 37 deletions(-) diff --git a/pkg/validator/container_test.go b/pkg/validator/container_test.go index 18862efa..c298586b 100644 --- a/pkg/validator/container_test.go +++ b/pkg/validator/container_test.go @@ -1189,8 +1189,8 @@ func TestValidateResourcesEmptyContainerCPURequestsExempt(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "foo", Annotations: map[string]string { - "polaris.fairwinds.com/cpu-requests-missing-exempt": "true", // Exempt this controller from cpuRequestsMissing - "polaris.fairwinds.com/memory-requests-missing-exempt": "truthy", // Don't actually exempt this controller from memoryRequestsMissing + "polaris.fairwinds.com/cpuRequestsMissing-exempt": "true", // Exempt this controller from cpuRequestsMissing + "polaris.fairwinds.com/memoryRequestsMissing-exempt": "truthy", // Don't actually exempt this controller from memoryRequestsMissing } , }, Spec: appsv1.DeploymentSpec{ diff --git a/pkg/validator/schema.go b/pkg/validator/schema.go index b560c226..1d5033f5 100644 --- a/pkg/validator/schema.go +++ b/pkg/validator/schema.go @@ -5,7 +5,6 @@ import ( "fmt" "io" "sort" - "regexp" "strings" packr "github.com/gobuffalo/packr/v2" @@ -108,11 +107,7 @@ func makeResult(conf *config.Configuration, check *config.SchemaCheck, passes bo } func getExemptKey(checkID string) string { - matchWordBoundary := regexp.MustCompile("([a-z])([A-Z])") - matchAcronymWordBoundary := regexp.MustCompile("([A-Z])([A-Z][a-z])") - wordSplitString := matchWordBoundary.ReplaceAllString(checkID, "${1}-${2}") - kebabCase := strings.ToLower(matchAcronymWordBoundary.ReplaceAllString(wordSplitString, "${1}-${2}")) - return fmt.Sprintf("polaris.fairwinds.com/%s-exempt", kebabCase) + return fmt.Sprintf("polaris.fairwinds.com/%s-exempt", checkID) } func applyPodSchemaChecks(conf *config.Configuration, controller controllers.Interface) (ResultSet, error) { diff --git a/pkg/validator/schema_test.go b/pkg/validator/schema_test.go index 72f05cca..3005558e 100644 --- a/pkg/validator/schema_test.go +++ b/pkg/validator/schema_test.go @@ -259,33 +259,4 @@ func TestValidateCustomCheckExemptions(t *testing.T) { }, } testValidate(t, &container, &customCheckExemptions, "notexempt", expectedErrors, expectedWarnings, expectedSuccesses) -} - -func TestGetExemptKey(t *testing.T) { - keyMap := map[string]string { - "hostIPCSet": "polaris.fairwinds.com/host-ipc-set-exempt", - "hostPIDSet": "polaris.fairwinds.com/host-pid-set-exempt", - "hostNetworkSet": "polaris.fairwinds.com/host-network-set-exempt", - "memoryLimitsMissing": "polaris.fairwinds.com/memory-limits-missing-exempt", - "memoryRequestsMissing": "polaris.fairwinds.com/memory-requests-missing-exempt", - "cpuLimitsMissing": "polaris.fairwinds.com/cpu-limits-missing-exempt", - "cpuRequestsMissing": "polaris.fairwinds.com/cpu-requests-missing-exempt", - "readinessProbeMissing": "polaris.fairwinds.com/readiness-probe-missing-exempt", - "livenessProbeMissing": "polaris.fairwinds.com/liveness-probe-missing-exempt", - "pullPolicyNotAlways": "polaris.fairwinds.com/pull-policy-not-always-exempt", - "tagNotSpecified": "polaris.fairwinds.com/tag-not-specified-exempt", - "hostPortSet": "polaris.fairwinds.com/host-port-set-exempt", - "runAsRootAllowed": "polaris.fairwinds.com/run-as-root-allowed-exempt", - "runAsPrivileged": "polaris.fairwinds.com/run-as-privileged-exempt", - "notReadOnlyRootFileSystem": "polaris.fairwinds.com/not-read-only-root-file-system-exempt", - "privilegeEscalationAllowed": "polaris.fairwinds.com/privilege-escalation-allowed-exempt", - "dangerousCapabilities": "polaris.fairwinds.com/dangerous-capabilities-exempt", - "insecureCapabilities": "polaris.fairwinds.com/insecure-capabilities-exempt", - } - for id, key := range keyMap { - exemptKey := getExemptKey(id) - assert.Equal(t, key, exemptKey) - } - - } \ No newline at end of file From ed48daa09250bd4211513c962ec78d2534add300 Mon Sep 17 00:00:00 2001 From: Bader Boland Date: Tue, 28 Jan 2020 09:35:20 -0500 Subject: [PATCH 6/7] Updated docs --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 6adeebb1..7e59be0f 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -78,7 +78,7 @@ exemptions: To exempt a controller from a particular check via annotations, use an annotation in the form of `polaris.fairwinds.com/-exempt=true`, e.g. ``` -kubectl annotate deployment my-deployment polaris.fairwinds.com/cpu-requests-missing-exempt=true +kubectl annotate deployment my-deployment polaris.fairwinds.com/cpuRequestsMissing-exempt=true ``` # Installing From 10fdf4ef33614c1917f3873e45ea4ca5983b5e85 Mon Sep 17 00:00:00 2001 From: Bader Boland Date: Tue, 28 Jan 2020 09:44:12 -0500 Subject: [PATCH 7/7] Updating CLA --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 39ff4703..ee58dc8c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Issues, whether bugs, tasks, or feature requests are essential for keeping Polar This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). Please review this document before contributing to this project. ## Sign the CLA -Before you can contribute, you will need to sign the [Contributor License Agreement](https://cla-assistant.io/fairwinds/polaris). +Before you can contribute, you will need to sign the [Contributor License Agreement](https://cla-assistant.io/fairwindsops/polaris). ## Project Structure