Skip to content

Commit c50b3a2

Browse files
committed
support v1 for sign command
1 parent 95548d3 commit c50b3a2

File tree

6 files changed

+133
-63
lines changed

6 files changed

+133
-63
lines changed

pkg/cmd/pipeline/sign.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ import (
2222
"github.com/spf13/cobra"
2323
"github.com/tektoncd/cli/pkg/cli"
2424
"github.com/tektoncd/cli/pkg/trustedresources"
25+
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
2526
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
cliopts "k8s.io/cli-runtime/pkg/genericclioptions"
2729
"sigs.k8s.io/yaml"
2830
)
@@ -31,6 +33,7 @@ type signOptions struct {
3133
keyfile string
3234
kmsKey string
3335
targetFile string
36+
apiVersion string
3437
}
3538

3639
func signCommand() *cobra.Command {
@@ -70,7 +73,13 @@ or using kms
7073
return err
7174
}
7275

73-
crd := &v1beta1.Pipeline{}
76+
var crd metav1.Object
77+
if opts.apiVersion == "v1beta1" {
78+
crd = &v1beta1.Pipeline{}
79+
} else {
80+
crd = &v1.Pipeline{}
81+
}
82+
7483
if err := yaml.Unmarshal(b, &crd); err != nil {
7584
return fmt.Errorf("error unmarshalling Pipeline: %v", err)
7685
}
@@ -87,7 +96,7 @@ or using kms
8796
c.Flags().StringVarP(&opts.keyfile, "key-file", "K", "", "Key file")
8897
c.Flags().StringVarP(&opts.kmsKey, "kms-key", "m", "", "KMS key url")
8998
c.Flags().StringVarP(&opts.targetFile, "file-name", "f", "", "Fle name of the signed pipeline, using the original file name will overwrite the file")
90-
99+
c.Flags().StringVarP(&opts.apiVersion, "version", "v", "v1", "apiVersion of the Pipeline to be signed")
91100
return c
92101
}
93102

pkg/cmd/pipeline/sign_test.go

+43-27
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package pipeline
1616

