Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Templated names and tags for Consul targets #610

Merged
merged 3 commits into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/user_guide/targets/target_discovery/consul_discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,28 @@ loader:
password: admin
```

### Templating with Consul

It is possible to set the target name to something other than the Consul Service ID using the `name` field under the config. The target name can be customized using [Go Templates](https://golang.org/pkg/text/template/).

In addition to setting the target name, it is also possible to use Go Templates on `event-tags` as well.

The templates use the Service under Consul, so access to things like `ID`, `Tags`, `Meta`, etc. are all available.

```yaml
loader:
type: consul
services:
- name: cluster1-gnmi-server
config:
name: "{{.Meta.device}}"
event-tags:
location: "{{.Meta.site_name}}"
model: "{{.Meta.device_type}}"
tag-1: "{{.Meta.tag_1}}"
boring-static-tag: "hello"
```

### Configuration

```yaml
Expand Down
1 change: 0 additions & 1 deletion pkg/config/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ func (c *Config) GetLoader() error {
}
return os.ExpandEnv(v)
})
fmt.Printf("LOADER: %+v\n", c.Loader)
return nil
}
}
Expand Down
52 changes: 52 additions & 0 deletions pkg/loaders/consul_loader/consul_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package consul_loader

import (
"bytes"
"context"
"encoding/json"
"errors"
Expand All @@ -17,7 +18,9 @@ import (
"log"
"net"
"strconv"
"strings"
"sync"
"text/template"
"time"

"gopkg.in/yaml.v2"
Expand Down Expand Up @@ -110,6 +113,8 @@ type serviceDef struct {
Config map[string]interface{} `mapstructure:"config,omitempty" json:"config,omitempty"`

tags map[string]struct{}
targetNameTemplate *template.Template
targetTagsTemplate map[string]*template.Template
}

func (c *consulLoader) Init(ctx context.Context, cfg map[string]interface{}, logger *log.Logger, opts ...loaders.Option) error {
Expand Down Expand Up @@ -403,7 +408,54 @@ SRV:
tc.Address = se.Node.Address
}
tc.Address = net.JoinHostPort(tc.Address, strconv.Itoa(se.Service.Port))

var buffer bytes.Buffer

tc.Name = se.Service.ID

if configName, ok := sd.Config["name"].(string); ok {
nameTemplate, err := template.New("targetName").Option("missingkey=zero").Parse(configName)
if err != nil {
c.logger.Println("Could not parse nameTemplate")
}
sd.targetNameTemplate = nameTemplate

buffer.Reset()
err = sd.targetNameTemplate.Execute(&buffer, se.Service)
if err != nil {
c.logger.Println("Could not execute nameTemplate")
continue
}
tc.Name = buffer.String()
}

// Create Event tags from Consul via templates
if configEventTags, ok := sd.Config["event-tags"].(map[string]interface{}); ok {
// Allow to use join function in tags
templateFunctions := template.FuncMap{"join": strings.Join}

sd.targetTagsTemplate = make(map[string]*template.Template)
for tagName, tagTemplateString := range configEventTags {
tagTemplate, err := template.New(tagName).Funcs(templateFunctions).Option("missingkey=zero").Parse(fmt.Sprintf("%v",tagTemplateString))
if err != nil {
c.logger.Println("Could not parse tagTemplate:", tagName)
continue
}
sd.targetTagsTemplate[tagName] = tagTemplate
}

eventTags := make(map[string]string)
for tagName, tagTemplate := range sd.targetTagsTemplate {
buffer.Reset()
err := tagTemplate.Execute(&buffer, se.Service)
if err != nil {
c.logger.Println("Could not execute tagTemplate:", tagName)
return nil, err
}
eventTags[tagName] = buffer.String()
}
tc.EventTags = eventTags
}
return tc, nil
}

Expand Down
Loading