0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-16 21:56:37 -05:00
zot/pkg/cli/config_reloader_test.go
Petu Eusebiu 6d04ab3cdc sync: support reloading sync config when the config file changes
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
2022-03-18 11:24:11 -07:00

384 lines
8.7 KiB
Go

package cli_test
import (
"fmt"
"io"
"io/ioutil"
"os"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
"golang.org/x/crypto/bcrypt"
"zotregistry.io/zot/pkg/cli"
"zotregistry.io/zot/pkg/test"
)
func TestConfigReloader(t *testing.T) {
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
Convey("reload access control config", t, func(c C) {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
logFile, err := ioutil.TempFile("", "zot-log*.txt")
So(err, ShouldBeNil)
username := "alice"
password := "alice"
hash, err := bcrypt.GenerateFromPassword([]byte(password), 10)
if err != nil {
panic(err)
}
usernameAndHash := fmt.Sprintf("%s:%s", username, string(hash))
htpasswdPath := test.MakeHtpasswdFileFromString(usernameAndHash)
defer os.Remove(htpasswdPath)
defer os.Remove(logFile.Name()) // clean up
content := fmt.Sprintf(`{
"distSpecVersion": "0.1.0-dev",
"storage": {
"rootDirectory": "/tmp/zot"
},
"http": {
"address": "127.0.0.1",
"port": "%s",
"realm": "zot",
"auth": {
"htpasswd": {
"path": "%s"
},
"failDelay": 1
},
"accessControl": {
"**": {
"policies": [
{
"users": ["charlie"],
"actions": ["read"]
}
],
"defaultPolicy": ["read", "create"]
},
"adminPolicy": {
"users": ["admin"],
"actions": ["read", "create", "update", "delete"]
}
}
},
"log": {
"level": "debug",
"output": "%s"
}
}`, port, htpasswdPath, 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)
}()
test.WaitTillServerReady(baseURL)
content = fmt.Sprintf(`{
"distSpecVersion": "0.1.0-dev",
"storage": {
"rootDirectory": "/tmp/zot"
},
"http": {
"address": "127.0.0.1",
"port": "%s",
"realm": "zot",
"auth": {
"htpasswd": {
"path": "%s"
},
"failDelay": 1
},
"accessControl": {
"**": {
"policies": [
{
"users": ["alice"],
"actions": ["read", "create", "update", "delete"]
}
],
"defaultPolicy": ["read"]
},
"adminPolicy": {
"users": ["admin"],
"actions": ["read", "create", "update", "delete"]
}
}
},
"log": {
"level": "debug",
"output": "%s"
}
}`, port, htpasswdPath, logFile.Name())
err = cfgfile.Truncate(0)
So(err, ShouldBeNil)
_, err = cfgfile.Seek(0, io.SeekStart)
So(err, ShouldBeNil)
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
err = cfgfile.Close()
So(err, ShouldBeNil)
// wait for config reload
time.Sleep(2 * time.Second)
data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, "reloaded params")
So(string(data), ShouldContainSubstring, "new configuration settings")
So(string(data), ShouldContainSubstring, "\"Users\":[\"alice\"]")
So(string(data), ShouldContainSubstring, "\"Actions\":[\"read\",\"create\",\"update\",\"delete\"]")
})
Convey("reload sync config", t, func(c C) {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
logFile, err := ioutil.TempFile("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
content := fmt.Sprintf(`{
"distSpecVersion": "0.1.0-dev",
"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)
}()
test.WaitTillServerReady(baseURL)
content = fmt.Sprintf(`{
"distSpecVersion": "0.1.0-dev",
"storage": {
"rootDirectory": "/tmp/zot"
},
"http": {
"address": "127.0.0.1",
"port": "%s"
},
"log": {
"level": "debug",
"output": "%s"
},
"extensions": {
"sync": {
"registries": [{
"urls": ["http://localhost:9999"],
"tlsVerify": true,
"onDemand": false,
"maxRetries": 10,
"retryDelay": "5m",
"certDir": "certs",
"content":[
{
"prefix": "zot-cve-test",
"tags": {
"regex": "tag",
"semver": false
}
}
]
}]
}
}
}`, port, logFile.Name())
err = cfgfile.Truncate(0)
So(err, ShouldBeNil)
_, err = cfgfile.Seek(0, io.SeekStart)
So(err, ShouldBeNil)
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
err = cfgfile.Close()
So(err, ShouldBeNil)
// wait for config reload
time.Sleep(2 * time.Second)
data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil)
So(string(data), ShouldContainSubstring, "reloaded params")
So(string(data), ShouldContainSubstring, "new configuration settings")
So(string(data), ShouldContainSubstring, "\"URLs\":[\"http://localhost:9999\"]")
So(string(data), ShouldContainSubstring, "\"TLSVerify\":true")
So(string(data), ShouldContainSubstring, "\"OnDemand\":false")
So(string(data), ShouldContainSubstring, "\"MaxRetries\":10")
So(string(data), ShouldContainSubstring, "\"RetryDelay\":300000000000")
So(string(data), ShouldContainSubstring, "\"CertDir\":\"certs\"")
So(string(data), ShouldContainSubstring, "\"Prefix\":\"zot-cve-test\"")
So(string(data), ShouldContainSubstring, "\"Regex\":\"tag\"")
So(string(data), ShouldContainSubstring, "\"Semver\":false")
})
Convey("reload bad config", t, func(c C) {
port := test.GetFreePort()
baseURL := test.GetBaseURL(port)
logFile, err := ioutil.TempFile("", "zot-log*.txt")
So(err, ShouldBeNil)
defer os.Remove(logFile.Name()) // clean up
content := fmt.Sprintf(`{
"distSpecVersion": "0.1.0-dev",
"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)
}()
test.WaitTillServerReady(baseURL)
content = "[]"
err = cfgfile.Truncate(0)
So(err, ShouldBeNil)
_, err = cfgfile.Seek(0, io.SeekStart)
So(err, ShouldBeNil)
_, err = cfgfile.WriteString(content)
So(err, ShouldBeNil)
err = cfgfile.Close()
So(err, ShouldBeNil)
// wait for config reload
time.Sleep(2 * time.Second)
data, err := os.ReadFile(logFile.Name())
So(err, ShouldBeNil)
So(string(data), ShouldNotContainSubstring, "reloaded params")
So(string(data), ShouldNotContainSubstring, "new configuration settings")
So(string(data), ShouldContainSubstring, "\"URLs\":[\"http://localhost:8080\"]")
So(string(data), ShouldContainSubstring, "\"TLSVerify\":false")
So(string(data), ShouldContainSubstring, "\"OnDemand\":true")
So(string(data), ShouldContainSubstring, "\"MaxRetries\":3")
So(string(data), ShouldContainSubstring, "\"CertDir\":\"\"")
So(string(data), ShouldContainSubstring, "\"Prefix\":\"zot-test\"")
So(string(data), ShouldContainSubstring, "\"Regex\":\".*\"")
So(string(data), ShouldContainSubstring, "\"Semver\":true")
})
}