From 8a503b39e95499718058b885b905e3c66a31b7da Mon Sep 17 00:00:00 2001 From: Allen Conlon Date: Wed, 13 Nov 2024 11:59:01 -0500 Subject: [PATCH] feature: Add ability for zarf to find oci artifacts for fluxcd ocirepo resource Signed-off-by: Allen Conlon --- src/pkg/packager/prepare.go | 33 ++++++++++++++++++- src/pkg/packager/prepare_test.go | 16 +++++++++ .../flux-oci-repo/oci-repo-digest.yaml | 10 ++++++ .../flux-oci-repo/oci-repo-semver.yaml | 11 +++++++ .../flux-oci-repo/oci-repo-tag.yaml | 10 ++++++ .../find-images/flux-oci-repo/zarf.yaml | 14 ++++++++ 6 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-digest.yaml create mode 100644 src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-semver.yaml create mode 100644 src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-tag.yaml create mode 100644 src/pkg/packager/testdata/find-images/flux-oci-repo/zarf.yaml diff --git a/src/pkg/packager/prepare.go b/src/pkg/packager/prepare.go index 2a25239189..03d625f4d0 100644 --- a/src/pkg/packager/prepare.go +++ b/src/pkg/packager/prepare.go @@ -8,7 +8,6 @@ import ( "context" "errors" "fmt" - "github.com/zarf-dev/zarf/src/pkg/logger" "os" "path/filepath" "regexp" @@ -16,7 +15,10 @@ import ( "strings" "time" + "github.com/zarf-dev/zarf/src/pkg/logger" + "github.com/defenseunicorns/pkg/helpers/v2" + sourcev1beta2 "github.com/fluxcd/source-controller/api/v1beta2" "github.com/goccy/go-yaml" "github.com/google/go-containerregistry/pkg/crane" v1 "k8s.io/api/apps/v1" @@ -412,6 +414,13 @@ func processUnstructuredImages(resource *unstructured.Unstructured, matchedImage } matchedImages = appendToImageMap(matchedImages, job.Spec.Template.Spec) + case "OCIRepository": + var ociRepo sourcev1beta2.OCIRepository + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(contents, &ociRepo); err != nil { + return nil, nil, fmt.Errorf("could not parse ocirepo: %w", err) + } + matchedImages = appendToImageMapOCIRepo(matchedImages, ociRepo.Spec) + default: // Capture any custom images matches := imageCheck.FindAllStringSubmatch(string(b), -1) @@ -465,6 +474,28 @@ func appendToImageMap(imgMap map[string]bool, pod corev1.PodSpec) map[string]boo return imgMap } +func appendToImageMapOCIRepo(imgMap map[string]bool, repo sourcev1beta2.OCIRepositorySpec) map[string]bool { + var regex = regexp.MustCompile(`oci://(.+)`) + var t = regex.FindStringSubmatch(repo.URL) + + s := strings.Builder{} + // Pulls out just the url from the regex + s.Write([]byte(t[1])) + + if repo.Reference.Tag != "" { + s.WriteString(":") + s.WriteString(repo.Reference.Tag) + } else if repo.Reference.Digest != "" { + s.WriteString("@") + s.WriteString(repo.Reference.Digest) + } else if repo.Reference.SemVer != "" || repo.Reference.SemverFilter != "" { + message.Warnf("Can not use semver or semverFilter with OCIRepository") + return imgMap + } + imgMap[s.String()] = true + return imgMap +} + func getSortedImages(matchedImages map[string]bool, maybeImages map[string]bool) ([]string, []string) { sortedMatchedImages := sort.StringSlice{} for image := range matchedImages { diff --git a/src/pkg/packager/prepare_test.go b/src/pkg/packager/prepare_test.go index ea244d8a52..2035a4d055 100644 --- a/src/pkg/packager/prepare_test.go +++ b/src/pkg/packager/prepare_test.go @@ -69,6 +69,22 @@ func TestFindImages(t *testing.T) { }, }, }, + { + name: "flux-oci-repo", + cfg: &types.PackagerConfig{ + CreateOpts: types.ZarfCreateOptions{ + BaseDir: "./testdata/find-images/flux-oci-repo", + }, + }, + expectedImages: map[string][]string{ + "baseline": { + "ghcr.io/stefanprodan/manifests/podinfo:6.4.1", + "ghcr.io/stefanprodan/manifests/podinfo@sha256:fc60d367cc05bedae04d6030e270daa89c3d82fa18b1a155314102b2fca39652", + "ghcr.io/stefanprodan/manifests/podinfo:sha256-3f4327936dd3b1c3fa2ce98e7c9d286a5e433d2bcd0a86f759bc75da285ae78c.sig", + "ghcr.io/stefanprodan/manifests/podinfo:sha256-fc60d367cc05bedae04d6030e270daa89c3d82fa18b1a155314102b2fca39652.sig", + }, + }, + }, { name: "image not found", cfg: &types.PackagerConfig{ diff --git a/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-digest.yaml b/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-digest.yaml new file mode 100644 index 0000000000..948b9e84d2 --- /dev/null +++ b/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-digest.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo-digest +spec: + interval: 30s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + digest: sha256:fc60d367cc05bedae04d6030e270daa89c3d82fa18b1a155314102b2fca39652 diff --git a/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-semver.yaml b/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-semver.yaml new file mode 100644 index 0000000000..d0fe5b7a6e --- /dev/null +++ b/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-semver.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo-semver +spec: + interval: 30s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + semver: ">= 6.1.x-0" + semverFilter: ".*-rc.*" diff --git a/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-tag.yaml b/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-tag.yaml new file mode 100644 index 0000000000..f69be3585b --- /dev/null +++ b/src/pkg/packager/testdata/find-images/flux-oci-repo/oci-repo-tag.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo-tag +spec: + interval: 30s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + tag: 6.4.1 diff --git a/src/pkg/packager/testdata/find-images/flux-oci-repo/zarf.yaml b/src/pkg/packager/testdata/find-images/flux-oci-repo/zarf.yaml new file mode 100644 index 0000000000..c92540a977 --- /dev/null +++ b/src/pkg/packager/testdata/find-images/flux-oci-repo/zarf.yaml @@ -0,0 +1,14 @@ +kind: ZarfPackageConfig +metadata: + name: agent + version: 1.0.0 +components: + - name: baseline + required: true + manifests: + - name: agent + namespace: default + files: + - oci-repo-tag.yaml + - oci-repo-digest.yaml + - oci-repo-semver.yaml