mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 07:26:55 +00:00
refactor: image utils (#3630)
Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
This commit is contained in:
parent
12bbca2477
commit
2e1a87d149
7 changed files with 151 additions and 81 deletions
|
@ -974,19 +974,13 @@ func (in *Rule) DeepCopyInto(out *Rule) {
|
|||
in, out := &in.ImageExtractors, &out.ImageExtractors
|
||||
*out = make(kube.ImageExtractorConfigs, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []*kube.ImageExtractorConfig
|
||||
var outVal []kube.ImageExtractorConfig
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]*kube.ImageExtractorConfig, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(kube.ImageExtractorConfig)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
*out = make([]kube.ImageExtractorConfig, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
jsonpatch "github.com/evanphx/json-patch/v5"
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
pkgcommon "github.com/kyverno/kyverno/pkg/common"
|
||||
imageutils "github.com/kyverno/kyverno/pkg/utils/image"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
"github.com/pkg/errors"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
|
@ -60,17 +59,17 @@ type Interface interface {
|
|||
AddElement(data map[string]interface{}, index int) error
|
||||
|
||||
// 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(resource *unstructured.Unstructured) error
|
||||
|
||||
// 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
|
||||
// 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()
|
||||
|
@ -92,7 +91,7 @@ type context struct {
|
|||
mutex sync.RWMutex
|
||||
jsonRaw []byte
|
||||
jsonRawCheckpoints [][]byte
|
||||
images map[string]map[string]imageutils.ImageInfo
|
||||
images map[string]map[string]kubeutils.ImageInfo
|
||||
}
|
||||
|
||||
// NewContext returns a new context
|
||||
|
@ -215,7 +214,7 @@ func (ctx *context) AddElement(data map[string]interface{}, index int) error {
|
|||
return addToContext(ctx, data)
|
||||
}
|
||||
|
||||
func (ctx *context) AddImageInfo(info imageutils.ImageInfo) error {
|
||||
func (ctx *context) AddImageInfo(info kubeutils.ImageInfo) error {
|
||||
data := map[string]interface{}{
|
||||
"image": info.String(),
|
||||
"registry": info.Registry,
|
||||
|
@ -239,7 +238,7 @@ func (ctx *context) AddImageInfos(resource *unstructured.Unstructured) error {
|
|||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -250,7 +249,7 @@ func (ctx *context) GenerateCustomImageInfo(resource *unstructured.Unstructured,
|
|||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
engineUtils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
"github.com/kyverno/kyverno/pkg/engine/variables"
|
||||
"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"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
@ -133,7 +133,7 @@ type imageVerifier struct {
|
|||
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
|
||||
imageVerify = imageVerify.Convert()
|
||||
|
||||
|
@ -180,7 +180,7 @@ func imageMatches(image string, imagePatterns []string) bool {
|
|||
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()
|
||||
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
|
||||
}
|
||||
|
||||
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 == "" {
|
||||
patch, err := makeAddDigestPatch(path, imageInfo, digest)
|
||||
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{})
|
||||
patch["op"] = "replace"
|
||||
patch["path"] = path
|
||||
|
@ -315,7 +315,7 @@ func makeAddDigestPatch(path string, imageInfo imageUtils.ImageInfo, digest stri
|
|||
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()
|
||||
start := time.Now()
|
||||
|
||||
|
@ -367,7 +367,7 @@ func buildStatementMap(statements []map[string]interface{}) map[string][]map[str
|
|||
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 {
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -22,9 +22,6 @@ type ImageInfo struct {
|
|||
|
||||
// Digest is the image digest portion e.g. `sha256:128c6e3534b842a2eec139999b8ce8aa9a2af9907e2b9269550809d18cd832a3`
|
||||
Digest string `json:"digest,omitempty"`
|
||||
|
||||
// Pointer is the path to the image object in the resource
|
||||
Pointer string `json:"-"`
|
||||
}
|
||||
|
||||
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)
|
||||
ref, err := reference.Parse(image)
|
||||
if err != nil {
|
||||
|
@ -64,7 +61,6 @@ func GetImageInfo(image string, pointer string) (*ImageInfo, error) {
|
|||
Path: path,
|
||||
Tag: tag,
|
||||
Digest: digest,
|
||||
Pointer: pointer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ func Test_GetImageInfo(t *testing.T) {
|
|||
}
|
||||
|
||||
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.Equal(t, name, i1.Name)
|
||||
assert.Equal(t, path, i1.Path)
|
||||
|
|
|
@ -9,7 +9,13 @@ import (
|
|||
"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 {
|
||||
// Path is the path to the object containing the image field in a custom resource.
|
||||
|
@ -52,15 +58,15 @@ type imageExtractor struct {
|
|||
Name string
|
||||
}
|
||||
|
||||
func (i *imageExtractor) ExtractFromResource(resource interface{}) (map[string]imageutils.ImageInfo, error) {
|
||||
imageInfo := map[string]imageutils.ImageInfo{}
|
||||
func (i *imageExtractor) ExtractFromResource(resource interface{}) (map[string]ImageInfo, error) {
|
||||
imageInfo := map[string]ImageInfo{}
|
||||
if err := extract(resource, []string{}, i.Key, i.Value, i.Fields, &imageInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
|
@ -100,10 +106,10 @@ func extract(obj interface{}, path []string, keyPath, valuePath string, fields [
|
|||
if !ok {
|
||||
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)
|
||||
} else {
|
||||
(*imageInfos)[key] = *imageInfo
|
||||
(*imageInfos)[key] = ImageInfo{*imageInfo, pointer}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -160,8 +166,8 @@ func lookupImageExtractor(kind string, configs ImageExtractorConfigs) []imageExt
|
|||
return registeredExtractors[kind]
|
||||
}
|
||||
|
||||
func ExtractImagesFromResource(resource unstructured.Unstructured, configs ImageExtractorConfigs) (map[string]map[string]imageutils.ImageInfo, error) {
|
||||
infos := map[string]map[string]imageutils.ImageInfo{}
|
||||
func ExtractImagesFromResource(resource unstructured.Unstructured, configs ImageExtractorConfigs) (map[string]map[string]ImageInfo, error) {
|
||||
infos := map[string]map[string]ImageInfo{}
|
||||
for _, extractor := range lookupImageExtractor(resource.GetKind(), configs) {
|
||||
if infoMap, err := extractor.ExtractFromResource(resource.Object); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
"github.com/kyverno/kyverno/pkg/utils/image"
|
||||
imageutils "github.com/kyverno/kyverno/pkg/utils/image"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
@ -13,106 +12,182 @@ func Test_extractImageInfo(t *testing.T) {
|
|||
tests := []struct {
|
||||
extractionConfig ImageExtractorConfigs
|
||||
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"}]}}`),
|
||||
images: map[string]map[string]image.ImageInfo{
|
||||
images: map[string]map[string]ImageInfo{
|
||||
"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": {
|
||||
"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": {
|
||||
"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"}]}}`),
|
||||
images: map[string]map[string]imageutils.ImageInfo{
|
||||
images: map[string]map[string]ImageInfo{
|
||||
"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"}] }}}}`),
|
||||
images: map[string]map[string]imageutils.ImageInfo{
|
||||
images: map[string]map[string]ImageInfo{
|
||||
"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": {
|
||||
"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": {
|
||||
"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"}]}}}}}}`),
|
||||
images: map[string]map[string]imageutils.ImageInfo{
|
||||
images: map[string]map[string]ImageInfo{
|
||||
"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{
|
||||
"Task": []*ImageExtractorConfig{
|
||||
"Task": []ImageExtractorConfig{
|
||||
{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":{}}]}}`),
|
||||
images: map[string]map[string]imageutils.ImageInfo{
|
||||
images: map[string]map[string]ImageInfo{
|
||||
"custom": {
|
||||
"/spec/steps/0/image": {
|
||||
Registry: "docker.io",
|
||||
Name: "ubuntu",
|
||||
Path: "ubuntu",
|
||||
Tag: "latest",
|
||||
Pointer: "/spec/steps/0/image",
|
||||
imageutils.ImageInfo{
|
||||
Registry: "docker.io",
|
||||
Name: "ubuntu",
|
||||
Path: "ubuntu",
|
||||
Tag: "latest",
|
||||
},
|
||||
"/spec/steps/0/image",
|
||||
},
|
||||
"/spec/steps/1/image": {
|
||||
Registry: "gcr.io",
|
||||
Name: "build-example",
|
||||
Path: "example-builders/build-example",
|
||||
Tag: "latest",
|
||||
Pointer: "/spec/steps/1/image",
|
||||
imageutils.ImageInfo{
|
||||
Registry: "gcr.io",
|
||||
Name: "build-example",
|
||||
Path: "example-builders/build-example",
|
||||
Tag: "latest",
|
||||
},
|
||||
"/spec/steps/1/image",
|
||||
},
|
||||
"/spec/steps/2/image": {
|
||||
Registry: "gcr.io",
|
||||
Name: "push-example",
|
||||
Path: "example-builders/push-example",
|
||||
Tag: "latest",
|
||||
Pointer: "/spec/steps/2/image",
|
||||
imageutils.ImageInfo{
|
||||
Registry: "gcr.io",
|
||||
Name: "push-example",
|
||||
Path: "example-builders/push-example",
|
||||
Tag: "latest",
|
||||
},
|
||||
"/spec/steps/2/image",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
extractionConfig: ImageExtractorConfigs{
|
||||
"Task": []*ImageExtractorConfig{
|
||||
"Task": []ImageExtractorConfig{
|
||||
{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)"]}]}}`),
|
||||
images: map[string]map[string]imageutils.ImageInfo{
|
||||
images: map[string]map[string]ImageInfo{
|
||||
"steps": {
|
||||
"dockerfile-pushexample": {
|
||||
Registry: "gcr.io",
|
||||
Name: "push-example",
|
||||
Path: "example-builders/push-example",
|
||||
Tag: "latest",
|
||||
Pointer: "/spec/steps/1/image",
|
||||
imageutils.ImageInfo{
|
||||
Registry: "gcr.io",
|
||||
Name: "push-example",
|
||||
Path: "example-builders/push-example",
|
||||
Tag: "latest",
|
||||
},
|
||||
"/spec/steps/1/image",
|
||||
},
|
||||
"ubuntu-example": {
|
||||
Registry: "docker.io",
|
||||
Name: "ubuntu",
|
||||
Path: "ubuntu",
|
||||
Tag: "latest",
|
||||
Pointer: "/spec/steps/0/image",
|
||||
imageutils.ImageInfo{
|
||||
Registry: "docker.io",
|
||||
Name: "ubuntu",
|
||||
Path: "ubuntu",
|
||||
Tag: "latest",
|
||||
},
|
||||
"/spec/steps/0/image",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Add table
Reference in a new issue