Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add more validation examples with e2e test cases #14

Merged
merged 2 commits into from
Aug 28, 2023
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
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
Loading