Merge pull request #1710 from ywk253100/170321_url

Refactor API URL.
This commit is contained in:
Wenkai Yin 2017-03-27 13:26:32 +08:00 committed by GitHub
commit 4cc2115a23
6 changed files with 94 additions and 108 deletions

View File

@ -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.

View File

@ -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
}

View File

@ -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)

View File

@ -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 {

View File

@ -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")

View File

@ -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));
}