From f5e82f75a723dfef1cb5a4190eb5619dc4ab98a8 Mon Sep 17 00:00:00 2001 From: stonezdj Date: Fri, 13 Jul 2018 19:19:54 +0800 Subject: [PATCH] Add SafeCast function and set default value for some sytem configure Add SafeCastString, SafeCastInt, SafeCastFloat64, SafeCastBool function to check the type matched and avoid panic in runtime Add default value to configure settings to avoid cannot save configure issue --- src/adminserver/api/cfg.go | 4 +- src/adminserver/systemcfg/systemcfg.go | 61 ++++++++----- src/adminserver/systemcfg/systemcfg_test.go | 34 +++++++- src/common/const.go | 84 ++++++++++++++++++ src/common/utils/utils.go | 32 +++++++ src/common/utils/utils_test.go | 88 +++++++++++++++++++ src/ui/api/config.go | 94 ++------------------ src/ui/api/systeminfo.go | 10 +-- src/ui/config/config.go | 97 +++++++++++---------- 9 files changed, 336 insertions(+), 168 deletions(-) diff --git a/src/adminserver/api/cfg.go b/src/adminserver/api/cfg.go index b23c1f86b..e18b0081e 100644 --- a/src/adminserver/api/cfg.go +++ b/src/adminserver/api/cfg.go @@ -31,7 +31,7 @@ func ListCfgs(w http.ResponseWriter, r *http.Request) { handleInternalServerError(w) return } - + systemcfg.AddMissedKey(cfg) if err = writeJSON(w, cfg); err != nil { log.Errorf("failed to write response: %v", err) return @@ -52,7 +52,6 @@ func UpdateCfgs(w http.ResponseWriter, r *http.Request) { handleBadRequestError(w, err.Error()) return } - if err = systemcfg.CfgStore.Write(m); err != nil { log.Errorf("failed to update system configurations: %v", err) handleInternalServerError(w) @@ -68,7 +67,6 @@ func ResetCfgs(w http.ResponseWriter, r *http.Request) { handleInternalServerError(w) return } - if err := systemcfg.CfgStore.Write(cfgs); err != nil { log.Errorf("failed to write system configurations to storage: %v", err) handleInternalServerError(w) diff --git a/src/adminserver/systemcfg/systemcfg.go b/src/adminserver/systemcfg/systemcfg.go index bf74fca9e..61dda2ffc 100644 --- a/src/adminserver/systemcfg/systemcfg.go +++ b/src/adminserver/systemcfg/systemcfg.go @@ -30,6 +30,7 @@ import ( comcfg "github.com/vmware/harbor/src/common/config" "github.com/vmware/harbor/src/common/dao" "github.com/vmware/harbor/src/common/models" + "github.com/vmware/harbor/src/common/utils" "github.com/vmware/harbor/src/common/utils/log" ) @@ -258,36 +259,30 @@ func Init() (err error) { if err := dao.InitDatabase(db); err != nil { return err } - if err := initCfgStore(); err != nil { return err } - cfgs := map[string]interface{}{} //Use reload key to avoid reset customed setting after restart curCfgs, err := CfgStore.Read() if err != nil { return err } - loadAll := isLoadAll(curCfgs[common.ReloadKey]) - if !loadAll { - cfgs = curCfgs - if cfgs == nil { - log.Info("configurations read from storage driver are null, will load them from environment variables") - loadAll = true - cfgs = map[string]interface{}{} - } + loadAll := isLoadAll(curCfgs) + if curCfgs == nil { + curCfgs = map[string]interface{}{} } - - if err = LoadFromEnv(cfgs, loadAll); err != nil { + //restart: only repeatload envs will be load + //reload_config: all envs will be reload except the skiped envs + if err = LoadFromEnv(curCfgs, loadAll); err != nil { return err } - - return CfgStore.Write(cfgs) + AddMissedKey(curCfgs) + return CfgStore.Write(curCfgs) } -func isLoadAll(curReloadKey interface{}) bool { - return strings.EqualFold(os.Getenv("RESET"), "true") && os.Getenv("RELOAD_KEY") != curReloadKey +func isLoadAll(cfg map[string]interface{}) bool { + return cfg == nil || strings.EqualFold(os.Getenv("RESET"), "true") && os.Getenv("RELOAD_KEY") != cfg[common.ReloadKey] } func initCfgStore() (err error) { @@ -328,7 +323,6 @@ func initCfgStore() (err error) { // only used when migrating harbor release before v1.3 // after v1.3 there is always a db configuration before migrate. validLdapScope(jsonconfig, true) - err = CfgStore.Write(jsonconfig) if err != nil { log.Error("Failed to update old configuration to database") @@ -418,11 +412,11 @@ func GetDatabaseFromCfg(cfg map[string]interface{}) *models.Database { database := &models.Database{} database.Type = cfg[common.DatabaseType].(string) postgresql := &models.PostGreSQL{} - postgresql.Host = cfg[common.PostGreSQLHOST].(string) - postgresql.Port = int(cfg[common.PostGreSQLPort].(int)) - postgresql.Username = cfg[common.PostGreSQLUsername].(string) - postgresql.Password = cfg[common.PostGreSQLPassword].(string) - postgresql.Database = cfg[common.PostGreSQLDatabase].(string) + postgresql.Host = utils.SafeCastString(cfg[common.PostGreSQLHOST]) + postgresql.Port = int(utils.SafeCastInt(cfg[common.PostGreSQLPort])) + postgresql.Username = utils.SafeCastString(cfg[common.PostGreSQLUsername]) + postgresql.Password = utils.SafeCastString(cfg[common.PostGreSQLPassword]) + postgresql.Database = utils.SafeCastString(cfg[common.PostGreSQLDatabase]) database.PostGreSQL = postgresql return database } @@ -448,3 +442,26 @@ func validLdapScope(cfg map[string]interface{}, isMigrate bool) { cfg[ldapScopeKey] = ldapScope } + +//AddMissedKey ... If the configure key is missing in the cfg map, add default value to it +func AddMissedKey(cfg map[string]interface{}) { + + for k, v := range common.HarborStringKeysMap { + if _, exist := cfg[k]; !exist { + cfg[k] = v + } + } + + for k, v := range common.HarborNumKeysMap { + if _, exist := cfg[k]; !exist { + cfg[k] = v + } + } + + for k, v := range common.HarborBoolKeysMap { + if _, exist := cfg[k]; !exist { + cfg[k] = v + } + } + +} diff --git a/src/adminserver/systemcfg/systemcfg_test.go b/src/adminserver/systemcfg/systemcfg_test.go index 581725c78..efc4bc1f5 100644 --- a/src/adminserver/systemcfg/systemcfg_test.go +++ b/src/adminserver/systemcfg/systemcfg_test.go @@ -135,8 +135,10 @@ func TestIsLoadAll(t *testing.T) { if err := os.Setenv("RESET", "True"); err != nil { t.Fatalf("failed to set env: %v", err) } - assert.False(t, isLoadAll("123456")) - assert.True(t, isLoadAll("654321")) + cfg1 := map[string]interface{}{common.ReloadKey: "123456"} + cfg2 := map[string]interface{}{common.ReloadKey: "654321"} + assert.False(t, isLoadAll(cfg1)) + assert.True(t, isLoadAll(cfg2)) } func TestLoadFromEnvWithReloadConfigInvalidSkipPattern(t *testing.T) { @@ -258,3 +260,31 @@ func TestValidLdapScope(t *testing.T) { } } +func Test_AddMissingKey(t *testing.T) { + + cfg := map[string]interface{}{ + common.LDAPURL: "sampleurl", + common.EmailPort: 555, + common.LDAPVerifyCert: true, + } + + type args struct { + cfg map[string]interface{} + } + tests := []struct { + name string + args args + }{ + {"Add default value", args{cfg}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + AddMissedKey(tt.args.cfg) + }) + } + + if _, ok := cfg[common.LDAPBaseDN]; !ok { + t.Errorf("Can not found default value for %v", common.LDAPBaseDN) + } + +} diff --git a/src/common/const.go b/src/common/const.go index c15dcd39b..e83629020 100644 --- a/src/common/const.go +++ b/src/common/const.go @@ -111,3 +111,87 @@ const ( LdapGroupAdminDn = "ldap_group_admin_dn" DefaultRegistryControllerEndpoint = "http://registryctl:8080" ) + +// Shared variable, not allowed to modify +var ( + // the keys of configurations which user can modify in PUT method and user can + // get in GET method + HarborValidKeys = []string{ + AUTHMode, + SelfRegistration, + LDAPURL, + LDAPSearchDN, + LDAPSearchPwd, + LDAPBaseDN, + LDAPUID, + LDAPFilter, + LDAPScope, + LDAPTimeout, + LDAPVerifyCert, + LDAPGroupAttributeName, + LDAPGroupBaseDN, + LDAPGroupSearchFilter, + LDAPGroupSearchScope, + EmailHost, + EmailPort, + EmailUsername, + EmailPassword, + EmailFrom, + EmailSSL, + EmailIdentity, + EmailInsecure, + ProjectCreationRestriction, + TokenExpiration, + ScanAllPolicy, + UAAClientID, + UAAClientSecret, + UAAEndpoint, + UAAVerifyCert, + ReadOnly, + } + + //value is default value + HarborStringKeysMap = map[string]string{ + AUTHMode: "db_auth", + LDAPURL: "", + LDAPSearchDN: "", + LDAPSearchPwd: "", + LDAPBaseDN: "", + LDAPUID: "", + LDAPFilter: "", + LDAPGroupAttributeName: "", + LDAPGroupBaseDN: "", + LDAPGroupSearchFilter: "", + EmailHost: "smtp.mydomain.com", + EmailUsername: "sample_admin@mydomain.com", + EmailPassword: "abc", + EmailFrom: "admin ", + EmailIdentity: "", + ProjectCreationRestriction: ProCrtRestrEveryone, + UAAClientID: "", + UAAEndpoint: "", + } + + HarborNumKeysMap = map[string]int{ + EmailPort: 25, + LDAPScope: 2, + LDAPTimeout: 5, + LDAPGroupSearchScope: 2, + TokenExpiration: 30, + } + + HarborBoolKeysMap = map[string]bool{ + EmailSSL: false, + EmailInsecure: false, + SelfRegistration: true, + LDAPVerifyCert: true, + UAAVerifyCert: true, + ReadOnly: false, + } + + HarborPasswordKeys = []string{ + EmailPassword, + LDAPSearchPwd, + UAAClientSecret, + } +) diff --git a/src/common/utils/utils.go b/src/common/utils/utils.go index 69f01001c..010f82f23 100644 --- a/src/common/utils/utils.go +++ b/src/common/utils/utils.go @@ -167,3 +167,35 @@ func ParseProjectIDOrName(value interface{}) (int64, string, error) { } return id, name, nil } + +//SafeCastString -- cast a object to string saftely +func SafeCastString(value interface{}) string { + if result, ok := value.(string); ok { + return result + } + return "" +} + +//SafeCastInt -- +func SafeCastInt(value interface{}) int { + if result, ok := value.(int); ok { + return result + } + return 0 +} + +//SafeCastBool -- +func SafeCastBool(value interface{}) bool { + if result, ok := value.(bool); ok { + return result + } + return false +} + +//SafeCastFloat64 -- +func SafeCastFloat64(value interface{}) float64 { + if result, ok := value.(float64); ok { + return result + } + return 0 +} diff --git a/src/common/utils/utils_test.go b/src/common/utils/utils_test.go index 7dcabc527..4a3d54063 100644 --- a/src/common/utils/utils_test.go +++ b/src/common/utils/utils_test.go @@ -248,3 +248,91 @@ func TestConvertMapToStruct(t *testing.T) { } } } + +func TestSafeCastString(t *testing.T) { + type args struct { + value interface{} + } + tests := []struct { + name string + args args + want string + }{ + {"nil value", args{nil}, ""}, + {"normal string", args{"sample"}, "sample"}, + {"wrong type", args{12}, ""}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := SafeCastString(tt.args.value); got != tt.want { + t.Errorf("SafeCastString() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestSafeCastBool(t *testing.T) { + type args struct { + value interface{} + } + tests := []struct { + name string + args args + want bool + }{ + {"nil value", args{nil}, false}, + {"normal bool", args{true}, true}, + {"wrong type", args{"true"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := SafeCastBool(tt.args.value); got != tt.want { + t.Errorf("SafeCastBool() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestSafeCastInt(t *testing.T) { + type args struct { + value interface{} + } + tests := []struct { + name string + args args + want int + }{ + {"nil value", args{nil}, 0}, + {"normal int", args{1234}, 1234}, + {"wrong type", args{"sample"}, 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := SafeCastInt(tt.args.value); got != tt.want { + t.Errorf("SafeCastInt() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestSafeCastFloat64(t *testing.T) { + type args struct { + value interface{} + } + tests := []struct { + name string + args args + want float64 + }{ + {"nil value", args{nil}, 0}, + {"normal float64", args{12.34}, 12.34}, + {"wrong type", args{false}, 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := SafeCastFloat64(tt.args.value); got != tt.want { + t.Errorf("SafeCastFloat64() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/src/ui/api/config.go b/src/ui/api/config.go index 50c1864b5..2cdd2abdb 100644 --- a/src/ui/api/config.go +++ b/src/ui/api/config.go @@ -26,88 +26,6 @@ import ( "github.com/vmware/harbor/src/ui/config" ) -var ( - // the keys of configurations which user can modify in PUT method and user can - // get in GET method - validKeys = []string{ - common.AUTHMode, - common.SelfRegistration, - common.LDAPURL, - common.LDAPSearchDN, - common.LDAPSearchPwd, - common.LDAPBaseDN, - common.LDAPUID, - common.LDAPFilter, - common.LDAPScope, - common.LDAPTimeout, - common.LDAPVerifyCert, - common.LDAPGroupAttributeName, - common.LDAPGroupBaseDN, - common.LDAPGroupSearchFilter, - common.LDAPGroupSearchScope, - common.EmailHost, - common.EmailPort, - common.EmailUsername, - common.EmailPassword, - common.EmailFrom, - common.EmailSSL, - common.EmailIdentity, - common.EmailInsecure, - common.ProjectCreationRestriction, - common.TokenExpiration, - common.ScanAllPolicy, - common.UAAClientID, - common.UAAClientSecret, - common.UAAEndpoint, - common.UAAVerifyCert, - common.ReadOnly, - } - - stringKeys = []string{ - common.AUTHMode, - common.LDAPURL, - common.LDAPSearchDN, - common.LDAPSearchPwd, - common.LDAPBaseDN, - common.LDAPUID, - common.LDAPFilter, - common.LDAPGroupAttributeName, - common.LDAPGroupBaseDN, - common.LDAPGroupSearchFilter, - common.EmailHost, - common.EmailUsername, - common.EmailPassword, - common.EmailFrom, - common.EmailIdentity, - common.ProjectCreationRestriction, - common.UAAClientID, - common.UAAEndpoint, - } - - numKeys = []string{ - common.EmailPort, - common.LDAPScope, - common.LDAPTimeout, - common.LDAPGroupSearchScope, - common.TokenExpiration, - } - - boolKeys = []string{ - common.EmailSSL, - common.EmailInsecure, - common.SelfRegistration, - common.LDAPVerifyCert, - common.UAAVerifyCert, - common.ReadOnly, - } - - passwordKeys = []string{ - common.EmailPassword, - common.LDAPSearchPwd, - common.UAAClientSecret, - } -) - // ConfigAPI ... type ConfigAPI struct { BaseController @@ -140,7 +58,7 @@ func (c *ConfigAPI) Get() { } cfgs := map[string]interface{}{} - for _, k := range validKeys { + for _, k := range common.HarborValidKeys { if v, ok := configs[k]; ok { cfgs[k] = v } @@ -162,7 +80,7 @@ func (c *ConfigAPI) Put() { c.DecodeJSONReq(&m) cfg := map[string]interface{}{} - for _, k := range validKeys { + for _, k := range common.HarborValidKeys { if v, ok := m[k]; ok { cfg[k] = v } @@ -205,7 +123,7 @@ func (c *ConfigAPI) Reset() { func validateCfg(c map[string]interface{}) (bool, error) { strMap := map[string]string{} - for _, k := range stringKeys { + for k := range common.HarborStringKeysMap { if _, ok := c[k]; !ok { continue } @@ -215,7 +133,7 @@ func validateCfg(c map[string]interface{}) (bool, error) { strMap[k] = c[k].(string) } numMap := map[string]int{} - for _, k := range numKeys { + for k := range common.HarborNumKeysMap { if _, ok := c[k]; !ok { continue } @@ -225,7 +143,7 @@ func validateCfg(c map[string]interface{}) (bool, error) { numMap[k] = int(c[k].(float64)) } boolMap := map[string]bool{} - for _, k := range boolKeys { + for k := range common.HarborBoolKeysMap { if _, ok := c[k]; !ok { continue } @@ -327,7 +245,7 @@ func validateCfg(c map[string]interface{}) (bool, error) { func convertForGet(cfg map[string]interface{}) (map[string]*value, error) { result := map[string]*value{} - for _, k := range passwordKeys { + for _, k := range common.HarborPasswordKeys { if _, ok := cfg[k]; ok { delete(cfg, k) } diff --git a/src/ui/api/systeminfo.go b/src/ui/api/systeminfo.go index 1a176d13a..e7e9a9448 100644 --- a/src/ui/api/systeminfo.go +++ b/src/ui/api/systeminfo.go @@ -167,17 +167,17 @@ func (sia *SystemInfoAPI) GetGeneralInfo() { _, caStatErr := os.Stat(defaultRootCert) harborVersion := sia.getVersion() info := GeneralInfo{ - AdmiralEndpoint: cfg[common.AdmiralEndpoint].(string), + AdmiralEndpoint: utils.SafeCastString(cfg[common.AdmiralEndpoint]), WithAdmiral: config.WithAdmiral(), WithNotary: config.WithNotary(), WithClair: config.WithClair(), - AuthMode: cfg[common.AUTHMode].(string), - ProjectCreationRestrict: cfg[common.ProjectCreationRestriction].(string), - SelfRegistration: cfg[common.SelfRegistration].(bool), + AuthMode: utils.SafeCastString(cfg[common.AUTHMode]), + ProjectCreationRestrict: utils.SafeCastString(cfg[common.ProjectCreationRestriction]), + SelfRegistration: utils.SafeCastBool(cfg[common.SelfRegistration]), RegistryURL: registryURL, HasCARoot: caStatErr == nil, HarborVersion: harborVersion, - RegistryStorageProviderName: cfg[common.RegistryStorageProviderName].(string), + RegistryStorageProviderName: utils.SafeCastString(cfg[common.RegistryStorageProviderName]), ReadOnly: config.ReadOnly(), } if info.WithClair { diff --git a/src/ui/config/config.go b/src/ui/config/config.go index ec651ec44..3ebba53e9 100644 --- a/src/ui/config/config.go +++ b/src/ui/config/config.go @@ -30,6 +30,7 @@ import ( comcfg "github.com/vmware/harbor/src/common/config" "github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/secret" + "github.com/vmware/harbor/src/common/utils" "github.com/vmware/harbor/src/common/utils/log" "github.com/vmware/harbor/src/ui/promgr" "github.com/vmware/harbor/src/ui/promgr/pmsdriver" @@ -187,7 +188,7 @@ func AuthMode() (string, error) { if err != nil { return "", err } - return cfg[common.AUTHMode].(string), nil + return utils.SafeCastString(cfg[common.AUTHMode]), nil } // TokenPrivateKeyPath returns the path to the key for signing token for registry @@ -206,14 +207,14 @@ func LDAPConf() (*models.LdapConf, error) { return nil, err } ldapConf := &models.LdapConf{} - ldapConf.LdapURL = cfg[common.LDAPURL].(string) - ldapConf.LdapSearchDn = cfg[common.LDAPSearchDN].(string) - ldapConf.LdapSearchPassword = cfg[common.LDAPSearchPwd].(string) - ldapConf.LdapBaseDn = cfg[common.LDAPBaseDN].(string) - ldapConf.LdapUID = cfg[common.LDAPUID].(string) - ldapConf.LdapFilter = cfg[common.LDAPFilter].(string) - ldapConf.LdapScope = int(cfg[common.LDAPScope].(float64)) - ldapConf.LdapConnectionTimeout = int(cfg[common.LDAPTimeout].(float64)) + ldapConf.LdapURL = utils.SafeCastString(cfg[common.LDAPURL]) + ldapConf.LdapSearchDn = utils.SafeCastString(cfg[common.LDAPSearchDN]) + ldapConf.LdapSearchPassword = utils.SafeCastString(cfg[common.LDAPSearchPwd]) + ldapConf.LdapBaseDn = utils.SafeCastString(cfg[common.LDAPBaseDN]) + ldapConf.LdapUID = utils.SafeCastString(cfg[common.LDAPUID]) + ldapConf.LdapFilter = utils.SafeCastString(cfg[common.LDAPFilter]) + ldapConf.LdapScope = int(utils.SafeCastFloat64(cfg[common.LDAPScope])) + ldapConf.LdapConnectionTimeout = int(utils.SafeCastFloat64(cfg[common.LDAPTimeout])) if cfg[common.LDAPVerifyCert] != nil { ldapConf.LdapVerifyCert = cfg[common.LDAPVerifyCert].(bool) } else { @@ -233,13 +234,13 @@ func LDAPGroupConf() (*models.LdapGroupConf, error) { ldapGroupConf := &models.LdapGroupConf{LdapGroupSearchScope: 2} if _, ok := cfg[common.LDAPGroupBaseDN]; ok { - ldapGroupConf.LdapGroupBaseDN = cfg[common.LDAPGroupBaseDN].(string) + ldapGroupConf.LdapGroupBaseDN = utils.SafeCastString(cfg[common.LDAPGroupBaseDN]) } if _, ok := cfg[common.LDAPGroupSearchFilter]; ok { - ldapGroupConf.LdapGroupFilter = cfg[common.LDAPGroupSearchFilter].(string) + ldapGroupConf.LdapGroupFilter = utils.SafeCastString(cfg[common.LDAPGroupSearchFilter]) } if _, ok := cfg[common.LDAPGroupAttributeName]; ok { - ldapGroupConf.LdapGroupNameAttribute = cfg[common.LDAPGroupAttributeName].(string) + ldapGroupConf.LdapGroupNameAttribute = utils.SafeCastString(cfg[common.LDAPGroupAttributeName]) } if _, ok := cfg[common.LDAPGroupSearchScope]; ok { if scopeStr, ok := cfg[common.LDAPGroupSearchScope].(string); ok { @@ -262,7 +263,7 @@ func TokenExpiration() (int, error) { return 0, err } - return int(cfg[common.TokenExpiration].(float64)), nil + return int(utils.SafeCastFloat64(cfg[common.TokenExpiration])), nil } // ExtEndpoint returns the external URL of Harbor: protocol://host:port @@ -271,7 +272,7 @@ func ExtEndpoint() (string, error) { if err != nil { return "", err } - return cfg[common.ExtEndpoint].(string), nil + return utils.SafeCastString(cfg[common.ExtEndpoint]), nil } // ExtURL returns the external URL: host:port @@ -298,7 +299,7 @@ func SelfRegistration() (bool, error) { if err != nil { return false, err } - return cfg[common.SelfRegistration].(bool), nil + return utils.SafeCastBool(cfg[common.SelfRegistration]), nil } // RegistryURL ... @@ -307,7 +308,7 @@ func RegistryURL() (string, error) { if err != nil { return "", err } - return cfg[common.RegistryURL].(string), nil + return utils.SafeCastString(cfg[common.RegistryURL]), nil } // InternalJobServiceURL returns jobservice URL for internal communication between Harbor containers @@ -321,7 +322,7 @@ func InternalJobServiceURL() string { if cfg[common.JobServiceURL] == nil { return common.DefaultJobserviceEndpoint } - return strings.TrimSuffix(cfg[common.JobServiceURL].(string), "/") + return strings.TrimSuffix(utils.SafeCastString(cfg[common.JobServiceURL]), "/") } // InternalUIURL returns the local ui url @@ -331,7 +332,7 @@ func InternalUIURL() string { log.Warningf("Failed to Get job service UI URL from backend, error: %v, will return default value.") return common.DefaultUIEndpoint } - return strings.TrimSuffix(cfg[common.UIURL].(string), "/") + return strings.TrimSuffix(utils.SafeCastString(cfg[common.UIURL]), "/") } @@ -351,7 +352,7 @@ func InternalNotaryEndpoint() string { if cfg[common.NotaryURL] == nil { return common.DefaultNotaryEndpoint } - return cfg[common.NotaryURL].(string) + return utils.SafeCastString(cfg[common.NotaryURL]) } // InitialAdminPassword returns the initial password for administrator @@ -360,7 +361,7 @@ func InitialAdminPassword() (string, error) { if err != nil { return "", err } - return cfg[common.AdminInitialPassword].(string), nil + return utils.SafeCastString(cfg[common.AdminInitialPassword]), nil } // OnlyAdminCreateProject returns the flag to restrict that only sys admin can create project @@ -369,7 +370,7 @@ func OnlyAdminCreateProject() (bool, error) { if err != nil { return true, err } - return cfg[common.ProjectCreationRestriction].(string) == common.ProCrtRestrAdmOnly, nil + return utils.SafeCastString(cfg[common.ProjectCreationRestriction]) == common.ProCrtRestrAdmOnly, nil } // Email returns email server settings @@ -380,14 +381,14 @@ func Email() (*models.Email, error) { } email := &models.Email{} - email.Host = cfg[common.EmailHost].(string) - email.Port = int(cfg[common.EmailPort].(float64)) - email.Username = cfg[common.EmailUsername].(string) - email.Password = cfg[common.EmailPassword].(string) - email.SSL = cfg[common.EmailSSL].(bool) - email.From = cfg[common.EmailFrom].(string) - email.Identity = cfg[common.EmailIdentity].(string) - email.Insecure = cfg[common.EmailInsecure].(bool) + email.Host = utils.SafeCastString(cfg[common.EmailHost]) + email.Port = int(utils.SafeCastFloat64(cfg[common.EmailPort])) + email.Username = utils.SafeCastString(cfg[common.EmailUsername]) + email.Password = utils.SafeCastString(cfg[common.EmailPassword]) + email.SSL = utils.SafeCastBool(cfg[common.EmailSSL]) + email.From = utils.SafeCastString(cfg[common.EmailFrom]) + email.Identity = utils.SafeCastString(cfg[common.EmailIdentity]) + email.Insecure = utils.SafeCastBool(cfg[common.EmailInsecure]) return email, nil } @@ -403,11 +404,11 @@ func Database() (*models.Database, error) { database.Type = cfg[common.DatabaseType].(string) postgresql := &models.PostGreSQL{} - postgresql.Host = cfg[common.PostGreSQLHOST].(string) - postgresql.Port = int(cfg[common.PostGreSQLPort].(float64)) - postgresql.Username = cfg[common.PostGreSQLUsername].(string) - postgresql.Password = cfg[common.PostGreSQLPassword].(string) - postgresql.Database = cfg[common.PostGreSQLDatabase].(string) + postgresql.Host = utils.SafeCastString(cfg[common.PostGreSQLHOST]) + postgresql.Port = int(utils.SafeCastFloat64(cfg[common.PostGreSQLPort])) + postgresql.Username = utils.SafeCastString(cfg[common.PostGreSQLUsername]) + postgresql.Password = utils.SafeCastString(cfg[common.PostGreSQLPassword]) + postgresql.Database = utils.SafeCastString(cfg[common.PostGreSQLDatabase]) database.PostGreSQL = postgresql return database, nil @@ -433,7 +434,7 @@ func WithNotary() bool { log.Warningf("Failed to get configuration, will return WithNotary == false") return false } - return cfg[common.WithNotary].(bool) + return utils.SafeCastBool(cfg[common.WithNotary]) } // WithClair returns a bool value to indicate if Harbor's deployed with Clair @@ -443,7 +444,7 @@ func WithClair() bool { log.Errorf("Failed to get configuration, will return WithClair == false") return false } - return cfg[common.WithClair].(bool) + return utils.SafeCastBool(cfg[common.WithClair]) } // ClairEndpoint returns the end point of clair instance, by default it's the one deployed within Harbor. @@ -453,7 +454,7 @@ func ClairEndpoint() string { log.Errorf("Failed to get configuration, use default clair endpoint") return common.DefaultClairEndpoint } - return cfg[common.ClairURL].(string) + return utils.SafeCastString(cfg[common.ClairURL]) } // ClairDB return Clair db info @@ -464,11 +465,11 @@ func ClairDB() (*models.PostGreSQL, error) { return nil, err } clairDB := &models.PostGreSQL{} - clairDB.Host = cfg[common.ClairDBHost].(string) - clairDB.Port = int(cfg[common.ClairDBPort].(float64)) - clairDB.Username = cfg[common.ClairDBUsername].(string) - clairDB.Password = cfg[common.ClairDBPassword].(string) - clairDB.Database = cfg[common.ClairDB].(string) + clairDB.Host = utils.SafeCastString(cfg[common.ClairDBHost]) + clairDB.Port = int(utils.SafeCastFloat64(cfg[common.ClairDBPort])) + clairDB.Username = utils.SafeCastString(cfg[common.ClairDBUsername]) + clairDB.Password = utils.SafeCastString(cfg[common.ClairDBPassword]) + clairDB.Database = utils.SafeCastString(cfg[common.ClairDB]) return clairDB, nil } @@ -483,7 +484,7 @@ func AdmiralEndpoint() string { if e, ok := cfg[common.AdmiralEndpoint].(string); !ok || e == "NA" { return "" } - return cfg[common.AdmiralEndpoint].(string) + return utils.SafeCastString(cfg[common.AdmiralEndpoint]) } // ScanAllPolicy returns the policy which controls the scan all. @@ -522,10 +523,10 @@ func UAASettings() (*models.UAASettings, error) { return nil, err } us := &models.UAASettings{ - Endpoint: cfg[common.UAAEndpoint].(string), - ClientID: cfg[common.UAAClientID].(string), - ClientSecret: cfg[common.UAAClientSecret].(string), - VerifyCert: cfg[common.UAAVerifyCert].(bool), + Endpoint: utils.SafeCastString(cfg[common.UAAEndpoint]), + ClientID: utils.SafeCastString(cfg[common.UAAClientID]), + ClientSecret: utils.SafeCastString(cfg[common.UAAClientSecret]), + VerifyCert: utils.SafeCastBool(cfg[common.UAAVerifyCert]), } return us, nil } @@ -537,5 +538,5 @@ func ReadOnly() bool { log.Errorf("Failed to get configuration, will return false as read only, error: %v", err) return false } - return cfg[common.ReadOnly].(bool) + return utils.SafeCastBool(cfg[common.ReadOnly]) }