change input config to simplify things

This commit is contained in:
Robert Brennan
2020-01-02 17:55:21 +00:00
parent 5efa416ea9
commit 04da47d83e
29 changed files with 146 additions and 239 deletions
-2
View File
@@ -1,5 +1,3 @@
name: CPULimitsMissing
id: cpuLimitsMissing
successMessage: CPU limits are set
failureMessage: CPU limits should be set
category: Resources
-2
View File
@@ -1,5 +1,3 @@
name: CPURequestsMissing
id: cpuRequestsMissing
successMessage: CPU requests are set
failureMessage: CPU requests should be set
category: Resources
-2
View File
@@ -1,5 +1,3 @@
name: DangerousCapabilities
id: dangerousCapabilities
successMessage: Container does not have any dangerous capabilities
failureMessage: Container should not have dangerous capabilities
category: Security
@@ -1,5 +1,3 @@
name: HostIPCSet
id: hostIPCSet
successMessage: Host IPC is not configured
failureMessage: Host IPC should not be configured
category: Security
@@ -1,5 +1,3 @@
name: HostNetworkSet
id: hostNetworkSet
successMessage: Host network is not configured
failureMessage: Host network should not be configured
category: Networking
@@ -1,5 +1,3 @@
name: HostPIDSet
id: hostPIDSet
successMessage: Host PID is not configured
failureMessage: Host PID should not be configured
category: Security
-2
View File
@@ -1,5 +1,3 @@
name: HostPortSet
id: hostPortSet
successMessage: Host port is not configured
failureMessage: Host port should not be configured
category: Networking
-2
View File
@@ -1,5 +1,3 @@
name: InsecureCapabilities
id: insecureCapabilities
successMessage: Container does not have any insecure capabilities
failureMessage: Container should not have insecure capabilities
category: Security
@@ -1,5 +1,3 @@
name: LivenessProbeMissing
id: livenessProbeMissing
successMessage: Liveness probe is configured
failureMessage: Liveness probe should be configured
category: Health Checks
-2
View File
@@ -1,5 +1,3 @@
name: MemoryLimitsMissing
id: memoryLimitsMissing
successMessage: Memory limits are set
failureMessage: Memory limits should be set
category: Resources
-2
View File
@@ -1,5 +1,3 @@
name: MemoryRequestsMissing
id: memoryRequestsMissing
successMessage: Memory requests are set
failureMessage: Memory requests should be set
category: Resources
-2
View File
@@ -1,5 +1,3 @@
name: NotReadOnlyRootFileSystem
id: notReadOnlyRootFileSystem
successMessage: Filesystem is read only
failureMessage: Filesystem should be read only
category: Security
-2
View File
@@ -1,5 +1,3 @@
name: PrivilegeEscalationAllowed
id: privilegeEscalationAllowed
successMessage: Privilege escalation not allowed
failureMessage: Privilege escalation should not be allowed
category: Security
-2
View File
@@ -1,5 +1,3 @@
name: PullPolicyNotAlways
id: pullPolicyNotAlways
successMessage: Image pull policy is "Always"
failureMessage: Image pull policy should be "Always"
category: Images
@@ -1,5 +1,3 @@
name: ReadinessProbeMissing
id: readinessProbeMissing
successMessage: Readiness probe is configured
failureMessage: Readiness probe should be configured
category: Health Checks
-2
View File
@@ -1,5 +1,3 @@
name: RunAsPrivileged
id: runAsPrivileged
successMessage: Not running as privileged
failureMessage: Should not be running as privileged
category: Security
-2
View File
@@ -1,5 +1,3 @@
name: RunAsRootAllowed
id: runAsRootAllowed
successMessage: Is not allowed to run as root
failureMessage: Should not be allowed to run as root
category: Security
-2
View File
@@ -1,5 +1,3 @@
name: TagNotSpecified
id: tagNotSpecified
successMessage: Image tag is specified
failureMessage: Image tag should be specified
category: Images
+1
View File
@@ -154,6 +154,7 @@ metadata:
namespace: polaris
labels:
app: polaris
foo: bar
component: dashboard
spec:
replicas: 1
+7 -6
View File
@@ -1,18 +1,19 @@
resources:
checks:
# resources
cpuRequestsMissing: warning
cpuLimitsMissing: warning
memoryRequestsMissing: warning
memoryLimitsMissing: warning
images:
# images
tagNotSpecified: error
pullPolicyNotAlways: ignore
healthChecks:
# healthChecks
readinessProbeMissing: warning
livenessProbeMissing: warning
networking:
# networking
hostNetworkSet: warning
hostPortSet: warning
security:
# security
hostIPCSet: error
hostPIDSet: error
notReadOnlyRootFileSystem: warning
@@ -21,7 +22,7 @@ security:
runAsPrivileged: error
dangerousCapabilities: error
insecureCapabilities: warning
controllers_to_scan:
controllersToScan:
- Deployments
- StatefulSets
- DaemonSets
+1 -6
View File
@@ -29,13 +29,8 @@ import (
// Configuration contains all of the config for the validation checks.
type Configuration struct {
DisplayName string `json:"displayName"`
Resources Resources `json:"resources"`
HealthChecks HealthChecks `json:"healthChecks"`
Images Images `json:"images"`
Networking Networking `json:"networking"`
Security Security `json:"security"`
Checks map[string]Severity `json:"checks"`
ControllersToScan []SupportedController `json:"controllers_to_scan"`
ControllersToScan []SupportedController `json:"controllersToScan"`
CustomChecks map[string]SchemaCheck `json:"customChecks"`
Exemptions []Exemption `json:"exemptions"`
DisallowExemptions bool `json:"disallowExemptions"`
+6 -6
View File
@@ -29,18 +29,18 @@ import (
var confInvalid = `test`
var confValidYAML = `
resources:
checks:
cpuRequestsMissing: warning
controllers_to_scan:
controllersToScan:
- Deployments
`
var confValidJSON = `
{
"resources": {
"checks": {
"cpuRequestsMissing": "warning"
},
"controllers_to_scan": ["Deployments"]
"controllersToScan": ["Deployments"]
}
`
@@ -96,7 +96,7 @@ func TestConfigNoServerError(t *testing.T) {
}
func testParsedConfig(t *testing.T, config *Configuration) {
assert.Equal(t, SeverityWarning, config.Resources.CPURequestsMissing)
assert.Equal(t, Severity(""), config.Resources.CPULimitsMissing)
assert.Equal(t, SeverityWarning, config.Checks["cpuRequestsMissing"])
assert.Equal(t, Severity(""), config.Checks["cpuLimitsMissing"])
assert.ElementsMatch(t, []SupportedController{Deployments}, config.ControllersToScan)
}
+2 -37
View File
@@ -1,19 +1,12 @@
package config
import (
"reflect"
"strings"
)
// IsActionable determines whether a check is actionable given the current configuration
func (conf Configuration) IsActionable(subConf interface{}, ruleName, controllerName string) bool {
if subConfStr, ok := subConf.(string); ok {
subConf = conf.GetCategoryConfig(subConfStr)
}
ruleID := GetIDFromField(subConf, ruleName)
subConfRef := reflect.ValueOf(subConf)
fieldVal := reflect.Indirect(subConfRef).FieldByName(ruleName).Interface()
if severity, ok := fieldVal.(Severity); ok && !severity.IsActionable() {
func (conf Configuration) IsActionable(ruleID, controllerName string) bool {
if severity, ok := conf.Checks[ruleID]; !ok || !severity.IsActionable() {
return false
}
if conf.DisallowExemptions {
@@ -33,31 +26,3 @@ func (conf Configuration) IsActionable(subConf interface{}, ruleName, controller
}
return true
}
// GetCategoryConfig returns the configuration for a particular category name
func (conf Configuration) GetCategoryConfig(category string) interface{} {
if category == "Networking" {
return conf.Networking
} else if category == "Security" {
return conf.Security
} else if category == "Health Checks" {
return conf.HealthChecks
} else if category == "Resources" {
return conf.Resources
} else if category == "Images" {
return conf.Images
}
return nil
}
// GetSeverity returns the severity configured for a particular check
func (conf Configuration) GetSeverity(category string, name string) Severity {
subConf := conf.GetCategoryConfig(category)
subConfRef := reflect.ValueOf(subConf)
fieldVal := reflect.Indirect(subConfRef).FieldByName(name).Interface()
if severity, ok := fieldVal.(Severity); ok {
return severity
}
// TODO: don't panic
panic("Unknown severity: " + category + "/" + name)
}
-1
View File
@@ -95,7 +95,6 @@ const (
// SchemaCheck is a Polaris check that runs using JSON Schema
type SchemaCheck struct {
Name string `yaml:"name"`
ID string `yaml:"id"`
Category string `yaml:"category"`
SuccessMessage string `yaml:"successMessage"`
+46 -46
View File
@@ -25,7 +25,7 @@ import (
)
var resourceConfMinimal = `---
resources:
checks:
cpuRequestsMissing: warning
memoryRequestsMissing: warning
cpuLimitsMissing: error
@@ -33,7 +33,7 @@ resources:
`
var resourceConfExemptions = `---
resources:
checks:
cpuRequestsMissing: warning
memoryRequestsMissing: warning
cpuLimitsMissing: error
@@ -338,14 +338,14 @@ func TestValidateResourcesFullyValid(t *testing.T) {
func TestValidateHealthChecks(t *testing.T) {
// Test setup.
p1 := conf.HealthChecks{}
p2 := conf.HealthChecks{
ReadinessProbeMissing: conf.SeverityIgnore,
LivenessProbeMissing: conf.SeverityIgnore,
p1 := make(map[string]conf.Severity)
p2 := map[string]conf.Severity{
"readinessProbeMissing": conf.SeverityIgnore,
"livenessProbeMissing": conf.SeverityIgnore,
}
p3 := conf.HealthChecks{
ReadinessProbeMissing: conf.SeverityError,
LivenessProbeMissing: conf.SeverityWarning,
p3 := map[string]conf.Severity{
"readinessProbeMissing": conf.SeverityError,
"livenessProbeMissing": conf.SeverityWarning,
}
probe := corev1.Probe{}
@@ -375,7 +375,7 @@ func TestValidateHealthChecks(t *testing.T) {
var testCases = []struct {
name string
probes conf.HealthChecks
probes map[string]conf.Severity
cv ContainerValidation
errors *[]*ResultMessage
warnings *[]*ResultMessage
@@ -390,7 +390,7 @@ func TestValidateHealthChecks(t *testing.T) {
for idx, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
err := applyContainerSchemaChecks(&conf.Configuration{HealthChecks: tt.probes}, "", conf.Deployments, &tt.cv)
err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.probes}, "", conf.Deployments, &tt.cv)
if err != nil {
panic(err)
}
@@ -408,14 +408,14 @@ func TestValidateHealthChecks(t *testing.T) {
}
func TestValidateImage(t *testing.T) {
emptyConf := conf.Images{}
standardConf := conf.Images{
TagNotSpecified: conf.SeverityError,
PullPolicyNotAlways: conf.SeverityIgnore,
emptyConf := make(map[string]conf.Severity)
standardConf := map[string]conf.Severity{
"tagNotSpecified": conf.SeverityError,
"pullPolicyNotAlways": conf.SeverityIgnore,
}
strongConf := conf.Images{
TagNotSpecified: conf.SeverityError,
PullPolicyNotAlways: conf.SeverityError,
strongConf := map[string]conf.Severity{
"tagNotSpecified": conf.SeverityError,
"pullPolicyNotAlways": conf.SeverityError,
}
emptyCV := ContainerValidation{
@@ -437,7 +437,7 @@ func TestValidateImage(t *testing.T) {
var testCases = []struct {
name string
image conf.Images
image map[string]conf.Severity
cv ContainerValidation
expected []*ResultMessage
}{
@@ -507,7 +507,7 @@ func TestValidateImage(t *testing.T) {
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
tt.cv = resetCV(tt.cv)
err := applyContainerSchemaChecks(&conf.Configuration{Images: tt.image}, "", conf.Deployments, &tt.cv)
err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.image}, "", conf.Deployments, &tt.cv)
if err != nil {
panic(err)
}
@@ -519,12 +519,12 @@ func TestValidateImage(t *testing.T) {
func TestValidateNetworking(t *testing.T) {
// Test setup.
emptyConf := conf.Networking{}
standardConf := conf.Networking{
HostPortSet: conf.SeverityWarning,
emptyConf := make(map[string]conf.Severity)
standardConf := map[string]conf.Severity{
"hostPortSet": conf.SeverityWarning,
}
strongConf := conf.Networking{
HostPortSet: conf.SeverityError,
strongConf := map[string]conf.Severity{
"hostPortSet": conf.SeverityError,
}
emptyCV := ContainerValidation{
@@ -553,7 +553,7 @@ func TestValidateNetworking(t *testing.T) {
var testCases = []struct {
name string
networkConf conf.Networking
networkConf map[string]conf.Severity
cv ContainerValidation
expectedMessages []*ResultMessage
}{
@@ -629,7 +629,7 @@ func TestValidateNetworking(t *testing.T) {
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
tt.cv = resetCV(tt.cv)
err := applyContainerSchemaChecks(&conf.Configuration{Networking: tt.networkConf}, "", conf.Deployments, &tt.cv)
err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.networkConf}, "", conf.Deployments, &tt.cv)
if err != nil {
panic(err)
}
@@ -644,22 +644,22 @@ func TestValidateSecurity(t *testing.T) {
falseVar := false
// Test setup.
emptyConf := conf.Security{}
standardConf := conf.Security{
RunAsRootAllowed: conf.SeverityWarning,
RunAsPrivileged: conf.SeverityError,
NotReadOnlyRootFileSystem: conf.SeverityWarning,
PrivilegeEscalationAllowed: conf.SeverityError,
DangerousCapabilities: conf.SeverityError,
InsecureCapabilities: conf.SeverityWarning,
emptyConf := map[string]conf.Severity{}
standardConf := map[string]conf.Severity{
"runAsRootAllowed": conf.SeverityWarning,
"runAsPrivileged": conf.SeverityError,
"notReadOnlyRootFileSystem": conf.SeverityWarning,
"privilegeEscalationAllowed": conf.SeverityError,
"dangerousCapabilities": conf.SeverityError,
"insecureCapabilities": conf.SeverityWarning,
}
strongConf := conf.Security{
RunAsRootAllowed: conf.SeverityError,
RunAsPrivileged: conf.SeverityError,
NotReadOnlyRootFileSystem: conf.SeverityError,
PrivilegeEscalationAllowed: conf.SeverityError,
DangerousCapabilities: conf.SeverityError,
InsecureCapabilities: conf.SeverityError,
strongConf := map[string]conf.Severity{
"runAsRootAllowed": conf.SeverityError,
"runAsPrivileged": conf.SeverityError,
"notReadOnlyRootFileSystem": conf.SeverityError,
"privilegeEscalationAllowed": conf.SeverityError,
"dangerousCapabilities": conf.SeverityError,
"insecureCapabilities": conf.SeverityError,
}
emptyCV := ContainerValidation{
@@ -780,7 +780,7 @@ func TestValidateSecurity(t *testing.T) {
var testCases = []struct {
name string
securityConf conf.Security
securityConf map[string]conf.Severity
cv ContainerValidation
expectedMessages []*ResultMessage
}{
@@ -1119,7 +1119,7 @@ func TestValidateSecurity(t *testing.T) {
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
tt.cv = resetCV(tt.cv)
err := applyContainerSchemaChecks(&conf.Configuration{Security: tt.securityConf}, "", conf.Deployments, &tt.cv)
err := applyContainerSchemaChecks(&conf.Configuration{Checks: tt.securityConf}, "", conf.Deployments, &tt.cv)
if err != nil {
panic(err)
}
@@ -1135,8 +1135,8 @@ func TestValidateRunAsRoot(t *testing.T) {
nonRootUser := int64(1000)
rootUser := int64(0)
config := conf.Configuration{
Security: conf.Security{
RunAsRootAllowed: conf.SeverityWarning,
Checks: map[string]conf.Severity{
"runAsRootAllowed": conf.SeverityWarning,
},
}
testCases := []struct {
+9 -9
View File
@@ -29,9 +29,9 @@ import (
func TestValidateController(t *testing.T) {
c := conf.Configuration{
Security: conf.Security{
HostIPCSet: conf.SeverityError,
HostPIDSet: conf.SeverityError,
Checks: map[string]conf.Severity{
"hostIPCSet": conf.SeverityError,
"hostPIDSet": conf.SeverityError,
},
}
deployment := controller.NewDeploymentController(test.MockDeploy())
@@ -64,9 +64,9 @@ func TestValidateController(t *testing.T) {
func TestSkipHealthChecks(t *testing.T) {
c := conf.Configuration{
HealthChecks: conf.HealthChecks{
ReadinessProbeMissing: conf.SeverityError,
LivenessProbeMissing: conf.SeverityWarning,
Checks: map[string]conf.Severity{
"readinessProbeMissing": conf.SeverityError,
"livenessProbeMissing": conf.SeverityWarning,
},
ControllersToScan: []conf.SupportedController{
conf.Deployments,
@@ -139,9 +139,9 @@ func TestSkipHealthChecks(t *testing.T) {
func TestControllerExemptions(t *testing.T) {
c := conf.Configuration{
HealthChecks: conf.HealthChecks{
ReadinessProbeMissing: conf.SeverityError,
LivenessProbeMissing: conf.SeverityWarning,
Checks: map[string]conf.Severity{
"readinessProbeMissing": conf.SeverityError,
"livenessProbeMissing": conf.SeverityWarning,
},
ControllersToScan: []conf.SupportedController{
conf.Deployments,
+3 -3
View File
@@ -16,9 +16,9 @@ func TestGetTemplateData(t *testing.T) {
assert.Equal(t, err, nil, "error should be nil")
c := conf.Configuration{
HealthChecks: conf.HealthChecks{
ReadinessProbeMissing: conf.SeverityError,
LivenessProbeMissing: conf.SeverityWarning,
Checks: map[string]conf.Severity{
"readinessProbeMissing": conf.SeverityError,
"livenessProbeMissing": conf.SeverityWarning,
},
ControllersToScan: []conf.SupportedController{
conf.Deployments,
+28 -38
View File
@@ -24,13 +24,11 @@ import (
func TestValidatePod(t *testing.T) {
c := conf.Configuration{
Security: conf.Security{
HostIPCSet: conf.SeverityError,
HostPIDSet: conf.SeverityError,
},
Networking: conf.Networking{
HostNetworkSet: conf.SeverityWarning,
HostPortSet: conf.SeverityError,
Checks: map[string]conf.Severity{
"hostIPCSet": conf.SeverityError,
"hostPIDSet": conf.SeverityError,
"hostNetworkSet": conf.SeverityWarning,
"hostPortSet": conf.SeverityError,
},
}
@@ -59,8 +57,8 @@ func TestValidatePod(t *testing.T) {
expectedMessages := []*ResultMessage{
{ID: "hostIPCSet", Message: "Host IPC is not configured", Type: "success", Category: "Security"},
{ID: "hostPIDSet", Message: "Host PID is not configured", Type: "success", Category: "Security"},
{ID: "hostNetworkSet", Message: "Host network is not configured", Type: "success", Category: "Networking"},
{ID: "hostPIDSet", Message: "Host PID is not configured", Type: "success", Category: "Security"},
}
actualPodResult := ValidatePod(c, &pod.Spec, "", conf.Deployments)
@@ -72,13 +70,11 @@ func TestValidatePod(t *testing.T) {
func TestInvalidIPCPod(t *testing.T) {
c := conf.Configuration{
Security: conf.Security{
HostIPCSet: conf.SeverityError,
HostPIDSet: conf.SeverityError,
},
Networking: conf.Networking{
HostNetworkSet: conf.SeverityWarning,
HostPortSet: conf.SeverityError,
Checks: map[string]conf.Severity{
"hostIPCSet": conf.SeverityError,
"hostPIDSet": conf.SeverityError,
"hostNetworkSet": conf.SeverityWarning,
"hostPortSet": conf.SeverityError,
},
}
@@ -107,8 +103,8 @@ func TestInvalidIPCPod(t *testing.T) {
}
expectedMessages := []*ResultMessage{
{ID: "hostIPCSet", Message: "Host IPC should not be configured", Type: "error", Category: "Security"},
{ID: "hostPIDSet", Message: "Host PID is not configured", Type: "success", Category: "Security"},
{ID: "hostNetworkSet", Message: "Host network is not configured", Type: "success", Category: "Networking"},
{ID: "hostPIDSet", Message: "Host PID is not configured", Type: "success", Category: "Security"},
}
actualPodResult := ValidatePod(c, &pod.Spec, "", conf.Deployments)
@@ -120,13 +116,11 @@ func TestInvalidIPCPod(t *testing.T) {
func TestInvalidNeworkPod(t *testing.T) {
c := conf.Configuration{
Networking: conf.Networking{
HostNetworkSet: conf.SeverityWarning,
HostPortSet: conf.SeverityError,
},
Security: conf.Security{
HostIPCSet: conf.SeverityError,
HostPIDSet: conf.SeverityError,
Checks: map[string]conf.Severity{
"hostNetworkSet": conf.SeverityWarning,
"hostPortSet": conf.SeverityError,
"hostIPCSet": conf.SeverityError,
"hostPIDSet": conf.SeverityError,
},
}
@@ -170,13 +164,11 @@ func TestInvalidNeworkPod(t *testing.T) {
func TestInvalidPIDPod(t *testing.T) {
c := conf.Configuration{
Security: conf.Security{
HostIPCSet: conf.SeverityError,
HostPIDSet: conf.SeverityError,
},
Networking: conf.Networking{
HostNetworkSet: conf.SeverityWarning,
HostPortSet: conf.SeverityError,
Checks: map[string]conf.Severity{
"hostIPCSet": conf.SeverityError,
"hostPIDSet": conf.SeverityError,
"hostNetworkSet": conf.SeverityWarning,
"hostPortSet": conf.SeverityError,
},
}
@@ -219,13 +211,11 @@ func TestInvalidPIDPod(t *testing.T) {
func TestExemption(t *testing.T) {
c := conf.Configuration{
Security: conf.Security{
HostIPCSet: conf.SeverityError,
HostPIDSet: conf.SeverityError,
},
Networking: conf.Networking{
HostNetworkSet: conf.SeverityWarning,
HostPortSet: conf.SeverityError,
Checks: map[string]conf.Severity{
"hostIPCSet": conf.SeverityError,
"hostNetworkSet": conf.SeverityWarning,
"hostPIDSet": conf.SeverityError,
"hostPortSet": conf.SeverityError,
},
Exemptions: []conf.Exemption{
conf.Exemption{
@@ -259,8 +249,8 @@ func TestExemption(t *testing.T) {
Errors: uint(0),
}
expectedMessages := []*ResultMessage{
{ID: "hostPIDSet", Message: "Host PID is not configured", Type: "success", Category: "Security"},
{ID: "hostNetworkSet", Message: "Host network is not configured", Type: "success", Category: "Networking"},
{ID: "hostPIDSet", Message: "Host PID is not configured", Type: "success", Category: "Security"},
}
actualPodResult := ValidatePod(c, &pod.Spec, "foo", conf.Deployments)
+43 -51
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"io"
"sort"
packr "github.com/gobuffalo/packr/v2"
corev1 "k8s.io/api/core/v1"
@@ -13,25 +14,22 @@ import (
)
var (
schemaBox = (*packr.Box)(nil)
checks = map[config.TargetKind][]config.SchemaCheck{
config.TargetContainer: []config.SchemaCheck{},
config.TargetPod: []config.SchemaCheck{},
}
schemaBox = (*packr.Box)(nil)
builtInChecks = map[string]config.SchemaCheck{}
// We explicitly set the order to avoid thrash in the
// tests as we migrate toward JSON schema
checkOrder = []string{
// Pod checks
"hostIPC",
"hostPID",
"hostNetwork",
"hostIPCSet",
"hostPIDSet",
"hostNetworkSet",
// Container checks
"memoryLimitsMissing",
"memoryRequestsMissing",
"cpuLimitsMissing",
"cpuRequestsMissing",
"readinessProbe",
"livenessProbe",
"readinessProbeMissing",
"livenessProbeMissing",
"pullPolicyNotAlways",
"tagNotSpecified",
"hostPortSet",
@@ -46,8 +44,8 @@ var (
func init() {
schemaBox = packr.New("Schemas", "../../checks")
for _, file := range checkOrder {
contents, err := schemaBox.Find(file + ".yaml")
for _, checkID := range checkOrder {
contents, err := schemaBox.Find(checkID + ".yaml")
if err != nil {
panic(err)
}
@@ -55,7 +53,8 @@ func init() {
if err != nil {
panic(err)
}
checks[check.Target] = append(checks[check.Target], check)
check.ID = checkID
builtInChecks[checkID] = check
}
}
@@ -74,14 +73,21 @@ func parseCheck(rawBytes []byte) (config.SchemaCheck, error) {
}
func applyPodSchemaChecks(conf *config.Configuration, pod *corev1.PodSpec, controllerName string, controllerType config.SupportedController, pv *PodValidation) error {
for _, check := range checks[config.TargetPod] {
if !conf.IsActionable(check.Category, check.Name, controllerName) {
checkIDs := getSortedKeys(conf.Checks)
for _, checkID := range checkIDs {
check, ok := conf.CustomChecks[checkID]
if !ok {
check, ok = builtInChecks[checkID]
}
if !ok {
return fmt.Errorf("Check %s not found", checkID)
}
if !conf.IsActionable(check.ID, controllerName) {
continue
}
if !check.IsActionable(config.TargetPod, controllerType, false) {
continue
}
severity := conf.GetSeverity(check.Category, check.Name)
passes, err := check.CheckPod(pod)
if err != nil {
return err
@@ -89,6 +95,7 @@ func applyPodSchemaChecks(conf *config.Configuration, pod *corev1.PodSpec, contr
if passes {
pv.addSuccess(check.SuccessMessage, check.Category, check.ID)
} else {
severity := conf.Checks[checkID]
pv.addFailure(check.FailureMessage, severity, check.Category, check.ID)
}
}
@@ -96,43 +103,18 @@ func applyPodSchemaChecks(conf *config.Configuration, pod *corev1.PodSpec, contr
}
func applyContainerSchemaChecks(conf *config.Configuration, controllerName string, controllerType config.SupportedController, cv *ContainerValidation) error {
for _, check := range checks[config.TargetContainer] {
if !conf.IsActionable(check.Category, check.Name, controllerName) {
continue
}
if !check.IsActionable(config.TargetContainer, controllerType, cv.IsInitContainer) {
continue
}
severity := conf.GetSeverity(check.Category, check.Name)
var passes bool
var err error
if check.SchemaTarget == config.TargetPod {
cv.parentPodSpec.Containers = []corev1.Container{*cv.Container}
passes, err = check.CheckPod(&cv.parentPodSpec)
cv.parentPodSpec.Containers = []corev1.Container{}
} else {
passes, err = check.CheckContainer(cv.Container)
}
if err != nil {
return err
}
if passes {
cv.addSuccess(check.SuccessMessage, check.Category, check.ID)
} else {
cv.addFailure(check.FailureMessage, severity, check.Category, check.ID)
}
}
for checkName, severity := range conf.Checks {
check, ok := conf.CustomChecks[checkName]
checkIDs := getSortedKeys(conf.Checks)
for _, checkID := range checkIDs {
check, ok := conf.CustomChecks[checkID]
if !ok {
return fmt.Errorf("Custom check %s not found", checkName)
check, ok = builtInChecks[checkID]
}
if !ok {
return fmt.Errorf("Check %s not found", checkID)
}
if !conf.IsActionable(check.ID, controllerName) {
continue
}
// FIXME: check actionability here
/*
if !conf.IsActionable(check.Category, check.Name, controllerName) {
continue
}
*/
if !check.IsActionable(config.TargetContainer, controllerType, cv.IsInitContainer) {
continue
}
@@ -151,8 +133,18 @@ func applyContainerSchemaChecks(conf *config.Configuration, controllerName strin
if passes {
cv.addSuccess(check.SuccessMessage, check.Category, check.ID)
} else {
severity := conf.Checks[checkID]
cv.addFailure(check.FailureMessage, severity, check.Category, check.ID)
}
}
return nil
}
func getSortedKeys(m map[string]config.Severity) []string {
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}