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 { func (s *Subscription) buildAlias(aliases map[string]string) error {
var err error
var gnmiLongPath, gnmiShortPath *gnmiLib.Path
// Build the subscription path without keys // Build the subscription path without keys
if gnmiLongPath, err = parsePath(s.Origin, s.Path, ""); err != nil { gnmiPath, err := parsePath(s.Origin, s.Path, "")
return err if err != nil {
}
if gnmiShortPath, err = parsePath("", s.Path, ""); err != nil {
return err return err
} }
longPath, _, err := handlePath(gnmiLongPath, nil, nil, "") origin, spath, _, err := handlePath(gnmiPath, nil, nil, "")
if err != nil { if err != nil {
return fmt.Errorf("handling long-path failed: %w", err) return fmt.Errorf("handling path failed: %w", err)
}
shortPath, _, err := handlePath(gnmiShortPath, nil, nil, "")
if err != nil {
return fmt.Errorf("handling short-path failed: %w", err)
} }
// If the user didn't provide a measurement name, use last path element // If the user didn't provide a measurement name, use last path element
name := s.Name name := s.Name
if len(name) == 0 { if name == "" {
name = path.Base(shortPath) name = path.Base(spath)
} }
if len(name) > 0 { if name != "" {
aliases[longPath] = name aliases[origin+spath] = name
aliases[shortPath] = name aliases[spath] = name
} }
return nil return nil
} }

View File

@ -174,10 +174,12 @@ func (h *handler) handleSubscribeResponseUpdate(acc telegraf.Accumulator, respon
} }
if response.Update.Prefix != nil { if response.Update.Prefix != nil {
var origin string
var err error 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) h.log.Errorf("handling path %q failed: %v", response.Update.Prefix, err)
} }
prefix = origin + prefix
} }
prefixTags["source"], _, _ = net.SplitHostPort(h.address) 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 // HandleTelemetryField and add it to a measurement
func (h *handler) handleTelemetryField(update *gnmiLib.Update, tags map[string]string, prefix string) (string, map[string]interface{}) { 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 { if err != nil {
h.log.Errorf("handling path %q failed: %v", update.Path, err) 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 // 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) builder := bytes.NewBufferString(prefix)
// Some devices do report the origin in the first path element // 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 // Prefix with origin
if len(gnmiPath.Origin) > 0 { if len(gnmiPath.Origin) > 0 {
if _, err := builder.WriteString(gnmiPath.Origin); err != nil { origin = gnmiPath.Origin + ":"
return "", "", err
}
if _, err := builder.WriteRune(':'); err != nil {
return "", "", err
}
} }
// Parse generic keys from prefix // Parse generic keys from prefix
for _, elem := range gnmiPath.Elem { for _, elem := range gnmiPath.Elem {
if len(elem.Name) > 0 { if len(elem.Name) > 0 {
if _, err := builder.WriteRune('/'); err != nil { if _, err := builder.WriteRune('/'); err != nil {
return "", "", err return "", "", "", err
} }
if _, err := builder.WriteString(elem.Name); err != nil { if _, err := builder.WriteString(elem.Name); err != nil {
return "", "", err return "", "", "", err
} }
} }
name := builder.String() name := builder.String()
if _, exists := aliases[name]; exists { if _, exists := aliases[origin+name]; exists {
aliasPath = name alias = origin + name
} else if _, exists := aliases[name]; exists {
alias = name
} }
if tags != nil { 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 // equalPathNoKeys checks if two gNMI paths are equal, without keys