Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
kunw 2016-09-14 11:09:58 +08:00
commit 9a5071ddf5
8 changed files with 1708 additions and 1444 deletions

View File

@ -17,6 +17,7 @@ LDAP_FILTER=$ldap_filter
LDAP_UID=$ldap_uid
LDAP_SCOPE=$ldap_scope
UI_SECRET=$ui_secret
SECRET_KEY=$secret_key
SELF_REGISTRATION=$self_registration
USE_COMPRESSED_JS=$use_compressed_js
LOG_LEVEL=debug

2678
LICENSE

File diff suppressed because it is too large Load Diff

21
NOTICE
View File

@ -1,11 +1,10 @@
Harbor 0.1.0 Beta
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
You may not use this product except in compliance with the License.
This product may include a number of subcomponents with
separate copyright notices and license terms. Your use of the source
code for the these subcomponents is subject to the terms and
conditions of the subcomponent's license, as noted in the LICENSE file.
NOTICE
Harbor version 0.4.0 Beta
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
This product is licensed to you under the Apache License, Version 2.0 (the "License"). You may not use this product except in compliance with the License.
This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.

View File

@ -79,6 +79,11 @@ func init() {
beego.Router("/api/repositories/tags", &RepositoryAPI{}, "get:GetTags")
beego.Router("/api/repositories/manifests", &RepositoryAPI{}, "get:GetManifests")
beego.Router("/api/repositories/top", &RepositoryAPI{}, "get:GetTopRepos")
beego.Router("/api/targets/", &TargetAPI{}, "get:List")
beego.Router("/api/targets/", &TargetAPI{}, "post:Post")
beego.Router("/api/targets/:id([0-9]+)", &TargetAPI{})
beego.Router("/api/targets/:id([0-9]+)/policies/", &TargetAPI{}, "get:ListPolicies")
beego.Router("/api/targets/ping", &TargetAPI{}, "post:Ping")
_ = updateInitPassword(1, "Harbor12345")
@ -502,6 +507,102 @@ func (a api) GetReposTop(authInfo usrInfo, count string) (int, error) {
return httpStatusCode, err
}
//-------------------------Targets Test---------------------------------------//
//Create a new replication target
func (a api) AddTargets(authInfo usrInfo, repTarget apilib.RepTargetPost) (int, error) {
_sling := sling.New().Post(a.basePath)
path := "/api/targets"
_sling = _sling.Path(path)
_sling = _sling.BodyJSON(repTarget)
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err
}
//List filters targets by name
func (a api) ListTargets(authInfo usrInfo, targetName string) (int, []apilib.RepTarget, error) {
_sling := sling.New().Get(a.basePath)
path := "/api/targets?name=" + targetName
_sling = _sling.Path(path)
var successPayload []apilib.RepTarget
httpStatusCode, body, err := request(_sling, jsonAcceptHeader, authInfo)
if err == nil && httpStatusCode == 200 {
err = json.Unmarshal(body, &successPayload)
}
return httpStatusCode, successPayload, err
}
//Ping target by targetID
func (a api) PingTargetsByID(authInfo usrInfo, targetID string) (int, error) {
_sling := sling.New().Post(a.basePath)
path := "/api/targets/ping?id=" + targetID
_sling = _sling.Path(path)
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err
}
//Get target by targetID
func (a api) GetTargetByID(authInfo usrInfo, targetID string) (int, error) {
_sling := sling.New().Get(a.basePath)
path := "/api/targets/" + targetID
_sling = _sling.Path(path)
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err
}
//Update target by targetID
func (a api) PutTargetByID(authInfo usrInfo, targetID string, repTarget apilib.RepTargetPost) (int, error) {
_sling := sling.New().Put(a.basePath)
path := "/api/targets/" + targetID
_sling = _sling.Path(path)
_sling = _sling.BodyJSON(repTarget)
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err
}
//List the target relevant policies by targetID
func (a api) GetTargetPoliciesByID(authInfo usrInfo, targetID string) (int, error) {
_sling := sling.New().Get(a.basePath)
path := "/api/targets/" + targetID + "/policies/"
_sling = _sling.Path(path)
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err
}
//Delete target by targetID
func (a api) DeleteTargetsByID(authInfo usrInfo, targetID string) (int, error) {
_sling := sling.New().Delete(a.basePath)
path := "/api/targets/" + targetID
_sling = _sling.Path(path)
httpStatusCode, _, err := request(_sling, jsonAcceptHeader, authInfo)
return httpStatusCode, err
}
//Return projects created by Harbor
//func (a HarborApi) ProjectsGet (projectName string, isPublic int32) ([]Project, error) {
// }

View File

@ -165,13 +165,15 @@ func (ra *RepositoryAPI) Delete() {
for _, t := range tags {
if err := rc.DeleteTag(t); err != nil {
if regErr, ok := err.(*registry_error.Error); ok {
ra.CustomAbort(regErr.StatusCode, regErr.Detail)
if regErr.StatusCode != http.StatusNotFound {
ra.CustomAbort(regErr.StatusCode, regErr.Detail)
}
} else {
log.Errorf("error occurred while deleting tag %s:%s: %v", repoName, t, err)
ra.CustomAbort(http.StatusInternalServerError, "internal error")
}
log.Errorf("error occurred while deleting tags of %s: %v", repoName, err)
ra.CustomAbort(http.StatusInternalServerError, "internal error")
}
log.Infof("delete tag: %s %s", repoName, t)
log.Infof("delete tag: %s:%s", repoName, t)
go TriggerReplicationByRepository(repoName, []string{t}, models.RepOpDelete)
go func(tag string) {

View File

@ -22,6 +22,7 @@ import (
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/service/cache"
"github.com/vmware/harbor/utils"
"github.com/vmware/harbor/utils/log"
)
@ -84,17 +85,12 @@ func (s *SearchAPI) Get() {
}
}
repos, err := dao.GetAllRepositories()
repositories, err := cache.GetRepoFromCache()
if err != nil {
log.Errorf("failed to list repositories: %v", err)
s.CustomAbort(http.StatusInternalServerError, "")
}
repositories := []string{}
for _, repo := range repos {
repositories = append(repositories, repo.Name)
}
sort.Strings(repositories)
repositoryResult := filterRepositories(repositories, projects, keyword)
result := &searchResult{Project: projectResult, Repository: repositoryResult}

274
api/target_test.go Normal file
View File

@ -0,0 +1,274 @@
package api
import (
"fmt"
"os"
"strconv"
"testing"
"github.com/stretchr/testify/assert"
"github.com/vmware/harbor/tests/apitests/apilib"
)
const (
addTargetName = "testTargets"
)
var addTargetID int
func TestTargetsPost(t *testing.T) {
var httpStatusCode int
var err error
assert := assert.New(t)
apiTest := newHarborAPI()
endPoint := os.Getenv("REGISTRY_URL")
repTargets := &apilib.RepTargetPost{endPoint, addTargetName, adminName, adminPwd}
fmt.Println("Testing Targets Post API")
//-------------------case 1 : response code = 201------------------------//
fmt.Println("case 1 : response code = 201")
httpStatusCode, err = apiTest.AddTargets(*admin, *repTargets)
if err != nil {
t.Error("Error whihle add targets", err.Error())
t.Log(err)
} else {
assert.Equal(int(201), httpStatusCode, "httpStatusCode should be 201")
}
//-----------case 2 : response code = 409,name is already used-----------//
fmt.Println("case 2 : response code = 409,name is already used")
httpStatusCode, err = apiTest.AddTargets(*admin, *repTargets)
if err != nil {
t.Error("Error whihle add targets", err.Error())
t.Log(err)
} else {
assert.Equal(int(409), httpStatusCode, "httpStatusCode should be 409")
}
//-----------case 3 : response code = 409,name is already used-----------//
fmt.Println("case 3 : response code = 409,endPoint is already used")
repTargets.Username = "errName"
httpStatusCode, err = apiTest.AddTargets(*admin, *repTargets)
if err != nil {
t.Error("Error whihle add targets", err.Error())
t.Log(err)
} else {
assert.Equal(int(409), httpStatusCode, "httpStatusCode should be 409")
}
//--------case 4 : response code = 401,User need to log in first.--------//
fmt.Println("case 4 : response code = 401,User need to log in first.")
httpStatusCode, err = apiTest.AddTargets(*unknownUsr, *repTargets)
if err != nil {
t.Error("Error whihle add targets", err.Error())
t.Log(err)
} else {
assert.Equal(int(401), httpStatusCode, "httpStatusCode should be 401")
}
fmt.Printf("\n")
}
func TestTargetsGet(t *testing.T) {
var httpStatusCode int
var err error
var reslut []apilib.RepTarget
assert := assert.New(t)
apiTest := newHarborAPI()
fmt.Println("Testing Targets Get API")
//-------------------case 1 : response code = 200------------------------//
fmt.Println("case 1 : response code = 200")
httpStatusCode, reslut, err = apiTest.ListTargets(*admin, addTargetName)
if err != nil {
t.Error("Error whihle get targets", err.Error())
t.Log(err)
} else {
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
addTargetID = int(reslut[0].Id)
}
}
func TestTargetPing(t *testing.T) {
var httpStatusCode int
var err error
assert := assert.New(t)
apiTest := newHarborAPI()
fmt.Println("Testing Targets Ping Post API")
//-------------------case 1 : response code = 200------------------------//
fmt.Println("case 1 : response code = 200")
id := strconv.Itoa(addTargetID)
httpStatusCode, err = apiTest.PingTargetsByID(*admin, id)
if err != nil {
t.Error("Error whihle ping target", err.Error())
t.Log(err)
} else {
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
}
//--------------case 2 : response code = 404,target not found------------//
fmt.Println("case 2 : response code = 404,target not found")
id = "1111"
httpStatusCode, err = apiTest.PingTargetsByID(*admin, id)
if err != nil {
t.Error("Error whihle ping target", err.Error())
t.Log(err)
} else {
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
}
//------------case 3 : response code = 400,targetID is invalid-----------//
fmt.Println("case 2 : response code = 400,target not found")
id = "cc"
httpStatusCode, err = apiTest.PingTargetsByID(*admin, id)
if err != nil {
t.Error("Error whihle ping target", err.Error())
t.Log(err)
} else {
assert.Equal(int(400), httpStatusCode, "httpStatusCode should be 400")
}
}
func TestTargetGetByID(t *testing.T) {
var httpStatusCode int
var err error
assert := assert.New(t)
apiTest := newHarborAPI()
fmt.Println("Testing Targets Get API by Id")
//-------------------case 1 : response code = 200------------------------//
fmt.Println("case 1 : response code = 200")
id := strconv.Itoa(addTargetID)
httpStatusCode, err = apiTest.GetTargetByID(*admin, id)
if err != nil {
t.Error("Error whihle get target by id", err.Error())
t.Log(err)
} else {
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
}
//--------------case 2 : response code = 404,target not found------------//
fmt.Println("case 2 : response code = 404,target not found")
id = "1111"
httpStatusCode, err = apiTest.GetTargetByID(*admin, id)
if err != nil {
t.Error("Error whihle get target by id", err.Error())
t.Log(err)
} else {
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
}
}
func TestTargetsPut(t *testing.T) {
var httpStatusCode int
var err error
assert := assert.New(t)
apiTest := newHarborAPI()
endPoint := "1.1.1.1"
updateRepTargets := &apilib.RepTargetPost{endPoint, addTargetName, adminName, adminPwd}
id := strconv.Itoa(addTargetID)
fmt.Println("Testing Target Put API")
//-------------------case 1 : response code = 200------------------------//
fmt.Println("case 1 : response code = 200")
httpStatusCode, err = apiTest.PutTargetByID(*admin, id, *updateRepTargets)
if err != nil {
t.Error("Error whihle update target", err.Error())
t.Log(err)
} else {
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
}
//--------------case 2 : response code = 404,target not found------------//
id = "111"
fmt.Println("case 2 : response code = 404,target not found")
httpStatusCode, err = apiTest.PutTargetByID(*admin, id, *updateRepTargets)
if err != nil {
t.Error("Error whihle update target", err.Error())
t.Log(err)
} else {
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
}
}
func TestTargetGetPolicies(t *testing.T) {
var httpStatusCode int
var err error
assert := assert.New(t)
apiTest := newHarborAPI()
fmt.Println("Testing Targets Get API to list policies")
//-------------------case 1 : response code = 200------------------------//
fmt.Println("case 1 : response code = 200")
id := strconv.Itoa(addTargetID)
httpStatusCode, err = apiTest.GetTargetPoliciesByID(*admin, id)
if err != nil {
t.Error("Error whihle get target by id", err.Error())
t.Log(err)
} else {
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
}
//--------------case 2 : response code = 404,target not found------------//
fmt.Println("case 2 : response code = 404,target not found")
id = "1111"
httpStatusCode, err = apiTest.GetTargetPoliciesByID(*admin, id)
if err != nil {
t.Error("Error whihle get target by id", err.Error())
t.Log(err)
} else {
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
}
}
func TestTargetsDelete(t *testing.T) {
var httpStatusCode int
var err error
assert := assert.New(t)
apiTest := newHarborAPI()
id := strconv.Itoa(addTargetID)
fmt.Println("Testing Targets Delete API")
//-------------------case 1 : response code = 200------------------------//
fmt.Println("case 1 : response code = 200")
httpStatusCode, err = apiTest.DeleteTargetsByID(*admin, id)
if err != nil {
t.Error("Error whihle delete targets", err.Error())
t.Log(err)
} else {
assert.Equal(int(200), httpStatusCode, "httpStatusCode should be 200")
}
//--------------case 2 : response code = 404,target not found------------//
fmt.Println("case 2 : response code = 404,target not found")
id = "1111"
httpStatusCode, err = apiTest.DeleteTargetsByID(*admin, id)
if err != nil {
t.Error("Error whihle delete targets", err.Error())
t.Log(err)
} else {
assert.Equal(int(404), httpStatusCode, "httpStatusCode should be 404")
}
}

View File

@ -16,9 +16,9 @@
package cache
import (
"os"
"time"
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/utils/log"
"github.com/vmware/harbor/utils/registry"
"github.com/vmware/harbor/utils/registry/auth"
@ -28,9 +28,7 @@ import (
var (
// Cache is the global cache in system.
Cache cache.Cache
endpoint string
username string
Cache cache.Cache
)
const catalogKey string = "catalog"
@ -41,52 +39,17 @@ func init() {
if err != nil {
log.Errorf("Failed to initialize cache, error:%v", err)
}
endpoint = os.Getenv("REGISTRY_URL")
username = "admin"
}
// RefreshCatalogCache calls registry's API to get repository list and write it to cache.
func RefreshCatalogCache() error {
log.Debug("refreshing catalog cache...")
registryClient, err := NewRegistryClient(endpoint, true, username,
"registry", "catalog", "*")
repos, err := getAllRepositories()
if err != nil {
return err
}
rs, err := registryClient.Catalog()
if err != nil {
return err
}
/*
repos := []string{}
for _, repo := range rs {
rc, ok := repositoryClients[repo]
if !ok {
rc, err = registry.NewRepositoryWithUsername(repo, endpoint, username)
if err != nil {
log.Errorf("error occurred while initializing repository client used by cache: %s %v", repo, err)
continue
}
repositoryClients[repo] = rc
}
tags, err := rc.ListTag()
if err != nil {
log.Errorf("error occurred while list tag for %s: %v", repo, err)
continue
}
if len(tags) != 0 {
repos = append(repos, repo)
log.Debugf("add %s to catalog cache", repo)
}
}
*/
Cache.Put(catalogKey, rs, 600*time.Second)
Cache.Put(catalogKey, repos, 600*time.Second)
return nil
}
@ -108,6 +71,18 @@ func GetRepoFromCache() ([]string, error) {
return result.([]string), nil
}
func getAllRepositories() ([]string, error) {
var repos []string
rs, err := dao.GetAllRepositories()
if err != nil {
return repos, err
}
for _, e := range rs {
repos = append(repos, e.Name)
}
return repos, nil
}
// NewRegistryClient ...
func NewRegistryClient(endpoint string, insecure bool, username, scopeType, scopeName string,
scopeActions ...string) (*registry.Registry, error) {