| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package jobmgr |
| 4 | |
| 5 | import ( |
| 6 | "context" |
| 7 | "fmt" |
| 8 | |
| 9 | "github.com/netdata/netdata/go/plugins/plugin/agent/secrets/resolver" |
| 10 | "github.com/netdata/netdata/go/plugins/plugin/agent/secrets/secretstore" |
| 11 | "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi" |
| 12 | "github.com/netdata/netdata/go/plugins/plugin/framework/confgroup" |
| 13 | "gopkg.in/yaml.v2" |
| 14 | ) |
| 15 | |
| 16 | func newConfigModule(creator collectorapi.Creator) (configModule, error) { |
| 17 | if creator.CreateV2 != nil { |
| 18 | mod := creator.CreateV2() |
| 19 | if mod == nil { |
| 20 | return nil, fmt.Errorf("CreateV2 returned nil") |
| 21 | } |
| 22 | return mod, nil |
| 23 | } |
| 24 | if creator.Create == nil { |
| 25 | return nil, fmt.Errorf("no module creator is defined") |
| 26 | } |
| 27 | mod := creator.Create() |
| 28 | if mod == nil { |
| 29 | return nil, fmt.Errorf("Create returned nil") |
| 30 | } |
| 31 | return mod, nil |
| 32 | } |
| 33 | |
| 34 | func applyConfig( |
| 35 | ctx context.Context, |
| 36 | cfg confgroup.Config, |
| 37 | module any, |
| 38 | resolver *secretresolver.Resolver, |
| 39 | storeService secretstore.Service, |
| 40 | storeSnapshot *secretstore.Snapshot, |
| 41 | ) error { |
| 42 | if resolver == nil { |
| 43 | return fmt.Errorf("secret resolver is nil") |
| 44 | } |
| 45 | cfgResolved, err := cfg.Clone() |
| 46 | if err != nil { |
| 47 | return fmt.Errorf("cloning config: %w", err) |
| 48 | } |
| 49 | storeResolver := secretresolver.StoreRefResolver(nil) |
| 50 | if storeService != nil { |
| 51 | storeResolver = func(resolveCtx context.Context, ref, original string) (string, error) { |
| 52 | if resolveCtx == nil { |
| 53 | resolveCtx = ctx |
| 54 | } |
| 55 | return storeService.Resolve(resolveCtx, storeSnapshot, ref, original) |
| 56 | } |
| 57 | } |
| 58 | if err := resolver.ResolveWithStoreResolver(ctx, cfgResolved, storeResolver); err != nil { |
| 59 | return fmt.Errorf("resolving secrets: %w", err) |
| 60 | } |
| 61 | bs, err := yaml.Marshal(cfgResolved) |
| 62 | if err != nil { |
| 63 | return err |
| 64 | } |
| 65 | return yaml.Unmarshal(bs, module) |
| 66 | } |
| 67 | |
| 68 | // applyConfigRaw applies config without resolving secrets. |
| 69 | // Used by dyncfg get to avoid exposing resolved secret values. |
| 70 | func applyConfigRaw(cfg confgroup.Config, module any) error { |
| 71 | bs, err := yaml.Marshal(cfg) |
| 72 | if err != nil { |
| 73 | return err |
| 74 | } |
| 75 | return yaml.Unmarshal(bs, module) |
| 76 | } |
| 77 | |
| 78 | func makeLabels(cfg confgroup.Config) map[string]string { |
| 79 | labels := make(map[string]string) |
| 80 | for name, value := range cfg.Labels() { |
| 81 | n, ok1 := name.(string) |
| 82 | v, ok2 := value.(string) |
| 83 | if ok1 && ok2 { |
| 84 | labels[n] = v |
| 85 | } |
| 86 | } |
| 87 | return labels |
| 88 | } |