2022-05-24 21:49:47 +08:00
|
|
|
//go:generate ../../../tools/readme_config_includer/generator
|
2020-07-01 14:19:16 +08:00
|
|
|
package gnmi
|
2019-06-05 05:39:46 +08:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2022-05-24 21:49:47 +08:00
|
|
|
_ "embed"
|
2019-06-05 05:39:46 +08:00
|
|
|
"fmt"
|
2019-09-25 02:05:56 +08:00
|
|
|
"path"
|
2022-11-22 03:59:26 +08:00
|
|
|
"regexp"
|
2019-06-05 05:39:46 +08:00
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
|
2022-04-26 21:38:02 +08:00
|
|
|
"github.com/google/gnxi/utils/xpath"
|
2021-07-28 05:28:26 +08:00
|
|
|
gnmiLib "github.com/openconfig/gnmi/proto/gnmi"
|
|
|
|
|
"google.golang.org/grpc/metadata"
|
|
|
|
|
|
2019-06-05 05:39:46 +08:00
|
|
|
"github.com/influxdata/telegraf"
|
2021-04-10 01:15:04 +08:00
|
|
|
"github.com/influxdata/telegraf/config"
|
2023-04-27 23:30:21 +08:00
|
|
|
"github.com/influxdata/telegraf/internal/choice"
|
2020-06-26 02:44:22 +08:00
|
|
|
internaltls "github.com/influxdata/telegraf/plugins/common/tls"
|
2019-06-05 05:39:46 +08:00
|
|
|
"github.com/influxdata/telegraf/plugins/inputs"
|
|
|
|
|
)
|
|
|
|
|
|
2022-05-24 21:49:47 +08:00
|
|
|
//go:embed sample.conf
|
|
|
|
|
var sampleConfig string
|
|
|
|
|
|
2022-11-22 03:59:26 +08:00
|
|
|
// Regular expression to see if a path element contains an origin
|
|
|
|
|
var originPattern = regexp.MustCompile(`^([\w-_]+):`)
|
|
|
|
|
|
2022-11-30 19:09:31 +08:00
|
|
|
// Define the warning to show if we cannot get a metric name.
|
|
|
|
|
const emptyNameWarning = `Got empty metric-name for response, usually indicating
|
|
|
|
|
configuration issues as the response cannot be related to any subscription.
|
|
|
|
|
Please open an issue on https://github.com/influxdata/telegraf including your
|
|
|
|
|
device model and the following response data:
|
|
|
|
|
%+v
|
|
|
|
|
This message is only printed once.`
|
|
|
|
|
|
2023-04-27 23:30:21 +08:00
|
|
|
// Currently supported GNMI Extensions
|
|
|
|
|
var supportedExtensions = []string{"juniper_header"}
|
|
|
|
|
|
2020-07-01 14:19:16 +08:00
|
|
|
// gNMI plugin instance
|
|
|
|
|
type GNMI struct {
|
2023-05-24 22:14:06 +08:00
|
|
|
Addresses []string `toml:"addresses"`
|
|
|
|
|
Subscriptions []Subscription `toml:"subscription"`
|
|
|
|
|
TagSubscriptions []TagSubscription `toml:"tag_subscription"`
|
|
|
|
|
Aliases map[string]string `toml:"aliases"`
|
|
|
|
|
Encoding string `toml:"encoding"`
|
|
|
|
|
Origin string `toml:"origin"`
|
|
|
|
|
Prefix string `toml:"prefix"`
|
|
|
|
|
Target string `toml:"target"`
|
|
|
|
|
UpdatesOnly bool `toml:"updates_only"`
|
|
|
|
|
VendorSpecific []string `toml:"vendor_specific"`
|
|
|
|
|
Username string `toml:"username"`
|
|
|
|
|
Password string `toml:"password"`
|
|
|
|
|
Redial config.Duration `toml:"redial"`
|
|
|
|
|
MaxMsgSize config.Size `toml:"max_msg_size"`
|
|
|
|
|
Trace bool `toml:"dump_responses"`
|
|
|
|
|
CanonicalFieldNames bool `toml:"canonical_field_names"`
|
2023-06-06 03:56:09 +08:00
|
|
|
EnableTLS bool `toml:"enable_tls" deprecated:"1.27.0;use 'tls_enable' instead"`
|
2023-05-24 22:14:06 +08:00
|
|
|
Log telegraf.Logger `toml:"-"`
|
2019-06-05 05:39:46 +08:00
|
|
|
internaltls.ClientConfig
|
|
|
|
|
|
|
|
|
|
// Internal state
|
2023-02-09 02:30:05 +08:00
|
|
|
internalAliases map[string]string
|
|
|
|
|
cancel context.CancelFunc
|
|
|
|
|
wg sync.WaitGroup
|
2022-07-08 02:50:40 +08:00
|
|
|
}
|
|
|
|
|
|
2020-07-01 14:19:16 +08:00
|
|
|
// Subscription for a gNMI client
|
2019-06-05 05:39:46 +08:00
|
|
|
type Subscription struct {
|
|
|
|
|
Name string
|
|
|
|
|
Origin string
|
|
|
|
|
Path string
|
|
|
|
|
|
2022-07-08 02:50:40 +08:00
|
|
|
fullPath *gnmiLib.Path
|
|
|
|
|
|
2019-06-05 05:39:46 +08:00
|
|
|
// Subscription mode and interval
|
2021-04-10 01:15:04 +08:00
|
|
|
SubscriptionMode string `toml:"subscription_mode"`
|
|
|
|
|
SampleInterval config.Duration `toml:"sample_interval"`
|
2019-06-05 05:39:46 +08:00
|
|
|
|
|
|
|
|
// Duplicate suppression
|
2021-04-10 01:15:04 +08:00
|
|
|
SuppressRedundant bool `toml:"suppress_redundant"`
|
|
|
|
|
HeartbeatInterval config.Duration `toml:"heartbeat_interval"`
|
2022-02-07 23:18:53 +08:00
|
|
|
|
|
|
|
|
// Mark this subscription as a tag-only lookup source, not emitting any metric
|
2023-01-10 03:35:13 +08:00
|
|
|
TagOnly bool `toml:"tag_only" deprecated:"1.25.0;2.0.0;please use 'tag_subscription's instead"`
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
|
|
|
|
|
2022-07-08 02:50:40 +08:00
|
|
|
// Tag Subscription for a gNMI client
|
|
|
|
|
type TagSubscription struct {
|
|
|
|
|
Subscription
|
2023-02-09 02:30:05 +08:00
|
|
|
Match string `toml:"match"`
|
2022-07-08 02:50:40 +08:00
|
|
|
Elements []string
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-24 21:49:47 +08:00
|
|
|
func (*GNMI) SampleConfig() string {
|
|
|
|
|
return sampleConfig
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-06 03:56:09 +08:00
|
|
|
func (c *GNMI) Init() error {
|
|
|
|
|
// Check options
|
|
|
|
|
if time.Duration(c.Redial) <= 0 {
|
|
|
|
|
return fmt.Errorf("redial duration must be positive")
|
|
|
|
|
}
|
2022-07-08 02:50:40 +08:00
|
|
|
|
2023-06-06 03:56:09 +08:00
|
|
|
// Check vendor_specific options configured by user
|
|
|
|
|
if err := choice.CheckSlice(c.VendorSpecific, supportedExtensions); err != nil {
|
|
|
|
|
return fmt.Errorf("unsupported vendor_specific option: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Use the new TLS option for enabling
|
|
|
|
|
// Honor deprecated option
|
|
|
|
|
enable := (c.ClientConfig.Enable != nil && *c.ClientConfig.Enable) || c.EnableTLS
|
|
|
|
|
c.ClientConfig.Enable = &enable
|
|
|
|
|
|
|
|
|
|
// Split the subscriptions into "normal" and "tag" subscription
|
|
|
|
|
// and prepare them.
|
2022-07-08 02:50:40 +08:00
|
|
|
for i := len(c.Subscriptions) - 1; i >= 0; i-- {
|
|
|
|
|
subscription := c.Subscriptions[i]
|
2023-06-06 03:56:09 +08:00
|
|
|
|
|
|
|
|
// Check the subscription
|
|
|
|
|
if subscription.Name == "" {
|
|
|
|
|
return fmt.Errorf("empty 'name' found for subscription %d", i+1)
|
|
|
|
|
}
|
|
|
|
|
if subscription.Path == "" {
|
|
|
|
|
return fmt.Errorf("empty 'path' found for subscription %d", i+1)
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-09 02:30:05 +08:00
|
|
|
// Support and convert legacy TagOnly subscriptions
|
2022-07-08 02:50:40 +08:00
|
|
|
if subscription.TagOnly {
|
2023-02-09 02:30:05 +08:00
|
|
|
tagSub := TagSubscription{
|
|
|
|
|
Subscription: subscription,
|
|
|
|
|
Match: "name",
|
|
|
|
|
}
|
2022-07-08 02:50:40 +08:00
|
|
|
c.TagSubscriptions = append(c.TagSubscriptions, tagSub)
|
|
|
|
|
// Remove from the original subscriptions list
|
|
|
|
|
c.Subscriptions = append(c.Subscriptions[:i], c.Subscriptions[i+1:]...)
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-06-06 03:56:09 +08:00
|
|
|
if err := subscription.buildFullPath(c); err != nil {
|
2022-07-08 02:50:40 +08:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for idx := range c.TagSubscriptions {
|
2023-06-06 03:56:09 +08:00
|
|
|
if err := c.TagSubscriptions[idx].buildFullPath(c); err != nil {
|
2022-07-08 02:50:40 +08:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if c.TagSubscriptions[idx].TagOnly != c.TagSubscriptions[0].TagOnly {
|
|
|
|
|
return fmt.Errorf("do not mix legacy tag_only subscriptions and tag subscriptions")
|
|
|
|
|
}
|
2023-02-09 02:30:05 +08:00
|
|
|
switch c.TagSubscriptions[idx].Match {
|
|
|
|
|
case "":
|
|
|
|
|
if len(c.TagSubscriptions[idx].Elements) > 0 {
|
|
|
|
|
c.TagSubscriptions[idx].Match = "elements"
|
|
|
|
|
} else {
|
|
|
|
|
c.TagSubscriptions[idx].Match = "name"
|
|
|
|
|
}
|
|
|
|
|
case "unconditional":
|
|
|
|
|
case "name":
|
|
|
|
|
case "elements":
|
|
|
|
|
if len(c.TagSubscriptions[idx].Elements) == 0 {
|
|
|
|
|
return fmt.Errorf("tag_subscription must have at least one element")
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("unknown match type %q for tag-subscription %q", c.TagSubscriptions[idx].Match, c.TagSubscriptions[idx].Name)
|
2022-07-08 02:50:40 +08:00
|
|
|
}
|
|
|
|
|
}
|
2019-06-05 05:39:46 +08:00
|
|
|
|
|
|
|
|
// Invert explicit alias list and prefill subscription names
|
2022-07-08 02:50:40 +08:00
|
|
|
c.internalAliases = make(map[string]string, len(c.Subscriptions)+len(c.Aliases)+len(c.TagSubscriptions))
|
|
|
|
|
for _, s := range c.Subscriptions {
|
|
|
|
|
if err := s.buildAlias(c.internalAliases); err != nil {
|
2019-09-25 02:05:56 +08:00
|
|
|
return err
|
|
|
|
|
}
|
2022-07-08 02:50:40 +08:00
|
|
|
}
|
|
|
|
|
for _, s := range c.TagSubscriptions {
|
|
|
|
|
if err := s.buildAlias(c.internalAliases); err != nil {
|
2019-06-15 02:29:06 +08:00
|
|
|
return err
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
|
|
|
|
}
|
2021-07-28 05:28:26 +08:00
|
|
|
for alias, encodingPath := range c.Aliases {
|
|
|
|
|
c.internalAliases[encodingPath] = alias
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
2022-11-22 03:59:26 +08:00
|
|
|
c.Log.Debugf("Internal alias mapping: %+v", c.internalAliases)
|
2019-06-05 05:39:46 +08:00
|
|
|
|
2023-06-06 03:56:09 +08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *GNMI) Start(acc telegraf.Accumulator) error {
|
|
|
|
|
// Validate configuration
|
|
|
|
|
request, err := c.newSubscribeRequest()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate TLS config if enabled
|
|
|
|
|
tlscfg, err := c.ClientConfig.TLSConfig()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Prepare the context, optionally with credentials
|
|
|
|
|
var ctx context.Context
|
|
|
|
|
ctx, c.cancel = context.WithCancel(context.Background())
|
|
|
|
|
if len(c.Username) > 0 {
|
|
|
|
|
ctx = metadata.AppendToOutgoingContext(ctx, "username", c.Username, "password", c.Password)
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-05 05:39:46 +08:00
|
|
|
// Create a goroutine for each device, dial and subscribe
|
|
|
|
|
c.wg.Add(len(c.Addresses))
|
|
|
|
|
for _, addr := range c.Addresses {
|
2023-02-09 02:30:05 +08:00
|
|
|
go func(addr string) {
|
2019-06-05 05:39:46 +08:00
|
|
|
defer c.wg.Done()
|
2023-05-24 22:14:06 +08:00
|
|
|
|
|
|
|
|
h := handler{
|
|
|
|
|
address: addr,
|
|
|
|
|
aliases: c.internalAliases,
|
|
|
|
|
tagsubs: c.TagSubscriptions,
|
|
|
|
|
maxMsgSize: int(c.MaxMsgSize),
|
|
|
|
|
vendorExt: c.VendorSpecific,
|
|
|
|
|
tagStore: newTagStore(c.TagSubscriptions),
|
|
|
|
|
trace: c.Trace,
|
|
|
|
|
canonicalFieldNames: c.CanonicalFieldNames,
|
|
|
|
|
log: c.Log,
|
2023-04-27 23:30:21 +08:00
|
|
|
}
|
2019-06-05 05:39:46 +08:00
|
|
|
for ctx.Err() == nil {
|
2023-02-09 02:30:05 +08:00
|
|
|
if err := h.subscribeGNMI(ctx, acc, tlscfg, request); err != nil && ctx.Err() == nil {
|
2019-06-05 05:39:46 +08:00
|
|
|
acc.AddError(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
select {
|
|
|
|
|
case <-ctx.Done():
|
2021-04-10 01:15:04 +08:00
|
|
|
case <-time.After(time.Duration(c.Redial)):
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-02-09 02:30:05 +08:00
|
|
|
}(addr)
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-08 02:50:40 +08:00
|
|
|
func (s *Subscription) buildSubscription() (*gnmiLib.Subscription, error) {
|
|
|
|
|
gnmiPath, err := parsePath(s.Origin, s.Path, "")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
mode, ok := gnmiLib.SubscriptionMode_value[strings.ToUpper(s.SubscriptionMode)]
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil, fmt.Errorf("invalid subscription mode %s", s.SubscriptionMode)
|
|
|
|
|
}
|
|
|
|
|
return &gnmiLib.Subscription{
|
|
|
|
|
Path: gnmiPath,
|
|
|
|
|
Mode: gnmiLib.SubscriptionMode(mode),
|
|
|
|
|
HeartbeatInterval: uint64(time.Duration(s.HeartbeatInterval).Nanoseconds()),
|
|
|
|
|
SampleInterval: uint64(time.Duration(s.SampleInterval).Nanoseconds()),
|
|
|
|
|
SuppressRedundant: s.SuppressRedundant,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-01 14:19:16 +08:00
|
|
|
// Create a new gNMI SubscribeRequest
|
2021-07-28 05:28:26 +08:00
|
|
|
func (c *GNMI) newSubscribeRequest() (*gnmiLib.SubscribeRequest, error) {
|
2019-06-05 05:39:46 +08:00
|
|
|
// Create subscription objects
|
2022-12-12 22:05:33 +08:00
|
|
|
subscriptions := make([]*gnmiLib.Subscription, 0, len(c.Subscriptions)+len(c.TagSubscriptions))
|
|
|
|
|
for _, subscription := range c.TagSubscriptions {
|
|
|
|
|
sub, err := subscription.buildSubscription()
|
|
|
|
|
if err != nil {
|
2019-06-05 05:39:46 +08:00
|
|
|
return nil, err
|
|
|
|
|
}
|
2022-12-12 22:05:33 +08:00
|
|
|
subscriptions = append(subscriptions, sub)
|
2022-07-08 02:50:40 +08:00
|
|
|
}
|
2022-12-12 22:05:33 +08:00
|
|
|
for _, subscription := range c.Subscriptions {
|
|
|
|
|
sub, err := subscription.buildSubscription()
|
|
|
|
|
if err != nil {
|
2022-07-08 02:50:40 +08:00
|
|
|
return nil, err
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
2022-12-12 22:05:33 +08:00
|
|
|
subscriptions = append(subscriptions, sub)
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Construct subscribe request
|
|
|
|
|
gnmiPath, err := parsePath(c.Origin, c.Prefix, c.Target)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-29 03:58:43 +08:00
|
|
|
// Do not provide an empty prefix. Required for Huawei NE40 router v8.21
|
|
|
|
|
// (and possibly others). See https://github.com/influxdata/telegraf/issues/12273.
|
|
|
|
|
if gnmiPath.Origin == "" && gnmiPath.Target == "" && len(gnmiPath.Elem) == 0 {
|
|
|
|
|
gnmiPath = nil
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-03 00:11:28 +08:00
|
|
|
if c.Encoding != "proto" && c.Encoding != "json" && c.Encoding != "json_ietf" && c.Encoding != "bytes" {
|
2019-06-05 05:39:46 +08:00
|
|
|
return nil, fmt.Errorf("unsupported encoding %s", c.Encoding)
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-28 05:28:26 +08:00
|
|
|
return &gnmiLib.SubscribeRequest{
|
|
|
|
|
Request: &gnmiLib.SubscribeRequest_Subscribe{
|
|
|
|
|
Subscribe: &gnmiLib.SubscriptionList{
|
2019-06-05 05:39:46 +08:00
|
|
|
Prefix: gnmiPath,
|
2021-07-28 05:28:26 +08:00
|
|
|
Mode: gnmiLib.SubscriptionList_STREAM,
|
|
|
|
|
Encoding: gnmiLib.Encoding(gnmiLib.Encoding_value[strings.ToUpper(c.Encoding)]),
|
2019-06-05 05:39:46 +08:00
|
|
|
Subscription: subscriptions,
|
|
|
|
|
UpdatesOnly: c.UpdatesOnly,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 02:49:36 +08:00
|
|
|
// ParsePath from XPath-like string to gNMI path structure
|
2021-07-28 05:28:26 +08:00
|
|
|
func parsePath(origin string, pathToParse string, target string) (*gnmiLib.Path, error) {
|
2022-04-26 21:38:02 +08:00
|
|
|
gnmiPath, err := xpath.ToGNMIPath(pathToParse)
|
2019-06-05 05:39:46 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2022-04-26 21:38:02 +08:00
|
|
|
gnmiPath.Origin = origin
|
|
|
|
|
gnmiPath.Target = target
|
|
|
|
|
return gnmiPath, err
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Stop listener and cleanup
|
2020-07-01 14:19:16 +08:00
|
|
|
func (c *GNMI) Stop() {
|
2019-06-05 05:39:46 +08:00
|
|
|
c.cancel()
|
|
|
|
|
c.wg.Wait()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Gather plugin measurements (unused)
|
2020-07-01 14:19:16 +08:00
|
|
|
func (c *GNMI) Gather(_ telegraf.Accumulator) error {
|
2019-06-05 05:39:46 +08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-01 14:19:16 +08:00
|
|
|
func New() telegraf.Input {
|
|
|
|
|
return &GNMI{
|
|
|
|
|
Encoding: "proto",
|
2021-04-10 01:15:04 +08:00
|
|
|
Redial: config.Duration(10 * time.Second),
|
2020-07-01 14:19:16 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-05 05:39:46 +08:00
|
|
|
func init() {
|
2020-07-01 14:19:16 +08:00
|
|
|
inputs.Add("gnmi", New)
|
|
|
|
|
// Backwards compatible alias:
|
|
|
|
|
inputs.Add("cisco_telemetry_gnmi", New)
|
2019-06-05 05:39:46 +08:00
|
|
|
}
|
2022-07-08 02:50:40 +08:00
|
|
|
|
|
|
|
|
func (s *Subscription) buildFullPath(c *GNMI) error {
|
|
|
|
|
var err error
|
|
|
|
|
if s.fullPath, err = xpath.ToGNMIPath(s.Path); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
s.fullPath.Origin = s.Origin
|
|
|
|
|
s.fullPath.Target = c.Target
|
|
|
|
|
if c.Prefix != "" {
|
|
|
|
|
prefix, err := xpath.ToGNMIPath(c.Prefix)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
s.fullPath.Elem = append(prefix.Elem, s.fullPath.Elem...)
|
|
|
|
|
if s.Origin == "" && c.Origin != "" {
|
|
|
|
|
s.fullPath.Origin = c.Origin
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Subscription) buildAlias(aliases map[string]string) error {
|
|
|
|
|
// Build the subscription path without keys
|
2023-05-23 21:06:02 +08:00
|
|
|
gnmiPath, err := parsePath(s.Origin, s.Path, "")
|
|
|
|
|
if err != nil {
|
2022-07-08 02:50:40 +08:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-23 21:06:02 +08:00
|
|
|
origin, spath, _, err := handlePath(gnmiPath, nil, nil, "")
|
2022-07-08 02:50:40 +08:00
|
|
|
if err != nil {
|
2023-05-23 21:06:02 +08:00
|
|
|
return fmt.Errorf("handling path failed: %w", err)
|
2022-07-08 02:50:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the user didn't provide a measurement name, use last path element
|
|
|
|
|
name := s.Name
|
2023-05-23 21:06:02 +08:00
|
|
|
if name == "" {
|
|
|
|
|
name = path.Base(spath)
|
2022-07-08 02:50:40 +08:00
|
|
|
}
|
2023-05-23 21:06:02 +08:00
|
|
|
if name != "" {
|
|
|
|
|
aliases[origin+spath] = name
|
|
|
|
|
aliases[spath] = name
|
2022-07-08 02:50:40 +08:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|