From 9ff7d46e8fa2c226c56aa39b0a890caaa03ac7a0 Mon Sep 17 00:00:00 2001 From: DQ Date: Sat, 28 Mar 2020 01:03:35 +0800 Subject: [PATCH 1/3] Rever chart version to original Because chart version should consistent with previous version Signed-off-by: DQ --- src/chartserver/handler_manipulation.go | 3 +-- src/chartserver/handler_proxy_traffic_test.go | 3 +-- src/chartserver/reverse_proxy.go | 23 +++++++---------- src/chartserver/reverse_proxy_test.go | 9 +++---- src/core/api/chart_repository.go | 25 ++++++++----------- src/core/api/chart_repository_test.go | 16 ++++++------ src/core/api/harborapi_test.go | 21 ++++++++-------- src/pkg/clients/core/chart.go | 7 +++--- .../adapter/harbor/chart_registry.go | 14 +++++------ .../adapter/harbor/chart_registry_test.go | 12 ++++----- .../middleware/quota/upload_chart_version.go | 3 +-- src/server/middleware/quota/util_test.go | 1 + src/server/middleware/security/oidc_cli.go | 1 + src/server/middleware/util/util.go | 5 ++-- src/server/route.go | 9 +++++++ src/server/v2.0/route/legacy.go | 12 --------- 16 files changed, 74 insertions(+), 90 deletions(-) diff --git a/src/chartserver/handler_manipulation.go b/src/chartserver/handler_manipulation.go index 3e4bda593..42e714916 100644 --- a/src/chartserver/handler_manipulation.go +++ b/src/chartserver/handler_manipulation.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/ghodss/yaml" - "github.com/goharbor/harbor/src/common/api" commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/replication" @@ -70,7 +69,7 @@ func (c *Controller) DeleteChartVersion(namespace, chartName, version string) er return errors.New("invalid chart for deleting") } - url := fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s/%s", api.APIVersion, namespace, chartName, version) + url := fmt.Sprintf("/api/chartrepo/%s/charts/%s/%s", namespace, chartName, version) req, _ := http.NewRequest(http.MethodDelete, url, nil) w := httptest.NewRecorder() diff --git a/src/chartserver/handler_proxy_traffic_test.go b/src/chartserver/handler_proxy_traffic_test.go index 69a29b1f4..5d54aefc3 100644 --- a/src/chartserver/handler_proxy_traffic_test.go +++ b/src/chartserver/handler_proxy_traffic_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/ghodss/yaml" - "github.com/goharbor/harbor/src/common/api" htesting "github.com/goharbor/harbor/src/testing" helm_repo "k8s.io/helm/pkg/repo" ) @@ -37,7 +36,7 @@ func TestStartMockServers(t *testing.T) { // Test /health func TestGetHealthOfBaseHandler(t *testing.T) { - content, err := httpClient.GetContent(fmt.Sprintf("%s/api/%s/chartrepo/health", frontServer.URL, api.APIVersion)) + content, err := httpClient.GetContent(fmt.Sprintf("%s/api/chartrepo/health", frontServer.URL)) if err != nil { t.Fatal(err) } diff --git a/src/chartserver/reverse_proxy.go b/src/chartserver/reverse_proxy.go index 189b47c41..5aaf27502 100644 --- a/src/chartserver/reverse_proxy.go +++ b/src/chartserver/reverse_proxy.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/goharbor/harbor/src/controller/event/metadata" "io/ioutil" "log" "net/http" @@ -16,9 +15,9 @@ import ( "time" "github.com/goharbor/harbor/src/common" - "github.com/goharbor/harbor/src/common/api" commonhttp "github.com/goharbor/harbor/src/common/http" hlog "github.com/goharbor/harbor/src/common/utils/log" + "github.com/goharbor/harbor/src/controller/event/metadata" n_event "github.com/goharbor/harbor/src/pkg/notifier/event" "github.com/goharbor/harbor/src/replication" rep_event "github.com/goharbor/harbor/src/replication/event" @@ -27,15 +26,11 @@ import ( const ( agentHarbor = "HARBOR" contentLengthHeader = "Content-Length" -) -var ( - defaultRepo = "library" - - chartRepoAPIPrefix = fmt.Sprintf("/api/%s/chartrepo", api.APIVersion) - rootUploadingEndpoint = fmt.Sprintf("/api/%s/chartrepo/charts", api.APIVersion) - chartRepoHealthEndpoint = fmt.Sprintf("/api/%s/chartrepo/health", api.APIVersion) - chartRepoPrefix = "/chartrepo" + defaultRepo = "library" + rootUploadingEndpoint = "/api/chartrepo/charts" + rootIndexEndpoint = "/chartrepo/index.yaml" + chartRepoHealthEndpoint = "/api/chartrepo/health" ) // ProxyEngine is used to proxy the related traffics @@ -229,19 +224,19 @@ func rewriteURLPath(req *http.Request) { // Root uploading endpoint if incomingURLPath == rootUploadingEndpoint { - req.URL.Path = strings.Replace(incomingURLPath, fmt.Sprintf("%s/chartrepo", api.APIVersion), defaultRepo, 1) + req.URL.Path = strings.Replace(incomingURLPath, "chartrepo", defaultRepo, 1) return } // Repository endpoints - if strings.HasPrefix(incomingURLPath, chartRepoPrefix) { + if strings.HasPrefix(incomingURLPath, "/chartrepo") { req.URL.Path = strings.TrimPrefix(incomingURLPath, "/chartrepo") return } // API endpoints - if strings.HasPrefix(incomingURLPath, chartRepoAPIPrefix) { - req.URL.Path = strings.Replace(incomingURLPath, fmt.Sprintf("/%s/chartrepo", api.APIVersion), "", 1) + if strings.HasPrefix(incomingURLPath, "/api/chartrepo") { + req.URL.Path = strings.Replace(incomingURLPath, "/chartrepo", "", 1) return } } diff --git a/src/chartserver/reverse_proxy_test.go b/src/chartserver/reverse_proxy_test.go index fef27f749..44cfa0964 100644 --- a/src/chartserver/reverse_proxy_test.go +++ b/src/chartserver/reverse_proxy_test.go @@ -1,16 +1,13 @@ package chartserver import ( - "fmt" "net/http" "testing" - - "github.com/goharbor/harbor/src/common/api" ) // Test the URL rewrite function func TestURLRewrite(t *testing.T) { - req, err := createRequest(http.MethodGet, fmt.Sprintf("/api/%s/chartrepo/health", api.APIVersion)) + req, err := createRequest(http.MethodGet, "/api/chartrepo/health") if err != nil { t.Fatal(err) } @@ -19,7 +16,7 @@ func TestURLRewrite(t *testing.T) { t.Fatalf("Expect url format %s but got %s", "/health", req.URL.Path) } - req, err = createRequest(http.MethodGet, fmt.Sprintf("/api/%s/chartrepo/library/charts", api.APIVersion)) + req, err = createRequest(http.MethodGet, "/api/chartrepo/library/charts") if err != nil { t.Fatal(err) } @@ -28,7 +25,7 @@ func TestURLRewrite(t *testing.T) { t.Fatalf("Expect url format %s but got %s", "/api/library/charts", req.URL.Path) } - req, err = createRequest(http.MethodPost, fmt.Sprintf("/api/%s/chartrepo/charts", api.APIVersion)) + req, err = createRequest(http.MethodPost, "/api/chartrepo/charts") if err != nil { t.Fatal(err) } diff --git a/src/core/api/chart_repository.go b/src/core/api/chart_repository.go index 0f19e7d3f..fb6467d19 100755 --- a/src/core/api/chart_repository.go +++ b/src/core/api/chart_repository.go @@ -5,7 +5,6 @@ import ( "context" "errors" "fmt" - "github.com/goharbor/harbor/src/controller/event/metadata" "io" "io/ioutil" "mime/multipart" @@ -17,9 +16,10 @@ import ( "strings" "time" + "github.com/goharbor/harbor/src/controller/event/metadata" + "github.com/goharbor/harbor/src/chartserver" "github.com/goharbor/harbor/src/common" - "github.com/goharbor/harbor/src/common/api" "github.com/goharbor/harbor/src/common/rbac" hlog "github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/core/config" @@ -33,9 +33,13 @@ import ( ) const ( - namespaceParam = ":repo" - nameParam = ":name" - filenameParam = ":filename" + namespaceParam = ":repo" + nameParam = ":name" + filenameParam = ":filename" + defaultRepo = "library" + rootUploadingEndpoint = "/api/chartrepo/charts" + rootIndexEndpoint = "/chartrepo/index.yaml" + chartRepoHealthEndpoint = "/api/chartrepo/health" accessLevelPublic = iota accessLevelRead @@ -51,13 +55,6 @@ const ( chartPackageFileExtension = "tgz" ) -var ( - defaultRepo = "library" - rootUploadingEndpoint = fmt.Sprintf("/api/%s/chartrepo/charts", api.APIVersion) - chartRepoHealthEndpoint = fmt.Sprintf("/api/%s/chartrepo/health", api.APIVersion) - rootIndexEndpoint = "/chartrepo/index.yaml" -) - // chartController is a singleton instance var chartController *chartserver.Controller @@ -116,7 +113,7 @@ func (cra *ChartRepositoryAPI) requireAccess(action rbac.Action, subresource ... return cra.RequireProjectAccess(cra.namespace, action, subresource...) } -// GetHealthStatus handles GET /chartrepo/health +// GetHealthStatus handles GET /api/chartrepo/health func (cra *ChartRepositoryAPI) GetHealthStatus() { // Check access if !cra.SecurityCtx.IsAuthenticated() { @@ -606,7 +603,7 @@ func initializeChartController() (*chartserver.Controller, error) { return nil, errors.New("Endpoint URL of chart storage server is malformed") } - chartVersionURL := fmt.Sprintf(`^/api/%s/chartrepo/(?P[^?#]+)/charts/(?P[^?#]+)/(?P[^?#]+)/?$`, api.APIVersion) + chartVersionURL := fmt.Sprintf(`^/api/chartrepo/(?P[^?#]+)/charts/(?P[^?#]+)/(?P[^?#]+)/?$`) skipper := middleware.NegativeSkipper(middleware.MethodAndPathSkipper(http.MethodDelete, regexp.MustCompile(chartVersionURL))) controller, err := chartserver.NewController(url, orm.Middleware(), quota.UploadChartVersionMiddleware(), quota.RefreshForProjectMiddleware(skipper)) diff --git a/src/core/api/chart_repository_test.go b/src/core/api/chart_repository_test.go index 0af990b57..5b1182da0 100644 --- a/src/core/api/chart_repository_test.go +++ b/src/core/api/chart_repository_test.go @@ -2,13 +2,11 @@ package api import ( "errors" - "fmt" "net/http" "net/http/httptest" "testing" "github.com/goharbor/harbor/src/chartserver" - "github.com/goharbor/harbor/src/common/api" "github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/core/promgr/metamgr" ) @@ -19,7 +17,7 @@ var ( ) func TestIsMultipartFormData(t *testing.T) { - req, err := createRequest(http.MethodPost, fmt.Sprintf("/api/%s/chartrepo/charts", api.APIVersion)) + req, err := createRequest(http.MethodPost, "/api/chartrepo/charts") if err != nil { t.Fatal(err) } @@ -57,7 +55,7 @@ func TestPrepareEnv(t *testing.T) { func TestGetHealthStatus(t *testing.T) { status := make(map[string]interface{}) err := handleAndParse(&testingRequest{ - url: fmt.Sprintf("/api/%s/chartrepo/health", api.APIVersion), + url: "/api/chartrepo/health", method: http.MethodGet, credential: sysAdmin, }, &status) @@ -111,7 +109,7 @@ func TestDownloadChart(t *testing.T) { func TesListCharts(t *testing.T) { charts := make([]*chartserver.ChartInfo, 0) err := handleAndParse(&testingRequest{ - url: fmt.Sprintf("/api/%s/chartrepo/library/charts", api.APIVersion), + url: "/api/chartrepo/library/charts", method: http.MethodGet, credential: projAdmin, }, &charts) @@ -129,7 +127,7 @@ func TesListCharts(t *testing.T) { func TestListChartVersions(t *testing.T) { chartVersions := make(chartserver.ChartVersions, 0) err := handleAndParse(&testingRequest{ - url: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor", api.APIVersion), + url: "/api/chartrepo/library/charts/harbor", method: http.MethodGet, credential: projAdmin, }, &chartVersions) @@ -147,7 +145,7 @@ func TestListChartVersions(t *testing.T) { func TestGetChartVersion(t *testing.T) { chartV := &chartserver.ChartVersionDetails{} err := handleAndParse(&testingRequest{ - url: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/0.2.0", api.APIVersion), + url: "/api/chartrepo/library/charts/harbor/0.2.0", method: http.MethodGet, credential: projAdmin, }, chartV) @@ -169,7 +167,7 @@ func TestGetChartVersion(t *testing.T) { func TestDeleteChartVersion(t *testing.T) { runCodeCheckingCases(t, &codeCheckingCase{ request: &testingRequest{ - url: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/0.2.1", api.APIVersion), + url: "/api/chartrepo/library/charts/harbor/0.2.1", method: http.MethodDelete, credential: projAdmin, }, @@ -181,7 +179,7 @@ func TestDeleteChartVersion(t *testing.T) { func TestDeleteChart(t *testing.T) { runCodeCheckingCases(t, &codeCheckingCase{ request: &testingRequest{ - url: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor", api.APIVersion), + url: "/api/chartrepo/library/charts/harbor", method: http.MethodDelete, credential: projAdmin, }, diff --git a/src/core/api/harborapi_test.go b/src/core/api/harborapi_test.go index 3938a962e..314a1df11 100644 --- a/src/core/api/harborapi_test.go +++ b/src/core/api/harborapi_test.go @@ -19,7 +19,6 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/goharbor/harbor/src/server/middleware/security" "io/ioutil" "log" "net/http" @@ -29,6 +28,8 @@ import ( "strconv" "strings" + "github.com/goharbor/harbor/src/server/middleware/security" + "github.com/astaxie/beego" "github.com/dghubble/sling" "github.com/goharbor/harbor/src/common/api" @@ -166,15 +167,15 @@ func init() { beego.Router("/api/projects/:pid([0-9]+)/immutabletagrules/:id([0-9]+)", &ImmutableTagRuleAPI{}) // Charts are controlled under projects chartRepositoryAPIType := &ChartRepositoryAPI{} - beego.Router("/api/"+api.APIVersion+"/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus") - beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts", chartRepositoryAPIType, "get:ListCharts") - beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "get:ListChartVersions") - beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "delete:DeleteChart") - beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "get:GetChartVersion") - beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "delete:DeleteChartVersion") - beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts", chartRepositoryAPIType, "post:UploadChartVersion") - beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/prov", chartRepositoryAPIType, "post:UploadChartProvFile") - beego.Router("/api/"+api.APIVersion+"/chartrepo/charts", chartRepositoryAPIType, "post:UploadChartVersion") + beego.Router("/api/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus") + beego.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "get:ListCharts") + beego.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "get:ListChartVersions") + beego.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "delete:DeleteChart") + beego.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "get:GetChartVersion") + beego.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "delete:DeleteChartVersion") + beego.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "post:UploadChartVersion") + beego.Router("/api/chartrepo/:repo/prov", chartRepositoryAPIType, "post:UploadChartProvFile") + beego.Router("/api/chartrepo/charts", chartRepositoryAPIType, "post:UploadChartVersion") // Repository services beego.Router("/chartrepo/:repo/index.yaml", chartRepositoryAPIType, "get:GetIndexByRepo") diff --git a/src/pkg/clients/core/chart.go b/src/pkg/clients/core/chart.go index ea7c50548..75d8c3983 100644 --- a/src/pkg/clients/core/chart.go +++ b/src/pkg/clients/core/chart.go @@ -18,11 +18,10 @@ import ( "fmt" "github.com/goharbor/harbor/src/chartserver" - "github.com/goharbor/harbor/src/common/api" ) func (c *client) ListAllCharts(project, repository string) ([]*chartserver.ChartVersion, error) { - url := c.buildURL(fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s", api.APIVersion, project, repository)) + url := c.buildURL(fmt.Sprintf("/api/chartrepo/%s/charts/%s", project, repository)) var charts []*chartserver.ChartVersion if err := c.httpclient.Get(url, &charts); err != nil { return nil, err @@ -31,11 +30,11 @@ func (c *client) ListAllCharts(project, repository string) ([]*chartserver.Chart } func (c *client) DeleteChart(project, repository, version string) error { - url := c.buildURL(fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s/%s", api.APIVersion, project, repository, version)) + url := c.buildURL(fmt.Sprintf("/api/chartrepo/%s/charts/%s/%s", project, repository, version)) return c.httpclient.Delete(url) } func (c *client) DeleteChartRepository(project, repository string) error { - url := c.buildURL(fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s", api.APIVersion, project, repository)) + url := c.buildURL(fmt.Sprintf("/api/chartrepo/%s/charts/%s", project, repository)) return c.httpclient.Delete(url) } diff --git a/src/replication/adapter/harbor/chart_registry.go b/src/replication/adapter/harbor/chart_registry.go index 4d71aea74..ee0a8ccb1 100644 --- a/src/replication/adapter/harbor/chart_registry.go +++ b/src/replication/adapter/harbor/chart_registry.go @@ -17,14 +17,14 @@ package harbor import ( "bytes" "fmt" - "github.com/goharbor/harbor/src/replication/filter" "io" "io/ioutil" "mime/multipart" "net/http" "strings" - "github.com/goharbor/harbor/src/common/api" + "github.com/goharbor/harbor/src/replication/filter" + common_http "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/replication/model" ) @@ -54,7 +54,7 @@ func (a *adapter) FetchCharts(filters []*model.Filter) ([]*model.Resource, error resources := []*model.Resource{} for _, project := range projects { - url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts", a.getURL(), api.APIVersion, project.Name) + url := fmt.Sprintf("%s/api/chartrepo/%s/charts", a.getURL(), project.Name) repositories := []*model.Repository{} if err := a.client.Get(url, &repositories); err != nil { return nil, err @@ -72,7 +72,7 @@ func (a *adapter) FetchCharts(filters []*model.Filter) ([]*model.Resource, error for _, repository := range repositories { name := strings.SplitN(repository.Name, "/", 2)[1] - url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts/%s", a.getURL(), api.APIVersion, project.Name, name) + url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s", a.getURL(), project.Name, name) versions := []*chartVersion{} if err := a.client.Get(url, &versions); err != nil { return nil, err @@ -133,7 +133,7 @@ func (a *adapter) getChartInfo(name, version string) (*chartVersionDetail, error if err != nil { return nil, err } - url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts/%s/%s", a.url, api.APIVersion, project, name, version) + url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s/%s", a.url, project, name, version) info := &chartVersionDetail{} if err = a.client.Get(url, info); err != nil { return nil, err @@ -193,7 +193,7 @@ func (a *adapter) UploadChart(name, version string, chart io.Reader) error { } w.Close() - url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts", a.url, api.APIVersion, project) + url := fmt.Sprintf("%s/api/chartrepo/%s/charts", a.url, project) req, err := http.NewRequest(http.MethodPost, url, buf) if err != nil { @@ -224,7 +224,7 @@ func (a *adapter) DeleteChart(name, version string) error { if err != nil { return err } - url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts/%s/%s", a.url, api.APIVersion, project, name, version) + url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s/%s", a.url, project, name, version) return a.client.Delete(url) } diff --git a/src/replication/adapter/harbor/chart_registry_test.go b/src/replication/adapter/harbor/chart_registry_test.go index e3c859f48..88ae6edc2 100644 --- a/src/replication/adapter/harbor/chart_registry_test.go +++ b/src/replication/adapter/harbor/chart_registry_test.go @@ -42,7 +42,7 @@ func TestFetchCharts(t *testing.T) { }, { Method: http.MethodGet, - Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor", api.APIVersion), + Pattern: "/api/chartrepo/library/charts/harbor", Handler: func(w http.ResponseWriter, r *http.Request) { data := `[{ "name": "harbor", @@ -56,7 +56,7 @@ func TestFetchCharts(t *testing.T) { }, { Method: http.MethodGet, - Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts", api.APIVersion), + Pattern: "/api/chartrepo/library/charts", Handler: func(w http.ResponseWriter, r *http.Request) { data := `[{ "name": "harbor" @@ -102,7 +102,7 @@ func TestFetchCharts(t *testing.T) { func TestChartExist(t *testing.T) { server := test.NewServer(&test.RequestHandlerMapping{ Method: http.MethodGet, - Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/1.0", api.APIVersion), + Pattern: "/api/chartrepo/library/charts/harbor/1.0", Handler: func(w http.ResponseWriter, r *http.Request) { data := `{ "metadata": { @@ -127,7 +127,7 @@ func TestDownloadChart(t *testing.T) { server := test.NewServer([]*test.RequestHandlerMapping{ { Method: http.MethodGet, - Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/1.0", api.APIVersion), + Pattern: "/api/chartrepo/library/charts/harbor/1.0", Handler: func(w http.ResponseWriter, r *http.Request) { data := `{ "metadata": { @@ -158,7 +158,7 @@ func TestDownloadChart(t *testing.T) { func TestUploadChart(t *testing.T) { server := test.NewServer(&test.RequestHandlerMapping{ Method: http.MethodPost, - Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts", api.APIVersion), + Pattern: "/api/chartrepo/library/charts", Handler: func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }, @@ -176,7 +176,7 @@ func TestUploadChart(t *testing.T) { func TestDeleteChart(t *testing.T) { server := test.NewServer(&test.RequestHandlerMapping{ Method: http.MethodDelete, - Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/1.0", api.APIVersion), + Pattern: "/api/chartrepo/library/charts/harbor/1.0", Handler: func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }, diff --git a/src/server/middleware/quota/upload_chart_version.go b/src/server/middleware/quota/upload_chart_version.go index 8bdafc9b4..2fff50f41 100644 --- a/src/server/middleware/quota/upload_chart_version.go +++ b/src/server/middleware/quota/upload_chart_version.go @@ -20,7 +20,6 @@ import ( "regexp" "strconv" - "github.com/goharbor/harbor/src/common/api" "github.com/goharbor/harbor/src/lib" "github.com/goharbor/harbor/src/pkg/types" "github.com/goharbor/harbor/src/server/middleware" @@ -30,7 +29,7 @@ import ( // UploadChartVersionMiddleware middleware to request count resources for the project func UploadChartVersionMiddleware() func(http.Handler) http.Handler { - chartsURL := fmt.Sprintf(`^/api/%s/chartrepo/(?P[^?#]+)/charts/?$`, api.APIVersion) + chartsURL := `^/api/chartrepo/(?P[^?#]+)/charts/?$` skipper := middleware.NegativeSkipper(middleware.MethodAndPathSkipper(http.MethodPost, regexp.MustCompile(chartsURL))) return RequestMiddleware(RequestConfig{ diff --git a/src/server/middleware/quota/util_test.go b/src/server/middleware/quota/util_test.go index 20a8f3679..fb0d76b52 100644 --- a/src/server/middleware/quota/util_test.go +++ b/src/server/middleware/quota/util_test.go @@ -58,6 +58,7 @@ func Test_projectReferenceObject(t *testing.T) { {"/api/v2.0/projects/library/repositories", args{req("/api/v2.0/projects/library/repositories")}, "project", "1", false}, {"/api/v2.0/projects/demo", args{req("/api/v2.0/projects/demo")}, "", "", true}, {"/api/v2.0/library", args{req("/api/v2.0/library")}, "", "", true}, + {"/api/chartrepo/library/charts", args{req("/api/chartrepo/library/charts")}, "project", "1", false}, {"/v2/library/photon/manifests/2.0", args{req("/v2/library/photon/manifests/2.0")}, "project", "1", false}, {"/v2", args{req("/v2")}, "", "", true}, } diff --git a/src/server/middleware/security/oidc_cli.go b/src/server/middleware/security/oidc_cli.go index 549711b71..4ebff36d8 100644 --- a/src/server/middleware/security/oidc_cli.go +++ b/src/server/middleware/security/oidc_cli.go @@ -38,6 +38,7 @@ func (o *oidcCli) Generate(req *http.Request) security.Context { if path != "/service/token" && !strings.HasPrefix(path, "/v2") && !strings.HasPrefix(path, "/chartrepo/") && + !strings.HasPrefix(path, "/api/chartrepo/") && !strings.HasPrefix(path, fmt.Sprintf("/api/%s/chartrepo/", api.APIVersion)) { return nil } diff --git a/src/server/middleware/util/util.go b/src/server/middleware/util/util.go index d48d3b591..f2e8320ee 100644 --- a/src/server/middleware/util/util.go +++ b/src/server/middleware/util/util.go @@ -31,8 +31,9 @@ func ParseProjectName(r *http.Request) string { var projectName string prefixes := []string{ - fmt.Sprintf("/api/%s/projects/", api.APIVersion), // v2.0 management APIs - fmt.Sprintf("/api/%s/chartrepo/", api.APIVersion), // chartmuseum APIs + fmt.Sprintf("/api/%s/projects/", api.APIVersion), // v2.0 management APIs + "/api/chartrepo/", // chartmuseum APIs + fmt.Sprintf("/api/%s/chartrepo/", api.APIVersion), // chartmuseum Label APIs } for _, prefix := range prefixes { diff --git a/src/server/route.go b/src/server/route.go index de8caf5e5..4a5f65952 100644 --- a/src/server/route.go +++ b/src/server/route.go @@ -56,6 +56,15 @@ func registerRoutes() { beego.Router("/chartrepo/:repo/index.yaml", chartRepositoryAPIType, "get:GetIndexByRepo") beego.Router("/chartrepo/index.yaml", chartRepositoryAPIType, "get:GetIndex") beego.Router("/chartrepo/:repo/charts/:filename", chartRepositoryAPIType, "get:DownloadChart") + beego.Router("/api/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus") + beego.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "get:ListCharts") + beego.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "get:ListChartVersions") + beego.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "delete:DeleteChart") + beego.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "get:GetChartVersion") + beego.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "delete:DeleteChartVersion") + beego.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "post:UploadChartVersion") + beego.Router("/api/chartrepo/:repo/prov", chartRepositoryAPIType, "post:UploadChartProvFile") + beego.Router("/api/chartrepo/charts", chartRepositoryAPIType, "post:UploadChartVersion") } // Error pages diff --git a/src/server/v2.0/route/legacy.go b/src/server/v2.0/route/legacy.go index 24d63bd46..d4da50763 100755 --- a/src/server/v2.0/route/legacy.go +++ b/src/server/v2.0/route/legacy.go @@ -110,18 +110,6 @@ func registerLegacyRoutes() { // APIs for chart repository if config.WithChartMuseum() { - // Charts are controlled under projects - chartRepositoryAPIType := &api.ChartRepositoryAPI{} - beego.Router("/api/"+version+"/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus") - beego.Router("/api/"+version+"/chartrepo/:repo/charts", chartRepositoryAPIType, "get:ListCharts") - beego.Router("/api/"+version+"/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "get:ListChartVersions") - beego.Router("/api/"+version+"/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "delete:DeleteChart") - beego.Router("/api/"+version+"/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "get:GetChartVersion") - beego.Router("/api/"+version+"/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "delete:DeleteChartVersion") - beego.Router("/api/"+version+"/chartrepo/:repo/charts", chartRepositoryAPIType, "post:UploadChartVersion") - beego.Router("/api/"+version+"/chartrepo/:repo/prov", chartRepositoryAPIType, "post:UploadChartProvFile") - beego.Router("/api/"+version+"/chartrepo/charts", chartRepositoryAPIType, "post:UploadChartVersion") - // Labels for chart chartLabelAPIType := &api.ChartLabelAPI{} beego.Router("/api/"+version+"/chartrepo/:repo/charts/:name/:version/labels", chartLabelAPIType, "get:GetLabels;post:MarkLabel") From 6216073d2a2deb4a2cd5b54e2ebdb9f88864f6bf Mon Sep 17 00:00:00 2001 From: DQ Date: Mon, 30 Mar 2020 22:53:00 +0800 Subject: [PATCH 2/3] Add ui change using api/chartreport for ui Signed-off-by: DQ --- src/portal/src/app/shared/shared.module.ts | 5 +++-- src/portal/src/lib/entities/service.config.ts | 2 ++ src/portal/src/lib/harbor-library.module.ts | 5 +++-- src/portal/src/lib/services/label.service.ts | 12 +++++++----- src/portal/src/lib/utils/utils.ts | 6 ++++++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/portal/src/app/shared/shared.module.ts b/src/portal/src/app/shared/shared.module.ts index 65eb9ddda..76e3fb575 100644 --- a/src/portal/src/app/shared/shared.module.ts +++ b/src/portal/src/app/shared/shared.module.ts @@ -46,7 +46,7 @@ import { ListChartVersionRoComponent } from "./list-chart-version-ro/list-chart- import { IServiceConfig, SERVICE_CONFIG } from "../../lib/entities/service.config"; import { ErrorHandler } from "../../lib/utils/error-handler"; import { HarborLibraryModule } from "../../lib/harbor-library.module"; -import { CURRENT_BASE_HREF } from "../../lib/utils/utils"; +import { CURRENT_BASE_HREF, V1_BASE_HREF } from "../../lib/utils/utils"; const uiLibConfig: IServiceConfig = { enablei18Support: true, @@ -67,8 +67,9 @@ const uiLibConfig: IServiceConfig = { configurationEndpoint: CURRENT_BASE_HREF + "/configurations", scanJobEndpoint: CURRENT_BASE_HREF + "/jobs/scan", labelEndpoint: CURRENT_BASE_HREF + "/labels", - helmChartEndpoint: CURRENT_BASE_HREF + "/chartrepo", + helmChartEndpoint: V1_BASE_HREF + "/chartrepo", downloadChartEndpoint: "/chartrepo", + helmChartLabelEndpoint: CURRENT_BASE_HREF + "/chartrepo", gcEndpoint: CURRENT_BASE_HREF + "/system/gc", ScanAllEndpoint: CURRENT_BASE_HREF + "/system/scanAll", quotaUrl: CURRENT_BASE_HREF + "/quotas" diff --git a/src/portal/src/lib/entities/service.config.ts b/src/portal/src/lib/entities/service.config.ts index 7a1a35591..f90dcbcab 100644 --- a/src/portal/src/lib/entities/service.config.ts +++ b/src/portal/src/lib/entities/service.config.ts @@ -229,6 +229,8 @@ export interface IServiceConfig { */ downloadChartEndpoint?: string; + helmChartLabelEndpoint?: string; + gcEndpoint?: string; ScanAllEndpoint?: string; diff --git a/src/portal/src/lib/harbor-library.module.ts b/src/portal/src/lib/harbor-library.module.ts index 9b9c94a28..b8a8db302 100644 --- a/src/portal/src/lib/harbor-library.module.ts +++ b/src/portal/src/lib/harbor-library.module.ts @@ -34,7 +34,7 @@ import { ErrorHandler, DefaultErrorHandler } from './utils/error-handler'; -import { DEFAULT_LANG_COOKIE_KEY, DEFAULT_SUPPORTING_LANGS, DEFAULT_LANG, CURRENT_BASE_HREF } from './utils/utils'; +import { DEFAULT_LANG_COOKIE_KEY, DEFAULT_SUPPORTING_LANGS, DEFAULT_LANG, CURRENT_BASE_HREF, V1_BASE_HREF } from './utils/utils'; import { OperationService } from './components/operation/operation.service'; import { GcHistoryComponent } from "./components/config/gc/gc-history/gc-history.component"; import { GcComponent } from "./components/config/gc/gc.component"; @@ -97,7 +97,8 @@ export const DefaultServiceConfig: IServiceConfig = { configurationEndpoint: CURRENT_BASE_HREF + "/configurations", scanJobEndpoint: CURRENT_BASE_HREF + "/jobs/scan", labelEndpoint: CURRENT_BASE_HREF + "/labels", - helmChartEndpoint: CURRENT_BASE_HREF + "/chartrepo", + helmChartEndpoint: V1_BASE_HREF + "/chartrepo", + helmChartLabelEndpoint: CURRENT_BASE_HREF + "/chartrepo", downloadChartEndpoint: "/chartrepo", gcEndpoint: CURRENT_BASE_HREF + "/system/gc", ScanAllEndpoint: CURRENT_BASE_HREF + "/system/scanAll" diff --git a/src/portal/src/lib/services/label.service.ts b/src/portal/src/lib/services/label.service.ts index 4e0a8a114..be363f39e 100644 --- a/src/portal/src/lib/services/label.service.ts +++ b/src/portal/src/lib/services/label.service.ts @@ -6,7 +6,7 @@ import { RequestQueryParams } from "./RequestQueryParams"; import { Label } from "./interface"; import { IServiceConfig, SERVICE_CONFIG } from "../entities/service.config"; -import { buildHttpRequestOptions, CURRENT_BASE_HREF, HTTP_JSON_OPTIONS } from "../utils/utils"; +import { buildHttpRequestOptions, CURRENT_BASE_HREF, V1_BASE_HREF, HTTP_JSON_OPTIONS } from "../utils/utils"; import { Observable, throwError as observableThrowError } from "rxjs"; export abstract class LabelService { @@ -72,6 +72,7 @@ export abstract class LabelService { export class LabelDefaultService extends LabelService { labelUrl: string; chartUrl: string; + chartLabelUrl: string; constructor( @Inject(SERVICE_CONFIG) config: IServiceConfig, @@ -79,7 +80,8 @@ export class LabelDefaultService extends LabelService { ) { super(); this.labelUrl = config.labelEndpoint ? config.labelEndpoint : CURRENT_BASE_HREF + "/labels"; - this.chartUrl = config.helmChartEndpoint ? config.helmChartEndpoint : CURRENT_BASE_HREF + "/chartrepo"; + this.chartUrl = config.helmChartEndpoint ? config.helmChartEndpoint : V1_BASE_HREF + "/chartrepo"; + this.chartLabelUrl = config.helmChartLabelEndpoint ? config.helmChartLabelEndpoint : CURRENT_BASE_HREF + "/chartrepo"; } @@ -208,7 +210,7 @@ export class LabelDefaultService extends LabelService { chartName: string, version: string ): Observable { - return this.http.get(`${this.chartUrl}/${projectName}/charts/${chartName}/${version}/labels`); + return this.http.get(`${this.chartLabelUrl}/${projectName}/charts/${chartName}/${version}/labels`); } markChartLabel( @@ -217,7 +219,7 @@ export class LabelDefaultService extends LabelService { version: string, label: Label, ): Observable { - return this.http.post(`${this.chartUrl}/${projectName}/charts/${chartName}/${version}/labels`, + return this.http.post(`${this.chartLabelUrl}/${projectName}/charts/${chartName}/${version}/labels`, JSON.stringify(label), HTTP_JSON_OPTIONS); } @@ -227,7 +229,7 @@ export class LabelDefaultService extends LabelService { version: string, label: Label, ): Observable { - return this.http.delete(`${this.chartUrl}/${projectName}/charts/${chartName}/${version}/labels/${label.id}`, HTTP_JSON_OPTIONS); + return this.http.delete(`${this.chartLabelUrl}/${projectName}/charts/${chartName}/${version}/labels/${label.id}`, HTTP_JSON_OPTIONS); } } diff --git a/src/portal/src/lib/utils/utils.ts b/src/portal/src/lib/utils/utils.ts index eac62db43..50245653f 100644 --- a/src/portal/src/lib/utils/utils.ts +++ b/src/portal/src/lib/utils/utils.ts @@ -13,6 +13,12 @@ enum APILevels { V1 = '', V2 = '/v2.0' } + +/** + * v1 base href + */ +export const V1_BASE_HREF = '/api' + APILevels.V1; + /** * Current base href */ From cd6933901471751de0edf3221e4cc8d85f533380 Mon Sep 17 00:00:00 2001 From: DQ Date: Tue, 31 Mar 2020 12:35:03 +0800 Subject: [PATCH 3/3] Fix API TEST for chart Version Fix api test for chart b/c revert the api Signed-off-by: DQ --- tests/apitests/python/test_list_helm_charts.py | 14 ++++++++------ tests/apitests/python/testutils.py | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/apitests/python/test_list_helm_charts.py b/tests/apitests/python/test_list_helm_charts.py index e6fd4e59c..0ae2a3fc8 100644 --- a/tests/apitests/python/test_list_helm_charts.py +++ b/tests/apitests/python/test_list_helm_charts.py @@ -2,7 +2,7 @@ from __future__ import absolute_import import unittest -from testutils import ADMIN_CLIENT +from testutils import ADMIN_CLIENT, CHART_API_CLIENT from testutils import TEARDOWN from library.user import User from library.project import Project @@ -27,7 +27,7 @@ class TestProjects(unittest.TestCase): @unittest.skipIf(TEARDOWN == False, "Test data won't be erased.") def test_ClearData(self): #1. Delete chart file; - self.chart.delete_chart_with_version(TestProjects.project_chart_name, TestProjects.CHART_NAME, TestProjects.VERSION, **ADMIN_CLIENT) + self.chart.delete_chart_with_version(TestProjects.project_chart_name, TestProjects.CHART_NAME, TestProjects.VERSION, **CHART_API_CLIENT) #2. Delete project(PA); self.project.delete_project(TestProjects.project_chart_id, **TestProjects.USER_CHART_CLIENT) @@ -50,8 +50,8 @@ class TestProjects(unittest.TestCase): 3. Delete user(UA). """ url = ADMIN_CLIENT["endpoint"] - - user_chart_password = "Aa123456" + chart_api_url = CHART_API_CLIENT['endpoint'] + user_chart_password = 'Aa123456' TestProjects.CHART_NAME = 'mariadb' TestProjects.VERSION = '4.3.1' @@ -60,14 +60,16 @@ class TestProjects(unittest.TestCase): TestProjects.USER_CHART_CLIENT=dict(endpoint = url, username = user_chart_name, password = user_chart_password) + TestProjects.API_CHART_CLIENT=dict(endpoint = chart_api_url, username = user_chart_name, password = user_chart_password) + #2. Create a new project(PA) by user(UA); TestProjects.project_chart_id, TestProjects.project_chart_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_CHART_CLIENT) #3. Upload a chart file to project(PA); - self.chart.upload_chart(TestProjects.project_chart_name, r'./tests/apitests/python/mariadb-{}.tgz'.format(TestProjects.VERSION), **TestProjects.USER_CHART_CLIENT) + self.chart.upload_chart(TestProjects.project_chart_name, r'./tests/apitests/python/mariadb-{}.tgz'.format(TestProjects.VERSION), **TestProjects.API_CHART_CLIENT) #4. Chart file should be exist in project(PA). - self.chart.chart_should_exist(TestProjects.project_chart_name, TestProjects.CHART_NAME, **TestProjects.USER_CHART_CLIENT) + self.chart.chart_should_exist(TestProjects.project_chart_name, TestProjects.CHART_NAME, **TestProjects.API_CHART_CLIENT) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/tests/apitests/python/testutils.py b/tests/apitests/python/testutils.py index aff96ad07..14fb16bd7 100644 --- a/tests/apitests/python/testutils.py +++ b/tests/apitests/python/testutils.py @@ -14,6 +14,7 @@ admin_pwd = "Harbor12345" harbor_server = os.environ["HARBOR_HOST"] #CLIENT=dict(endpoint="https://"+harbor_server+"/api") ADMIN_CLIENT=dict(endpoint = os.environ.get("HARBOR_HOST_SCHEMA", "https")+ "://"+harbor_server+"/api/v2.0", username = admin_user, password = admin_pwd) +CHART_API_CLIENT=dict(endpoint = os.environ.get("HARBOR_HOST_SCHEMA", "https")+ "://"+harbor_server+"/api", username = admin_user, password = admin_pwd) USER_ROLE=dict(admin=0,normal=1) TEARDOWN = os.environ.get('TEARDOWN', 'true').lower() in ('true', 'yes')