Skip to content

Commit 06b94e1

Browse files
authored
verify-definition task used to run ec validate definition (conforma#545)
* create verify-definition task to run validate definition * remove bash based task tests * all task tests are in acceptance tests
1 parent f2deeee commit 06b94e1

File tree

13 files changed

+273
-145
lines changed

13 files changed

+273
-145
lines changed

.github/workflows/checks.yaml

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -92,31 +92,4 @@ jobs:
9292
with:
9393
files: ./coverage-acceptance.out
9494
flags: acceptance
95-
96-
Task:
97-
runs-on: ubuntu-latest
98-
env:
99-
TASK_BUNDLE_REF: registry.image-registry.svc.cluster.local:5000/ec-task-bundle
100-
steps:
101-
- name: Checkout repository
102-
uses: actions/checkout@v3
103-
104-
- name: Restore Cache
105-
uses: actions/cache/restore@v3
106-
with:
107-
key: main
108-
path: '**'
109-
110-
- name: Setup Go environment
111-
uses: actions/setup-go@v4
112-
with:
113-
go-version-file: go.mod
114-
cache: false
115-
116-
- name: Setup Tekton Test environment
117-
run: hack/setup-test-environment.sh
118-
119-
- name: Testing ec task
120-
env:
121-
TASK_VERSION: 0.1
122-
run: tasks/verify-enterprise-contract/tests/run.sh
95+

.github/workflows/release.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ jobs:
3434
env:
3535
IMAGE_REPO: quay.io/hacbs-contract/ec-cli
3636
TAG: ${{ github.sha }}
37-
TASK: tasks/verify-enterprise-contract/0.1/verify-enterprise-contract.yaml
3837

3938
steps:
4039
- name: Checkout repository
@@ -108,4 +107,6 @@ jobs:
108107
run: make dist-image-push IMAGE_TAG=$TAG IMAGE_REPO=$IMAGE_REPO ADD_IMAGE_TAG=snapshot
109108

110109
- name: Create and push the tekton bundle
110+
env:
111+
TASK: "tasks/verify-enterprise-contract/0.1/verify-enterprise-contract.yaml,tasks/verify-definition/0.1/verify-definition.yaml"
111112
run: make task-bundle-snapshot TASK_TAG=$TAG TASK=<( yq e ".spec.steps[].image? = \"$IMAGE_REPO:$TAG\"" $TASK)

acceptance/kubernetes/kind/image.go

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"fmt"
2323
"os"
2424
"os/exec"
25-
"path"
2625
"path/filepath"
2726
"runtime"
2827
"strings"
@@ -54,74 +53,78 @@ func (k *kindCluster) buildCliImage(ctx context.Context) error {
5453
// only the task of a particular version. The image reference to the ec-cli
5554
// image is replaced with the image reference from buildCliImage.
5655
func (k *kindCluster) buildTaskBundleImage(ctx context.Context) error {
57-
versions, err := filepath.Glob(path.Join("tasks/verify-enterprise-contract", "*.*"))
56+
taskBundles := make(map[string][]string)
57+
58+
basePath := "tasks/"
59+
taskDirs, err := os.ReadDir(basePath)
5860
if err != nil {
5961
return err
6062
}
6163

62-
for _, version := range versions {
63-
if info, err := os.Stat(version); err != nil {
64-
return err
65-
} else if !info.IsDir() {
64+
for _, task := range taskDirs {
65+
if !task.IsDir() {
6666
continue
6767
}
68-
69-
// we expect a file called `verify-enterprise-contract.yaml` in each
70-
// version containing the Tekton Task definition
71-
taskFile := path.Join(version, "verify-enterprise-contract.yaml")
72-
73-
if info, err := os.Stat(taskFile); err != nil {
74-
if errors.Is(err, os.ErrNotExist) {
75-
continue
76-
}
77-
68+
// once all the directories under tasks/ are collected, gather all the versions
69+
versions, err := filepath.Glob(filepath.Join(basePath, task.Name(), "*.*"))
70+
if err != nil {
7871
return err
79-
} else if info.IsDir() {
80-
continue
8172
}
73+
for _, versionPath := range versions {
74+
pathSplit := strings.Split(versionPath, "/")
75+
// there should only be versions under the task path i.e. tasks/verify-definition/0.1
76+
version := pathSplit[len(pathSplit)-1]
77+
// assume the task definition file is named the same as the task directory
78+
fileName := filepath.Join(versionPath, fmt.Sprintf("%s.yaml", task.Name()))
79+
if _, err := os.Stat(fileName); err != nil {
80+
if errors.Is(err, os.ErrNotExist) {
81+
continue
82+
}
83+
return err
84+
}
85+
var bytes []byte
86+
if bytes, err = os.ReadFile(fileName); err != nil {
87+
return err
88+
}
8289

83-
var bytes []byte
84-
if bytes, err = os.ReadFile(taskFile); err != nil {
85-
return err
86-
}
90+
var taskDefinition v1beta1.Task
91+
if err := yaml.Unmarshal(bytes, &taskDefinition); err != nil {
92+
return err
93+
}
8794

88-
var taskDefinition v1beta1.Task
89-
if err := yaml.Unmarshal(bytes, &taskDefinition); err != nil {
90-
return err
91-
}
95+
// using registry.image-registry.svc.cluster.local instead of 127.0.0.1
96+
// leads to "dial tcp: lookup registry.image-registry.svc.cluster.local:
97+
// Temporary failure in name resolution" in Tekton Pipeline controller
98+
img := fmt.Sprintf("127.0.0.1:%d/ec-cli:latest-%s-%s", k.registryPort, runtime.GOOS, runtime.GOARCH)
99+
steps := taskDefinition.Spec.Steps
100+
for i, step := range steps {
101+
if strings.Contains(step.Image, "/ec-cli:") {
102+
steps[i].Image = img
103+
}
104+
}
92105

93-
// using registry.image-registry.svc.cluster.local instead of 127.0.0.1
94-
// leads to "dial tcp: lookup registry.image-registry.svc.cluster.local:
95-
// Temporary failure in name resolution" in Tekton Pipeline controller
96-
img := fmt.Sprintf("127.0.0.1:%d/ec-cli:latest-%s-%s", k.registryPort, runtime.GOOS, runtime.GOARCH)
97-
steps := taskDefinition.Spec.Steps
98-
for i, step := range steps {
99-
if strings.Contains(step.Image, "/ec-cli:") {
100-
steps[i].Image = img
106+
out, err := yaml.Marshal(taskDefinition)
107+
if err != nil {
108+
return err
101109
}
102-
}
103110

104-
out, err := yaml.Marshal(taskDefinition)
105-
if err != nil {
106-
return err
107-
}
111+
task, err := os.CreateTemp("", "v-e-c-*.yaml")
112+
if err != nil {
113+
return err
114+
}
115+
defer os.Remove(task.Name())
108116

109-
task, err := os.CreateTemp("", "v-e-c-*.yaml")
110-
if err != nil {
111-
return err
112-
}
113-
defer os.Remove(task.Name())
117+
if _, err = task.Write(out); err != nil {
118+
return err
119+
}
114120

115-
if _, err = task.Write(out); err != nil {
116-
return err
121+
taskBundles[version] = append(taskBundles[version], task.Name())
117122
}
123+
}
118124

119-
// given a path like task/0.1 is `0.1` which gives us the version of the
120-
// Task by the directory layout convention for the Tekton/Artifact Hub
121-
ver := path.Base(version)
122-
123-
cmd := exec.CommandContext(ctx, "make", "task-bundle", fmt.Sprintf("TASK_REPO=localhost:%d/ec-task-bundle", k.registryPort), fmt.Sprintf("TASK=%s", task.Name()), fmt.Sprintf("TASK_TAG=%s", ver))
124-
125+
for version, tasks := range taskBundles {
126+
tasksPath := strings.Join(tasks, ",")
127+
cmd := exec.CommandContext(ctx, "make", "task-bundle", fmt.Sprintf("TASK_REPO=localhost:%d/ec-task-bundle", k.registryPort), fmt.Sprintf("TASK=%s", tasksPath), fmt.Sprintf("TASK_TAG=%s", version))
125128
if out, err := cmd.CombinedOutput(); err != nil {
126129
fmt.Print(string(out))
127130
return err

acceptance/kubernetes/kind/kubernetes.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ func stringParam(name, value string, t *testState) tknv1beta1.Param {
243243

244244
// RunTask creates a TaskRun with a random name running the Task from the Tekton
245245
// Bundle of a specific version with the provided parameters
246-
func (k *kindCluster) RunTask(ctx context.Context, version string, params map[string]string) error {
246+
func (k *kindCluster) RunTask(ctx context.Context, version, name, workspace string, params map[string]string) error {
247247
t := testenv.FetchState[testState](ctx)
248248

249249
tkn, err := tekton.NewForConfig(k.config)
@@ -261,19 +261,28 @@ func (k *kindCluster) RunTask(ctx context.Context, version string, params map[st
261261
return err
262262
}
263263

264+
var wkspace []tknv1beta1.WorkspaceBinding
265+
if workspace != "" {
266+
wkspace = append(wkspace, tknv1beta1.WorkspaceBinding{
267+
Name: workspace,
268+
EmptyDir: &v1.EmptyDirVolumeSource{},
269+
})
270+
}
271+
264272
tr, err := tkn.TaskRuns(t.namespace).Create(ctx, &tknv1beta1.TaskRun{
265273
ObjectMeta: metav1.ObjectMeta{
266274
GenerateName: "acceptance-taskrun-",
267275
},
268276
Spec: tknv1beta1.TaskRunSpec{
277+
Workspaces: wkspace,
269278
Params: tknParams,
270279
ServiceAccountName: "default",
271280
TaskRef: &tknv1beta1.TaskRef{
272281
ResolverRef: tknv1beta1.ResolverRef{
273282
Resolver: "bundles",
274283
Params: []tknv1beta1.Param{
275284
stringParam("bundle", fmt.Sprintf("registry.image-registry.svc.cluster.local:%d/ec-task-bundle:%s", k.registryPort, version), t),
276-
stringParam("name", "verify-enterprise-contract", t),
285+
stringParam("name", name, t),
277286
stringParam("kind", "task", t),
278287
},
279288
},

acceptance/kubernetes/kubernetes.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ func createPolicy(ctx context.Context, specification *godog.DocString) error {
133133
return c.cluster.CreatePolicy(ctx, specification.Content)
134134
}
135135

136-
func runTask(ctx context.Context, version string, params *godog.Table) error {
136+
func runTask(ctx context.Context, version, name string, params *godog.Table) error {
137+
return runTaskWithWorkspace(ctx, version, name, "", params)
138+
}
139+
140+
func runTaskWithWorkspace(ctx context.Context, version, name, workspace string, params *godog.Table) error {
137141
c := testenv.FetchState[ClusterState](ctx)
138142

139143
if err := mustBeUp(ctx, *c); err != nil {
@@ -145,7 +149,7 @@ func runTask(ctx context.Context, version string, params *godog.Table) error {
145149
taskParams[row.Cells[0].Value] = row.Cells[1].Value
146150
}
147151

148-
return c.cluster.RunTask(ctx, version, taskParams)
152+
return c.cluster.RunTask(ctx, version, name, workspace, taskParams)
149153
}
150154

151155
func theTaskShouldSucceed(ctx context.Context) error {
@@ -229,7 +233,8 @@ func AddStepsTo(sc *godog.ScenarioContext) {
229233
sc.Step(`^a working namespace$`, createNamespace)
230234
sc.Step(`^policy configuration named "([^"]*)" with specification$`, createNamedPolicy)
231235
sc.Step(`^a cluster policy with content:$`, createPolicy)
232-
sc.Step(`^version ([\d.]+) of the task is run with parameters:$`, runTask)
236+
sc.Step(`^version ([\d.]+) of the task named "([^"]*)" is run with parameters:$`, runTask)
237+
sc.Step(`^version ([\d.]+) of the task named "([^"]*)" with workspace "([^"]*)" is run with parameters:$`, runTaskWithWorkspace)
233238
sc.Step(`^the task should succeed$`, theTaskShouldSucceed)
234239
sc.Step(`^an Snapshot named "([^"]*)" with specification$`, createNamedSnapshot)
235240
// stops the cluster unless the environment is persisted, the cluster state

acceptance/kubernetes/stub/stub.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func (s stubCluster) CreatePolicy(_ context.Context, _ string) error {
107107
return errors.New("use `Given policy configuration named \"<name>\" with specification` when using the stub Kubernetes")
108108
}
109109

110-
func (s stubCluster) RunTask(_ context.Context, _ string, _ map[string]string) error {
110+
func (s stubCluster) RunTask(_ context.Context, _, _, _ string, _ map[string]string) error {
111111
return errors.New("can't run tasks when using the stub Kubernetes")
112112
}
113113

acceptance/kubernetes/types/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type Cluster interface {
2727
CreateNamespace(context.Context) (context.Context, error)
2828
CreateNamedPolicy(context.Context, string, string) error
2929
CreatePolicy(context.Context, string) error
30-
RunTask(context.Context, string, map[string]string) error
30+
RunTask(context.Context, string, string, string, map[string]string) error
3131
AwaitUntilTaskIsDone(context.Context) (bool, error)
3232
TaskInfo(context.Context) (*TaskInfo, error)
3333
CreateNamedSnapshot(context.Context, string, string) error
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Feature: Verify Enterprise Contract Tekton Tasks
2+
The Verify Enterprise Contract Tekton task verification against a set of golden images
3+
4+
Background:
5+
Given a cluster running
6+
7+
Scenario: Verifying a simple task definition
8+
Given a working namespace
9+
10+
When version 0.1 of the task named "verify-definition" with workspace "output" is run with parameters:
11+
| DEFINITION | {"kind": "Task"} |
12+
| POLICY_SOURCE | git::github.com/hacbs-contract/ec-policies//policy/task |
13+
| NAMESPACE | policy.task.kind |
14+
Then the task should succeed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Feature: Verify Enterprise Contract Tekton Task
1+
Feature: Verify Enterprise Contract Tekton Tasks
22
The Verify Enterprise Contract Tekton task verification against a set of golden images
33

44
Background:
@@ -24,7 +24,7 @@ Feature: Verify Enterprise Contract Tekton Task
2424
}
2525
}
2626
```
27-
When version 0.1 of the task is run with parameters:
27+
When version 0.1 of the task named "verify-enterprise-contract" is run with parameters:
2828
| IMAGES | {"components": [{"containerImage": "quay.io/hacbs-contract-demo/golden-container@sha256:e76a4ae9dd8a52a0d191fd34ca133af5b4f2609536d32200a4a40a09fdc93a0d"}]} |
2929
| POLICY_CONFIGURATION | ${NAMESPACE}/${POLICY_NAME} |
3030
| STRICT | true |
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Verify Definition Task
2+
3+
This task is used to verify any valid YAML or JSON
4+
5+
## Install the task
6+
kubectl apply -f https://raw.githubusercontent.com/hacbs-contract/ec-cli/main/tasks/verify-definition/0.1/verify-definition.yaml
7+
8+
## Parameters
9+
### Required
10+
* **DEFINITION**: The definition(s) to validate. This can be a yaml or json file, the files' contents
11+
or a directory containing the definition files.
12+
* **POLICY_SOURCE**: The source containing the policy files.
13+
### Optional
14+
* **NAMESPACE**: An optional policy package namespace.
15+
* **POLICY_LIB**: The source containing the policy files libraries.
16+
* **POLICY_DATA**: The source containing the policy files configuration data.
17+
* **HOMEDIR**: Value for the HOME environment variable.
18+
19+
## Usage
20+
This TaskRun runs the Task to verify the JSON string '{"kind": "Task"}'.
21+
22+
```yaml
23+
---
24+
apiVersion: tekton.dev/v1beta1
25+
kind: TaskRun
26+
metadata:
27+
generateName: verify-definition-run-
28+
spec:
29+
params:
30+
- name: HOMEDIR
31+
value: /tekton/home
32+
- name: DEFINITION
33+
value: '{"kind": "Task"}'
34+
- name: NAMESPACE
35+
value: policy.task.kind
36+
- name: POLICY_SOURCE
37+
value: git::github.com/hacbs-contract/ec-policies//policy/task
38+
resources: {}
39+
serviceAccountName: default
40+
taskRef:
41+
resolver: bundles
42+
params:
43+
- name: bundle
44+
value: ${TASK_BUNDLE_REF}
45+
- name: name
46+
value: verify-definition
47+
- name: kind
48+
value: task
49+
timeout: 10m
50+
```
51+
52+
53+

0 commit comments

Comments
 (0)