-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
provide support for multiple buildTypes. The initial types are to
support more general slsa verifiers and provide more verbose output for tekton verifiers. This implementation will default to the slsa buildType.
- Loading branch information
1 parent
25e7a6c
commit 51b23bf
Showing
14 changed files
with
937 additions
and
316 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
pkg/chains/formats/slsa/v2alpha2/internal/build_definitions/build_definitions.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package builddefinitions | ||
|
||
const ( | ||
SlsaBuildType = "https://tekton.dev/chains/v2/slsa" | ||
TektonBuildType = "https://tekton.dev/chains/v2/slsa-tekton" | ||
) |
70 changes: 70 additions & 0 deletions
70
pkg/chains/formats/slsa/v2alpha2/internal/build_definitions/pipelinerun.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package builddefinitions | ||
|
||
import ( | ||
"fmt" | ||
|
||
v1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1" | ||
"github.com/tektoncd/chains/pkg/chains/objects" | ||
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" | ||
) | ||
|
||
type PipelineBuildType struct { | ||
BuildType string | ||
Pro *objects.PipelineRunObject | ||
InternalParameters func(*objects.PipelineRunObject) map[string]any | ||
AddTaskDescriptorContent func(*v1beta1.TaskRun) (v1.ResourceDescriptor, error) | ||
} | ||
|
||
// internalParameters adds the tekton feature flags that were enabled | ||
// for the pipelinerun. | ||
func (p PipelineBuildType) GetInternalParameters() map[string]any { | ||
return p.InternalParameters(p.Pro) | ||
} | ||
|
||
// externalParameters adds the pipeline run spec | ||
func (p PipelineBuildType) GetExternalParameters() map[string]any { | ||
externalParams := make(map[string]any) | ||
|
||
// add the origin of top level pipeline config | ||
// isRemotePipeline checks if the pipeline was fetched using a remote resolver | ||
isRemotePipeline := false | ||
if p.Pro.Spec.PipelineRef != nil { | ||
if p.Pro.Spec.PipelineRef.Resolver != "" && p.Pro.Spec.PipelineRef.Resolver != "Cluster" { | ||
isRemotePipeline = true | ||
} | ||
} | ||
|
||
if p := p.Pro.Status.Provenance; p != nil && p.RefSource != nil && isRemotePipeline { | ||
ref := "" | ||
for alg, hex := range p.RefSource.Digest { | ||
ref = fmt.Sprintf("%s:%s", alg, hex) | ||
break | ||
} | ||
buildConfigSource := map[string]string{ | ||
"ref": ref, | ||
"repository": p.RefSource.URI, | ||
"path": p.RefSource.EntryPoint, | ||
} | ||
externalParams["buildConfigSource"] = buildConfigSource | ||
} | ||
externalParams["runSpec"] = p.Pro.Spec | ||
return externalParams | ||
} | ||
|
||
func TektonPipelineInternalParameters(pro *objects.PipelineRunObject) map[string]any { | ||
internalParams := make(map[string]any) | ||
if pro.Status.Provenance != nil && pro.Status.Provenance.FeatureFlags != nil { | ||
internalParams["tekton-pipelines-feature-flags"] = *pro.Status.Provenance.FeatureFlags | ||
} | ||
internalParams["labels"] = pro.ObjectMeta.Labels | ||
internalParams["annotations"] = pro.ObjectMeta.Annotations | ||
return internalParams | ||
} | ||
|
||
func SLSAPipelineInternalParameters(pro *objects.PipelineRunObject) map[string]any { | ||
internalParams := make(map[string]any) | ||
if pro.Status.Provenance != nil && pro.Status.Provenance.FeatureFlags != nil { | ||
internalParams["tekton-pipelines-feature-flags"] = *pro.Status.Provenance.FeatureFlags | ||
} | ||
return internalParams | ||
} |
188 changes: 188 additions & 0 deletions
188
pkg/chains/formats/slsa/v2alpha2/internal/build_definitions/pipelinerun_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
package builddefinitions | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/tektoncd/chains/pkg/chains/objects" | ||
"github.com/tektoncd/pipeline/pkg/apis/config" | ||
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" | ||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
const pipelineFile = "pipeline.yaml" | ||
|
||
func TestPipelineInternalParameters(t *testing.T) { | ||
pr := &v1beta1.PipelineRun{ | ||
Status: v1beta1.PipelineRunStatus{ | ||
PipelineRunStatusFields: v1beta1.PipelineRunStatusFields{ | ||
Provenance: &v1beta1.Provenance{ | ||
FeatureFlags: &config.FeatureFlags{ | ||
RunningInEnvWithInjectedSidecars: true, | ||
EnableAPIFields: "stable", | ||
AwaitSidecarReadiness: true, | ||
VerificationNoMatchPolicy: "skip", | ||
EnableProvenanceInStatus: true, | ||
ResultExtractionMethod: "termination-message", | ||
MaxResultSize: 4096, | ||
}, | ||
}, | ||
}, | ||
}, | ||
ObjectMeta: v1.ObjectMeta{ | ||
Annotations: map[string]string{ | ||
"Annotation1": "Annotation1-value", | ||
}, | ||
Labels: map[string]string{ | ||
"Label1": "Label1-value", | ||
}, | ||
}, | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
buildType PipelineBuildType | ||
want map[string]any | ||
}{ | ||
{ | ||
name: "test slsa verfifier", | ||
buildType: PipelineBuildType{ | ||
BuildType: "slsa build", | ||
Pro: objects.NewPipelineRunObject(pr), | ||
InternalParameters: SLSAPipelineInternalParameters, | ||
}, | ||
want: map[string]any{ | ||
"tekton-pipelines-feature-flags": config.FeatureFlags{ | ||
RunningInEnvWithInjectedSidecars: true, | ||
EnableAPIFields: "stable", | ||
AwaitSidecarReadiness: true, | ||
VerificationNoMatchPolicy: "skip", | ||
EnableProvenanceInStatus: true, | ||
ResultExtractionMethod: "termination-message", | ||
MaxResultSize: 4096, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "test tekton verfifier", | ||
buildType: PipelineBuildType{ | ||
BuildType: "tekton build", | ||
Pro: objects.NewPipelineRunObject(pr), | ||
InternalParameters: TektonPipelineInternalParameters, | ||
}, | ||
want: map[string]any{ | ||
"tekton-pipelines-feature-flags": config.FeatureFlags{ | ||
RunningInEnvWithInjectedSidecars: true, | ||
EnableAPIFields: "stable", | ||
AwaitSidecarReadiness: true, | ||
VerificationNoMatchPolicy: "skip", | ||
EnableProvenanceInStatus: true, | ||
ResultExtractionMethod: "termination-message", | ||
MaxResultSize: 4096, | ||
}, | ||
"annotations": map[string]string{ | ||
"Annotation1": "Annotation1-value", | ||
}, | ||
"labels": map[string]string{ | ||
"Label1": "Label1-value", | ||
}, | ||
}, | ||
}, | ||
} | ||
for _, tc := range tests { | ||
t.Run(tc.name, func(t *testing.T) { | ||
got := tc.buildType.GetInternalParameters() | ||
if d := cmp.Diff(tc.want, got); d != "" { | ||
t.Fatalf("internalParameters (-want, +got):\n%s", d) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestPipelineExternalParameters(t *testing.T) { | ||
pr := &v1beta1.PipelineRun{ | ||
Spec: v1beta1.PipelineRunSpec{ | ||
Params: v1beta1.Params{ | ||
{ | ||
Name: "my-param", | ||
Value: v1beta1.ResultValue{Type: "string", StringVal: "string-param"}, | ||
}, | ||
{ | ||
Name: "my-array-param", | ||
Value: v1beta1.ResultValue{Type: "array", ArrayVal: []string{"my", "array"}}, | ||
}, | ||
{ | ||
Name: "my-empty-string-param", | ||
Value: v1beta1.ResultValue{Type: "string"}, | ||
}, | ||
{ | ||
Name: "my-empty-array-param", | ||
Value: v1beta1.ResultValue{Type: "array", ArrayVal: []string{}}, | ||
}, | ||
}, | ||
PipelineRef: &v1beta1.PipelineRef{ | ||
ResolverRef: v1beta1.ResolverRef{ | ||
Resolver: "git", | ||
}, | ||
}, | ||
}, | ||
Status: v1beta1.PipelineRunStatus{ | ||
PipelineRunStatusFields: v1beta1.PipelineRunStatusFields{ | ||
Provenance: &v1beta1.Provenance{ | ||
RefSource: &v1beta1.RefSource{ | ||
URI: "hello", | ||
Digest: map[string]string{ | ||
"sha1": "abc123", | ||
}, | ||
EntryPoint: pipelineFile, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
buildType PipelineBuildType | ||
want map[string]any | ||
}{ | ||
{ | ||
name: "test slsa verfifier", | ||
buildType: PipelineBuildType{ | ||
BuildType: "slsa build", | ||
Pro: objects.NewPipelineRunObject(pr), | ||
}, | ||
want: map[string]any{ | ||
"buildConfigSource": map[string]string{ | ||
"path": pipelineFile, | ||
"ref": "sha1:abc123", | ||
"repository": "hello", | ||
}, | ||
"runSpec": pr.Spec, | ||
}, | ||
}, | ||
{ | ||
name: "test tekton verfifier", | ||
buildType: PipelineBuildType{ | ||
BuildType: "tekton build", | ||
Pro: objects.NewPipelineRunObject(pr), | ||
}, | ||
want: map[string]any{ | ||
"buildConfigSource": map[string]string{ | ||
"path": pipelineFile, | ||
"ref": "sha1:abc123", | ||
"repository": "hello", | ||
}, | ||
"runSpec": pr.Spec, | ||
}, | ||
}, | ||
} | ||
for _, tc := range tests { | ||
t.Run(tc.name, func(t *testing.T) { | ||
got := tc.buildType.GetExternalParameters() | ||
if d := cmp.Diff(tc.want, got); d != "" { | ||
t.Fatalf("internalParameters (-want, +got):\n%s", d) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.