Skip to content

Commit

Permalink
Merge pull request #14 from Peefy/add-more-validation-examples
Browse files Browse the repository at this point in the history
feat: add more validation examples with e2e test cases
  • Loading branch information
Peefy authored Aug 28, 2023
2 parents bec775e + 71fa70c commit 12cb304
Show file tree
Hide file tree
Showing 70 changed files with 1,084 additions and 232 deletions.
83 changes: 83 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package main

import (
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"testing"

"kcl-lang.io/krm-kcl/pkg/options"

pkg "kcl-lang.io/kpm/pkg/package"
)

type fields struct {
InputPath string
OutputPath string
}

type suite struct {
name string
fields fields
wantErr bool
}

func TestRunExamples(t *testing.T) {
var tests []suite
filepath.Walk("./examples", func(path string, info fs.FileInfo, err error) error {
if !strings.HasSuffix(path, "kcl.mod") {
return nil
}
dir := filepath.Dir(path)

kPkg, err := pkg.LoadKclPkg(dir)
if err != nil {
return err
}
suiteDir := filepath.Join(dir, "suite")
goodSuite := filepath.Join(suiteDir, "good.yaml")
badSuite := filepath.Join(suiteDir, "bad.yaml")

tests = append(tests, suite{
kPkg.GetPkgName() + "-good-suite",
fields{
InputPath: goodSuite,
},
false,
})
// Bad test suite is optional
if FileExists(badSuite) {
tests = append(tests, suite{
dir + "-bad-suite",
fields{
InputPath: badSuite,
},
true,
})
}
return nil
})
fmt.Printf("%d total suites checked\n", len(tests))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
o := &options.RunOptions{
InputPath: tt.fields.InputPath,
OutputPath: tt.fields.OutputPath,
}
if err := o.Run(); (err != nil) != tt.wantErr {
t.Errorf("TestRunHttps() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

// FileExists mark whether the path exists.
func FileExists(path string) bool {
fi, err := os.Lstat(path)
if err != nil || fi.IsDir() {
return false
}
return true
}
13 changes: 6 additions & 7 deletions examples/abstraction/web-service/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: web-service
metadata:
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: abstraction
documentation: >-
Web service application abstraction
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: abstraction
documentation: >-
Web service application abstraction
spec:
params:
name: app
Expand All @@ -23,7 +22,7 @@ spec:
name: app
source: |
resource = option("resource_list")
params = resource.functionConfig.spec.params
params = option("params")
# Convert the `App` model into Kubernetes Deployment and Service Manifests
kubernetesRender = lambda a {
Expand Down
4 changes: 4 additions & 0 deletions examples/mutation/add-capabilities/kcl.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "add-capabilities"
edition = "*"
version = "0.0.1"
Empty file.
7 changes: 7 additions & 0 deletions examples/mutation/add-capabilities/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
capabilities = option("params").capabilities or ["SETUID", "SETFCAP"]
items = [item | {
if item.kind == "Pod":
spec.containers: [{
"securityContext": {"capabilities": {"add" += [c] if c not in (container?.securityContext?.capabilities?.drop or []) else [] for c in capabilities}}
} for container in item.spec.containers]
} for item in option("items")]
29 changes: 29 additions & 0 deletions examples/mutation/add-capabilities/suite/good.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: add-capabilities
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: mutation
documentation: >-
In the earlier Pod Security Policy controller, it was possible to configure a policy
to add capabilities to containers within a Pod. This made it easier to assign some basic defaults
rather than blocking Pods or to simply provide capabilities for certain workloads if not specified.
This policy mutates Pods to add the capabilities SETFCAP and SETUID so long as they are not listed
as dropped capabilities first.
spec:
params:
capabilities:
- SETUID
source: ./examples/mutation/add-capabilities/main.k
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
13 changes: 6 additions & 7 deletions examples/mutation/conditionally-add-annotations/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: conditionally-add-annotations
metadata:
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: mutation
documentation: >-
Conditionally add annotations
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: mutation
documentation: >-
Conditionally add annotations
spec:
params:
toMatch:
Expand All @@ -16,7 +15,7 @@ spec:
configmanagement.gke.io/managed: disabled
source: |
resource = option("resource_list")
params = resource.functionConfig.spec.params
params = option("params")
toMatch = params.toMatch
toAdd = params.toAdd
items = [item | {
Expand Down
13 changes: 6 additions & 7 deletions examples/mutation/conditionally-add-labels/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: conditionally-add-labels
metadata:
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: mutation
documentation: >-
Conditionally add labels
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: mutation
documentation: >-
Conditionally add labels
spec:
params:
toMatch:
Expand All @@ -16,7 +15,7 @@ spec:
configmanagement.gke.io/managed: disabled
source: |
resource = option("resource_list")
params = resource.functionConfig.spec.params
params = option("params")
toMatch = params.toMatch
toAdd = params.toAdd
items = [item | {
Expand Down
2 changes: 1 addition & 1 deletion examples/mutation/set-annotations/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ spec:
config.kubernetes.io/local-config: "true"
source: |
resource = option("resource_list")
params = resource.functionConfig.spec.params
params = option("params")
# Use `k = v` to override existing annotations
annotations = {k = v for k, v in params.annotations}
items = [item | {
Expand Down
2 changes: 1 addition & 1 deletion examples/mutation/set-labels/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ spec:
config.kubernetes.io/local-config: "true"
source: |
resource = option("resource_list")
params = resource.functionConfig.spec.params
params = option("params")
# Use `k = v` to override existing labels
labels = {k = v for k, v in params.labels}
items = [item | {
Expand Down
2 changes: 1 addition & 1 deletion examples/mutation/set-replicas/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ spec:
replicas: 5
source: |
resource = option("resource_list")
replicas = resource.functionConfig.spec.params.replicas
replicas = option("params").replicas
setReplicas = lambda items: [], replicas: int {
[item | {
if item.kind == "Deployment":
Expand Down
28 changes: 0 additions & 28 deletions examples/validation/external-ips/config.yaml

This file was deleted.

4 changes: 4 additions & 0 deletions examples/validation/external-ips/kcl.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "external-ips"
edition = "*"
version = "0.0.1"
Empty file.
10 changes: 10 additions & 0 deletions examples/validation/external-ips/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Define the validation function
validate_external_ips = lambda item, allowedIps: [str] {
if allowedIps and item.kind == "Service" and item.spec.externalIPs:
assert all ip in item.spec.externalIPs {
ip in allowedIps
}, "Service external IPs must be in ${allowedIps} for ${item.kind}: ${item.metadata.name}"
item
}
# Validate All resource
items = [validate_external_ips(i, option("params")?.allowedIps or []) for i in option("items")]
29 changes: 29 additions & 0 deletions examples/validation/external-ips/suite/bad.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: external-ips
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: validation
documentation: >-
Restricts Service externalIPs to an allowed list of IP addresses.
More info: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips
spec:
params:
allowedIps: ["198.51.100.32"]
source: ./examples/validation/external-ips/main.k
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 49152
externalIPs:
- 127.0.0.1
14 changes: 14 additions & 0 deletions examples/validation/external-ips/suite/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: external-ips
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: validation
documentation: >-
Restricts Service externalIPs to an allowed list of IP addresses.
More info: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips
spec:
params:
allowedIps: ["198.51.100.32"]
source: oci://ghcr.io/kcl-lang/external-ips
29 changes: 29 additions & 0 deletions examples/validation/external-ips/suite/good.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: external-ips
annotations:
krm.kcl.dev/version: 0.0.1
krm.kcl.dev/type: validation
documentation: >-
Restricts Service externalIPs to an allowed list of IP addresses.
More info: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips
spec:
params:
allowedIps: ["198.51.100.32"]
source: ./examples/validation/external-ips/main.k
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 49152
externalIPs:
- 198.51.100.32
27 changes: 0 additions & 27 deletions examples/validation/https-only/config.yaml

This file was deleted.

4 changes: 4 additions & 0 deletions examples/validation/https-only/kcl.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "https-only"
edition = "*"
version = "0.0.1"
Empty file.
9 changes: 9 additions & 0 deletions examples/validation/https-only/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
params = option("params")
# Define the validation function
validate_https_only = lambda item {
if item.kind == "Ingress" and item.spec.tls:
assert item.metadata.annotations["kubernetes.io/ingress.allow-http"] == "false", "Ingress should be https. The `kubernetes.io/ingress.allow-http: \"false\"` annotation is required for ${item.kind}: ${item.metadata.name}"
item
}
# Validate All resource
items = [validate_https_only(i) for i in option("items")]
Loading

0 comments on commit 12cb304

Please sign in to comment.