1717
import (
1818
"context"
19+
"fmt"
1920
"os"
2021
"path/filepath"
2122
"testing"
@@ -28,37 +29,52 @@ import (
2829
func TestSign(t *testing.T) {
2930
ctx := context.Background()
3031
p := &test.Params{}
31-
32-
task := Command(p)
33-
32+
pipeline := Command(p)
3433
os.Setenv("PRIVATE_PASSWORD", "1234")
35-
tmpDir := t.TempDir()
36-
targetFile := filepath.Join(tmpDir, "signed.yaml")
37-
out, err := test.ExecuteCommand(task, "sign", "testdata/pipeline.yaml", "-K", "testdata/cosign.key", "-f", targetFile)
38-
if err != nil {
39-
t.Errorf("Unexpected error: %v", err)
40-
}
41-
expected := "*Warning*: This is an experimental command, it's usage and behavior can change in the next release(s)\nPipeline testdata/pipeline.yaml is signed successfully \n"
42-
test.AssertOutput(t, expected, out)
4334

44-
// verify the signed task
45-
verifier, err := cosignsignature.LoadPublicKey(ctx, "testdata/cosign.pub")
46-
if err != nil {
47-
t.Errorf("error getting verifier from key file: %v", err)
48-
}
35+
testcases := []struct {
36+
name string
37+
taskFile string
38+
apiVersion string
39+
}{{
40+
name: "sign and verify v1beta1 Pipeline",
41+
taskFile: "testdata/pipeline.yaml",
42+
apiVersion: "v1beta1",
43+
}, {
44+
name: "sign and verify v1 Pipeline",
45+
taskFile: "testdata/pipeline-v1.yaml",
46+
apiVersion: "v1",
47+
}}
48+
for _, tc := range testcases {
49+
t.Run(tc.name, func(t *testing.T) {
50+
tmpDir := t.TempDir()
51+
targetFile := filepath.Join(tmpDir, "signed.yaml")
52+
out, err := test.ExecuteCommand(pipeline, "sign", tc.taskFile, "-K", "testdata/cosign.key", "-f", targetFile, "-v", tc.apiVersion)
53+
if err != nil {
54+
t.Errorf("Unexpected error: %v", err)
55+
}
56+
expected := fmt.Sprintf("*Warning*: This is an experimental command, it's usage and behavior can change in the next release(s)\nPipeline %s is signed successfully \n", tc.taskFile)
57+
test.AssertOutput(t, expected, out)
4958

50-
signed, err := os.ReadFile(targetFile)
51-
if err != nil {
52-
t.Fatalf("error reading file: %v", err)
53-
}
59+
// verify the signed task
60+
verifier, err := cosignsignature.LoadPublicKey(ctx, "testdata/cosign.pub")
61+
if err != nil {
62+
t.Errorf("error getting verifier from key file: %v", err)
63+
}
5464

55-
target, signature, err := trustedresources.UnmarshalCRD(signed, "Pipeline")
56-
if err != nil {
57-
t.Fatalf("error unmarshalling crd: %v", err)
58-
}
65+
signed, err := os.ReadFile(targetFile)
66+
if err != nil {
67+
t.Fatalf("error reading file: %v", err)
68+
}
5969

60-
if err := trustedresources.VerifyInterface(target, verifier, signature); err != nil {
61-
t.Fatalf("VerifyInterface get error: %v", err)
62-
}
70+
target, signature, err := trustedresources.UnmarshalCRD(signed, "Pipeline", tc.apiVersion)
71+
if err != nil {
72+
t.Fatalf("error unmarshalling crd: %v", err)
73+
}
6374

75+
if err := trustedresources.VerifyInterface(target, verifier, signature); err != nil {
76+
t.Fatalf("VerifyInterface get error: %v", err)
77+
}
78+
})
79+
}
6480
}

pkg/cmd/task/sign.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ import (
2222
"github.com/spf13/cobra"
2323
"github.com/tektoncd/cli/pkg/cli"
2424
"github.com/tektoncd/cli/pkg/trustedresources"
25+
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
2526
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
cliopts "k8s.io/cli-runtime/pkg/genericclioptions"
2729
"sigs.k8s.io/yaml"
2830
)
@@ -36,6 +38,7 @@ type signOptions struct {
3638
keyfile string
3739
kmsKey string
3840
targetFile string
41+
apiVersion string
3942
}
4043

4144
func signCommand() *cobra.Command {
@@ -74,8 +77,13 @@ or using kms
7477
log.Fatalf("error reading file: %v", err)
7578
return err
7679
}
80+
var crd metav1.Object
81+
if opts.apiVersion == "v1beta1" {
82+
crd = &v1beta1.Task{}
83+
} else {
84+
crd = &v1.Task{}
85+
}
7786

78-
crd := &v1beta1.Task{}
7987
if err := yaml.Unmarshal(b, &crd); err != nil {
8088
return fmt.Errorf("error unmarshalling Task: %v", err)
8189
}
@@ -91,6 +99,6 @@ or using kms
9199
c.Flags().StringVarP(&opts.keyfile, "key-file", "K", "", "Key file")
92100
c.Flags().StringVarP(&opts.kmsKey, "kms-key", "m", "", "KMS key url")
93101
c.Flags().StringVarP(&opts.targetFile, "file-name", "f", "", "file name of the signed task, using the original file name will overwrite the file")
94-
102+
c.Flags().StringVarP(&opts.apiVersion, "version", "v", "v1", "apiVersion of the Task to be signed")
95103
return c
96104
}

pkg/cmd/task/sign_test.go

+43-24
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package task
1616

1717
import (
1818
"context"
19+
"fmt"
1920
"os"
2021
"path/filepath"
2122
"testing"
@@ -32,32 +33,50 @@ func TestSign(t *testing.T) {
3233
task := Command(p)
3334

3435
os.Setenv("PRIVATE_PASSWORD", "1234")
35-
tmpDir := t.TempDir()
36-
targetFile := filepath.Join(tmpDir, "signed.yaml")
37-
out, err := test.ExecuteCommand(task, "sign", "testdata/task.yaml", "-K", "testdata/cosign.key", "-f", targetFile)
38-
if err != nil {
39-
t.Errorf("Unexpected error: %v", err)
40-
}
41-
expected := "*Warning*: This is an experimental command, it's usage and behavior can change in the next release(s)\nTask testdata/task.yaml is signed successfully \n"
42-
test.AssertOutput(t, expected, out)
4336

44-
// verify the signed task
45-
verifier, err := cosignsignature.LoadPublicKey(ctx, "testdata/cosign.pub")
46-
if err != nil {
47-
t.Errorf("error getting verifier from key file: %v", err)
48-
}
37+
testcases := []struct {
38+
name string
39+
taskFile string
40+
apiVersion string
41+
}{{
42+
name: "sign and verify v1beta1 Task",
43+
taskFile: "testdata/task.yaml",
44+
apiVersion: "v1beta1",
45+
}, {
46+
name: "sign and verify v1 Task",
47+
taskFile: "testdata/task-v1.yaml",
48+
apiVersion: "v1",
49+
}}
4950

50-
signed, err := os.ReadFile(targetFile)
51-
if err != nil {
52-
t.Fatalf("error reading file: %v", err)
53-
}
51+
for _, tc := range testcases {
52+
t.Run(tc.name, func(t *testing.T) {
53+
tmpDir := t.TempDir()
54+
targetFile := filepath.Join(tmpDir, "signed.yaml")
55+
out, err := test.ExecuteCommand(task, "sign", tc.taskFile, "-K", "testdata/cosign.key", "-f", targetFile, "-v", tc.apiVersion)
56+
if err != nil {
57+
t.Errorf("Unexpected error: %v", err)
58+
}
59+
expected := fmt.Sprintf("*Warning*: This is an experimental command, it's usage and behavior can change in the next release(s)\nTask %s is signed successfully \n", tc.taskFile)
60+
test.AssertOutput(t, expected, out)
5461

55-
target, signature, err := trustedresources.UnmarshalCRD(signed, "Task")
56-
if err != nil {
57-
t.Fatalf("error unmarshalling crd: %v", err)
58-
}
59-
if err := trustedresources.VerifyInterface(target, verifier, signature); err != nil {
60-
t.Fatalf("VerifyTaskOCIBundle get error: %v", err)
61-
}
62+
// verify the signed task
63+
verifier, err := cosignsignature.LoadPublicKey(ctx, "testdata/cosign.pub")
64+
if err != nil {
65+
t.Errorf("error getting verifier from key file: %v", err)
66+
}
67+
68+
signed, err := os.ReadFile(targetFile)
69+
if err != nil {
70+
t.Fatalf("error reading file: %v", err)
71+
}
6272

73+
target, signature, err := trustedresources.UnmarshalCRD(signed, "Task", tc.apiVersion)
74+
if err != nil {
75+
t.Fatalf("error unmarshalling crd: %v", err)
76+
}
77+
if err := trustedresources.VerifyInterface(target, verifier, signature); err != nil {
78+
t.Fatalf("VerifyInterface get error: %v", err)
79+
}
80+
})
81+
}
6382
}

pkg/trustedresources/sign.go

+22-7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929

3030
"github.com/sigstore/sigstore/pkg/signature"
3131
"github.com/sigstore/sigstore/pkg/signature/kms"
32+
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
3233
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
3334
"golang.org/x/term"
3435
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -114,20 +115,34 @@ func signInterface(signer signature.Signer, i interface{}) ([]byte, error) {
114115
}
115116

116117
// UnmarshalCRD will get the task/pipeline from buffer and extract the signature.
117-
func UnmarshalCRD(buf []byte, kind string) (metav1.Object, []byte, error) {
118+
func UnmarshalCRD(buf []byte, kind string, version string) (metav1.Object, []byte, error) {
118119
var resource metav1.Object
119120
var signature []byte
120121

121122
switch kind {
122123
case "Task":
123-
resource = &v1beta1.Task{}
124-
if err := yaml.Unmarshal(buf, &resource); err != nil {
125-
return nil, nil, err
124+
if version == "v1beta1" {
125+
resource = &v1beta1.Task{}
126+
if err := yaml.Unmarshal(buf, &resource); err != nil {
127+
return nil, nil, err
128+
}
129+
} else {
130+
resource = &v1.Task{}
131+
if err := yaml.Unmarshal(buf, &resource); err != nil {
132+
return nil, nil, err
133+
}
126134
}
127135
case "Pipeline":
128-
resource = &v1beta1.Pipeline{}
129-
if err := yaml.Unmarshal(buf, &resource); err != nil {
130-
return nil, nil, err
136+
if version == "v1beta1" {
137+
resource = &v1beta1.Pipeline{}
138+
if err := yaml.Unmarshal(buf, &resource); err != nil {
139+
return nil, nil, err
140+
}
141+
} else {
142+
resource = &v1.Pipeline{}
143+
if err := yaml.Unmarshal(buf, &resource); err != nil {
144+
return nil, nil, err
145+
}
131146
}
132147
}
133148
annotations := resource.GetAnnotations()

pkg/trustedresources/sign_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,19 @@ func TestSign(t *testing.T) {
7878
resource metav1.Object
7979
kind string
8080
targetFile string
81+
apiVersion string
8182
}{{
8283
name: "Task Sign and pass verification",
8384
resource: getTask(),
8485
kind: "Task",
8586
targetFile: "signed-task.yaml",
87+
apiVersion: "v1beta1",
8688
}, {
8789
name: "Pipeline Sign and pass verification",
8890
resource: getPipeline(),
8991
kind: "Pipeline",
9092
targetFile: "signed-pipeline.yaml",
93+
apiVersion: "v1beta1",
9194
},
9295
}
9396

@@ -101,7 +104,7 @@ func TestSign(t *testing.T) {
101104
t.Fatalf("error reading file: %v", err)
102105
}
103106

104-
target, signature, err := UnmarshalCRD(signed, tc.kind)
107+
target, signature, err := UnmarshalCRD(signed, tc.kind, tc.apiVersion)
105108
if err != nil {
106109
t.Fatalf("error unmarshalling crd: %v", err)
107110
}

0 commit comments

Comments
 (0)