-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathconfig.go
More file actions
94 lines (77 loc) · 2.23 KB
/
config.go
File metadata and controls
94 lines (77 loc) · 2.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package plugin
import (
"fmt"
"reflect"
// Register built-in plugins
"github.com/bluemedora/bplogagent/bundle"
"github.com/mitchellh/mapstructure"
"go.etcd.io/bbolt"
"go.uber.org/zap"
)
var PluginConfigDefinitions = make(map[string]func() PluginConfig)
// RegisterConfig will register a config struct by name in the packages config registry
// during package load time.
func RegisterConfig(name string, config PluginConfig) {
PluginConfigDefinitions[name] = func() PluginConfig {
val := reflect.New(reflect.TypeOf(config).Elem()).Interface()
return val.(PluginConfig)
}
}
type PluginConfig interface {
ID() PluginID
Type() string
Build(BuildContext) (Plugin, error)
}
type OutputterConfig interface {
PluginConfig
OutputIDs() []PluginID
}
type InputterConfig interface {
PluginConfig
IsInputter()
}
type BuildContext struct {
Plugins map[PluginID]Plugin
Bundles []*bundle.BundleDefinition
// TODO this should be an array of bundle IDs to namespace the plugin ids in the bundles
IsBundle bool
Database *bbolt.DB
Logger *zap.SugaredLogger
}
func UnmarshalHook(c *mapstructure.DecoderConfig) {
c.DecodeHook = newPluginConfigDecoder()
}
func newPluginConfigDecoder() mapstructure.DecodeHookFunc {
return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
var m map[interface{}]interface{}
if f != reflect.TypeOf(m) {
return data, nil
}
if t.String() != "plugin.PluginConfig" {
return data, nil
}
d, ok := data.(map[interface{}]interface{})
if !ok {
return nil, fmt.Errorf("unexpected data type %T for plugin config", data)
}
typeInterface, ok := d["type"]
if !ok {
return nil, fmt.Errorf("missing type field for plugin config")
}
typeString, ok := typeInterface.(string)
if !ok {
return nil, fmt.Errorf("unexpected type %T for plugin config type", typeInterface)
}
configDefinitionFunc, ok := PluginConfigDefinitions[typeString]
if !ok {
return nil, fmt.Errorf("unknown plugin config type %s", typeString)
}
configDefinition := configDefinitionFunc()
// TODO handle unused keys
err := mapstructure.Decode(data, &configDefinition)
if err != nil {
return nil, fmt.Errorf("decode plugin definition: %s", err)
}
return configDefinition, nil
}
}