mirror of https://github.com/status-im/consul.git
config: use the new HookTranslateKeys instead of lib.TranslateKeys
With the exception of CA provider config, which will be migrated at some later time.
This commit is contained in:
parent
8ced4300c8
commit
6a2d7d77c0
|
@ -6,6 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/lib"
|
"github.com/hashicorp/consul/lib"
|
||||||
|
"github.com/hashicorp/consul/lib/decode"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/hcl"
|
"github.com/hashicorp/hcl"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
|
@ -108,30 +109,9 @@ func Parse(data string, format string) (c Config, keys []string, err error) {
|
||||||
"config_entries.bootstrap", // completely ignore this tree (fixed elsewhere)
|
"config_entries.bootstrap", // completely ignore this tree (fixed elsewhere)
|
||||||
})
|
})
|
||||||
|
|
||||||
// There is a difference of representation of some fields depending on
|
|
||||||
// where they are used. The HTTP API uses CamelCase whereas the config
|
|
||||||
// files use snake_case and between the two there is no automatic mapping.
|
|
||||||
// While the JSON and HCL parsers match keys without case (both `id` and
|
|
||||||
// `ID` are mapped to an ID field) the same thing does not happen between
|
|
||||||
// CamelCase and snake_case. Since changing either format would break
|
|
||||||
// existing setups we have to support both and slowly transition to one of
|
|
||||||
// the formats. Also, there is at least one case where we use the "wrong"
|
|
||||||
// key and want to map that to the new key to support deprecation -
|
|
||||||
// see [GH-3179]. TranslateKeys maps potentially CamelCased values to the
|
|
||||||
// snake_case that is used in the config file parser. If both the CamelCase
|
|
||||||
// and snake_case values are set the snake_case value is used and the other
|
|
||||||
// value is discarded.
|
|
||||||
lib.TranslateKeys(m, map[string]string{
|
|
||||||
"deregistercriticalserviceafter": "deregister_critical_service_after",
|
|
||||||
"dockercontainerid": "docker_container_id",
|
|
||||||
"scriptargs": "args",
|
|
||||||
"serviceid": "service_id",
|
|
||||||
"tlsskipverify": "tls_skip_verify",
|
|
||||||
"config_entries.bootstrap": "",
|
|
||||||
})
|
|
||||||
|
|
||||||
var md mapstructure.Metadata
|
var md mapstructure.Metadata
|
||||||
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||||
|
DecodeHook: decode.HookTranslateKeys,
|
||||||
Metadata: &md,
|
Metadata: &md,
|
||||||
Result: &c,
|
Result: &c,
|
||||||
})
|
})
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/lib"
|
"github.com/hashicorp/consul/lib"
|
||||||
|
"github.com/hashicorp/consul/lib/decode"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -105,15 +106,12 @@ func decodeDiscoveryChainReadRequest(raw map[string]interface{}) (*discoveryChai
|
||||||
// to do this part first.
|
// to do this part first.
|
||||||
raw = lib.PatchSliceOfMaps(raw, nil, nil)
|
raw = lib.PatchSliceOfMaps(raw, nil, nil)
|
||||||
|
|
||||||
lib.TranslateKeys(raw, map[string]string{
|
|
||||||
"override_mesh_gateway": "overridemeshgateway",
|
|
||||||
"override_protocol": "overrideprotocol",
|
|
||||||
"override_connect_timeout": "overrideconnecttimeout",
|
|
||||||
})
|
|
||||||
|
|
||||||
var apiReq discoveryChainReadRequest
|
var apiReq discoveryChainReadRequest
|
||||||
decodeConf := &mapstructure.DecoderConfig{
|
decodeConf := &mapstructure.DecoderConfig{
|
||||||
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
|
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
||||||
|
decode.HookTranslateKeys,
|
||||||
|
mapstructure.StringToTimeDurationHookFunc(),
|
||||||
|
),
|
||||||
Result: &apiReq,
|
Result: &apiReq,
|
||||||
WeaklyTypedInput: true,
|
WeaklyTypedInput: true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/cache"
|
"github.com/hashicorp/consul/agent/cache"
|
||||||
"github.com/hashicorp/consul/lib"
|
"github.com/hashicorp/consul/lib"
|
||||||
|
"github.com/hashicorp/consul/lib/decode"
|
||||||
"github.com/hashicorp/go-msgpack/codec"
|
"github.com/hashicorp/go-msgpack/codec"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/mitchellh/hashstructure"
|
"github.com/mitchellh/hashstructure"
|
||||||
|
@ -283,7 +284,7 @@ func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) {
|
||||||
return nil, fmt.Errorf("Kind value in payload is not a string")
|
return nil, fmt.Errorf("Kind value in payload is not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
skipWhenPatching, translateKeysDict, err := ConfigEntryDecodeRulesForKind(entry.GetKind())
|
skipWhenPatching, err := ConfigEntryDecodeRulesForKind(entry.GetKind())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -292,11 +293,12 @@ func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) {
|
||||||
// to do this part first.
|
// to do this part first.
|
||||||
raw = lib.PatchSliceOfMaps(raw, skipWhenPatching, nil)
|
raw = lib.PatchSliceOfMaps(raw, skipWhenPatching, nil)
|
||||||
|
|
||||||
lib.TranslateKeys(raw, translateKeysDict)
|
|
||||||
|
|
||||||
var md mapstructure.Metadata
|
var md mapstructure.Metadata
|
||||||
decodeConf := &mapstructure.DecoderConfig{
|
decodeConf := &mapstructure.DecoderConfig{
|
||||||
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
|
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
||||||
|
decode.HookTranslateKeys,
|
||||||
|
mapstructure.StringToTimeDurationHookFunc(),
|
||||||
|
),
|
||||||
Metadata: &md,
|
Metadata: &md,
|
||||||
Result: &entry,
|
Result: &entry,
|
||||||
WeaklyTypedInput: true,
|
WeaklyTypedInput: true,
|
||||||
|
@ -327,27 +329,17 @@ func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) {
|
||||||
// ConfigEntryDecodeRulesForKind returns rules for 'fixing' config entry key
|
// ConfigEntryDecodeRulesForKind returns rules for 'fixing' config entry key
|
||||||
// formats by kind. This is shared between the 'structs' and 'api' variations
|
// formats by kind. This is shared between the 'structs' and 'api' variations
|
||||||
// of config entries.
|
// of config entries.
|
||||||
func ConfigEntryDecodeRulesForKind(kind string) (skipWhenPatching []string, translateKeysDict map[string]string, err error) {
|
func ConfigEntryDecodeRulesForKind(kind string) (skipWhenPatching []string, err error) {
|
||||||
switch kind {
|
switch kind {
|
||||||
case ProxyDefaults:
|
case ProxyDefaults:
|
||||||
return []string{
|
return []string{
|
||||||
"expose.paths",
|
"expose.paths",
|
||||||
"Expose.Paths",
|
"Expose.Paths",
|
||||||
}, map[string]string{
|
|
||||||
"local_path_port": "localpathport",
|
|
||||||
"listener_port": "listenerport",
|
|
||||||
"mesh_gateway": "meshgateway",
|
|
||||||
"config": "",
|
|
||||||
}, nil
|
}, nil
|
||||||
case ServiceDefaults:
|
case ServiceDefaults:
|
||||||
return []string{
|
return []string{
|
||||||
"expose.paths",
|
"expose.paths",
|
||||||
"Expose.Paths",
|
"Expose.Paths",
|
||||||
}, map[string]string{
|
|
||||||
"local_path_port": "localpathport",
|
|
||||||
"listener_port": "listenerport",
|
|
||||||
"mesh_gateway": "meshgateway",
|
|
||||||
"external_sni": "externalsni",
|
|
||||||
}, nil
|
}, nil
|
||||||
case ServiceRouter:
|
case ServiceRouter:
|
||||||
return []string{
|
return []string{
|
||||||
|
@ -357,50 +349,28 @@ func ConfigEntryDecodeRulesForKind(kind string) (skipWhenPatching []string, tran
|
||||||
"Routes.Match.HTTP.Header",
|
"Routes.Match.HTTP.Header",
|
||||||
"routes.match.http.query_param",
|
"routes.match.http.query_param",
|
||||||
"Routes.Match.HTTP.QueryParam",
|
"Routes.Match.HTTP.QueryParam",
|
||||||
}, map[string]string{
|
|
||||||
"num_retries": "numretries",
|
|
||||||
"path_exact": "pathexact",
|
|
||||||
"path_prefix": "pathprefix",
|
|
||||||
"path_regex": "pathregex",
|
|
||||||
"prefix_rewrite": "prefixrewrite",
|
|
||||||
"query_param": "queryparam",
|
|
||||||
"request_timeout": "requesttimeout",
|
|
||||||
"retry_on_connect_failure": "retryonconnectfailure",
|
|
||||||
"retry_on_status_codes": "retryonstatuscodes",
|
|
||||||
"service_subset": "servicesubset",
|
|
||||||
}, nil
|
}, nil
|
||||||
case ServiceSplitter:
|
case ServiceSplitter:
|
||||||
return []string{
|
return []string{
|
||||||
"splits",
|
"splits",
|
||||||
"Splits",
|
"Splits",
|
||||||
}, map[string]string{
|
|
||||||
"service_subset": "servicesubset",
|
|
||||||
}, nil
|
}, nil
|
||||||
case ServiceResolver:
|
case ServiceResolver:
|
||||||
return nil, map[string]string{
|
return nil, nil
|
||||||
"connect_timeout": "connecttimeout",
|
|
||||||
"default_subset": "defaultsubset",
|
|
||||||
"only_passing": "onlypassing",
|
|
||||||
"service_subset": "servicesubset",
|
|
||||||
}, nil
|
|
||||||
case IngressGateway:
|
case IngressGateway:
|
||||||
return []string{
|
return []string{
|
||||||
"listeners",
|
"listeners",
|
||||||
"Listeners",
|
"Listeners",
|
||||||
"listeners.services",
|
"listeners.services",
|
||||||
"Listeners.Services",
|
"Listeners.Services",
|
||||||
}, nil, nil
|
}, nil
|
||||||
case TerminatingGateway:
|
case TerminatingGateway:
|
||||||
return []string{
|
return []string{
|
||||||
"services",
|
"services",
|
||||||
"Services",
|
"Services",
|
||||||
}, map[string]string{
|
|
||||||
"ca_file": "cafile",
|
|
||||||
"cert_file": "certfile",
|
|
||||||
"key_file": "keyfile",
|
|
||||||
}, nil
|
}, nil
|
||||||
default:
|
default:
|
||||||
return nil, nil, fmt.Errorf("kind %q should be explicitly handled here", kind)
|
return nil, fmt.Errorf("kind %q should be explicitly handled here", kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
envoycluster "github.com/envoyproxy/go-control-plane/envoy/api/v2/cluster"
|
envoycluster "github.com/envoyproxy/go-control-plane/envoy/api/v2/cluster"
|
||||||
"github.com/gogo/protobuf/types"
|
"github.com/gogo/protobuf/types"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/lib"
|
"github.com/hashicorp/consul/lib/decode"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -97,15 +97,18 @@ type GatewayConfig struct {
|
||||||
// error occurs during parsing, it is returned along with the default config. This
|
// error occurs during parsing, it is returned along with the default config. This
|
||||||
// allows the caller to choose whether and how to report the error
|
// allows the caller to choose whether and how to report the error
|
||||||
func ParseGatewayConfig(m map[string]interface{}) (GatewayConfig, error) {
|
func ParseGatewayConfig(m map[string]interface{}) (GatewayConfig, error) {
|
||||||
// Fixup for deprecated mesh gateway names
|
|
||||||
lib.TranslateKeys(m, map[string]string{
|
|
||||||
"envoy_mesh_gateway_bind_tagged_addresses": "envoy_gateway_bind_tagged_addresses",
|
|
||||||
"envoy_mesh_gateway_bind_addresses": "envoy_gateway_bind_addresses",
|
|
||||||
"envoy_mesh_gateway_no_default_bind": "envoy_gateway_no_default_bind",
|
|
||||||
})
|
|
||||||
|
|
||||||
var cfg GatewayConfig
|
var cfg GatewayConfig
|
||||||
err := mapstructure.WeakDecode(m, &cfg)
|
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||||
|
DecodeHook: decode.HookTranslateKeys,
|
||||||
|
Result: &cfg,
|
||||||
|
WeaklyTypedInput: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return cfg, err
|
||||||
|
}
|
||||||
|
if err := d.Decode(m); err != nil {
|
||||||
|
return cfg, err
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.ConnectTimeoutMs < 1 {
|
if cfg.ConnectTimeoutMs < 1 {
|
||||||
cfg.ConnectTimeoutMs = 5000
|
cfg.ConnectTimeoutMs = 5000
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/hashicorp/consul/command/flags"
|
"github.com/hashicorp/consul/command/flags"
|
||||||
"github.com/hashicorp/consul/command/helpers"
|
"github.com/hashicorp/consul/command/helpers"
|
||||||
"github.com/hashicorp/consul/lib"
|
"github.com/hashicorp/consul/lib"
|
||||||
|
"github.com/hashicorp/consul/lib/decode"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
|
@ -132,7 +133,7 @@ func newDecodeConfigEntry(raw map[string]interface{}) (api.ConfigEntry, error) {
|
||||||
return nil, fmt.Errorf("Kind value in payload is not a string")
|
return nil, fmt.Errorf("Kind value in payload is not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
skipWhenPatching, translateKeysDict, err := structs.ConfigEntryDecodeRulesForKind(entry.GetKind())
|
skipWhenPatching, err := structs.ConfigEntryDecodeRulesForKind(entry.GetKind())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -141,14 +142,12 @@ func newDecodeConfigEntry(raw map[string]interface{}) (api.ConfigEntry, error) {
|
||||||
// to do this part first.
|
// to do this part first.
|
||||||
raw = lib.PatchSliceOfMaps(raw, skipWhenPatching, nil)
|
raw = lib.PatchSliceOfMaps(raw, skipWhenPatching, nil)
|
||||||
|
|
||||||
// CamelCase is the canonical form for these, since this translation
|
|
||||||
// happens in the `consul config write` command and the JSON form is sent
|
|
||||||
// off to the server.
|
|
||||||
lib.TranslateKeys(raw, translateKeysDict)
|
|
||||||
|
|
||||||
var md mapstructure.Metadata
|
var md mapstructure.Metadata
|
||||||
decodeConf := &mapstructure.DecoderConfig{
|
decodeConf := &mapstructure.DecoderConfig{
|
||||||
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
|
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
||||||
|
decode.HookTranslateKeys,
|
||||||
|
mapstructure.StringToTimeDurationHookFunc(),
|
||||||
|
),
|
||||||
Metadata: &md,
|
Metadata: &md,
|
||||||
Result: &entry,
|
Result: &entry,
|
||||||
WeaklyTypedInput: true,
|
WeaklyTypedInput: true,
|
||||||
|
|
|
@ -34,6 +34,8 @@ import (
|
||||||
// // item's config field
|
// // item's config field
|
||||||
// "widgets.config": "",
|
// "widgets.config": "",
|
||||||
// })
|
// })
|
||||||
|
//
|
||||||
|
// Deprecated: Use lib/decode.HookTranslateKeys instead.
|
||||||
func TranslateKeys(v map[string]interface{}, dict map[string]string) {
|
func TranslateKeys(v map[string]interface{}, dict map[string]string) {
|
||||||
// Convert all dict keys for exclusions to lower. so we can match against them
|
// Convert all dict keys for exclusions to lower. so we can match against them
|
||||||
// unambiguously with a single lookup.
|
// unambiguously with a single lookup.
|
||||||
|
|
Loading…
Reference in New Issue