mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-25 11:46:43 +01:00
commit
4cc2115a23
@ -702,26 +702,27 @@ paths:
|
||||
description: Project ID does not exist.
|
||||
500:
|
||||
description: Unexpected internal errors.
|
||||
/repositories/{repo_name}/tags/{tag}:
|
||||
delete:
|
||||
summary: Delete a repository or a tag in a repository.
|
||||
summary: Delete a tag in a repository.
|
||||
description: |
|
||||
This endpoint let user delete repositories and tags with repo name and tag.
|
||||
This endpoint let user delete tags with repo name and tag.
|
||||
parameters:
|
||||
- name: repo_name
|
||||
in: query
|
||||
in: path
|
||||
type: string
|
||||
required: true
|
||||
description: The name of repository which will be deleted.
|
||||
- name: tag
|
||||
in: query
|
||||
in: path
|
||||
type: string
|
||||
required: false
|
||||
required: true
|
||||
description: Tag of a repository.
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
200:
|
||||
description: Delete repository or tag successfully.
|
||||
description: Delete tag successfully.
|
||||
400:
|
||||
description: Invalid repo_name.
|
||||
401:
|
||||
@ -730,14 +731,14 @@ paths:
|
||||
description: Repository or tag not found.
|
||||
403:
|
||||
description: Forbidden.
|
||||
/repositories/tags:
|
||||
/repositories/{repo_name}/tags:
|
||||
get:
|
||||
summary: Get tags of a relevant repository.
|
||||
description: |
|
||||
This endpoint aims to retrieve tags from a relevant repository.
|
||||
parameters:
|
||||
- name: repo_name
|
||||
in: query
|
||||
in: path
|
||||
type: string
|
||||
required: true
|
||||
description: Relevant repository name.
|
||||
@ -757,19 +758,42 @@ paths:
|
||||
$ref: '#/definitions/DetailedTag'
|
||||
500:
|
||||
description: Unexpected internal errors.
|
||||
/repositories/manifests:
|
||||
delete:
|
||||
summary: Delete all tags of a repository.
|
||||
description: |
|
||||
This endpoint let user delete all tags with repo name.
|
||||
parameters:
|
||||
- name: repo_name
|
||||
in: path
|
||||
type: string
|
||||
required: true
|
||||
description: The name of repository which will be deleted.
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
200:
|
||||
description: Delete successfully.
|
||||
400:
|
||||
description: Invalid repo_name.
|
||||
401:
|
||||
description: Unauthorized.
|
||||
404:
|
||||
description: Repository not found.
|
||||
403:
|
||||
description: Forbidden.
|
||||
/repositories/{repo_name}/tags/{tag}/manifest:
|
||||
get:
|
||||
summary: Get manifests of a relevant repository.
|
||||
description: |
|
||||
This endpoint aims to retreive manifests from a relevant repository.
|
||||
parameters:
|
||||
- name: repo_name
|
||||
in: query
|
||||
in: path
|
||||
type: string
|
||||
required: true
|
||||
description: Repository name
|
||||
- name: tag
|
||||
in: query
|
||||
in: path
|
||||
type: string
|
||||
required: true
|
||||
description: Tag name
|
||||
@ -789,7 +813,7 @@ paths:
|
||||
description: Retrieved manifests from a relevant repository not found.
|
||||
500:
|
||||
description: Unexpected internal errors.
|
||||
/repositories/signatures:
|
||||
/repositories/{repo_name}/signatures:
|
||||
get:
|
||||
summary: Get signature information of a repository
|
||||
description: |
|
||||
@ -799,7 +823,7 @@ paths:
|
||||
return an empty list with response code 200, instead of 404
|
||||
parameters:
|
||||
- name: repo_name
|
||||
in: query
|
||||
in: path
|
||||
type: string
|
||||
required: true
|
||||
description: repository name.
|
||||
|
@ -82,12 +82,14 @@ func init() {
|
||||
beego.Router("/api/projects/:id/publicity", &ProjectAPI{}, "put:ToggleProjectPublic")
|
||||
beego.Router("/api/projects/:id([0-9]+)/logs/filter", &ProjectAPI{}, "post:FilterAccessLog")
|
||||
beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &ProjectMemberAPI{}, "get:Get;post:Post;delete:Delete;put:Put")
|
||||
beego.Router("/api/repositories", &RepositoryAPI{})
|
||||
beego.Router("/api/statistics", &StatisticAPI{})
|
||||
beego.Router("/api/users/?:id", &UserAPI{})
|
||||
beego.Router("/api/logs", &LogAPI{})
|
||||
beego.Router("/api/repositories", &RepositoryAPI{})
|
||||
beego.Router("/api/repositories/tags", &RepositoryAPI{}, "get:GetTags")
|
||||
beego.Router("/api/repositories/manifests", &RepositoryAPI{}, "get:GetManifests")
|
||||
beego.Router("/api/repositories/*/tags/?:tag", &RepositoryAPI{}, "delete:Delete")
|
||||
beego.Router("/api/repositories/*/tags", &RepositoryAPI{}, "get:GetTags")
|
||||
beego.Router("/api/repositories/*/tags/:tag/manifest", &RepositoryAPI{}, "get:GetManifests")
|
||||
beego.Router("/api/repositories/*/signatures", &RepositoryAPI{}, "get:GetSignatures")
|
||||
beego.Router("/api/repositories/top", &RepositoryAPI{}, "get:GetTopRepos")
|
||||
beego.Router("/api/targets/", &TargetAPI{}, "get:List")
|
||||
beego.Router("/api/targets/", &TargetAPI{}, "post:Post")
|
||||
@ -505,18 +507,16 @@ func (a testapi) GetReposTags(authInfo usrInfo, repoName,
|
||||
detail string) (int, interface{}, error) {
|
||||
_sling := sling.New().Get(a.basePath)
|
||||
|
||||
path := "/api/repositories/tags"
|
||||
path := fmt.Sprintf("/api/repositories/%s/tags", repoName)
|
||||
|
||||
_sling = _sling.Path(path)
|
||||
|
||||
type QueryParams struct {
|
||||
RepoName string `url:"repo_name"`
|
||||
Detail string `url:"detail"`
|
||||
Detail string `url:"detail"`
|
||||
}
|
||||
|
||||
_sling = _sling.QueryStruct(&QueryParams{
|
||||
RepoName: repoName,
|
||||
Detail: detail,
|
||||
Detail: detail,
|
||||
})
|
||||
httpStatusCode, body, err := request(_sling, jsonAcceptHeader, authInfo)
|
||||
if err != nil {
|
||||
@ -546,16 +546,10 @@ func (a testapi) GetReposTags(authInfo usrInfo, repoName,
|
||||
func (a testapi) GetReposManifests(authInfo usrInfo, repoName string, tag string) (int, error) {
|
||||
_sling := sling.New().Get(a.basePath)
|
||||
|
||||
path := "/api/repositories/manifests"
|
||||
path := fmt.Sprintf("/api/repositories/%s/tags/%s/manifest", repoName, tag)
|
||||
|
||||
_sling = _sling.Path(path)
|
||||
|
||||
type QueryParams struct {
|
||||
RepoName string `url:"repo_name"`
|
||||
Tag string `url:"tag"`
|
||||
}
|
||||
|
||||
_sling = _sling.QueryStruct(&QueryParams{RepoName: repoName, Tag: tag})
|
||||
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
|
||||
return httpStatusCode, err
|
||||
}
|
||||
|
@ -169,10 +169,8 @@ func populateTagsCount(repositories []*models.RepoRecord) ([]*repoResp, error) {
|
||||
|
||||
// Delete ...
|
||||
func (ra *RepositoryAPI) Delete() {
|
||||
repoName := ra.GetString("repo_name")
|
||||
if len(repoName) == 0 {
|
||||
ra.CustomAbort(http.StatusBadRequest, "repo_name is nil")
|
||||
}
|
||||
// using :splat to get * part in path
|
||||
repoName := ra.GetString(":splat")
|
||||
|
||||
projectName, _ := utils.ParseRepository(repoName)
|
||||
project, err := dao.GetProjectByName(projectName)
|
||||
@ -197,7 +195,7 @@ func (ra *RepositoryAPI) Delete() {
|
||||
}
|
||||
|
||||
tags := []string{}
|
||||
tag := ra.GetString("tag")
|
||||
tag := ra.GetString(":tag")
|
||||
if len(tag) == 0 {
|
||||
tagList, err := rc.ListTag()
|
||||
if err != nil {
|
||||
@ -284,12 +282,9 @@ type tag struct {
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
// GetTags handles GET /api/repositories/tags
|
||||
// GetTags returns tags of a repository
|
||||
func (ra *RepositoryAPI) GetTags() {
|
||||
repoName := ra.GetString("repo_name")
|
||||
if len(repoName) == 0 {
|
||||
ra.CustomAbort(http.StatusBadRequest, "repo_name is nil")
|
||||
}
|
||||
repoName := ra.GetString(":splat")
|
||||
detail := ra.GetString("detail") == "1" || ra.GetString("detail") == "true"
|
||||
|
||||
projectName, _ := utils.ParseRepository(repoName)
|
||||
@ -380,14 +375,10 @@ func listTag(client *registry.Repository) ([]string, error) {
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
// GetManifests handles GET /api/repositories/manifests
|
||||
// GetManifests returns the manifest of a tag
|
||||
func (ra *RepositoryAPI) GetManifests() {
|
||||
repoName := ra.GetString("repo_name")
|
||||
tag := ra.GetString("tag")
|
||||
|
||||
if len(repoName) == 0 || len(tag) == 0 {
|
||||
ra.CustomAbort(http.StatusBadRequest, "repo_name or tag is nil")
|
||||
}
|
||||
repoName := ra.GetString(":splat")
|
||||
tag := ra.GetString(":tag")
|
||||
|
||||
version := ra.GetString("version")
|
||||
if len(version) == 0 {
|
||||
@ -535,7 +526,7 @@ func (ra *RepositoryAPI) getUsername() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
//GetTopRepos handles request GET /api/repositories/top
|
||||
//GetTopRepos returns the most populor repositories
|
||||
func (ra *RepositoryAPI) GetTopRepos() {
|
||||
count, err := ra.GetInt("count", 10)
|
||||
if err != nil || count <= 0 {
|
||||
@ -579,7 +570,7 @@ func (ra *RepositoryAPI) GetTopRepos() {
|
||||
ra.ServeJSON()
|
||||
}
|
||||
|
||||
//GetSignatures handles request GET /api/repositories/signatures
|
||||
//GetSignatures returns signatures of a repository
|
||||
func (ra *RepositoryAPI) GetSignatures() {
|
||||
//use this func to init session.
|
||||
ra.GetUserIDForRequest()
|
||||
@ -587,10 +578,8 @@ func (ra *RepositoryAPI) GetSignatures() {
|
||||
if err != nil {
|
||||
log.Warningf("Error when getting username: %v", err)
|
||||
}
|
||||
repoName := ra.GetString("repo_name")
|
||||
if len(repoName) == 0 {
|
||||
ra.CustomAbort(http.StatusBadRequest, "repo_name is nil")
|
||||
}
|
||||
repoName := ra.GetString(":splat")
|
||||
|
||||
targets, err := getNotaryTargets(username, repoName)
|
||||
if err != nil {
|
||||
log.Errorf("Error while fetching signature from notary: %v", err)
|
||||
|
@ -32,20 +32,10 @@ func TestGetRepos(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------case 2 : response code = 400------------------------//
|
||||
fmt.Println("case 2 : response code = 400,invalid project_id")
|
||||
projectID = "ccc"
|
||||
httpStatusCode, _, err := apiTest.GetRepos(*admin, projectID, keyword, detail)
|
||||
if err != nil {
|
||||
t.Error("Error whihle get repos by projectID", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(400), httpStatusCode, "httpStatusCode should be 400")
|
||||
}
|
||||
//-------------------case 3 : response code = 404------------------------//
|
||||
fmt.Println("case 3 : response code = 404:project not found")
|
||||
//-------------------case 2 : response code = 404------------------------//
|
||||
fmt.Println("case 2 : response code = 404:project not found")
|
||||
projectID = "111"
|
||||
httpStatusCode, _, err = apiTest.GetRepos(*admin, projectID, keyword, detail)
|
||||
httpStatusCode, _, err := apiTest.GetRepos(*admin, projectID, keyword, detail)
|
||||
if err != nil {
|
||||
t.Error("Error whihle get repos by projectID", err.Error())
|
||||
t.Log(err)
|
||||
@ -53,8 +43,8 @@ func TestGetRepos(t *testing.T) {
|
||||
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
|
||||
}
|
||||
|
||||
//-------------------case 4 : response code = 200------------------------//
|
||||
fmt.Println("case 4 : response code = 200")
|
||||
//-------------------case 3 : response code = 200------------------------//
|
||||
fmt.Println("case 3 : response code = 200")
|
||||
projectID = "1"
|
||||
detail = "false"
|
||||
code, repositories, err = apiTest.GetRepos(*admin, projectID, keyword, detail)
|
||||
@ -70,6 +60,17 @@ func TestGetRepos(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------case 4 : response code = 400------------------------//
|
||||
fmt.Println("case 4 : response code = 400,invalid project_id")
|
||||
projectID = "ccc"
|
||||
httpStatusCode, _, err = apiTest.GetRepos(*admin, projectID, keyword, detail)
|
||||
if err != nil {
|
||||
t.Error("Error whihle get repos by projectID", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(400), httpStatusCode, "httpStatusCode should be 400")
|
||||
}
|
||||
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
@ -78,31 +79,18 @@ func TestGetReposTags(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
apiTest := newHarborAPI()
|
||||
|
||||
repository := ""
|
||||
//-------------------case 1 : response code = 404------------------------//
|
||||
fmt.Println("case 1 : response code = 404,repo not found")
|
||||
repository := "errorRepos"
|
||||
detail := "false"
|
||||
|
||||
fmt.Println("Testing ReposTags Get API")
|
||||
//-------------------case 1 : response code = 400------------------------//
|
||||
fmt.Println("case 1 : response code = 400,repo_name is nil")
|
||||
|
||||
code, _, err := apiTest.GetReposTags(*admin, repository, detail)
|
||||
if err != nil {
|
||||
t.Errorf("failed to get tags of repository %s: %v", repository, err)
|
||||
} else {
|
||||
assert.Equal(int(400), code, "httpStatusCode should be 400")
|
||||
}
|
||||
|
||||
//-------------------case 2 : response code = 404------------------------//
|
||||
fmt.Println("case 2 : response code = 404,repo not found")
|
||||
repository = "errorRepos"
|
||||
code, _, err = apiTest.GetReposTags(*admin, repository, detail)
|
||||
if err != nil {
|
||||
t.Errorf("failed to get tags of repository %s: %v", repository, err)
|
||||
} else {
|
||||
assert.Equal(int(404), code, "httpStatusCode should be 404")
|
||||
}
|
||||
//-------------------case 3 : response code = 200------------------------//
|
||||
fmt.Println("case 3 : response code = 200")
|
||||
//-------------------case 2 : response code = 200------------------------//
|
||||
fmt.Println("case 2 : response code = 200")
|
||||
repository = "library/hello-world"
|
||||
code, tags, err := apiTest.GetReposTags(*admin, repository, detail)
|
||||
if err != nil {
|
||||
@ -117,8 +105,8 @@ func TestGetReposTags(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------case 4 : response code = 200------------------------//
|
||||
fmt.Println("case 4 : response code = 200")
|
||||
//-------------------case 3 : response code = 200------------------------//
|
||||
fmt.Println("case 3 : response code = 200")
|
||||
repository = "library/hello-world"
|
||||
detail = "true"
|
||||
code, tags, err = apiTest.GetReposTags(*admin, repository, detail)
|
||||
@ -169,18 +157,8 @@ func TestGetReposManifests(t *testing.T) {
|
||||
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
|
||||
}
|
||||
|
||||
//-------------------case 3 : response code = 400------------------------//
|
||||
fmt.Println("case 3 : response code = 400,repo_name or is nil")
|
||||
repoName = ""
|
||||
httpStatusCode, err = apiTest.GetReposManifests(*admin, repoName, tag)
|
||||
if err != nil {
|
||||
t.Error("Error whihle get reposManifests by repoName and tag", err.Error())
|
||||
t.Log(err)
|
||||
} else {
|
||||
assert.Equal(int(400), httpStatusCode, "httpStatusCode should be 400")
|
||||
}
|
||||
//-------------------case 4 : response code = 404------------------------//
|
||||
fmt.Println("case 4 : response code = 404,repo not found")
|
||||
//-------------------case 3 : response code = 404------------------------//
|
||||
fmt.Println("case 3 : response code = 404,repo not found")
|
||||
repoName = "111"
|
||||
httpStatusCode, err = apiTest.GetReposManifests(*admin, repoName, tag)
|
||||
if err != nil {
|
||||
|
@ -63,17 +63,18 @@ func initRouters() {
|
||||
beego.Router("/api/search", &api.SearchAPI{})
|
||||
beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &api.ProjectMemberAPI{})
|
||||
beego.Router("/api/projects/", &api.ProjectAPI{}, "get:List;post:Post;head:Head")
|
||||
beego.Router("/api/projects/:id", &api.ProjectAPI{})
|
||||
beego.Router("/api/projects/:id/publicity", &api.ProjectAPI{}, "put:ToggleProjectPublic")
|
||||
beego.Router("/api/statistics", &api.StatisticAPI{})
|
||||
beego.Router("/api/projects/:id([0-9]+)", &api.ProjectAPI{})
|
||||
beego.Router("/api/projects/:id([0-9]+)/publicity", &api.ProjectAPI{}, "put:ToggleProjectPublic")
|
||||
beego.Router("/api/projects/:id([0-9]+)/logs/filter", &api.ProjectAPI{}, "post:FilterAccessLog")
|
||||
beego.Router("/api/statistics", &api.StatisticAPI{})
|
||||
beego.Router("/api/users/?:id", &api.UserAPI{})
|
||||
beego.Router("/api/users/:id([0-9]+)/password", &api.UserAPI{}, "put:ChangePassword")
|
||||
beego.Router("/api/internal/syncregistry", &api.InternalAPI{}, "post:SyncRegistry")
|
||||
beego.Router("/api/repositories", &api.RepositoryAPI{})
|
||||
beego.Router("/api/repositories/tags", &api.RepositoryAPI{}, "get:GetTags")
|
||||
beego.Router("/api/repositories/manifests", &api.RepositoryAPI{}, "get:GetManifests")
|
||||
beego.Router("/api/repositories/signatures", &api.RepositoryAPI{}, "get:GetSignatures")
|
||||
beego.Router("/api/repositories/*/tags/?:tag", &api.RepositoryAPI{}, "delete:Delete")
|
||||
beego.Router("/api/repositories/*/tags", &api.RepositoryAPI{}, "get:GetTags")
|
||||
beego.Router("/api/repositories/*/tags/:tag/manifest", &api.RepositoryAPI{}, "get:GetManifests")
|
||||
beego.Router("/api/repositories/*/signatures", &api.RepositoryAPI{}, "get:GetSignatures")
|
||||
beego.Router("/api/jobs/replication/", &api.RepJobAPI{}, "get:List")
|
||||
beego.Router("/api/jobs/replication/:id([0-9]+)", &api.RepJobAPI{})
|
||||
beego.Router("/api/jobs/replication/:id([0-9]+)/log", &api.RepJobAPI{}, "get:GetLog")
|
||||
|
@ -27,14 +27,14 @@ export class RepositoryService {
|
||||
|
||||
listTags(repoName: string): Observable<Tag[]> {
|
||||
return this.http
|
||||
.get(`/api/repositories/tags?repo_name=${repoName}&detail=1`)
|
||||
.get(`/api/repositories/${repoName}/tags?detail=1`)
|
||||
.map(response=>response.json())
|
||||
.catch(error=>Observable.throw(error));
|
||||
}
|
||||
|
||||
listNotarySignatures(repoName: string): Observable<VerifiedSignature[]> {
|
||||
return this.http
|
||||
.get(`/api/repositories/signatures?repo_name=${repoName}`)
|
||||
.get(`/api/repositories/${repoName}/signatures`)
|
||||
.map(response=>response.json())
|
||||
.catch(error=>Observable.throw(error));
|
||||
}
|
||||
@ -64,7 +64,7 @@ export class RepositoryService {
|
||||
deleteRepository(repoName: string): Observable<any> {
|
||||
console.log('Delete repository with repo name:' + repoName);
|
||||
return this.http
|
||||
.delete(`/api/repositories?repo_name=${repoName}`)
|
||||
.delete(`/api/repositories/${repoName}/tags`)
|
||||
.map(response=>response.status)
|
||||
.catch(error=>Observable.throw(error));
|
||||
}
|
||||
@ -72,7 +72,7 @@ export class RepositoryService {
|
||||
deleteRepoByTag(repoName: string, tag: string): Observable<any> {
|
||||
console.log('Delete repository with repo name:' + repoName + ', tag:' + tag);
|
||||
return this.http
|
||||
.delete(`/api/repositories?repo_name=${repoName}&tag=${tag}`)
|
||||
.delete(`/api/repositories/${repoName}/tags/${tag}`)
|
||||
.map(response=>response.status)
|
||||
.catch(error=>Observable.throw(error));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user