From 2015fdd668a8572fd5d11c45da1cbaf646fbc147 Mon Sep 17 00:00:00 2001 From: genofire Date: Sat, 20 Jul 2024 00:31:16 +0200 Subject: [PATCH 1/3] feat(link-info): move from meshviewer-ffrgb to runtime --- database/influxdb/node_test.go | 3 + output/meshviewer-ffrgb/meshviewer.go | 68 +------------ output/meshviewer-ffrgb/meshviewer_test.go | 41 +++++--- runtime/link.go | 56 +++++++++++ runtime/node.go | 11 --- runtime/nodes.go | 109 ++++++++++++++++----- runtime/nodes_test.go | 20 ++-- 7 files changed, 187 insertions(+), 121 deletions(-) create mode 100644 runtime/link.go diff --git a/database/influxdb/node_test.go b/database/influxdb/node_test.go index 229fa783..1a3683ad 100644 --- a/database/influxdb/node_test.go +++ b/database/influxdb/node_test.go @@ -14,6 +14,7 @@ func TestToInflux(t *testing.T) { assert := assert.New(t) node := &runtime.Node{ + Online: true, Statistics: &data.Statistics{ NodeID: "deadbeef", LoadAverage: 0.5, @@ -105,6 +106,7 @@ func TestToInflux(t *testing.T) { } neighbour := &runtime.Node{ + Online: true, Nodeinfo: &data.Nodeinfo{ NodeID: "foobar", Network: data.Network{ @@ -132,6 +134,7 @@ func TestToInflux(t *testing.T) { // do not add a empty statistics of a node droppednode := &runtime.Node{ + Online: true, Nodeinfo: &data.Nodeinfo{ NodeID: "notfound", Network: data.Network{ diff --git a/output/meshviewer-ffrgb/meshviewer.go b/output/meshviewer-ffrgb/meshviewer.go index 7ab0c81e..a9fb1510 100644 --- a/output/meshviewer-ffrgb/meshviewer.go +++ b/output/meshviewer-ffrgb/meshviewer.go @@ -4,18 +4,10 @@ import ( "fmt" "strings" - "github.com/bdlm/log" - "github.com/FreifunkBremen/yanic/lib/jsontime" "github.com/FreifunkBremen/yanic/runtime" ) -const ( - LINK_TYPE_WIRELESS = "wifi" - LINK_TYPE_TUNNEL = "vpn" - LINK_TYPE_FALLBACK = "other" -) - func transform(nodes *runtime.Nodes) *Meshviewer { meshviewer := &Meshviewer{ @@ -25,7 +17,6 @@ func transform(nodes *runtime.Nodes) *Meshviewer { } links := make(map[string]*Link) - typeList := make(map[string]string) nodes.RLock() defer nodes.RUnlock() @@ -38,19 +29,6 @@ func transform(nodes *runtime.Nodes) *Meshviewer { continue } - if nodeinfo := nodeOrigin.Nodeinfo; nodeinfo != nil { - if meshes := nodeinfo.Network.Mesh; meshes != nil { - for _, mesh := range meshes { - for _, addr := range mesh.Interfaces.Wireless { - typeList[addr] = LINK_TYPE_WIRELESS - } - for _, addr := range mesh.Interfaces.Tunnel { - typeList[addr] = LINK_TYPE_TUNNEL - } - } - } - } - for _, linkOrigin := range nodes.NodeLinks(nodeOrigin) { var key string // keep source and target in the same order @@ -62,36 +40,11 @@ func transform(nodes *runtime.Nodes) *Meshviewer { } if link := links[key]; link != nil { - linkType, linkTypeFound := typeList[linkOrigin.SourceAddress] - if !linkTypeFound { - linkType, linkTypeFound = typeList[linkOrigin.TargetAddress] - } - if switchSourceTarget { link.TargetTQ = linkOrigin.TQ - - linkType, linkTypeFound = typeList[linkOrigin.TargetAddress] - if !linkTypeFound { - linkType, linkTypeFound = typeList[linkOrigin.SourceAddress] - } } else { link.SourceTQ = linkOrigin.TQ } - - if linkTypeFound && linkType != link.Type { - if link.Type == LINK_TYPE_FALLBACK { - link.Type = linkType - } else { - log.WithFields(map[string]interface{}{ - "link": fmt.Sprintf("%s-%s", linkOrigin.SourceAddress, linkOrigin.TargetAddress), - "prev": link.Type, - "new": linkType, - "source": typeList[linkOrigin.SourceAddress], - "target": typeList[linkOrigin.TargetAddress], - }).Warn("different linktypes") - } - } - continue } link := &Link{ @@ -101,11 +54,7 @@ func transform(nodes *runtime.Nodes) *Meshviewer { TargetAddress: linkOrigin.TargetAddress, SourceTQ: linkOrigin.TQ, TargetTQ: 0, - } - - linkType, linkTypeFound := typeList[linkOrigin.SourceAddress] - if !linkTypeFound { - linkType, linkTypeFound = typeList[linkOrigin.TargetAddress] + Type: linkOrigin.Type.String(), } if switchSourceTarget { @@ -115,22 +64,13 @@ func transform(nodes *runtime.Nodes) *Meshviewer { link.TargetTQ = linkOrigin.TQ link.Target = linkOrigin.SourceID link.TargetAddress = linkOrigin.SourceAddress - - linkType, linkTypeFound = typeList[linkOrigin.TargetAddress] - if !linkTypeFound { - linkType, linkTypeFound = typeList[linkOrigin.SourceAddress] - } } - if linkTypeFound { - link.Type = linkType - } else { - link.Type = LINK_TYPE_FALLBACK - } links[key] = link - meshviewer.Links = append(meshviewer.Links, link) } } - + for _, link := range links { + meshviewer.Links = append(meshviewer.Links, link) + } return meshviewer } diff --git a/output/meshviewer-ffrgb/meshviewer_test.go b/output/meshviewer-ffrgb/meshviewer_test.go index b03dbf21..39844964 100644 --- a/output/meshviewer-ffrgb/meshviewer_test.go +++ b/output/meshviewer-ffrgb/meshviewer_test.go @@ -128,8 +128,8 @@ func TestTransform(t *testing.T) { Other []string `json:"other,omitempty"` Tunnel []string `json:"tunnel,omitempty"` }{ - Wireless: []string{"node:b:mac:wifi"}, - Other: []string{"node:b:mac:lan"}, + Wireless: []string{"node:d:mac:wifi"}, + Other: []string{"node:d:mac:lan"}, }, }, }, @@ -155,28 +155,41 @@ func TestTransform(t *testing.T) { meshviewer := transform(nodes) assert.NotNil(meshviewer) assert.Len(meshviewer.Nodes, 4) + /* + links: + a:wifi <-> b:wifi 153 / 204 + a:lan -> b:lan 51 + c:lan <-> b:lan 102 / 204 + d:lan -> c:lan 204 (but offline) + d:wifi -> a:wifi 204 (but offline) + */ links := meshviewer.Links assert.Len(links, 3) + counter := 0 for _, link := range links { switch link.SourceAddress { case "node:a:mac:lan": - assert.Equal("other", link.Type) - assert.Equal("node:b:mac:lan", link.TargetAddress) - assert.Equal(float32(0.2), link.SourceTQ) - assert.Equal(float32(0), link.TargetTQ) + assert.Equal("node:b:mac:lan", link.TargetAddress, "a:lan -> b:lan") + assert.Equal("other", link.Type, "a:lan -> b:lan") + assert.Equal(float32(0.2), link.SourceTQ, "a:lan -> b:lan") + assert.Equal(float32(0), link.TargetTQ, "a:lan -> b:lan") + counter++ case "node:a:mac:wifi": - assert.Equal("wifi", link.Type) - assert.Equal("node:b:mac:wifi", link.TargetAddress) - assert.Equal(float32(0.6), link.SourceTQ) - assert.Equal(float32(0.8), link.TargetTQ) + assert.Equal("node:b:mac:wifi", link.TargetAddress, "a:wifi <-> b:wifi") + assert.Equal("wifi", link.Type, "a:wifi <-> b:wifi") + assert.Equal(float32(0.6), link.SourceTQ, "a:wifi <-> b:wifi") + assert.Equal(float32(0.8), link.TargetTQ, "a:wifi <-> b:wifi") + counter++ case "node:b:mac:lan": - assert.Equal("other", link.Type) - assert.Equal("node:c:mac:lan", link.TargetAddress) - assert.Equal(float32(0.8), link.SourceTQ) - assert.Equal(float32(0.4), link.TargetTQ) + assert.Equal("other", link.Type, "b:lan <-> c:lan") + assert.Equal("node:c:mac:lan", link.TargetAddress, "b:lan <-> c:lan") + assert.Equal(float32(0.8), link.SourceTQ, "b:lan <-> c:lan") + assert.Equal(float32(0.4), link.TargetTQ, "b:lan <-> c:lan") + counter++ default: assert.False(true, "invalid link.SourceAddress found") } } + assert.Equal(3, counter, "not found every link") } diff --git a/runtime/link.go b/runtime/link.go new file mode 100644 index 00000000..2cad206e --- /dev/null +++ b/runtime/link.go @@ -0,0 +1,56 @@ +package runtime + +type LinkType int + +const ( + UnknownLinkType LinkType = iota + WirelessLinkType + TunnelLinkType + OtherLinkType +) + +func (lt LinkType) String() string { + switch lt { + case WirelessLinkType: + return "wifi" + case TunnelLinkType: + return "vpn" + case OtherLinkType: + return "other" + } + return "unknown" +} + +type LinkProtocol int + +const ( + UnknownLinkProtocol LinkProtocol = iota + BatadvLinkProtocol + BabelLinkProtocol + LLDPLinkProtocol +) + +func (lp LinkProtocol) String() string { + switch lp { + case BatadvLinkProtocol: + return "batadv" + case BabelLinkProtocol: + return "babel" + case LLDPLinkProtocol: + return "lldp" + } + return "unkown" +} + +// Link represents a link between two nodes +type Link struct { + SourceID string + SourceHostname string + SourceAddress string + TargetID string + TargetAddress string + TargetHostname string + TQ float32 + Type LinkType + Protocol LinkProtocol +} diff --git a/runtime/node.go b/runtime/node.go index cf003779..a1af31ac 100644 --- a/runtime/node.go +++ b/runtime/node.go @@ -19,17 +19,6 @@ type Node struct { CustomFields map[string]interface{} `json:"custom_fields"` } -// Link represents a link between two nodes -type Link struct { - SourceID string - SourceHostname string - SourceAddress string - TargetID string - TargetAddress string - TargetHostname string - TQ float32 -} - // IsGateway returns whether the node is a gateway func (node *Node) IsGateway() bool { if info := node.Nodeinfo; info != nil { diff --git a/runtime/nodes.go b/runtime/nodes.go index 7db9f730..138d3dff 100644 --- a/runtime/nodes.go +++ b/runtime/nodes.go @@ -14,18 +14,22 @@ import ( // Nodes struct: cache DB of Node's structs type Nodes struct { - List map[string]*Node `json:"nodes"` // the current nodemap, indexed by node ID - ifaceToNodeID map[string]string // mapping from MAC address to NodeID - config *NodesConfig + List map[string]*Node `json:"nodes"` // the current nodemap, indexed by node ID + ifaceToNodeID map[string]string // mapping from MAC address to NodeID + ifaceToLinkType map[string]LinkType // mapping from MAC address to LinkType + ifaceToLinkProtocol map[string]LinkProtocol // mapping from MAC address to LinkProtocol + config *NodesConfig sync.RWMutex } // NewNodes create Nodes structs func NewNodes(config *NodesConfig) *Nodes { nodes := &Nodes{ - List: make(map[string]*Node), - ifaceToNodeID: make(map[string]string), - config: config, + List: make(map[string]*Node), + ifaceToNodeID: make(map[string]string), + ifaceToLinkType: make(map[string]LinkType), + ifaceToLinkProtocol: make(map[string]LinkProtocol), + config: config, } if config.StatePath != "" { @@ -48,7 +52,7 @@ func (nodes *Nodes) AddNode(node *Node) { nodes.Lock() defer nodes.Unlock() nodes.List[nodeinfo.NodeID] = node - nodes.readIfaces(nodeinfo, false) + nodes.readIfaces(nodeinfo, node.Neighbours, false) } // Update a Node @@ -65,7 +69,7 @@ func (nodes *Nodes) Update(nodeID string, res *data.ResponseData) *Node { nodes.List[nodeID] = node } if res.Nodeinfo != nil { - nodes.readIfaces(res.Nodeinfo, true) + nodes.readIfaces(res.Nodeinfo, res.Neighbours, true) } nodes.Unlock() @@ -110,7 +114,7 @@ func (nodes *Nodes) GetNodeIDbyAddress(addr string) string { func (nodes *Nodes) NodeLinks(node *Node) (result []Link) { // Store link data neighbours := node.Neighbours - if neighbours == nil || neighbours.NodeID == "" { + if neighbours == nil || neighbours.NodeID == "" || !node.Online { return } @@ -133,6 +137,11 @@ func (nodes *Nodes) NodeLinks(node *Node) (result []Link) { if node.Nodeinfo != nil { link.SourceHostname = node.Nodeinfo.Hostname } + if lt, ok := nodes.ifaceToLinkType[sourceMAC]; ok && lt != OtherLinkType { + link.Type = lt + } else if lt, ok := nodes.ifaceToLinkType[neighbourMAC]; ok { + link.Type = lt + } result = append(result, link) } @@ -141,27 +150,39 @@ func (nodes *Nodes) NodeLinks(node *Node) (result []Link) { for _, iface := range neighbours.Babel { for neighbourIP, link := range iface.Neighbours { if neighbourID := nodes.ifaceToNodeID[neighbourIP]; neighbourID != "" { - result = append(result, Link{ + link := Link{ SourceID: neighbours.NodeID, SourceAddress: iface.LinkLocalAddress, TargetID: neighbourID, TargetAddress: neighbourIP, TQ: 1.0 - (float32(link.Cost) / 65535.0), - }) + } + if lt, ok := nodes.ifaceToLinkType[iface.LinkLocalAddress]; ok && lt != OtherLinkType { + link.Type = lt + } else if lt, ok := nodes.ifaceToLinkType[neighbourIP]; ok { + link.Type = lt + } + result = append(result, link) } } } - for portmac, neighmacs := range neighbours.LLDP { - for _, neighmac := range neighmacs { - if neighbourID := nodes.ifaceToNodeID[neighmac]; neighbourID != "" { - result = append(result, Link{ + for sourceMAC, neighmacs := range neighbours.LLDP { + for _, neighbourMAC := range neighmacs { + if neighbourID := nodes.ifaceToNodeID[neighbourMAC]; neighbourID != "" { + link := Link{ SourceID: neighbours.NodeID, - SourceAddress: portmac, + SourceAddress: sourceMAC, TargetID: neighbourID, - TargetAddress: neighmac, + TargetAddress: neighbourMAC, // TODO maybe change LLDP for link quality / 100M or 1GE TQ: 1.0, - }) + } + if lt, ok := nodes.ifaceToLinkType[sourceMAC]; ok && lt != OtherLinkType { + link.Type = lt + } else if lt, ok := nodes.ifaceToLinkType[neighbourMAC]; ok { + link.Type = lt + } + result = append(result, link) } } } @@ -207,8 +228,18 @@ func (nodes *Nodes) expire() { } } +func updateIface[K string | LinkProtocol | LinkType](class string, addr string, dataMap map[string]K, value K, warning bool) { + if oldValue := dataMap[addr]; oldValue != value { + var empty K + if oldValue != empty && warning { + log.Warnf("override %s from %s to %s on %s", class, oldValue, value, addr) + } + dataMap[addr] = value + } +} + // adds the nodes interface addresses to the internal map -func (nodes *Nodes) readIfaces(nodeinfo *data.Nodeinfo, warning bool) { +func (nodes *Nodes) readIfaces(nodeinfo *data.Nodeinfo, neighbours *data.Neighbours, warning bool) { nodeID := nodeinfo.NodeID network := nodeinfo.Network @@ -220,6 +251,15 @@ func (nodes *Nodes) readIfaces(nodeinfo *data.Nodeinfo, warning bool) { addresses := []string{network.Mac} for _, iface := range network.Mesh { + for _, addr := range iface.Interfaces.Wireless { + updateIface("interface-type", addr, nodes.ifaceToLinkType, WirelessLinkType, warning) + } + for _, addr := range iface.Interfaces.Tunnel { + updateIface("interface-type", addr, nodes.ifaceToLinkType, TunnelLinkType, warning) + } + for _, addr := range iface.Interfaces.Other { + updateIface("interface-type", addr, nodes.ifaceToLinkType, OtherLinkType, warning) + } addresses = append(addresses, iface.Addresses()...) } @@ -227,13 +267,32 @@ func (nodes *Nodes) readIfaces(nodeinfo *data.Nodeinfo, warning bool) { if addr == "" { continue } - if oldNodeID := nodes.ifaceToNodeID[addr]; oldNodeID != nodeID { - if oldNodeID != "" && warning { - log.Warnf("override nodeID from %s to %s on MAC address %s", oldNodeID, nodeID, addr) - } - nodes.ifaceToNodeID[addr] = nodeID + updateIface("nodeID", addr, nodes.ifaceToNodeID, nodeID, warning) + } + + if neighbours == nil || neighbours.NodeID == "" { + return + } + + for sourceMAC, batadv := range neighbours.Batadv { + updateIface("mesh-protocol", sourceMAC, nodes.ifaceToLinkProtocol, BatadvLinkProtocol, warning) + for neighbourMAC := range batadv.Neighbours { + updateIface("mesh-protocol", neighbourMAC, nodes.ifaceToLinkProtocol, BatadvLinkProtocol, warning) } } + for _, iface := range neighbours.Babel { + updateIface("mesh-protocol", iface.LinkLocalAddress, nodes.ifaceToLinkProtocol, BabelLinkProtocol, warning) + for neighbourIP := range iface.Neighbours { + updateIface("mesh-protocol", neighbourIP, nodes.ifaceToLinkProtocol, BabelLinkProtocol, warning) + } + } + for portmac, neighmacs := range neighbours.LLDP { + updateIface("mesh-protocol", portmac, nodes.ifaceToLinkProtocol, LLDPLinkProtocol, warning) + for _, neighmac := range neighmacs { + updateIface("mesh-protocol", neighmac, nodes.ifaceToLinkProtocol, LLDPLinkProtocol, warning) + } + } + } func (nodes *Nodes) load() { @@ -246,7 +305,7 @@ func (nodes *Nodes) load() { nodes.Lock() for _, node := range nodes.List { if node.Nodeinfo != nil { - nodes.readIfaces(node.Nodeinfo, false) + nodes.readIfaces(node.Nodeinfo, node.Neighbours, false) } } nodes.Unlock() diff --git a/runtime/nodes_test.go b/runtime/nodes_test.go index fb2ad32c..5f3f6baf 100644 --- a/runtime/nodes_test.go +++ b/runtime/nodes_test.go @@ -18,9 +18,11 @@ func TestExpire(t *testing.T) { // to get default (100%) path of testing // config.PruneAfter.Duration = time.Hour * 24 * 6 nodes := &Nodes{ - config: config, - List: make(map[string]*Node), - ifaceToNodeID: make(map[string]string), + config: config, + List: make(map[string]*Node), + ifaceToNodeID: make(map[string]string), + ifaceToLinkType: make(map[string]LinkType), + ifaceToLinkProtocol: make(map[string]LinkProtocol), } nodes.Update("expire", &data.ResponseData{}) // should expire @@ -89,8 +91,10 @@ func TestLoadAndSave(t *testing.T) { func TestUpdateNodes(t *testing.T) { assert := assert.New(t) nodes := &Nodes{ - List: make(map[string]*Node), - ifaceToNodeID: make(map[string]string), + List: make(map[string]*Node), + ifaceToNodeID: make(map[string]string), + ifaceToLinkType: make(map[string]LinkType), + ifaceToLinkProtocol: make(map[string]LinkProtocol), } assert.Len(nodes.List, 0) @@ -156,8 +160,10 @@ func TestLinksNodes(t *testing.T) { assert := assert.New(t) nodes := &Nodes{ - List: make(map[string]*Node), - ifaceToNodeID: make(map[string]string), + List: make(map[string]*Node), + ifaceToNodeID: make(map[string]string), + ifaceToLinkType: make(map[string]LinkType), + ifaceToLinkProtocol: make(map[string]LinkProtocol), } assert.Len(nodes.List, 0) From da87a8e2de54b23827a933839e528762ec54cd50 Mon Sep 17 00:00:00 2001 From: genofire Date: Sat, 20 Jul 2024 00:33:16 +0200 Subject: [PATCH 2/3] fix(database/influxdb*): add type to link --- database/influxdb/link.go | 1 + database/influxdb/node_test.go | 1 + database/influxdb2/link.go | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/database/influxdb/link.go b/database/influxdb/link.go index 37c2bd90..3ccbebcb 100644 --- a/database/influxdb/link.go +++ b/database/influxdb/link.go @@ -14,6 +14,7 @@ func (conn *Connection) InsertLink(link *runtime.Link, t time.Time) { tags.SetString("source.addr", link.SourceAddress) tags.SetString("target.id", link.TargetID) tags.SetString("target.addr", link.TargetAddress) + tags.SetString("type", link.Type.String()) if link.SourceHostname != "" { tags.SetString("source.hostname", link.SourceHostname) } diff --git a/database/influxdb/node_test.go b/database/influxdb/node_test.go index 1a3683ad..5580ce45 100644 --- a/database/influxdb/node_test.go +++ b/database/influxdb/node_test.go @@ -187,6 +187,7 @@ func TestToInflux(t *testing.T) { "source.addr": "a-interface-mac", "target.id": "foobar", "target.addr": "BAFF1E5", + "type": "vpn", }, tags) assert.EqualValues(80, fields["tq"]) diff --git a/database/influxdb2/link.go b/database/influxdb2/link.go index 4dd36d0a..a28f570a 100644 --- a/database/influxdb2/link.go +++ b/database/influxdb2/link.go @@ -19,7 +19,8 @@ func (conn *Connection) InsertLink(link *runtime.Link, t time.Time) { AddTag("source.id", link.SourceID). AddTag("source.addr", link.SourceAddress). AddTag("target.id", link.TargetID). - AddTag("target.addr", link.TargetAddress) + AddTag("target.addr", link.TargetAddress). + AddTag("type", link.Type.String()) if link.SourceHostname != "" { p.AddTag("source.hostname", link.SourceHostname) } From 20c214d2b6bb97e59bd70fd28535981a54130aac Mon Sep 17 00:00:00 2001 From: genofire Date: Fri, 5 Jul 2024 02:08:54 +0200 Subject: [PATCH 3/3] feat(webserver): add Prometheus --- cmd/serve.go | 4 +- config_example.toml | 10 + go.mod | 97 ++--- go.sum | 294 +++------------- webserver/config.go | 7 +- webserver/prometheus.go | 685 ++++++++++++++++++++++++++++++++++++ webserver/webserver.go | 19 +- webserver/webserver_test.go | 7 +- 8 files changed, 803 insertions(+), 320 deletions(-) create mode 100644 webserver/prometheus.go diff --git a/cmd/serve.go b/cmd/serve.go index 0fd283d0..f37a5df7 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -41,9 +41,11 @@ var serveCmd = &cobra.Command{ if config.Webserver.Enable { log.Infof("starting webserver on %s", config.Webserver.Bind) - srv := webserver.New(config.Webserver.Bind, config.Webserver.Webroot) + srv := webserver.New(config.Webserver, nodes) go webserver.Start(srv) defer srv.Close() + } else if prom := config.Webserver.Prometheus; prom != nil && prom.Enable { + log.Error("to enable prometheus exporter, please enable webserver ") } if config.Respondd.Enable { diff --git a/config_example.toml b/config_example.toml index 2542c6c4..5693a465 100644 --- a/config_example.toml +++ b/config_example.toml @@ -54,6 +54,16 @@ enable = false bind = "127.0.0.1:8080" webroot = "/var/www/html/meshviewer" +[webserver.prometheus] +# need webserver +enable = false +disable_labels = [ + # "hostname", + # "owner", + # "location", +] + + [nodes] # Cache file diff --git a/go.mod b/go.mod index 002a3b68..fb0066cc 100644 --- a/go.mod +++ b/go.mod @@ -1,99 +1,52 @@ module github.com/FreifunkBremen/yanic -go 1.21 +go 1.22 + +toolchain go1.22.3 require ( - github.com/BurntSushi/toml v1.3.2 + github.com/BurntSushi/toml v1.4.0 github.com/NYTimes/gziphandler v1.1.1 github.com/bdlm/log v0.1.20 github.com/bdlm/std v1.0.1 github.com/fgrosse/graphigo v0.0.0-20151222101953-5770fe631d9a - github.com/influxdata/influxdb-client-go/v2 v2.12.3 + github.com/influxdata/influxdb-client-go/v2 v2.13.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c github.com/paulmach/go.geojson v1.5.0 github.com/pkg/errors v0.9.1 - github.com/spf13/cobra v1.7.0 - github.com/stretchr/testify v1.8.4 - github.com/tidwall/gjson v1.16.0 - golang.org/x/sys v0.15.0 + github.com/prometheus/client_golang v1.19.1 + github.com/spf13/cobra v1.8.1 + github.com/stretchr/testify v1.9.0 + github.com/tidwall/gjson v1.17.1 + golang.org/x/sys v0.22.0 ) require ( - github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect - github.com/CloudyKit/jet/v6 v6.2.0 // indirect - github.com/Joker/jade v1.1.3 // indirect - github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/aymerick/douceur v0.2.0 // indirect - github.com/bytedance/sonic v1.10.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect - github.com/chenzhuoyu/iasm v0.9.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deepmap/oapi-codegen v1.15.0 // indirect - github.com/fatih/structs v1.1.0 // indirect - github.com/flosch/pongo2/v4 v4.0.2 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.1 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.4 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20230916125811-7478c230c7cd // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/gorilla/css v1.0.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf // indirect - github.com/iris-contrib/schema v0.0.6 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kataras/blocks v0.0.7 // indirect - github.com/kataras/golog v0.1.9 // indirect - github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 // indirect - github.com/kataras/pio v0.0.12 // indirect - github.com/kataras/sitemap v0.0.6 // indirect - github.com/kataras/tunnel v0.0.4 // indirect - github.com/klauspost/compress v1.17.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/labstack/echo/v4 v4.11.1 // indirect - github.com/labstack/gommon v0.4.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect - github.com/mailgun/raymond/v2 v2.0.48 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/microcosm-cc/bluemonday v1.0.25 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/kr/text v0.1.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nxadm/tail v1.4.11 // indirect + github.com/oapi-codegen/runtime v1.1.1 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/gomega v1.19.0 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/schollz/closestmatch v2.1.0+incompatible // indirect - github.com/sirupsen/logrus v1.9.3 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/tdewolff/minify/v2 v2.12.9 // indirect - github.com/tdewolff/parse/v2 v2.6.8 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/yosssi/ace v0.0.5 // indirect - golang.org/x/arch v0.5.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/term v0.22.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/fgrosse/graphigo.v2 v2.0.0-20151220153422-55a0a92a7030 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index a2fae59e..dd9c4a30 100644 --- a/go.sum +++ b/go.sum @@ -1,78 +1,31 @@ -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= -github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= -github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= -github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bdlm/log v0.1.20 h1:fSxBuBSHz+DkxPSFlaVcPiep20mCYUJZ5azUynkjhfA= github.com/bdlm/log v0.1.20/go.mod h1:30V5Zwc5Vt5ePq5rd9KJ6JQ/A5aFUcKzq5fYtO7c9qc= github.com/bdlm/std v1.0.1 h1:USdxays+0tgB3BJCEQ9z942tmTWmzpVPC7jCvczsj/I= github.com/bdlm/std v1.0.1/go.mod h1:dittT3gnvbHQ4P+1UbkdSwkHFHVl1gx8qYu4zIFyB+Q= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc= -github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= -github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deepmap/oapi-codegen v1.15.0 h1:SQqViaeb4k2vMul8gx12oDOIadEtoRqTdLkxjzqtQ90= -github.com/deepmap/oapi-codegen v1.15.0/go.mod h1:a6KoHV7lMRwsPoEg2C6NDHiXYV3EQfiFocOlJ8dgJQE= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fgrosse/graphigo v0.0.0-20151222101953-5770fe631d9a h1:vV0pSGlrwV+cPffwHDKckZiU3qcaIXTnZGXLX64i4Rk= github.com/fgrosse/graphigo v0.0.0-20151222101953-5770fe631d9a/go.mod h1:m3fD9iVpJUF8Kl2kz/HwASu4Hf1x3s3V+H0BiEj46XQ= -github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= -github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs= -github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -80,97 +33,36 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230916125811-7478c230c7cd h1:laCEzrtkKEkT2424vMTGl6N1m0xN8kq371hksD5Be+8= -github.com/gomarkdown/markdown v0.0.0-20230916125811-7478c230c7cd/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/influxdb-client-go/v2 v2.12.3 h1:28nRlNMRIV4QbtIUvxhWqaxn0IpXeMSkY/uJa/O/vC4= -github.com/influxdata/influxdb-client-go/v2 v2.12.3/go.mod h1:IrrLUbCjjfkmRuaCiGQg4m2GbkaeJDcuWoxiWdQEbA0= +github.com/influxdata/influxdb-client-go/v2 v2.13.0 h1:ioBbLmR5NMbAjP4UVA5r9b5xGjpABD7j65pI8kFphDM= +github.com/influxdata/influxdb-client-go/v2 v2.13.0/go.mod h1:k+spCbt9hcvqvUiz0sr5D8LolXHqAAOfPw9v/RIRHl4= github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs= github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf h1:7JTmneyiNEwVBOHSjoMxiWAqB992atOeepeFYegn5RU= github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go= -github.com/iris-contrib/httpexpect/v2 v2.15.2/go.mod h1:JLDgIqnFy5loDSUv1OA2j0mb6p/rDhiCqigP22Uq9xE= -github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= -github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/kataras/blocks v0.0.7 h1:cF3RDY/vxnSRezc7vLFlQFTYXG/yAr1o7WImJuZbzC4= -github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= -github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= -github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= -github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= -github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= -github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= -github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= -github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= -github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= -github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= -github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4= -github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= -github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= -github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= +github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -181,148 +73,79 @@ github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/paulmach/go.geojson v1.5.0 h1:7mhpMK89SQdHFcEGomT7/LuJhwhEgfmpWYVlVmLEdQw= github.com/paulmach/go.geojson v1.5.0/go.mod h1:DgdUy2rRVDDVgKqrjMe2vZAHMfhDTrjVKt3LmHIXGbU= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= -github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= -github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= -github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= -github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= -github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= -github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= -github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg= -github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= -github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= -github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y= -golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -330,17 +153,14 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fgrosse/graphigo.v2 v2.0.0-20151220153422-55a0a92a7030 h1:EFs63oNabMkD6Id8lVrIUAA+61GGtkzxnA4auRoAkwY= gopkg.in/fgrosse/graphigo.v2 v2.0.0-20151220153422-55a0a92a7030/go.mod h1:DXZVkyME6s9B/JGEUvA8aN0ip2fJgEhA72/rvfOeiIA= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -348,11 +168,5 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= -moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/webserver/config.go b/webserver/config.go index 6edca0bb..d527fbda 100644 --- a/webserver/config.go +++ b/webserver/config.go @@ -1,7 +1,8 @@ package webserver type Config struct { - Enable bool `toml:"enable"` - Bind string `toml:"bind"` - Webroot string `toml:"webroot"` + Enable bool `toml:"enable"` + Bind string `toml:"bind"` + Webroot string `toml:"webroot"` + Prometheus *Prometheus `toml:"prometheus"` } diff --git a/webserver/prometheus.go b/webserver/prometheus.go new file mode 100644 index 00000000..eba96d9b --- /dev/null +++ b/webserver/prometheus.go @@ -0,0 +1,685 @@ +package webserver + +import ( + "fmt" + "strconv" + + "github.com/FreifunkBremen/yanic/data" + "github.com/FreifunkBremen/yanic/runtime" + + "github.com/prometheus/client_golang/prometheus" +) + +var ( + promDescNodeInfo = prometheus.NewDesc("yanic_node_info", "node info on labels", []string{ + "node_id", + "hostname", + "owner", + "latitude", + "longitude", + "site_code", + "domain_code", + "model", + "nproc", + "firmware_base", + "firmware_release", + "autoupdater", + }, prometheus.Labels{}) + + nodeLabels = []string{"node_id"} + + promDescNodeUP = prometheus.NewDesc("yanic_node_up", "node is up", nodeLabels, prometheus.Labels{}) + promDescNodeFirstseen = prometheus.NewDesc("yanic_node_firstseen", "node firstseen as timestemp", nodeLabels, prometheus.Labels{}) + promDescNodeLastseen = prometheus.NewDesc("yanic_node_lastseen", "node lastseen as timestemp", nodeLabels, prometheus.Labels{}) + + promDescNodeLoad = prometheus.NewDesc("yanic_node_load", "load of node", nodeLabels, prometheus.Labels{}) + + promDescNodeTimeUP = prometheus.NewDesc("yanic_node_time_up", "", nodeLabels, prometheus.Labels{}) + promDescNodeTimeIdle = prometheus.NewDesc("yanic_node_time_idle", "", nodeLabels, prometheus.Labels{}) + + promDescNodeProcRunning = prometheus.NewDesc("yanic_node_proc_running", "", nodeLabels, prometheus.Labels{}) + + // Clients - complete + promDescNodeClientsWifi = prometheus.NewDesc("yanic_node_clients_wifi", "", nodeLabels, prometheus.Labels{}) + promDescNodeClientsWifi24 = prometheus.NewDesc("yanic_node_clients_wifi24", "", nodeLabels, prometheus.Labels{}) + promDescNodeClientsWifi5 = prometheus.NewDesc("yanic_node_clients_wifi5", "", nodeLabels, prometheus.Labels{}) + + promDescNodeClientsOwe = prometheus.NewDesc("yanic_node_clients_owe", "", nodeLabels, prometheus.Labels{}) + promDescNodeClientsOwe24 = prometheus.NewDesc("yanic_node_clients_owe24", "", nodeLabels, prometheus.Labels{}) + promDescNodeClientsOwe5 = prometheus.NewDesc("yanic_node_clients_owe5", "", nodeLabels, prometheus.Labels{}) + promDescNodeClientsTotal = prometheus.NewDesc("yanic_node_clients_total", "", nodeLabels, prometheus.Labels{}) + + // Memory - compelte + promDescNodeMemBuffers = prometheus.NewDesc("yanic_node_memmory_buffers", "", nodeLabels, prometheus.Labels{}) + promDescNodeMemCached = prometheus.NewDesc("yanic_node_memmory_cached", "", nodeLabels, prometheus.Labels{}) + promDescNodeMemFree = prometheus.NewDesc("yanic_node_memmory_free", "", nodeLabels, prometheus.Labels{}) + promDescNodeMemTotal = prometheus.NewDesc("yanic_node_memmory_total", "", nodeLabels, prometheus.Labels{}) + promDescNodeMemAvailable = prometheus.NewDesc("yanic_node_memmory_available", "", nodeLabels, prometheus.Labels{}) + + // ProcStats - complete + promDescNodeStatCPUUser = prometheus.NewDesc("yanic_node_stat_cpu_user", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatCPUNice = prometheus.NewDesc("yanic_node_stat_cpu_nice", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatCPUSystem = prometheus.NewDesc("yanic_node_stat_cpu_system", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatCPUIdle = prometheus.NewDesc("yanic_node_stat_cpu_idle", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatCPUIOWait = prometheus.NewDesc("yanic_node_stat_cpu_iowait", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatCPUIRQ = prometheus.NewDesc("yanic_node_stat_cpu_irq", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatCPUSoftIRQ = prometheus.NewDesc("yanic_node_stat_cpu_softirq", "", nodeLabels, prometheus.Labels{}) + + promDescNodeStatIntr = prometheus.NewDesc("yanic_node_stat_intr", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatContextSwitches = prometheus.NewDesc("yanic_node_stat_ctxt", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatSoftIRQ = prometheus.NewDesc("yanic_node_stat_softirq", "", nodeLabels, prometheus.Labels{}) + promDescNodeStatProcesses = prometheus.NewDesc("yanic_node_stat_processes", "", nodeLabels, prometheus.Labels{}) + + // Traffic - complete + promDescNodeTrafficRxBytes = prometheus.NewDesc("yanic_node_traffic_rx_bytes", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficRxPackets = prometheus.NewDesc("yanic_node_traffic_rx_packets", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficRxDropped = prometheus.NewDesc("yanic_node_traffic_rx_dropped", "", nodeLabels, prometheus.Labels{}) + + promDescNodeTrafficTxBytes = prometheus.NewDesc("yanic_node_traffic_tx_bytes", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficTxPackets = prometheus.NewDesc("yanic_node_traffic_tx_packets", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficTxDropped = prometheus.NewDesc("yanic_node_traffic_tx_dropped", "", nodeLabels, prometheus.Labels{}) + + promDescNodeTrafficForwardBytes = prometheus.NewDesc("yanic_node_traffic_forward_bytes", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficForwardPackets = prometheus.NewDesc("yanic_node_traffic_forward_packets", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficForwardDropped = prometheus.NewDesc("yanic_node_traffic_forward_dropped", "", nodeLabels, prometheus.Labels{}) + + promDescNodeTrafficMgmtRxBytes = prometheus.NewDesc("yanic_node_traffic_mgmt_rx_bytes", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficMgmtRxPackets = prometheus.NewDesc("yanic_node_traffic_mgmt_rx_packets", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficMgmtRxDropped = prometheus.NewDesc("yanic_node_traffic_mgmt_rx_dropped", "", nodeLabels, prometheus.Labels{}) + + promDescNodeTrafficMgmtTxBytes = prometheus.NewDesc("yanic_node_traffic_mgmt_tx_bytes", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficMgmtTxPackets = prometheus.NewDesc("yanic_node_traffic_mgmt_tx_packets", "", nodeLabels, prometheus.Labels{}) + promDescNodeTrafficMgmtTxDropped = prometheus.NewDesc("yanic_node_traffic_mgmt_tx_dropped", "", nodeLabels, prometheus.Labels{}) + + // Wireless - just necessary + allLabelsWithFrequency = append(nodeLabels, "frequency", "frequency_name") + promDescNodeFrequency = prometheus.NewDesc("yanic_node_frequency", "", allLabelsWithFrequency, prometheus.Labels{}) + promDescNodeAirtimeChanUtil = prometheus.NewDesc("yanic_node_airtime_chan_util", "", allLabelsWithFrequency, prometheus.Labels{}) + promDescNodeAirtimeTxUtil = prometheus.NewDesc("yanic_node_airtime_tx_util", "", allLabelsWithFrequency, prometheus.Labels{}) + promDescNodeAirtimeRxUtil = prometheus.NewDesc("yanic_node_airtime_rx_util", "", allLabelsWithFrequency, prometheus.Labels{}) + promDescNodeAirtimeNoise = prometheus.NewDesc("yanic_node_airtime_noise", "", allLabelsWithFrequency, prometheus.Labels{}) + promDescNodeWirelessTxPower = prometheus.NewDesc("yanic_node_wireless_txpower", "", allLabelsWithFrequency, prometheus.Labels{}) + + // Links - just necessary + labelLinks = []string{"source_id", "target_id", "source_address", "target_address", "type"} + promDescLinkTQ = prometheus.NewDesc("yanic_link_tq", "", labelLinks, prometheus.Labels{}) +) + +type Prometheus struct { + Enable bool `toml:"enable"` + DisableLabels []string `toml:"disable_labels"` + nodes *runtime.Nodes + disLabels map[string]bool +} + +func (prom *Prometheus) Init(nodes *runtime.Nodes) { + prom.nodes = nodes + prom.disLabels = make(map[string]bool) + for _, label := range prom.DisableLabels { + prom.disLabels[label] = false + } + +} + +func (prom *Prometheus) Describe(d chan<- *prometheus.Desc) { + d <- promDescNodeInfo + + d <- promDescNodeUP + d <- promDescNodeFirstseen + d <- promDescNodeLastseen + + d <- promDescNodeLoad + + d <- promDescNodeTimeUP + d <- promDescNodeTimeIdle + + d <- promDescNodeProcRunning + + d <- promDescNodeClientsWifi + d <- promDescNodeClientsWifi24 + d <- promDescNodeClientsWifi5 + + d <- promDescNodeClientsOwe + d <- promDescNodeClientsOwe24 + d <- promDescNodeClientsOwe5 + d <- promDescNodeClientsTotal + + d <- promDescNodeMemBuffers + d <- promDescNodeMemCached + d <- promDescNodeMemFree + d <- promDescNodeMemTotal + d <- promDescNodeMemAvailable + + d <- promDescNodeStatCPUUser + d <- promDescNodeStatCPUNice + d <- promDescNodeStatCPUSystem + d <- promDescNodeStatCPUIdle + d <- promDescNodeStatCPUIOWait + d <- promDescNodeStatCPUIRQ + d <- promDescNodeStatCPUSoftIRQ + + d <- promDescNodeStatIntr + d <- promDescNodeStatContextSwitches + d <- promDescNodeStatSoftIRQ + d <- promDescNodeStatProcesses + + d <- promDescNodeTrafficRxBytes + d <- promDescNodeTrafficRxPackets + d <- promDescNodeTrafficRxDropped + + d <- promDescNodeTrafficTxBytes + d <- promDescNodeTrafficTxPackets + d <- promDescNodeTrafficTxDropped + + d <- promDescNodeTrafficForwardBytes + d <- promDescNodeTrafficForwardPackets + d <- promDescNodeTrafficForwardDropped + + d <- promDescNodeTrafficMgmtRxBytes + d <- promDescNodeTrafficMgmtRxPackets + d <- promDescNodeTrafficMgmtRxDropped + + d <- promDescNodeTrafficMgmtTxBytes + d <- promDescNodeTrafficMgmtTxPackets + d <- promDescNodeTrafficMgmtTxDropped + + d <- promDescNodeFrequency + d <- promDescNodeAirtimeChanUtil + d <- promDescNodeAirtimeRxUtil + d <- promDescNodeAirtimeTxUtil + d <- promDescNodeAirtimeNoise + d <- promDescNodeWirelessTxPower + + d <- promDescLinkTQ +} + +func (prom *Prometheus) getNodeLabels(ni *data.Nodeinfo) []string { + labels := make([]string, 12) + labels[0] = ni.NodeID + if _, nok := prom.disLabels["hostname"]; !nok { + labels[1] = ni.Hostname + } else { + labels[1] = "DISABLED" + } + if _, nok := prom.disLabels["owner"]; !nok { + if owner := ni.Owner; owner != nil { + labels[2] = owner.Contact + } + } else { + labels[2] = "DISABLED" + } + if _, nok := prom.disLabels["location"]; !nok { + if location := ni.Location; location != nil { + labels[3] = fmt.Sprintf("%v", location.Latitude) + labels[4] = fmt.Sprintf("%v", location.Longitude) + } + } else { + labels[3] = "DISABLED" + labels[4] = "DISABLED" + } + labels[5] = ni.System.SiteCode + labels[6] = ni.System.DomainCode + labels[7] = ni.Hardware.Model + labels[8] = strconv.Itoa(ni.Hardware.Nproc) + if firmware := ni.Software.Firmware; firmware != nil { + labels[9] = firmware.Base + labels[10] = firmware.Release + } + if ni.Software.Autoupdater != nil && ni.Software.Autoupdater.Enabled { + labels[11] = ni.Software.Autoupdater.Branch + } else { + labels[11] = runtime.DISABLED_AUTOUPDATER + } + return labels + +} + +func (prom *Prometheus) Collect(metrics chan<- prometheus.Metric) { + prom.nodes.Lock() + defer prom.nodes.Unlock() + for _, node := range prom.nodes.List { + nodeinfo := node.Nodeinfo + if nodeinfo == nil { + continue + } + nodeLabelValues := prom.getNodeLabels(nodeinfo) + if m, err := prometheus.NewConstMetric( + promDescNodeInfo, + prometheus.CounterValue, + 1, + nodeLabelValues...); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeFirstseen, + prometheus.CounterValue, + float64(node.Firstseen.Unix()), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeLastseen, + prometheus.CounterValue, + float64(node.Lastseen.Unix()), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if !node.Online { + if m, err := prometheus.NewConstMetric( + promDescNodeUP, + prometheus.GaugeValue, + 0, + nodeinfo.NodeID); err == nil { + metrics <- m + } + continue + } + stats := node.Statistics + if stats == nil { + continue + } + if m, err := prometheus.NewConstMetric( + promDescNodeUP, + prometheus.GaugeValue, + 1, + nodeinfo.NodeID); err == nil { + metrics <- m + } + + if m, err := prometheus.NewConstMetric( + promDescNodeLoad, + prometheus.GaugeValue, + stats.LoadAverage, + nodeinfo.NodeID); err == nil { + metrics <- m + } + + if m, err := prometheus.NewConstMetric( + promDescNodeTimeUP, + prometheus.GaugeValue, + float64(stats.Uptime), + nodeinfo.NodeID); err == nil { + metrics <- m + } + + if m, err := prometheus.NewConstMetric( + promDescNodeTimeIdle, + prometheus.GaugeValue, + stats.Idletime, + nodeinfo.NodeID); err == nil { + metrics <- m + } + + if m, err := prometheus.NewConstMetric( + promDescNodeProcRunning, + prometheus.GaugeValue, + float64(stats.Processes.Running), + nodeinfo.NodeID); err == nil { + metrics <- m + } + + // Clients + if m, err := prometheus.NewConstMetric( + promDescNodeClientsWifi, + prometheus.GaugeValue, + float64(stats.Clients.Wifi), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeClientsWifi24, + prometheus.GaugeValue, + float64(stats.Clients.Wifi24), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeClientsWifi5, + prometheus.GaugeValue, + float64(stats.Clients.Wifi5), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeClientsOwe, + prometheus.GaugeValue, + float64(stats.Clients.OWE), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeClientsOwe24, + prometheus.GaugeValue, + float64(stats.Clients.OWE24), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeClientsOwe5, + prometheus.GaugeValue, + float64(stats.Clients.OWE5), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeClientsTotal, + prometheus.GaugeValue, + float64(stats.Clients.Total), + nodeinfo.NodeID); err == nil { + metrics <- m + } + + // Memory + if m, err := prometheus.NewConstMetric( + promDescNodeMemBuffers, + prometheus.GaugeValue, + float64(stats.Memory.Buffers), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeMemCached, + prometheus.GaugeValue, + float64(stats.Memory.Cached), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeMemFree, + prometheus.GaugeValue, + float64(stats.Memory.Free), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeMemTotal, + prometheus.GaugeValue, + float64(stats.Memory.Total), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeMemAvailable, + prometheus.GaugeValue, + float64(stats.Memory.Available), + nodeinfo.NodeID); err == nil { + metrics <- m + } + + if procstat := stats.ProcStats; procstat != nil { + if m, err := prometheus.NewConstMetric( + promDescNodeStatCPUUser, + prometheus.GaugeValue, + float64(procstat.CPU.User), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatCPUNice, + prometheus.GaugeValue, + float64(procstat.CPU.Nice), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatCPUSystem, + prometheus.GaugeValue, + float64(procstat.CPU.System), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatCPUIdle, + prometheus.GaugeValue, + float64(procstat.CPU.Idle), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatCPUIOWait, + prometheus.GaugeValue, + float64(procstat.CPU.IOWait), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatCPUIRQ, + prometheus.GaugeValue, + float64(procstat.CPU.IRQ), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatCPUSoftIRQ, + prometheus.GaugeValue, + float64(procstat.CPU.SoftIRQ), + nodeinfo.NodeID); err == nil { + metrics <- m + } + + if m, err := prometheus.NewConstMetric( + promDescNodeStatIntr, + prometheus.GaugeValue, + float64(procstat.Intr), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatContextSwitches, + prometheus.GaugeValue, + float64(procstat.ContextSwitches), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatSoftIRQ, + prometheus.GaugeValue, + float64(procstat.SoftIRQ), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeStatProcesses, + prometheus.GaugeValue, + float64(procstat.Processes), + nodeinfo.NodeID); err == nil { + metrics <- m + } + } + if t := stats.Traffic.Rx; t != nil { + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficRxBytes, + prometheus.GaugeValue, + float64(t.Bytes), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficRxPackets, + prometheus.GaugeValue, + float64(t.Packets), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficRxDropped, + prometheus.GaugeValue, + float64(t.Dropped), + nodeinfo.NodeID); err == nil { + metrics <- m + } + } + if t := stats.Traffic.Tx; t != nil { + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficTxBytes, + prometheus.GaugeValue, + float64(t.Bytes), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficTxPackets, + prometheus.GaugeValue, + float64(t.Packets), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficTxDropped, + prometheus.GaugeValue, + float64(t.Dropped), + nodeinfo.NodeID); err == nil { + metrics <- m + } + } + if t := stats.Traffic.Forward; t != nil { + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficForwardBytes, + prometheus.GaugeValue, + float64(t.Bytes), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficForwardPackets, + prometheus.GaugeValue, + float64(t.Packets), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficForwardDropped, + prometheus.GaugeValue, + float64(t.Dropped), + nodeinfo.NodeID); err == nil { + metrics <- m + } + } + if t := stats.Traffic.MgmtTx; t != nil { + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficMgmtTxBytes, + prometheus.GaugeValue, + float64(t.Bytes), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficMgmtTxPackets, + prometheus.GaugeValue, + float64(t.Packets), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficMgmtTxDropped, + prometheus.GaugeValue, + float64(t.Dropped), + nodeinfo.NodeID); err == nil { + metrics <- m + } + } + if t := stats.Traffic.MgmtRx; t != nil { + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficMgmtRxBytes, + prometheus.GaugeValue, + float64(t.Bytes), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficMgmtRxPackets, + prometheus.GaugeValue, + float64(t.Packets), + nodeinfo.NodeID); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeTrafficMgmtRxDropped, + prometheus.GaugeValue, + float64(t.Dropped), + nodeinfo.NodeID); err == nil { + metrics <- m + } + } + + // add a label for frequency_name + labelIndex := len(nodeLabels) + labels := []string{nodeinfo.NodeID, "", ""} + for _, airtime := range stats.Wireless { + labels[labelIndex] = strconv.Itoa(int(airtime.Frequency)) + labels[labelIndex+1] = airtime.FrequencyName() + + if m, err := prometheus.NewConstMetric( + promDescNodeFrequency, + prometheus.GaugeValue, + float64(airtime.Frequency), + labels...); err == nil { + metrics <- m + } + + if m, err := prometheus.NewConstMetric( + promDescNodeAirtimeChanUtil, + prometheus.GaugeValue, + float64(airtime.ChanUtil), + labels...); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeAirtimeTxUtil, + prometheus.GaugeValue, + float64(airtime.TxUtil), + labels...); err == nil { + metrics <- m + } + + if m, err := prometheus.NewConstMetric( + promDescNodeAirtimeRxUtil, + prometheus.GaugeValue, + float64(airtime.RxUtil), + labels...); err == nil { + metrics <- m + } + if m, err := prometheus.NewConstMetric( + promDescNodeAirtimeNoise, + prometheus.GaugeValue, + float64(airtime.Noise), + labels...); err == nil { + metrics <- m + } + if wireless := nodeinfo.Wireless; wireless != nil { + if airtime.Frequency < 5000 { + if m, err := prometheus.NewConstMetric( + promDescNodeWirelessTxPower, + prometheus.GaugeValue, + float64(wireless.TxPower24), + labels...); err == nil { + metrics <- m + } + } else { + if m, err := prometheus.NewConstMetric( + promDescNodeWirelessTxPower, + prometheus.GaugeValue, + float64(wireless.TxPower5), + labels...); err == nil { + metrics <- m + } + } + } + } + for _, link := range prom.nodes.NodeLinks(node) { + if m, err := prometheus.NewConstMetric( + promDescLinkTQ, + prometheus.GaugeValue, + float64(link.TQ), + // labels: + link.SourceID, + link.TargetID, + link.SourceAddress, + link.TargetAddress, + link.Type.String(), + ); err == nil { + metrics <- m + } + } + } +} diff --git a/webserver/webserver.go b/webserver/webserver.go index 0a277696..6125a80a 100644 --- a/webserver/webserver.go +++ b/webserver/webserver.go @@ -3,15 +3,28 @@ package webserver import ( "net/http" + "github.com/FreifunkBremen/yanic/runtime" + "github.com/NYTimes/gziphandler" "github.com/bdlm/log" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" ) // New creates a new webserver and starts it -func New(bindAddr, webroot string) *http.Server { +func New(config Config, nodes *runtime.Nodes) *http.Server { + mux := http.NewServeMux() + if config.Prometheus != nil && config.Prometheus.Enable { + config.Prometheus.Init(nodes) + prometheus.MustRegister(config.Prometheus) + mux.Handle("/metrics", promhttp.Handler()) + } + if config.Webroot != "" { + mux.Handle("/", gziphandler.GzipHandler(http.FileServer(http.Dir(config.Webroot)))) + } return &http.Server{ - Addr: bindAddr, - Handler: gziphandler.GzipHandler(http.FileServer(http.Dir(webroot))), + Addr: config.Bind, + Handler: mux, } } diff --git a/webserver/webserver_test.go b/webserver/webserver_test.go index d612799f..9815cba9 100644 --- a/webserver/webserver_test.go +++ b/webserver/webserver_test.go @@ -10,7 +10,12 @@ import ( func TestWebserver(t *testing.T) { assert := assert.New(t) - srv := New(":12345", "/tmp") + config := Config{ + Bind: ":12345", + Webroot: "/tmp", + } + + srv := New(config, nil) assert.NotNil(srv) go Start(srv)