feat(userprefs): update documentation and list extensions endpoint (#1456)
Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
This commit is contained in:
parent
970997f3a8
commit
2b8479f7f2
@ -7249,11 +7249,12 @@ func TestDistSpecExtensions(t *testing.T) {
|
||||
err = json.Unmarshal(resp.Body(), &extensionList)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(extensionList.Extensions), ShouldEqual, 1)
|
||||
So(len(extensionList.Extensions[0].Endpoints), ShouldEqual, 1)
|
||||
So(len(extensionList.Extensions[0].Endpoints), ShouldEqual, 2)
|
||||
So(extensionList.Extensions[0].Name, ShouldEqual, "_zot")
|
||||
So(extensionList.Extensions[0].URL, ShouldContainSubstring, "_zot.md")
|
||||
So(extensionList.Extensions[0].Description, ShouldNotBeEmpty)
|
||||
So(extensionList.Extensions[0].Endpoints[0], ShouldEqual, constants.FullSearchPrefix)
|
||||
So(extensionList.Extensions[0].Endpoints, ShouldContain, constants.FullSearchPrefix)
|
||||
So(extensionList.Extensions[0].Endpoints, ShouldContain, constants.FullUserPreferencesPrefix)
|
||||
})
|
||||
|
||||
Convey("start zot server with search and mgmt extensions", t, func(c C) {
|
||||
@ -7297,17 +7298,14 @@ func TestDistSpecExtensions(t *testing.T) {
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
err = json.Unmarshal(resp.Body(), &extensionList)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(extensionList.Extensions), ShouldEqual, 2)
|
||||
So(len(extensionList.Extensions[0].Endpoints), ShouldEqual, 1)
|
||||
So(len(extensionList.Extensions[1].Endpoints), ShouldEqual, 1)
|
||||
So(len(extensionList.Extensions), ShouldEqual, 1)
|
||||
So(len(extensionList.Extensions[0].Endpoints), ShouldEqual, 3)
|
||||
So(extensionList.Extensions[0].Name, ShouldEqual, "_zot")
|
||||
So(extensionList.Extensions[0].URL, ShouldContainSubstring, "_zot.md")
|
||||
So(extensionList.Extensions[0].Description, ShouldNotBeEmpty)
|
||||
So(extensionList.Extensions[0].Endpoints[0], ShouldEqual, constants.FullSearchPrefix)
|
||||
So(extensionList.Extensions[1].Name, ShouldEqual, "_zot")
|
||||
So(extensionList.Extensions[1].URL, ShouldContainSubstring, "_zot.md")
|
||||
So(extensionList.Extensions[1].Description, ShouldNotBeEmpty)
|
||||
So(extensionList.Extensions[1].Endpoints[0], ShouldEqual, constants.FullMgmtPrefix)
|
||||
So(extensionList.Extensions[0].Endpoints, ShouldContain, constants.FullSearchPrefix)
|
||||
So(extensionList.Extensions[0].Endpoints, ShouldContain, constants.FullUserPreferencesPrefix)
|
||||
So(extensionList.Extensions[0].Endpoints, ShouldContain, constants.FullMgmtPrefix)
|
||||
})
|
||||
|
||||
Convey("start minimal zot server", t, func(c C) {
|
||||
|
@ -7,6 +7,7 @@ Component | Endpoint | Description
|
||||
--- | --- | ---
|
||||
[`search`](search/search.md) | `/v2/_zot/ext/search` | efficient and enhanced registry search capabilities using graphQL backend
|
||||
[`mgmt`](mgmt.md) | `/v2/_zot/ext/mgmt` | config management
|
||||
[`userprefs`](userprefs.md) | `/v2/_zot/ext/userprefs` | change user preferences
|
||||
|
||||
|
||||
# References
|
||||
|
@ -40,6 +40,10 @@ type StrippedConfig struct {
|
||||
} `json:"http" mapstructure:"http"`
|
||||
}
|
||||
|
||||
func IsBuiltWithMGMTExtension() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (auth Auth) MarshalJSON() ([]byte, error) {
|
||||
type localAuth Auth
|
||||
|
||||
|
@ -10,6 +10,10 @@ import (
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
)
|
||||
|
||||
func IsBuiltWithMGMTExtension() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func SetupMgmtRoutes(config *config.Config, router *mux.Router, log log.Logger) {
|
||||
log.Warn().Msg("skipping setting up mgmt routes because given zot binary doesn't include this feature," +
|
||||
"please build a binary that does so")
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
|
||||
gqlHandler "github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/gorilla/mux"
|
||||
distext "github.com/opencontainers/distribution-spec/specs-go/v1/extensions"
|
||||
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/api/constants"
|
||||
@ -34,6 +33,10 @@ const (
|
||||
done
|
||||
)
|
||||
|
||||
func IsBuiltWithSearchExtension() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func GetCVEInfo(config *config.Config, storeController storage.StoreController,
|
||||
repoDB repodb.RepoDB, log log.Logger,
|
||||
) CveInfo {
|
||||
@ -199,42 +202,3 @@ func SearchACHeadersHandler() mux.MiddlewareFunc {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getExtension(name, url, description string, endpoints []string) distext.Extension {
|
||||
return distext.Extension{
|
||||
Name: name,
|
||||
URL: url,
|
||||
Description: description,
|
||||
Endpoints: endpoints,
|
||||
}
|
||||
}
|
||||
|
||||
func GetExtensions(config *config.Config) distext.ExtensionList {
|
||||
extensionList := distext.ExtensionList{}
|
||||
|
||||
extensions := make([]distext.Extension, 0)
|
||||
|
||||
if config.Extensions != nil && config.Extensions.Search != nil {
|
||||
endpoints := []string{constants.FullSearchPrefix}
|
||||
searchExt := getExtension("_zot",
|
||||
"https://github.com/project-zot/zot/blob/"+config.ReleaseTag+"/pkg/extensions/_zot.md",
|
||||
"zot registry extensions",
|
||||
endpoints)
|
||||
|
||||
extensions = append(extensions, searchExt)
|
||||
}
|
||||
|
||||
if config.Extensions != nil && config.Extensions.Mgmt != nil {
|
||||
endpoints := []string{constants.FullMgmtPrefix}
|
||||
mgmtExt := getExtension("_zot",
|
||||
"https://github.com/project-zot/zot/blob/"+config.ReleaseTag+"/pkg/extensions/_zot.md",
|
||||
"zot registry extensions",
|
||||
endpoints)
|
||||
|
||||
extensions = append(extensions, mgmtExt)
|
||||
}
|
||||
|
||||
extensionList.Extensions = extensions
|
||||
|
||||
return extensionList
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ package extensions
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
distext "github.com/opencontainers/distribution-spec/specs-go/v1/extensions"
|
||||
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
@ -22,6 +21,10 @@ func GetCVEInfo(config *config.Config, storeController storage.StoreController,
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsBuiltWithSearchExtension() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// EnableSearchExtension ...
|
||||
func EnableSearchExtension(config *config.Config, storeController storage.StoreController,
|
||||
repoDB repodb.RepoDB, scheduler *scheduler.Scheduler, cveInfo CveInfo, log log.Logger,
|
||||
@ -37,8 +40,3 @@ func SetupSearchRoutes(config *config.Config, router *mux.Router, storeControlle
|
||||
log.Warn().Msg("skipping setting up search routes because given zot binary doesn't include this feature," +
|
||||
"please build a binary that does so")
|
||||
}
|
||||
|
||||
// GetExtensions...
|
||||
func GetExtensions(config *config.Config) distext.ExtensionList {
|
||||
return distext.ExtensionList{}
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ const (
|
||||
ToggleRepoStarAction = "toggleStar"
|
||||
)
|
||||
|
||||
func IsBuiltWithUserPrefsExtension() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func SetupUserPreferencesRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
|
||||
repoDB repodb.RepoDB, cveInfo CveInfo, log log.Logger,
|
||||
) {
|
||||
|
@ -12,6 +12,10 @@ import (
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
func IsBuiltWithUserPrefsExtension() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func SetupUserPreferencesRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
|
||||
repoDB repodb.RepoDB, cveInfo CveInfo, log log.Logger,
|
||||
) {
|
||||
|
42
pkg/extensions/get_extensions.go
Normal file
42
pkg/extensions/get_extensions.go
Normal file
@ -0,0 +1,42 @@
|
||||
package extensions
|
||||
|
||||
import (
|
||||
distext "github.com/opencontainers/distribution-spec/specs-go/v1/extensions"
|
||||
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/api/constants"
|
||||
)
|
||||
|
||||
func GetExtensions(config *config.Config) distext.ExtensionList {
|
||||
extensionList := distext.ExtensionList{}
|
||||
|
||||
endpoints := []string{}
|
||||
extensions := []distext.Extension{}
|
||||
|
||||
if config.Extensions != nil && config.Extensions.Search != nil {
|
||||
if IsBuiltWithSearchExtension() {
|
||||
endpoints = append(endpoints, constants.FullSearchPrefix)
|
||||
}
|
||||
|
||||
if IsBuiltWithUserPrefsExtension() {
|
||||
endpoints = append(endpoints, constants.FullUserPreferencesPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
if IsBuiltWithMGMTExtension() && config.Extensions != nil && config.Extensions.Mgmt != nil {
|
||||
endpoints = append(endpoints, constants.FullMgmtPrefix)
|
||||
}
|
||||
|
||||
if len(endpoints) > 0 {
|
||||
extensions = append(extensions, distext.Extension{
|
||||
Name: "_zot",
|
||||
URL: "https://github.com/project-zot/zot/blob/" + config.ReleaseTag + "/pkg/extensions/_zot.md",
|
||||
Description: "zot registry extensions",
|
||||
Endpoints: endpoints,
|
||||
})
|
||||
}
|
||||
|
||||
extensionList.Extensions = extensions
|
||||
|
||||
return extensionList
|
||||
}
|
76
pkg/extensions/get_extensions_disabled_test.go
Normal file
76
pkg/extensions/get_extensions_disabled_test.go
Normal file
@ -0,0 +1,76 @@
|
||||
//go:build !search && !mgmt && !userprefs
|
||||
|
||||
package extensions_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
distext "github.com/opencontainers/distribution-spec/specs-go/v1/extensions"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"gopkg.in/resty.v1"
|
||||
|
||||
"zotregistry.io/zot/pkg/api"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/api/constants"
|
||||
extconf "zotregistry.io/zot/pkg/extensions/config"
|
||||
"zotregistry.io/zot/pkg/test"
|
||||
)
|
||||
|
||||
func TestGetExensionsDisabled(t *testing.T) {
|
||||
Convey("start zot server with extensions but no extensions built", t, func(c C) {
|
||||
conf := config.New()
|
||||
port := test.GetFreePort()
|
||||
baseURL := test.GetBaseURL(port)
|
||||
|
||||
conf.HTTP.Port = port
|
||||
|
||||
defaultVal := true
|
||||
|
||||
searchConfig := &extconf.SearchConfig{
|
||||
BaseConfig: extconf.BaseConfig{Enable: &defaultVal},
|
||||
}
|
||||
|
||||
mgmtConfg := &extconf.MgmtConfig{
|
||||
BaseConfig: extconf.BaseConfig{Enable: &defaultVal},
|
||||
}
|
||||
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: searchConfig,
|
||||
Mgmt: mgmtConfg,
|
||||
}
|
||||
|
||||
logFile, err := os.CreateTemp("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
conf.Log.Output = logFile.Name()
|
||||
defer os.Remove(logFile.Name()) // clean up
|
||||
|
||||
ctlr := makeController(conf, t.TempDir(), "")
|
||||
|
||||
cm := test.NewControllerManager(ctlr)
|
||||
cm.StartAndWait(port)
|
||||
defer cm.StopServer()
|
||||
|
||||
var extensionList distext.ExtensionList
|
||||
|
||||
resp, err := resty.R().Get(baseURL + constants.RoutePrefix + constants.ExtOciDiscoverPrefix)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
err = json.Unmarshal(resp.Body(), &extensionList)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(extensionList.Extensions), ShouldEqual, 0)
|
||||
})
|
||||
}
|
||||
|
||||
func makeController(conf *config.Config, dir string, copyTestDataDest string) *api.Controller {
|
||||
ctlr := api.NewController(conf)
|
||||
|
||||
if copyTestDataDest != "" {
|
||||
test.CopyTestFiles(copyTestDataDest, dir)
|
||||
}
|
||||
ctlr.Config.Storage.RootDirectory = dir
|
||||
|
||||
return ctlr
|
||||
}
|
31
pkg/extensions/userprefs.md
Normal file
31
pkg/extensions/userprefs.md
Normal file
@ -0,0 +1,31 @@
|
||||
# `userprefs`
|
||||
|
||||
`userprefs` component provides an endpoint for adding user preferences for repos. It is available only to authentificated users. Unauthentificated users will be denied access.
|
||||
|
||||
| Supported queries | Input | Output | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| [Toggle repo star](#toggle-repo-star) | None | None | Sets the repo starred property to true if it is false, and to false if it is true |
|
||||
| [Toggle repo bookmark](#toggle-repo-bookmark) | None | None | Sets the repo bookmarked property to true if it is false, and to false if it is true |
|
||||
|
||||
## General usage
|
||||
The userprefs endpoint accepts as a query parameter what `action` to perform and then all other required parameters for the specified action.
|
||||
|
||||
## Toggle repo star
|
||||
| Action | Parameter | Parameter Type | Parameter Description |
|
||||
| --- | --- | --- | --- |
|
||||
| toggleStar | repo | string | The repo name which should be starred |
|
||||
|
||||
A request to togle a star on a repo would look like this:
|
||||
```
|
||||
(PUT) http://localhost:8080/v2/_zot/ext/userprefs?action=toggleStar&repo=repoName
|
||||
```
|
||||
|
||||
## Toggle repo bookmark
|
||||
| Action | Parameter | Parameter Type | Parameter Description |
|
||||
| --- | --- | --- | --- |
|
||||
| toggleBookmark | repo | string | The repo name which should be bookmarked |
|
||||
|
||||
A request to togle a bookmark on a repo would look like this:
|
||||
```
|
||||
(PUT) http://localhost:8080/v2/_zot/ext/userprefs?action=toggleBookmark&repo=repoName
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user