Skip to content

Commit

Permalink
feat: update chain's controllers to use v1 Tekton APIs natively while…
Browse files Browse the repository at this point in the history
… converting to v1beta1 to keep formats backwards compatible
  • Loading branch information
aaron-prindle committed Dec 14, 2023
1 parent 61dd9f2 commit 6fe2a77
Show file tree
Hide file tree
Showing 112 changed files with 9,429 additions and 1,482 deletions.
1 change: 0 additions & 1 deletion .github/workflows/kind-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ jobs:
fail-fast: false # Keep running if one leg fails.
matrix:
pipelines-release:
- v0.41.3 # LTS
- v0.44.4 # LTS
- v0.47.3 # LTS
- v0.50.1 # LTS
Expand Down
2 changes: 1 addition & 1 deletion cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ func main() {
flag.Parse()
ctx := injection.WithNamespaceScope(signals.NewContext(), *namespace)

sharedmain.MainWithContext(ctx, "watcher", taskrun.NewController, pipelinerun.NewController)
sharedmain.MainWithContext(ctx, "watcher", taskrun.NewControllerV1, pipelinerun.NewControllerV1)
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/tektoncd/chains

go 1.20
go 1.21

require (
cloud.google.com/go/compute/metadata v0.2.3
Expand Down Expand Up @@ -268,6 +268,7 @@ require (
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/jstemmer/go-junit-report v1.0.0 // indirect
github.com/julz/importas v0.1.0 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jstemmer/go-junit-report v1.0.0 h1:8X1gzZpR+nVQLAht+L/foqOeX2l9DTZoaIPbEQHxsds=
github.com/jstemmer/go-junit-report v1.0.0/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
Expand Down
123 changes: 69 additions & 54 deletions pkg/artifacts/signable.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@ import (
"context"
_ "crypto/sha256" // Recommended by go-digest.
_ "crypto/sha512" // Recommended by go-digest.
"encoding/json"
"fmt"
"regexp"
"strings"

"github.com/google/go-containerregistry/pkg/name"
"github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
"github.com/opencontainers/go-digest"
"github.com/opentracing/opentracing-go/log"
"github.com/tektoncd/chains/internal/backport"
"github.com/tektoncd/chains/pkg/chains/objects"
"github.com/tektoncd/chains/pkg/config"
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
"k8s.io/apimachinery/pkg/util/sets"
"knative.dev/pkg/logging"
Expand Down Expand Up @@ -65,12 +68,12 @@ type TaskRunArtifact struct{}
var _ Signable = &TaskRunArtifact{}

func (ta *TaskRunArtifact) ShortKey(obj interface{}) string {
tro := obj.(*objects.TaskRunObject)
tro := obj.(*objects.TaskRunObjectV1)
return "taskrun-" + string(tro.UID)
}

func (ta *TaskRunArtifact) FullKey(obj interface{}) string {
tro := obj.(*objects.TaskRunObject)
tro := obj.(*objects.TaskRunObjectV1)
gvk := tro.GetGroupVersionKind()
return fmt.Sprintf("%s-%s-%s-%s", gvk.Group, gvk.Version, gvk.Kind, tro.UID)
}
Expand Down Expand Up @@ -104,12 +107,12 @@ type PipelineRunArtifact struct{}
var _ Signable = &PipelineRunArtifact{}

func (pa *PipelineRunArtifact) ShortKey(obj interface{}) string {
pro := obj.(*objects.PipelineRunObject)
pro := obj.(*objects.PipelineRunObjectV1)
return "pipelinerun-" + string(pro.UID)
}

func (pa *PipelineRunArtifact) FullKey(obj interface{}) string {
pro := obj.(*objects.PipelineRunObject)
pro := obj.(*objects.PipelineRunObjectV1)
gvk := pro.GetGroupVersionKind()
return fmt.Sprintf("%s-%s-%s-%s", gvk.Group, gvk.Version, gvk.Kind, pro.UID)
}
Expand Down Expand Up @@ -149,40 +152,56 @@ type image struct {
}

func (oa *OCIArtifact) ExtractObjects(ctx context.Context, obj objects.TektonObject) []interface{} {
log := logging.FromContext(ctx)
objs := []interface{}{}

// TODO: Not applicable to PipelineRuns, should look into a better way to separate this out
if tr, ok := obj.GetObject().(*v1beta1.TaskRun); ok {
imageResourceNames := map[string]*image{}
if tr.Status.TaskSpec != nil && tr.Status.TaskSpec.Resources != nil {
for _, output := range tr.Status.TaskSpec.Resources.Outputs {
if output.Type == backport.PipelineResourceTypeImage {
imageResourceNames[output.Name] = &image{}
}
if trV1, ok := obj.GetObject().(*v1.TaskRun); ok {
var resources v1beta1.TaskResources //nolint:staticcheck
shouldReplace := false
if serializedResources, ok := trV1.Annotations["tekton.dev/v1beta1-status-taskrunstatusfields-taskspec-resources"]; ok {
if err := json.Unmarshal([]byte(serializedResources), &resources); err == nil {
shouldReplace = true
}
}

for _, rr := range tr.Status.ResourcesResult {
img, ok := imageResourceNames[rr.ResourceName]
if !ok {
continue
}
// We have a result for an image!
if rr.Key == "url" {
img.url = rr.Value
} else if rr.Key == "digest" {
img.digest = rr.Value
var results []v1beta1.RunResult //nolint:staticcheck
if serializedResources, ok := trV1.Annotations["tekton.dev/v1beta1ResourcesResult"]; ok {
if err := json.Unmarshal([]byte(serializedResources), &results); err == nil {
shouldReplace = shouldReplace && true
}
}
trV1Beta1 := &v1beta1.TaskRun{} //nolint:staticcheck
if err := trV1Beta1.ConvertFrom(ctx, trV1); err == nil {
if shouldReplace {
trV1Beta1.Status.TaskSpec.Resources = &resources //nolint:staticcheck
trV1Beta1.Status.ResourcesResult = results //nolint:staticcheck
}
imageResourceNames := map[string]*image{}
if trV1Beta1.Status.TaskSpec != nil && trV1Beta1.Status.TaskSpec.Resources != nil { //nolint:staticcheck
for _, output := range trV1Beta1.Status.TaskSpec.Resources.Outputs { //nolint:staticcheck
if output.Type == backport.PipelineResourceTypeImage {
imageResourceNames[output.Name] = &image{}
}
}
}
for _, rr := range trV1Beta1.Status.ResourcesResult {
img, ok := imageResourceNames[rr.ResourceName]
if !ok {
continue
}
// We have a result for an image!
if rr.Key == "url" {
img.url = rr.Value
} else if rr.Key == "digest" {
img.digest = rr.Value
}
}

for _, image := range imageResourceNames {
dgst, err := name.NewDigest(fmt.Sprintf("%s@%s", image.url, image.digest))
if err != nil {
log.Error(err)
continue
for _, image := range imageResourceNames {
dgst, err := name.NewDigest(fmt.Sprintf("%s@%s", image.url, image.digest))
if err != nil {
log.Error(err)
continue
}
objs = append(objs, dgst)
}
objs = append(objs, dgst)
}
}

Expand All @@ -197,6 +216,7 @@ func ExtractOCIImagesFromResults(ctx context.Context, obj objects.TektonObject)
logger := logging.FromContext(ctx)
objs := []interface{}{}

logger.Infof("aprindle-10 - here")
extractor := structuredSignableExtractor{
uriSuffix: "IMAGE_URL",
digestSuffix: "IMAGE_DIGEST",
Expand All @@ -205,19 +225,19 @@ func ExtractOCIImagesFromResults(ctx context.Context, obj objects.TektonObject)
for _, s := range extractor.extract(ctx, obj) {
dgst, err := name.NewDigest(fmt.Sprintf("%s@%s", s.URI, s.Digest))
if err != nil {
logger.Infof("aprindle-11 - here")
logger.Errorf("error getting digest: %v", err)
continue
}

objs = append(objs, dgst)
}

// look for a comma separated list of images
for _, key := range obj.GetResults() {
if key.Name != "IMAGES" {
if key.GetName() != "IMAGES" {
continue
}
imgs := strings.FieldsFunc(key.Value.StringVal, split)
imgs := strings.FieldsFunc(key.GetStringValue(), split)

for _, img := range imgs {
trimmed := strings.TrimSpace(img)
Expand All @@ -226,12 +246,14 @@ func ExtractOCIImagesFromResults(ctx context.Context, obj objects.TektonObject)
}
dgst, err := name.NewDigest(trimmed)
if err != nil {
logger.Infof("aprindle-12 - here")
logger.Errorf("error getting digest for img %s: %v", trimmed, err)
continue
}
objs = append(objs, dgst)
}
}
logger.Infof("aprindle-13 - here")

return objs
}
Expand Down Expand Up @@ -291,43 +313,36 @@ func ExtractStructuredTargetFromResults(ctx context.Context, obj objects.TektonO
}

// TODO(#592): support structured results using Run
results := []objects.Result{}
for _, res := range obj.GetResults() {
results = append(results, objects.Result{
Name: res.Name,
Value: res.Value,
})
}
for _, res := range results {
if strings.HasSuffix(res.Name, categoryMarker) {
if strings.HasSuffix(res.GetName(), categoryMarker) {
valid, err := isStructuredResult(res, categoryMarker)
if err != nil {
logger.Debugf("ExtractStructuredTargetFromResults: %v", err)
}
if valid {
logger.Debugf("Extracted Structured data from Result %s, %s", res.Value.ObjectVal["uri"], res.Value.ObjectVal["digest"])
objs = append(objs, &StructuredSignable{URI: res.Value.ObjectVal["uri"], Digest: res.Value.ObjectVal["digest"]})
logger.Debugf("Extracted Structured data from Result %v", res)
objs = append(objs, &StructuredSignable{URI: res.GetObjectValue("uri"), Digest: res.GetObjectValue("digest")})
}
}
}
return objs
}

func isStructuredResult(res objects.Result, categoryMarker string) (bool, error) {
if !strings.HasSuffix(res.Name, categoryMarker) {
func isStructuredResult(res objects.GenericResult, categoryMarker string) (bool, error) {
if !strings.HasSuffix(res.GetName(), categoryMarker) {
return false, nil
}
if res.Value.ObjectVal == nil {
return false, fmt.Errorf("%s should be an object: %v", res.Name, res.Value.ObjectVal)
if res.ObjectValueIsNil() {
return false, fmt.Errorf("%s should be an object: %v", res.GetName(), res)
}
if res.Value.ObjectVal["uri"] == "" {
return false, fmt.Errorf("%s should have uri field: %v", res.Name, res.Value.ObjectVal)
if res.GetObjectValue("uri") == "" {
return false, fmt.Errorf("%s should have uri field: %v", res.GetName(), res)
}
if res.Value.ObjectVal["digest"] == "" {
return false, fmt.Errorf("%s should have digest field: %v", res.Name, res.Value.ObjectVal)
if res.GetObjectValue("digest") == "" {
return false, fmt.Errorf("%s should have digest field: %v", res.GetName(), res)
}
if _, _, err := ParseDigest(res.Value.ObjectVal["digest"]); err != nil {
return false, fmt.Errorf("error getting digest %s: %v", res.Value.ObjectVal["digest"], err)
if _, _, err := ParseDigest(res.GetObjectValue("digest")); err != nil {
return false, fmt.Errorf("error getting digest %s: %v", res.GetObjectValue("digest"), err)
}
return true, nil
}
Expand Down
Loading

0 comments on commit 6fe2a77

Please sign in to comment.