master
go 219 lines 5.73 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package agent
4
5 import (
6 "io"
7 "os"
8
9 "github.com/netdata/netdata/go/plugins/pkg/pluginconfig"
10 "github.com/netdata/netdata/go/plugins/plugin/agent/discovery"
11 "github.com/netdata/netdata/go/plugins/plugin/agent/secrets/secretstore"
12 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
13 "github.com/netdata/netdata/go/plugins/plugin/framework/confgroup"
14 "github.com/netdata/netdata/go/plugins/plugin/framework/functions"
15 "github.com/netdata/netdata/go/plugins/plugin/framework/vnodes"
16 "gopkg.in/yaml.v2"
17 )
18
19 func (a *Agent) loadPluginConfig() config {
20 a.Info("loading config file")
21
22 if len(a.ConfigDir) == 0 {
23 a.Info("config dir not provided, will use defaults")
24 return defaultConfig()
25 }
26
27 cfgPath := a.Name + ".conf"
28 a.Debugf("looking for '%s' in %v", cfgPath, a.ConfigDir)
29
30 path, err := a.ConfigDir.Find(cfgPath)
31 if err != nil || path == "" {
32 a.Warning("couldn't find config, will use defaults")
33 return defaultConfig()
34 }
35 a.Infof("found '%s", path)
36
37 cfg := defaultConfig()
38 if err := loadYAML(&cfg, path); err != nil {
39 a.Warningf("couldn't load config '%s': %v, will use defaults", path, err)
40 return defaultConfig()
41 }
42 a.Info("config successfully loaded")
43 return cfg
44 }
45
46 func (a *Agent) loadEnabledModules(cfg config) collectorapi.Registry {
47 a.Info("loading modules")
48
49 all := a.RunModule == "all" || a.RunModule == ""
50 enabled := collectorapi.Registry{}
51
52 for name, creator := range a.ModuleRegistry {
53 if !all && a.RunModule != name {
54 continue
55 }
56 if all {
57 if !cfg.isExplicitlyEnabled(name) && creator.Disabled {
58 a.Infof("'%s' module disabled by default, should be explicitly enabled in the config", name)
59 continue
60 }
61 if !cfg.isImplicitlyEnabled(name) {
62 a.Infof("'%s' module disabled in the config file", name)
63 continue
64 }
65 }
66 enabled[name] = creator
67 }
68
69 a.Infof("enabled/registered modules: %d/%d", len(enabled), len(a.ModuleRegistry))
70
71 return enabled
72 }
73
74 func (a *Agent) buildDiscoveryConf(enabled collectorapi.Registry, fnReg functions.Registry) discovery.Config {
75 a.Info("building discovery config")
76
77 reg := confgroup.Registry{}
78 for name, creator := range enabled {
79 reg.Register(name, confgroup.Default{
80 MinUpdateEvery: a.MinUpdateEvery,
81 UpdateEvery: creator.UpdateEvery,
82 AutoDetectionRetry: creator.AutoDetectionRetry,
83 Priority: creator.Priority,
84 })
85 }
86
87 var readPaths, dummyPaths []string
88
89 watchPaths := a.CollectorsConfigWatchPath
90 sdConfDir := a.ServiceDiscoveryConfigDir
91 if !a.serviceDiscoveryEnabled() {
92 sdConfDir = nil
93 }
94
95 cfg := discovery.Config{
96 Registry: reg,
97 BuildContext: discovery.BuildContext{
98 Policy: discovery.PlatformPolicy{
99 IsInsideK8s: a.IsInsideK8s,
100 },
101 RunMode: a.runModePolicy,
102 Identity: discovery.PluginIdentity{
103 Name: a.Name,
104 },
105 Out: a.Out,
106 Paths: discovery.PathsConfig{
107 PluginConfigDir: a.ConfigDir,
108 CollectorsConfigDir: a.CollectorsConfDir,
109 CollectorsConfigWatchPath: watchPaths,
110 ServiceDiscoveryConfigDir: sdConfDir,
111 VarLibDir: a.VarLibDir,
112 },
113 Registry: reg,
114 ReadPaths: readPaths,
115 DummyNames: dummyPaths,
116 FnReg: fnReg,
117 },
118 Providers: append([]discovery.ProviderFactory(nil), a.DiscoveryProviders...),
119 }
120
121 if len(a.CollectorsConfDir) == 0 {
122 if a.IsInsideK8s {
123 cfg.Providers = nil
124 return cfg
125 }
126 a.Info("modules conf dir not provided, will use default config for all enabled modules")
127 for name := range enabled {
128 dummyPaths = append(dummyPaths, name)
129 }
130 watchPaths = nil
131 cfg.BuildContext.Paths.CollectorsConfigWatchPath = watchPaths
132 cfg.BuildContext.DummyNames = dummyPaths
133 return cfg
134 }
135
136 for name := range enabled {
137 cfgName := name + ".conf"
138 a.Debugf("looking for '%s' in %v", cfgName, a.CollectorsConfDir)
139
140 path, err := a.CollectorsConfDir.Find(cfgName)
141 if a.IsInsideK8s {
142 if err != nil {
143 a.Infof("not found '%s', won't use default (reading stock configs is disabled in k8s)", cfgName)
144 continue
145 } else if isStockConfig(path) {
146 a.Infof("found '%s', but won't load it (reading stock configs is disabled in k8s)", cfgName)
147 continue
148 }
149 }
150 if err != nil {
151 a.Infof("couldn't find '%s' module config, will use default config", name)
152 dummyPaths = append(dummyPaths, name)
153 } else {
154 a.Debugf("found '%s", path)
155 readPaths = append(readPaths, path)
156 }
157 }
158
159 a.Infof("dummy/read/watch paths: %d/%d/%d", len(dummyPaths), len(readPaths), len(a.CollectorsConfigWatchPath))
160 cfg.BuildContext.Paths.CollectorsConfigWatchPath = watchPaths
161 cfg.BuildContext.Paths.ServiceDiscoveryConfigDir = sdConfDir
162 cfg.BuildContext.ReadPaths = readPaths
163 cfg.BuildContext.DummyNames = dummyPaths
164
165 return cfg
166 }
167
168 func (a *Agent) setupVnodeRegistry() map[string]*vnodes.VirtualNode {
169 a.Debugf("looking for 'vnodes/' in %v", a.ConfigDir)
170 if len(a.ConfigDir) == 0 {
171 return nil
172 }
173
174 dirPath, err := a.ConfigDir.Find("vnodes/")
175 if err != nil || dirPath == "" {
176 return nil
177 }
178
179 reg := vnodes.Load(dirPath)
180 a.Infof("found '%s' (%d vhosts)", dirPath, len(reg))
181
182 return reg
183 }
184
185 func (a *Agent) setupSecretStoreConfigs() []secretstore.Config {
186 a.Debugf("looking for 'ss/' in %v", a.CollectorsConfDir)
187 if len(a.CollectorsConfDir) == 0 {
188 return nil
189 }
190
191 cfgs, errs := secretstore.LoadFileConfigs(a.CollectorsConfDir)
192 for _, err := range errs {
193 a.Warningf("%v", err)
194 }
195 if len(cfgs) > 0 {
196 a.Infof("loaded %d secretstore configs from 'ss/'", len(cfgs))
197 }
198 return cfgs
199 }
200
201 func loadYAML(conf any, path string) error {
202 f, err := os.Open(path)
203 if err != nil {
204 return err
205 }
206 defer func() { _ = f.Close() }()
207
208 if err = yaml.NewDecoder(f).Decode(conf); err != nil {
209 if err == io.EOF {
210 return nil
211 }
212 return err
213 }
214 return nil
215 }
216
217 func isStockConfig(path string) bool {
218 return pluginconfig.IsStock(path)
219 }