Skip to content

Commit

Permalink
Migrate policy-controller-validate to use kyaml
Browse files Browse the repository at this point in the history
  • Loading branch information
Mengqi Yu committed Mar 30, 2021
1 parent 245c206 commit 7d6a45e
Show file tree
Hide file tree
Showing 18 changed files with 1,299 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exitCode: 1
runCount: 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: policy-controller-validate
items:
- message: |+
Found 1 violations:
[1] The following banned keys are being used in the config map: {"private_key"}
name: "super-secret"
path: resources.yaml
violatedConstraint: no-secrets-in-configmap
severity: error
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# policy-controller-validate: invalid configmap

## Overview

This example demonstrates how to validate config maps using a constraint.

There are 3 resources: a ConstraintTemplate, a K8sBannedConfigMapKeysV1 and a
ConfigMap.
The constraint disallows `private_key` to be used as a key in the config map.

## Function invocation

```shell
kpt pkg get https://github.com/GoogleContainerTools/kpt-functions-catalog.git/examples/validators/policy-controller-validate/invalid-configmap .
kpt fn run invalid-configmap
```

## Expected result

It should complain like the following:

```
Found 1 violations:
[1] The following banned keys are being used in the config map: {"private_key"}
name: "super-secret"
path: resources.yaml
violatedConstraint: no-secrets-in-configmap
error: exit status 1
```

In the `resources.yaml` file, replace the key `private_key` in the config map
with something else e.g. `public_key` to pass validation.
Rerun the command. It will succeed (no output).

## Function Reference

TODO: add the link
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: my-func-config
annotations:
config.k8s.io/function: |
container:
image: gcr.io/kpt-fn/policy-controller-validate:unstable
config.kubernetes.io/local-config: 'true'
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sbannedconfigmapkeysv1
spec:
crd:
spec:
names:
kind: K8sBannedConfigMapKeysV1
validation:
openAPIV3Schema:
properties:
keys:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |-
package ban_keys
violation[{"msg": sprintf("%v", [val])}] {
keys = {key | input.review.object.data[key]}
banned = {key | input.parameters.keys[_] = key}
overlap = keys & banned
count(overlap) > 0
val := sprintf("The following banned keys are being used in the config map: %v", [overlap])
}
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBannedConfigMapKeysV1
metadata:
name: no-secrets-in-configmap
spec:
match:
kinds:
- apiGroups:
- ''
kinds:
- ConfigMap
parameters:
keys:
- private_key
---
apiVersion: v1
kind: ConfigMap
metadata:
name: super-secret
namespace: default
data:
private_key: sensitive data goes here
3 changes: 2 additions & 1 deletion functions/go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ FUNCTIONS := \
set-namespace \
starlark \
apply-setters \
search-replace
search-replace \
policy-controller-validate

# Targets for running all function tests
FUNCTION_TESTS := $(patsubst %,%-TEST,$(FUNCTIONS))
Expand Down
15 changes: 15 additions & 0 deletions functions/go/policy-controller-validate/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM golang:1.15-alpine3.12
ENV CGO_ENABLED=0
WORKDIR /go/src/

COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN go build -o /usr/local/bin/validate ./

#############################################

FROM alpine:3.12
COPY --from=0 /usr/local/bin/validate /usr/local/bin/validate
ENTRYPOINT ["validate"]
126 changes: 126 additions & 0 deletions functions/go/policy-controller-validate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# policy-controller-validate

### Overview

<!--mdtogo:Short-->

Validate the KRM resources using the policy controller.

<!--mdtogo-->


config-root/.../*-constraint.yaml and *-template.yaml define Policy Controller constraints and templates which all configs in config-root/ must pass.

### Synopsis

<!--mdtogo:Long-->
You can use the policy controller to validate KRM resources. To learn more about
the policy controller, see: https://cloud.google.com/anthos-config-management/docs/concepts/policy-controller.

The function takes 3 types of resources from the input resource list:

- constraint templates
- constraints
- KRM resources to be audited against

Every constraint should be backed by a constraint template that defines the
schema and logic of the constraint.

The function uses the constraints to audit the input KRM resources.

To learn more about how to write constraint templates and constraints, see:
https://cloud.google.com/anthos-config-management/docs/how-to/write-a-constraint-template
and
https://cloud.google.com/anthos-config-management/docs/how-to/creating-constraints.
<!--mdtogo-->

### Examples

<!--mdtogo:Examples-->
We have a constraint template which defines a rule that a config map can't have
any keys defined in the banned keys.

```yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sbannedconfigmapkeysv1
spec:
crd:
spec:
names:
kind: K8sBannedConfigMapKeysV1
validation:
openAPIV3Schema:
properties:
keys:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |-
package ban_keys
violation[{"msg": sprintf("%v", [val])}] {
keys = {key | input.review.object.data[key]}
banned = {key | input.parameters.keys[_] = key}
overlap = keys & banned
count(overlap) > 0
val := sprintf("The following banned keys are being used in the config map: %v", [overlap])
}
```
We also have a constraint backed by the above constraint template. It defines
the target resources are the config maps, and the banned keys list only contains
"private-key".
```yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBannedConfigMapKeysV1
metadata:
name: no-secrets-in-configmap
spec:
match:
kinds:
- apiGroups:
- ''
kinds:
- ConfigMap
parameters:
keys:
- private_key
```
We have a config map to be audited.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: super-secret
namespace: default
data:
private_key: sensitive data goes here
```
To run the function to audit the resources:
```shell
kpt fn run gcr.io/kpt-fn/policy-controller-validate:unstable .
```

We will see the following validation error:
```
Found 1 violations:
[1] The following banned keys are being used in the config map: {"private_key"}
name: "super-secret"
path: resources.yaml
violatedConstraint: no-secrets-in-configmap
error: exit status 1
```

<!--mdtogo-->
103 changes: 103 additions & 0 deletions functions/go/policy-controller-validate/generated/docs.go

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

11 changes: 11 additions & 0 deletions functions/go/policy-controller-validate/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/policy-controller-validate

go 1.15

require (
github.com/open-policy-agent/frameworks/constraint v0.0.0-20210317225149-4f80ac172ddf
github.com/open-policy-agent/gatekeeper v3.0.4-beta.2+incompatible
k8s.io/apimachinery v0.17.2
sigs.k8s.io/kustomize/kyaml v0.10.13
sigs.k8s.io/yaml v1.2.0
)
Loading

0 comments on commit 7d6a45e

Please sign in to comment.