github.com/netdata/go.d.plugin@v0.58.1/agent/confgroup/group.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package confgroup
     4  
     5  import (
     6  	"fmt"
     7  	"net/url"
     8  	"regexp"
     9  	"strings"
    10  
    11  	"github.com/netdata/go.d.plugin/agent/hostinfo"
    12  	"github.com/netdata/go.d.plugin/agent/module"
    13  
    14  	"github.com/ilyam8/hashstructure"
    15  )
    16  
    17  type Group struct {
    18  	Configs []Config
    19  	Source  string
    20  }
    21  
    22  type Config map[string]interface{}
    23  
    24  func (c Config) HashIncludeMap(_ string, k, _ interface{}) (bool, error) {
    25  	s := k.(string)
    26  	return !(strings.HasPrefix(s, "__") && strings.HasSuffix(s, "__")), nil
    27  }
    28  
    29  func (c Config) NameWithHash() string    { return fmt.Sprintf("%s_%d", c.Name(), c.Hash()) }
    30  func (c Config) Name() string            { v, _ := c.get("name").(string); return v }
    31  func (c Config) Module() string          { v, _ := c.get("module").(string); return v }
    32  func (c Config) FullName() string        { return fullName(c.Name(), c.Module()) }
    33  func (c Config) UpdateEvery() int        { v, _ := c.get("update_every").(int); return v }
    34  func (c Config) AutoDetectionRetry() int { v, _ := c.get("autodetection_retry").(int); return v }
    35  func (c Config) Priority() int           { v, _ := c.get("priority").(int); return v }
    36  func (c Config) Labels() map[any]any     { v, _ := c.get("labels").(map[any]any); return v }
    37  func (c Config) Hash() uint64            { return calcHash(c) }
    38  func (c Config) Source() string          { v, _ := c.get("__source__").(string); return v }
    39  func (c Config) Provider() string        { v, _ := c.get("__provider__").(string); return v }
    40  func (c Config) Vnode() string           { v, _ := c.get("vnode").(string); return v }
    41  
    42  func (c Config) SetName(v string)     { c.set("name", v) }
    43  func (c Config) SetModule(v string)   { c.set("module", v) }
    44  func (c Config) SetSource(v string)   { c.set("__source__", v) }
    45  func (c Config) SetProvider(v string) { c.set("__provider__", v) }
    46  
    47  func (c Config) set(key string, value interface{}) { c[key] = value }
    48  func (c Config) get(key string) interface{}        { return c[key] }
    49  
    50  func (c Config) Apply(def Default) {
    51  	if c.UpdateEvery() <= 0 {
    52  		v := firstPositive(def.UpdateEvery, module.UpdateEvery)
    53  		c.set("update_every", v)
    54  	}
    55  	if c.AutoDetectionRetry() <= 0 {
    56  		v := firstPositive(def.AutoDetectionRetry, module.AutoDetectionRetry)
    57  		c.set("autodetection_retry", v)
    58  	}
    59  	if c.Priority() <= 0 {
    60  		v := firstPositive(def.Priority, module.Priority)
    61  		c.set("priority", v)
    62  	}
    63  	if c.UpdateEvery() < def.MinUpdateEvery && def.MinUpdateEvery > 0 {
    64  		c.set("update_every", def.MinUpdateEvery)
    65  	}
    66  	if c.Name() == "" {
    67  		c.set("name", c.Module())
    68  	} else {
    69  		c.set("name", cleanName(jobNameResolveHostname(c.Name())))
    70  	}
    71  
    72  	if v, ok := c.get("url").(string); ok {
    73  		c.set("url", urlResolveHostname(v))
    74  	}
    75  }
    76  
    77  func cleanName(name string) string {
    78  	return reInvalidCharacters.ReplaceAllString(name, "_")
    79  }
    80  
    81  var reInvalidCharacters = regexp.MustCompile(`\s+|\.+`)
    82  
    83  func fullName(name, module string) string {
    84  	if name == module {
    85  		return name
    86  	}
    87  	return module + "_" + name
    88  }
    89  
    90  func calcHash(obj interface{}) uint64 {
    91  	hash, _ := hashstructure.Hash(obj, nil)
    92  	return hash
    93  }
    94  
    95  func firstPositive(value int, others ...int) int {
    96  	if value > 0 || len(others) == 0 {
    97  		return value
    98  	}
    99  	return firstPositive(others[0], others[1:]...)
   100  }
   101  
   102  func urlResolveHostname(rawURL string) string {
   103  	if hostinfo.Hostname == "" || !strings.Contains(rawURL, "hostname") {
   104  		return rawURL
   105  	}
   106  
   107  	u, err := url.Parse(rawURL)
   108  	if err != nil || (u.Hostname() != "hostname" && !strings.Contains(u.Hostname(), "hostname.")) {
   109  		return rawURL
   110  	}
   111  
   112  	u.Host = strings.Replace(u.Host, "hostname", hostinfo.Hostname, 1)
   113  
   114  	return u.String()
   115  }
   116  
   117  func jobNameResolveHostname(name string) string {
   118  	if hostinfo.Hostname == "" || !strings.Contains(name, "hostname") {
   119  		return name
   120  	}
   121  
   122  	if name != "hostname" && !strings.HasPrefix(name, "hostname.") && !strings.HasPrefix(name, "hostname_") {
   123  		return name
   124  	}
   125  
   126  	return strings.Replace(name, "hostname", hostinfo.Hostname, 1)
   127  }