diff --git a/src/chartserver/handler_manipulation.go b/src/chartserver/handler_manipulation.go index 42e714916..3e4bda593 100644 --- a/src/chartserver/handler_manipulation.go +++ b/src/chartserver/handler_manipulation.go @@ -9,6 +9,7 @@ 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" @@ -69,7 +70,7 @@ func (c *Controller) DeleteChartVersion(namespace, chartName, version string) er return errors.New("invalid chart for deleting") } - url := fmt.Sprintf("/api/chartrepo/%s/charts/%s/%s", namespace, chartName, version) + url := fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s/%s", api.APIVersion, 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 5d54aefc3..69a29b1f4 100644 --- a/src/chartserver/handler_proxy_traffic_test.go +++ b/src/chartserver/handler_proxy_traffic_test.go @@ -10,6 +10,7 @@ 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" ) @@ -36,7 +37,7 @@ func TestStartMockServers(t *testing.T) { // Test /health func TestGetHealthOfBaseHandler(t *testing.T) { - content, err := httpClient.GetContent(fmt.Sprintf("%s/api/chartrepo/health", frontServer.URL)) + content, err := httpClient.GetContent(fmt.Sprintf("%s/api/%s/chartrepo/health", frontServer.URL, api.APIVersion)) if err != nil { t.Fatal(err) } diff --git a/src/chartserver/reverse_proxy.go b/src/chartserver/reverse_proxy.go index ca4cc7a47..7391dbe79 100644 --- a/src/chartserver/reverse_proxy.go +++ b/src/chartserver/reverse_proxy.go @@ -12,24 +12,29 @@ import ( "os" "strconv" "strings" + "time" "github.com/goharbor/harbor/src/common" + "github.com/goharbor/harbor/src/common/api" hlog "github.com/goharbor/harbor/src/common/utils/log" 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" "github.com/justinas/alice" - "time" ) const ( agentHarbor = "HARBOR" contentLengthHeader = "Content-Length" +) - defaultRepo = "library" - rootUploadingEndpoint = "/api/chartrepo/charts" - rootIndexEndpoint = "/chartrepo/index.yaml" - chartRepoHealthEndpoint = "/api/chartrepo/health" +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" ) // ProxyEngine is used to proxy the related traffics @@ -220,19 +225,19 @@ func rewriteURLPath(req *http.Request) { // Root uploading endpoint if incomingURLPath == rootUploadingEndpoint { - req.URL.Path = strings.Replace(incomingURLPath, "chartrepo", defaultRepo, 1) + req.URL.Path = strings.Replace(incomingURLPath, fmt.Sprintf("%s/chartrepo", api.APIVersion), defaultRepo, 1) return } // Repository endpoints - if strings.HasPrefix(incomingURLPath, "/chartrepo") { + if strings.HasPrefix(incomingURLPath, chartRepoPrefix) { req.URL.Path = strings.TrimPrefix(incomingURLPath, "/chartrepo") return } // API endpoints - if strings.HasPrefix(incomingURLPath, "/api/chartrepo") { - req.URL.Path = strings.Replace(incomingURLPath, "/chartrepo", "", 1) + if strings.HasPrefix(incomingURLPath, chartRepoAPIPrefix) { + req.URL.Path = strings.Replace(incomingURLPath, fmt.Sprintf("/%s/chartrepo", api.APIVersion), "", 1) return } } diff --git a/src/chartserver/reverse_proxy_test.go b/src/chartserver/reverse_proxy_test.go index 44cfa0964..fef27f749 100644 --- a/src/chartserver/reverse_proxy_test.go +++ b/src/chartserver/reverse_proxy_test.go @@ -1,13 +1,16 @@ 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, "/api/chartrepo/health") + req, err := createRequest(http.MethodGet, fmt.Sprintf("/api/%s/chartrepo/health", api.APIVersion)) if err != nil { t.Fatal(err) } @@ -16,7 +19,7 @@ func TestURLRewrite(t *testing.T) { t.Fatalf("Expect url format %s but got %s", "/health", req.URL.Path) } - req, err = createRequest(http.MethodGet, "/api/chartrepo/library/charts") + req, err = createRequest(http.MethodGet, fmt.Sprintf("/api/%s/chartrepo/library/charts", api.APIVersion)) if err != nil { t.Fatal(err) } @@ -25,7 +28,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, "/api/chartrepo/charts") + req, err = createRequest(http.MethodPost, fmt.Sprintf("/api/%s/chartrepo/charts", api.APIVersion)) if err != nil { t.Fatal(err) } diff --git a/src/common/api/base.go b/src/common/api/base.go index 1547a090b..859bc0dac 100644 --- a/src/common/api/base.go +++ b/src/common/api/base.go @@ -21,6 +21,7 @@ import ( "strconv" "errors" + "github.com/astaxie/beego" "github.com/astaxie/beego/validation" commonhttp "github.com/goharbor/harbor/src/common/http" @@ -31,6 +32,9 @@ import ( const ( defaultPageSize int64 = 500 maxPageSize int64 = 500 + + // APIVersion is the current core api version + APIVersion = "v2.0" ) // BaseAPI wraps common methods for controllers to host API diff --git a/src/core/api/chart_label_test.go b/src/core/api/chart_label_test.go index c316c0782..7caa96747 100644 --- a/src/core/api/chart_label_test.go +++ b/src/core/api/chart_label_test.go @@ -22,6 +22,7 @@ import ( "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/dao" "github.com/goharbor/harbor/src/common/models" "github.com/stretchr/testify/assert" @@ -29,9 +30,9 @@ import ( ) var ( - resourceLabelAPIPath = "/api/chartrepo/library/charts/harbor/0.2.0/labels" - resourceLabelAPIPathWithFakeProject = "/api/chartrepo/not-exist/charts/harbor/0.2.0/labels" - resourceLabelAPIPathWithFakeChart = "/api/chartrepo/library/charts/not-exist/0.2.0/labels" + resourceLabelAPIPath = fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/0.2.0/labels", api.APIVersion) + resourceLabelAPIPathWithFakeProject = fmt.Sprintf("/api/%s/chartrepo/not-exist/charts/harbor/0.2.0/labels", api.APIVersion) + resourceLabelAPIPathWithFakeChart = fmt.Sprintf("/api/%s/chartrepo/library/charts/not-exist/0.2.0/labels", api.APIVersion) cProLibraryLabelID int64 mockChartServer *httptest.Server oldChartController *chartserver.Controller diff --git a/src/core/api/chart_repository.go b/src/core/api/chart_repository.go index e8e1b1b1e..559347a9b 100755 --- a/src/core/api/chart_repository.go +++ b/src/core/api/chart_repository.go @@ -17,6 +17,7 @@ import ( "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" @@ -28,13 +29,9 @@ import ( ) const ( - namespaceParam = ":repo" - nameParam = ":name" - filenameParam = ":filename" - defaultRepo = "library" - rootUploadingEndpoint = "/api/chartrepo/charts" - rootIndexEndpoint = "/chartrepo/index.yaml" - chartRepoHealthEndpoint = "/api/chartrepo/health" + namespaceParam = ":repo" + nameParam = ":name" + filenameParam = ":filename" accessLevelPublic = iota accessLevelRead @@ -50,6 +47,13 @@ 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 @@ -108,7 +112,7 @@ func (cra *ChartRepositoryAPI) requireAccess(action rbac.Action, subresource ... return cra.RequireProjectAccess(cra.namespace, action, subresource...) } -// GetHealthStatus handles GET /api/chartrepo/health +// GetHealthStatus handles GET /chartrepo/health func (cra *ChartRepositoryAPI) GetHealthStatus() { // Check access if !cra.SecurityCtx.IsAuthenticated() { diff --git a/src/core/api/chart_repository_test.go b/src/core/api/chart_repository_test.go index d095ca71f..1bcfbcbdd 100644 --- a/src/core/api/chart_repository_test.go +++ b/src/core/api/chart_repository_test.go @@ -2,11 +2,13 @@ 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/common/rbac" "github.com/goharbor/harbor/src/core/promgr/metamgr" @@ -18,7 +20,7 @@ var ( ) func TestIsMultipartFormData(t *testing.T) { - req, err := createRequest(http.MethodPost, "/api/chartrepo/charts") + req, err := createRequest(http.MethodPost, fmt.Sprintf("/api/%s/chartrepo/charts", api.APIVersion)) if err != nil { t.Fatal(err) } @@ -56,7 +58,7 @@ func TestPrepareEnv(t *testing.T) { func TestGetHealthStatus(t *testing.T) { status := make(map[string]interface{}) err := handleAndParse(&testingRequest{ - url: "/api/chartrepo/health", + url: fmt.Sprintf("/api/%s/chartrepo/health", api.APIVersion), method: http.MethodGet, credential: sysAdmin, }, &status) @@ -110,7 +112,7 @@ func TestDownloadChart(t *testing.T) { func TesListCharts(t *testing.T) { charts := make([]*chartserver.ChartInfo, 0) err := handleAndParse(&testingRequest{ - url: "/api/chartrepo/library/charts", + url: fmt.Sprintf("/api/%s/chartrepo/library/charts", api.APIVersion), method: http.MethodGet, credential: projAdmin, }, &charts) @@ -128,7 +130,7 @@ func TesListCharts(t *testing.T) { func TestListChartVersions(t *testing.T) { chartVersions := make(chartserver.ChartVersions, 0) err := handleAndParse(&testingRequest{ - url: "/api/chartrepo/library/charts/harbor", + url: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor", api.APIVersion), method: http.MethodGet, credential: projAdmin, }, &chartVersions) @@ -146,7 +148,7 @@ func TestListChartVersions(t *testing.T) { func TestGetChartVersion(t *testing.T) { chartV := &chartserver.ChartVersionDetails{} err := handleAndParse(&testingRequest{ - url: "/api/chartrepo/library/charts/harbor/0.2.0", + url: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/0.2.0", api.APIVersion), method: http.MethodGet, credential: projAdmin, }, chartV) @@ -168,7 +170,7 @@ func TestGetChartVersion(t *testing.T) { func TestDeleteChartVersion(t *testing.T) { runCodeCheckingCases(t, &codeCheckingCase{ request: &testingRequest{ - url: "/api/chartrepo/library/charts/harbor/0.2.1", + url: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/0.2.1", api.APIVersion), method: http.MethodDelete, credential: projAdmin, }, @@ -180,7 +182,7 @@ func TestDeleteChartVersion(t *testing.T) { func TestDeleteChart(t *testing.T) { runCodeCheckingCases(t, &codeCheckingCase{ request: &testingRequest{ - url: "/api/chartrepo/library/charts/harbor", + url: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor", api.APIVersion), method: http.MethodDelete, credential: projAdmin, }, diff --git a/src/core/api/harborapi_test.go b/src/core/api/harborapi_test.go index 38d1a60ee..2812d41eb 100644 --- a/src/core/api/harborapi_test.go +++ b/src/core/api/harborapi_test.go @@ -30,6 +30,7 @@ import ( "github.com/astaxie/beego" "github.com/dghubble/sling" + "github.com/goharbor/harbor/src/common/api" "github.com/goharbor/harbor/src/common/dao" "github.com/goharbor/harbor/src/common/job/test" "github.com/goharbor/harbor/src/common/models" @@ -172,15 +173,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/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") + 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") // Repository services beego.Router("/chartrepo/:repo/index.yaml", chartRepositoryAPIType, "get:GetIndexByRepo") @@ -188,8 +189,8 @@ func init() { beego.Router("/chartrepo/:repo/charts/:filename", chartRepositoryAPIType, "get:DownloadChart") // Labels for chart chartLabelAPIType := &ChartLabelAPI{} - beego.Router("/api/chartrepo/:repo/charts/:name/:version/labels", chartLabelAPIType, "get:GetLabels;post:MarkLabel") - beego.Router("/api/chartrepo/:repo/charts/:name/:version/labels/:id([0-9]+)", chartLabelAPIType, "delete:RemoveLabel") + beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name/:version/labels", chartLabelAPIType, "get:GetLabels;post:MarkLabel") + beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name/:version/labels/:id([0-9]+)", chartLabelAPIType, "delete:RemoveLabel") quotaAPIType := &QuotaAPI{} beego.Router("/api/quotas", quotaAPIType, "get:List") diff --git a/src/core/filter/security.go b/src/core/filter/security.go index e83285385..1db1e08cf 100644 --- a/src/core/filter/security.go +++ b/src/core/filter/security.go @@ -23,6 +23,7 @@ import ( beegoctx "github.com/astaxie/beego/context" "github.com/docker/distribution/reference" "github.com/goharbor/harbor/src/common" + "github.com/goharbor/harbor/src/common/api" "github.com/goharbor/harbor/src/common/dao" "github.com/goharbor/harbor/src/common/dao/group" "github.com/goharbor/harbor/src/common/models" @@ -209,7 +210,7 @@ func (oc *oidcCliReqCtxModifier) Modify(ctx *beegoctx.Context) bool { path := ctx.Request.URL.Path if path != "/service/token" && !strings.HasPrefix(path, "/chartrepo/") && - !strings.HasPrefix(path, "/api/chartrepo/") { + !strings.HasPrefix(path, fmt.Sprintf("/api/%s/chartrepo/", api.APIVersion)) { log.Debug("OIDC CLI modifier only handles request by docker CLI or helm CLI") return false } diff --git a/src/core/middlewares/chart/builder.go b/src/core/middlewares/chart/builder.go index 76d623748..f872ed610 100644 --- a/src/core/middlewares/chart/builder.go +++ b/src/core/middlewares/chart/builder.go @@ -20,6 +20,7 @@ import ( "regexp" "strconv" + "github.com/goharbor/harbor/src/common/api" "github.com/goharbor/harbor/src/common/dao" "github.com/goharbor/harbor/src/core/config" "github.com/goharbor/harbor/src/core/middlewares/interceptor" @@ -29,8 +30,10 @@ import ( ) var ( - deleteChartVersionRe = regexp.MustCompile(`^/api/chartrepo/(?P[^?#]+)/charts/(?P[^?#]+)/(?P[^?#]+)/?$`) - createChartVersionRe = regexp.MustCompile(`^/api/chartrepo/(?P[^?#]+)/charts/?$`) + deleteChartVersionRePattern = fmt.Sprintf(`^/api/%s/chartrepo/(?P[^?#]+)/charts/(?P[^?#]+)/(?P[^?#]+)/?$`, api.APIVersion) + deleteChartVersionRe = regexp.MustCompile(deleteChartVersionRePattern) + createChartVersionRePattern = fmt.Sprintf(`^/api/%s/chartrepo/(?P[^?#]+)/charts/?$`, api.APIVersion) + createChartVersionRe = regexp.MustCompile(createChartVersionRePattern) ) var ( diff --git a/src/core/middlewares/chart/handler_test.go b/src/core/middlewares/chart/handler_test.go index 217c1c70f..d0821152f 100644 --- a/src/core/middlewares/chart/handler_test.go +++ b/src/core/middlewares/chart/handler_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/goharbor/harbor/src/chartserver" + "github.com/goharbor/harbor/src/common/api" "github.com/goharbor/harbor/src/common/dao" "github.com/goharbor/harbor/src/core/middlewares/util" "github.com/goharbor/harbor/src/pkg/types" @@ -30,7 +31,7 @@ import ( ) func deleteChartVersion(projectName, chartName, version string) { - url := fmt.Sprintf("/api/chartrepo/%s/charts/%s/%s", projectName, chartName, version) + url := fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s/%s", api.APIVersion, projectName, chartName, version) req, _ := http.NewRequest(http.MethodDelete, url, nil) next := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { @@ -43,7 +44,7 @@ func deleteChartVersion(projectName, chartName, version string) { } func uploadChartVersion(projectID int64, projectName, chartName, version string) { - url := fmt.Sprintf("/api/chartrepo/%s/charts/", projectName) + url := fmt.Sprintf("/api/%s/chartrepo/%s/charts/", api.APIVersion, projectName) req, _ := http.NewRequest(http.MethodPost, url, nil) info := &util.ChartVersionInfo{ diff --git a/src/pkg/clients/core/chart.go b/src/pkg/clients/core/chart.go index 75d8c3983..ea7c50548 100644 --- a/src/pkg/clients/core/chart.go +++ b/src/pkg/clients/core/chart.go @@ -18,10 +18,11 @@ 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/chartrepo/%s/charts/%s", project, repository)) + url := c.buildURL(fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s", api.APIVersion, project, repository)) var charts []*chartserver.ChartVersion if err := c.httpclient.Get(url, &charts); err != nil { return nil, err @@ -30,11 +31,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/chartrepo/%s/charts/%s/%s", project, repository, version)) + url := c.buildURL(fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s/%s", api.APIVersion, project, repository, version)) return c.httpclient.Delete(url) } func (c *client) DeleteChartRepository(project, repository string) error { - url := c.buildURL(fmt.Sprintf("/api/chartrepo/%s/charts/%s", project, repository)) + url := c.buildURL(fmt.Sprintf("/api/%s/chartrepo/%s/charts/%s", api.APIVersion, project, repository)) return c.httpclient.Delete(url) } diff --git a/src/replication/adapter/harbor/adapter.go b/src/replication/adapter/harbor/adapter.go index e15f72d7e..f9c4a1563 100644 --- a/src/replication/adapter/harbor/adapter.go +++ b/src/replication/adapter/harbor/adapter.go @@ -17,6 +17,11 @@ package harbor import ( "errors" "fmt" + "net/http" + "strconv" + "strings" + + "github.com/goharbor/harbor/src/common/api" common_http "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/http/modifier" common_http_auth "github.com/goharbor/harbor/src/common/http/modifier/auth" @@ -26,9 +31,6 @@ import ( "github.com/goharbor/harbor/src/replication/adapter/native" "github.com/goharbor/harbor/src/replication/model" "github.com/goharbor/harbor/src/replication/util" - "net/http" - "strconv" - "strings" ) func init() { @@ -117,7 +119,7 @@ func (a *adapter) Info() (*model.RegistryInfo, error) { sys := &struct { ChartRegistryEnabled bool `json:"with_chartmuseum"` }{} - if err := a.client.Get(a.getURL()+"/api/v2.0/systeminfo", sys); err != nil { + if err := a.client.Get(fmt.Sprintf("%s/api/%s/systeminfo", a.getURL(), api.APIVersion), sys); err != nil { return nil, err } if sys.ChartRegistryEnabled { @@ -127,7 +129,7 @@ func (a *adapter) Info() (*model.RegistryInfo, error) { Name string `json:"name"` }{} // label isn't supported in some previous version of Harbor - if err := a.client.Get(a.getURL()+"/api/v2.0/labels?scope=g", &labels); err != nil { + if err := a.client.Get(fmt.Sprintf("%s/api/%s/labels?scope=g", a.getURL(), api.APIVersion), &labels); err != nil { if e, ok := err.(*common_http.Error); !ok || e.Code != http.StatusNotFound { return nil, err } @@ -183,7 +185,7 @@ func (a *adapter) PrepareForPush(resources []*model.Resource) error { Name: project.Name, Metadata: project.Metadata, } - err := a.client.Post(a.getURL()+"/api/v2.0/projects", pro) + err := a.client.Post(fmt.Sprintf("%s/api/%s/projects", a.getURL(), api.APIVersion), pro) if err != nil { if httpErr, ok := err.(*common_http.Error); ok && httpErr.Code == http.StatusConflict { log.Debugf("got 409 when trying to create project %s", project.Name) @@ -249,7 +251,7 @@ type project struct { func (a *adapter) getProjects(name string) ([]*project, error) { projects := []*project{} - url := fmt.Sprintf("%s/api/v2.0/projects?name=%s&page=1&page_size=500", a.getURL(), name) + url := fmt.Sprintf("%s/api/%s/projects?name=%s&page=1&page_size=500", a.getURL(), api.APIVersion, name) if err := a.client.GetAndIteratePagination(url, &projects); err != nil { return nil, err } @@ -284,7 +286,7 @@ func (a *adapter) getProject(name string) (*project, error) { func (a *adapter) getRepositories(projectID int64) ([]*adp.Repository, error) { repositories := []*adp.Repository{} - url := fmt.Sprintf("%s/api/v2.0/repositories?project_id=%d&page=1&page_size=500", a.getURL(), projectID) + url := fmt.Sprintf("%s/api/%s/repositories?project_id=%d&page=1&page_size=500", a.getURL(), api.APIVersion, projectID) if err := a.client.GetAndIteratePagination(url, &repositories); err != nil { return nil, err } diff --git a/src/replication/adapter/harbor/chart_registry.go b/src/replication/adapter/harbor/chart_registry.go index 2cab3f202..8d872f912 100644 --- a/src/replication/adapter/harbor/chart_registry.go +++ b/src/replication/adapter/harbor/chart_registry.go @@ -23,6 +23,7 @@ import ( "net/http" "strings" + "github.com/goharbor/harbor/src/common/api" common_http "github.com/goharbor/harbor/src/common/http" adp "github.com/goharbor/harbor/src/replication/adapter" "github.com/goharbor/harbor/src/replication/model" @@ -52,7 +53,7 @@ func (a *adapter) FetchCharts(filters []*model.Filter) ([]*model.Resource, error } resources := []*model.Resource{} for _, project := range projects { - url := fmt.Sprintf("%s/api/v2.0/chartrepo/%s/charts", a.getURL(), project.Name) + url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts", a.getURL(), api.APIVersion, project.Name) repositories := []*adp.Repository{} if err := a.client.Get(url, &repositories); err != nil { return nil, err @@ -71,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/v2.0/chartrepo/%s/charts/%s", a.getURL(), project.Name, name) + url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts/%s", a.getURL(), api.APIVersion, project.Name, name) versions := []*chartVersion{} if err := a.client.Get(url, &versions); err != nil { return nil, err @@ -131,7 +132,7 @@ func (a *adapter) getChartInfo(name, version string) (*chartVersionDetail, error if err != nil { return nil, err } - url := fmt.Sprintf("%s/api/v2.0/chartrepo/%s/charts/%s/%s", a.url, project, name, version) + url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts/%s/%s", a.url, api.APIVersion, project, name, version) info := &chartVersionDetail{} if err = a.client.Get(url, info); err != nil { return nil, err @@ -191,7 +192,7 @@ func (a *adapter) UploadChart(name, version string, chart io.Reader) error { } w.Close() - url := fmt.Sprintf("%s/api/v2.0/chartrepo/%s/charts", a.url, project) + url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts", a.url, api.APIVersion, project) req, err := http.NewRequest(http.MethodPost, url, buf) if err != nil { @@ -222,7 +223,7 @@ func (a *adapter) DeleteChart(name, version string) error { if err != nil { return err } - url := fmt.Sprintf("%s/api/v2.0/chartrepo/%s/charts/%s/%s", a.url, project, name, version) + url := fmt.Sprintf("%s/api/%s/chartrepo/%s/charts/%s/%s", a.url, api.APIVersion, 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 a2820faf1..113448860 100644 --- a/src/replication/adapter/harbor/chart_registry_test.go +++ b/src/replication/adapter/harbor/chart_registry_test.go @@ -16,9 +16,11 @@ package harbor import ( "bytes" + "fmt" "net/http" "testing" + "github.com/goharbor/harbor/src/common/api" "github.com/goharbor/harbor/src/common/utils/test" "github.com/goharbor/harbor/src/replication/model" "github.com/stretchr/testify/assert" @@ -29,7 +31,7 @@ func TestFetchCharts(t *testing.T) { server := test.NewServer([]*test.RequestHandlerMapping{ { Method: http.MethodGet, - Pattern: "/api/v2.0/projects", + Pattern: fmt.Sprintf("/api/%s/projects", api.APIVersion), Handler: func(w http.ResponseWriter, r *http.Request) { data := `[{ "name": "library", @@ -40,7 +42,7 @@ func TestFetchCharts(t *testing.T) { }, { Method: http.MethodGet, - Pattern: "/api/v2.0/chartrepo/library/charts/harbor", + Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor", api.APIVersion), Handler: func(w http.ResponseWriter, r *http.Request) { data := `[{ "name": "harbor", @@ -54,7 +56,7 @@ func TestFetchCharts(t *testing.T) { }, { Method: http.MethodGet, - Pattern: "/api/v2.0/chartrepo/library/charts", + Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts", api.APIVersion), Handler: func(w http.ResponseWriter, r *http.Request) { data := `[{ "name": "harbor" @@ -100,7 +102,7 @@ func TestFetchCharts(t *testing.T) { func TestChartExist(t *testing.T) { server := test.NewServer(&test.RequestHandlerMapping{ Method: http.MethodGet, - Pattern: "/api/v2.0/chartrepo/library/charts/harbor/1.0", + Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/1.0", api.APIVersion), Handler: func(w http.ResponseWriter, r *http.Request) { data := `{ "metadata": { @@ -125,7 +127,7 @@ func TestDownloadChart(t *testing.T) { server := test.NewServer([]*test.RequestHandlerMapping{ { Method: http.MethodGet, - Pattern: "/api/v2.0/chartrepo/library/charts/harbor/1.0", + Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/1.0", api.APIVersion), Handler: func(w http.ResponseWriter, r *http.Request) { data := `{ "metadata": { @@ -156,7 +158,7 @@ func TestDownloadChart(t *testing.T) { func TestUploadChart(t *testing.T) { server := test.NewServer(&test.RequestHandlerMapping{ Method: http.MethodPost, - Pattern: "/api/v2.0/chartrepo/library/charts", + Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts", api.APIVersion), Handler: func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }, @@ -174,7 +176,7 @@ func TestUploadChart(t *testing.T) { func TestDeleteChart(t *testing.T) { server := test.NewServer(&test.RequestHandlerMapping{ Method: http.MethodDelete, - Pattern: "/api/v2.0/chartrepo/library/charts/harbor/1.0", + Pattern: fmt.Sprintf("/api/%s/chartrepo/library/charts/harbor/1.0", api.APIVersion), Handler: func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) },