Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into rg2-change-log
Browse files Browse the repository at this point in the history
  • Loading branch information
rahulguptajss committed Aug 8, 2023
2 parents 40424fa + aff01d0 commit 86d7411
Show file tree
Hide file tree
Showing 82 changed files with 4,436 additions and 3,352 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Build, Test, Lint License

env:
GO_VERSION: "1.20.6"
GO_VERSION: "1.20.7"

on:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
steps:
- uses: actions/setup-go@v4
with:
go-version: '1.20.6'
go-version: '1.20.7'
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
Expand Down
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,10 @@ ifeq ($(origin ci),undefined)
@echo make ci=/path/to/harvest.yml ci-local
@exit 1
endif
-@docker stop $$(docker ps -aq) && docker rm $$(docker ps -aq)
-@docker volume rm harvest_grafana_data harvest_prometheus_data
@cp $(ci) harvest.yml
-@docker stop $$(docker ps -aq) 2>/dev/null || true
-@docker rm $$(docker ps -aq) 2>/dev/null || true
-@docker volume rm harvest_grafana_data harvest_prometheus_data 2>/dev/null || true
@if [ "$(ci)" != "harvest.yml" ]; then cp $(ci) harvest.yml; else echo "Source and destination files are the same, skipping copy"; fi
@./bin/harvest generate docker full --port --output harvest-compose.yml
@docker build -f container/onePollerPerContainer/Dockerfile -t ghcr.io/netapp/harvest:latest . --no-cache --build-arg VERSION=${VERSION}
@docker-compose -f prom-stack.yml -f harvest-compose.yml up -d --remove-orphans
Expand Down
2 changes: 1 addition & 1 deletion cmd/collectors/rest/plugins/sensor/sensor.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin {
return &Sensor{AbstractPlugin: p}
}

var ambientRegex = regexp.MustCompile(`^(Ambient Temp|Ambient Temp \d|PSU\d AmbTemp|PSU\d Inlet|PSU\d Inlet Temp|In Flow Temp|Front Temp|System Inlet|Bat Ambient \d|Riser Inlet Temp)$`)
var ambientRegex = regexp.MustCompile(`^(Ambient Temp|Ambient Temp \d|PSU\d AmbTemp|PSU\d Inlet|PSU\d Inlet Temp|In Flow Temp|Front Temp|Bat_Ambient \d|Riser Inlet Temp)$`)
var powerInRegex = regexp.MustCompile(`^PSU\d (InPwr Monitor|InPower|PIN|Power In)$`)
var voltageRegex = regexp.MustCompile(`^PSU\d (\d+V|InVoltage|VIN|AC In Volt)$`)
var currentRegex = regexp.MustCompile(`^PSU\d (\d+V Curr|Curr|InCurrent|Curr IIN|AC In Curr)$`)
Expand Down
88 changes: 87 additions & 1 deletion cmd/collectors/rest/plugins/volume/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ import (
"github.com/netapp/harvest/v2/pkg/conf"
"github.com/netapp/harvest/v2/pkg/errs"
"github.com/netapp/harvest/v2/pkg/matrix"
"github.com/netapp/harvest/v2/pkg/tree/node"
"github.com/tidwall/gjson"
"strconv"
"strings"
"time"
)

const HoursInMonth = 24 * 30

type Volume struct {
*plugin.AbstractPlugin
currentVal int
client *rest.Client
aggrsMap map[string]string // aggregate-uuid -> aggregate-name map
arw *matrix.Matrix
}

func New(p *plugin.AbstractPlugin) plugin.Plugin {
Expand Down Expand Up @@ -55,6 +59,16 @@ func (my *Volume) Init() error {
return err
}

my.arw = matrix.New(my.Parent+".Volume", "volume_arw", "volume_arw")
exportOptions := node.NewS("export_options")
instanceKeys := exportOptions.NewChildS("instance_keys", "")
instanceKeys.NewChildS("", "ArwStatus")
my.arw.SetExportOptions(exportOptions)
_, err = my.arw.NewMetricFloat64("status", "status")
if err != nil {
my.Logger.Error().Stack().Err(err).Msg("add metric")
return err
}
return nil
}

Expand All @@ -79,8 +93,11 @@ func (my *Volume) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, erro
// update volume instance labels
my.updateVolumeLabels(data)

// parse anti_ransomware_start_time, antiRansomwareState for all volumes and export at cluster level
my.handleARWProtection(data)

my.currentVal++
return nil, nil
return []*matrix.Matrix{my.arw}, nil
}

