Skip to content

Commit

Permalink
feat: add policy tables in data protection dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
Hardikl committed Dec 17, 2024
1 parent 7e2ebf3 commit 89fedad
Show file tree
Hide file tree
Showing 8 changed files with 516 additions and 190 deletions.
82 changes: 82 additions & 0 deletions cmd/collectors/commonutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/netapp/harvest/v2/third_party/tidwall/gjson"
"log/slog"
"os"
"regexp"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -543,3 +544,84 @@ func PopulateIfgroupMetrics(portIfgroupMap map[string]string, portDataMap map[st
}
return nil
}

func HandleDuration(value string) float64 {
// Example: duration: PT8H35M42S
timeDurationRegex := `^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:.\d+)?)S)?$`

regexTimeDuration := regexp.MustCompile(timeDurationRegex)
if match := regexTimeDuration.MatchString(value); match {
// example: PT8H35M42S ==> 30942
matches := regexTimeDuration.FindStringSubmatch(value)
if matches == nil {
return 0
}

seconds := 0.0

// years
// months

// days
if matches[3] != "" {
f, err := strconv.ParseFloat(matches[3], 64)
if err != nil {
fmt.Printf("%v", err)
return 0
}
seconds += f * 24 * 60 * 60
}

// hours
if matches[4] != "" {
f, err := strconv.ParseFloat(matches[4], 64)
if err != nil {
fmt.Printf("%v", err)
return 0
}
seconds += f * 60 * 60
}

// minutes
if matches[5] != "" {
f, err := strconv.ParseFloat(matches[5], 64)
if err != nil {
fmt.Printf("%v", err)
return 0
}
seconds += f * 60
}

// seconds & milliseconds
if matches[6] != "" {
f, err := strconv.ParseFloat(matches[6], 64)
if err != nil {
fmt.Printf("%v", err)
return 0
}
seconds += f
}
return seconds
}

return 0
}

// 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
}
62 changes: 62 additions & 0 deletions cmd/collectors/commonutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,65 @@ func Test_SplitVscanName(t *testing.T) {
})
}
}

func Test_HandleDuration(t *testing.T) {

type test struct {
timeFieldValue string
want float64
}

var tests = []test{
{
timeFieldValue: "PT54S",
want: 54,
},
{
timeFieldValue: "PT48M",
want: 2880,
},
{
timeFieldValue: "P428DT22H45M19S",
want: 37061119,
},
{
timeFieldValue: "PT8H35M42S",
want: 30942,
},
}

for _, tt := range tests {
t.Run(tt.timeFieldValue, func(t *testing.T) {
if got := HandleDuration(tt.timeFieldValue); got != tt.want {
t.Errorf("actual value = %v, want %v", got, tt.want)
}
})
}
}

func Test_HandleTimestamp(t *testing.T) {

type test struct {
timeFieldValue string
want float64
}

var tests = []test{
{
timeFieldValue: "2020-12-02T18:36:19-08:00",
want: 1606962979,
},
{
timeFieldValue: "2022-01-31T04:05:02-05:00",
want: 1643619902,
},
}

for _, tt := range tests {
t.Run(tt.timeFieldValue, func(t *testing.T) {
if got := HandleTimestamp(tt.timeFieldValue); got != tt.want {
t.Errorf("actual value = %v, want %v", got, tt.want)
}
})
}
}
60 changes: 60 additions & 0 deletions cmd/collectors/rest/plugins/clusterschedule/clusterschedule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package clusterschedule

import (
"github.com/netapp/harvest/v2/cmd/collectors"
"github.com/netapp/harvest/v2/cmd/poller/plugin"
"github.com/netapp/harvest/v2/pkg/matrix"
"github.com/netapp/harvest/v2/pkg/util"
"github.com/netapp/harvest/v2/third_party/tidwall/gjson"
"strconv"
"strings"
)

type ClusterScheule struct {
*plugin.AbstractPlugin
}

func New(p *plugin.AbstractPlugin) plugin.Plugin {
return &ClusterScheule{AbstractPlugin: p}
}

