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

fix(inputs.gnmi): Allow optional origin for update path #13304

Merged
merged 3 commits into from
May 23, 2023
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
27 changes: 9 additions & 18 deletions plugins/inputs/gnmi/gnmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,34 +346,25 @@ func (s *Subscription) buildFullPath(c *GNMI) error {
}

func (s *Subscription) buildAlias(aliases map[string]string) error {
var err error
var gnmiLongPath, gnmiShortPath *gnmiLib.Path

// Build the subscription path without keys
if gnmiLongPath, err = parsePath(s.Origin, s.Path, ""); err != nil {
return err
}
if gnmiShortPath, err = parsePath("", s.Path, ""); err != nil {
gnmiPath, err := parsePath(s.Origin, s.Path, "")
if err != nil {
return err
}

longPath, _, err := handlePath(gnmiLongPath, nil, nil, "")
if err != nil {
return fmt.Errorf("handling long-path failed: %w", err)
}
shortPath, _, err := handlePath(gnmiShortPath, nil, nil, "")
origin, spath, _, err := handlePath(gnmiPath, nil, nil, "")
if err != nil {
return fmt.Errorf("handling short-path failed: %w", err)
return fmt.Errorf("handling path failed: %w", err)
}

// If the user didn't provide a measurement name, use last path element
name := s.Name
if len(name) == 0 {
name = path.Base(shortPath)
if name == "" {
name = path.Base(spath)
}
if len(name) > 0 {
aliases[longPath] = name
aliases[shortPath] = name
if name != "" {
aliases[origin+spath] = name
aliases[spath] = name
}
return nil
}
6 changes: 4 additions & 2 deletions plugins/inputs/gnmi/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,12 @@ func (h *handler) handleSubscribeResponseUpdate(acc telegraf.Accumulator, respon
}

if response.Update.Prefix != nil {
var origin string
var err error
if prefix, prefixAliasPath, err = handlePath(response.Update.Prefix, prefixTags, h.aliases, ""); err != nil {
if origin, prefix, prefixAliasPath, err = handlePath(response.Update.Prefix, prefixTags, h.aliases, ""); err != nil {
h.log.Errorf("handling path %q failed: %v", response.Update.Prefix, err)
}
prefix = origin + prefix
}

prefixTags["source"], _, _ = net.SplitHostPort(h.address)
Expand Down Expand Up @@ -287,7 +289,7 @@ func (h *handler) handleSubscribeResponseUpdate(acc telegraf.Accumulator, respon

// HandleTelemetryField and add it to a measurement
func (h *handler) handleTelemetryField(update *gnmiLib.Update, tags map[string]string, prefix string) (string, map[string]interface{}) {
gpath, aliasPath, err := handlePath(update.Path, tags, h.aliases, prefix)
_, gpath, aliasPath, err := handlePath(update.Path, tags, h.aliases, prefix)
if err != nil {
h.log.Errorf("handling path %q failed: %v", update.Path, err)
}
Expand Down
1 change: 1 addition & 0 deletions plugins/inputs/gnmi/testcases/issue_12931/expected.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
interface,name=ethernet-1/1,source=127.0.0.1 interface=1i,transceiver=2i,ethernet=3i,ethernet/flow_control="false",sflow="disable" 1679648530391910312
94 changes: 94 additions & 0 deletions plugins/inputs/gnmi/testcases/issue_12931/responses.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
[
{
"update": {
"timestamp": "1679648530391910312",
"update": [
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
}
]
},
"val": {
"intVal": "1"
}
},
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
},
{
"name": "transceiver"
}
]
},
"val": {
"intVal": "2"
}
},
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
},
{
"name": "ethernet"
}
]
},
"val": {
"intVal": "3"
}
},
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
},
{
"name": "ethernet"
},
{
"name": "flow-control"
}
]
},
"val": {
"stringVal": "false"
}
},
{
"path": {
"origin": "srl_nokia-interfaces",
"elem": [
{
"name": "interface",
"key":{"name":"ethernet-1/1"}
},
{
"name": "sflow"
}
]
},
"val": {
"stringVal": "disable"
}
}
]
}
}
]
10 changes: 10 additions & 0 deletions plugins/inputs/gnmi/testcases/issue_12931/telegraf.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[[inputs.gnmi]]
addresses = ["dummy"]
name_override = "gnmi"
redial = "10s"

[[inputs.gnmi.subscription]]
name = "interface"
path = "/interface"
subscription_mode = "sample"
sample_interval = "10s"
23 changes: 11 additions & 12 deletions plugins/inputs/gnmi/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import (
)

// Parse path to path-buffer and tag-field
func handlePath(gnmiPath *gnmiLib.Path, tags map[string]string, aliases map[string]string, prefix string) (pathBuffer string, aliasPath string, err error) {
//
//nolint:revive //function-result-limit conditionally 4 return results allowed
func handlePath(gnmiPath *gnmiLib.Path, tags map[string]string, aliases map[string]string, prefix string) (origin, path, alias string, err error) {
builder := bytes.NewBufferString(prefix)

// Some devices do report the origin in the first path element
Expand All @@ -28,28 +30,25 @@ func handlePath(gnmiPath *gnmiLib.Path, tags map[string]string, aliases map[stri

// Prefix with origin
if len(gnmiPath.Origin) > 0 {
if _, err := builder.WriteString(gnmiPath.Origin); err != nil {
return "", "", err
}
if _, err := builder.WriteRune(':'); err != nil {
return "", "", err
}
origin = gnmiPath.Origin + ":"
}

// Parse generic keys from prefix
for _, elem := range gnmiPath.Elem {
if len(elem.Name) > 0 {
if _, err := builder.WriteRune('/'); err != nil {
return "", "", err
return "", "", "", err
}
if _, err := builder.WriteString(elem.Name); err != nil {
return "", "", err
return "", "", "", err
}
}
name := builder.String()

if _, exists := aliases[name]; exists {
aliasPath = name
if _, exists := aliases[origin+name]; exists {
alias = origin + name
} else if _, exists := aliases[name]; exists {
alias = name
}

if tags != nil {
Expand All @@ -66,7 +65,7 @@ func handlePath(gnmiPath *gnmiLib.Path, tags map[string]string, aliases map[stri
}
}

return builder.String(), aliasPath, nil
return origin, builder.String(), alias, nil
}

// equalPathNoKeys checks if two gNMI paths are equal, without keys
Expand Down