# Custom Checks
If you'd like to create your own checks, you can use JSON Schema (opens new window). This is how built-in Polaris checks are defined as well - you can see all the built-in checks in the checks folder (opens new window) for examples.
If you write a check that could be useful for others, feel free to open a PR to add it in!
# Basic Example
For example, to disallow images from quay.io:
checks:
imageRegistry: warning
customChecks:
imageRegistry:
successMessage: Image comes from allowed registries
failureMessage: Image should not be from disallowed registry
category: Security
target: Container
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
image:
type: string
not:
pattern: ^quay.io
# Available Options
All custom checks should go under the customChecks
field in your Polaris config, keyed by the
check ID. Note that you'll also have to set its severity in the checks
section of your Polaris config.
successMessage
- the message to show when the check succeedsfailureMessage
- the message to show when the check failscategory
- one ofSecurity
,Efficiency
, orReliability
target
- specifies the type of resource to check. This can be:- a group and kind, e.g.
apps/Deployment
ornetworking.k8s.io/Ingress
Controller
, to check any resource that creates Pods (e.g. Deployments, CronJobs, StatefulSets), as well as naked PodsPodTemplate
, same asController
, but the schema applies to the Pod template rather than the top-level controllerPodSpec
, same asController
, but the schema applies to the Pod spec rather than the top-level controllerContainer
same asController
, but the schema applies to all Container specs rather than the top-level controller
- a group and kind, e.g.
controllers
- iftarget
isController
,PodSpec
orContainer
, you can use this to change which types of controllers are checkedcontrollers.include
- only check these controllerscontrollers.exclude
- check all controllers except thesecontainers
- iftarget
isContainer
, you can use this to decide ifinitContainers
,containers
, or both should be checkedcontainers.exclude
- can be set to a list includinginitContainer
orcontainer
schema
- the JSON Schema to check against, as a YAML objectschemaString
- this JSON Schema to check against, as a YAML or JSON string. See Templating below- Note: only one of
schema
andschemaString
can be specified.
- Note: only one of
additionalSchemas
- see Multi-Resource Checks belowadditionalSchemaStrings
- see Multi-Resource Checks below- Note: only one of
additionalSchemas
andadditionalSchemaStrings
can be specified.
- Note: only one of
# Checking CPU and Memory
We extend JSON Schema with resourceMinimum
and resourceMaximum
fields to help compare memory and CPU resource
strings like 1000m
and 1G
. Here's an example check that memory and CPU falls within a certain range.
customChecks:
resourceLimits:
containers:
exclude:
- initContainer
successMessage: Resource limits are within the required range
failureMessage: Resource 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
- cpu
properties:
memory:
type: string
resourceMinimum: 100M
resourceMaximum: 6G
cpu:
type: string
resourceMinimum: 100m
resourceMaximum: "2"
# Resource Presence
You can test for the presence of a resource in each Namespace. For example, to ensure an AlertmanagerConfig is in every Namespace:
successMessage: Namespace has monitoring configuration
failureMessage: Namespace should have monitoring configuration
category: Security
target: Namespace
schema: {}
additionalSchemas:
monitoring.coreos.com/AlertmanagerConfig: {}
# Templating
You can also utilize go templating in your JSON schema in order to match one field against another.
E.g. here is the built-in check to ensure that the name
annotation matches the object's name:
successMessage: Label app.kubernetes.io/name matches metadata.name
failureMessage: Label app.kubernetes.io/name must match metadata.name
target: Controller
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
metadata:
type: object
required: ["labels"]
properties:
labels:
type: object
required: ["app.kubernetes.io/name"]
properties:
app.kubernetes.io/name:
const: "{{ .metadata.name }}"
- The object available via the go template is the full object, and not limited by
target
. - A check of
target: PodSpec
can directly access the pod specification via the go template variable.Polaris.PodSpec
. - A check of
target: PodTemplate
can directly access the pod template via the go template variable.Polaris.PodTemplate
. - A check of
target: Container
can directly access the container being checked via the go template variable.Polaris.container
. The pod template and pod specification can also be accessed via the respective variables.Polaris.PodTemplate
and.Polaris.PodSpec
. Access to pod-level fields allows a container check to consult related fields from the pod, such assecurityContext
.
You can also use the full Go template syntax (opens new window), though
you may need to specify your schema as a string in order to use concepts like range
. E.g.
this check ensures that at least one of the object's labels is present in matchLabels
:
schemaString: |
type: object
properties:
spec:
type: object
required: ["selector"]
properties:
selector:
type: object
required: ["matchLabels"]
properties:
matchLabels:
type: object
anyOf:
{{ range $key, $value := .metadata.labels }}
- properties:
"{{ $key }}":
type: string
const: {{ $value }}
required: ["{{ $key }}"]
{{ end }}
# Additional Go Template Functions
These functions are also available in the GO template.
- hasPrefix (opens new window) - for example,
hasPrefix "string" "prefix"
- hasSuffix (opens new window) - for example,
hasSuffix "string" "suffix"
For example, the hasPrefix
function can be used in a template to determine whether a resource name starts with system:
{{ if hasPrefix .metadata.name "system:" }}
# Multi-Resource Checks
You can write checks that span multiple resources. This is helpful for ensuring e.g. that every Deployment has a PDB or an HPA associated with it.
Here's the check to ensure that every Deployment has a PDB:
successMessage: A PodDisruptionBudget is attached
failureMessage: Should have a PodDisruptionBudget
category: Reliability
target: Controller
controllers:
include:
- Deployment
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
metadata:
type: object
properties:
labels:
type: object
minProperties: 1
additionalSchemaStrings:
policy/PodDisruptionBudget: |
type: object
properties:
spec:
type: object
required: ["selector"]
properties:
selector:
type: object
required: ["matchLabels"]
properties:
matchLabels:
type: object
anyOf:
{{ range $key, $value := .metadata.labels }}
- properties:
"{{ $key }}":
type: string
const: {{ $value }}
required: ["{{ $key }}"]
{{ end }}
# JSON vs YAML
Schemas can also be specified as JSON strings instead of YAML, for easier copy/pasting:
customChecks:
foo:
jsonSchema: |
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object"
}