Skip to content

Commit

Permalink
Merge pull request #130 from AKYD/update_multi_re_support_storage
Browse files Browse the repository at this point in the history
 Update multi routing engine support for the "storage" module
  • Loading branch information
czerwonk authored Apr 20, 2021
2 parents ecf3a52 + 79da211 commit 5ed6550
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 57 deletions.
21 changes: 11 additions & 10 deletions storage/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ func (*storageCollector) Describe(ch chan<- *prometheus.Desc) {

// Collect collects metrics from JunOS
func (c *storageCollector) Collect(client *rpc.Client, ch chan<- prometheus.Metric, labelValues []string) error {
var x = MultiRoutingEngineResults{}
var x = RpcReply{}
err := client.RunCommandAndParseWithParser("show system storage", func(b []byte) error {
return parseXML(b, &x)
})
if err != nil {
return err
}

for _, re := range x.Results {
for _, f := range re.Storage.Information.Filesystems {
for _, re := range x.MultiRoutingEngineResults.RoutingEngine {
for _, f := range re.StorageInformation.Filesystems {
l := append(labelValues, f.FilesystemName, re.Name, f.MountedOn)

ch <- prometheus.MustNewConstMetric(totalBlocksDesc, prometheus.GaugeValue, float64(f.TotalBlocks), l...)
Expand All @@ -77,21 +77,22 @@ func (c *storageCollector) Collect(client *rpc.Client, ch chan<- prometheus.Metr
return nil
}

func parseXML(b []byte, res *MultiRoutingEngineResults) error {
func parseXML(b []byte, res *RpcReply) error {
if strings.Contains(string(b), "multi-routing-engine-results") {
return xml.Unmarshal(b, res)
}

si := StorageInformation{}
err := xml.Unmarshal(b, &si)
fi := RpcReplyNoRE{}

err := xml.Unmarshal(b, &fi)
if err != nil {
return err
}

res.Results = []MultiRoutingEngineItem{
MultiRoutingEngineItem{
Name: "",
Storage: si,
res.MultiRoutingEngineResults.RoutingEngine = []RoutingEngine{
RoutingEngine{
Name: "N/A",
StorageInformation: fi.StorageInformation,
},
}
return nil
Expand Down
24 changes: 17 additions & 7 deletions storage/rpc.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package storage

import "encoding/xml"

type RpcReply struct {
XMLName xml.Name `xml:"rpc-reply"`
MultiRoutingEngineResults MultiRoutingEngineResults `xml:"multi-routing-engine-results"`
}

type MultiRoutingEngineResults struct {
Results []MultiRoutingEngineItem `xml:"multi-routing-engine-results"`
RoutingEngine []RoutingEngine `xml:"multi-routing-engine-item"`
}

type MultiRoutingEngineItem struct {
Name string `xml:"re-name"`
Storage StorageInformation `xml:"multi-routing-engine-item"`
type RoutingEngine struct {
Name string `xml:"re-name"`
StorageInformation StorageInformation `xml:"system-storage-information"`
}

type StorageInformation struct {
Information struct {
Filesystems []Filesystem `xml:"filesystem"`
} `xml:"system-storage-information"`
Filesystems []Filesystem `xml:"filesystem"`
}

type Filesystem struct {
Expand All @@ -23,3 +28,8 @@ type Filesystem struct {
UsedPercent string `xml:"used-percent"`
MountedOn string `xml:"mounted-on"`
}

type RpcReplyNoRE struct {
XMLName xml.Name `xml:"rpc-reply"`
StorageInformation StorageInformation `xml:"system-storage-information"`
}
134 changes: 94 additions & 40 deletions storage/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,8 @@ import (
"github.com/stretchr/testify/assert"
)

func TestParse(t *testing.T) {
tests := []struct {
name string
resp string
}{
{
name: "no nulti routing engine",
resp: `<rpc-reply xmlns:junos="http://xml.juniper.net/junos/18.2R1/junos">
func TestParseMultiREOutput(t *testing.T) {
body := `<rpc-reply xmlns:junos="http://xml.juniper.net/junos/17.2R1/junos">
<multi-routing-engine-results>
<multi-routing-engine-item>
<re-name>fpc0</re-name>
Expand All @@ -26,47 +20,107 @@ func TestParse(t *testing.T) {
<used-percent> 65</used-percent>
<mounted-on>/.mount</mounted-on>
</filesystem>
<filesystem>
<filesystem-name>/dev/sda</filesystem-name>
<total-blocks junos:format="1.3G">2796512</total-blocks>
<used-blocks junos:format="814M">1667792</used-blocks>
<available-blocks junos:format="442M">905000</available-blocks>
<used-percent> 6r75</used-percent>
<mounted-on>/</mounted-on>
</filesystem>
</system-storage-information>
</multi-routing-engine-item>
<multi-routing-engine-item>
<re-name>fpc1</re-name>
<system-storage-information junos:style="brief">
<filesystem>
<filesystem-name>/dev/gpt/junos1</filesystem-name>
<total-blocks junos:format="1.1G">2796512</total-blocks>
<used-blocks junos:format="810M">1667792</used-blocks>
<available-blocks junos:format="440M">905000</available-blocks>
<used-percent> 65</used-percent>
<mounted-on>/.mount</mounted-on>
</filesystem>
</system-storage-information>
</multi-routing-engine-item>
</multi-routing-engine-results>
<cli>
<banner>{master:0}</banner>
</cli>
</rpc-reply>`,
},
{
name: "multi routing engine",
resp: `<rpc-reply xmlns:junos="http://xml.juniper.net/junos/18.2R1/junos">
<system-storage-information junos:style="brief">
<filesystem>
<filesystem-name>/dev/gpt/junos</filesystem-name>
<total-blocks junos:format="1.3G">2796512</total-blocks>
<used-blocks junos:format="814M">1667792</used-blocks>
<available-blocks junos:format="442M">905000</available-blocks>
<used-percent> 65</used-percent>
<mounted-on>/.mount</mounted-on>
</filesystem>#
</system-storage-information>
<cli>
<banner>{master:0}</banner>
</cli>
</rpc-reply>`,
},
</rpc-reply>`

rpc := RpcReply{}
err := parseXML([]byte(body), &rpc)

if err != nil {
t.Fatal(err)
}

t.Parallel()
assert.NotEmpty(t, rpc.MultiRoutingEngineResults.RoutingEngine[0].StorageInformation)

// test first routing engine
assert.Equal(t, "fpc0", rpc.MultiRoutingEngineResults.RoutingEngine[0].Name, "re-name")

for _, test := range tests {
t.Run(test.name, func(te *testing.T) {
rpc := MultiRoutingEngineResults{}
err := parseXML([]byte(test.resp), &rpc)
if err != nil {
te.Fatal(err)
}
f := rpc.MultiRoutingEngineResults.RoutingEngine[0].StorageInformation.Filesystems[1]

if assert.Equal(te, len(rpc.Results), 1, "Engines") {
assert.Equal(te, len(rpc.Results[0].Storage.Information.Filesystems), 1, "Filesystems")
}
})
assert.Equal(t, "/dev/sda", f.FilesystemName, "filesystem-name")
assert.Equal(t, int64(2796512), f.TotalBlocks, "total-blocks")
assert.Equal(t, int64(1667792), f.UsedBlocks, "used-blocks")
assert.Equal(t, "/", f.MountedOn, "mounted-on")

// test second routing engine
assert.Equal(t, "fpc1", rpc.MultiRoutingEngineResults.RoutingEngine[1].Name, "re-name")

f = rpc.MultiRoutingEngineResults.RoutingEngine[1].StorageInformation.Filesystems[0]

assert.Equal(t, "/dev/gpt/junos1", f.FilesystemName, "filesystem-name")
assert.Equal(t, int64(2796512), f.TotalBlocks, "total-blocks")
assert.Equal(t, int64(1667792), f.UsedBlocks, "used-blocks")
assert.Equal(t, "/.mount", f.MountedOn, "mounted-on")
}

func TestParseNoMultiREOutput(t *testing.T) {
body := `<rpc-reply xmlns:junos="http://xml.juniper.net/junos/18.2R1/junos">
<system-storage-information junos:style="brief">
<filesystem>
<filesystem-name>/dev/md0.uzip</filesystem-name>
<total-blocks junos:format="21M">43628</total-blocks>
<used-blocks junos:format="21M">43628</used-blocks>
<available-blocks junos:format="0B">0</available-blocks>
<used-percent>100</used-percent>
<mounted-on>/</mounted-on>
</filesystem>
<filesystem>
<filesystem-name>/var/log</filesystem-name>
<total-blocks junos:format="21G">44306520</total-blocks>
<used-blocks junos:format="11G">23882504</used-blocks>
<available-blocks junos:format="8.0G">16879496</available-blocks>
<used-percent> 59</used-percent>
<mounted-on>/.mount/packages/mnt/jweb-xxx/jail/var/log</mounted-on>
</filesystem>
</system-storage-information>
<cli>
<banner>{backup}</banner>
</cli>
</rpc-reply>`

rpc := RpcReply{}
err := parseXML([]byte(body), &rpc)

if err != nil {
t.Fatal(err)
}

assert.NotEmpty(t, rpc.MultiRoutingEngineResults.RoutingEngine[0].StorageInformation)

assert.Equal(t, "N/A", rpc.MultiRoutingEngineResults.RoutingEngine[0].Name, "re-name")

f := rpc.MultiRoutingEngineResults.RoutingEngine[0].StorageInformation.Filesystems[1]

assert.Equal(t, "/var/log", f.FilesystemName, "filesystem-name")
assert.Equal(t, int64(44306520), f.TotalBlocks, "total-blocks")
assert.Equal(t, int64(23882504), f.UsedBlocks, "used-blocks")
assert.Equal(t, " 59", f.UsedPercent, "used-percent")
assert.Equal(t, "/.mount/packages/mnt/jweb-xxx/jail/var/log", f.MountedOn, "mounted-on")
}

0 comments on commit 5ed6550

Please sign in to comment.