1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 15:37:19 +00:00

refactor: image utils (#3630)

Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
This commit is contained in:
Charles-Edouard Brétéché 2022-04-20 17:01:02 +02:00 committed by GitHub
parent 12bbca2477
commit 2e1a87d149
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 151 additions and 81 deletions

View file

@ -974,19 +974,13 @@ func (in *Rule) DeepCopyInto(out *Rule) {
in, out := &in.ImageExtractors, &out.ImageExtractors in, out := &in.ImageExtractors, &out.ImageExtractors
*out = make(kube.ImageExtractorConfigs, len(*in)) *out = make(kube.ImageExtractorConfigs, len(*in))
for key, val := range *in { for key, val := range *in {
var outVal []*kube.ImageExtractorConfig var outVal []kube.ImageExtractorConfig
if val == nil { if val == nil {
(*out)[key] = nil (*out)[key] = nil
} else { } else {
in, out := &val, &outVal in, out := &val, &outVal
*out = make([]*kube.ImageExtractorConfig, len(*in)) *out = make([]kube.ImageExtractorConfig, len(*in))
for i := range *in { copy(*out, *in)
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(kube.ImageExtractorConfig)
**out = **in
}
}
} }
(*out)[key] = outVal (*out)[key] = outVal
} }

View file

@ -8,7 +8,6 @@ import (
jsonpatch "github.com/evanphx/json-patch/v5" jsonpatch "github.com/evanphx/json-patch/v5"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1" kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
pkgcommon "github.com/kyverno/kyverno/pkg/common" pkgcommon "github.com/kyverno/kyverno/pkg/common"
imageutils "github.com/kyverno/kyverno/pkg/utils/image"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"github.com/pkg/errors" "github.com/pkg/errors"
admissionv1 "k8s.io/api/admission/v1" admissionv1 "k8s.io/api/admission/v1"
@ -60,17 +59,17 @@ type Interface interface {
AddElement(data map[string]interface{}, index int) error AddElement(data map[string]interface{}, index int) error
// AddImageInfo adds image info to the context // AddImageInfo adds image info to the context
AddImageInfo(info imageutils.ImageInfo) error AddImageInfo(info kubeutils.ImageInfo) error
// AddImageInfos adds image infos to the context // AddImageInfos adds image infos to the context
AddImageInfos(resource *unstructured.Unstructured) error AddImageInfos(resource *unstructured.Unstructured) error
// ImageInfo returns image infos present in the context // ImageInfo returns image infos present in the context
ImageInfo() map[string]map[string]imageutils.ImageInfo ImageInfo() map[string]map[string]kubeutils.ImageInfo
// GenerateCustomImageInfo returns image infos as defined by a custom image extraction config // GenerateCustomImageInfo returns image infos as defined by a custom image extraction config
// and updates the context // and updates the context
GenerateCustomImageInfo(resource *unstructured.Unstructured, imageExtractorConfigs kubeutils.ImageExtractorConfigs) (map[string]map[string]imageutils.ImageInfo, error) GenerateCustomImageInfo(resource *unstructured.Unstructured, imageExtractorConfigs kubeutils.ImageExtractorConfigs) (map[string]map[string]kubeutils.ImageInfo, error)
// Checkpoint creates a copy of the current internal state and pushes it into a stack of stored states. // Checkpoint creates a copy of the current internal state and pushes it into a stack of stored states.
Checkpoint() Checkpoint()
@ -92,7 +91,7 @@ type context struct {
mutex sync.RWMutex mutex sync.RWMutex
jsonRaw []byte jsonRaw []byte
jsonRawCheckpoints [][]byte jsonRawCheckpoints [][]byte
images map[string]map[string]imageutils.ImageInfo images map[string]map[string]kubeutils.ImageInfo
} }
// NewContext returns a new context // NewContext returns a new context
@ -215,7 +214,7 @@ func (ctx *context) AddElement(data map[string]interface{}, index int) error {
return addToContext(ctx, data) return addToContext(ctx, data)
} }
func (ctx *context) AddImageInfo(info imageutils.ImageInfo) error { func (ctx *context) AddImageInfo(info kubeutils.ImageInfo) error {
data := map[string]interface{}{ data := map[string]interface{}{
"image": info.String(), "image": info.String(),
"registry": info.Registry, "registry": info.Registry,
@ -239,7 +238,7 @@ func (ctx *context) AddImageInfos(resource *unstructured.Unstructured) error {
return addToContext(ctx, images, "images") return addToContext(ctx, images, "images")
} }
func (ctx *context) GenerateCustomImageInfo(resource *unstructured.Unstructured, imageExtractorConfigs kubeutils.ImageExtractorConfigs) (map[string]map[string]imageutils.ImageInfo, error) { func (ctx *context) GenerateCustomImageInfo(resource *unstructured.Unstructured, imageExtractorConfigs kubeutils.ImageExtractorConfigs) (map[string]map[string]kubeutils.ImageInfo, error) {
images, err := kubeutils.ExtractImagesFromResource(*resource, imageExtractorConfigs) images, err := kubeutils.ExtractImagesFromResource(*resource, imageExtractorConfigs)
if err != nil { if err != nil {
return nil, err return nil, err
@ -250,7 +249,7 @@ func (ctx *context) GenerateCustomImageInfo(resource *unstructured.Unstructured,
return images, addToContext(ctx, images, "images") return images, addToContext(ctx, images, "images")
} }
func (ctx *context) ImageInfo() map[string]map[string]imageutils.ImageInfo { func (ctx *context) ImageInfo() map[string]map[string]kubeutils.ImageInfo {
return ctx.images return ctx.images
} }

View file

@ -15,7 +15,7 @@ import (
engineUtils "github.com/kyverno/kyverno/pkg/engine/utils" engineUtils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/engine/variables" "github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/registryclient" "github.com/kyverno/kyverno/pkg/registryclient"
imageUtils "github.com/kyverno/kyverno/pkg/utils/image" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"github.com/pkg/errors" "github.com/pkg/errors"
"sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log"
) )
@ -133,7 +133,7 @@ type imageVerifier struct {
resp *response.EngineResponse resp *response.EngineResponse
} }
func (iv *imageVerifier) verify(imageVerify *v1.ImageVerification, images map[string]map[string]imageUtils.ImageInfo) { func (iv *imageVerifier) verify(imageVerify *v1.ImageVerification, images map[string]map[string]kubeutils.ImageInfo) {
// for backward compatibility // for backward compatibility
imageVerify = imageVerify.Convert() imageVerify = imageVerify.Convert()
@ -180,7 +180,7 @@ func imageMatches(image string, imagePatterns []string) bool {
return false return false
} }
func (iv *imageVerifier) verifySignatures(imageVerify *v1.ImageVerification, imageInfo imageUtils.ImageInfo) (*response.RuleResponse, string) { func (iv *imageVerifier) verifySignatures(imageVerify *v1.ImageVerification, imageInfo kubeutils.ImageInfo) (*response.RuleResponse, string) {
image := imageInfo.String() image := imageInfo.String()
iv.logger.Info("verifying image", "image", image, "attestors", len(imageVerify.Attestors), "attestations", len(imageVerify.Attestations)) iv.logger.Info("verifying image", "image", image, "attestors", len(imageVerify.Attestors), "attestations", len(imageVerify.Attestations))
@ -295,7 +295,7 @@ func (iv *imageVerifier) buildOptionsAndPath(attestor *v1.Attestor, imageVerify
return opts, path return opts, path
} }
func (iv *imageVerifier) patchDigest(path string, imageInfo imageUtils.ImageInfo, digest string, ruleResp *response.RuleResponse) { func (iv *imageVerifier) patchDigest(path string, imageInfo kubeutils.ImageInfo, digest string, ruleResp *response.RuleResponse) {
if imageInfo.Digest == "" { if imageInfo.Digest == "" {
patch, err := makeAddDigestPatch(path, imageInfo, digest) patch, err := makeAddDigestPatch(path, imageInfo, digest)
if err != nil { if err != nil {
@ -307,7 +307,7 @@ func (iv *imageVerifier) patchDigest(path string, imageInfo imageUtils.ImageInfo
} }
} }
func makeAddDigestPatch(path string, imageInfo imageUtils.ImageInfo, digest string) ([]byte, error) { func makeAddDigestPatch(path string, imageInfo kubeutils.ImageInfo, digest string) ([]byte, error) {
var patch = make(map[string]interface{}) var patch = make(map[string]interface{})
patch["op"] = "replace" patch["op"] = "replace"
patch["path"] = path patch["path"] = path
@ -315,7 +315,7 @@ func makeAddDigestPatch(path string, imageInfo imageUtils.ImageInfo, digest stri
return json.Marshal(patch) return json.Marshal(patch)
} }
func (iv *imageVerifier) attestImage(imageVerify *v1.ImageVerification, imageInfo imageUtils.ImageInfo) *response.RuleResponse { func (iv *imageVerifier) attestImage(imageVerify *v1.ImageVerification, imageInfo kubeutils.ImageInfo) *response.RuleResponse {
image := imageInfo.String() image := imageInfo.String()
start := time.Now() start := time.Now()
@ -367,7 +367,7 @@ func buildStatementMap(statements []map[string]interface{}) map[string][]map[str
return results return results
} }
func (iv *imageVerifier) checkAttestations(a *v1.Attestation, s map[string]interface{}, img imageUtils.ImageInfo) (bool, error) { func (iv *imageVerifier) checkAttestations(a *v1.Attestation, s map[string]interface{}, img kubeutils.ImageInfo) (bool, error) {
if len(a.Conditions) == 0 { if len(a.Conditions) == 0 {
return true, nil return true, nil
} }

View file

@ -22,9 +22,6 @@ type ImageInfo struct {
// Digest is the image digest portion e.g. `sha256:128c6e3534b842a2eec139999b8ce8aa9a2af9907e2b9269550809d18cd832a3` // Digest is the image digest portion e.g. `sha256:128c6e3534b842a2eec139999b8ce8aa9a2af9907e2b9269550809d18cd832a3`
Digest string `json:"digest,omitempty"` Digest string `json:"digest,omitempty"`
// Pointer is the path to the image object in the resource
Pointer string `json:"-"`
} }
func (i *ImageInfo) String() string { func (i *ImageInfo) String() string {
@ -36,7 +33,7 @@ func (i *ImageInfo) String() string {
} }
} }
func GetImageInfo(image string, pointer string) (*ImageInfo, error) { func GetImageInfo(image string) (*ImageInfo, error) {
image = addDefaultDomain(image) image = addDefaultDomain(image)
ref, err := reference.Parse(image) ref, err := reference.Parse(image)
if err != nil { if err != nil {
@ -64,7 +61,6 @@ func GetImageInfo(image string, pointer string) (*ImageInfo, error) {
Path: path, Path: path,
Tag: tag, Tag: tag,
Digest: digest, Digest: digest,
Pointer: pointer,
}, nil }, nil
} }

View file

@ -62,7 +62,7 @@ func Test_GetImageInfo(t *testing.T) {
} }
func validateImageInfo(t *testing.T, raw, name, path, registry, tag, digest, str string) { func validateImageInfo(t *testing.T, raw, name, path, registry, tag, digest, str string) {
i1, err := GetImageInfo(raw, "") i1, err := GetImageInfo(raw)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, name, i1.Name) assert.Equal(t, name, i1.Name)
assert.Equal(t, path, i1.Path) assert.Equal(t, path, i1.Path)

View file

@ -9,7 +9,13 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
) )
type ImageExtractorConfigs map[string][]*ImageExtractorConfig type ImageInfo struct {
imageutils.ImageInfo
// Pointer is the path to the image object in the resource
Pointer string `json:"-"`
}
type ImageExtractorConfigs map[string][]ImageExtractorConfig
type ImageExtractorConfig struct { type ImageExtractorConfig struct {
// Path is the path to the object containing the image field in a custom resource. // Path is the path to the object containing the image field in a custom resource.
@ -52,15 +58,15 @@ type imageExtractor struct {
Name string Name string
} }
func (i *imageExtractor) ExtractFromResource(resource interface{}) (map[string]imageutils.ImageInfo, error) { func (i *imageExtractor) ExtractFromResource(resource interface{}) (map[string]ImageInfo, error) {
imageInfo := map[string]imageutils.ImageInfo{} imageInfo := map[string]ImageInfo{}
if err := extract(resource, []string{}, i.Key, i.Value, i.Fields, &imageInfo); err != nil { if err := extract(resource, []string{}, i.Key, i.Value, i.Fields, &imageInfo); err != nil {
return nil, err return nil, err
} }
return imageInfo, nil return imageInfo, nil
} }
func extract(obj interface{}, path []string, keyPath, valuePath string, fields []string, imageInfos *map[string]imageutils.ImageInfo) error { func extract(obj interface{}, path []string, keyPath, valuePath string, fields []string, imageInfos *map[string]ImageInfo) error {
if obj == nil { if obj == nil {
return nil return nil
} }
@ -100,10 +106,10 @@ func extract(obj interface{}, path []string, keyPath, valuePath string, fields [
if !ok { if !ok {
return fmt.Errorf("invalid value") return fmt.Errorf("invalid value")
} }
if imageInfo, err := imageutils.GetImageInfo(value, pointer); err != nil { if imageInfo, err := imageutils.GetImageInfo(value); err != nil {
return fmt.Errorf("invalid image %s", value) return fmt.Errorf("invalid image %s", value)
} else { } else {
(*imageInfos)[key] = *imageInfo (*imageInfos)[key] = ImageInfo{*imageInfo, pointer}
} }
return nil return nil
} }
@ -160,8 +166,8 @@ func lookupImageExtractor(kind string, configs ImageExtractorConfigs) []imageExt
return registeredExtractors[kind] return registeredExtractors[kind]
} }
func ExtractImagesFromResource(resource unstructured.Unstructured, configs ImageExtractorConfigs) (map[string]map[string]imageutils.ImageInfo, error) { func ExtractImagesFromResource(resource unstructured.Unstructured, configs ImageExtractorConfigs) (map[string]map[string]ImageInfo, error) {
infos := map[string]map[string]imageutils.ImageInfo{} infos := map[string]map[string]ImageInfo{}
for _, extractor := range lookupImageExtractor(resource.GetKind(), configs) { for _, extractor := range lookupImageExtractor(resource.GetKind(), configs) {
if infoMap, err := extractor.ExtractFromResource(resource.Object); err != nil { if infoMap, err := extractor.ExtractFromResource(resource.Object); err != nil {
return nil, err return nil, err

View file

@ -4,7 +4,6 @@ import (
"testing" "testing"
"github.com/kyverno/kyverno/pkg/engine/utils" "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/utils/image"
imageutils "github.com/kyverno/kyverno/pkg/utils/image" imageutils "github.com/kyverno/kyverno/pkg/utils/image"
"gotest.tools/assert" "gotest.tools/assert"
) )
@ -13,106 +12,182 @@ func Test_extractImageInfo(t *testing.T) {
tests := []struct { tests := []struct {
extractionConfig ImageExtractorConfigs extractionConfig ImageExtractorConfigs
raw []byte raw []byte
images map[string]map[string]imageutils.ImageInfo images map[string]map[string]ImageInfo
}{ }{
{ {
raw: []byte(`{"apiVersion": "v1","kind": "Pod","metadata": {"name": "myapp"},"spec": {"initContainers": [{"name": "init","image": "index.docker.io/busybox:v1.2.3"}],"containers": [{"name": "nginx","image": "nginx:latest"}], "ephemeralContainers": [{"name": "ephemeral", "image":"test/nginx:latest"}]}}`), raw: []byte(`{"apiVersion": "v1","kind": "Pod","metadata": {"name": "myapp"},"spec": {"initContainers": [{"name": "init","image": "index.docker.io/busybox:v1.2.3"}],"containers": [{"name": "nginx","image": "nginx:latest"}], "ephemeralContainers": [{"name": "ephemeral", "image":"test/nginx:latest"}]}}`),
images: map[string]map[string]image.ImageInfo{ images: map[string]map[string]ImageInfo{
"initContainers": { "initContainers": {
"init": {Registry: "index.docker.io", Name: "busybox", Path: "busybox", Tag: "v1.2.3", Pointer: "/spec/initContainers/0/image"}, "init": {
imageutils.ImageInfo{
Registry: "index.docker.io",
Name: "busybox",
Path: "busybox",
Tag: "v1.2.3",
},
"/spec/initContainers/0/image",
},
}, },
"containers": { "containers": {
"nginx": {Registry: "docker.io", Name: "nginx", Path: "nginx", Tag: "latest", Pointer: "/spec/containers/0/image"}, "nginx": {
imageutils.ImageInfo{
Registry: "docker.io",
Name: "nginx",
Path: "nginx",
Tag: "latest",
},
"/spec/containers/0/image",
},
}, },
"ephemeralContainers": { "ephemeralContainers": {
"ephemeral": {Registry: "docker.io", Name: "nginx", Path: "test/nginx", Tag: "latest", Pointer: "/spec/ephemeralContainers/0/image"}, "ephemeral": {
imageutils.ImageInfo{
Registry: "docker.io",
Name: "nginx",
Path: "test/nginx",
Tag: "latest",
},
"/spec/ephemeralContainers/0/image",
},
}, },
}, },
}, },
{ {
raw: []byte(`{"apiVersion": "v1","kind": "Pod","metadata": {"name": "myapp"},"spec": {"containers": [{"name": "nginx","image": "test/nginx:latest"}]}}`), raw: []byte(`{"apiVersion": "v1","kind": "Pod","metadata": {"name": "myapp"},"spec": {"containers": [{"name": "nginx","image": "test/nginx:latest"}]}}`),
images: map[string]map[string]imageutils.ImageInfo{ images: map[string]map[string]ImageInfo{
"containers": { "containers": {
"nginx": {Registry: "docker.io", Name: "nginx", Path: "test/nginx", Tag: "latest", Pointer: "/spec/containers/0/image"}, "nginx": {
imageutils.ImageInfo{
Registry: "docker.io",
Name: "nginx",
Path: "test/nginx",
Tag: "latest",
},
"/spec/containers/0/image",
},
}, },
}, },
}, },
{ {
raw: []byte(`{"apiVersion": "apps/v1","kind": "Deployment","metadata": {"name": "myapp"},"spec": {"selector": {"matchLabels": {"app": "myapp"}},"template": {"metadata": {"labels": {"app": "myapp"}},"spec": {"initContainers": [{"name": "init","image": "fictional.registry.example:10443/imagename:tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}],"containers": [{"name": "myapp","image": "fictional.registry.example:10443/imagename"}],"ephemeralContainers": [{"name": "ephemeral","image": "fictional.registry.example:10443/imagename:tag@sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}] }}}}`), raw: []byte(`{"apiVersion": "apps/v1","kind": "Deployment","metadata": {"name": "myapp"},"spec": {"selector": {"matchLabels": {"app": "myapp"}},"template": {"metadata": {"labels": {"app": "myapp"}},"spec": {"initContainers": [{"name": "init","image": "fictional.registry.example:10443/imagename:tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}],"containers": [{"name": "myapp","image": "fictional.registry.example:10443/imagename"}],"ephemeralContainers": [{"name": "ephemeral","image": "fictional.registry.example:10443/imagename:tag@sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}] }}}}`),
images: map[string]map[string]imageutils.ImageInfo{ images: map[string]map[string]ImageInfo{
"initContainers": { "initContainers": {
"init": {Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "tag", Digest: "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", Pointer: "/spec/template/spec/initContainers/0/image"}, "init": {
imageutils.ImageInfo{
Registry: "fictional.registry.example:10443",
Name: "imagename",
Path: "imagename",
Tag: "tag",
Digest: "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
},
"/spec/template/spec/initContainers/0/image",
},
}, },
"containers": { "containers": {
"myapp": {Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "latest", Pointer: "/spec/template/spec/containers/0/image"}, "myapp": {
imageutils.ImageInfo{
Registry: "fictional.registry.example:10443",
Name: "imagename",
Path: "imagename",
Tag: "latest",
},
"/spec/template/spec/containers/0/image",
},
}, },
"ephemeralContainers": { "ephemeralContainers": {
"ephemeral": {Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "tag", Digest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", Pointer: "/spec/template/spec/ephemeralContainers/0/image"}, "ephemeral": {
imageutils.ImageInfo{
Registry: "fictional.registry.example:10443",
Name: "imagename",
Path: "imagename",
Tag: "tag",
Digest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
},
"/spec/template/spec/ephemeralContainers/0/image",
},
}, },
}, },
}, },
{ {
raw: []byte(`{"apiVersion": "batch/v1beta1","kind": "CronJob","metadata": {"name": "hello"},"spec": {"schedule": "*/1 * * * *","jobTemplate": {"spec": {"template": {"spec": {"containers": [{"name": "hello","image": "test.example.com/test/my-app:v2"}]}}}}}}`), raw: []byte(`{"apiVersion": "batch/v1beta1","kind": "CronJob","metadata": {"name": "hello"},"spec": {"schedule": "*/1 * * * *","jobTemplate": {"spec": {"template": {"spec": {"containers": [{"name": "hello","image": "test.example.com/test/my-app:v2"}]}}}}}}`),
images: map[string]map[string]imageutils.ImageInfo{ images: map[string]map[string]ImageInfo{
"containers": { "containers": {
"hello": {Registry: "test.example.com", Name: "my-app", Path: "test/my-app", Tag: "v2", Pointer: "/spec/jobTemplate/spec/template/spec/containers/0/image"}, "hello": {
imageutils.ImageInfo{
Registry: "test.example.com",
Name: "my-app",
Path: "test/my-app",
Tag: "v2",
},
"/spec/jobTemplate/spec/template/spec/containers/0/image",
},
}, },
}, },
}, },
{ {
extractionConfig: ImageExtractorConfigs{ extractionConfig: ImageExtractorConfigs{
"Task": []*ImageExtractorConfig{ "Task": []ImageExtractorConfig{
{Path: "/spec/steps/*/image"}, {Path: "/spec/steps/*/image"},
}, },
}, },
raw: []byte(`{"apiVersion":"tekton.dev/v1beta1","kind":"Task","metadata":{"name":"example-task-name"},"spec":{"params":[{"name":"pathToDockerFile","type":"string","description":"The path to the dockerfile to build","default":"/workspace/workspace/Dockerfile"}],"resources":{"inputs":[{"name":"workspace","type":"git"}],"outputs":[{"name":"builtImage","type":"image"}]},"steps":[{"name":"ubuntu-example","image":"ubuntu","args":["ubuntu-build-example","SECRETS-example.md"]},{"image":"gcr.io/example-builders/build-example","command":["echo"],"args":["$(params.pathToDockerFile)"]},{"name":"dockerfile-pushexample","image":"gcr.io/example-builders/push-example","args":["push","$(resources.outputs.builtImage.url)"],"volumeMounts":[{"name":"docker-socket-example","mountPath":"/var/run/docker.sock"}]}],"volumes":[{"name":"example-volume","emptyDir":{}}]}}`), raw: []byte(`{"apiVersion":"tekton.dev/v1beta1","kind":"Task","metadata":{"name":"example-task-name"},"spec":{"params":[{"name":"pathToDockerFile","type":"string","description":"The path to the dockerfile to build","default":"/workspace/workspace/Dockerfile"}],"resources":{"inputs":[{"name":"workspace","type":"git"}],"outputs":[{"name":"builtImage","type":"image"}]},"steps":[{"name":"ubuntu-example","image":"ubuntu","args":["ubuntu-build-example","SECRETS-example.md"]},{"image":"gcr.io/example-builders/build-example","command":["echo"],"args":["$(params.pathToDockerFile)"]},{"name":"dockerfile-pushexample","image":"gcr.io/example-builders/push-example","args":["push","$(resources.outputs.builtImage.url)"],"volumeMounts":[{"name":"docker-socket-example","mountPath":"/var/run/docker.sock"}]}],"volumes":[{"name":"example-volume","emptyDir":{}}]}}`),
images: map[string]map[string]imageutils.ImageInfo{ images: map[string]map[string]ImageInfo{
"custom": { "custom": {
"/spec/steps/0/image": { "/spec/steps/0/image": {
Registry: "docker.io", imageutils.ImageInfo{
Name: "ubuntu", Registry: "docker.io",
Path: "ubuntu", Name: "ubuntu",
Tag: "latest", Path: "ubuntu",
Pointer: "/spec/steps/0/image", Tag: "latest",
},
"/spec/steps/0/image",
}, },
"/spec/steps/1/image": { "/spec/steps/1/image": {
Registry: "gcr.io", imageutils.ImageInfo{
Name: "build-example", Registry: "gcr.io",
Path: "example-builders/build-example", Name: "build-example",
Tag: "latest", Path: "example-builders/build-example",
Pointer: "/spec/steps/1/image", Tag: "latest",
},
"/spec/steps/1/image",
}, },
"/spec/steps/2/image": { "/spec/steps/2/image": {
Registry: "gcr.io", imageutils.ImageInfo{
Name: "push-example", Registry: "gcr.io",
Path: "example-builders/push-example", Name: "push-example",
Tag: "latest", Path: "example-builders/push-example",
Pointer: "/spec/steps/2/image", Tag: "latest",
},
"/spec/steps/2/image",
}, },
}, },
}, },
}, },
{ {
extractionConfig: ImageExtractorConfigs{ extractionConfig: ImageExtractorConfigs{
"Task": []*ImageExtractorConfig{ "Task": []ImageExtractorConfig{
{Name: "steps", Path: "/spec/steps/*", Value: "image", Key: "name"}, {Name: "steps", Path: "/spec/steps/*", Value: "image", Key: "name"},
}, },
}, raw: []byte(`{"apiVersion":"tekton.dev/v1beta1","kind":"Task","metadata":{"name":"example-task-name"},"spec":{"steps":[{"name":"ubuntu-example","image":"ubuntu","args":["ubuntu-build-example","SECRETS-example.md"]},{"name":"dockerfile-pushexample","image":"gcr.io/example-builders/push-example","args":["push","$(resources.outputs.builtImage.url)"]}]}}`), }, raw: []byte(`{"apiVersion":"tekton.dev/v1beta1","kind":"Task","metadata":{"name":"example-task-name"},"spec":{"steps":[{"name":"ubuntu-example","image":"ubuntu","args":["ubuntu-build-example","SECRETS-example.md"]},{"name":"dockerfile-pushexample","image":"gcr.io/example-builders/push-example","args":["push","$(resources.outputs.builtImage.url)"]}]}}`),
images: map[string]map[string]imageutils.ImageInfo{ images: map[string]map[string]ImageInfo{
"steps": { "steps": {
"dockerfile-pushexample": { "dockerfile-pushexample": {
Registry: "gcr.io", imageutils.ImageInfo{
Name: "push-example", Registry: "gcr.io",
Path: "example-builders/push-example", Name: "push-example",
Tag: "latest", Path: "example-builders/push-example",
Pointer: "/spec/steps/1/image", Tag: "latest",
},
"/spec/steps/1/image",
}, },
"ubuntu-example": { "ubuntu-example": {
Registry: "docker.io", imageutils.ImageInfo{
Name: "ubuntu", Registry: "docker.io",
Path: "ubuntu", Name: "ubuntu",
Tag: "latest", Path: "ubuntu",
Pointer: "/spec/steps/0/image", Tag: "latest",
},
"/spec/steps/0/image",
}, },
}, },
}, },