From 4adb4953d6547bed213b6ae447f511455a2eb0bc Mon Sep 17 00:00:00 2001 From: jcreixell Date: Wed, 15 Nov 2023 21:48:01 +0100 Subject: [PATCH 01/12] Agent Management: Introduce support for template variables - This change allows managing template variables for remote configuration on a per-agent basis. - Both base configurations and snippets can be interpreted as templates and evaluated at load time with the provided template variables. - Templates must follow go's `text/template` syntax. - This greatly increases the flexibility and reusability of snippets. - Template evaluation has been tested in different scenarios and seems really robust. If the variables defined in the template cannot be resolved (even nested ones), and empty string is rendered instead. - Note: templates are only evaluated when the `template_variables` field within the `agent_metadata` remote config field is non-empty. - Note: this feature only applies to static mode. --- pkg/config/agentmanagement_remote_config.go | 40 ++++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/pkg/config/agentmanagement_remote_config.go b/pkg/config/agentmanagement_remote_config.go index f5deeed9a47c..cdffb53a06c1 100644 --- a/pkg/config/agentmanagement_remote_config.go +++ b/pkg/config/agentmanagement_remote_config.go @@ -1,6 +1,9 @@ package config import ( + "bytes" + "text/template" + "github.com/grafana/agent/pkg/integrations" "github.com/grafana/agent/pkg/logs" "github.com/grafana/agent/pkg/metrics/instance" @@ -27,7 +30,8 @@ type ( } AgentMetadata struct { - ExternalLabels map[string]string `json:"external_labels,omitempty" yaml:"external_labels,omitempty"` + ExternalLabels map[string]string `json:"external_labels,omitempty" yaml:"external_labels,omitempty"` + TemplateVariables map[string]any `json:"template_variables,omitempty" yaml:"template_variables,omitempty"` } // SnippetContent defines the internal structure of a snippet configuration. @@ -54,8 +58,13 @@ func NewRemoteConfig(buf []byte) (*RemoteConfig, error) { // BuildAgentConfig builds an agent configuration from a base config and a list of snippets func (rc *RemoteConfig) BuildAgentConfig() (*Config, error) { + baseConfig, err := evaluateTemplateVariables(string(rc.BaseConfig), rc.AgentMetadata.TemplateVariables) + if err != nil { + return nil, err + } + c := DefaultConfig() - err := yaml.Unmarshal([]byte(rc.BaseConfig), &c) + err = yaml.Unmarshal([]byte(baseConfig), &c) if err != nil { return nil, err } @@ -65,7 +74,7 @@ func (rc *RemoteConfig) BuildAgentConfig() (*Config, error) { return nil, err } - err = appendSnippets(&c, rc.Snippets) + err = appendSnippets(&c, rc.Snippets, rc.AgentMetadata.TemplateVariables) if err != nil { return nil, err } @@ -73,7 +82,7 @@ func (rc *RemoteConfig) BuildAgentConfig() (*Config, error) { return &c, nil } -func appendSnippets(c *Config, snippets []Snippet) error { +func appendSnippets(c *Config, snippets []Snippet, templateVars map[string]any) error { metricsConfigs := instance.DefaultConfig metricsConfigs.Name = "snippets" logsConfigs := logs.InstanceConfig{ @@ -90,8 +99,13 @@ func appendSnippets(c *Config, snippets []Snippet) error { } for _, snippet := range snippets { + snippetConfig, err := evaluateTemplateVariables(snippet.Config, templateVars) + if err != nil { + return err + } + var snippetContent SnippetContent - err := yaml.Unmarshal([]byte(snippet.Config), &snippetContent) + err = yaml.Unmarshal([]byte(snippetConfig), &snippetContent) if err != nil { return err } @@ -138,3 +152,19 @@ func appendExternalLabels(c *Config, externalLabels map[string]string) { } c.Metrics.Global.Prometheus.ExternalLabels = labels.FromMap(newExternalLabels) } + +func evaluateTemplateVariables(config string, templateVariables map[string]any) (string, error) { + // Avoid doing anything if there are no template variables + if len(templateVariables) == 0 { + return config, nil + } + + tpl, err := template.New("snip").Parse(config) + if err != nil { + return "", err + } + + var buf bytes.Buffer + tpl.Execute(&buf, templateVariables) + return buf.String(), nil +} From 674366424d68df68f3a829a2f6add744dace1988 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Wed, 15 Nov 2023 22:04:10 +0100 Subject: [PATCH 02/12] Improve naming --- pkg/config/agentmanagement_remote_config.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/config/agentmanagement_remote_config.go b/pkg/config/agentmanagement_remote_config.go index cdffb53a06c1..6f97a1543e9a 100644 --- a/pkg/config/agentmanagement_remote_config.go +++ b/pkg/config/agentmanagement_remote_config.go @@ -58,7 +58,7 @@ func NewRemoteConfig(buf []byte) (*RemoteConfig, error) { // BuildAgentConfig builds an agent configuration from a base config and a list of snippets func (rc *RemoteConfig) BuildAgentConfig() (*Config, error) { - baseConfig, err := evaluateTemplateVariables(string(rc.BaseConfig), rc.AgentMetadata.TemplateVariables) + baseConfig, err := evaluateTemplate(string(rc.BaseConfig), rc.AgentMetadata.TemplateVariables) if err != nil { return nil, err } @@ -99,7 +99,7 @@ func appendSnippets(c *Config, snippets []Snippet, templateVars map[string]any) } for _, snippet := range snippets { - snippetConfig, err := evaluateTemplateVariables(snippet.Config, templateVars) + snippetConfig, err := evaluateTemplate(snippet.Config, templateVars) if err != nil { return err } @@ -153,13 +153,13 @@ func appendExternalLabels(c *Config, externalLabels map[string]string) { c.Metrics.Global.Prometheus.ExternalLabels = labels.FromMap(newExternalLabels) } -func evaluateTemplateVariables(config string, templateVariables map[string]any) (string, error) { +func evaluateTemplate(config string, templateVariables map[string]any) (string, error) { // Avoid doing anything if there are no template variables if len(templateVariables) == 0 { return config, nil } - tpl, err := template.New("snip").Parse(config) + tpl, err := template.New("config").Parse(config) if err != nil { return "", err } From b5000a35929b92890c91d23f359c996e4cf8054b Mon Sep 17 00:00:00 2001 From: jcreixell Date: Thu, 16 Nov 2023 09:13:20 +0100 Subject: [PATCH 03/12] Check error for template execution --- pkg/config/agentmanagement_remote_config.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/config/agentmanagement_remote_config.go b/pkg/config/agentmanagement_remote_config.go index 6f97a1543e9a..865664dcb72b 100644 --- a/pkg/config/agentmanagement_remote_config.go +++ b/pkg/config/agentmanagement_remote_config.go @@ -165,6 +165,10 @@ func evaluateTemplate(config string, templateVariables map[string]any) (string, } var buf bytes.Buffer - tpl.Execute(&buf, templateVariables) + err = tpl.Execute(&buf, templateVariables) + if err != nil { + return "", err + } + return buf.String(), nil } From 54b9d989810bd92c204cc10614b6ad4bb06f3846 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Thu, 16 Nov 2023 19:57:14 +0100 Subject: [PATCH 04/12] Add tests - Tests different scenarios, including: - Referencing non existing nested objects - Conditionals - Ranges - Character escaping --- .../agent_management_remote_config_test.go | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/pkg/config/agent_management_remote_config_test.go b/pkg/config/agent_management_remote_config_test.go index af97bd70190a..264c501dfce3 100644 --- a/pkg/config/agent_management_remote_config_test.go +++ b/pkg/config/agent_management_remote_config_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + process_exporter "github.com/grafana/agent/pkg/integrations/process_exporter" "github.com/grafana/agent/pkg/metrics/instance" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/model/labels" @@ -182,6 +183,81 @@ integration_configs: require.Equal(t, 5*time.Second, c.Integrations.ConfigV1.IntegrationRestartBackoff) }) + t.Run("template variables provided", func(t *testing.T) { + baseConfig := ` +server: + log_level: {{.log_level}} +` + snippet := Snippet{ + Config: ` +integration_configs: + process_exporter: + enabled: true + process_names: + - name: "grafana-agent" + cmdline: + - 'grafana-agent' + - name: "{{.nonexistent.foo.bar.baz.bat}}" + cmdline: + - 'non-existent' + # Custom process monitors + {{- range $key, $value := .process_exporter_processes }} + - name: "{{ $value.name }}" + cmdline: + - "{{ $value.cmdline }}" + {{if $value.exe}} + exe: + - "{{ $value.exe }}" + {{end}} + {{- end }} +`, + } + + rc := RemoteConfig{ + BaseConfig: BaseConfigContent(baseConfig), + Snippets: []Snippet{snippet}, + AgentMetadata: AgentMetadata{ + TemplateVariables: map[string]any{ + "log_level": "debug", + "process_exporter_processes": []map[string]string{ + { + "name": "java_processes", + "cmdline": ".*/java", + }, + { + "name": "{{.ExeFull}}:{{.Matches.Cfgfile}}", + "cmdline": `-config.path\\s+(?P\\S+)`, + "exe": "/usr/local/bin/process-exporter", + }, + }, + }, + }, + } + + c, err := rc.BuildAgentConfig() + require.NoError(t, err) + require.Equal(t, 1, len(c.Integrations.ConfigV1.Integrations)) + processExporterConfig := c.Integrations.ConfigV1.Integrations[0].Config.(*process_exporter.Config) + + require.Equal(t, 4, len(processExporterConfig.ProcessExporter)) + + require.Equal(t, "grafana-agent", processExporterConfig.ProcessExporter[0].Name) + require.Equal(t, "grafana-agent", processExporterConfig.ProcessExporter[0].CmdlineRules[0]) + require.Equal(t, 0, len(processExporterConfig.ProcessExporter[0].ExeRules)) + + require.Equal(t, "", processExporterConfig.ProcessExporter[1].Name) + require.Equal(t, "non-existent", processExporterConfig.ProcessExporter[1].CmdlineRules[0]) + require.Equal(t, 0, len(processExporterConfig.ProcessExporter[1].ExeRules)) + + require.Equal(t, "java_processes", processExporterConfig.ProcessExporter[2].Name) + require.Equal(t, ".*/java", processExporterConfig.ProcessExporter[2].CmdlineRules[0]) + require.Equal(t, 0, len(processExporterConfig.ProcessExporter[2].ExeRules)) + + require.Equal(t, "{{.ExeFull}}:{{.Matches.Cfgfile}}", processExporterConfig.ProcessExporter[3].Name) + require.Equal(t, `-config.path\s+(?P\S+)`, processExporterConfig.ProcessExporter[3].CmdlineRules[0]) + require.Equal(t, "/usr/local/bin/process-exporter", processExporterConfig.ProcessExporter[3].ExeRules[0]) + }) + t.Run("no external labels provided", func(t *testing.T) { rc := RemoteConfig{ BaseConfig: BaseConfigContent(baseConfig), From c5a1918a21cb4f363da2db945f012e3295f55d39 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Thu, 16 Nov 2023 20:05:28 +0100 Subject: [PATCH 05/12] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dd878676da2..502d2461976d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,8 @@ Main (unreleased) - Agent Management: Introduce support for remotely managed external labels for logs. (@jcreixell) +- Agent Management: Introduce support for templated configuration. (@jcreixell) + ### Enhancements - The `loki.write` WAL now has snappy compression enabled by default. (@thepalbi) From 8db1f5311de3e6f679559eda1dfe37cd59bb4ea3 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Fri, 17 Nov 2023 11:16:32 +0100 Subject: [PATCH 06/12] Always evaluate templates - This is required because certain agents might start before their labels are synced. If some of the snippets assigned to them contain template variables, loading the config will fail. --- pkg/config/agentmanagement_remote_config.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pkg/config/agentmanagement_remote_config.go b/pkg/config/agentmanagement_remote_config.go index 0a255878b8ca..8b5093861381 100644 --- a/pkg/config/agentmanagement_remote_config.go +++ b/pkg/config/agentmanagement_remote_config.go @@ -164,11 +164,6 @@ func appendExternalLabels(c *Config, externalLabels map[string]string) { } func evaluateTemplate(config string, templateVariables map[string]any) (string, error) { - // Avoid doing anything if there are no template variables - if len(templateVariables) == 0 { - return config, nil - } - tpl, err := template.New("config").Parse(config) if err != nil { return "", err From 55de58af3eeecb55c494a5ed560d42556db2005d Mon Sep 17 00:00:00 2001 From: jcreixell Date: Tue, 21 Nov 2023 17:18:04 +0100 Subject: [PATCH 07/12] Add test for template inside a template - Templates inside templates must be escaped using backticks to avoid them being evaluated by the snippet template execution --- pkg/config/agent_management_remote_config_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/config/agent_management_remote_config_test.go b/pkg/config/agent_management_remote_config_test.go index 264c501dfce3..834375bda3ce 100644 --- a/pkg/config/agent_management_remote_config_test.go +++ b/pkg/config/agent_management_remote_config_test.go @@ -188,6 +188,7 @@ integration_configs: server: log_level: {{.log_level}} ` + templateInsideTemplate := "`{{ .template_inside_template }}`" snippet := Snippet{ Config: ` integration_configs: @@ -199,7 +200,7 @@ integration_configs: - 'grafana-agent' - name: "{{.nonexistent.foo.bar.baz.bat}}" cmdline: - - 'non-existent' + - "{{ ` + templateInsideTemplate + ` }}" # Custom process monitors {{- range $key, $value := .process_exporter_processes }} - name: "{{ $value.name }}" @@ -246,7 +247,7 @@ integration_configs: require.Equal(t, 0, len(processExporterConfig.ProcessExporter[0].ExeRules)) require.Equal(t, "", processExporterConfig.ProcessExporter[1].Name) - require.Equal(t, "non-existent", processExporterConfig.ProcessExporter[1].CmdlineRules[0]) + require.Equal(t, "{{ .template_inside_template }}", processExporterConfig.ProcessExporter[1].CmdlineRules[0]) require.Equal(t, 0, len(processExporterConfig.ProcessExporter[1].ExeRules)) require.Equal(t, "java_processes", processExporterConfig.ProcessExporter[2].Name) From a3c7c471a7bdcf91ccf59619cc32384935618b66 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Tue, 21 Nov 2023 18:17:19 +0100 Subject: [PATCH 08/12] Move feature to the next release in CHANGELOG --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 912fec72b554..79e14e50572e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ internal API changes are not present. Main (unreleased) ----------------- +### Features + +- Agent Management: Introduce support for templated configuration. (@jcreixell) + v0.38.0 (2023-11-21) -------------------- @@ -64,8 +68,6 @@ v0.38.0 (2023-11-21) - Agent Management: Introduce support for remotely managed external labels for logs. (@jcreixell) -- Agent Management: Introduce support for templated configuration. (@jcreixell) - ### Enhancements - The `loki.write` WAL now has snappy compression enabled by default. (@thepalbi) From 526bcc1ddc1fb4ed6a52bff694407cd07cc4ef10 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Wed, 22 Nov 2023 10:56:33 +0100 Subject: [PATCH 09/12] Add sprig utility function to snip templates - Adds convenient functions for manipulating strings among other things (used by helm). --- go.mod | 3 +++ go.sum | 4 ++++ pkg/config/agent_management_remote_config_test.go | 4 ++-- pkg/config/agentmanagement_remote_config.go | 3 ++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 891de83235af..ce7352b02719 100644 --- a/go.mod +++ b/go.mod @@ -620,8 +620,11 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 ) +require github.com/Masterminds/semver v1.5.0 // indirect + require ( dario.cat/mergo v1.0.0 // indirect + github.com/Masterminds/sprig v2.22.0+incompatible github.com/Shopify/sarama v1.38.1 // indirect github.com/Workiva/go-datastructures v1.1.0 // indirect github.com/drone/envsubst v1.0.3 // indirect diff --git a/go.sum b/go.sum index 0384745ab682..88d7658d1b9b 100644 --- a/go.sum +++ b/go.sum @@ -193,9 +193,13 @@ github.com/Lusitaniae/apache_exporter v0.11.1-0.20220518131644-f9522724dab4/go.m github.com/MasslessParticle/azure-storage-blob-go v0.14.1-0.20220216145902-b5e698eff68e/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Mellanox/rdmamap v0.0.0-20191106181932-7c3c4763a6ee/go.mod h1:jDA6v0TUYrFEIAE5uGJ29LQOeONIgMdP4Rkqb8HUnPM= diff --git a/pkg/config/agent_management_remote_config_test.go b/pkg/config/agent_management_remote_config_test.go index 834375bda3ce..e31d574646be 100644 --- a/pkg/config/agent_management_remote_config_test.go +++ b/pkg/config/agent_management_remote_config_test.go @@ -197,7 +197,7 @@ integration_configs: process_names: - name: "grafana-agent" cmdline: - - 'grafana-agent' + - '{{ "grafana-agent" | replace "grafana-" "" }}' - name: "{{.nonexistent.foo.bar.baz.bat}}" cmdline: - "{{ ` + templateInsideTemplate + ` }}" @@ -243,7 +243,7 @@ integration_configs: require.Equal(t, 4, len(processExporterConfig.ProcessExporter)) require.Equal(t, "grafana-agent", processExporterConfig.ProcessExporter[0].Name) - require.Equal(t, "grafana-agent", processExporterConfig.ProcessExporter[0].CmdlineRules[0]) + require.Equal(t, "agent", processExporterConfig.ProcessExporter[0].CmdlineRules[0]) require.Equal(t, 0, len(processExporterConfig.ProcessExporter[0].ExeRules)) require.Equal(t, "", processExporterConfig.ProcessExporter[1].Name) diff --git a/pkg/config/agentmanagement_remote_config.go b/pkg/config/agentmanagement_remote_config.go index 8b5093861381..7c6efb12bc4b 100644 --- a/pkg/config/agentmanagement_remote_config.go +++ b/pkg/config/agentmanagement_remote_config.go @@ -4,6 +4,7 @@ import ( "bytes" "text/template" + "github.com/Masterminds/sprig" "github.com/grafana/agent/pkg/integrations" "github.com/grafana/agent/pkg/logs" "github.com/grafana/agent/pkg/metrics/instance" @@ -164,7 +165,7 @@ func appendExternalLabels(c *Config, externalLabels map[string]string) { } func evaluateTemplate(config string, templateVariables map[string]any) (string, error) { - tpl, err := template.New("config").Parse(config) + tpl, err := template.New("config").Funcs(sprig.FuncMap()).Parse(config) if err != nil { return "", err } From dd5e3c72ca2ed580582a3f57686f1d17cd9a9587 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Wed, 22 Nov 2023 14:44:13 +0100 Subject: [PATCH 10/12] Revert "Add sprig utility function to snip templates" This reverts commit 526bcc1ddc1fb4ed6a52bff694407cd07cc4ef10. --- go.mod | 3 --- go.sum | 4 ---- pkg/config/agent_management_remote_config_test.go | 4 ++-- pkg/config/agentmanagement_remote_config.go | 3 +-- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index ce7352b02719..891de83235af 100644 --- a/go.mod +++ b/go.mod @@ -620,11 +620,8 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 ) -require github.com/Masterminds/semver v1.5.0 // indirect - require ( dario.cat/mergo v1.0.0 // indirect - github.com/Masterminds/sprig v2.22.0+incompatible github.com/Shopify/sarama v1.38.1 // indirect github.com/Workiva/go-datastructures v1.1.0 // indirect github.com/drone/envsubst v1.0.3 // indirect diff --git a/go.sum b/go.sum index 88d7658d1b9b..0384745ab682 100644 --- a/go.sum +++ b/go.sum @@ -193,13 +193,9 @@ github.com/Lusitaniae/apache_exporter v0.11.1-0.20220518131644-f9522724dab4/go.m github.com/MasslessParticle/azure-storage-blob-go v0.14.1-0.20220216145902-b5e698eff68e/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Mellanox/rdmamap v0.0.0-20191106181932-7c3c4763a6ee/go.mod h1:jDA6v0TUYrFEIAE5uGJ29LQOeONIgMdP4Rkqb8HUnPM= diff --git a/pkg/config/agent_management_remote_config_test.go b/pkg/config/agent_management_remote_config_test.go index e31d574646be..834375bda3ce 100644 --- a/pkg/config/agent_management_remote_config_test.go +++ b/pkg/config/agent_management_remote_config_test.go @@ -197,7 +197,7 @@ integration_configs: process_names: - name: "grafana-agent" cmdline: - - '{{ "grafana-agent" | replace "grafana-" "" }}' + - 'grafana-agent' - name: "{{.nonexistent.foo.bar.baz.bat}}" cmdline: - "{{ ` + templateInsideTemplate + ` }}" @@ -243,7 +243,7 @@ integration_configs: require.Equal(t, 4, len(processExporterConfig.ProcessExporter)) require.Equal(t, "grafana-agent", processExporterConfig.ProcessExporter[0].Name) - require.Equal(t, "agent", processExporterConfig.ProcessExporter[0].CmdlineRules[0]) + require.Equal(t, "grafana-agent", processExporterConfig.ProcessExporter[0].CmdlineRules[0]) require.Equal(t, 0, len(processExporterConfig.ProcessExporter[0].ExeRules)) require.Equal(t, "", processExporterConfig.ProcessExporter[1].Name) diff --git a/pkg/config/agentmanagement_remote_config.go b/pkg/config/agentmanagement_remote_config.go index 7c6efb12bc4b..8b5093861381 100644 --- a/pkg/config/agentmanagement_remote_config.go +++ b/pkg/config/agentmanagement_remote_config.go @@ -4,7 +4,6 @@ import ( "bytes" "text/template" - "github.com/Masterminds/sprig" "github.com/grafana/agent/pkg/integrations" "github.com/grafana/agent/pkg/logs" "github.com/grafana/agent/pkg/metrics/instance" @@ -165,7 +164,7 @@ func appendExternalLabels(c *Config, externalLabels map[string]string) { } func evaluateTemplate(config string, templateVariables map[string]any) (string, error) { - tpl, err := template.New("config").Funcs(sprig.FuncMap()).Parse(config) + tpl, err := template.New("config").Parse(config) if err != nil { return "", err } From f38ab1da8b809075aa981efe9a3b0a383525b0a7 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Wed, 22 Nov 2023 17:51:10 +0100 Subject: [PATCH 11/12] Document templating functionality --- docs/sources/static/configuration/agent-management.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sources/static/configuration/agent-management.md b/docs/sources/static/configuration/agent-management.md index 0feb5c78def1..ac49a2677040 100644 --- a/docs/sources/static/configuration/agent-management.md +++ b/docs/sources/static/configuration/agent-management.md @@ -123,7 +123,6 @@ selector: > **Note:** Snippet selection is currently done in the API server. This behaviour is subject to change in the future. - ### Example response body ```yaml @@ -164,3 +163,5 @@ snippets: os: linux app: app1 ``` + +> **Note:** Base configurations and snippets can contain go's [text/template](https://pkg.go.dev/text/template) actions. If you need preserve the literal value of a template action, you can escape them using backticks (for example, `{{ .template_inside_template }}`). \ No newline at end of file From 5cf552faa149c7d786b5842aecf6f2219a0a5950 Mon Sep 17 00:00:00 2001 From: jcreixell Date: Wed, 22 Nov 2023 18:12:50 +0100 Subject: [PATCH 12/12] Fix doc --- docs/sources/static/configuration/agent-management.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/sources/static/configuration/agent-management.md b/docs/sources/static/configuration/agent-management.md index ac49a2677040..af327bb17b6e 100644 --- a/docs/sources/static/configuration/agent-management.md +++ b/docs/sources/static/configuration/agent-management.md @@ -164,4 +164,8 @@ snippets: app: app1 ``` -> **Note:** Base configurations and snippets can contain go's [text/template](https://pkg.go.dev/text/template) actions. If you need preserve the literal value of a template action, you can escape them using backticks (for example, `{{ .template_inside_template }}`). \ No newline at end of file +> **Note:** Base configurations and snippets can contain go's [text/template](https://pkg.go.dev/text/template) actions. If you need preserve the literal value of a template action, you can escape it using backticks. For example: + +``` +{{ `{{ .template_var }}` }} +```