mirror of
https://github.com/FairwindsOps/polaris.git
synced 2026-05-15 13:47:41 +00:00
initial implementation of updated configuration syntax
This commit is contained in:
138
config.yml
138
config.yml
@@ -1,35 +1,107 @@
|
||||
resources:
|
||||
requests:
|
||||
cpu:
|
||||
min: 50m
|
||||
max: 1
|
||||
memory:
|
||||
min: 100M
|
||||
max: 3G
|
||||
limits:
|
||||
cpu:
|
||||
min: 150m
|
||||
max: 2
|
||||
memory:
|
||||
min: 150M
|
||||
max: 4G
|
||||
healthChecks:
|
||||
readiness:
|
||||
require: true
|
||||
liveness:
|
||||
require: true
|
||||
cpuRequests:
|
||||
onAbsence: warning
|
||||
warning:
|
||||
below: 50m
|
||||
above: 1000m
|
||||
error:
|
||||
below: 500m
|
||||
above: 2000m
|
||||
cpuLimits:
|
||||
onAbsence: warning
|
||||
warning:
|
||||
below: 50m
|
||||
above: 1000m
|
||||
error:
|
||||
below: 500m
|
||||
above: 2000m
|
||||
memoryRequests:
|
||||
onAbsence: warning
|
||||
warning:
|
||||
below: 50M
|
||||
above: 2G
|
||||
error:
|
||||
below: 100M
|
||||
above: 4G
|
||||
memoryLimits:
|
||||
onAbsence: warning
|
||||
warning:
|
||||
below: 50M
|
||||
above: 2G
|
||||
error:
|
||||
below: 100M
|
||||
above: 4G
|
||||
resources:
|
||||
cpuRequests:
|
||||
error:
|
||||
below: 100m
|
||||
above: 1
|
||||
warning:
|
||||
below: 200m
|
||||
above: 800m
|
||||
memoryRequests:
|
||||
error:
|
||||
below: 100M
|
||||
above: 3G
|
||||
warning:
|
||||
below: 200M
|
||||
above: 2G
|
||||
cpuLimits:
|
||||
error:
|
||||
below: 100m
|
||||
above: 2
|
||||
warning:
|
||||
below: 300m
|
||||
above: 1800m
|
||||
memoryLimits:
|
||||
error:
|
||||
below: 200M
|
||||
above: 6G
|
||||
warning:
|
||||
below: 300M
|
||||
above: 4G
|
||||
|
||||
images:
|
||||
tagRequired: true
|
||||
whitelistRepos:
|
||||
- gcr.io
|
||||
hostNetwork:
|
||||
hostAlias:
|
||||
require: true
|
||||
hostIPC:
|
||||
require: true
|
||||
hostNetwork:
|
||||
require: true
|
||||
hostPID:
|
||||
require: true
|
||||
hostPort:
|
||||
require: true
|
||||
tagNotSpecified: 'error'
|
||||
pullPolicyNotAlways: 'warning'
|
||||
error:
|
||||
whitelist:
|
||||
- gcr.io/*
|
||||
warning:
|
||||
blacklist:
|
||||
- docker.io/*
|
||||
healthChecks:
|
||||
readinessProbeMissing: warning
|
||||
livenessProbeMissing: warning
|
||||
networking:
|
||||
hostAliasSet: error
|
||||
hostIPCSet: error
|
||||
hostNetworkSet: error
|
||||
hostPIDSet: error
|
||||
hostPortSet: error
|
||||
security:
|
||||
runAsPriviliged: warning
|
||||
notReadOnlyRootFileSystem: warning
|
||||
runAsNonRoot: warning
|
||||
capabilities:
|
||||
warning:
|
||||
blacklist:
|
||||
- CHOWN
|
||||
- SYS_CHROOT
|
||||
- AUDIT_WRITE
|
||||
error:
|
||||
whitelist:
|
||||
- CHOWN
|
||||
- DAC_OVERRIDE
|
||||
- FSETID
|
||||
- FOWNER
|
||||
- MKNOD
|
||||
- NET_RAW
|
||||
- SETGID
|
||||
- SETUID
|
||||
- SETFCAP
|
||||
- SETPCAP
|
||||
- NET_BIND_SERVICE
|
||||
- SYS_CHROOT
|
||||
- KILL
|
||||
- AUDIT_WRITE
|
||||
|
||||
@@ -6,58 +6,89 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
// Configuration contains all of the config for the validation checks.
|
||||
type Configuration struct {
|
||||
Resources RequestsAndLimits `json:"resources"`
|
||||
HealthChecks Probes `json:"healthChecks"`
|
||||
Images Images `json:"images"`
|
||||
HostNetworking HostNetworking `json:"hostNetworking"`
|
||||
Resources Resources `json:"resources"`
|
||||
HealthChecks HealthChecks `json:"healthChecks"`
|
||||
Images Images `json:"images"`
|
||||
Networking Networking `json:"networking"`
|
||||
Security Security `json:"security"`
|
||||
}
|
||||
|
||||
// RequestsAndLimits contains config for resource requests and limits.
|
||||
type RequestsAndLimits struct {
|
||||
Requests ResourceList `json:"requests"`
|
||||
Limits ResourceList `json:"limits"`
|
||||
// Severity represents the severity of action to take (Ignore, Warning, Error).
|
||||
type Severity string
|
||||
|
||||
// Resources contains config for resource requests and limits.
|
||||
type Resources struct {
|
||||
CPURequests Resource `json:"cpuRequests"`
|
||||
CPULimits Resource `json:"cpuLimits"`
|
||||
MemoryRequests Resource `json:"memoryRequests"`
|
||||
MemoryLimits Resource `json:"memoryLimits"`
|
||||
}
|
||||
|
||||
// ResourceList maps the resource name to a range on min and max values.
|
||||
type ResourceList map[corev1.ResourceName]ResourceMinMax
|
||||
|
||||
// ResourceMinMax sets a range for a min and max setting for a resource.
|
||||
type ResourceMinMax struct {
|
||||
Min *resource.Quantity `json:"min"`
|
||||
Max *resource.Quantity `json:"max"`
|
||||
// Resource contains config for requests or limits for a specific resource.
|
||||
type Resource struct {
|
||||
Absent Severity `json:"absent"`
|
||||
Warning ResourceRange `json:"warning"`
|
||||
Error ResourceRange `json:"error"`
|
||||
}
|
||||
|
||||
// Probes contains config for the readiness and liveness probes.
|
||||
type Probes struct {
|
||||
Readiness ResourceRequire `json:"readiness"`
|
||||
Liveness ResourceRequire `json:"liveness"`
|
||||
// ResourceRange can contain below and above conditions for validation.
|
||||
type ResourceRange struct {
|
||||
Below *resource.Quantity `json:"below"`
|
||||
Above *resource.Quantity `json:"above"`
|
||||
}
|
||||
|
||||
// ResourceRequire indicates if this resource should be validated.
|
||||
type ResourceRequire struct {
|
||||
Require bool `json:"require"`
|
||||
// HealthChecks contains config for readiness and liveness probes.
|
||||
type HealthChecks struct {
|
||||
ReadinessProbeMissing Severity `json:"readinessProbeMissing"`
|
||||
LivenessProbeMissing Severity `json:"livenessProbeMissing"`
|
||||
}
|
||||
|
||||
// Images contains the config for images.
|
||||
type Images struct {
|
||||
TagRequired bool `json:"tagRequired"`
|
||||
WhitelistRepos []string `json:"whitelistRepos"`
|
||||
TagNotSpecified Severity `json:"tagNotSpecified"`
|
||||
PullPolicyNotAlways Severity `json:"pullPolicyNotAlways"`
|
||||
Repositories Repositories `json:"repositories"`
|
||||
}
|
||||
|
||||
// HostNetworking contains the config for host networking validations.
|
||||
type HostNetworking struct {
|
||||
HostAlias ResourceRequire `json:"hostAlias"`
|
||||
HostIPC ResourceRequire `json:"hostIPC"`
|
||||
HostNetwork ResourceRequire `json:"hostNetwork"`
|
||||
HostPID ResourceRequire `json:"hostPID"`
|
||||
HostPort ResourceRequire `json:"hostPort"`
|
||||
// Repositories provides lists of patterns to match or avoid in image tags.
|
||||
type Repositories struct {
|
||||
Error WhitelistBlacklist `json:"error"`
|
||||
Warning WhitelistBlacklist `json:"warning"`
|
||||
}
|
||||
|
||||
// WhitelistBlacklist can contain a whitelist or blacklist.
|
||||
type WhitelistBlacklist struct {
|
||||
Whitelist []string `json:"whitelist"`
|
||||
Blacklist []string `json:"blacklist"`
|
||||
}
|
||||
|
||||
// Networking contains the config for networking validations.
|
||||
type Networking struct {
|
||||
HostAliasSet Severity `json:"hostAliasSet"`
|
||||
HostIPCSet Severity `json:"hostIPCSet"`
|
||||
HostNetworkSet Severity `json:"hostNetworkSet"`
|
||||
HostPIDSet Severity `json:"hostPIDSet"`
|
||||
HostPortSet Severity `json:"hostPortSet"`
|
||||
}
|
||||
|
||||
// Security contains the config for security validations.
|
||||
type Security struct {
|
||||
runAsNonRoot Severity `json:"runAsNonRoot"`
|
||||
runAsPriviliged Severity `json:"runAsPriviliged"`
|
||||
notReadOnlyRootFileSystem Severity `json:"notReadOnlyRootFileSystem"`
|
||||
capabilities SecurityCapabilities `json:"capabilities"`
|
||||
}
|
||||
|
||||
// SecurityCapabilities contains the config for security capabilities validations.
|
||||
type SecurityCapabilities struct {
|
||||
Error WhitelistBlacklist `json:"error"`
|
||||
Warning WhitelistBlacklist `json:"warning"`
|
||||
}
|
||||
|
||||
// ParseFile parses config from a file.
|
||||
|
||||
@@ -25,42 +25,76 @@ var resourceConfInvalid1 = `test`
|
||||
|
||||
var resourceConfYAML1 = `---
|
||||
resources:
|
||||
requests:
|
||||
cpu:
|
||||
min: 100m
|
||||
max: 1
|
||||
memory:
|
||||
min: 100M
|
||||
max: 3G
|
||||
limits:
|
||||
cpu:
|
||||
min: 150m
|
||||
max: 2
|
||||
memory:
|
||||
min: 150M
|
||||
max: 4G
|
||||
cpuRequests:
|
||||
error:
|
||||
below: 100m
|
||||
above: 1
|
||||
warning:
|
||||
below: 200m
|
||||
above: 800m
|
||||
memoryRequests:
|
||||
error:
|
||||
below: 100M
|
||||
above: 3G
|
||||
warning:
|
||||
below: 200M
|
||||
above: 2G
|
||||
cpuLimits:
|
||||
error:
|
||||
below: 100m
|
||||
above: 2
|
||||
warning:
|
||||
below: 300m
|
||||
above: 1800m
|
||||
memoryLimits:
|
||||
error:
|
||||
below: 200M
|
||||
above: 6G
|
||||
warning:
|
||||
below: 300M
|
||||
above: 4G
|
||||
`
|
||||
|
||||
var resourceConfJSON1 = `{
|
||||
"resources": {
|
||||
"requests": {
|
||||
"cpu": {
|
||||
"min": "100m",
|
||||
"max": "1"
|
||||
"cpuRequests": {
|
||||
"error": {
|
||||
"below": "100m",
|
||||
"above": 1
|
||||
},
|
||||
"memory": {
|
||||
"min": "100M",
|
||||
"max": "3G"
|
||||
"warning": {
|
||||
"below": "200m",
|
||||
"above": "800m"
|
||||
}
|
||||
},
|
||||
"limits": {
|
||||
"cpu": {
|
||||
"min": "150m",
|
||||
"max": "2"
|
||||
"memoryRequests": {
|
||||
"error": {
|
||||
"below": "100M",
|
||||
"above": "3G"
|
||||
},
|
||||
"memory": {
|
||||
"min": "150M",
|
||||
"max": "4G"
|
||||
"warning": {
|
||||
"below": "200M",
|
||||
"above": "2G"
|
||||
}
|
||||
},
|
||||
"cpuLimits": {
|
||||
"error": {
|
||||
"below": "100m",
|
||||
"above": 2
|
||||
},
|
||||
"warning": {
|
||||
"below": "300m",
|
||||
"above": "1800m"
|
||||
}
|
||||
},
|
||||
"memoryLimits": {
|
||||
"error": {
|
||||
"below": "200M",
|
||||
"above": "6G"
|
||||
},
|
||||
"warning": {
|
||||
"below": "300M",
|
||||
"above": "4G"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,34 +108,40 @@ func TestParseError(t *testing.T) {
|
||||
|
||||
func TestParseYaml(t *testing.T) {
|
||||
parsedConf, err := Parse([]byte(resourceConfYAML1))
|
||||
assert.NoError(t, err, "Expected no error when parsing config")
|
||||
assert.NoError(t, err, "Expected no error when parsing YAML config")
|
||||
|
||||
requests := parsedConf.Resources.Requests
|
||||
assert.Equal(t, int64(100), requests["cpu"].Min.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(1000), requests["cpu"].Max.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(100), requests["memory"].Min.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(3000), requests["memory"].Max.ScaledValue(resource.Mega))
|
||||
|
||||
limits := parsedConf.Resources.Limits
|
||||
assert.Equal(t, int64(150), limits["cpu"].Min.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(2000), limits["cpu"].Max.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(150), limits["memory"].Min.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(4000), limits["memory"].Max.ScaledValue(resource.Mega))
|
||||
testParsedConfig(t, &parsedConf)
|
||||
}
|
||||
|
||||
func TestParseJson(t *testing.T) {
|
||||
parsedConf, err := Parse([]byte(resourceConfJSON1))
|
||||
assert.NoError(t, err, "Expected no error when parsing config")
|
||||
assert.NoError(t, err, "Expected no error when parsing JSON config")
|
||||
|
||||
requests := parsedConf.Resources.Requests
|
||||
assert.Equal(t, int64(100), requests["cpu"].Min.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(1000), requests["cpu"].Max.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(100), requests["memory"].Min.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(3000), requests["memory"].Max.ScaledValue(resource.Mega))
|
||||
|
||||
limits := parsedConf.Resources.Limits
|
||||
assert.Equal(t, int64(150), limits["cpu"].Min.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(2000), limits["cpu"].Max.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(150), limits["memory"].Min.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(4000), limits["memory"].Max.ScaledValue(resource.Mega))
|
||||
testParsedConfig(t, &parsedConf)
|
||||
}
|
||||
|
||||
func testParsedConfig(t *testing.T, config *Configuration) {
|
||||
cpuRequests := config.Resources.CPURequests
|
||||
assert.Equal(t, int64(100), cpuRequests.Error.Below.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(1000), cpuRequests.Error.Above.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(200), cpuRequests.Warning.Below.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(800), cpuRequests.Warning.Above.ScaledValue(resource.Milli))
|
||||
|
||||
memRequests := config.Resources.MemoryRequests
|
||||
assert.Equal(t, int64(100), memRequests.Error.Below.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(3000), memRequests.Error.Above.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(200), memRequests.Warning.Below.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(2000), memRequests.Warning.Above.ScaledValue(resource.Mega))
|
||||
|
||||
cpuLimits := config.Resources.CPULimits
|
||||
assert.Equal(t, int64(100), cpuLimits.Error.Below.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(2000), cpuLimits.Error.Above.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(300), cpuLimits.Warning.Below.ScaledValue(resource.Milli))
|
||||
assert.Equal(t, int64(1800), cpuLimits.Warning.Above.ScaledValue(resource.Milli))
|
||||
|
||||
memLimits := config.Resources.MemoryLimits
|
||||
assert.Equal(t, int64(200), memLimits.Error.Below.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(6000), memLimits.Error.Above.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(300), memLimits.Warning.Below.ScaledValue(resource.Mega))
|
||||
assert.Equal(t, int64(4000), memLimits.Warning.Above.ScaledValue(resource.Mega))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user