mirror of
https://github.com/FairwindsOps/polaris.git
synced 2026-05-12 04:06:44 +00:00
Merge pull request #239 from FairwindsOps/bb/exclude-check
Exclude individual checks from a controller
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# x.x.x (next release)
|
||||
* Added the ability to exempt a particular controller from a particular check.
|
||||
|
||||
# 0.6.0
|
||||
* Fixed webhook support in Kubernetes 1.16
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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/<check>-exempt=true`, e.g.
|
||||
```
|
||||
kubectl annotate deployment my-deployment polaris.fairwinds.com/cpuRequestsMissing-exempt=true
|
||||
```
|
||||
|
||||
# Installing
|
||||
There are several ways to install and use Polaris. Below outline ways to install using `kubectl`, `helm` and `local binary`.
|
||||
|
||||
|
||||
@@ -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/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{
|
||||
Template: corev1.PodTemplateSpec{},
|
||||
},
|
||||
})
|
||||
testValidateWithController(t, &container, &resourceConfMinimal, controller, expectedErrors, expectedWarnings, expectedSuccesses)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
packr "github.com/gobuffalo/packr/v2"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -105,10 +106,19 @@ func makeResult(conf *config.Configuration, check *config.SchemaCheck, passes bo
|
||||
return result
|
||||
}
|
||||
|
||||
func getExemptKey(checkID string) string {
|
||||
return fmt.Sprintf("polaris.fairwinds.com/%s-exempt", checkID)
|
||||
}
|
||||
|
||||
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 +140,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
|
||||
|
||||
@@ -259,4 +259,4 @@ func TestValidateCustomCheckExemptions(t *testing.T) {
|
||||
},
|
||||
}
|
||||
testValidate(t, &container, &customCheckExemptions, "notexempt", expectedErrors, expectedWarnings, expectedSuccesses)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user