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

This commit is contained in:
Sven Rebhan 2023-05-23 15:06:02 +02:00 committed by GitHub
parent 66f4b5b03a
commit fb3cd61579
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 32 deletions

View File

@ -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, "")
origin, spath, _, err := handlePath(gnmiPath, nil, nil, "")
if err != nil {
return fmt.Errorf("handling long-path failed: %w", err)
}
shortPath, _, err := handlePath(gnmiShortPath, 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
}

View File

@ -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)
@ -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)
}

View File

@ -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

View File

@ -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"
}
}
]
}
}
]

View File

@ -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"

View File

@ -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
@ -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 {
@ -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