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  }