mirror of
https://github.com/FairwindsOps/polaris.git
synced 2026-08-22 21:56:32 +00:00
* Start working on updating dependencies: * Fix webhook * Rollback jsonschema update * Checkin new config * Fix run as root * Update versions of kind * Fix typo in kind URL * Fix kind config * Add csr permissions * Fix weird image thing * Fixed certificates * Add to logging * Approve cert manually * Fix approval * Add cert script * Fix deployment * Add requests/limits * Wait if certificate doesn't exist yet * Add check for file size * Add variable * Try a different imagE * Fix command * Update certificate logic * Add healthz * Don't check cert size * Remove stat * Fix vet * Put in change that makes no sense * Fix cert names * Roll back * Try changing config * Add logging for each request * Cleanup code some * Remove bad deployments * Fix client injection * Update timeout * Add logging * Fixed e2e webhook tests * Add permissions for approval * Fix permissions for CSR * Remove logging code * Remove refresh certs file * Fix merge issues * Update deployments * Try beta of admission controller config * Target 1.15 for testing * Add beta versions of resourceS * Lower webhook timeout * Refactor out a method * Fix up PR issues * Fix more tabs * Remove unnecessary messageS * Fix go.sum * Fix go.sum
264 lines
6.5 KiB
Go
264 lines
6.5 KiB
Go
package validator
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
conf "github.com/fairwindsops/polaris/pkg/config"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/resource"
|
|
)
|
|
|
|
var customCheckExemptions = `
|
|
checks:
|
|
foo: danger
|
|
customChecks:
|
|
foo:
|
|
successMessage: success!
|
|
failureMessage: fail!
|
|
target: Container
|
|
category: Security
|
|
schema:
|
|
properties:
|
|
image:
|
|
pattern: ^quay.io
|
|
exemptions:
|
|
- controllerNames:
|
|
- exempt
|
|
rules:
|
|
- foo
|
|
`
|
|
|
|
var resourceConfRanges = `
|
|
checks:
|
|
memoryRequestsRange: danger
|
|
memoryLimitsRange: warning
|
|
customChecks:
|
|
memoryLimitsRange:
|
|
containers:
|
|
exclude:
|
|
- initContainer
|
|
successMessage: Memory limits are within the required range
|
|
failureMessage: Memory limits should be within the required range
|
|
category: Resources
|
|
target: Container
|
|
schema:
|
|
'$schema': http://json-schema.org/draft-07/schema
|
|
type: object
|
|
required:
|
|
- resources
|
|
properties:
|
|
resources:
|
|
type: object
|
|
required:
|
|
- limits
|
|
properties:
|
|
limits:
|
|
type: object
|
|
required:
|
|
- memory
|
|
properties:
|
|
memory:
|
|
type: string
|
|
resourceMinimum: 200M
|
|
resourceMaximum: 6G
|
|
memoryRequestsRange:
|
|
successMessage: Memory requests are within the required range
|
|
failureMessage: Memory requests should be within the required range
|
|
category: Resources
|
|
target: Container
|
|
containers:
|
|
exclude:
|
|
- initContainer
|
|
schema:
|
|
'$schema': http://json-schema.org/draft-07/schema
|
|
type: object
|
|
required:
|
|
- resources
|
|
properties:
|
|
resources:
|
|
type: object
|
|
required:
|
|
- requests
|
|
properties:
|
|
requests:
|
|
required:
|
|
- memory
|
|
properties:
|
|
memory:
|
|
type: string
|
|
resourceMinimum: 200M
|
|
resourceMaximum: 3G
|
|
`
|
|
|
|
func TestValidateResourcesPartiallyValid(t *testing.T) {
|
|
cpuRequest, err := resource.ParseQuantity("100m")
|
|
assert.NoError(t, err, "Error parsing quantity")
|
|
|
|
cpuLimit, err := resource.ParseQuantity("200m")
|
|
assert.NoError(t, err, "Error parsing quantity")
|
|
|
|
container := corev1.Container{
|
|
Name: "Empty",
|
|
Resources: corev1.ResourceRequirements{
|
|
Requests: corev1.ResourceList{
|
|
"cpu": cpuRequest,
|
|
},
|
|
Limits: corev1.ResourceList{
|
|
"cpu": cpuLimit,
|
|
},
|
|
},
|
|
}
|
|
|
|
expectedWarnings := []ResultMessage{
|
|
{
|
|
ID: "memoryLimitsRange",
|
|
Success: false,
|
|
Severity: "warning",
|
|
Message: "Memory limits should be within the required range",
|
|
Category: "Resources",
|
|
},
|
|
}
|
|
|
|
expectedDangers := []ResultMessage{
|
|
{
|
|
ID: "memoryRequestsRange",
|
|
Success: false,
|
|
Severity: "danger",
|
|
Message: "Memory requests should be within the required range",
|
|
Category: "Resources",
|
|
},
|
|
}
|
|
|
|
expectedSuccesses := []ResultMessage{}
|
|
|
|
testValidate(t, &container, &resourceConfRanges, "foo", expectedDangers, expectedWarnings, expectedSuccesses)
|
|
}
|
|
|
|
func TestValidateResourcesInit(t *testing.T) {
|
|
emptyContainer := &corev1.Container{}
|
|
controller := getEmptyWorkload(t, "")
|
|
|
|
parsedConf, err := conf.Parse([]byte(resourceConfRanges))
|
|
assert.NoError(t, err, "Expected no error when parsing config")
|
|
|
|
results, err := applyContainerSchemaChecks(context.Background(), &parsedConf, controller, emptyContainer, false)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
assert.Equal(t, uint(1), results.GetSummary().Dangers)
|
|
assert.Equal(t, uint(1), results.GetSummary().Warnings)
|
|
|
|
results, err = applyContainerSchemaChecks(context.Background(), &parsedConf, controller, emptyContainer, true)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
assert.Equal(t, uint(0), results.GetSummary().Dangers)
|
|
assert.Equal(t, uint(0), results.GetSummary().Warnings)
|
|
}
|
|
|
|
func TestValidateResourcesFullyValid(t *testing.T) {
|
|
cpuRequest, err := resource.ParseQuantity("300m")
|
|
assert.NoError(t, err, "Error parsing quantity")
|
|
|
|
cpuLimit, err := resource.ParseQuantity("400m")
|
|
assert.NoError(t, err, "Error parsing quantity")
|
|
|
|
memoryRequest, err := resource.ParseQuantity("400Mi")
|
|
assert.NoError(t, err, "Error parsing quantity")
|
|
|
|
memoryLimit, err := resource.ParseQuantity("500Mi")
|
|
assert.NoError(t, err, "Error parsing quantity")
|
|
|
|
container := corev1.Container{
|
|
Name: "Empty",
|
|
Resources: corev1.ResourceRequirements{
|
|
Requests: corev1.ResourceList{
|
|
"cpu": cpuRequest,
|
|
"memory": memoryRequest,
|
|
},
|
|
Limits: corev1.ResourceList{
|
|
"cpu": cpuLimit,
|
|
"memory": memoryLimit,
|
|
},
|
|
},
|
|
}
|
|
|
|
expectedSuccesses := []ResultMessage{
|
|
{
|
|
ID: "memoryRequestsRange",
|
|
Success: true,
|
|
Severity: "danger",
|
|
Message: "Memory requests are within the required range",
|
|
Category: "Resources",
|
|
},
|
|
{
|
|
ID: "memoryLimitsRange",
|
|
Success: true,
|
|
Severity: "warning",
|
|
Message: "Memory limits are within the required range",
|
|
Category: "Resources",
|
|
},
|
|
}
|
|
|
|
testValidate(t, &container, &resourceConfRanges, "foo", []ResultMessage{}, []ResultMessage{}, expectedSuccesses)
|
|
|
|
expectedSuccesses = []ResultMessage{
|
|
{
|
|
ID: "cpuRequestsMissing",
|
|
Success: true,
|
|
Severity: "warning",
|
|
Message: "CPU requests are set",
|
|
Category: "Resources",
|
|
},
|
|
{
|
|
ID: "memoryRequestsMissing",
|
|
Success: true,
|
|
Severity: "warning",
|
|
Message: "Memory requests are set",
|
|
Category: "Resources",
|
|
},
|
|
{
|
|
ID: "cpuLimitsMissing",
|
|
Success: true,
|
|
Severity: "danger",
|
|
Message: "CPU limits are set",
|
|
Category: "Resources",
|
|
},
|
|
{
|
|
ID: "memoryLimitsMissing",
|
|
Success: true,
|
|
Severity: "danger",
|
|
Message: "Memory limits are set",
|
|
Category: "Resources",
|
|
},
|
|
}
|
|
|
|
testValidate(t, &container, &resourceConfMinimal, "foo", []ResultMessage{}, []ResultMessage{}, expectedSuccesses)
|
|
}
|
|
|
|
func TestValidateCustomCheckExemptions(t *testing.T) {
|
|
container := corev1.Container{
|
|
Name: "example",
|
|
Image: "hub.docker.com/foo",
|
|
}
|
|
|
|
expectedWarnings := []ResultMessage{}
|
|
expectedDangers := []ResultMessage{}
|
|
expectedSuccesses := []ResultMessage{}
|
|
testValidate(t, &container, &customCheckExemptions, "exempt", expectedDangers, expectedWarnings, expectedSuccesses)
|
|
|
|
expectedDangers = []ResultMessage{
|
|
{
|
|
ID: "foo",
|
|
Success: false,
|
|
Severity: "danger",
|
|
Message: "fail!",
|
|
Category: "Security",
|
|
},
|
|
}
|
|
testValidate(t, &container, &customCheckExemptions, "notexempt", expectedDangers, expectedWarnings, expectedSuccesses)
|
|
}
|