From 995546e7c685136924c9d30ba5b49b30d6e2ddb1 Mon Sep 17 00:00:00 2001
From: Patrick Hemmer <phemmer@users.noreply.github.com>
Date: Fri, 24 Mar 2017 15:06:52 -0400
Subject: [PATCH] snmp: support table indexes as tags (#2366)

---
 CHANGELOG.md                     |  1 +
 plugins/inputs/snmp/README.md    |  3 +++
 plugins/inputs/snmp/snmp.go      | 15 ++++++++++++---
 plugins/inputs/snmp/snmp_test.go | 21 ++++++++++++++++-----
 4 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd1ec513..b1655f77 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -58,6 +58,7 @@ be deprecated eventually.
 - [#1678](https://github.com/influxdata/telegraf/pull/1678): Add AMQP consumer input plugin
 - [#2501](https://github.com/influxdata/telegraf/pull/2501): Support DEAD(X) state in system input plugin.
 - [#2522](https://github.com/influxdata/telegraf/pull/2522): Add support for mongodb client certificates.
+- [#1948](https://github.com/influxdata/telegraf/pull/1948): Support adding SNMP table indexes as tags.
 
 ### Bugfixes
 
diff --git a/plugins/inputs/snmp/README.md b/plugins/inputs/snmp/README.md
index 473f2a52..27b1f757 100644
--- a/plugins/inputs/snmp/README.md
+++ b/plugins/inputs/snmp/README.md
@@ -168,6 +168,9 @@ If not specified, it defaults to the value of `oid`.  If `oid` is numeric, an at
 * `inherit_tags`:
 Which tags to inherit from the top-level config and to use in the output of this table's measurement.
 
+* `index_as_tag`:
+Adds each row's index within the table as a tag.  
+
 ### MIB lookups
 If the plugin is configured such that it needs to perform lookups from the MIB, it will use the net-snmp utilities `snmptranslate` and `snmptable`.
 
diff --git a/plugins/inputs/snmp/snmp.go b/plugins/inputs/snmp/snmp.go
index 9296bc04..5394e57d 100644
--- a/plugins/inputs/snmp/snmp.go
+++ b/plugins/inputs/snmp/snmp.go
@@ -168,6 +168,9 @@ type Table struct {
 	// Which tags to inherit from the top-level config.
 	InheritTags []string
 
+	// Adds each row's table index as a tag.
+	IndexAsTag bool
+
 	// Fields is the tags and values to look up.
 	Fields []Field `toml:"field"`
 
@@ -464,13 +467,19 @@ func (t Table) Build(gs snmpConnection, walk bool) (*RTable, error) {
 			}
 		}
 
-		for i, v := range ifv {
-			rtr, ok := rows[i]
+		for idx, v := range ifv {
+			rtr, ok := rows[idx]
 			if !ok {
 				rtr = RTableRow{}
 				rtr.Tags = map[string]string{}
 				rtr.Fields = map[string]interface{}{}
-				rows[i] = rtr
+				rows[idx] = rtr
+			}
+			if t.IndexAsTag && idx != "" {
+				if idx[0] == '.' {
+					idx = idx[1:]
+				}
+				rtr.Tags["index"] = idx
 			}
 			// don't add an empty string
 			if vs, ok := v.(string); !ok || vs != "" {
diff --git a/plugins/inputs/snmp/snmp_test.go b/plugins/inputs/snmp/snmp_test.go
index 62b19fce..07fdeddc 100644
--- a/plugins/inputs/snmp/snmp_test.go
+++ b/plugins/inputs/snmp/snmp_test.go
@@ -413,7 +413,8 @@ func TestGosnmpWrapper_get_retry(t *testing.T) {
 
 func TestTableBuild_walk(t *testing.T) {
 	tbl := Table{
-		Name: "mytable",
+		Name:       "mytable",
+		IndexAsTag: true,
 		Fields: []Field{
 			{
 				Name:  "myfield1",
@@ -442,7 +443,10 @@ func TestTableBuild_walk(t *testing.T) {
 
 	assert.Equal(t, tb.Name, "mytable")
 	rtr1 := RTableRow{
-		Tags: map[string]string{"myfield1": "foo"},
+		Tags: map[string]string{
+			"myfield1": "foo",
+			"index":    "0",
+		},
 		Fields: map[string]interface{}{
 			"myfield2": 1,
 			"myfield3": float64(0.123),
@@ -450,7 +454,10 @@ func TestTableBuild_walk(t *testing.T) {
 		},
 	}
 	rtr2 := RTableRow{
-		Tags: map[string]string{"myfield1": "bar"},
+		Tags: map[string]string{
+			"myfield1": "bar",
+			"index":    "1",
+		},
 		Fields: map[string]interface{}{
 			"myfield2": 2,
 			"myfield3": float64(0.456),
@@ -458,14 +465,18 @@ func TestTableBuild_walk(t *testing.T) {
 		},
 	}
 	rtr3 := RTableRow{
-		Tags: map[string]string{},
+		Tags: map[string]string{
+			"index": "2",
+		},
 		Fields: map[string]interface{}{
 			"myfield2": 0,
 			"myfield3": float64(0.0),
 		},
 	}
 	rtr4 := RTableRow{
-		Tags: map[string]string{},
+		Tags: map[string]string{
+			"index": "3",
+		},
 		Fields: map[string]interface{}{
 			"myfield3": float64(9.999),
 		},
-- 
GitLab