mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-25 19:56:09 +01:00
update
This commit is contained in:
parent
6dc6b4fa79
commit
06519bb3f2
@ -3,7 +3,7 @@ services:
|
|||||||
log:
|
log:
|
||||||
build:
|
build:
|
||||||
context: ../../
|
context: ../../
|
||||||
dockerfile: make/ubuntu/log/Dockerfile
|
dockerfile: make/photon/log/Dockerfile
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- /var/log/harbor/:/var/log/docker/
|
- /var/log/harbor/:/var/log/docker/
|
||||||
|
@ -78,7 +78,7 @@ func getCfgStore() string {
|
|||||||
|
|
||||||
//read the following attrs from env every time boots up
|
//read the following attrs from env every time boots up
|
||||||
func readFromEnv(cfg map[string]interface{}) error {
|
func readFromEnv(cfg map[string]interface{}) error {
|
||||||
cfg[comcfg.DomainName] = os.Getenv("EXT_ENDPOINT")
|
cfg[comcfg.ExtEndpoint] = os.Getenv("EXT_ENDPOINT")
|
||||||
|
|
||||||
cfg[comcfg.DatabaseType] = os.Getenv("DATABASE_TYPE")
|
cfg[comcfg.DatabaseType] = os.Getenv("DATABASE_TYPE")
|
||||||
cfg[comcfg.MySQLHost] = os.Getenv("MYSQL_HOST")
|
cfg[comcfg.MySQLHost] = os.Getenv("MYSQL_HOST")
|
||||||
|
@ -40,7 +40,7 @@ const (
|
|||||||
LDAPScopeOnelevel = "2"
|
LDAPScopeOnelevel = "2"
|
||||||
LDAPScopeSubtree = "3"
|
LDAPScopeSubtree = "3"
|
||||||
|
|
||||||
DomainName = "domain_name"
|
ExtEndpoint = "ext_endpoint"
|
||||||
AUTHMode = "auth_mode"
|
AUTHMode = "auth_mode"
|
||||||
DatabaseType = "database_type"
|
DatabaseType = "database_type"
|
||||||
MySQLHost = "mysql_host"
|
MySQLHost = "mysql_host"
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -134,19 +133,24 @@ func (t *tokenAuthorizer) updateCachedToken(token string, expiresIn int) {
|
|||||||
// Implements interface Authorizer
|
// Implements interface Authorizer
|
||||||
type standardTokenAuthorizer struct {
|
type standardTokenAuthorizer struct {
|
||||||
tokenAuthorizer
|
tokenAuthorizer
|
||||||
client *http.Client
|
client *http.Client
|
||||||
credential Credential
|
credential Credential
|
||||||
|
tokenServiceEndpoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStandardTokenAuthorizer returns a standard token authorizer. The authorizer will request a token
|
// NewStandardTokenAuthorizer returns a standard token authorizer. The authorizer will request a token
|
||||||
// from token server and add it to the origin request
|
// from token server and add it to the origin request
|
||||||
func NewStandardTokenAuthorizer(credential Credential, insecure bool, scopeType, scopeName string, scopeActions ...string) Authorizer {
|
// If tokenServiceURL is set, the token request will be sent to it instead of the server get from authorizer
|
||||||
|
// The usage please refer to the function tokenURL
|
||||||
|
func NewStandardTokenAuthorizer(credential Credential, insecure bool,
|
||||||
|
tokenServiceEndpoint string, scopeType, scopeName string, scopeActions ...string) Authorizer {
|
||||||
authorizer := &standardTokenAuthorizer{
|
authorizer := &standardTokenAuthorizer{
|
||||||
client: &http.Client{
|
client: &http.Client{
|
||||||
Transport: registry.GetHTTPTransport(insecure),
|
Transport: registry.GetHTTPTransport(insecure),
|
||||||
Timeout: 30 * time.Second,
|
Timeout: 30 * time.Second,
|
||||||
},
|
},
|
||||||
credential: credential,
|
credential: credential,
|
||||||
|
tokenServiceEndpoint: tokenServiceEndpoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(scopeType) != 0 || len(scopeName) != 0 {
|
if len(scopeType) != 0 || len(scopeName) != 0 {
|
||||||
@ -163,7 +167,7 @@ func NewStandardTokenAuthorizer(credential Credential, insecure bool, scopeType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *standardTokenAuthorizer) generateToken(realm, service string, scopes []string) (token string, expiresIn int, issuedAt *time.Time, err error) {
|
func (s *standardTokenAuthorizer) generateToken(realm, service string, scopes []string) (token string, expiresIn int, issuedAt *time.Time, err error) {
|
||||||
realm = tokenURL(realm)
|
realm = s.tokenURL(realm)
|
||||||
|
|
||||||
u, err := url.Parse(realm)
|
u, err := url.Parse(realm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -230,17 +234,15 @@ func (s *standardTokenAuthorizer) generateToken(realm, service string, scopes []
|
|||||||
|
|
||||||
// when the registry client is used inside Harbor, the token request
|
// when the registry client is used inside Harbor, the token request
|
||||||
// can be posted to token service directly rather than going through nginx.
|
// can be posted to token service directly rather than going through nginx.
|
||||||
// this solution can resolve two problems:
|
// If realm is set as the internal url of token service, this can resolve
|
||||||
|
// two problems:
|
||||||
// 1. performance issue
|
// 1. performance issue
|
||||||
// 2. the realm field returned by registry is an IP which can not reachable
|
// 2. the realm field returned by registry is an IP which can not reachable
|
||||||
// inside Harbor
|
// inside Harbor
|
||||||
func tokenURL(realm string) string {
|
func (s *standardTokenAuthorizer) tokenURL(realm string) string {
|
||||||
|
if len(s.tokenServiceEndpoint) != 0 {
|
||||||
domainName := os.Getenv("DOMAIN_NAME")
|
return s.tokenServiceEndpoint
|
||||||
if len(domainName) != 0 && strings.Contains(realm, domainName) {
|
|
||||||
realm = "http://ui/service/token"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return realm
|
return realm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ func TestAuthorizeOfStandardTokenAuthorizer(t *testing.T) {
|
|||||||
})
|
})
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
authorizer := NewStandardTokenAuthorizer(nil, false, "repository", "library/ubuntu", "pull")
|
authorizer := NewStandardTokenAuthorizer(nil, false, "", "repository", "library/ubuntu", "pull")
|
||||||
req, err := http.NewRequest("GET", "http://registry", nil)
|
req, err := http.NewRequest("GET", "http://registry", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create request: %v", err)
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
@ -23,47 +23,53 @@ import (
|
|||||||
"github.com/vmware/harbor/src/common/config"
|
"github.com/vmware/harbor/src/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var adminServerDefaultConfig = map[string]interface{}{
|
||||||
|
config.ExtEndpoint: "host01.com",
|
||||||
|
config.AUTHMode: config.DBAuth,
|
||||||
|
config.DatabaseType: "mysql",
|
||||||
|
config.MySQLHost: "127.0.0.1",
|
||||||
|
config.MySQLPort: 3306,
|
||||||
|
config.MySQLUsername: "user01",
|
||||||
|
config.MySQLPassword: "password",
|
||||||
|
config.MySQLDatabase: "registry",
|
||||||
|
config.SQLiteFile: "/tmp/registry.db",
|
||||||
|
config.SelfRegistration: true,
|
||||||
|
config.LDAPURL: "ldap://127.0.0.1",
|
||||||
|
config.LDAPSearchDN: "uid=searchuser,ou=people,dc=mydomain,dc=com",
|
||||||
|
config.LDAPSearchPwd: "password",
|
||||||
|
config.LDAPBaseDN: "ou=people,dc=mydomain,dc=com",
|
||||||
|
config.LDAPUID: "uid",
|
||||||
|
config.LDAPFilter: "",
|
||||||
|
config.LDAPScope: 3,
|
||||||
|
config.LDAPTimeout: 30,
|
||||||
|
config.TokenServiceURL: "http://token_service",
|
||||||
|
config.RegistryURL: "http://registry",
|
||||||
|
config.EmailHost: "127.0.0.1",
|
||||||
|
config.EmailPort: 25,
|
||||||
|
config.EmailUsername: "user01",
|
||||||
|
config.EmailPassword: "password",
|
||||||
|
config.EmailFrom: "from",
|
||||||
|
config.EmailSSL: true,
|
||||||
|
config.EmailIdentity: "",
|
||||||
|
config.ProjectCreationRestriction: config.ProCrtRestrAdmOnly,
|
||||||
|
config.VerifyRemoteCert: false,
|
||||||
|
config.MaxJobWorkers: 3,
|
||||||
|
config.TokenExpiration: 30,
|
||||||
|
config.CfgExpiration: 5,
|
||||||
|
config.JobLogDir: "/var/log/jobs",
|
||||||
|
config.UseCompressedJS: true,
|
||||||
|
config.SecretKey: "secret",
|
||||||
|
config.AdminInitialPassword: "password",
|
||||||
|
}
|
||||||
|
|
||||||
// NewAdminserver returns a mock admin server
|
// NewAdminserver returns a mock admin server
|
||||||
func NewAdminserver() (*httptest.Server, error) {
|
func NewAdminserver(config map[string]interface{}) (*httptest.Server, error) {
|
||||||
m := []*RequestHandlerMapping{}
|
m := []*RequestHandlerMapping{}
|
||||||
b, err := json.Marshal(map[string]interface{}{
|
if config == nil {
|
||||||
config.DomainName: "host01.com",
|
config = adminServerDefaultConfig
|
||||||
config.AUTHMode: config.DBAuth,
|
}
|
||||||
config.DatabaseType: "mysql",
|
|
||||||
config.MySQLHost: "127.0.0.1",
|
b, err := json.Marshal(config)
|
||||||
config.MySQLPort: 3306,
|
|
||||||
config.MySQLUsername: "user01",
|
|
||||||
config.MySQLPassword: "password",
|
|
||||||
config.MySQLDatabase: "registry",
|
|
||||||
config.SQLiteFile: "/tmp/registry.db",
|
|
||||||
config.SelfRegistration: true,
|
|
||||||
config.LDAPURL: "ldap://127.0.0.1",
|
|
||||||
config.LDAPSearchDN: "uid=searchuser,ou=people,dc=mydomain,dc=com",
|
|
||||||
config.LDAPSearchPwd: "password",
|
|
||||||
config.LDAPBaseDN: "ou=people,dc=mydomain,dc=com",
|
|
||||||
config.LDAPUID: "uid",
|
|
||||||
config.LDAPFilter: "",
|
|
||||||
config.LDAPScope: 3,
|
|
||||||
config.LDAPTimeout: 30,
|
|
||||||
config.TokenServiceURL: "http://token_service",
|
|
||||||
config.RegistryURL: "http://registry",
|
|
||||||
config.EmailHost: "127.0.0.1",
|
|
||||||
config.EmailPort: 25,
|
|
||||||
config.EmailUsername: "user01",
|
|
||||||
config.EmailPassword: "password",
|
|
||||||
config.EmailFrom: "from",
|
|
||||||
config.EmailSSL: true,
|
|
||||||
config.EmailIdentity: "",
|
|
||||||
config.ProjectCreationRestriction: config.ProCrtRestrAdmOnly,
|
|
||||||
config.VerifyRemoteCert: false,
|
|
||||||
config.MaxJobWorkers: 3,
|
|
||||||
config.TokenExpiration: 30,
|
|
||||||
config.CfgExpiration: 5,
|
|
||||||
config.JobLogDir: "/var/log/jobs",
|
|
||||||
config.UseCompressedJS: true,
|
|
||||||
config.SecretKey: "secret",
|
|
||||||
config.AdminInitialPassword: "password",
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -121,11 +121,16 @@ func UISecret() string {
|
|||||||
return os.Getenv("UI_SECRET")
|
return os.Getenv("UI_SECRET")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DomainName ...
|
// ExtEndpoint ...
|
||||||
func DomainName() (string, error) {
|
func ExtEndpoint() (string, error) {
|
||||||
cfg, err := mg.Get()
|
cfg, err := mg.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return cfg[comcfg.DomainName].(string), nil
|
return cfg[comcfg.ExtEndpoint].(string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InternalTokenServiceEndpoint ...
|
||||||
|
func InternalTokenServiceEndpoint() string {
|
||||||
|
return "http://ui/service/token"
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
|
|
||||||
// test functions under package jobservice/config
|
// test functions under package jobservice/config
|
||||||
func TestConfig(t *testing.T) {
|
func TestConfig(t *testing.T) {
|
||||||
server, err := test.NewAdminserver()
|
server, err := test.NewAdminserver(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create a mock admin server: %v", err)
|
t.Fatalf("failed to create a mock admin server: %v", err)
|
||||||
}
|
}
|
||||||
@ -53,8 +53,6 @@ func TestConfig(t *testing.T) {
|
|||||||
t.Fatalf("failed to get max job workers: %v", err)
|
t.Fatalf("failed to get max job workers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalUIURL()
|
|
||||||
|
|
||||||
if _, err := LocalRegURL(); err != nil {
|
if _, err := LocalRegURL(); err != nil {
|
||||||
t.Fatalf("failed to get registry URL: %v", err)
|
t.Fatalf("failed to get registry URL: %v", err)
|
||||||
}
|
}
|
||||||
@ -67,5 +65,11 @@ func TestConfig(t *testing.T) {
|
|||||||
t.Fatalf("failed to get secret key: %v", err)
|
t.Fatalf("failed to get secret key: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
UISecret()
|
if len(InternalTokenServiceEndpoint()) == 0 {
|
||||||
|
t.Error("the internal token service endpoint is null")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ExtEndpoint(); err != nil {
|
||||||
|
t.Fatalf("failed to get ext endpoint: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ func (i *Initializer) enter() (string, error) {
|
|||||||
c := &http.Cookie{Name: models.UISecretCookie, Value: i.srcSecret}
|
c := &http.Cookie{Name: models.UISecretCookie, Value: i.srcSecret}
|
||||||
srcCred := auth.NewCookieCredential(c)
|
srcCred := auth.NewCookieCredential(c)
|
||||||
srcClient, err := newRepositoryClient(i.srcURL, i.insecure, srcCred,
|
srcClient, err := newRepositoryClient(i.srcURL, i.insecure, srcCred,
|
||||||
i.repository, "repository", i.repository, "pull", "push", "*")
|
config.InternalTokenServiceEndpoint(), i.repository, "repository", i.repository, "pull", "push", "*")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
i.logger.Errorf("an error occurred while creating source repository client: %v", err)
|
i.logger.Errorf("an error occurred while creating source repository client: %v", err)
|
||||||
return "", err
|
return "", err
|
||||||
@ -148,7 +148,7 @@ func (i *Initializer) enter() (string, error) {
|
|||||||
|
|
||||||
dstCred := auth.NewBasicAuthCredential(i.dstUsr, i.dstPwd)
|
dstCred := auth.NewBasicAuthCredential(i.dstUsr, i.dstPwd)
|
||||||
dstClient, err := newRepositoryClient(i.dstURL, i.insecure, dstCred,
|
dstClient, err := newRepositoryClient(i.dstURL, i.insecure, dstCred,
|
||||||
i.repository, "repository", i.repository, "pull", "push", "*")
|
"", i.repository, "repository", i.repository, "pull", "push", "*")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
i.logger.Errorf("an error occurred while creating destination repository client: %v", err)
|
i.logger.Errorf("an error occurred while creating destination repository client: %v", err)
|
||||||
return "", err
|
return "", err
|
||||||
@ -459,10 +459,11 @@ func (m *ManifestPusher) enter() (string, error) {
|
|||||||
return StatePullManifest, nil
|
return StatePullManifest, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRepositoryClient(endpoint string, insecure bool, credential auth.Credential, repository, scopeType, scopeName string,
|
func newRepositoryClient(endpoint string, insecure bool, credential auth.Credential,
|
||||||
|
tokenServiceEndpoint, repository, scopeType, scopeName string,
|
||||||
scopeActions ...string) (*registry.Repository, error) {
|
scopeActions ...string) (*registry.Repository, error) {
|
||||||
|
|
||||||
domain, err := config.DomainName()
|
domain, err := config.ExtEndpoint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -470,7 +471,8 @@ func newRepositoryClient(endpoint string, insecure bool, credential auth.Credent
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
authorizer := auth.NewStandardTokenAuthorizer(credential, insecure, scopeType, scopeName, scopeActions...)
|
authorizer := auth.NewStandardTokenAuthorizer(credential, insecure,
|
||||||
|
tokenServiceEndpoint, scopeType, scopeName, scopeActions...)
|
||||||
|
|
||||||
store, err := auth.NewAuthorizerStore(endpoint, insecure, authorizer)
|
store, err := auth.NewAuthorizerStore(endpoint, insecure, authorizer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -119,7 +119,14 @@ func (c *ConfigAPI) Put() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateCfg(cfg); err != nil {
|
isSysErr, err := validateCfg(cfg)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if isSysErr {
|
||||||
|
log.Errorf("failed to validate configurations: %v", err)
|
||||||
|
c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
||||||
|
}
|
||||||
|
|
||||||
c.CustomAbort(http.StatusBadRequest, err.Error())
|
c.CustomAbort(http.StatusBadRequest, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,42 +169,68 @@ func (c *ConfigAPI) Put() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateCfg(c map[string]string) error {
|
func validateCfg(c map[string]string) (bool, error) {
|
||||||
|
isSysErr := false
|
||||||
|
|
||||||
|
mode, err := config.AuthMode()
|
||||||
|
if err != nil {
|
||||||
|
isSysErr = true
|
||||||
|
return isSysErr, err
|
||||||
|
}
|
||||||
|
|
||||||
if value, ok := c[comcfg.AUTHMode]; ok {
|
if value, ok := c[comcfg.AUTHMode]; ok {
|
||||||
if value != comcfg.DBAuth && value != comcfg.LDAPAuth {
|
if value != comcfg.DBAuth && value != comcfg.LDAPAuth {
|
||||||
return fmt.Errorf("invalid %s, shoud be %s or %s", comcfg.AUTHMode, comcfg.DBAuth, comcfg.LDAPAuth)
|
return isSysErr, fmt.Errorf("invalid %s, shoud be %s or %s", comcfg.AUTHMode, comcfg.DBAuth, comcfg.LDAPAuth)
|
||||||
|
}
|
||||||
|
mode = value
|
||||||
|
}
|
||||||
|
|
||||||
|
if mode == comcfg.LDAPAuth {
|
||||||
|
ldap, err := config.LDAP()
|
||||||
|
if err != nil {
|
||||||
|
isSysErr = true
|
||||||
|
return isSysErr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if value == comcfg.LDAPAuth {
|
if len(ldap.URL) == 0 {
|
||||||
if _, ok := c[comcfg.LDAPURL]; !ok {
|
if _, ok := c[comcfg.LDAPURL]; !ok {
|
||||||
return fmt.Errorf("%s is missing", comcfg.LDAPURL)
|
return isSysErr, fmt.Errorf("%s is missing", comcfg.LDAPURL)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ldap.BaseDN) == 0 {
|
||||||
if _, ok := c[comcfg.LDAPBaseDN]; !ok {
|
if _, ok := c[comcfg.LDAPBaseDN]; !ok {
|
||||||
return fmt.Errorf("%s is missing", comcfg.LDAPBaseDN)
|
return isSysErr, fmt.Errorf("%s is missing", comcfg.LDAPBaseDN)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if len(ldap.UID) == 0 {
|
||||||
if _, ok := c[comcfg.LDAPUID]; !ok {
|
if _, ok := c[comcfg.LDAPUID]; !ok {
|
||||||
return fmt.Errorf("%s is missing", comcfg.LDAPUID)
|
return isSysErr, fmt.Errorf("%s is missing", comcfg.LDAPUID)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if ldap.Scope == 0 {
|
||||||
if _, ok := c[comcfg.LDAPScope]; !ok {
|
if _, ok := c[comcfg.LDAPScope]; !ok {
|
||||||
return fmt.Errorf("%s is missing", comcfg.LDAPScope)
|
return isSysErr, fmt.Errorf("%s is missing", comcfg.LDAPScope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Infof("===========%v", c)
|
||||||
|
|
||||||
if ldapURL, ok := c[comcfg.LDAPURL]; ok && len(ldapURL) == 0 {
|
if ldapURL, ok := c[comcfg.LDAPURL]; ok && len(ldapURL) == 0 {
|
||||||
return fmt.Errorf("%s is empty", comcfg.LDAPURL)
|
return isSysErr, fmt.Errorf("%s is empty", comcfg.LDAPURL)
|
||||||
}
|
}
|
||||||
if baseDN, ok := c[comcfg.LDAPBaseDN]; ok && len(baseDN) == 0 {
|
if baseDN, ok := c[comcfg.LDAPBaseDN]; ok && len(baseDN) == 0 {
|
||||||
return fmt.Errorf("%s is empty", comcfg.LDAPBaseDN)
|
return isSysErr, fmt.Errorf("%s is empty", comcfg.LDAPBaseDN)
|
||||||
}
|
}
|
||||||
if uID, ok := c[comcfg.LDAPUID]; ok && len(uID) == 0 {
|
if uID, ok := c[comcfg.LDAPUID]; ok && len(uID) == 0 {
|
||||||
return fmt.Errorf("%s is empty", comcfg.LDAPUID)
|
return isSysErr, fmt.Errorf("%s is empty", comcfg.LDAPUID)
|
||||||
}
|
}
|
||||||
if scope, ok := c[comcfg.LDAPScope]; ok &&
|
if scope, ok := c[comcfg.LDAPScope]; ok &&
|
||||||
scope != comcfg.LDAPScopeBase &&
|
scope != comcfg.LDAPScopeBase &&
|
||||||
scope != comcfg.LDAPScopeOnelevel &&
|
scope != comcfg.LDAPScopeOnelevel &&
|
||||||
scope != comcfg.LDAPScopeSubtree {
|
scope != comcfg.LDAPScopeSubtree {
|
||||||
return fmt.Errorf("invalid %s, should be %s, %s or %s",
|
return isSysErr, fmt.Errorf("invalid %s, should be %s, %s or %s",
|
||||||
comcfg.LDAPScope,
|
comcfg.LDAPScope,
|
||||||
comcfg.LDAPScopeBase,
|
comcfg.LDAPScopeBase,
|
||||||
comcfg.LDAPScopeOnelevel,
|
comcfg.LDAPScopeOnelevel,
|
||||||
@ -205,41 +238,41 @@ func validateCfg(c map[string]string) error {
|
|||||||
}
|
}
|
||||||
if timeout, ok := c[comcfg.LDAPTimeout]; ok {
|
if timeout, ok := c[comcfg.LDAPTimeout]; ok {
|
||||||
if t, err := strconv.Atoi(timeout); err != nil || t < 0 {
|
if t, err := strconv.Atoi(timeout); err != nil || t < 0 {
|
||||||
return fmt.Errorf("invalid %s", comcfg.LDAPTimeout)
|
return isSysErr, fmt.Errorf("invalid %s", comcfg.LDAPTimeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self, ok := c[comcfg.SelfRegistration]; ok &&
|
if self, ok := c[comcfg.SelfRegistration]; ok &&
|
||||||
self != "0" && self != "1" {
|
self != "0" && self != "1" {
|
||||||
return fmt.Errorf("%s should be %s or %s",
|
return isSysErr, fmt.Errorf("%s should be %s or %s",
|
||||||
comcfg.SelfRegistration, "0", "1")
|
comcfg.SelfRegistration, "0", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
if port, ok := c[comcfg.EmailPort]; ok {
|
if port, ok := c[comcfg.EmailPort]; ok {
|
||||||
if p, err := strconv.Atoi(port); err != nil || p < 0 || p > 65535 {
|
if p, err := strconv.Atoi(port); err != nil || p < 0 || p > 65535 {
|
||||||
return fmt.Errorf("invalid %s", comcfg.EmailPort)
|
return isSysErr, fmt.Errorf("invalid %s", comcfg.EmailPort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ssl, ok := c[comcfg.EmailSSL]; ok && ssl != "0" && ssl != "1" {
|
if ssl, ok := c[comcfg.EmailSSL]; ok && ssl != "0" && ssl != "1" {
|
||||||
return fmt.Errorf("%s should be %s or %s", comcfg.EmailSSL, "0", "1")
|
return isSysErr, fmt.Errorf("%s should be %s or %s", comcfg.EmailSSL, "0", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
if crt, ok := c[comcfg.ProjectCreationRestriction]; ok &&
|
if crt, ok := c[comcfg.ProjectCreationRestriction]; ok &&
|
||||||
crt != comcfg.ProCrtRestrEveryone &&
|
crt != comcfg.ProCrtRestrEveryone &&
|
||||||
crt != comcfg.ProCrtRestrAdmOnly {
|
crt != comcfg.ProCrtRestrAdmOnly {
|
||||||
return fmt.Errorf("invalid %s, should be %s or %s",
|
return isSysErr, fmt.Errorf("invalid %s, should be %s or %s",
|
||||||
comcfg.ProjectCreationRestriction,
|
comcfg.ProjectCreationRestriction,
|
||||||
comcfg.ProCrtRestrAdmOnly,
|
comcfg.ProCrtRestrAdmOnly,
|
||||||
comcfg.ProCrtRestrEveryone)
|
comcfg.ProCrtRestrEveryone)
|
||||||
}
|
}
|
||||||
|
|
||||||
if verify, ok := c[comcfg.VerifyRemoteCert]; ok && verify != "0" && verify != "1" {
|
if verify, ok := c[comcfg.VerifyRemoteCert]; ok && verify != "0" && verify != "1" {
|
||||||
return fmt.Errorf("invalid %s, should be %s or %s",
|
return isSysErr, fmt.Errorf("invalid %s, should be %s or %s",
|
||||||
comcfg.VerifyRemoteCert, "0", "1")
|
comcfg.VerifyRemoteCert, "0", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return isSysErr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//encode passwords and convert map[string]string to map[string]interface{}
|
//encode passwords and convert map[string]string to map[string]interface{}
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/docker/distribution/manifest/schema1"
|
"github.com/docker/distribution/manifest/schema1"
|
||||||
@ -444,15 +443,8 @@ func newRepositoryClient(endpoint string, insecure bool, username, password, rep
|
|||||||
|
|
||||||
credential := auth.NewBasicAuthCredential(username, password)
|
credential := auth.NewBasicAuthCredential(username, password)
|
||||||
|
|
||||||
domain, err := config.DomainName()
|
authorizer := auth.NewStandardTokenAuthorizer(credential, insecure,
|
||||||
if err != nil {
|
config.InternalTokenServiceEndpoint(), scopeType, scopeName, scopeActions...)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := os.Setenv("DOMAIN_NAME", domain); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
authorizer := auth.NewStandardTokenAuthorizer(credential, insecure, scopeType, scopeName, scopeActions...)
|
|
||||||
|
|
||||||
store, err := auth.NewAuthorizerStore(endpoint, insecure, authorizer)
|
store, err := auth.NewAuthorizerStore(endpoint, insecure, authorizer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common/api"
|
"github.com/vmware/harbor/src/common/api"
|
||||||
@ -342,15 +341,8 @@ func newRegistryClient(endpoint string, insecure bool, username, password, scope
|
|||||||
scopeActions ...string) (*registry.Registry, error) {
|
scopeActions ...string) (*registry.Registry, error) {
|
||||||
credential := auth.NewBasicAuthCredential(username, password)
|
credential := auth.NewBasicAuthCredential(username, password)
|
||||||
|
|
||||||
domain, err := config.DomainName()
|
authorizer := auth.NewStandardTokenAuthorizer(credential, insecure,
|
||||||
if err != nil {
|
"", scopeType, scopeName, scopeActions...)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := os.Setenv("DOMAIN_NAME", domain); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
authorizer := auth.NewStandardTokenAuthorizer(credential, insecure, scopeType, scopeName, scopeActions...)
|
|
||||||
|
|
||||||
store, err := auth.NewAuthorizerStore(endpoint, insecure, authorizer)
|
store, err := auth.NewAuthorizerStore(endpoint, insecure, authorizer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -114,13 +114,13 @@ func TokenExpiration() (int, error) {
|
|||||||
return int(cfg[comcfg.TokenExpiration].(float64)), nil
|
return int(cfg[comcfg.TokenExpiration].(float64)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DomainName returns the external URL of Harbor: protocal://host:port
|
// ExtEndpoint returns the external URL of Harbor: protocal://host:port
|
||||||
func DomainName() (string, error) {
|
func ExtEndpoint() (string, error) {
|
||||||
cfg, err := mg.Get()
|
cfg, err := mg.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return cfg[comcfg.DomainName].(string), nil
|
return cfg[comcfg.ExtEndpoint].(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecretKey returns the secret key to encrypt the password of target
|
// SecretKey returns the secret key to encrypt the password of target
|
||||||
@ -155,6 +155,11 @@ func InternalJobServiceURL() string {
|
|||||||
return "http://jobservice"
|
return "http://jobservice"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InternalTokenServiceEndpoint returns token service endpoint for internal communication between Harbor containers
|
||||||
|
func InternalTokenServiceEndpoint() string {
|
||||||
|
return "http://ui/service/token"
|
||||||
|
}
|
||||||
|
|
||||||
// InitialAdminPassword returns the initial password for administrator
|
// InitialAdminPassword returns the initial password for administrator
|
||||||
func InitialAdminPassword() (string, error) {
|
func InitialAdminPassword() (string, error) {
|
||||||
cfg, err := mg.Get()
|
cfg, err := mg.Get()
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
|
|
||||||
// test functions under package ui/config
|
// test functions under package ui/config
|
||||||
func TestConfig(t *testing.T) {
|
func TestConfig(t *testing.T) {
|
||||||
server, err := test.NewAdminserver()
|
server, err := test.NewAdminserver(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create a mock admin server: %v", err)
|
t.Fatalf("failed to create a mock admin server: %v", err)
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ func TestConfig(t *testing.T) {
|
|||||||
t.Fatalf("failed to get token expiration: %v", err)
|
t.Fatalf("failed to get token expiration: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := DomainName(); err != nil {
|
if _, err := ExtEndpoint(); err != nil {
|
||||||
t.Fatalf("failed to get domain name: %v", err)
|
t.Fatalf("failed to get domain name: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +84,17 @@ func TestConfig(t *testing.T) {
|
|||||||
t.Fatalf("failed to get registry URL: %v", err)
|
t.Fatalf("failed to get registry URL: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalJobServiceURL()
|
if len(InternalJobServiceURL()) == 0 {
|
||||||
|
t.Error("the internal job service url is null")
|
||||||
|
}
|
||||||
|
|
||||||
InitialAdminPassword()
|
if len(InternalTokenServiceEndpoint()) == 0 {
|
||||||
|
t.Error("the internal token service endpoint is null")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := InitialAdminPassword(); err != nil {
|
||||||
|
t.Fatalf("failed to get initial admin password: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := OnlyAdminCreateProject(); err != nil {
|
if _, err := OnlyAdminCreateProject(); err != nil {
|
||||||
t.Fatalf("failed to get onldy admin create project: %v", err)
|
t.Fatalf("failed to get onldy admin create project: %v", err)
|
||||||
@ -103,6 +111,4 @@ func TestConfig(t *testing.T) {
|
|||||||
if _, err := Database(); err != nil {
|
if _, err := Database(); err != nil {
|
||||||
t.Fatalf("failed to get database: %v", err)
|
t.Fatalf("failed to get database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
UISecret()
|
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ func (cc *CommonController) SendEmail() {
|
|||||||
|
|
||||||
message := new(bytes.Buffer)
|
message := new(bytes.Buffer)
|
||||||
|
|
||||||
harborURL, err := config.DomainName()
|
harborURL, err := config.ExtEndpoint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to get domain name: %v", err)
|
log.Errorf("failed to get domain name: %v", err)
|
||||||
cc.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
cc.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
||||||
|
@ -15,7 +15,7 @@ type RepositoryController struct {
|
|||||||
|
|
||||||
// Get renders repository page
|
// Get renders repository page
|
||||||
func (rc *RepositoryController) Get() {
|
func (rc *RepositoryController) Get() {
|
||||||
url, err := config.DomainName()
|
url, err := config.ExtEndpoint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to get domain name: %v", err)
|
log.Errorf("failed to get domain name: %v", err)
|
||||||
rc.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
rc.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
||||||
|
@ -84,7 +84,7 @@ func FilterAccess(username string, a *token.ResourceActions) {
|
|||||||
repoLength := len(repoSplit)
|
repoLength := len(repoSplit)
|
||||||
if repoLength > 1 { //Only check the permission when the requested image has a namespace, i.e. project
|
if repoLength > 1 { //Only check the permission when the requested image has a namespace, i.e. project
|
||||||
var projectName string
|
var projectName string
|
||||||
registryURL, err := config.DomainName()
|
registryURL, err := config.ExtEndpoint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to get domain name: %v", err)
|
log.Errorf("failed to get domain name: %v", err)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user