master
go 148 lines 4.34 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package confgroup
4
5 import (
6 "fmt"
7 "regexp"
8 "strings"
9
10 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
11
12 "github.com/gohugoio/hashstructure"
13 "gopkg.in/yaml.v2"
14 )
15
16 const (
17 keyName = "name"
18 keyModule = "module"
19 keyUpdateEvery = "update_every"
20 keyDetectRetry = "autodetection_retry"
21 keyPriority = "priority"
22 keyLabels = "labels"
23 keyVnode = "vnode"
24 keyFunctionOnly = "function_only"
25
26 ikeySource = "__source__"
27 ikeySourceType = "__source_type__"
28 ikeyProvider = "__provider__"
29 )
30
31 const (
32 TypeStock = "stock"
33 TypeUser = "user"
34 TypeDiscovered = "discovered"
35 TypeDyncfg = "dyncfg"
36 )
37
38 type Config map[string]any
39
40 func (c Config) HashIncludeMap(_ string, k, _ any) (bool, error) {
41 s := k.(string)
42 return !strings.HasPrefix(s, "__") && !strings.HasSuffix(s, "__"), nil
43 }
44
45 func (c Config) Set(key string, value any) Config { c[key] = value; return c }
46 func (c Config) Get(key string) any { return c[key] }
47
48 func (c Config) Name() string { v, _ := c.Get(keyName).(string); return v }
49 func (c Config) Module() string { v, _ := c.Get(keyModule).(string); return v }
50 func (c Config) FullName() string { return fullName(c.Name(), c.Module()) }
51 func (c Config) ExposedKey() string { return c.FullName() }
52 func (c Config) UpdateEvery() int { v, _ := c.Get(keyUpdateEvery).(int); return v }
53 func (c Config) AutoDetectionRetry() int { v, _ := c.Get(keyDetectRetry).(int); return v }
54 func (c Config) Priority() int { v, _ := c.Get(keyPriority).(int); return v }
55 func (c Config) Labels() map[any]any { v, _ := c.Get(keyLabels).(map[any]any); return v }
56 func (c Config) Hash() uint64 { return calcHash(c) }
57 func (c Config) Vnode() string { v, _ := c.Get(keyVnode).(string); return v }
58 func (c Config) FunctionOnly() bool { v, _ := c.Get(keyFunctionOnly).(bool); return v }
59
60 func (c Config) SetName(v string) Config { return c.Set(keyName, v) }
61 func (c Config) SetModule(v string) Config { return c.Set(keyModule, v) }
62
63 func (c Config) UID() string {
64 return fmt.Sprintf("%s_%s_%s_%s_%d", c.SourceType(), c.Provider(), c.Source(), c.FullName(), c.Hash())
65 }
66
67 func (c Config) Source() string { v, _ := c.Get(ikeySource).(string); return v }
68 func (c Config) SourceType() string { v, _ := c.Get(ikeySourceType).(string); return v }
69 func (c Config) Provider() string { v, _ := c.Get(ikeyProvider).(string); return v }
70 func (c Config) SetSource(v string) Config { return c.Set(ikeySource, v) }
71 func (c Config) SetSourceType(v string) Config { return c.Set(ikeySourceType, v) }
72 func (c Config) SetProvider(v string) Config { return c.Set(ikeyProvider, v) }
73
74 func (c Config) SourceTypePriority() int {
75 switch c.SourceType() {
76 default:
77 return 0
78 case TypeStock:
79 return 2
80 case TypeDiscovered:
81 return 4
82 case TypeUser:
83 return 8
84 case TypeDyncfg:
85 return 16
86 }
87 }
88
89 func (c Config) Clone() (Config, error) {
90 type plain Config
91 bytes, err := yaml.Marshal((plain)(c))
92 if err != nil {
93 return nil, err
94 }
95 var newConfig Config
96 if err := yaml.Unmarshal(bytes, &newConfig); err != nil {
97 return nil, err
98 }
99 return newConfig, nil
100 }
101
102 func (c Config) ApplyDefaults(def Default) {
103 if c.UpdateEvery() <= 0 {
104 v := firstPositive(def.UpdateEvery, collectorapi.UpdateEvery)
105 c.Set("update_every", v)
106 }
107 if c.AutoDetectionRetry() <= 0 {
108 v := firstPositive(def.AutoDetectionRetry, collectorapi.AutoDetectionRetry)
109 c.Set("autodetection_retry", v)
110 }
111 if c.Priority() <= 0 {
112 v := firstPositive(def.Priority, collectorapi.Priority)
113 c.Set("priority", v)
114 }
115 if c.UpdateEvery() < def.MinUpdateEvery && def.MinUpdateEvery > 0 {
116 c.Set("update_every", def.MinUpdateEvery)
117 }
118 if c.Name() == "" {
119 c.Set("name", c.Module())
120 } else {
121 c.Set("name", cleanName(c.Name()))
122 }
123 }
124
125 var reInvalidCharacters = regexp.MustCompile(`\s+|\.+|:+`)
126
127 func cleanName(name string) string {
128 return reInvalidCharacters.ReplaceAllString(name, "_")
129 }
130
131 func fullName(name, module string) string {
132 if name == module {
133 return name
134 }
135 return module + "_" + name
136 }
137
138 func calcHash(obj any) uint64 {
139 hash, _ := hashstructure.Hash(obj, nil)
140 return hash
141 }
142
143 func firstPositive(value int, others ...int) int {
144 if value > 0 || len(others) == 0 {
145 return value
146 }
147 return firstPositive(others[0], others[1:]...)
148 }