mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-03 14:37:44 +01:00
add internal reg request handler chain
this is for internal registry api call, the request should be intercpeted by quota middlerwares, like retag and delete. Note: The api developer has to know that if the internal registry call in your api, please consider to use NewRepositoryClientForLocal() to init the repository client, which can handle quota change. Signed-off-by: wang yan <wangyan@vmware.com>
This commit is contained in:
parent
dcc79ca2a4
commit
4410cc93f9
@ -31,6 +31,7 @@ CLAIR_DB_USERNAME={{clair_db_username}}
|
|||||||
CLAIR_DB={{clair_db_name}}
|
CLAIR_DB={{clair_db_name}}
|
||||||
CLAIR_DB_SSLMODE={{clair_db_sslmode}}
|
CLAIR_DB_SSLMODE={{clair_db_sslmode}}
|
||||||
CORE_URL={{core_url}}
|
CORE_URL={{core_url}}
|
||||||
|
CORE_LOCAL_URL={{core_local_url}}
|
||||||
JOBSERVICE_URL={{jobservice_url}}
|
JOBSERVICE_URL={{jobservice_url}}
|
||||||
CLAIR_URL={{clair_url}}
|
CLAIR_URL={{clair_url}}
|
||||||
NOTARY_URL={{notary_url}}
|
NOTARY_URL={{notary_url}}
|
||||||
|
@ -67,6 +67,7 @@ def parse_yaml_config(config_file_path):
|
|||||||
'registry_url': "http://registry:5000",
|
'registry_url': "http://registry:5000",
|
||||||
'registry_controller_url': "http://registryctl:8080",
|
'registry_controller_url': "http://registryctl:8080",
|
||||||
'core_url': "http://core:8080",
|
'core_url': "http://core:8080",
|
||||||
|
'core_local_url': "http://127.0.0.1:8080",
|
||||||
'token_service_url': "http://core:8080/service/token",
|
'token_service_url': "http://core:8080/service/token",
|
||||||
'jobservice_url': 'http://jobservice:8080',
|
'jobservice_url': 'http://jobservice:8080',
|
||||||
'clair_url': 'http://clair:6060',
|
'clair_url': 'http://clair:6060',
|
||||||
|
@ -75,6 +75,7 @@ var (
|
|||||||
{Name: common.ClairURL, Scope: SystemScope, Group: ClairGroup, EnvKey: "CLAIR_URL", DefaultValue: "http://clair:6060", ItemType: &StringType{}, Editable: false},
|
{Name: common.ClairURL, Scope: SystemScope, Group: ClairGroup, EnvKey: "CLAIR_URL", DefaultValue: "http://clair:6060", ItemType: &StringType{}, Editable: false},
|
||||||
|
|
||||||
{Name: common.CoreURL, Scope: SystemScope, Group: BasicGroup, EnvKey: "CORE_URL", DefaultValue: "http://core:8080", ItemType: &StringType{}, Editable: false},
|
{Name: common.CoreURL, Scope: SystemScope, Group: BasicGroup, EnvKey: "CORE_URL", DefaultValue: "http://core:8080", ItemType: &StringType{}, Editable: false},
|
||||||
|
{Name: common.CoreLocalURL, Scope: SystemScope, Group: BasicGroup, EnvKey: "CORE_LOCAL_URL", DefaultValue: "http://127.0.0.1:8080", ItemType: &StringType{}, Editable: false},
|
||||||
{Name: common.DatabaseType, Scope: SystemScope, Group: BasicGroup, EnvKey: "DATABASE_TYPE", DefaultValue: "postgresql", ItemType: &StringType{}, Editable: false},
|
{Name: common.DatabaseType, Scope: SystemScope, Group: BasicGroup, EnvKey: "DATABASE_TYPE", DefaultValue: "postgresql", ItemType: &StringType{}, Editable: false},
|
||||||
|
|
||||||
{Name: common.EmailFrom, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_FROM", DefaultValue: "admin <sample_admin@mydomain.com>", ItemType: &StringType{}, Editable: false},
|
{Name: common.EmailFrom, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_FROM", DefaultValue: "admin <sample_admin@mydomain.com>", ItemType: &StringType{}, Editable: false},
|
||||||
|
@ -55,6 +55,7 @@ const (
|
|||||||
PostGreSQLSSLMode = "postgresql_sslmode"
|
PostGreSQLSSLMode = "postgresql_sslmode"
|
||||||
SelfRegistration = "self_registration"
|
SelfRegistration = "self_registration"
|
||||||
CoreURL = "core_url"
|
CoreURL = "core_url"
|
||||||
|
CoreLocalURL = "core_local_url"
|
||||||
JobServiceURL = "jobservice_url"
|
JobServiceURL = "jobservice_url"
|
||||||
LDAPURL = "ldap_url"
|
LDAPURL = "ldap_url"
|
||||||
LDAPSearchDN = "ldap_search_dn"
|
LDAPSearchDN = "ldap_search_dn"
|
||||||
|
@ -238,7 +238,7 @@ func (ra *RepositoryAPI) Delete() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rc, err := coreutils.NewRepositoryClientForUI(ra.SecurityCtx.GetUsername(), repoName)
|
rc, err := coreutils.NewRepositoryClientForLocal(ra.SecurityCtx.GetUsername(), repoName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err)
|
log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err)
|
||||||
ra.SendInternalServerError(errors.New("internal error"))
|
ra.SendInternalServerError(errors.New("internal error"))
|
||||||
|
@ -280,7 +280,11 @@ func InternalJobServiceURL() string {
|
|||||||
// InternalCoreURL returns the local harbor core url
|
// InternalCoreURL returns the local harbor core url
|
||||||
func InternalCoreURL() string {
|
func InternalCoreURL() string {
|
||||||
return strings.TrimSuffix(cfgMgr.Get(common.CoreURL).GetString(), "/")
|
return strings.TrimSuffix(cfgMgr.Get(common.CoreURL).GetString(), "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocalCoreURL returns the local harbor core url
|
||||||
|
func LocalCoreURL() string {
|
||||||
|
return cfgMgr.Get(common.CoreLocalURL).GetString()
|
||||||
}
|
}
|
||||||
|
|
||||||
// InternalTokenServiceEndpoint returns token service endpoint for internal communication between Harbor containers
|
// InternalTokenServiceEndpoint returns token service endpoint for internal communication between Harbor containers
|
||||||
|
@ -208,6 +208,9 @@ func TestConfig(t *testing.T) {
|
|||||||
assert.Equal("http://myjob:8888", InternalJobServiceURL())
|
assert.Equal("http://myjob:8888", InternalJobServiceURL())
|
||||||
assert.Equal("http://myui:8888/service/token", InternalTokenServiceEndpoint())
|
assert.Equal("http://myui:8888/service/token", InternalTokenServiceEndpoint())
|
||||||
|
|
||||||
|
localCoreURL := LocalCoreURL()
|
||||||
|
assert.Equal("http://127.0.0.1:8080", localCoreURL)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func currPath() string {
|
func currPath() string {
|
||||||
|
@ -28,3 +28,6 @@ const (
|
|||||||
|
|
||||||
// Middlewares with sequential organization
|
// Middlewares with sequential organization
|
||||||
var Middlewares = []string{READONLY, URL, MUITIPLEMANIFEST, LISTREPO, CONTENTTRUST, VULNERABLE, SIZEQUOTA, COUNTQUOTA}
|
var Middlewares = []string{READONLY, URL, MUITIPLEMANIFEST, LISTREPO, CONTENTTRUST, VULNERABLE, SIZEQUOTA, COUNTQUOTA}
|
||||||
|
|
||||||
|
// MiddlewaresLocal ...
|
||||||
|
var MiddlewaresLocal = []string{SIZEQUOTA, COUNTQUOTA}
|
||||||
|
@ -16,26 +16,42 @@ package middlewares
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
|
"github.com/goharbor/harbor/src/core/filter"
|
||||||
"github.com/goharbor/harbor/src/core/middlewares/registryproxy"
|
"github.com/goharbor/harbor/src/core/middlewares/registryproxy"
|
||||||
"github.com/goharbor/harbor/src/core/middlewares/util"
|
"github.com/goharbor/harbor/src/core/middlewares/util"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
var head http.Handler
|
var head http.Handler
|
||||||
|
var proxy http.Handler
|
||||||
|
|
||||||
// Init initialize the Proxy instance and handler chain.
|
// Init initialize the Proxy instance and handler chain.
|
||||||
func Init() error {
|
func Init() error {
|
||||||
ph := registryproxy.New()
|
proxy = registryproxy.New()
|
||||||
if ph == nil {
|
if proxy == nil {
|
||||||
return errors.New("get nil when to create proxy")
|
return errors.New("get nil when to create proxy")
|
||||||
}
|
}
|
||||||
handlerChain := New(Middlewares).Create()
|
|
||||||
head = handlerChain.Then(ph)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle handles the request.
|
// Handle handles the request.
|
||||||
func Handle(rw http.ResponseWriter, req *http.Request) {
|
func Handle(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
securityCtx, err := filter.GetSecurityContext(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get security context in middlerware: %v", err)
|
||||||
|
// error to get security context, use the default chain.
|
||||||
|
head = New(Middlewares).Create().Then(proxy)
|
||||||
|
} else {
|
||||||
|
// true: the request is from 127.0.0.1, only quota middlewares are applied to request
|
||||||
|
// false: the request is from outside, all of middlewares are applied to the request.
|
||||||
|
if securityCtx.IsSolutionUser() {
|
||||||
|
head = New(MiddlewaresLocal).Create().Then(proxy)
|
||||||
|
} else {
|
||||||
|
head = New(Middlewares).Create().Then(proxy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
customResW := util.NewCustomResponseWriter(rw)
|
customResW := util.NewCustomResponseWriter(rw)
|
||||||
head.ServeHTTP(customResW, req)
|
head.ServeHTTP(customResW, req)
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/pkg/scan/whitelist"
|
"github.com/goharbor/harbor/src/pkg/scan/whitelist"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -368,6 +369,16 @@ func GetProjectID(name string) (int64, error) {
|
|||||||
|
|
||||||
// GetRegRedisCon ...
|
// GetRegRedisCon ...
|
||||||
func GetRegRedisCon() (redis.Conn, error) {
|
func GetRegRedisCon() (redis.Conn, error) {
|
||||||
|
// FOR UT
|
||||||
|
if os.Getenv("UTTEST") == "true" {
|
||||||
|
return redis.Dial(
|
||||||
|
"tcp",
|
||||||
|
fmt.Sprintf("%s:%d", os.Getenv("REDIS_HOST"), 6379),
|
||||||
|
redis.DialConnectTimeout(DialConnectionTimeout),
|
||||||
|
redis.DialReadTimeout(DialReadTimeout),
|
||||||
|
redis.DialWriteTimeout(DialWriteTimeout),
|
||||||
|
)
|
||||||
|
}
|
||||||
return redis.DialURL(
|
return redis.DialURL(
|
||||||
config.GetRedisOfRegURL(),
|
config.GetRedisOfRegURL(),
|
||||||
redis.DialConnectTimeout(DialConnectionTimeout),
|
redis.DialConnectTimeout(DialConnectionTimeout),
|
||||||
|
@ -28,13 +28,13 @@ import (
|
|||||||
// Retag tags an image to another
|
// Retag tags an image to another
|
||||||
func Retag(srcImage, destImage *models.Image) error {
|
func Retag(srcImage, destImage *models.Image) error {
|
||||||
isSameRepo := getRepoName(srcImage) == getRepoName(destImage)
|
isSameRepo := getRepoName(srcImage) == getRepoName(destImage)
|
||||||
srcClient, err := NewRepositoryClientForUI("harbor-ui", getRepoName(srcImage))
|
srcClient, err := NewRepositoryClientForLocal("harbor-ui", getRepoName(srcImage))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
destClient := srcClient
|
destClient := srcClient
|
||||||
if !isSameRepo {
|
if !isSameRepo {
|
||||||
destClient, err = NewRepositoryClientForUI("harbor-ui", getRepoName(destImage))
|
destClient, err = NewRepositoryClientForLocal("harbor-ui", getRepoName(destImage))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
"github.com/goharbor/harbor/src/common/utils/log"
|
||||||
@ -33,7 +34,20 @@ func NewRepositoryClientForUI(username, repository string) (*registry.Repository
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return newRepositoryClient(endpoint, username, repository)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRepositoryClientForLocal creates a repository client that can only be used to
|
||||||
|
// access the internal registry with 127.0.0.1
|
||||||
|
func NewRepositoryClientForLocal(username, repository string) (*registry.Repository, error) {
|
||||||
|
// The 127.0.0.1:8080 is not reachable as we do not enable core in UT env.
|
||||||
|
if os.Getenv("UTTEST") == "true" {
|
||||||
|
return NewRepositoryClientForUI(username, repository)
|
||||||
|
}
|
||||||
|
return newRepositoryClient(config.LocalCoreURL(), username, repository)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRepositoryClient(endpoint, username, repository string) (*registry.Repository, error) {
|
||||||
uam := &auth.UserAgentModifier{
|
uam := &auth.UserAgentModifier{
|
||||||
UserAgent: "harbor-registry-client",
|
UserAgent: "harbor-registry-client",
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user