mirror of
https://github.com/goharbor/harbor
synced 2025-04-18 19:24:00 +00:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
9a5071ddf5
|
@ -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
|
||||
|
|
21
NOTICE
21
NOTICE
|
@ -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.
|
||||
|
||||
|
|
|
@ -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) {
|
||||
// }
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
274
api/target_test.go
Normal 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")
|
||||
}
|
||||
|
||||
}
|
57
service/cache/cache.go
vendored
57
service/cache/cache.go
vendored
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user