diff --git a/README.md b/README.md index 870b3dde..ae431b32 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,11 @@ cd web && yarn && yarn build && cd .. && make build - [x] Support OCI artifact such as helm and so on. - [x] Support OCI sbom. - [x] Support Image security scan. -- [ ] Support registry proxy. -- [ ] Support Namespace quota. +- [x] Support registry proxy. +- [x] Support Namespace quota. +- [x] Support Image automatic garbage collection. +- [x] Support Multi-tenancy. - [ ] Support Image replication. - [ ] Support Image build in docker, podman and kubernetes. - [ ] Support Image sign. -- [ ] Support Image automatic garbage collection. -- [ ] Support Multi-tenancy. - [ ] Support helm chart search and index.json. diff --git a/cmd/distribution.go b/cmd/distribution.go new file mode 100644 index 00000000..c7a30308 --- /dev/null +++ b/cmd/distribution.go @@ -0,0 +1,61 @@ +package cmd + +import ( + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/ximager/ximager/pkg/cmds/distribution" + "github.com/ximager/ximager/pkg/configs" + "github.com/ximager/ximager/pkg/daemon" + "github.com/ximager/ximager/pkg/dal" + "github.com/ximager/ximager/pkg/inits" + "github.com/ximager/ximager/pkg/logger" +) + +// distributionCmd represents the distribution command +var distributionCmd = &cobra.Command{ + Use: "distribution", + Aliases: []string{"ds"}, + Short: "Start the XImager distribution server", + PersistentPreRun: func(_ *cobra.Command, _ []string) { + initConfig() + logger.SetLevel(viper.GetString("log.level")) + }, + Run: func(_ *cobra.Command, _ []string) { + err := configs.Initialize() + if err != nil { + log.Error().Err(err).Msg("Initialize configs with error") + return + } + + err = dal.Initialize() + if err != nil { + log.Error().Err(err).Msg("Initialize database with error") + return + } + + err = inits.Initialize() + if err != nil { + log.Error().Err(err).Msg("Initialize inits with error") + return + } + + err = daemon.InitializeClient() + if err != nil { + log.Error().Err(err).Msg("Initialize daemon client with error") + return + } + + err = distribution.Serve() + if err != nil { + log.Error().Err(err).Msg("Start distribution with error") + return + } + }, +} + +func init() { + distributionCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is /etc/ximager/ximager.yaml)") + rootCmd.AddCommand(distributionCmd) +} diff --git a/cmd/imports/apis.go b/cmd/imports/apis.go new file mode 100644 index 00000000..2237943d --- /dev/null +++ b/cmd/imports/apis.go @@ -0,0 +1,10 @@ +package cmd + +import ( + _ "github.com/ximager/ximager/pkg/handlers/artifacts" + _ "github.com/ximager/ximager/pkg/handlers/namespaces" + _ "github.com/ximager/ximager/pkg/handlers/repositories" + _ "github.com/ximager/ximager/pkg/handlers/tags" + _ "github.com/ximager/ximager/pkg/handlers/tokens" + _ "github.com/ximager/ximager/pkg/handlers/users" +) diff --git a/cmd/imports/distribution.go b/cmd/imports/distribution.go new file mode 100644 index 00000000..eda1b878 --- /dev/null +++ b/cmd/imports/distribution.go @@ -0,0 +1,8 @@ +package cmd + +import ( + _ "github.com/ximager/ximager/pkg/handlers/distribution/base" + _ "github.com/ximager/ximager/pkg/handlers/distribution/blob" + _ "github.com/ximager/ximager/pkg/handlers/distribution/manifest" + _ "github.com/ximager/ximager/pkg/handlers/distribution/upload" +) diff --git a/cmd/imports/storage.go b/cmd/imports/storage.go new file mode 100644 index 00000000..54a16261 --- /dev/null +++ b/cmd/imports/storage.go @@ -0,0 +1,7 @@ +package cmd + +import ( + _ "github.com/ximager/ximager/pkg/storage/cos" + _ "github.com/ximager/ximager/pkg/storage/filesystem" + _ "github.com/ximager/ximager/pkg/storage/s3" +) diff --git a/cmd/root.go b/cmd/root.go index d5e80afe..66e7954b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -23,10 +23,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - _ "github.com/golang/mock/mockgen/model" - _ "github.com/ximager/ximager/pkg/storage/cos" - _ "github.com/ximager/ximager/pkg/storage/filesystem" - _ "github.com/ximager/ximager/pkg/storage/s3" + _ "github.com/ximager/ximager/cmd/imports" ) var cfgFile string diff --git a/cmd/server.go b/cmd/server.go index 6502ed90..e1cbcf7e 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -60,7 +60,10 @@ var serverCmd = &cobra.Command{ return } - err = server.Serve() + err = server.Serve(server.ServerConfig{ + WithoutDistribution: withoutDistribution, + WithoutWorker: withoutWorker, + }) if err != nil { log.Error().Err(err).Msg("Serve with error") return @@ -68,7 +71,12 @@ var serverCmd = &cobra.Command{ }, } +var withoutDistribution bool +var withoutWorker bool + func init() { serverCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is /etc/ximager/ximager.yaml)") + serverCmd.PersistentFlags().BoolVar(&withoutDistribution, "without-distribution", false, "server without distribution service") + serverCmd.PersistentFlags().BoolVar(&withoutWorker, "without-worker", false, "server without worker service") rootCmd.AddCommand(serverCmd) } diff --git a/e2e/sc.js b/e2e/sc.js index 6d2b3728..4aaa6d92 100644 --- a/e2e/sc.js +++ b/e2e/sc.js @@ -11,7 +11,7 @@ const password = 'ximager'; const host = "http://127.0.0.1:3000"; export default function () { - let response = http.post(`${host}/user/login`, JSON.stringify({ username, password }), { + let response = http.post(`${host}/api/v1/users/login`, JSON.stringify({ username, password }), { headers: { 'Content-Type': 'application/json' }, }); check(response, { @@ -20,7 +20,7 @@ export default function () { const token = JSON.parse(response.body).token; - response = http.post(`${host}/namespaces/`, JSON.stringify({ "name": "test", "description": "test" }), { + response = http.post(`${host}/api/v1/namespaces/`, JSON.stringify({ "name": "test", "description": "test" }), { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, @@ -31,7 +31,7 @@ export default function () { }); const namespaceId = JSON.parse(response.body).id; - response = http.del(`${host}/namespaces/${namespaceId}`, null, { + response = http.del(`${host}/api/v1/namespaces/${namespaceId}`, null, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, @@ -41,9 +41,9 @@ export default function () { 'delete namespace status is 204': (r) => r.status === 204, }); - let page_size = 100; - let page_num = 1; - response = http.get(`${host}/namespaces/?page_size=${page_size}&page_num=${page_num}`, { + let limit = 100; + let last = 0; + response = http.get(`${host}/api/v1/namespaces/?limit=${limit}&last=${last}`, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, diff --git a/main.go b/main.go index d19bf66b..b66d9614 100644 --- a/main.go +++ b/main.go @@ -19,14 +19,13 @@ import "github.com/ximager/ximager/cmd" // @title XImager API // @version 1.0 -// @contact.name tosone -// @contact.url https://github.com/tosone -// @contact.email ximager@tosone.cn +// @contact.name XImager +// @contact.url https://github.com/ximager/ximager // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0 -// @BasePath / +// @BasePath /api/v1 // @securityDefinitions.basic BasicAuth // @in header diff --git a/pkg/cmds/distribution/distribution.go b/pkg/cmds/distribution/distribution.go new file mode 100644 index 00000000..d9c98bfe --- /dev/null +++ b/pkg/cmds/distribution/distribution.go @@ -0,0 +1,77 @@ +package distribution + +import ( + "context" + "net/http" + "os" + "os/signal" + "time" + + "github.com/labstack/echo-contrib/pprof" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "github.com/rs/zerolog/log" + "github.com/spf13/viper" + + "github.com/ximager/ximager/pkg/handlers" + "github.com/ximager/ximager/pkg/middlewares" + "github.com/ximager/ximager/pkg/storage" + "github.com/ximager/ximager/pkg/utils/serializer" +) + +func Serve() error { + e := echo.New() + e.HideBanner = true + e.HidePort = true + e.Use(middleware.GzipWithConfig(middleware.GzipConfig{Level: 5})) + e.Use(echo.MiddlewareFunc(func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + n := next(c) + log.Debug(). + Str("method", c.Request().Method). + Str("path", c.Request().URL.Path). + Str("query", c.Request().URL.RawQuery). + Interface("req-header", c.Request().Header). + Interface("resp-header", c.Response().Header()). + Int("status", c.Response().Status). + Msg("Request debugger") + return n + } + })) + + e.Use(middleware.CORS()) + e.Use(middlewares.Healthz()) + e.JSONSerializer = new(serializer.DefaultJSONSerializer) + + if viper.GetInt("log.level") < 1 { + pprof.Register(e) + } + + handlers.InitializeDistribution(e) + err := storage.Initialize() + if err != nil { + return err + } + + go func() { + log.Info().Str("addr", viper.GetString("http.server")).Msg("Server listening") + err = e.Start(viper.GetString("http.server")) + if err != http.ErrServerClosed { + log.Fatal().Err(err).Msg("Listening on interface failed") + } + }() + + // Wait for interrupt signal to gracefully shutdown the server with a timeout of 10 seconds. + // Use a buffered channel to avoid missing signals as recommended for signal.Notify + quit := make(chan os.Signal, 1) + signal.Notify(quit, os.Interrupt) + <-quit + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + err = e.Shutdown(ctx) + if err != nil { + log.Error().Err(err).Msg("Server shutdown failed") + } + + return nil +} diff --git a/pkg/cmds/server/server.go b/pkg/cmds/server/server.go index 3cffbb52..47d8ec4c 100644 --- a/pkg/cmds/server/server.go +++ b/pkg/cmds/server/server.go @@ -27,25 +27,21 @@ import ( "github.com/rs/zerolog/log" "github.com/spf13/viper" + "github.com/ximager/ximager/pkg/daemon" "github.com/ximager/ximager/pkg/handlers" "github.com/ximager/ximager/pkg/middlewares" "github.com/ximager/ximager/pkg/storage" "github.com/ximager/ximager/pkg/utils/serializer" - - _ "github.com/ximager/ximager/pkg/handlers/artifact" - _ "github.com/ximager/ximager/pkg/handlers/distribution/base" - _ "github.com/ximager/ximager/pkg/handlers/distribution/blob" - _ "github.com/ximager/ximager/pkg/handlers/distribution/manifest" - _ "github.com/ximager/ximager/pkg/handlers/distribution/upload" - _ "github.com/ximager/ximager/pkg/handlers/namespaces" - _ "github.com/ximager/ximager/pkg/handlers/repositories" - _ "github.com/ximager/ximager/pkg/handlers/tag" - _ "github.com/ximager/ximager/pkg/handlers/token" - _ "github.com/ximager/ximager/pkg/handlers/user" ) +// ServerConfig ... +type ServerConfig struct { + WithoutDistribution bool + WithoutWorker bool +} + // Serve starts the server -func Serve() error { +func Serve(config ServerConfig) error { e := echo.New() e.HideBanner = true e.HidePort = true @@ -64,7 +60,7 @@ func Serve() error { return n } })) - // e.Use(middleware.RequestID()) + e.Use(middleware.CORS()) e.Use(middlewares.Healthz()) e.JSONSerializer = new(serializer.DefaultJSONSerializer) @@ -73,6 +69,16 @@ func Serve() error { pprof.Register(e) } + if !config.WithoutDistribution { + handlers.InitializeDistribution(e) + } + if !config.WithoutWorker { + err := daemon.InitializeServer() + if err != nil { + return err + } + } + err := handlers.Initialize(e) if err != nil { return err diff --git a/pkg/consts/consts.go b/pkg/consts/consts.go index e8e44c48..76b15249 100644 --- a/pkg/consts/consts.go +++ b/pkg/consts/consts.go @@ -91,3 +91,8 @@ const ( // CacherManifest ... CacherManifest = "manifest" ) + +const ( + // APIV1 api v1 for api router + APIV1 = "/api/v1" +) diff --git a/pkg/handlers/apidocs/docs.go b/pkg/handlers/apidocs/docs.go index 0381b8b0..7ad3de10 100644 --- a/pkg/handlers/apidocs/docs.go +++ b/pkg/handlers/apidocs/docs.go @@ -11,9 +11,8 @@ const docTemplate = `{ "description": "{{escape .Description}}", "title": "{{.Title}}", "contact": { - "name": "tosone", - "url": "https://github.com/tosone", - "email": "ximager@tosone.cn" + "name": "XImager", + "url": "https://github.com/ximager/ximager" }, "license": { "name": "Apache 2.0", @@ -47,17 +46,17 @@ const docTemplate = `{ "minimum": 10, "type": "integer", "default": 10, - "description": "page size", - "name": "page_size", + "description": "limit", + "name": "limit", "in": "query", "required": true }, { - "minimum": 1, + "minimum": 0, "type": "integer", - "default": 1, - "description": "page number", - "name": "page_num", + "default": 0, + "description": "last", + "name": "last", "in": "query", "required": true }, @@ -252,17 +251,17 @@ const docTemplate = `{ "minimum": 10, "type": "integer", "default": 10, - "description": "page size", - "name": "page_size", + "description": "limit", + "name": "limit", "in": "query", "required": true }, { - "minimum": 1, + "minimum": 0, "type": "integer", - "default": 1, - "description": "page number", - "name": "page_num", + "default": 0, + "description": "last", + "name": "last", "in": "query", "required": true }, @@ -790,7 +789,7 @@ const docTemplate = `{ var SwaggerInfo = &swag.Spec{ Version: "1.0", Host: "", - BasePath: "/", + BasePath: "/api/v1", Schemes: []string{}, Title: "XImager API", Description: "", diff --git a/pkg/handlers/apidocs/swagger.json b/pkg/handlers/apidocs/swagger.json index 83e623bc..fe64b0e8 100644 --- a/pkg/handlers/apidocs/swagger.json +++ b/pkg/handlers/apidocs/swagger.json @@ -3,9 +3,8 @@ "info": { "title": "XImager API", "contact": { - "name": "tosone", - "url": "https://github.com/tosone", - "email": "ximager@tosone.cn" + "name": "XImager", + "url": "https://github.com/ximager/ximager" }, "license": { "name": "Apache 2.0", @@ -13,7 +12,7 @@ }, "version": "1.0" }, - "basePath": "/", + "basePath": "/api/v1", "paths": { "/namespaces/": { "get": { @@ -38,17 +37,17 @@ "minimum": 10, "type": "integer", "default": 10, - "description": "page size", - "name": "page_size", + "description": "limit", + "name": "limit", "in": "query", "required": true }, { - "minimum": 1, + "minimum": 0, "type": "integer", - "default": 1, - "description": "page number", - "name": "page_num", + "default": 0, + "description": "last", + "name": "last", "in": "query", "required": true }, @@ -243,17 +242,17 @@ "minimum": 10, "type": "integer", "default": 10, - "description": "page size", - "name": "page_size", + "description": "limit", + "name": "limit", "in": "query", "required": true }, { - "minimum": 1, + "minimum": 0, "type": "integer", - "default": 1, - "description": "page number", - "name": "page_num", + "default": 0, + "description": "last", + "name": "last", "in": "query", "required": true }, diff --git a/pkg/handlers/apidocs/swagger.yaml b/pkg/handlers/apidocs/swagger.yaml index 3ab639ca..d33142e2 100644 --- a/pkg/handlers/apidocs/swagger.yaml +++ b/pkg/handlers/apidocs/swagger.yaml @@ -1,4 +1,4 @@ -basePath: / +basePath: /api/v1 definitions: enums.Visibility: enum: @@ -180,9 +180,8 @@ definitions: type: object info: contact: - email: ximager@tosone.cn - name: tosone - url: https://github.com/tosone + name: XImager + url: https://github.com/ximager/ximager license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0 @@ -195,18 +194,18 @@ paths: - application/json parameters: - default: 10 - description: page size + description: limit in: query maximum: 100 minimum: 10 - name: page_size + name: limit required: true type: integer - - default: 1 - description: page number + - default: 0 + description: last in: query - minimum: 1 - name: page_num + minimum: 0 + name: last required: true type: integer - description: search namespace with name @@ -321,18 +320,18 @@ paths: - application/json parameters: - default: 10 - description: page size + description: limit in: query maximum: 100 minimum: 10 - name: page_size + name: limit required: true type: integer - - default: 1 - description: page number + - default: 0 + description: last in: query - minimum: 1 - name: page_num + minimum: 0 + name: last required: true type: integer - description: namespace diff --git a/pkg/handlers/artifact/artifact_delete.go b/pkg/handlers/artifacts/artifacts_delete.go similarity index 100% rename from pkg/handlers/artifact/artifact_delete.go rename to pkg/handlers/artifacts/artifacts_delete.go diff --git a/pkg/handlers/artifact/artifact_delete_test.go b/pkg/handlers/artifacts/artifacts_delete_test.go similarity index 100% rename from pkg/handlers/artifact/artifact_delete_test.go rename to pkg/handlers/artifacts/artifacts_delete_test.go diff --git a/pkg/handlers/artifact/artifact_get.go b/pkg/handlers/artifacts/artifacts_get.go similarity index 100% rename from pkg/handlers/artifact/artifact_get.go rename to pkg/handlers/artifacts/artifacts_get.go diff --git a/pkg/handlers/artifact/artifact_get_test.go b/pkg/handlers/artifacts/artifacts_get_test.go similarity index 100% rename from pkg/handlers/artifact/artifact_get_test.go rename to pkg/handlers/artifacts/artifacts_get_test.go diff --git a/pkg/handlers/artifact/artifact_list.go b/pkg/handlers/artifacts/artifacts_list.go similarity index 100% rename from pkg/handlers/artifact/artifact_list.go rename to pkg/handlers/artifacts/artifacts_list.go diff --git a/pkg/handlers/artifact/artifact_list_test.go b/pkg/handlers/artifacts/artifacts_list_test.go similarity index 100% rename from pkg/handlers/artifact/artifact_list_test.go rename to pkg/handlers/artifacts/artifacts_list_test.go diff --git a/pkg/handlers/artifact/handler.go b/pkg/handlers/artifacts/handler.go similarity index 94% rename from pkg/handlers/artifact/handler.go rename to pkg/handlers/artifacts/handler.go index a08a66b5..6a6274e8 100644 --- a/pkg/handlers/artifact/handler.go +++ b/pkg/handlers/artifacts/handler.go @@ -20,6 +20,7 @@ import ( "github.com/labstack/echo/v4" + "github.com/ximager/ximager/pkg/consts" "github.com/ximager/ximager/pkg/dal/dao" rhandlers "github.com/ximager/ximager/pkg/handlers" "github.com/ximager/ximager/pkg/middlewares" @@ -85,7 +86,7 @@ type factory struct{} // Initialize initializes the namespace handlers func (f factory) Initialize(e *echo.Echo) error { - artifactGroup := e.Group("/namespace/:namespace/artifact", middlewares.AuthWithConfig(middlewares.AuthConfig{})) + artifactGroup := e.Group(consts.APIV1+"/namespace/:namespace/artifact", middlewares.AuthWithConfig(middlewares.AuthConfig{})) artifactHandler := handlerNew() artifactGroup.GET("/", artifactHandler.ListArtifact) artifactGroup.GET("/:id", artifactHandler.GetArtifact) diff --git a/pkg/handlers/artifact/handler_test.go b/pkg/handlers/artifacts/handler_test.go similarity index 100% rename from pkg/handlers/artifact/handler_test.go rename to pkg/handlers/artifacts/handler_test.go diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index fe9aec0f..900a70f2 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -27,14 +27,17 @@ import ( _ "github.com/ximager/ximager/pkg/handlers/apidocs" ) +// InitializeDistribution ... +func InitializeDistribution(e *echo.Echo) { + e.Any("/v2/*", distribution.All, middlewares.AuthWithConfig(middlewares.AuthConfig{DS: true})) +} + // Initialize ... func Initialize(e *echo.Echo) error { e.Any("/swagger/*", echoSwagger.WrapHandler) validators.Initialize(e) - e.Any("/v2/*", distribution.All, middlewares.AuthWithConfig(middlewares.AuthConfig{DS: true})) - for name, factory := range routerFactories { if err := factory.Initialize(e); err != nil { return fmt.Errorf("failed to initialize router factory %q: %v", name, err) diff --git a/pkg/handlers/namespaces/handler.go b/pkg/handlers/namespaces/handler.go index 5d6e76f0..9230c7d5 100644 --- a/pkg/handlers/namespaces/handler.go +++ b/pkg/handlers/namespaces/handler.go @@ -20,6 +20,7 @@ import ( "github.com/labstack/echo/v4" + "github.com/ximager/ximager/pkg/consts" "github.com/ximager/ximager/pkg/dal/dao" rhandlers "github.com/ximager/ximager/pkg/handlers" "github.com/ximager/ximager/pkg/middlewares" @@ -75,7 +76,7 @@ type factory struct{} // Initialize initializes the namespace handlers func (f factory) Initialize(e *echo.Echo) error { - namespaceGroup := e.Group("/namespaces", middlewares.AuthWithConfig(middlewares.AuthConfig{})) + namespaceGroup := e.Group(consts.APIV1+"/namespaces", middlewares.AuthWithConfig(middlewares.AuthConfig{})) namespaceHandler := handlerNew() namespaceGroup.POST("/", namespaceHandler.PostNamespace) namespaceGroup.PUT("/:id", namespaceHandler.PutNamespace) diff --git a/pkg/handlers/namespaces/namespaces_list.go b/pkg/handlers/namespaces/namespaces_list.go index cd7936f4..4425c280 100644 --- a/pkg/handlers/namespaces/namespaces_list.go +++ b/pkg/handlers/namespaces/namespaces_list.go @@ -34,8 +34,8 @@ import ( // @Accept json // @Produce json // @Router /namespaces/ [get] -// @Param page_size query int64 true "page size" minimum(10) maximum(100) default(10) -// @Param page_num query int64 true "page number" minimum(1) default(1) +// @Param limit query int64 true "limit" minimum(10) maximum(100) default(10) +// @Param last query int64 true "last" minimum(0) default(0) // @Param name query string false "search namespace with name" // @Success 200 {object} types.CommonList{items=[]types.NamespaceItem} func (h *handlers) ListNamespace(c echo.Context) error { diff --git a/pkg/handlers/repositories/handler.go b/pkg/handlers/repositories/handler.go index 9d7e60ef..33f4842e 100644 --- a/pkg/handlers/repositories/handler.go +++ b/pkg/handlers/repositories/handler.go @@ -20,6 +20,7 @@ import ( "github.com/labstack/echo/v4" + "github.com/ximager/ximager/pkg/consts" "github.com/ximager/ximager/pkg/dal/dao" rhandlers "github.com/ximager/ximager/pkg/handlers" "github.com/ximager/ximager/pkg/middlewares" @@ -83,7 +84,7 @@ type factory struct{} // Initialize initializes the namespace handlers func (f factory) Initialize(e *echo.Echo) error { - repositoryGroup := e.Group("/namespaces/:namespace/repositories", middlewares.AuthWithConfig(middlewares.AuthConfig{})) + repositoryGroup := e.Group(consts.APIV1+"/namespaces/:namespace/repositories", middlewares.AuthWithConfig(middlewares.AuthConfig{})) repositoryHandler := handlerNew() repositoryGroup.GET("/", repositoryHandler.ListRepository) repositoryGroup.GET("/:id", repositoryHandler.GetRepository) diff --git a/pkg/handlers/repositories/repositories_list.go b/pkg/handlers/repositories/repositories_list.go index 8babcc03..4522face 100644 --- a/pkg/handlers/repositories/repositories_list.go +++ b/pkg/handlers/repositories/repositories_list.go @@ -33,8 +33,8 @@ import ( // @Accept json // @Produce json // @Router /namespaces/{namespace}/repositories/ [get] -// @Param page_size query int64 true "page size" minimum(10) maximum(100) default(10) -// @Param page_num query int64 true "page number" minimum(1) default(1) +// @Param limit query int64 true "limit" minimum(10) maximum(100) default(10) +// @Param last query int64 true "last" minimum(0) default(0) // @Param namespace path string true "namespace" // @Success 200 {object} types.CommonList{items=[]types.RepositoryItem} // @Failure 404 {object} xerrors.ErrCode diff --git a/pkg/handlers/tag/handler.go b/pkg/handlers/tags/handler.go similarity index 93% rename from pkg/handlers/tag/handler.go rename to pkg/handlers/tags/handler.go index 39cb0828..20ca1bc8 100644 --- a/pkg/handlers/tag/handler.go +++ b/pkg/handlers/tags/handler.go @@ -20,8 +20,10 @@ import ( "github.com/labstack/echo/v4" + "github.com/ximager/ximager/pkg/consts" "github.com/ximager/ximager/pkg/dal/dao" rhandlers "github.com/ximager/ximager/pkg/handlers" + "github.com/ximager/ximager/pkg/middlewares" "github.com/ximager/ximager/pkg/utils" ) @@ -83,8 +85,8 @@ func handlerNew(injects ...inject) Handlers { type factory struct{} func (f factory) Initialize(e *echo.Echo) error { - tagGroup := e.Group("/namespace/:namespace/tag") tagHandler := handlerNew() + tagGroup := e.Group(consts.APIV1+"/namespace/:namespace/tag", middlewares.AuthWithConfig(middlewares.AuthConfig{})) tagGroup.GET("/", tagHandler.ListTag) tagGroup.GET("/:id", tagHandler.GetTag) tagGroup.DELETE("/:id", tagHandler.DeleteTag) diff --git a/pkg/handlers/tag/handler_test.go b/pkg/handlers/tags/handler_test.go similarity index 100% rename from pkg/handlers/tag/handler_test.go rename to pkg/handlers/tags/handler_test.go diff --git a/pkg/handlers/tag/tag_delete.go b/pkg/handlers/tags/tags_delete.go similarity index 100% rename from pkg/handlers/tag/tag_delete.go rename to pkg/handlers/tags/tags_delete.go diff --git a/pkg/handlers/tag/tag_delete_test.go b/pkg/handlers/tags/tags_delete_test.go similarity index 100% rename from pkg/handlers/tag/tag_delete_test.go rename to pkg/handlers/tags/tags_delete_test.go diff --git a/pkg/handlers/tag/tag_get.go b/pkg/handlers/tags/tags_get.go similarity index 100% rename from pkg/handlers/tag/tag_get.go rename to pkg/handlers/tags/tags_get.go diff --git a/pkg/handlers/tag/tag_get_test.go b/pkg/handlers/tags/tags_get_test.go similarity index 100% rename from pkg/handlers/tag/tag_get_test.go rename to pkg/handlers/tags/tags_get_test.go diff --git a/pkg/handlers/tag/tag_list.go b/pkg/handlers/tags/tags_list.go similarity index 100% rename from pkg/handlers/tag/tag_list.go rename to pkg/handlers/tags/tags_list.go diff --git a/pkg/handlers/tag/tag_list_test.go b/pkg/handlers/tags/tags_list_test.go similarity index 100% rename from pkg/handlers/tag/tag_list_test.go rename to pkg/handlers/tags/tags_list_test.go diff --git a/pkg/handlers/token/handler.go b/pkg/handlers/tokens/handler.go similarity index 95% rename from pkg/handlers/token/handler.go rename to pkg/handlers/tokens/handler.go index c1b24cfb..2f710701 100644 --- a/pkg/handlers/token/handler.go +++ b/pkg/handlers/tokens/handler.go @@ -21,6 +21,7 @@ import ( "github.com/labstack/echo/v4" "github.com/spf13/viper" + "github.com/ximager/ximager/pkg/consts" "github.com/ximager/ximager/pkg/dal/dao" rhandlers "github.com/ximager/ximager/pkg/handlers" "github.com/ximager/ximager/pkg/utils" @@ -82,7 +83,8 @@ func (f factory) Initialize(e *echo.Echo) error { if err != nil { return err } - e.GET("/token", userHandler.Token) + tokenGroup := e.Group(consts.APIV1) + tokenGroup.GET("/tokens", userHandler.Token) return nil } diff --git a/pkg/handlers/token/handler_test.go b/pkg/handlers/tokens/handler_test.go similarity index 100% rename from pkg/handlers/token/handler_test.go rename to pkg/handlers/tokens/handler_test.go diff --git a/pkg/handlers/token/token.go b/pkg/handlers/tokens/tokens.go similarity index 100% rename from pkg/handlers/token/token.go rename to pkg/handlers/tokens/tokens.go diff --git a/pkg/handlers/token/token_test.go b/pkg/handlers/tokens/tokens_test.go similarity index 100% rename from pkg/handlers/token/token_test.go rename to pkg/handlers/tokens/tokens_test.go diff --git a/pkg/handlers/user/handler.go b/pkg/handlers/users/handler.go similarity index 97% rename from pkg/handlers/user/handler.go rename to pkg/handlers/users/handler.go index 2d06412e..50dc804a 100644 --- a/pkg/handlers/user/handler.go +++ b/pkg/handlers/users/handler.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/viper" "golang.org/x/exp/slices" + "github.com/ximager/ximager/pkg/consts" "github.com/ximager/ximager/pkg/dal/dao" rhandlers "github.com/ximager/ximager/pkg/handlers" "github.com/ximager/ximager/pkg/middlewares" @@ -88,7 +89,7 @@ type factory struct{} var skipAuths = []string{"post:/user/login", "get:/user/token", "get:/user/signup", "get:/user/create"} func (f factory) Initialize(e *echo.Echo) error { - userGroup := e.Group("/user") + userGroup := e.Group(consts.APIV1 + "/users") userHandler, err := handlerNew() if err != nil { return err diff --git a/pkg/handlers/user/handler_test.go b/pkg/handlers/users/handler_test.go similarity index 100% rename from pkg/handlers/user/handler_test.go rename to pkg/handlers/users/handler_test.go diff --git a/pkg/handlers/user/user_login.go b/pkg/handlers/users/users_login.go similarity index 100% rename from pkg/handlers/user/user_login.go rename to pkg/handlers/users/users_login.go diff --git a/pkg/handlers/user/user_login_test.go b/pkg/handlers/users/users_login_test.go similarity index 100% rename from pkg/handlers/user/user_login_test.go rename to pkg/handlers/users/users_login_test.go diff --git a/pkg/handlers/user/user_logout.go b/pkg/handlers/users/users_logout.go similarity index 100% rename from pkg/handlers/user/user_logout.go rename to pkg/handlers/users/users_logout.go diff --git a/pkg/handlers/user/user_logout_test.go b/pkg/handlers/users/users_logout_test.go similarity index 100% rename from pkg/handlers/user/user_logout_test.go rename to pkg/handlers/users/users_logout_test.go diff --git a/pkg/handlers/user/user_signup.go b/pkg/handlers/users/users_signup.go similarity index 100% rename from pkg/handlers/user/user_signup.go rename to pkg/handlers/users/users_signup.go diff --git a/pkg/handlers/user/user_signup_test.go b/pkg/handlers/users/users_signup_test.go similarity index 100% rename from pkg/handlers/user/user_signup_test.go rename to pkg/handlers/users/users_signup_test.go diff --git a/pkg/middlewares/auth.go b/pkg/middlewares/auth.go index 335fd258..5e66e46c 100644 --- a/pkg/middlewares/auth.go +++ b/pkg/middlewares/auth.go @@ -147,7 +147,7 @@ func AuthWithConfig(config AuthConfig) echo.MiddlewareFunc { } func genWwwAuthenticate(host, schema string) string { - realm := fmt.Sprintf("%s://%s/token", schema, host) + realm := fmt.Sprintf("%s://%s%s/tokens", schema, host, consts.APIV1) rRealm := viper.GetString("auth.token.realm") if rRealm != "" { realm = rRealm