mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
17a554b504
putting this info into error detail would be ideal, but skopeo doesn't print them, so overwrite the error message. Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
871 lines
26 KiB
Go
871 lines
26 KiB
Go
//go:build lint
|
|
// +build lint
|
|
|
|
package lint_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"path"
|
|
"testing"
|
|
|
|
godigest "github.com/opencontainers/go-digest"
|
|
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
"gopkg.in/resty.v1"
|
|
|
|
"zotregistry.io/zot/pkg/api"
|
|
"zotregistry.io/zot/pkg/api/config"
|
|
extconf "zotregistry.io/zot/pkg/extensions/config"
|
|
"zotregistry.io/zot/pkg/extensions/lint"
|
|
"zotregistry.io/zot/pkg/extensions/monitoring"
|
|
"zotregistry.io/zot/pkg/log"
|
|
"zotregistry.io/zot/pkg/storage/local"
|
|
"zotregistry.io/zot/pkg/test"
|
|
)
|
|
|
|
const (
|
|
username = "test"
|
|
passphrase = "test"
|
|
ServerCert = "../../test/data/server.cert"
|
|
ServerKey = "../../test/data/server.key"
|
|
CACert = "../../test/data/ca.crt"
|
|
AuthorizedNamespace = "everyone/isallowed"
|
|
UnauthorizedNamespace = "fortknox/notallowed"
|
|
ALICE = "alice"
|
|
AuthorizationNamespace = "authz/image"
|
|
AuthorizationAllRepos = "**"
|
|
)
|
|
|
|
func TestVerifyMandatoryAnnotations(t *testing.T) {
|
|
//nolint: dupl
|
|
Convey("Mandatory annotations disabled", t, func() {
|
|
port := test.GetFreePort()
|
|
baseURL := test.GetBaseURL(port)
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
enable := false
|
|
conf.Extensions = &extconf.ExtensionConfig{Lint: &extconf.LintConfig{}}
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{}
|
|
conf.Extensions.Lint.Enable = &enable
|
|
|
|
ctlr := api.NewController(conf)
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
ctlr.Config.Storage.RootDirectory = dir
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
defer cm.StopServer()
|
|
|
|
resp, err := resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
manifestBlob := resp.Body()
|
|
var manifest ispec.Manifest
|
|
err = json.Unmarshal(manifestBlob, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
resp, err = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
|
|
SetBody(content).Put(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
|
|
})
|
|
|
|
//nolint: dupl
|
|
Convey("Mandatory annotations enabled, but no list in config", t, func() {
|
|
port := test.GetFreePort()
|
|
baseURL := test.GetBaseURL(port)
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
enable := true
|
|
conf.Extensions = &extconf.ExtensionConfig{Lint: &extconf.LintConfig{}}
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{}
|
|
|
|
conf.Extensions.Lint.Enable = &enable
|
|
|
|
ctlr := api.NewController(conf)
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
ctlr.Config.Storage.RootDirectory = dir
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
defer cm.StopServer()
|
|
|
|
resp, err := resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
manifestBlob := resp.Body()
|
|
var manifest ispec.Manifest
|
|
err = json.Unmarshal(manifestBlob, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
resp, err = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
|
|
SetBody(content).Put(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
|
|
})
|
|
|
|
Convey("Mandatory annotations verification passing", t, func() {
|
|
port := test.GetFreePort()
|
|
baseURL := test.GetBaseURL(port)
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
enable := true
|
|
conf.Extensions = &extconf.ExtensionConfig{Lint: &extconf.LintConfig{}}
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{}
|
|
|
|
conf.Extensions.Lint.Enable = &enable
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{"annotation1", "annotation2", "annotation3"}
|
|
|
|
ctlr := api.NewController(conf)
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
ctlr.Config.Storage.RootDirectory = dir
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
defer cm.StopServer()
|
|
|
|
resp, err := resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
manifestBlob := resp.Body()
|
|
var manifest ispec.Manifest
|
|
err = json.Unmarshal(manifestBlob, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "testPass1"
|
|
manifest.Annotations["annotation2"] = "testPass2"
|
|
manifest.Annotations["annotation3"] = "testPass3"
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
resp, err = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
|
|
SetBody(content).Put(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
|
|
})
|
|
|
|
Convey("Mandatory annotations verification in manifest and config passing", t, func() {
|
|
port := test.GetFreePort()
|
|
baseURL := test.GetBaseURL(port)
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
enable := true
|
|
conf.Extensions = &extconf.ExtensionConfig{Lint: &extconf.LintConfig{}}
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{}
|
|
|
|
conf.Extensions.Lint.Enable = &enable
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{"annotation1", "annotation2", "annotation3"}
|
|
|
|
ctlr := api.NewController(conf)
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
ctlr.Config.Storage.RootDirectory = dir
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
defer cm.StopServer()
|
|
|
|
resp, err := resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
manifestBlob := resp.Body()
|
|
var manifest ispec.Manifest
|
|
err = json.Unmarshal(manifestBlob, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "annotationPass1"
|
|
manifest.Annotations["annotation2"] = "annotationPass2"
|
|
|
|
configDigest := manifest.Config.Digest
|
|
|
|
resp, err = resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + fmt.Sprintf("/v2/zot-test/blobs/%s", configDigest))
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
configBlob := resp.Body()
|
|
var imageConfig ispec.Image
|
|
err = json.Unmarshal(configBlob, &imageConfig)
|
|
So(err, ShouldBeNil)
|
|
|
|
imageConfig.Config.Labels = make(map[string]string)
|
|
imageConfig.Config.Labels["annotation3"] = "annotationPass3"
|
|
|
|
configContent, err := json.Marshal(imageConfig)
|
|
So(err, ShouldBeNil)
|
|
|
|
configBlobDigestRaw := godigest.FromBytes(configContent)
|
|
manifest.Config.Digest = configBlobDigestRaw
|
|
manifest.Config.Size = int64(len(configContent))
|
|
manifestContent, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
// upload image config blob
|
|
resp, err = resty.R().
|
|
Post(fmt.Sprintf("%s/v2/zot-test/blobs/uploads/", baseURL))
|
|
So(err, ShouldBeNil)
|
|
loc := test.Location(baseURL, resp)
|
|
|
|
_, err = resty.R().
|
|
SetContentLength(true).
|
|
SetHeader("Content-Length", fmt.Sprintf("%d", len(configContent))).
|
|
SetHeader("Content-Type", "application/octet-stream").
|
|
SetQueryParam("digest", configBlobDigestRaw.String()).
|
|
SetBody(configContent).
|
|
Put(loc)
|
|
So(err, ShouldBeNil)
|
|
|
|
resp, err = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
|
|
SetBody(manifestContent).Put(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
|
|
})
|
|
|
|
Convey("Mandatory annotations verification in manifest and config failing", t, func() {
|
|
port := test.GetFreePort()
|
|
baseURL := test.GetBaseURL(port)
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
enable := true
|
|
conf.Extensions = &extconf.ExtensionConfig{Lint: &extconf.LintConfig{}}
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{}
|
|
|
|
conf.Extensions.Lint.Enable = &enable
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{"annotation1", "annotation2", "annotation3"}
|
|
|
|
ctlr := api.NewController(conf)
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
ctlr.Config.Storage.RootDirectory = dir
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
defer cm.StopServer()
|
|
|
|
resp, err := resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
manifestBlob := resp.Body()
|
|
var manifest ispec.Manifest
|
|
err = json.Unmarshal(manifestBlob, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "testFail1"
|
|
|
|
configDigest := manifest.Config.Digest
|
|
|
|
resp, err = resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + fmt.Sprintf("/v2/zot-test/blobs/%s", configDigest))
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
configBlob := resp.Body()
|
|
var imageConfig ispec.Image
|
|
err = json.Unmarshal(configBlob, &imageConfig)
|
|
So(err, ShouldBeNil)
|
|
|
|
imageConfig.Config.Labels = make(map[string]string)
|
|
imageConfig.Config.Labels["annotation2"] = "testFail2"
|
|
|
|
configContent, err := json.Marshal(imageConfig)
|
|
So(err, ShouldBeNil)
|
|
|
|
configBlobDigestRaw := godigest.FromBytes(configContent)
|
|
manifest.Config.Digest = configBlobDigestRaw
|
|
manifest.Config.Size = int64(len(configContent))
|
|
manifestContent, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
// upload image config blob
|
|
_, err = resty.R().
|
|
Post(fmt.Sprintf("%s/v2/zot-test/blobs/uploads/", baseURL))
|
|
So(err, ShouldBeNil)
|
|
loc := test.Location(baseURL, resp)
|
|
|
|
_, err = resty.R().
|
|
SetContentLength(true).
|
|
SetHeader("Content-Length", fmt.Sprintf("%d", len(configContent))).
|
|
SetHeader("Content-Type", "application/octet-stream").
|
|
SetQueryParam("digest", configBlobDigestRaw.String()).
|
|
SetBody(configContent).
|
|
Put(loc)
|
|
So(err, ShouldBeNil)
|
|
|
|
resp, err = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
|
|
SetBody(manifestContent).Put(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusBadRequest)
|
|
})
|
|
|
|
Convey("Mandatory annotations incomplete in manifest", t, func() {
|
|
port := test.GetFreePort()
|
|
baseURL := test.GetBaseURL(port)
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
enable := true
|
|
conf.Extensions = &extconf.ExtensionConfig{Lint: &extconf.LintConfig{}}
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{}
|
|
|
|
conf.Extensions.Lint.Enable = &enable
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{"annotation1", "annotation2", "annotation3"}
|
|
|
|
ctlr := api.NewController(conf)
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
ctlr.Config.Storage.RootDirectory = dir
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
defer cm.StopServer()
|
|
|
|
resp, err := resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
manifestBlob := resp.Body()
|
|
var manifest ispec.Manifest
|
|
err = json.Unmarshal(manifestBlob, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "testFail1"
|
|
manifest.Annotations["annotation3"] = "testFail3"
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
resp, err = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
|
|
SetBody(content).Put(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusBadRequest)
|
|
})
|
|
|
|
Convey("Mandatory annotations verification passing - more annotations than the mandatory list", t, func() {
|
|
port := test.GetFreePort()
|
|
baseURL := test.GetBaseURL(port)
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
enable := true
|
|
conf.Extensions = &extconf.ExtensionConfig{Lint: &extconf.LintConfig{}}
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{}
|
|
conf.Extensions.Lint.Enable = &enable
|
|
conf.Extensions.Lint.MandatoryAnnotations = []string{"annotation1", "annotation2", "annotation3"}
|
|
|
|
ctlr := api.NewController(conf)
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
files, err := os.ReadDir(dir)
|
|
So(err, ShouldBeNil)
|
|
|
|
t.Log("Files in dir:", dir, ": ", files)
|
|
|
|
ctlr.Config.Storage.RootDirectory = dir
|
|
cm := test.NewControllerManager(ctlr)
|
|
|
|
cm.StartAndWait(port)
|
|
defer cm.StopServer()
|
|
|
|
resp, err := resty.R().SetBasicAuth(username, passphrase).
|
|
Get(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp, ShouldNotBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
|
|
|
manifestBlob := resp.Body()
|
|
var manifest ispec.Manifest
|
|
err = json.Unmarshal(manifestBlob, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "testPassMore1"
|
|
manifest.Annotations["annotation2"] = "testPassMore2"
|
|
manifest.Annotations["annotation3"] = "testPassMore3"
|
|
manifest.Annotations["annotation4"] = "testPassMore4"
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
resp, err = resty.R().SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
|
|
SetBody(content).Put(baseURL + "/v2/zot-test/manifests/0.0.1")
|
|
So(err, ShouldBeNil)
|
|
So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
|
|
})
|
|
}
|
|
|
|
func TestVerifyMandatoryAnnotationsFunction(t *testing.T) {
|
|
Convey("Mandatory annotations disabled", t, func() {
|
|
enable := false
|
|
|
|
lintConfig := &extconf.LintConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &enable},
|
|
MandatoryAnnotations: []string{},
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
var index ispec.Index
|
|
|
|
linter := lint.NewLinter(lintConfig, log.NewLogger("debug", ""))
|
|
imgStore := local.NewImageStore(dir, false, 0, false, false,
|
|
log.NewLogger("debug", ""), monitoring.NewMetricsServer(false, log.NewLogger("debug", "")), linter, nil)
|
|
|
|
indexContent, err := imgStore.GetIndexContent("zot-test")
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(indexContent, &index)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := index.Manifests[0].Digest
|
|
|
|
pass, err := linter.CheckMandatoryAnnotations("zot-test", manifestDigest, imgStore)
|
|
So(err, ShouldBeNil)
|
|
So(pass, ShouldBeTrue)
|
|
})
|
|
|
|
Convey("Mandatory annotations enabled, but no list in config", t, func() {
|
|
enable := true
|
|
|
|
lintConfig := &extconf.LintConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &enable},
|
|
MandatoryAnnotations: []string{},
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
var index ispec.Index
|
|
|
|
linter := lint.NewLinter(lintConfig, log.NewLogger("debug", ""))
|
|
imgStore := local.NewImageStore(dir, false, 0, false, false,
|
|
log.NewLogger("debug", ""), monitoring.NewMetricsServer(false, log.NewLogger("debug", "")), linter, nil)
|
|
|
|
indexContent, err := imgStore.GetIndexContent("zot-test")
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(indexContent, &index)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := index.Manifests[0].Digest
|
|
|
|
pass, err := linter.CheckMandatoryAnnotations("zot-test", manifestDigest, imgStore)
|
|
So(err, ShouldBeNil)
|
|
So(pass, ShouldBeTrue)
|
|
})
|
|
|
|
Convey("Mandatory annotations verification passing", t, func() {
|
|
enable := true
|
|
|
|
lintConfig := &extconf.LintConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &enable},
|
|
MandatoryAnnotations: []string{"annotation1", "annotation2", "annotation3"},
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
var index ispec.Index
|
|
buf, err := os.ReadFile(path.Join(dir, "zot-test", "index.json"))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &index)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := index.Manifests[0].Digest
|
|
|
|
var manifest ispec.Manifest
|
|
buf, err = os.ReadFile(path.Join(dir, "zot-test", "blobs",
|
|
manifestDigest.Algorithm().String(), manifestDigest.Encoded()))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "testPass1"
|
|
manifest.Annotations["annotation2"] = "testPass2"
|
|
manifest.Annotations["annotation3"] = "testPass3"
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
So(content, ShouldNotBeNil)
|
|
|
|
digest := godigest.FromBytes(content)
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
err = os.WriteFile(path.Join(dir, "zot-test", "blobs",
|
|
digest.Algorithm().String(), digest.Encoded()), content, 0o600)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDesc := ispec.Descriptor{
|
|
Size: int64(len(content)),
|
|
Digest: digest,
|
|
}
|
|
|
|
index.Manifests = append(index.Manifests, manifestDesc)
|
|
|
|
linter := lint.NewLinter(lintConfig, log.NewLogger("debug", ""))
|
|
imgStore := local.NewImageStore(dir, false, 0, false, false,
|
|
log.NewLogger("debug", ""), monitoring.NewMetricsServer(false, log.NewLogger("debug", "")), linter, nil)
|
|
|
|
pass, err := linter.CheckMandatoryAnnotations("zot-test", digest, imgStore)
|
|
So(err, ShouldBeNil)
|
|
So(pass, ShouldBeTrue)
|
|
})
|
|
|
|
Convey("Mandatory annotations incomplete in manifest", t, func() {
|
|
enable := true
|
|
|
|
lintConfig := &extconf.LintConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &enable},
|
|
MandatoryAnnotations: []string{"annotation1", "annotation2", "annotation3"},
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
var index ispec.Index
|
|
buf, err := os.ReadFile(path.Join(dir, "zot-test", "index.json"))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &index)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := index.Manifests[0].Digest
|
|
|
|
var manifest ispec.Manifest
|
|
buf, err = os.ReadFile(path.Join(dir, "zot-test", "blobs",
|
|
manifestDigest.Algorithm().String(), manifestDigest.Encoded()))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "test1"
|
|
manifest.Annotations["annotation3"] = "test3"
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
So(content, ShouldNotBeNil)
|
|
|
|
digest := godigest.FromBytes(content)
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
err = os.WriteFile(path.Join(dir, "zot-test", "blobs",
|
|
digest.Algorithm().String(), digest.Encoded()), content, 0o600)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDesc := ispec.Descriptor{
|
|
Size: int64(len(content)),
|
|
Digest: digest,
|
|
}
|
|
|
|
index.Manifests = append(index.Manifests, manifestDesc)
|
|
|
|
linter := lint.NewLinter(lintConfig, log.NewLogger("debug", ""))
|
|
imgStore := local.NewImageStore(dir, false, 0, false, false,
|
|
log.NewLogger("debug", ""), monitoring.NewMetricsServer(false, log.NewLogger("debug", "")), linter, nil)
|
|
|
|
pass, err := linter.CheckMandatoryAnnotations("zot-test", digest, imgStore)
|
|
So(err, ShouldNotBeNil)
|
|
So(pass, ShouldBeFalse)
|
|
})
|
|
|
|
Convey("Mandatory annotations verification passing - more annotations than the mandatory list", t, func() {
|
|
enable := true
|
|
|
|
lintConfig := &extconf.LintConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &enable},
|
|
MandatoryAnnotations: []string{"annotation1", "annotation2", "annotation3"},
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
var index ispec.Index
|
|
buf, err := os.ReadFile(path.Join(dir, "zot-test", "index.json"))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &index)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := index.Manifests[0].Digest
|
|
|
|
var manifest ispec.Manifest
|
|
buf, err = os.ReadFile(path.Join(dir, "zot-test", "blobs",
|
|
manifestDigest.Algorithm().String(), manifestDigest.Encoded()))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "testPassMore1"
|
|
manifest.Annotations["annotation2"] = "testPassMore2"
|
|
manifest.Annotations["annotation3"] = "testPassMore3"
|
|
manifest.Annotations["annotation4"] = "testPassMore4"
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
So(content, ShouldNotBeNil)
|
|
|
|
digest := godigest.FromBytes(content)
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
err = os.WriteFile(path.Join(dir, "zot-test", "blobs",
|
|
digest.Algorithm().String(), digest.Encoded()), content, 0o600)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDesc := ispec.Descriptor{
|
|
Size: int64(len(content)),
|
|
Digest: digest,
|
|
}
|
|
|
|
index.Manifests = append(index.Manifests, manifestDesc)
|
|
|
|
linter := lint.NewLinter(lintConfig, log.NewLogger("debug", ""))
|
|
imgStore := local.NewImageStore(dir, false, 0, false, false,
|
|
log.NewLogger("debug", ""), monitoring.NewMetricsServer(false, log.NewLogger("debug", "")), linter, nil)
|
|
|
|
pass, err := linter.CheckMandatoryAnnotations("zot-test", digest, imgStore)
|
|
So(err, ShouldBeNil)
|
|
So(pass, ShouldBeTrue)
|
|
})
|
|
|
|
Convey("Cannot unmarshal manifest", t, func() {
|
|
enable := true
|
|
|
|
lintConfig := &extconf.LintConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &enable},
|
|
MandatoryAnnotations: []string{"annotation1", "annotation2", "annotation3"},
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
var index ispec.Index
|
|
buf, err := os.ReadFile(path.Join(dir, "zot-test", "index.json"))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &index)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := index.Manifests[0].Digest
|
|
|
|
var manifest ispec.Manifest
|
|
buf, err = os.ReadFile(path.Join(dir, "zot-test", "blobs",
|
|
manifestDigest.Algorithm().String(), manifestDigest.Encoded()))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "testUnmarshal1"
|
|
manifest.Annotations["annotation2"] = "testUnmarshal2"
|
|
manifest.Annotations["annotation3"] = "testUnmarshal3"
|
|
|
|
manifest.SchemaVersion = 2
|
|
content, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
So(content, ShouldNotBeNil)
|
|
|
|
digest := godigest.FromBytes(content)
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
err = os.WriteFile(path.Join(dir, "zot-test", "blobs",
|
|
digest.Algorithm().String(), digest.Encoded()), content, 0o600)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDesc := ispec.Descriptor{
|
|
Size: int64(len(content)),
|
|
Digest: digest,
|
|
}
|
|
|
|
index.Manifests = append(index.Manifests, manifestDesc)
|
|
|
|
linter := lint.NewLinter(lintConfig, log.NewLogger("debug", ""))
|
|
imgStore := local.NewImageStore(dir, false, 0, false, false,
|
|
log.NewLogger("debug", ""), monitoring.NewMetricsServer(false, log.NewLogger("debug", "")), linter, nil)
|
|
|
|
err = os.Chmod(path.Join(dir, "zot-test", "blobs"), 0o000)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
pass, err := linter.CheckMandatoryAnnotations("zot-test", digest, imgStore)
|
|
So(err, ShouldNotBeNil)
|
|
So(pass, ShouldBeFalse)
|
|
|
|
err = os.Chmod(path.Join(dir, "zot-test", "blobs"), 0o755)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
})
|
|
|
|
Convey("Cannot get config file", t, func() {
|
|
enable := true
|
|
|
|
lintConfig := &extconf.LintConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &enable},
|
|
MandatoryAnnotations: []string{"annotation1", "annotation2", "annotation3"},
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
|
|
test.CopyTestFiles("../../../test/data", dir)
|
|
|
|
var index ispec.Index
|
|
buf, err := os.ReadFile(path.Join(dir, "zot-test", "index.json"))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &index)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := index.Manifests[0].Digest
|
|
|
|
var manifest ispec.Manifest
|
|
buf, err = os.ReadFile(path.Join(dir, "zot-test", "blobs",
|
|
manifestDigest.Algorithm().String(), manifestDigest.Encoded()))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &manifest)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifest.Annotations = make(map[string]string)
|
|
|
|
manifest.Annotations["annotation1"] = "testAnnotation1"
|
|
manifest.Annotations["annotation2"] = "testAnnotation2"
|
|
|
|
// write config
|
|
var imageConfig ispec.Image
|
|
configDigest := manifest.Config.Digest
|
|
buf, err = os.ReadFile(path.Join(dir, "zot-test", "blobs", "sha256",
|
|
configDigest.Encoded()))
|
|
So(err, ShouldBeNil)
|
|
err = json.Unmarshal(buf, &imageConfig)
|
|
So(err, ShouldBeNil)
|
|
|
|
imageConfig.Config.Labels = make(map[string]string)
|
|
imageConfig.Config.Labels["annotation3"] = "testAnnotation3"
|
|
|
|
configContent, err := json.Marshal(imageConfig)
|
|
So(err, ShouldBeNil)
|
|
So(configContent, ShouldNotBeNil)
|
|
|
|
cfgDigest := godigest.FromBytes(configContent)
|
|
So(cfgDigest, ShouldNotBeNil)
|
|
|
|
err = os.WriteFile(path.Join(dir, "zot-test", "blobs", "sha256",
|
|
cfgDigest.Encoded()), configContent, 0o600)
|
|
So(err, ShouldBeNil)
|
|
|
|
// write manifest
|
|
manifest.SchemaVersion = 2
|
|
manifest.Config.Size = int64(len(configContent))
|
|
manifest.Config.Digest = cfgDigest
|
|
manifestContent, err := json.Marshal(manifest)
|
|
So(err, ShouldBeNil)
|
|
So(manifestContent, ShouldNotBeNil)
|
|
|
|
digest := godigest.FromBytes(manifestContent)
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
err = os.WriteFile(path.Join(dir, "zot-test", "blobs",
|
|
digest.Algorithm().String(), digest.Encoded()), manifestContent, 0o600)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDesc := ispec.Descriptor{
|
|
Size: int64(len(manifestContent)),
|
|
Digest: digest,
|
|
}
|
|
|
|
index.Manifests = append(index.Manifests, manifestDesc)
|
|
|
|
linter := lint.NewLinter(lintConfig, log.NewLogger("debug", ""))
|
|
imgStore := local.NewImageStore(dir, false, 0, false, false,
|
|
log.NewLogger("debug", ""), monitoring.NewMetricsServer(false, log.NewLogger("debug", "")), linter, nil)
|
|
|
|
err = os.Chmod(path.Join(dir, "zot-test", "blobs", "sha256", manifest.Config.Digest.Encoded()), 0o000)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
pass, err := linter.CheckMandatoryAnnotations("zot-test", digest, imgStore)
|
|
So(err, ShouldNotBeNil)
|
|
So(pass, ShouldBeFalse)
|
|
|
|
err = os.Chmod(path.Join(dir, "zot-test", "blobs", "sha256", manifest.Config.Digest.Encoded()), 0o755)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
})
|
|
}
|