mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
Added config enable=true/false for extensions with default value as enabled closes #258
Signed-off-by: Alexei Dodon <adodon@cisco.com>
This commit is contained in:
parent
730fe70f2f
commit
47c9b6244e
19 changed files with 970 additions and 85 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -13,9 +13,7 @@
|
|||
|
||||
bin/
|
||||
bazel-*
|
||||
coverage.txt
|
||||
coverage-extended.txt
|
||||
coverage-minimal.txt
|
||||
coverage*.txt
|
||||
test/data/
|
||||
*.orig
|
||||
.idea/
|
||||
|
|
|
@ -388,7 +388,7 @@ Configure each registry sync:
|
|||
"pollInterval": "6h", # polling interval, if not set then periodically polling will not run
|
||||
"tlsVerify": true, # whether or not to verify tls (default is true)
|
||||
"certDir": "/home/user/certs", # use certificates at certDir path, if not specified then use the default certs dir
|
||||
"maxRetries": 5, # mandatory option! maxRetries in case of temporary errors
|
||||
"maxRetries": 5, # mandatory option! maxRetries in case of temporary errors
|
||||
"retryDelay": "10m", # mandatory option! delay between retries, retry options are applied for both on demand and periodically sync.
|
||||
"content":[ # which content to periodically pull, also it's used for filtering ondemand images, if not set then periodically polling will not run
|
||||
{
|
||||
|
@ -401,7 +401,7 @@ Configure each registry sync:
|
|||
{
|
||||
"prefix":"/repo2/repo*" # pull all images that matches repo2/repo.*
|
||||
},
|
||||
{
|
||||
{
|
||||
"prefix":"/repo3/**" # pull all images under repo3/ (matches recursively all repos under repo3/)
|
||||
}
|
||||
]
|
||||
|
@ -411,7 +411,7 @@ Configure each registry sync:
|
|||
"pollInterval": "12h",
|
||||
"tlsVerify": false,
|
||||
"onDemand": false,
|
||||
"maxRetries": 5,
|
||||
"maxRetries": 5,
|
||||
"retryDelay": "10m",
|
||||
"content":[
|
||||
{
|
||||
|
@ -426,8 +426,8 @@ Configure each registry sync:
|
|||
"urls": ["https://docker.io/library"],
|
||||
"onDemand": true, # doesn't have content, don't periodically pull, pull just on demand.
|
||||
"tlsVerify": true,
|
||||
"maxRetries": 3,
|
||||
"retryDelay": "15m"
|
||||
"maxRetries": 3,
|
||||
"retryDelay": "15m"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
46
examples/config-allextensions.json
Normal file
46
examples/config-allextensions.json
Normal file
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"version": "0.1.0-dev",
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "8080"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug"
|
||||
},
|
||||
"extensions": {
|
||||
"metrics": {
|
||||
},
|
||||
"sync": {
|
||||
"credentialsFile": "./examples/sync-auth-filepath.json",
|
||||
"registries": [{
|
||||
"urls": ["https://registry1:5000"],
|
||||
"onDemand": false,
|
||||
"pollInterval": "6h",
|
||||
"tlsVerify": true,
|
||||
"certDir": "/home/user/certs",
|
||||
"maxRetries": 3,
|
||||
"retryDelay": "15m",
|
||||
"content":[
|
||||
{
|
||||
"prefix":"/repo1/repo",
|
||||
"tags":{
|
||||
"regex":"4.*",
|
||||
"semver":true
|
||||
}
|
||||
},
|
||||
{
|
||||
"prefix":"/repo2/repo"
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
"search": {
|
||||
"cve": {
|
||||
"updateInterval": "2h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
},
|
||||
"extensions":{
|
||||
"sync": {
|
||||
"enable": true,
|
||||
"credentialsFile": "./examples/sync-auth-filepath.json",
|
||||
"registries": [{
|
||||
"urls": ["https://registry1:5000"],
|
||||
|
|
|
@ -45,7 +45,6 @@ func NewController(config *config.Config) *Controller {
|
|||
var controller Controller
|
||||
|
||||
logger := log.NewLogger(config.Log.Level, config.Log.Output)
|
||||
|
||||
controller.Config = config
|
||||
controller.Log = logger
|
||||
controller.wgShutDown = new(goSync.WaitGroup)
|
||||
|
@ -137,7 +136,7 @@ func (c *Controller) Run() error {
|
|||
if c.Config != nil &&
|
||||
c.Config.Extensions != nil &&
|
||||
c.Config.Extensions.Metrics != nil &&
|
||||
c.Config.Extensions.Metrics.Enable {
|
||||
*c.Config.Extensions.Metrics.Enable {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
|
@ -296,7 +295,7 @@ func (c *Controller) InitImageStore() error {
|
|||
}
|
||||
|
||||
// Enable extensions if extension config is provided
|
||||
if c.Config.Extensions != nil && c.Config.Extensions.Sync != nil {
|
||||
if c.Config.Extensions != nil && c.Config.Extensions.Sync != nil && *c.Config.Extensions.Sync.Enable {
|
||||
ext.EnableSyncExtension(c.Config, c.wgShutDown, c.StoreController, c.Log)
|
||||
}
|
||||
|
||||
|
|
|
@ -1324,7 +1324,9 @@ func getImageManifest(routeHandler *RouteHandler, imgStore storage.ImageStore, n
|
|||
content, digest, mediaType, err := imgStore.GetImageManifest(name, reference)
|
||||
if err != nil {
|
||||
if errors.Is(err, zerr.ErrRepoNotFound) || errors.Is(err, zerr.ErrManifestNotFound) {
|
||||
if routeHandler.c.Config.Extensions != nil && routeHandler.c.Config.Extensions.Sync != nil {
|
||||
if routeHandler.c.Config.Extensions != nil &&
|
||||
routeHandler.c.Config.Extensions.Sync != nil &&
|
||||
*routeHandler.c.Config.Extensions.Sync.Enable {
|
||||
routeHandler.c.Log.Info().Msgf("image not found, trying to get image %s:%s by syncing on demand",
|
||||
name, reference)
|
||||
|
||||
|
@ -1350,7 +1352,9 @@ func getReferrers(routeHandler *RouteHandler, imgStore storage.ImageStore, name,
|
|||
artifactType string) ([]artifactspec.Descriptor, error) {
|
||||
refs, err := imgStore.GetReferrers(name, digest, artifactType)
|
||||
if err != nil {
|
||||
if routeHandler.c.Config.Extensions != nil && routeHandler.c.Config.Extensions.Sync != nil {
|
||||
if routeHandler.c.Config.Extensions != nil &&
|
||||
routeHandler.c.Config.Extensions.Sync != nil &&
|
||||
*routeHandler.c.Config.Extensions.Sync.Enable {
|
||||
routeHandler.c.Log.Info().Msgf("signature not found, trying to get signature %s:%s by syncing on demand",
|
||||
name, digest)
|
||||
|
||||
|
|
|
@ -290,7 +290,6 @@ func TestServerCVEResponse(t *testing.T) {
|
|||
url := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
ctlr := api.NewController(conf)
|
||||
|
||||
dir, err := ioutil.TempDir("", "oci-repo-test")
|
||||
if err != nil {
|
||||
|
@ -304,18 +303,21 @@ func TestServerCVEResponse(t *testing.T) {
|
|||
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
ctlr.Config.Storage.RootDirectory = dir
|
||||
conf.Storage.RootDirectory = dir
|
||||
cveConfig := &extconf.CVEConfig{
|
||||
UpdateInterval: 2,
|
||||
}
|
||||
defaultVal := true
|
||||
searchConfig := &extconf.SearchConfig{
|
||||
CVE: cveConfig,
|
||||
Enable: true,
|
||||
Enable: &defaultVal,
|
||||
}
|
||||
ctlr.Config.Extensions = &extconf.ExtensionConfig{
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: searchConfig,
|
||||
}
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
||||
go func(controller *api.Controller) {
|
||||
// this blocks
|
||||
if err := controller.Run(); err != nil {
|
||||
|
|
666
pkg/cli/extensions_test.go
Normal file
666
pkg/cli/extensions_test.go
Normal file
|
@ -0,0 +1,666 @@
|
|||
//go:build extended
|
||||
// +build extended
|
||||
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"gopkg.in/resty.v1"
|
||||
"zotregistry.io/zot/pkg/cli"
|
||||
. "zotregistry.io/zot/pkg/test"
|
||||
)
|
||||
|
||||
func TestServeExtensions(t *testing.T) {
|
||||
oldArgs := os.Args
|
||||
|
||||
defer func() { os.Args = oldArgs }()
|
||||
|
||||
Convey("config file with no extensions", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
|
||||
WaitTillServerReady(baseURL)
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring, "\"Extensions\":null")
|
||||
})
|
||||
|
||||
Convey("config file with empty extensions", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
|
||||
WaitTillServerReady(baseURL)
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring, "\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":null")
|
||||
})
|
||||
}
|
||||
|
||||
func testWithMetricsEnabled(cfgContentFormat string) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(cfgContentFormat, port, logFile.Name())
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
resp, err := resty.R().Get(baseURL + "/metrics")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
||||
|
||||
respStr := string(resp.Body())
|
||||
So(respStr, ShouldContainSubstring, "zot_info")
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":{\"Enable\":true,\"Prometheus\":{\"Path\":\"/metrics\"}}}") // nolint:lll
|
||||
}
|
||||
|
||||
func TestServeMetricsExtension(t *testing.T) {
|
||||
oldArgs := os.Args
|
||||
|
||||
defer func() { os.Args = oldArgs }()
|
||||
|
||||
Convey("no explicit enable", t, func(c C) {
|
||||
content := `{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"metrics": {
|
||||
}
|
||||
}
|
||||
}`
|
||||
testWithMetricsEnabled(content)
|
||||
})
|
||||
|
||||
Convey("no explicit enable but with prometheus parameter", t, func(c C) {
|
||||
content := `{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"metrics": {
|
||||
"prometheus": {
|
||||
"path": "/metrics"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
testWithMetricsEnabled(content)
|
||||
})
|
||||
|
||||
Convey("with explicit enable, but without prometheus parameter", t, func(c C) {
|
||||
content := `{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"metrics": {
|
||||
"enable": true
|
||||
}
|
||||
}
|
||||
}`
|
||||
testWithMetricsEnabled(content)
|
||||
})
|
||||
|
||||
Convey("with explicit disable", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"metrics": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
resp, err := resty.R().Get(baseURL + "/metrics")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":null,\"Sync\":null,\"Metrics\":{\"Enable\":false,\"Prometheus\":{\"Path\":\"/metrics\"}}}") // nolint:lll
|
||||
})
|
||||
}
|
||||
|
||||
func TestServeSyncExtension(t *testing.T) {
|
||||
oldArgs := os.Args
|
||||
|
||||
defer func() { os.Args = oldArgs }()
|
||||
|
||||
Convey("sync implicitly enabled", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"sync": {
|
||||
"registries": [{
|
||||
"urls": ["http://localhost:8080"],
|
||||
"tlsVerify": false,
|
||||
"onDemand": true,
|
||||
"maxRetries": 3,
|
||||
"retryDelay": "15m",
|
||||
"certDir": "",
|
||||
"content":[
|
||||
{
|
||||
"prefix": "zot-test",
|
||||
"tags": {
|
||||
"regex": ".*",
|
||||
"semver": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":null,\"Sync\":{\"Enable\":true")
|
||||
})
|
||||
|
||||
Convey("sync explicitly enabled", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"sync": {
|
||||
"enable": true,
|
||||
"registries": [{
|
||||
"urls": ["http://localhost:8080"],
|
||||
"tlsVerify": false,
|
||||
"onDemand": true,
|
||||
"maxRetries": 3,
|
||||
"retryDelay": "15m",
|
||||
"certDir": "",
|
||||
"content":[
|
||||
{
|
||||
"prefix": "zot-test",
|
||||
"tags": {
|
||||
"regex": ".*",
|
||||
"semver": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":null,\"Sync\":{\"Enable\":true")
|
||||
})
|
||||
|
||||
Convey("sync explicitly disabled", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"sync": {
|
||||
"enable": false,
|
||||
"registries": [{
|
||||
"urls": ["http://127.0.0.1:8080"],
|
||||
"tlsVerify": false,
|
||||
"certDir": "",
|
||||
"maxRetries": 3,
|
||||
"retryDelay": "15m"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":null,\"Sync\":{\"Enable\":false")
|
||||
})
|
||||
}
|
||||
|
||||
func TestServeSearchExtension(t *testing.T) {
|
||||
oldArgs := os.Args
|
||||
|
||||
defer func() { os.Args = oldArgs }()
|
||||
|
||||
Convey("search implicitly enabled", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"search": {
|
||||
}
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":86400000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null}") // nolint:lll
|
||||
So(string(data), ShouldContainSubstring, "updating the CVE database")
|
||||
})
|
||||
|
||||
Convey("search implicitly enabled with CVE param set", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"search": {
|
||||
"cve": {
|
||||
"updateInterval": "1h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
// Even if in config we specified updateInterval=1h, the minimum interval is 2h
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":3600000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null}") // nolint:lll
|
||||
So(string(data), ShouldContainSubstring, "updating the CVE database")
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.")
|
||||
})
|
||||
|
||||
Convey("search explicitly enabled, but CVE parameter not set", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"search": {
|
||||
"enable": true
|
||||
}
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":86400000000000},\"Enable\":true},\"Sync\":null,\"Metrics\":null}") // nolint:lll
|
||||
So(string(data), ShouldContainSubstring, "updating the CVE database")
|
||||
})
|
||||
|
||||
Convey("search explicitly disabled", t, func(c C) {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
logFile, err := ioutil.TempFile("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
content := fmt.Sprintf(`{
|
||||
"storage": {
|
||||
"rootDirectory": "/tmp/zot"
|
||||
},
|
||||
"http": {
|
||||
"address": "127.0.0.1",
|
||||
"port": "%s"
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"output": "%s"
|
||||
},
|
||||
"extensions": {
|
||||
"search": {
|
||||
"enable": false,
|
||||
"cve": {
|
||||
"updateInterval": "3h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, port, logFile.Name())
|
||||
|
||||
cfgfile, err := ioutil.TempFile("", "zot-test*.json")
|
||||
So(err, ShouldBeNil)
|
||||
defer os.Remove(cfgfile.Name()) // clean up
|
||||
_, err = cfgfile.Write([]byte(content))
|
||||
So(err, ShouldBeNil)
|
||||
err = cfgfile.Close()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
os.Args = []string{"cli_test", "serve", cfgfile.Name()}
|
||||
go func() {
|
||||
err = cli.NewServerRootCmd().Execute()
|
||||
So(err, ShouldBeNil)
|
||||
}()
|
||||
WaitTillServerReady(baseURL)
|
||||
|
||||
data, err := os.ReadFile(logFile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"Extensions\":{\"Search\":{\"CVE\":{\"UpdateInterval\":10800000000000},\"Enable\":false},\"Sync\":null,\"Metrics\":null}") // nolint:lll
|
||||
So(string(data), ShouldContainSubstring, "CVE config not provided, skipping CVE update")
|
||||
So(string(data), ShouldNotContainSubstring,
|
||||
"CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.")
|
||||
})
|
||||
}
|
|
@ -286,8 +286,9 @@ func TestServerResponse(t *testing.T) {
|
|||
url := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{Enable: true},
|
||||
Search: &extconf.SearchConfig{Enable: &defaultVal},
|
||||
}
|
||||
ctlr := api.NewController(conf)
|
||||
dir, err := ioutil.TempDir("", "oci-repo-test")
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
glob "github.com/bmatcuk/doublestar/v4"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
|
@ -15,6 +16,7 @@ import (
|
|||
"zotregistry.io/zot/errors"
|
||||
"zotregistry.io/zot/pkg/api"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
extconf "zotregistry.io/zot/pkg/extensions/config"
|
||||
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
@ -293,6 +295,64 @@ func validateConfiguration(config *config.Config) {
|
|||
}
|
||||
}
|
||||
|
||||
func applyDefaultValues(config *config.Config, viperInstance *viper.Viper) {
|
||||
defaultVal := true
|
||||
|
||||
if config.Extensions == nil && viperInstance.Get("extensions") != nil {
|
||||
config.Extensions = &extconf.ExtensionConfig{}
|
||||
|
||||
extMap := viperInstance.GetStringMap("extensions")
|
||||
_, ok := extMap["metrics"]
|
||||
|
||||
if ok {
|
||||
// we found a config like `"extensions": {"metrics": {}}`
|
||||
// Note: In case metrics is not empty the config.Extensions will not be nil and we will not reach here
|
||||
config.Extensions.Metrics = &extconf.MetricsConfig{}
|
||||
}
|
||||
|
||||
_, ok = extMap["search"]
|
||||
if ok {
|
||||
// we found a config like `"extensions": {"search": {}}`
|
||||
// Note: In case search is not empty the config.Extensions will not be nil and we will not reach here
|
||||
config.Extensions.Search = &extconf.SearchConfig{}
|
||||
}
|
||||
}
|
||||
|
||||
if config.Extensions != nil {
|
||||
if config.Extensions.Sync != nil {
|
||||
if config.Extensions.Sync.Enable == nil {
|
||||
config.Extensions.Sync.Enable = &defaultVal
|
||||
}
|
||||
|
||||
for id, regCfg := range config.Extensions.Sync.Registries {
|
||||
if regCfg.TLSVerify == nil {
|
||||
config.Extensions.Sync.Registries[id].TLSVerify = &defaultVal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if config.Extensions.Search != nil {
|
||||
if config.Extensions.Search.Enable == nil {
|
||||
config.Extensions.Search.Enable = &defaultVal
|
||||
}
|
||||
|
||||
if config.Extensions.Search.CVE == nil {
|
||||
config.Extensions.Search.CVE = &extconf.CVEConfig{UpdateInterval: 24 * time.Hour} // nolint: gomnd
|
||||
}
|
||||
}
|
||||
|
||||
if config.Extensions.Metrics != nil {
|
||||
if config.Extensions.Metrics.Enable == nil {
|
||||
config.Extensions.Metrics.Enable = &defaultVal
|
||||
}
|
||||
|
||||
if config.Extensions.Metrics.Prometheus == nil {
|
||||
config.Extensions.Metrics.Prometheus = &extconf.PrometheusConfig{Path: "/metrics"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func LoadConfiguration(config *config.Config, configPath string) {
|
||||
// Default is dot (.) but because we allow glob patterns in authz
|
||||
// we need another key delimiter.
|
||||
|
@ -322,17 +382,9 @@ func LoadConfiguration(config *config.Config, configPath string) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
// defaults
|
||||
applyDefaultValues(config, viperInstance)
|
||||
|
||||
// various config checks
|
||||
validateConfiguration(config)
|
||||
|
||||
// defaults
|
||||
defaultTLSVerify := true
|
||||
|
||||
if config.Extensions != nil && config.Extensions.Sync != nil {
|
||||
for id, regCfg := range config.Extensions.Sync.Registries {
|
||||
if regCfg.TLSVerify == nil {
|
||||
config.Extensions.Sync.Registries[id].TLSVerify = &defaultTLSVerify
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,8 @@ import (
|
|||
. "zotregistry.io/zot/pkg/test"
|
||||
)
|
||||
|
||||
const (
|
||||
SecondToNanoseconds = 1000000000
|
||||
)
|
||||
|
||||
func getRandomLatencyN(maxNanoSeconds int64) time.Duration {
|
||||
nBig, err := rand.Int(rand.Reader, big.NewInt(maxNanoSeconds))
|
||||
func getRandomLatencyN(max int64) time.Duration {
|
||||
nBig, err := rand.Int(rand.Reader, big.NewInt(max))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -43,7 +39,7 @@ func getRandomLatencyN(maxNanoSeconds int64) time.Duration {
|
|||
}
|
||||
|
||||
func getRandomLatency() time.Duration {
|
||||
return getRandomLatencyN(120 * SecondToNanoseconds) // a random latency (in nanoseconds) that can be up to 2 minutes
|
||||
return getRandomLatencyN(int64(2 * time.Minute)) // a random latency (in nanoseconds) that can be up to 2 minutes
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
|
@ -423,11 +419,11 @@ func TestNewExporter(t *testing.T) {
|
|||
var latency time.Duration
|
||||
if index == 0 {
|
||||
// first bucket value
|
||||
latency = getRandomLatencyN(int64(fvalue * SecondToNanoseconds))
|
||||
latency = getRandomLatencyN(int64(fvalue * float64(time.Second)))
|
||||
} else {
|
||||
pvalue := dBuckets[index-1] // previous bucket value
|
||||
latency = time.Duration(pvalue*SecondToNanoseconds) +
|
||||
getRandomLatencyN(int64(dBuckets[0]*SecondToNanoseconds))
|
||||
latency = time.Duration(pvalue*float64(time.Second)) +
|
||||
getRandomLatencyN(int64(dBuckets[0]*float64(time.Second)))
|
||||
}
|
||||
latencySum += latency.Seconds()
|
||||
monitoring.ObserveHTTPMethodLatency(serverController.Metrics, "GET", latency)
|
||||
|
|
|
@ -15,7 +15,7 @@ type ExtensionConfig struct {
|
|||
type SearchConfig struct {
|
||||
// CVE search
|
||||
CVE *CVEConfig
|
||||
Enable bool
|
||||
Enable *bool
|
||||
}
|
||||
|
||||
type CVEConfig struct {
|
||||
|
@ -23,7 +23,7 @@ type CVEConfig struct {
|
|||
}
|
||||
|
||||
type MetricsConfig struct {
|
||||
Enable bool
|
||||
Enable *bool
|
||||
Prometheus *PrometheusConfig
|
||||
}
|
||||
|
||||
|
|
|
@ -35,13 +35,13 @@ func downloadTrivyDB(dbDir string, log log.Logger, updateInterval time.Duration)
|
|||
}
|
||||
|
||||
func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
|
||||
if config.Extensions.Search != nil && config.Extensions.Search.Enable && config.Extensions.Search.CVE != nil {
|
||||
if config.Extensions.Search != nil && *config.Extensions.Search.Enable && config.Extensions.Search.CVE != nil {
|
||||
defaultUpdateInterval, _ := time.ParseDuration("2h")
|
||||
|
||||
if config.Extensions.Search.CVE.UpdateInterval < defaultUpdateInterval {
|
||||
config.Extensions.Search.CVE.UpdateInterval = defaultUpdateInterval
|
||||
|
||||
log.Warn().Msg("CVE update interval set to too-short interval <= 1, changing update duration to 2 hours and continuing.") // nolint: lll
|
||||
log.Warn().Msg("CVE update interval set to too-short interval < 2h, changing update duration to 2 hours and continuing.") // nolint: lll
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
@ -56,7 +56,7 @@ func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
|
|||
}
|
||||
|
||||
if config.Extensions.Metrics != nil &&
|
||||
config.Extensions.Metrics.Enable &&
|
||||
*config.Extensions.Metrics.Enable &&
|
||||
config.Extensions.Metrics.Prometheus != nil {
|
||||
if config.Extensions.Metrics.Prometheus.Path == "" {
|
||||
config.Extensions.Metrics.Prometheus.Path = "/metrics"
|
||||
|
@ -71,7 +71,7 @@ func EnableExtensions(config *config.Config, log log.Logger, rootDir string) {
|
|||
// EnableSyncExtension enables sync extension.
|
||||
func EnableSyncExtension(config *config.Config, wg *goSync.WaitGroup,
|
||||
storeController storage.StoreController, log log.Logger) {
|
||||
if config.Extensions.Sync != nil {
|
||||
if config.Extensions.Sync != nil && *config.Extensions.Sync.Enable {
|
||||
if err := sync.Run(*config.Extensions.Sync, storeController, wg, log); err != nil {
|
||||
log.Error().Err(err).Msg("Error encountered while setting up syncing")
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func SetupRoutes(config *config.Config, router *mux.Router, storeController stor
|
|||
log := log.Logger{Logger: l.With().Caller().Timestamp().Logger()}
|
||||
log.Info().Msg("setting up extensions routes")
|
||||
|
||||
if config.Extensions.Search != nil && config.Extensions.Search.Enable {
|
||||
if config.Extensions.Search != nil && *config.Extensions.Search.Enable {
|
||||
var resConfig search.Config
|
||||
|
||||
if config.Extensions.Search.CVE != nil {
|
||||
|
@ -100,7 +100,7 @@ func SetupRoutes(config *config.Config, router *mux.Router, storeController stor
|
|||
Handler(gqlHandler.NewDefaultServer(search.NewExecutableSchema(resConfig)))
|
||||
}
|
||||
|
||||
if config.Extensions.Metrics != nil && config.Extensions.Metrics.Enable {
|
||||
if config.Extensions.Metrics != nil && *config.Extensions.Metrics.Enable {
|
||||
router.PathPrefix(config.Extensions.Metrics.Prometheus.Path).
|
||||
Handler(promhttp.Handler())
|
||||
}
|
||||
|
|
|
@ -36,8 +36,9 @@ func TestExtensionMetrics(t *testing.T) {
|
|||
|
||||
conf.Storage.RootDirectory = rootDir
|
||||
conf.Extensions = &extconf.ExtensionConfig{}
|
||||
enabled := true
|
||||
conf.Extensions.Metrics = &extconf.MetricsConfig{
|
||||
Enable: true,
|
||||
Enable: &enabled,
|
||||
Prometheus: &extconf.PrometheusConfig{Path: "/metrics"},
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,8 @@ func TestExtensionMetrics(t *testing.T) {
|
|||
|
||||
conf.Storage.RootDirectory = rootDir
|
||||
conf.Extensions = &extconf.ExtensionConfig{}
|
||||
conf.Extensions.Metrics = &extconf.MetricsConfig{Enable: false}
|
||||
var disabled bool
|
||||
conf.Extensions.Metrics = &extconf.MetricsConfig{Enable: &disabled}
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
So(ctlr, ShouldNotBeNil)
|
||||
|
|
|
@ -186,8 +186,9 @@ func TestLatestTagSearchHTTP(t *testing.T) {
|
|||
conf.Storage.RootDirectory = rootDir
|
||||
conf.Storage.SubPaths = make(map[string]config.StorageConfig)
|
||||
conf.Storage.SubPaths["/a"] = config.StorageConfig{RootDirectory: subRootDir}
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{Enable: true},
|
||||
Search: &extconf.SearchConfig{Enable: &defaultVal},
|
||||
}
|
||||
|
||||
conf.Extensions.Search.CVE = nil
|
||||
|
|
|
@ -380,7 +380,7 @@ func TestDownloadDB(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCVESearch(t *testing.T) {
|
||||
Convey("Test image vulenrability scanning", t, func() {
|
||||
Convey("Test image vulnerability scanning", t, func() {
|
||||
updateDuration, _ = time.ParseDuration("1h")
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
|
@ -395,18 +395,21 @@ func TestCVESearch(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
ctlr.Config.Storage.RootDirectory = dbDir
|
||||
conf.Storage.RootDirectory = dbDir
|
||||
cveConfig := &extconf.CVEConfig{
|
||||
UpdateInterval: updateDuration,
|
||||
}
|
||||
defaultVal := true
|
||||
searchConfig := &extconf.SearchConfig{
|
||||
Enable: &defaultVal,
|
||||
CVE: cveConfig,
|
||||
Enable: true,
|
||||
}
|
||||
ctlr.Config.Extensions = &extconf.ExtensionConfig{
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: searchConfig,
|
||||
}
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
||||
go func() {
|
||||
// this blocks
|
||||
if err := ctlr.Run(); err != nil {
|
||||
|
|
|
@ -145,8 +145,9 @@ func TestDigestSearchHTTP(t *testing.T) {
|
|||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
conf.Storage.RootDirectory = rootDir
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{Enable: true},
|
||||
Search: &extconf.SearchConfig{Enable: &defaultVal},
|
||||
}
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
@ -272,8 +273,9 @@ func TestDigestSearchHTTPSubPaths(t *testing.T) {
|
|||
baseURL := GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{Enable: true},
|
||||
Search: &extconf.SearchConfig{Enable: &defaultVal},
|
||||
}
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
@ -339,6 +341,7 @@ func TestDigestSearchHTTPSubPaths(t *testing.T) {
|
|||
|
||||
func TestDigestSearchDisabled(t *testing.T) {
|
||||
Convey("Test disabling image search", t, func() {
|
||||
var disabled bool
|
||||
dir, err := ioutil.TempDir("", "digest_test")
|
||||
So(err, ShouldBeNil)
|
||||
port := GetFreePort()
|
||||
|
@ -347,7 +350,7 @@ func TestDigestSearchDisabled(t *testing.T) {
|
|||
conf.HTTP.Port = port
|
||||
conf.Storage.RootDirectory = dir
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{Enable: false},
|
||||
Search: &extconf.SearchConfig{Enable: &disabled},
|
||||
}
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
|
|
@ -42,6 +42,7 @@ type Credentials struct {
|
|||
}
|
||||
|
||||
type Config struct {
|
||||
Enable *bool
|
||||
CredentialsFile string
|
||||
Registries []RegistryConfig
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ func startUpstreamServer(secure, basicAuth bool) (*api.Controller, string, strin
|
|||
|
||||
client.SetTLSClientConfig(&tls.Config{RootCAs: caCertPool, MinVersion: tls.VersionTLS12})
|
||||
|
||||
cert, err := tls.LoadX509KeyPair("../../../test/data/client.cert", "../../../test/data/client.key")
|
||||
cert, err := tls.LoadX509KeyPair(ClientCert, ClientKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ func startDownstreamServer(secure bool, syncConfig *sync.Config) (*api.Controlle
|
|||
|
||||
client.SetTLSClientConfig(&tls.Config{RootCAs: caCertPool, MinVersion: tls.VersionTLS12})
|
||||
|
||||
cert, err := tls.LoadX509KeyPair("../../../test/data/client.cert", "../../../test/data/client.key")
|
||||
cert, err := tls.LoadX509KeyPair(ClientCert, ClientKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -279,7 +279,9 @@ func TestOnDemand(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
|
@ -413,7 +415,11 @@ func TestPeriodically(t *testing.T) {
|
|||
RetryDelay: &delay,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -485,7 +491,10 @@ func TestPeriodically(t *testing.T) {
|
|||
CertDir: "",
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -578,7 +587,11 @@ func TestPermsDenied(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -634,7 +647,11 @@ func TestBadTLS(t *testing.T) {
|
|||
TLSVerify: &tlsVerify,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(true, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -729,7 +746,11 @@ func TestTLS(t *testing.T) {
|
|||
CertDir: destClientCertDir,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, _, destDir, _ := startDownstreamServer(true, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -791,7 +812,9 @@ func TestBasicAuth(t *testing.T) {
|
|||
CertDir: "",
|
||||
}
|
||||
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
CredentialsFile: credentialsFile,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
@ -896,8 +919,9 @@ func TestBasicAuth(t *testing.T) {
|
|||
}
|
||||
|
||||
destConfig.Extensions = &extconf.ExtensionConfig{}
|
||||
destConfig.Extensions.Search = nil
|
||||
defaultVal := true
|
||||
destConfig.Extensions.Sync = &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
CredentialsFile: credentialsFile,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
@ -973,7 +997,9 @@ func TestBasicAuth(t *testing.T) {
|
|||
CertDir: "",
|
||||
}
|
||||
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
CredentialsFile: credentialsFile,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
@ -1019,8 +1045,10 @@ func TestBasicAuth(t *testing.T) {
|
|||
OnDemand: false,
|
||||
}
|
||||
|
||||
defaultVal := true
|
||||
// add file path to the credentials
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
CredentialsFile: credentialsFile,
|
||||
Registries: []sync.RegistryConfig{
|
||||
unreacheableSyncRegistryConfig1,
|
||||
|
@ -1115,7 +1143,11 @@ func TestBadURL(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1159,7 +1191,11 @@ func TestNoImagesByRegex(t *testing.T) {
|
|||
CertDir: "",
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1217,7 +1253,11 @@ func TestInvalidRegex(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, _, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1272,7 +1312,11 @@ func TestNotSemver(t *testing.T) {
|
|||
CertDir: "",
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1367,7 +1411,11 @@ func TestInvalidCerts(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1421,7 +1469,11 @@ func TestInvalidUrl(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1469,7 +1521,9 @@ func TestInvalidTags(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
|
@ -1555,7 +1609,9 @@ func TestSubPaths(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
|
@ -1662,7 +1718,11 @@ func TestOnDemandRepoErr(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1708,7 +1768,11 @@ func TestOnDemandContentFiltering(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1744,7 +1808,11 @@ func TestOnDemandContentFiltering(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1790,7 +1858,11 @@ func TestConfigRules(t *testing.T) {
|
|||
OnDemand: false,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1817,7 +1889,11 @@ func TestConfigRules(t *testing.T) {
|
|||
OnDemand: false,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1841,7 +1917,11 @@ func TestConfigRules(t *testing.T) {
|
|||
OnDemand: false,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1888,7 +1968,11 @@ func TestMultipleURLs(t *testing.T) {
|
|||
CertDir: "",
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dc, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -1983,7 +2067,9 @@ func TestPeriodicallySignatures(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
|
@ -2258,7 +2344,11 @@ func TestOnDemandRetryGoroutine(t *testing.T) {
|
|||
syncRegistryConfig.MaxRetries = &maxRetries
|
||||
syncRegistryConfig.RetryDelay = &delay
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dc, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -2336,7 +2426,11 @@ func TestOnDemandMultipleRetries(t *testing.T) {
|
|||
syncRegistryConfig.MaxRetries = &maxRetries
|
||||
syncRegistryConfig.RetryDelay = &delay
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dc, destBaseURL, destDir, destClient := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -2446,7 +2540,11 @@ func TestOnDemandPullsOnce(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dc, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -2542,7 +2640,11 @@ func TestError(t *testing.T) {
|
|||
CertDir: "",
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, client := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -2601,7 +2703,11 @@ func TestSignaturesOnDemand(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
@ -2737,7 +2843,11 @@ func TestOnlySignaturesOnDemand(t *testing.T) {
|
|||
OnDemand: true,
|
||||
}
|
||||
|
||||
syncConfig := &sync.Config{Registries: []sync.RegistryConfig{syncBadRegistryConfig, syncRegistryConfig}}
|
||||
defaultVal := true
|
||||
syncConfig := &sync.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []sync.RegistryConfig{syncBadRegistryConfig, syncRegistryConfig},
|
||||
}
|
||||
|
||||
dctlr, destBaseURL, destDir, _ := startDownstreamServer(false, syncConfig)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
|
Loading…
Reference in a new issue