mirror of
https://github.com/FairwindsOps/polaris.git
synced 2026-05-09 10:47:05 +00:00
Implement namespace support for exceptions (#421)
* Implement namespace support for exceptions Signed-off-by: Markus Blaschke <mblaschke82@gmail.com> * remove debug Signed-off-by: Markus Blaschke <mblaschke82@gmail.com> * Add documentation Signed-off-by: Markus Blaschke <mblaschke82@gmail.com> Co-authored-by: baderbuddy <bader@fairwinds.com>
This commit is contained in:
@@ -71,9 +71,16 @@ To exempt a controller from all checks via annotations, use the annotation `pola
|
||||
kubectl annotate deployment my-deployment polaris.fairwinds.com/exempt=true
|
||||
```
|
||||
|
||||
To exempt a controller via the config, you have to specify a list of controller names and a list of rules, e.g.
|
||||
To exempt a controller via the config, you have to specify a namespace (optional), a list of controller names and a list of rules, e.g.
|
||||
```yaml
|
||||
exemptions:
|
||||
# exception valid for kube-system namespace
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- dns-controller
|
||||
rules:
|
||||
- hostNetworkSet
|
||||
# exception valid in all namespaces
|
||||
- controllerNames:
|
||||
- dns-controller
|
||||
rules:
|
||||
|
||||
@@ -35,6 +35,12 @@ exemptions:
|
||||
rules:
|
||||
- hostNetworkSet
|
||||
- hostPortSet
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- my-network-controller
|
||||
rules:
|
||||
- hostNetworkSet
|
||||
- hostPortSet
|
||||
|
||||
customChecks:
|
||||
resourceLimits:
|
||||
|
||||
@@ -27,7 +27,8 @@ checks:
|
||||
insecureCapabilities: warning
|
||||
|
||||
exemptions:
|
||||
- controllerNames:
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- kube-apiserver
|
||||
- kube-proxy
|
||||
- kube-scheduler
|
||||
|
||||
@@ -40,6 +40,7 @@ type Configuration struct {
|
||||
type Exemption struct {
|
||||
Rules []string `json:"rules"`
|
||||
ControllerNames []string `json:"controllerNames"`
|
||||
Namespace string `json:"namespace"`
|
||||
}
|
||||
|
||||
var configBox = (*packr.Box)(nil)
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
// IsActionable determines whether a check is actionable given the current configuration
|
||||
func (conf Configuration) IsActionable(ruleID, controllerName string) bool {
|
||||
func (conf Configuration) IsActionable(ruleID, namespace, controllerName string) bool {
|
||||
if severity, ok := conf.Checks[ruleID]; !ok || !severity.IsActionable() {
|
||||
return false
|
||||
}
|
||||
@@ -14,10 +14,15 @@ func (conf Configuration) IsActionable(ruleID, controllerName string) bool {
|
||||
}
|
||||
|
||||
for _, example := range conf.Exemptions {
|
||||
if example.Namespace != "" && example.Namespace != namespace {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, rule := range example.Rules {
|
||||
if rule != ruleID {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, controller := range example.ControllerNames {
|
||||
if strings.HasPrefix(controllerName, controller) {
|
||||
return false
|
||||
|
||||
@@ -39,10 +39,19 @@ exemptions:
|
||||
- test
|
||||
`
|
||||
|
||||
var confNamespaceTest = `
|
||||
checks:
|
||||
ANY: warning
|
||||
exemptions:
|
||||
- namespace: kube-system
|
||||
controllerNames:
|
||||
- test
|
||||
`
|
||||
|
||||
func TestInclusiveExemption(t *testing.T) {
|
||||
parsedConf, _ := Parse([]byte(confExemptTest))
|
||||
applicable := parsedConf.IsActionable("ANY", "test")
|
||||
applicableOtherController := parsedConf.IsActionable("ANY", "other")
|
||||
applicable := parsedConf.IsActionable("ANY", "test", "test")
|
||||
applicableOtherController := parsedConf.IsActionable("ANY","test", "other")
|
||||
|
||||
assert.False(t, applicable, "Expected all checks to be exempted when their controller is specified.")
|
||||
assert.True(t, applicableOtherController, "Expected checks to only be exempted when their controller is specified.")
|
||||
@@ -50,13 +59,22 @@ func TestInclusiveExemption(t *testing.T) {
|
||||
|
||||
func TestIndividualRuleException(t *testing.T) {
|
||||
parsedConf, _ := Parse([]byte(confExemptRuleTest))
|
||||
applicable := parsedConf.IsActionable("ANY", "test")
|
||||
applicableOtherRule := parsedConf.IsActionable("OTHER", "test")
|
||||
applicableOtherRuleOtherController := parsedConf.IsActionable("OTHER", "other")
|
||||
applicableRuleOtherController := parsedConf.IsActionable("ANY", "other")
|
||||
applicable := parsedConf.IsActionable("ANY", "test", "test")
|
||||
applicableOtherRule := parsedConf.IsActionable("OTHER","test", "test")
|
||||
applicableOtherRuleOtherController := parsedConf.IsActionable("OTHER","test", "other")
|
||||
applicableRuleOtherController := parsedConf.IsActionable("ANY","test", "other")
|
||||
|
||||
assert.False(t, applicable, "Expected all checks to be exempted when their controller and rule are specified.")
|
||||
assert.True(t, applicableOtherRule, "Expected checks to only be exempted when their controller and rule are specified.")
|
||||
assert.True(t, applicableOtherRuleOtherController, "Expected checks to only be exempted when their controller and rule are specified.")
|
||||
assert.True(t, applicableRuleOtherController, "Expected checks to only be exempted when their controller and rule are specified.")
|
||||
}
|
||||
|
||||
func TestNamespaceExemption(t *testing.T) {
|
||||
parsedConf, _ := Parse([]byte(confNamespaceTest))
|
||||
applicable := parsedConf.IsActionable("ANY", "kube-system", "test")
|
||||
applicableOtherController := parsedConf.IsActionable("ANY","default", "test")
|
||||
|
||||
assert.False(t, applicable, "Expected all checks to be exempted when their namespace and controller is specified.")
|
||||
assert.True(t, applicableOtherController, "Expected checks to only be exempted when their namespace and controller is specified.")
|
||||
}
|
||||
@@ -152,7 +152,7 @@ func (check SchemaCheck) CheckObject(obj interface{}) (bool, error) {
|
||||
}
|
||||
|
||||
// IsActionable decides if this check applies to a particular target
|
||||
func (check SchemaCheck) IsActionable(target TargetKind, controllerType string, isInit bool) bool {
|
||||
func (check SchemaCheck) IsActionable(target TargetKind, namespace, controllerType string, isInit bool) bool {
|
||||
if check.Target != target {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -86,10 +86,10 @@ func resolveCheck(conf *config.Configuration, checkID string, controller kube.Ge
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Check %s not found", checkID)
|
||||
}
|
||||
if !conf.IsActionable(check.ID, controller.ObjectMeta.GetName()) {
|
||||
if !conf.IsActionable(check.ID, controller.ObjectMeta.GetNamespace(), controller.ObjectMeta.GetName()) {
|
||||
return nil, nil
|
||||
}
|
||||
if !check.IsActionable(target, controller.Kind, isInitContainer) {
|
||||
if !check.IsActionable(target, controller.ObjectMeta.GetNamespace(), controller.Kind, isInitContainer) {
|
||||
return nil, nil
|
||||
}
|
||||
return &check, nil
|
||||
|
||||
Reference in New Issue
Block a user