Order all keys in config (#8541)

New changes

- return default values when sub-sys is
  not configured.
- state is hidden parameter now
- remove worm mode to be saved in config
This commit is contained in:
Harshavardhana
2019-11-20 15:10:24 -08:00
committed by GitHub
parent ca96560d56
commit 5ac4b517c9
51 changed files with 1436 additions and 642 deletions

View File

@@ -62,7 +62,6 @@ const (
PolicyOPASubSys = "policy_opa"
IdentityOpenIDSubSys = "identity_openid"
IdentityLDAPSubSys = "identity_ldap"
WormSubSys = "worm"
CacheSubSys = "cache"
RegionSubSys = "region"
EtcdSubSys = "etcd"
@@ -94,7 +93,6 @@ const (
// SubSystems - all supported sub-systems
var SubSystems = set.CreateStringSet([]string{
CredentialsSubSys,
WormSubSys,
RegionSubSys,
EtcdSubSys,
CacheSubSys,
@@ -121,7 +119,6 @@ var SubSystems = set.CreateStringSet([]string{
// SubSystemsSingleTargets - subsystems which only support single target.
var SubSystemsSingleTargets = set.CreateStringSet([]string{
CredentialsSubSys,
WormSubSys,
RegionSubSys,
EtcdSubSys,
CacheSubSys,
@@ -148,9 +145,15 @@ const (
EnvWordDelimiter = `_`
)
// KV - is a shorthand of each key value.
type KV struct {
Key string `json:"key"`
Value string `json:"value"`
}
// KVS - is a shorthand for some wrapper functions
// to operate on list of key values.
type KVS map[string]string
type KVS []KV
// Empty - return if kv is empty
func (kvs KVS) Empty() bool {
@@ -159,15 +162,15 @@ func (kvs KVS) Empty() bool {
func (kvs KVS) String() string {
var s strings.Builder
for k, v := range kvs {
for _, kv := range kvs {
// Do not need to print if state is on
if k == State && v == StateOn {
if kv.Key == State && kv.Value == StateOn {
continue
}
s.WriteString(k)
s.WriteString(kv.Key)
s.WriteString(KvSeparator)
s.WriteString(KvDoubleQuote)
s.WriteString(v)
s.WriteString(kv.Value)
s.WriteString(KvDoubleQuote)
s.WriteString(KvSpaceSeparator)
}
@@ -176,7 +179,21 @@ func (kvs KVS) String() string {
// Get - returns the value of a key, if not found returns empty.
func (kvs KVS) Get(key string) string {
return kvs[key]
v, ok := kvs.Lookup(key)
if ok {
return v
}
return ""
}
// Lookup - lookup a key in a list of KVS
func (kvs KVS) Lookup(key string) (string, bool) {
for _, kv := range kvs {
if kv.Key == key {
return kv.Value, true
}
}
return "", false
}
// Config - MinIO server config structure.
@@ -202,21 +219,29 @@ func (c Config) String() string {
// Default KV configs for worm and region
var (
DefaultCredentialKVS = KVS{
State: StateOff,
Comment: "This is a default credential configuration",
AccessKey: auth.DefaultAccessKey,
SecretKey: auth.DefaultSecretKey,
}
DefaultWormKVS = KVS{
State: StateOff,
Comment: "This is a default WORM configuration",
KV{
Key: State,
Value: StateOff,
},
KV{
Key: AccessKey,
Value: auth.DefaultAccessKey,
},
KV{
Key: SecretKey,
Value: auth.DefaultSecretKey,
},
}
DefaultRegionKVS = KVS{
State: StateOff,
Comment: "This is a default Region configuration",
RegionName: "",
KV{
Key: State,
Value: StateOff,
},
KV{
Key: RegionName,
Value: "",
},
}
)
@@ -259,30 +284,20 @@ func LookupRegion(kv KVS) (string, error) {
// returns error if it find extra or superflous keys.
func CheckValidKeys(subSys string, kv KVS, validKVS KVS) error {
nkv := KVS{}
for k, v := range kv {
if _, ok := validKVS[k]; !ok {
nkv[k] = v
for _, kv := range kv {
if _, ok := validKVS.Lookup(kv.Key); !ok {
nkv = append(nkv, kv)
}
}
if len(nkv) > 0 {
return Error(fmt.Sprintf("found invalid keys (%s) for '%s' sub-system", nkv.String(), subSys))
return Errorf("found invalid keys (%s) for '%s' sub-system", nkv.String(), subSys)
}
return nil
}
// LookupWorm - check if worm is enabled
func LookupWorm(kv KVS) (bool, error) {
if err := CheckValidKeys(WormSubSys, kv, DefaultWormKVS); err != nil {
return false, err
}
worm := env.Get(EnvWorm, "")
if worm == "" {
worm = env.Get(EnvWormState, kv.Get(State))
if worm == "" {
return false, nil
}
}
return ParseBool(worm)
func LookupWorm() (bool, error) {
return ParseBool(env.Get(EnvWorm, StateOff))
}
// New - initialize a new server config.
@@ -295,17 +310,17 @@ func New() Config {
}
// GetKVS - get kvs from specific subsystem.
func (c Config) GetKVS(s string) (map[string]KVS, error) {
func (c Config) GetKVS(s string, defaultKVS map[string]KVS) (map[string]KVS, error) {
if len(s) == 0 {
return nil, Error("input cannot be empty")
}
inputs := strings.Fields(s)
if len(inputs) > 1 {
return nil, Error(fmt.Sprintf("invalid number of arguments %s", s))
return nil, Errorf("invalid number of arguments %s", s)
}
subSystemValue := strings.SplitN(inputs[0], SubSystemSeparator, 2)
if len(subSystemValue) == 0 {
return nil, Error(fmt.Sprintf("invalid number of arguments %s", s))
return nil, Errorf("invalid number of arguments %s", s)
}
found := SubSystems.Contains(subSystemValue[0])
if !found {
@@ -314,36 +329,38 @@ func (c Config) GetKVS(s string) (map[string]KVS, error) {
found = !SubSystems.FuncMatch(strings.HasPrefix, subSystemValue[0]).IsEmpty() && len(subSystemValue) == 1
}
if !found {
return nil, Error(fmt.Sprintf("unknown sub-system %s", s))
return nil, Errorf("unknown sub-system %s", s)
}
kvs := make(map[string]KVS)
var ok bool
subSysPrefix := subSystemValue[0]
if len(subSystemValue) == 2 {
if len(subSystemValue[1]) == 0 {
err := fmt.Sprintf("sub-system target '%s' cannot be empty", s)
return nil, Error(err)
return nil, Errorf("sub-system target '%s' cannot be empty", s)
}
kvs[inputs[0]], ok = c[subSystemValue[0]][subSystemValue[1]]
kvs[inputs[0]], ok = c[subSysPrefix][subSystemValue[1]]
if !ok {
err := fmt.Sprintf("sub-system target '%s' doesn't exist", s)
return nil, Error(err)
return nil, Errorf("sub-system target '%s' doesn't exist", s)
}
return kvs, nil
}
for subSys, subSysTgts := range c {
if !strings.HasPrefix(subSys, subSystemValue[0]) {
continue
}
for k, kv := range subSysTgts {
if k != Default {
kvs[subSys+SubSystemSeparator+k] = kv
} else {
kvs[subSys] = kv
} else {
for subSys, subSysTgts := range c {
if !strings.HasPrefix(subSys, subSysPrefix) {
continue
}
for k, kv := range subSysTgts {
if k != Default {
kvs[subSys+SubSystemSeparator+k] = kv
} else {
kvs[subSys] = kv
}
}
}
}
if len(kvs) == 0 {
kvs[subSysPrefix] = defaultKVS[subSysPrefix]
return kvs, nil
}
return kvs, nil
}
@@ -354,24 +371,28 @@ func (c Config) DelKVS(s string) error {
}
inputs := strings.Fields(s)
if len(inputs) > 1 {
return Error(fmt.Sprintf("invalid number of arguments %s", s))
return Errorf("invalid number of arguments %s", s)
}
subSystemValue := strings.SplitN(inputs[0], SubSystemSeparator, 2)
if len(subSystemValue) == 0 {
return Error(fmt.Sprintf("invalid number of arguments %s", s))
return Errorf("invalid number of arguments %s", s)
}
if !SubSystems.Contains(subSystemValue[0]) {
return Error(fmt.Sprintf("unknown sub-system %s", s))
return Errorf("unknown sub-system %s", s)
}
tgt := Default
subSys := subSystemValue[0]
if len(subSystemValue) == 2 {
if len(subSystemValue[1]) == 0 {
err := fmt.Sprintf("sub-system target '%s' cannot be empty", s)
return Error(err)
return Errorf("sub-system target '%s' cannot be empty", s)
}
delete(c[subSystemValue[0]], subSystemValue[1])
return nil
tgt = subSystemValue[1]
}
delete(c[subSystemValue[0]], Default)
_, ok := c[subSys][tgt]
if !ok {
return Errorf("sub-system %s already deleted", s)
}
delete(c[subSys], tgt)
return nil
}
@@ -387,35 +408,32 @@ func (c Config) Clone() Config {
for subSys, tgtKV := range c {
cp[subSys] = make(map[string]KVS)
for tgt, kv := range tgtKV {
cp[subSys][tgt] = KVS{}
for k, v := range kv {
cp[subSys][tgt][k] = v
}
cp[subSys][tgt] = append(cp[subSys][tgt], kv...)
}
}
return cp
}
// SetKVS - set specific key values per sub-system.
func (c Config) SetKVS(s string) error {
func (c Config) SetKVS(s string, defaultKVS map[string]KVS) error {
if len(s) == 0 {
return Error("input arguments cannot be empty")
}
inputs := strings.SplitN(s, KvSpaceSeparator, 2)
if len(inputs) <= 1 {
return Error(fmt.Sprintf("invalid number of arguments '%s'", s))
return Errorf("invalid number of arguments '%s'", s)
}
subSystemValue := strings.SplitN(inputs[0], SubSystemSeparator, 2)
if len(subSystemValue) == 0 {
return Error(fmt.Sprintf("invalid number of arguments %s", s))
return Errorf("invalid number of arguments %s", s)
}
if !SubSystems.Contains(subSystemValue[0]) {
return Error(fmt.Sprintf("unknown sub-system %s", s))
return Errorf("unknown sub-system %s", s)
}
if SubSystemsSingleTargets.Contains(subSystemValue[0]) && len(subSystemValue) == 2 {
return Error(fmt.Sprintf("sub-system '%s' only supports single target", subSystemValue[0]))
return Errorf("sub-system '%s' only supports single target", subSystemValue[0])
}
var kvs = KVS{}
@@ -426,35 +444,48 @@ func (c Config) SetKVS(s string) error {
continue
}
if len(kv) == 1 && prevK != "" {
kvs[prevK] = strings.Join([]string{kvs[prevK], sanitizeValue(kv[0])}, KvSpaceSeparator)
kvs = append(kvs, KV{
Key: prevK,
Value: strings.Join([]string{kvs.Get(prevK), sanitizeValue(kv[0])}, KvSpaceSeparator),
})
continue
}
if len(kv) == 1 {
return Error(fmt.Sprintf("key '%s', cannot have empty value", kv[0]))
return Errorf("key '%s', cannot have empty value", kv[0])
}
prevK = kv[0]
kvs[kv[0]] = sanitizeValue(kv[1])
kvs = append(kvs, KV{
Key: kv[0],
Value: sanitizeValue(kv[1]),
})
}
tgt := Default
subSys := subSystemValue[0]
if len(subSystemValue) == 2 {
tgt = subSystemValue[1]
}
_, ok := c[subSystemValue[0]][tgt]
_, ok := c[subSys][tgt]
if !ok {
c[subSystemValue[0]][tgt] = KVS{}
c[subSys][tgt] = KVS{}
} else {
c[subSys][tgt] = kvs
}
for k, v := range kvs {
c[subSystemValue[0]][tgt][k] = v
}
_, ok = c[subSystemValue[0]][tgt][State]
_, ok = c[subSys][tgt].Lookup(State)
if !ok {
// implicit state "on" if not specified.
c[subSystemValue[0]][tgt][State] = StateOn
c[subSys][tgt] = append(c[subSys][tgt], KV{
Key: State,
Value: StateOn,
})
}
for _, kv := range defaultKVS[subSys] {
_, ok := c[subSys][tgt].Lookup(kv.Key)
if !ok {
c[subSys][tgt] = append(c[subSys][tgt], kv)
}
}
return nil
}