Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ install: manifests

# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
deploy: manifests
kubectl get node
touch -a ./overlays/dev/manager_image_patch.yaml
kubectl apply -f config/crds
kubectl apply -f vendor/github.com/open-policy-agent/frameworks/constraint/deploy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ anyrule[}}}//invalid//rego
if len(status.Errors) != 1 {
return errors.New("InvalidRego template should contain 1 parse error")
} else {
if status.Errors[0].Code != "create_error" {
if status.Errors[0].Code != "rego_parse_error" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surprised this test has been passing

return errors.New(fmt.Sprintf("InvalidRego template returning unexpected error %s", status.Errors[0].Code))
}
return nil
Expand Down
221 changes: 113 additions & 108 deletions test/bats/tests/templates/k8scontainterlimits_template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,121 +20,126 @@ spec:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
libs:
- |
package lib.helpers

missing(obj, field) = true {
not obj[field]
}

missing(obj, field) = true {
obj[field] == ""
}

canonify_cpu(orig) = new {
is_number(orig)
new := orig * 1000
}

canonify_cpu(orig) = new {
not is_number(orig)
endswith(orig, "m")
new := to_number(replace(orig, "m", ""))
}

canonify_cpu(orig) = new {
not is_number(orig)
not endswith(orig, "m")
re_match("^[0-9]+$", orig)
new := to_number(orig) * 1000
}

# 10 ** 18
mem_multiple("E") = 1000000000000000000 { true }

# 10 ** 15
mem_multiple("P") = 1000000000000000 { true }

# 10 ** 12
mem_multiple("T") = 1000000000000 { true }

# 10 ** 9
mem_multiple("G") = 1000000000 { true }

# 10 ** 6
mem_multiple("M") = 1000000 { true }

# 10 ** 3
mem_multiple("K") = 1000 { true }

# 10 ** 0
mem_multiple("") = 1 { true }

# 2 ** 10
mem_multiple("Ki") = 1024 { true }

# 2 ** 20
mem_multiple("Mi") = 1048576 { true }

# 2 ** 30
mem_multiple("Gi") = 1073741824 { true }

# 2 ** 40
mem_multiple("Ti") = 1099511627776 { true }

# 2 ** 50
mem_multiple("Pi") = 1125899906842624 { true }

# 2 ** 60
mem_multiple("Ei") = 1152921504606846976 { true }

get_suffix(mem) = suffix {
not is_string(mem)
suffix := ""
}

get_suffix(mem) = suffix {
is_string(mem)
suffix := substring(mem, count(mem) - 1, -1)
mem_multiple(suffix)
}

get_suffix(mem) = suffix {
is_string(mem)
suffix := substring(mem, count(mem) - 2, -1)
mem_multiple(suffix)
}

get_suffix(mem) = suffix {
is_string(mem)
not substring(mem, count(mem) - 1, -1)
not substring(mem, count(mem) - 2, -1)
suffix := ""
}

canonify_mem(orig) = new {
is_number(orig)
new := orig
}

canonify_mem(orig) = new {
not is_number(orig)
suffix := get_suffix(orig)
raw := replace(orig, suffix, "")
new := to_number(raw) * mem_multiple(suffix)
}
rego: |
package k8scontainerlimits
import data.lib.helpers

missing(obj, field) = true {
not obj[field]
}

missing(obj, field) = true {
obj[field] == ""
}

canonify_cpu(orig) = new {
is_number(orig)
new := orig * 1000
}

canonify_cpu(orig) = new {
not is_number(orig)
endswith(orig, "m")
new := to_number(replace(orig, "m", ""))
}

canonify_cpu(orig) = new {
not is_number(orig)
not endswith(orig, "m")
re_match("^[0-9]+$", orig)
new := to_number(orig) * 1000
}

# 10 ** 18
mem_multiple("E") = 1000000000000000000 { true }

# 10 ** 15
mem_multiple("P") = 1000000000000000 { true }

# 10 ** 12
mem_multiple("T") = 1000000000000 { true }

# 10 ** 9
mem_multiple("G") = 1000000000 { true }

# 10 ** 6
mem_multiple("M") = 1000000 { true }

# 10 ** 3
mem_multiple("K") = 1000 { true }

# 10 ** 0
mem_multiple("") = 1 { true }

# 2 ** 10
mem_multiple("Ki") = 1024 { true }

# 2 ** 20
mem_multiple("Mi") = 1048576 { true }

# 2 ** 30
mem_multiple("Gi") = 1073741824 { true }

# 2 ** 40
mem_multiple("Ti") = 1099511627776 { true }

# 2 ** 50
mem_multiple("Pi") = 1125899906842624 { true }

# 2 ** 60
mem_multiple("Ei") = 1152921504606846976 { true }

get_suffix(mem) = suffix {
not is_string(mem)
suffix := ""
}

get_suffix(mem) = suffix {
is_string(mem)
suffix := substring(mem, count(mem) - 1, -1)
mem_multiple(suffix)
}

get_suffix(mem) = suffix {
is_string(mem)
suffix := substring(mem, count(mem) - 2, -1)
mem_multiple(suffix)
}

get_suffix(mem) = suffix {
is_string(mem)
not substring(mem, count(mem) - 1, -1)
not substring(mem, count(mem) - 2, -1)
suffix := ""
}

canonify_mem(orig) = new {
is_number(orig)
new := orig
}

canonify_mem(orig) = new {
not is_number(orig)
suffix := get_suffix(orig)
raw := replace(orig, suffix, "")
new := to_number(raw) * mem_multiple(suffix)
}

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
cpu_orig := container.resources.limits.cpu
not canonify_cpu(cpu_orig)
not helpers.canonify_cpu(cpu_orig)
msg := sprintf("container <%v> cpu limit <%v> could not be parsed", [container.name, cpu_orig])
}

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
mem_orig := container.resources.limits.memory
not canonify_mem(mem_orig)
not helpers.canonify_mem(mem_orig)
msg := sprintf("container <%v> memory limit <%v> could not be parsed", [container.name, mem_orig])
}

Expand All @@ -152,32 +157,32 @@ spec:

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
missing(container.resources.limits, "cpu")
helpers.missing(container.resources.limits, "cpu")
msg := sprintf("container <%v> has no cpu limit", [container.name])
}

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
missing(container.resources.limits, "memory")
helpers.missing(container.resources.limits, "memory")
msg := sprintf("container <%v> has no memory limit", [container.name])
}

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
cpu_orig := container.resources.limits.cpu
cpu := canonify_cpu(cpu_orig)
cpu := helpers.canonify_cpu(cpu_orig)
max_cpu_orig := input.parameters.cpu
max_cpu := canonify_cpu(max_cpu_orig)
max_cpu := helpers.canonify_cpu(max_cpu_orig)
cpu > max_cpu
msg := sprintf("container <%v> cpu limit <%v> is higher than the maximum allowed of <%v>", [container.name, cpu_orig, max_cpu_orig])
}

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
mem_orig := container.resources.limits.memory
mem := canonify_mem(mem_orig)
mem := helpers.canonify_mem(mem_orig)
max_mem_orig := input.parameters.memory
max_mem := canonify_mem(max_mem_orig)
max_mem := helpers.canonify_mem(max_mem_orig)
mem > max_mem
msg := sprintf("container <%v> memory limit <%v> is higher than the maximum allowed of <%v>", [container.name, mem_orig, max_mem_orig])
}
Loading