Extend further validation of config values (#8469)

- This PR allows config KVS to be validated properly
  without being affected by ENV overrides, rejects
  invalid values during set operation

- Expands unit tests and refactors the error handling
  for notification targets, returns error instead of
  ignoring targets for invalid KVS

- Does all the prep-work for implementing safe-mode
  style operation for MinIO server, introduces a new
  global variable to toggle safe mode based operations
  NOTE: this PR itself doesn't provide safe mode operations
This commit is contained in:
Harshavardhana
2019-10-30 23:39:09 -07:00
committed by kannappanr
parent 599aae5ba6
commit 9e7a3e6adc
53 changed files with 723 additions and 396 deletions

View File

@@ -21,6 +21,7 @@ import (
"github.com/minio/minio/cmd/config"
"github.com/minio/minio/pkg/env"
xnet "github.com/minio/minio/pkg/net"
)
// KMSConfig has the KMS config for hashicorp vault
@@ -148,9 +149,21 @@ func LookupConfig(kvs config.KVS) (KMSConfig, error) {
if !stateBool {
return kmsCfg, nil
}
vcfg := VaultConfig{}
// Lookup Hashicorp-Vault configuration & overwrite config entry if ENV var is present
vcfg.Endpoint = env.Get(EnvKMSVaultEndpoint, kvs.Get(KMSVaultEndpoint))
vcfg := VaultConfig{
Auth: VaultAuth{
Type: "approle",
},
}
endpointStr := env.Get(EnvKMSVaultEndpoint, kvs.Get(KMSVaultEndpoint))
if endpointStr != "" {
// Lookup Hashicorp-Vault configuration & overwrite config entry if ENV var is present
endpoint, err := xnet.ParseHTTPURL(endpointStr)
if err != nil {
return kmsCfg, err
}
endpointStr = endpoint.String()
}
vcfg.Endpoint = endpointStr
vcfg.CAPath = env.Get(EnvKMSVaultCAPath, kvs.Get(KMSVaultCAPath))
vcfg.Auth.Type = env.Get(EnvKMSVaultAuthType, kvs.Get(KMSVaultAuthType))
vcfg.Auth.AppRole.ID = env.Get(EnvKMSVaultAppRoleID, kvs.Get(KMSVaultAppRoleID))
@@ -177,7 +190,7 @@ func LookupConfig(kvs config.KVS) (KMSConfig, error) {
// NewKMS - initialize a new KMS.
func NewKMS(cfg KMSConfig) (kms KMS, err error) {
// Lookup KMS master keys - only available through ENV.
if masterKeyLegacy, ok := env.Lookup(EnvKMSMasterKeyLegacy); ok {
if masterKeyLegacy := env.Get(EnvKMSMasterKeyLegacy, ""); len(masterKeyLegacy) != 0 {
if !cfg.Vault.IsEmpty() { // Vault and KMS master key provided
return kms, errors.New("Ambiguous KMS configuration: vault configuration and a master key are provided at the same time")
}
@@ -185,7 +198,7 @@ func NewKMS(cfg KMSConfig) (kms KMS, err error) {
if err != nil {
return kms, err
}
} else if masterKey, ok := env.Lookup(EnvKMSMasterKey); ok {
} else if masterKey := env.Get(EnvKMSMasterKey, ""); len(masterKey) != 0 {
if !cfg.Vault.IsEmpty() { // Vault and KMS master key provided
return kms, errors.New("Ambiguous KMS configuration: vault configuration and a master key are provided at the same time")
}

View File

@@ -22,6 +22,7 @@ import (
"github.com/minio/minio/cmd/config"
"github.com/minio/minio/pkg/env"
xnet "github.com/minio/minio/pkg/net"
)
const (
@@ -119,9 +120,16 @@ func lookupConfigLegacy(kvs config.KVS) (KMSConfig, error) {
if err != nil {
return KMSConfig{}, err
}
cfg := KMSConfig{
AutoEncryption: autoBool,
Vault: VaultConfig{
Auth: VaultAuth{
Type: "approle",
},
},
}
// Assume default as "on" for legacy config since we didn't have a _STATE
// flag to turn it off, but we should honor it nonetheless to turn it off
// if the vault endpoint is down and there is no way to start the server.
@@ -132,29 +140,37 @@ func lookupConfigLegacy(kvs config.KVS) (KMSConfig, error) {
if !stateBool {
return cfg, nil
}
vcfg := VaultConfig{}
// Lookup Hashicorp-Vault configuration & overwrite config entry if ENV var is present
vcfg.Endpoint = env.Get(EnvVaultEndpoint, kvs.Get(KMSVaultEndpoint))
vcfg.CAPath = env.Get(EnvVaultCAPath, kvs.Get(KMSVaultCAPath))
vcfg.Auth.Type = env.Get(EnvVaultAuthType, kvs.Get(KMSVaultAuthType))
vcfg.Auth.AppRole.ID = env.Get(EnvVaultAppRoleID, kvs.Get(KMSVaultAppRoleID))
vcfg.Auth.AppRole.Secret = env.Get(EnvVaultAppSecretID, kvs.Get(KMSVaultAppRoleSecret))
vcfg.Key.Name = env.Get(EnvVaultKeyName, kvs.Get(KMSVaultKeyName))
vcfg.Namespace = env.Get(EnvVaultNamespace, kvs.Get(KMSVaultNamespace))
endpointStr := env.Get(EnvKMSVaultEndpoint, kvs.Get(KMSVaultEndpoint))
if endpointStr != "" {
// Lookup Hashicorp-Vault configuration & overwrite config entry if ENV var is present
endpoint, err := xnet.ParseHTTPURL(endpointStr)
if err != nil {
return cfg, err
}
endpointStr = endpoint.String()
}
cfg.Vault.Endpoint = endpointStr
cfg.Vault.CAPath = env.Get(EnvVaultCAPath, kvs.Get(KMSVaultCAPath))
cfg.Vault.Auth.Type = env.Get(EnvVaultAuthType, kvs.Get(KMSVaultAuthType))
cfg.Vault.Auth.AppRole.ID = env.Get(EnvVaultAppRoleID, kvs.Get(KMSVaultAppRoleID))
cfg.Vault.Auth.AppRole.Secret = env.Get(EnvVaultAppSecretID, kvs.Get(KMSVaultAppRoleSecret))
cfg.Vault.Key.Name = env.Get(EnvVaultKeyName, kvs.Get(KMSVaultKeyName))
cfg.Vault.Namespace = env.Get(EnvVaultNamespace, kvs.Get(KMSVaultNamespace))
keyVersion := env.Get(EnvVaultKeyVersion, kvs.Get(KMSVaultKeyVersion))
if keyVersion != "" {
vcfg.Key.Version, err = strconv.Atoi(keyVersion)
cfg.Vault.Key.Version, err = strconv.Atoi(keyVersion)
if err != nil {
return cfg, fmt.Errorf("Invalid ENV variable: Unable to parse %s value (`%s`)",
EnvVaultKeyVersion, keyVersion)
}
}
if err = vcfg.Verify(); err != nil {
if err = cfg.Vault.Verify(); err != nil {
return cfg, err
}
cfg.Vault = vcfg
return cfg, nil
}