github.com/netdata/go.d.plugin@v0.58.1/agent/discovery/sd/pipeline/compose.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package pipeline 4 5 import ( 6 "bytes" 7 "text/template" 8 9 "github.com/netdata/go.d.plugin/agent/confgroup" 10 "github.com/netdata/go.d.plugin/agent/discovery/sd/model" 11 "github.com/netdata/go.d.plugin/logger" 12 13 "gopkg.in/yaml.v2" 14 ) 15 16 func newConfigComposer(cfg []ComposeRuleConfig) (*configComposer, error) { 17 rules, err := newComposeRules(cfg) 18 if err != nil { 19 return nil, err 20 } 21 22 c := &configComposer{ 23 rules: rules, 24 buf: bytes.Buffer{}, 25 } 26 27 return c, nil 28 } 29 30 type ( 31 configComposer struct { 32 *logger.Logger 33 rules []*composeRule 34 buf bytes.Buffer 35 } 36 37 composeRule struct { 38 name string 39 sr selector 40 conf []*composeRuleConf 41 } 42 composeRuleConf struct { 43 sr selector 44 tmpl *template.Template 45 } 46 ) 47 48 func (c *configComposer) compose(tgt model.Target) []confgroup.Config { 49 var configs []confgroup.Config 50 51 for i, rule := range c.rules { 52 if !rule.sr.matches(tgt.Tags()) { 53 continue 54 } 55 56 for j, conf := range rule.conf { 57 if !conf.sr.matches(tgt.Tags()) { 58 continue 59 } 60 61 c.buf.Reset() 62 63 if err := conf.tmpl.Execute(&c.buf, tgt); err != nil { 64 c.Warningf("failed to execute rule[%d]->config[%d]->template on target '%s'", i+1, j+1, tgt.TUID()) 65 continue 66 } 67 if c.buf.Len() == 0 { 68 continue 69 } 70 71 var cfg confgroup.Config 72 73 if err := yaml.Unmarshal(c.buf.Bytes(), &cfg); err != nil { 74 c.Warningf("failed on yaml unmarshalling: %v", err) 75 continue 76 } 77 78 configs = append(configs, cfg) 79 } 80 } 81 82 if len(configs) > 0 { 83 c.Infof("created %d config(s) for target '%s'", len(configs), tgt.TUID()) 84 } 85 return configs 86 } 87 88 func newComposeRules(cfg []ComposeRuleConfig) ([]*composeRule, error) { 89 var rules []*composeRule 90 91 fmap := newFuncMap() 92 93 for _, ruleCfg := range cfg { 94 rule := composeRule{name: ruleCfg.Name} 95 96 sr, err := parseSelector(ruleCfg.Selector) 97 if err != nil { 98 return nil, err 99 } 100 rule.sr = sr 101 102 for _, confCfg := range ruleCfg.Config { 103 var conf composeRuleConf 104 105 sr, err := parseSelector(confCfg.Selector) 106 if err != nil { 107 return nil, err 108 } 109 conf.sr = sr 110 111 tmpl, err := parseTemplate(confCfg.Template, fmap) 112 if err != nil { 113 return nil, err 114 } 115 conf.tmpl = tmpl 116 117 rule.conf = append(rule.conf, &conf) 118 } 119 120 rules = append(rules, &rule) 121 } 122 123 return rules, nil 124 }