func (c *ClusterScheule) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, *util.Metadata, error) {
for _, instance := range dataMap[c.Object].GetInstances() {
intervalVal := collectors.HandleDuration(instance.GetLabel("interval"))
instance.SetLabel("interval", strconv.FormatFloat(intervalVal, 'f', -1, 64))

cron := instance.GetLabel("cron")
updateDetailsJSON := gjson.Result{Type: gjson.JSON, Raw: cron}
var cronVal, minStr, hourStr, weekDayStr string
if minutes := updateDetailsJSON.Get("minutes"); minutes.Exists() {
for _, m := range minutes.Array() {
minStr = minStr + m.String() + ", "
}
minStr = strings.TrimSuffix(minStr, ", ")
}
if hours := updateDetailsJSON.Get("hours"); hours.Exists() {
for _, h := range hours.Array() {
hourStr = hourStr + h.String() + ", "
}
hourStr = strings.TrimSuffix(hourStr, ", ")
}
if weekdays := updateDetailsJSON.Get("weekdays"); weekdays.Exists() {
for _, w := range weekdays.Array() {
weekDayStr = weekDayStr + w.String() + ", "
}
weekDayStr = strings.TrimSuffix(weekDayStr, ", ")
}

if minStr != "" {
cronVal = cronVal + "minutes: " + "[" + minStr + "] "
}
if hourStr != "" {
cronVal = cronVal + "hours: " + "[" + hourStr + "] "
}
if weekDayStr != "" {
cronVal = cronVal + "weekdays: " + "[" + weekDayStr + "]"
}
instance.SetLabel("cron", cronVal)
}
return nil, nil, nil
}
7 changes: 5 additions & 2 deletions cmd/collectors/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/aggregate"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/certificate"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/cluster"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/clusterschedule"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/clustersoftware"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/disk"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/health"
Expand Down Expand Up @@ -475,6 +476,8 @@ func (r *Rest) LoadPlugin(kind string, abc *plugin.AbstractPlugin) plugin.Plugin
return aggregate.New(abc)
case "Cluster":
return cluster.New(abc)
case "ClusterSchedule":
return clusterschedule.New(abc)
case "ClusterSoftware":
return clustersoftware.New(abc)
case "Disk":
Expand Down Expand Up @@ -633,9 +636,9 @@ func (r *Rest) HandleResults(mat *matrix.Matrix, result []gjson.Result, prop *pr
var floatValue float64
switch metric.MetricType {
case "duration":
floatValue = HandleDuration(f.ClonedString())
floatValue = collectors.HandleDuration(f.ClonedString())
case "timestamp":
floatValue = HandleTimestamp(f.ClonedString())
floatValue = collectors.HandleTimestamp(f.ClonedString())
case "":
floatValue = f.Float()
default:
Expand Down
84 changes: 0 additions & 84 deletions cmd/collectors/rest/templating.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package rest

import (
"fmt"
"github.com/netapp/harvest/v2/cmd/collectors"
"github.com/netapp/harvest/v2/pkg/errs"
"github.com/netapp/harvest/v2/pkg/tree/node"
"github.com/netapp/harvest/v2/pkg/util"
"log/slog"
"maps"
"regexp"
"slices"
"strconv"
"strings"
"time"
)

func (r *Rest) LoadTemplate() (string, error) {
Expand Down Expand Up @@ -94,87 +91,6 @@ func (r *Rest) InitCache() error {
return nil
}

func HandleDuration(value string) float64 {
// Example: duration: PT8H35M42S
timeDurationRegex := `^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:.\d+)?)S)?$`

regexTimeDuration := regexp.MustCompile(timeDurationRegex)
if match := regexTimeDuration.MatchString(value); match {
// example: PT8H35M42S ==> 30942
matches := regexTimeDuration.FindStringSubmatch(value)
if matches == nil {
return 0
}

seconds := 0.0

// years
// months

// days
if matches[3] != "" {
f, err := strconv.ParseFloat(matches[3], 64)
if err != nil {
fmt.Printf("%v", err)
return 0
}
seconds += f * 24 * 60 * 60
}

// hours
if matches[4] != "" {
f, err := strconv.ParseFloat(matches[4], 64)
if err != nil {
fmt.Printf("%v", err)
return 0
}
seconds += f * 60 * 60
}

// minutes
if matches[5] != "" {
f, err := strconv.ParseFloat(matches[5], 64)
if err != nil {
fmt.Printf("%v", err)
return 0
}
seconds += f * 60
}

// seconds & milliseconds
if matches[6] != "" {
f, err := strconv.ParseFloat(matches[6], 64)
if err != nil {
fmt.Printf("%v", err)
return 0
}
seconds += f
}
return seconds
}

return 0
}

// 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
}

func (r *Rest) ParseRestCounters(counter *node.Node, prop *prop) {
var (
display, name, kind, metricType string
Expand Down
Loading

0 comments on commit 89fedad

Please sign in to comment.