func (my *Volume) updateVolumeLabels(data *matrix.Matrix) {
Expand All @@ -96,6 +113,75 @@ func (my *Volume) updateVolumeLabels(data *matrix.Matrix) {
}
}

func (my *Volume) handleARWProtection(data *matrix.Matrix) {
var (
arwInstance *matrix.Instance
arwStartTimeValue time.Time
err error
)

// Purge and reset data
my.arw.PurgeInstances()
my.arw.Reset()

// Set all global labels
my.arw.SetGlobalLabels(data.GetGlobalLabels())
arwStatusValue := "Active Mode"
// Case where cluster don't have any volumes, arwStatus show as 'Not Monitoring'
if len(data.GetInstances()) == 0 {
arwStatusValue = "Not Monitoring"
}

// This is how cluster level arwStatusValue has been calculated based on each volume
// If any one volume arwStatus is disabled --> "Not Monitoring"
// If any one volume has been completed learning mode --> "Switch to Active Mode"
// If all volumes are in learning mode --> "Learning Mode"
// Else indicates arwStatus for all volumes are enabled --> "Active Mode"
for _, volume := range data.GetInstances() {
if arwState := volume.GetLabel("antiRansomwareState"); arwState == "" {
// Case where REST call don't return `antiRansomwareState` field, arwStatus show as 'Not Monitoring'
arwStatusValue = "Not Monitoring"
break
} else {
if arwState == "disabled" {
arwStatusValue = "Not Monitoring"
break
} else if arwState == "dry_run" || arwState == "enable_paused" {
arwStartTime := volume.GetLabel("anti_ransomware_start_time")
if arwStartTime == "" || arwStatusValue == "Switch to Active Mode" {
continue
}
// If ARW startTime is more than 30 days old, which indicates that learning mode has been finished.
if arwStartTimeValue, err = time.Parse(time.RFC3339, arwStartTime); err != nil {
my.Logger.Error().Err(err).Msg("Failed to parse arw start time")
arwStartTimeValue = time.Now()
}
if time.Since(arwStartTimeValue).Hours() > HoursInMonth {
arwStatusValue = "Switch to Active Mode"
} else {
arwStatusValue = "Learning Mode"
}
}
}
}

arwInstanceKey := data.GetGlobalLabels().Get("cluster") + data.GetGlobalLabels().Get("datacenter")
if arwInstance, err = my.arw.NewInstance(arwInstanceKey); err != nil {
my.Logger.Error().Err(err).Str("arwInstanceKey", arwInstanceKey).Msg("Failed to create arw instance")
return
}

arwInstance.SetLabel("ArwStatus", arwStatusValue)
m := my.arw.GetMetric("status")
// populate numeric data
value := 1.0
if err = m.SetValueFloat64(arwInstance, value); err != nil {
my.Logger.Error().Stack().Err(err).Float64("value", value).Msg("Failed to parse value")
} else {
my.Logger.Debug().Float64("value", value).Msg("added value")
}
}

