mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-12 06:24:10 +01:00
common/helper: add a helper to rename a configuration setting
This commit is contained in:
@@ -106,6 +106,39 @@ func DefaultValuesUnmarshallerHook[Configuration any](defaultConfiguration Confi
|
||||
}
|
||||
}
|
||||
|
||||
// RenameKeyUnmarshallerHook move a configuration setting from one place to another.
|
||||
func RenameKeyUnmarshallerHook[Configuration any](zeroConfiguration Configuration, fromLabel, toLabel string) mapstructure.DecodeHookFunc {
|
||||
return func(from, to reflect.Value) (interface{}, error) {
|
||||
if from.Kind() != reflect.Map || from.IsNil() || to.Type() != reflect.TypeOf(zeroConfiguration) {
|
||||
return from.Interface(), nil
|
||||
}
|
||||
|
||||
// country-database → geo-database
|
||||
var fromKey, toKey *reflect.Value
|
||||
fromMap := from.MapKeys()
|
||||
for i, k := range fromMap {
|
||||
k = ElemOrIdentity(k)
|
||||
if k.Kind() != reflect.String {
|
||||
return from.Interface(), nil
|
||||
}
|
||||
if MapStructureMatchName(k.String(), fromLabel) {
|
||||
fromKey = &fromMap[i]
|
||||
} else if MapStructureMatchName(k.String(), toLabel) {
|
||||
toKey = &fromMap[i]
|
||||
}
|
||||
}
|
||||
if fromKey != nil && toKey != nil {
|
||||
return nil, fmt.Errorf("cannot have both %q and %q", fromKey.String(), toKey.String())
|
||||
}
|
||||
if fromKey != nil {
|
||||
from.SetMapIndex(reflect.ValueOf(toLabel), from.MapIndex(*fromKey))
|
||||
from.SetMapIndex(*fromKey, reflect.Value{})
|
||||
}
|
||||
|
||||
return from.Interface(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// ParametrizedConfigurationUnmarshallerHook will help decode a configuration
|
||||
// structure parametrized by a type by selecting the appropriate concrete type
|
||||
// depending on the type contained in the source. We have two configuration
|
||||
|
||||
@@ -119,6 +119,54 @@ func TestDefaultValuesConfig(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestRenameConfig(t *testing.T) {
|
||||
type Configuration struct {
|
||||
UnchangedLabel string
|
||||
NewLabel string
|
||||
}
|
||||
RegisterMapstructureUnmarshallerHook(RenameKeyUnmarshallerHook(Configuration{}, "OldLabel", "NewLabel"))
|
||||
TestConfigurationDecode(t, ConfigurationDecodeCases{
|
||||
{
|
||||
Description: "no rename needed",
|
||||
Initial: func() interface{} { return Configuration{} },
|
||||
Configuration: func() interface{} {
|
||||
return gin.H{
|
||||
"unchanged-label": "hello",
|
||||
"new-label": "bye",
|
||||
}
|
||||
},
|
||||
Expected: Configuration{
|
||||
UnchangedLabel: "hello",
|
||||
NewLabel: "bye",
|
||||
},
|
||||
}, {
|
||||
Description: "rename needed",
|
||||
Initial: func() interface{} { return Configuration{} },
|
||||
Configuration: func() interface{} {
|
||||
return gin.H{
|
||||
"unchanged-label": "hello",
|
||||
"old-label": "bye",
|
||||
}
|
||||
},
|
||||
Expected: Configuration{
|
||||
UnchangedLabel: "hello",
|
||||
NewLabel: "bye",
|
||||
},
|
||||
}, {
|
||||
Description: "conflicts",
|
||||
Initial: func() interface{} { return Configuration{} },
|
||||
Configuration: func() interface{} {
|
||||
return gin.H{
|
||||
"unchanged-label": "hello",
|
||||
"old-label": "bye",
|
||||
"new-label": "whatt?",
|
||||
}
|
||||
},
|
||||
Error: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestParametrizedConfig(t *testing.T) {
|
||||
type InnerConfigurationType1 struct {
|
||||
CC string
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"akvorado/common/helpers"
|
||||
@@ -13,8 +11,6 @@ import (
|
||||
"akvorado/inlet/metadata/provider/gnmi"
|
||||
"akvorado/inlet/metadata/provider/snmp"
|
||||
"akvorado/inlet/metadata/provider/static"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
// Configuration describes the configuration for the metadata client
|
||||
@@ -49,40 +45,6 @@ func DefaultConfiguration() Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
// ConfigurationUnmarshallerHook renames "provider" to "providers".
|
||||
func ConfigurationUnmarshallerHook() mapstructure.DecodeHookFunc {
|
||||
return func(from, to reflect.Value) (interface{}, error) {
|
||||
if from.Kind() != reflect.Map || from.IsNil() || to.Type() != reflect.TypeOf(Configuration{}) {
|
||||
return from.Interface(), nil
|
||||
}
|
||||
|
||||
// provider → providers
|
||||
{
|
||||
var providerKey, providersKey *reflect.Value
|
||||
fromKeys := from.MapKeys()
|
||||
for i, k := range fromKeys {
|
||||
k = helpers.ElemOrIdentity(k)
|
||||
if k.Kind() != reflect.String {
|
||||
return from.Interface(), nil
|
||||
}
|
||||
if helpers.MapStructureMatchName(k.String(), "Provider") {
|
||||
providerKey = &fromKeys[i]
|
||||
} else if helpers.MapStructureMatchName(k.String(), "Providers") {
|
||||
providersKey = &fromKeys[i]
|
||||
}
|
||||
}
|
||||
if providersKey != nil && providerKey != nil {
|
||||
return nil, fmt.Errorf("cannot have both %q and %q", providerKey.String(), providersKey.String())
|
||||
}
|
||||
if providerKey != nil {
|
||||
from.SetMapIndex(reflect.ValueOf("providers"), from.MapIndex(*providerKey))
|
||||
from.SetMapIndex(*providerKey, reflect.Value{})
|
||||
}
|
||||
}
|
||||
return from.Interface(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// ProviderConfiguration represents the configuration for a metadata provider.
|
||||
type ProviderConfiguration struct {
|
||||
// Config is the actual configuration for the provider.
|
||||
@@ -101,7 +63,8 @@ var providers = map[string](func() provider.Configuration){
|
||||
}
|
||||
|
||||
func init() {
|
||||
helpers.RegisterMapstructureUnmarshallerHook(ConfigurationUnmarshallerHook())
|
||||
helpers.RegisterMapstructureUnmarshallerHook(
|
||||
helpers.RenameKeyUnmarshallerHook(Configuration{}, "Provider", "Providers"))
|
||||
helpers.RegisterMapstructureUnmarshallerHook(
|
||||
helpers.ParametrizedConfigurationUnmarshallerHook(ProviderConfiguration{}, providers))
|
||||
}
|
||||
|
||||
@@ -4,12 +4,7 @@
|
||||
package geoip
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"akvorado/common/helpers"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
// Configuration describes the configuration for the GeoIP component.
|
||||
@@ -29,40 +24,7 @@ func DefaultConfiguration() Configuration {
|
||||
return Configuration{}
|
||||
}
|
||||
|
||||
// ConfigurationUnmarshallerHook normalize GeoIP configuration:
|
||||
// - replace country-database by geo-database
|
||||
func ConfigurationUnmarshallerHook() mapstructure.DecodeHookFunc {
|
||||
return func(from, to reflect.Value) (interface{}, error) {
|
||||
if from.Kind() != reflect.Map || from.IsNil() || to.Type() != reflect.TypeOf(Configuration{}) {
|
||||
return from.Interface(), nil
|
||||
}
|
||||
|
||||
// country-database → geo-database
|
||||
var countryKey, geoKey *reflect.Value
|
||||
fromMap := from.MapKeys()
|
||||
for i, k := range fromMap {
|
||||
k = helpers.ElemOrIdentity(k)
|
||||
if k.Kind() != reflect.String {
|
||||
return from.Interface(), nil
|
||||
}
|
||||
if helpers.MapStructureMatchName(k.String(), "CountryDatabase") {
|
||||
countryKey = &fromMap[i]
|
||||
} else if helpers.MapStructureMatchName(k.String(), "GeoDatabase") {
|
||||
geoKey = &fromMap[i]
|
||||
}
|
||||
}
|
||||
if countryKey != nil && geoKey != nil {
|
||||
return nil, fmt.Errorf("cannot have both %q and %q", countryKey.String(), geoKey.String())
|
||||
}
|
||||
if countryKey != nil {
|
||||
from.SetMapIndex(reflect.ValueOf("geo-database"), from.MapIndex(*countryKey))
|
||||
from.SetMapIndex(*countryKey, reflect.Value{})
|
||||
}
|
||||
|
||||
return from.Interface(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
helpers.RegisterMapstructureUnmarshallerHook(ConfigurationUnmarshallerHook())
|
||||
helpers.RegisterMapstructureUnmarshallerHook(
|
||||
helpers.RenameKeyUnmarshallerHook(Configuration{}, "CountryDatabase", "GeoDatabase"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user