Skip to content

Commit

Permalink
feat: ARW related fields and autoupdate+notification details
Browse files Browse the repository at this point in the history
  • Loading branch information
Hardikl committed Jul 21, 2023
1 parent 9afc781 commit 34e6854
Show file tree
Hide file tree
Showing 6 changed files with 293 additions and 37 deletions.
99 changes: 98 additions & 1 deletion cmd/collectors/rest/plugins/volume/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
package volume

import (
"fmt"
"github.com/netapp/harvest/v2/cmd/collectors"
"github.com/netapp/harvest/v2/cmd/poller/plugin"
"github.com/netapp/harvest/v2/cmd/tools/rest"
"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"
"regexp"
"strconv"
"strings"
"time"
Expand All @@ -22,6 +25,7 @@ type Volume struct {
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,67 @@ func (my *Volume) updateVolumeLabels(data *matrix.Matrix) {
}
}

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

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

// Set all global labels
my.arw.SetGlobalLabels(data.GetGlobalLabels())

learningModeCount := 0
learningCompleted := 0
disabledCount := 0

for _, volume := range data.GetInstances() {
if arwState := volume.GetLabel("antiRansomwareState"); arwState != "" {
if arwState == "dry_run" || arwState == "enable_paused" {
if arwStartTime := volume.GetLabel("anti_ransomware_start_time"); arwStartTime != "" {
// If ARW startTime is more than 30 days old, which indicates that learning mode has been finished.
if (float64(time.Now().Unix()) - HandleTimestamp(arwStartTime)) > 2629743 {
learningCompleted++
}
}
learningModeCount++
} else if arwState == "disabled" {
disabledCount++
}
}
}

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

if disabledCount > 0 {
arwInstance.SetLabel("ArwStatus", "Not Monitoring")
} else if learningModeCount > 0 {
if learningCompleted > 0 {
arwInstance.SetLabel("ArwStatus", "Switch to Active Mode")
} else {
arwInstance.SetLabel("ArwStatus", "Learning Mode")
}
} else {
arwInstance.SetLabel("ArwStatus", "Active Mode")
}

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 Expand Up @@ -126,3 +204,22 @@ func (my *Volume) updateAggrMap(disks []gjson.Result) {
}
}
}

// Example: timestamp: 2020-12-02T18:36:19-08:00
var regexTimeStamp = regexp.MustCompile(
`[+-]?\d{4}(-[01]\d(-[0-3]\d(T[0-2]\d:[0-5]\d:?([0-5]\d(\.\d+)?)?[+-][0-2]\d:[0-5]\d?)?)?)?`)

func HandleTimestamp(value string) float64 {
var timestamp time.Time
var err error

if match := regexTimeStamp.MatchString(value); match {
// example: 2020-12-02T18:36:19-08:00 ==> 1606962979
if timestamp, err = time.Parse(time.RFC3339, value); err != nil {
fmt.Printf("%v", err)
return 0
}
return float64(timestamp.Unix())
}
return 0
}
24 changes: 24 additions & 0 deletions conf/rest/9.12.0/ems_destination.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

name: EmsDestination
query: api/support/ems/destinations
object: ems_destination

counters:
- ^^destination => destination
- ^^name => name
- ^^type => type
- ^certificate => certificate
- ^filter => filter
- ^syslog => syslog
- ^system_defined => system_defined
- filter:
- system_defined=false

export_options:
instance_keys:
- destination
- name
- type
instance_labels:
- filter
- syslog
15 changes: 15 additions & 0 deletions conf/rest/9.12.0/support_auto_update.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

name: SupportAutoUpdate
query: api/support/auto-update
object: support_auto_update

counters:
- ^enabled => auto_update_enabled

#export_options:
# include_all_labels: true
export_options:
instance_keys:
- auto_update_enabled
instance_labels:
- auto_update_enabled
2 changes: 1 addition & 1 deletion conf/rest/9.12.0/volume.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ counters:
- ^^svm.name => svm
- ^aggregates.#.name => aggr
- ^aggregates.#.uuid => aggrUuid # handled in plugin for flexgroup
- ^anti_ransomware.dry_run_start_time => anti_ransomware_start_time
- ^anti_ransomware.state => antiRansomwareState
- ^encryption.enabled => isEncrypted
- ^is_svm_root => svm_root
Expand All @@ -18,7 +19,6 @@ counters:
- ^state => state
- ^style => style
- ^type => type
- anti_ransomware.dry_run_start_time(timestamp) => anti_ransomware_start_time
- autosize.grow_threshold => autosize_grow_threshold_percent
- autosize.maximum => autosize_maximum_size
- snapshot_count
Expand Down
2 changes: 2 additions & 0 deletions conf/rest/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ objects:
CloudTarget: cloud_target.yaml
ClusterPeer: clusterpeer.yaml
Disk: disk.yaml
EmsDestination: ems_destination.yaml
# ExportRule: exports.yaml
LIF: lif.yaml
Health: health.yaml
Expand Down Expand Up @@ -42,6 +43,7 @@ objects:
Status: status.yaml
Subsystem: subsystem.yaml
Support: support.yaml
SupportAutoUpdate: support_auto_update.yaml
SVM: svm.yaml
Volume: volume.yaml
VolumeAnalytics: volume_analytics.yaml
Loading

0 comments on commit 34e6854

Please sign in to comment.