func (my *Volume) getEncryptedDisks() ([]gjson.Result, error) {
var (
result []gjson.Result
Expand Down
25 changes: 25 additions & 0 deletions cmd/collectors/zapi/plugins/aggregate/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package aggregate

import (
"errors"
goversion "github.com/hashicorp/go-version"
"github.com/netapp/harvest/v2/cmd/collectors"
"github.com/netapp/harvest/v2/cmd/poller/plugin"
"github.com/netapp/harvest/v2/pkg/api/ontapi/zapi"
"github.com/netapp/harvest/v2/pkg/conf"
"github.com/netapp/harvest/v2/pkg/errs"
"github.com/netapp/harvest/v2/pkg/matrix"
"github.com/netapp/harvest/v2/pkg/tree/node"
"strconv"
"strings"
)

Expand Down Expand Up @@ -73,6 +75,29 @@ func (a *Aggregate) getCloudStores() error {
err error
)

// aggr-object-store-get-iter Zapi was introduced in 9.2.
version := a.client.Version()
clusterVersion := strconv.Itoa(version[0]) + "." + strconv.Itoa(version[1]) + "." + strconv.Itoa(version[2])
ontapVersion, err := goversion.NewVersion(clusterVersion)
if err != nil {
a.Logger.Error().Err(err).
Str("version", clusterVersion).
Msg("Failed to parse version")
return err
}
version92 := "9.2"
version92After, err := goversion.NewVersion(version92)
if err != nil {
a.Logger.Error().Err(err).
Str("version", version92).
Msg("Failed to parse version")
return err
}

if ontapVersion.LessThan(version92After) {
return nil
}

a.aggrCloudStoresMap = make(map[string][]string)
request := node.NewXMLS("aggr-object-store-get-iter")
request.NewChildS("max-records", collectors.DefaultBatchSize)
Expand Down
2 changes: 1 addition & 1 deletion cmd/collectors/zapi/plugins/sensor/sensor.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func New(p *plugin.AbstractPlugin) plugin.Plugin {
return &Sensor{AbstractPlugin: p}
}

var ambientRegex = regexp.MustCompile(`^(Ambient Temp|Ambient Temp \d|PSU\d AmbTemp|PSU\d Inlet|PSU\d Inlet Temp|In Flow Temp|Front Temp|System Inlet|Bat Ambient \d|Riser Inlet Temp)$`)
var ambientRegex = regexp.MustCompile(`^(Ambient Temp|Ambient Temp \d|PSU\d AmbTemp|PSU\d Inlet|PSU\d Inlet Temp|In Flow Temp|Front Temp|Bat_Ambient \d|Riser Inlet Temp)$`)
var powerInRegex = regexp.MustCompile(`^PSU\d (InPwr Monitor|InPower|PIN|Power In)$`)
var voltageRegex = regexp.MustCompile(`^PSU\d (\d+V|InVoltage|VIN|AC In Volt)$`)
var currentRegex = regexp.MustCompile(`^PSU\d (\d+V Curr|Curr|InCurrent|Curr IIN|AC In Curr)$`)
Expand Down
43 changes: 22 additions & 21 deletions cmd/collectors/zapi/plugins/sensor/sensor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,28 +89,29 @@ func init() {
// Verified temperature sensor values by parsing, pivoting, etc. externally via dasel, jq, miller

// average_ambient_temperature is
// cat cmd/collectors/zapi/plugins/sensor/testdata/sensor.xml | dasel -r xml -w json | jq -r '.root."attributes-list"."environment-sensors-info"[] | select(."sensor-type" | test("thermal")) | {node: (."node-name"), name: (."sensor-name"), value: (."threshold-sensor-value")} | [.node, .name, .value] | @csv' | rg "Ambient Temp|Ambient Temp \d|PSU\d AmbTemp|PSU\d Inlet|PSU\d Inlet Temp|In Flow Temp|Front Temp|System Inlet|Bat Ambient \d|Riser Inlet Temp" | rg -v "Fake" | mlr --csv --implicit-csv-header label node,name,value then stats1 -a min,mean,max -f value -g node | mlr --csv --opprint --barred cat

// +------------+-----------+--------------------+-----------+
// | node | value_min | value_mean | value_max |
// +------------+-----------+--------------------+-----------+
// | cdot-k3-05 | 21 | 21.666666666666668 | 23 |
// | cdot-k3-06 | 21 | 22 | 24 |
// | cdot-k3-07 | 21 | 21.666666666666668 | 23 |
// | cdot-k3-08 | 21 | 22.333333333333332 | 24 |
// +------------+-----------+--------------------+-----------+
// cat cmd/collectors/zapi/plugins/sensor/testdata/sensor.xml | dasel -r xml -w json | jq -r '.root."attributes-list"."environment-sensors-info"[] | select(."sensor-type" | test("thermal")) | {node: (."node-name"), name: (."sensor-name"), value: (."threshold-sensor-value")} | [.node, .name, .value] | @csv' | rg "Ambient Temp|Ambient Temp \d|PSU\d AmbTemp|PSU\d Inlet|PSU\d Inlet Temp|In Flow Temp|Front Temp|Bat Ambient \d|Riser Inlet Temp" | rg -v "Fake" | mlr --csv --implicit-csv-header label node,name,value then stats1 -a min,mean,max -f value -g node | mlr --csv --opprint --barred cat

//+------------+-----------+------------+-----------+
//| node | value_min | value_mean | value_max |
//+------------+-----------+------------+-----------+
//| cdot-k3-05 | 21 | 22 | 23 |
//| cdot-k3-06 | 21 | 22.5 | 24 |
//| cdot-k3-07 | 21 | 22 | 23 |
//| cdot-k3-08 | 21 | 22.5 | 24 |
//+------------+-----------+------------+-----------+

//
// average_temperature [min, avg, max] is calculated like so
// cat cmd/collectors/zapi/plugins/sensor/testdata/sensor.xml | dasel -r xml -w json | jq -r '.root."attributes-list"."environment-sensors-info"[] | select(."sensor-type" | test("thermal")) | {node: (."node-name"), name: (."sensor-name"), value: (."threshold-sensor-value")} | [.node, .name, .value] | @csv' | rg -v "Ambient Temp|Ambient Temp \d|PSU\d AmbTemp|PSU\d Inlet|PSU\d Inlet Temp|In Flow Temp|Front Temp|System Inlet|Bat Ambient \d|Riser Inlet Temp" | rg -v "Fake" | mlr --csv --implicit-csv-header label node,name,value then stats1 -a min,mean,max -f value -g node | mlr --csv --opprint --barred cat
// cat cmd/collectors/zapi/plugins/sensor/testdata/sensor.xml | dasel -r xml -w json | jq -r '.root."attributes-list"."environment-sensors-info"[] | select(."sensor-type" | test("thermal")) | {node: (."node-name"), name: (."sensor-name"), value: (."threshold-sensor-value")} | [.node, .name, .value] | @csv' | rg -v "Ambient Temp|Ambient Temp \d|PSU\d AmbTemp|PSU\d Inlet|PSU\d Inlet Temp|In Flow Temp|Front Temp|Bat Ambient \d|Riser Inlet Temp" | rg -v "Fake" | mlr --csv --implicit-csv-header label node,name,value then stats1 -a min,mean,max -f value -g node | mlr --csv --opprint --barred cat

// +------------+-----------+------------+-----------+
// | node | value_min | value_mean | value_max |
// +------------+-----------+------------+-----------+
// | cdot-k3-05 | 19 | 27.1875 | 36 |
// | cdot-k3-06 | 19 | 26.6875 | 35 |
// | cdot-k3-07 | 19 | 26.6875 | 35 |
// | cdot-k3-08 | 20 | 27.5 | 36 |
// +------------+-----------+------------+-----------+
//+------------+-----------+--------------------+-----------+
//| node | value_min | value_mean | value_max |
//+------------+-----------+--------------------+-----------+
//| cdot-k3-05 | 19 | 26.823529411764707 | 36 |
//| cdot-k3-06 | 19 | 26.352941176470587 | 35 |
//| cdot-k3-07 | 19 | 26.352941176470587 | 35 |
//| cdot-k3-08 | 20 | 27.176470588235293 | 36 |
//+------------+-----------+--------------------+-----------+

func TestSensor_Run(t *testing.T) {

Expand All @@ -120,12 +121,12 @@ func TestSensor_Run(t *testing.T) {
omat, _ := sensor.Run(dataMap)

expected := map[string]map[string]float64{
"average_ambient_temperature": {"cdot-k3-05": 21.666666666666668, "cdot-k3-06": 22, "cdot-k3-07": 21.666666666666668, "cdot-k3-08": 22.333333333333332},
"average_ambient_temperature": {"cdot-k3-05": 22, "cdot-k3-06": 22.5, "cdot-k3-07": 22, "cdot-k3-08": 22.5},
"average_fan_speed": {"cdot-k3-05": 7030, "cdot-k3-06": 7050, "cdot-k3-07": 7040, "cdot-k3-08": 7050},
"max_fan_speed": {"cdot-k3-05": 7700, "cdot-k3-06": 7700, "cdot-k3-07": 7700, "cdot-k3-08": 7700},
"min_fan_speed": {"cdot-k3-05": 4600, "cdot-k3-06": 4500, "cdot-k3-07": 4600, "cdot-k3-08": 4500},
"power": {"cdot-k3-05": 383.4, "cdot-k3-06": 347.9, "cdot-k3-07": 340.8, "cdot-k3-08": 362.1},
"average_temperature": {"cdot-k3-05": 27.1875, "cdot-k3-06": 26.6875, "cdot-k3-07": 26.6875, "cdot-k3-08": 27.5},
"average_temperature": {"cdot-k3-05": 26.823529411764707, "cdot-k3-06": 26.352941176470587, "cdot-k3-07": 26.352941176470587, "cdot-k3-08": 27.176470588235293},
"max_temperature": {"cdot-k3-05": 36, "cdot-k3-06": 35, "cdot-k3-07": 35, "cdot-k3-08": 36},
"min_ambient_temperature": {"cdot-k3-05": 21, "cdot-k3-06": 21, "cdot-k3-07": 21, "cdot-k3-08": 21},
"min_temperature": {"cdot-k3-05": 19, "cdot-k3-06": 19, "cdot-k3-07": 19, "cdot-k3-08": 20},
Expand Down
Loading

0 comments on commit 86d7411

Please sign in to comment.