Repository: influxdata/telegraf-operator
Pull request #99 (2022-06-15 07:58:29)

feat: add namepass for metric scraping; cleanup config generation
Allow providing `namepass` annotation to limit metrics that are gathered via Prometheus scraping.

Also update example deployment to have an image that provides metrics and provide `namepass` in the example.

- [x] Signed the [InfluxData CLA](https://www.influxdata.com/legal/cla/)
  ([if necessary](https://github.com/influxdata/telegraf-operator/blob/master/CONTRIBUTING.md#sign-the-influxdata-cla))
- [x] Tests pass (no build errors)
- [x] Rebased/mergeable



Patch:
diff --git a/README.md b/README.md
index f945767..191763d 100644
--- a/README.md
+++ b/README.md
@@ -226,8 +226,9 @@ Users can configure the `inputs.prometheus` plugin by setting the following anno
 - `telegraf.influxdata.com/scheme` : is used to configure at the scheme for the metrics to scrape, will apply to all ports if multiple are configured ( only `http` or `https` are allowed as values)
 - `telegraf.influxdata.com/interval` : is used to configure interval for telegraf scraping (Go style duration, e.g 5s, 30s, 2m .. )
 - `telegraf.influxdata.com/metric-version` : is used to configure which metrics parsing version to use (1, 2)
+- `telegraf.influxdata.com/namepass` : is used to configure scraped metrics to preserve configuration for `telegraf`, being a TOML value to add to telegraf configuration; all metrics are passed if not specified
 
-**NOTE**: all annotations should be formatted as strings - for example `telegraf.influxdata.com/port: "8080"` or `telegraf.influxdata.com/metric-version: "2"`.
+**NOTE**: all annotations should be formatted as strings - for example `telegraf.influxdata.com/port: "8080"`, `telegraf.influxdata.com/metric-version: "2"` or  `telegraf.influxdata.com/namepass: "['metric1','metric2']"`.
 
 ### Example Prometheus Scraping
 
diff --git a/examples/deployment.yml b/examples/deployment.yml
index 7aecbc0..19f49fd 100644
--- a/examples/deployment.yml
+++ b/examples/deployment.yml
@@ -1,20 +1,21 @@
 apiVersion: apps/v1
 kind: Deployment
 metadata:
-  name: nginx
+  name: hello-world
   namespace: test
 spec:
   replicas: 3
   selector:
     matchLabels:
-      app: nginx
+      app: hello-world
   template:
     metadata:
       labels:
-        app: nginx
+        app: hello-world
       annotations:
-        telegraf.influxdata.com/ports: "9090"
+        telegraf.influxdata.com/ports: "8080"
+        telegraf.influxdata.com/namepass: "['go_info','hello_processed_total','go_memstats*']"
     spec:
       containers:
-      - name: nginx
-        image: nginx:alpine
+      - name: hello-world
+        image: okteto/hello-world:golang-metrics
diff --git a/sidecar.go b/sidecar.go
index 941bae8..90bc7fb 100644
--- a/sidecar.go
+++ b/sidecar.go
@@ -37,6 +37,8 @@ const (
 	TelegrafMetricsScheme = "telegraf.influxdata.com/scheme"
 	// TelegrafMetricVersion is used to configure which metrics parsing version to use (1, 2)
 	TelegrafMetricVersion = "telegraf.influxdata.com/metric-version"
+	// TelegrafMetricsNamepass is used to specify value for namepass for Prometheus metrics, as raw TOML configuration
+	TelegrafMetricsNamepass = "telegraf.influxdata.com/namepass"
 	// TelegrafInterval is used to configure interval for telegraf (Go style duration, e.g 5s, 30s, 2m .. )
 	TelegrafInterval = "telegraf.influxdata.com/interval"
 	// TelegrafRawInput is used to configure custom inputs for telegraf
@@ -242,29 +244,33 @@ func (h *sidecarHandler) assembleConf(pod *corev1.Pod, className string) (telegr
 		if extScheme, ok := pod.Annotations[TelegrafMetricsScheme]; ok {
 			scheme = extScheme
 		}
-		intervalConfig := ""
+
+		additionalConfig := ""
+
 		intervalRaw, ok := pod.Annotations[TelegrafInterval]
 		if ok {
-			intervalConfig = fmt.Sprintf("interval = \"%s\"", intervalRaw)
+			additionalConfig = fmt.Sprintf("%s  interval = \"%s\"\n", additionalConfig, intervalRaw)
 		}
 
-		versionConfig := ""
 		if versionRaw, ok := pod.Annotations[TelegrafMetricVersion]; ok {
 			version, err := strconv.ParseInt(versionRaw, 10, 0)
 			if err != nil {
 				return "", fmt.Errorf("value supplied for %s must be a number, %s given", TelegrafMetricVersion, versionRaw)
 			}
 
-			versionConfig = fmt.Sprintf("metric_version = %d", version)
+			additionalConfig = fmt.Sprintf("%s  metric_version = %d\n", additionalConfig, version)
+		}
+
+		if namepass, ok := pod.Annotations[TelegrafMetricsNamepass]; ok {
+			additionalConfig = fmt.Sprintf("%s  namepass = %s\n", additionalConfig, namepass)
 		}
 
 		urls := []string{}
 		for _, port := range ports {
 			urls = append(urls, fmt.Sprintf("%s://127.0.0.1:%s%s", scheme, port, path))
 		}
-		if len(urls) != 0 {
-			telegrafConf = fmt.Sprintf("%s\n%s", telegrafConf, fmt.Sprintf("[[inputs.prometheus]]\n  urls = [\"%s\"]\n  %s\n  %s\n", strings.Join(urls, `", "`), intervalConfig, versionConfig))
-		}
+
+		telegrafConf = fmt.Sprintf("%s\n[[inputs.prometheus]]\n  urls = [\"%s\"]\n%s\n", telegrafConf, strings.Join(urls, `", "`), additionalConfig)
 	}
 	enableInternal := h.EnableDefaultInternalPlugin
 	if internalRaw, ok := pod.Annotations[TelegrafEnableInternal]; ok {


Test patch:
diff --git a/sidecar_test.go b/sidecar_test.go
index 30ebf2b..a5874bf 100644
--- a/sidecar_test.go
+++ b/sidecar_test.go
@@ -216,8 +216,7 @@ func Test_assembleConf(t *testing.T) {
 			wantConfig: `
 [[inputs.prometheus]]
   urls = ["http://127.0.0.1:6060/metrics"]
-  
-  
+
 
 [global_tags]
   dc = "us-east-1"
@@ -228,12 +227,13 @@ func Test_assembleConf(t *testing.T) {
 			pod: &corev1.Pod{
 				ObjectMeta: metav1.ObjectMeta{
 					Annotations: map[string]string{
-						TelegrafMetricsPath:    "/metrics/usage",
-						TelegrafMetricsScheme:  "https",
-						TelegrafInterval:       "10s",
-						TelegrafMetricsPorts:   "6060,8086",
-						TelegrafEnableInternal: "true",
-						TelegrafMetricVersion:  "2",
+						TelegrafMetricsPath:     "/metrics/usage",
+						TelegrafMetricsScheme:   "https",
+						TelegrafInterval:        "10s",
+						TelegrafMetricsPorts:    "6060,8086",
+						TelegrafEnableInternal:  "true",
+						TelegrafMetricVersion:   "2",
+						TelegrafMetricsNamepass: "['a','b','c']",
 					},
 				},
 			},
@@ -242,6 +242,8 @@ func Test_assembleConf(t *testing.T) {
   urls = ["https://127.0.0.1:6060/metrics/usage", "https://127.0.0.1:8086/metrics/usage"]
   interval = "10s"
   metric_version = 2
+  namepass = ['a','b','c']
+
 
 [[inputs.internal]]
 
@@ -260,7 +262,6 @@ func Test_assembleConf(t *testing.T) {
 			wantConfig: `
 [[inputs.prometheus]]
   urls = ["http://127.0.0.1:6060/metrics"]
-  
   metric_version = 2
 
 `,
@@ -277,6 +278,23 @@ func Test_assembleConf(t *testing.T) {
 			},
 			wantErr: true,
 		},
+		{
+			name: "default prometheus settings with namepass",
+			pod: &corev1.Pod{
+				ObjectMeta: metav1.ObjectMeta{
+					Annotations: map[string]string{
+						TelegrafMetricsPorts:    "6060",
+						TelegrafMetricsNamepass: "['a','b','c']",
+					},
+				},
+			},
+			wantConfig: `
+[[inputs.prometheus]]
+  urls = ["http://127.0.0.1:6060/metrics"]
+  namepass = ['a','b','c']
+
+`,
+		},
 		{
 			name: "valid TOML syntax",
 			pod: &corev1.Pod{
@@ -421,7 +439,12 @@ metadata:
   name: telegraf-config-myname
   namespace: mynamespace
 stringData:
-  telegraf.conf: "\n[[inputs.prometheus]]\n  urls = [\"http://127.0.0.1:6060/metrics\"]\n  \n  \n\n"
+  telegraf.conf: |2+
+
+    [[inputs.prometheus]]
+      urls = ["http://127.0.0.1:6060/metrics"]
+
+
 type: Opaque`,
 			},
 		},