Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding the bucket and policy rest template #3374

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
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
}
45 changes: 45 additions & 0 deletions cmd/collectors/rest/plugins/snapshotpolicy/snapshotpolicy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright NetApp Inc, 2024 All rights reserved
*/

package snapshotpolicy

import (
"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 SnapshotPolicy struct {
*plugin.AbstractPlugin
}

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

func (m *SnapshotPolicy) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, *util.Metadata, error) {
// Purge and reset data
data := dataMap[m.Object]

for _, instance := range data.GetInstances() {
copies := instance.GetLabel("copies")
copiesJSON := gjson.Result{Type: gjson.JSON, Raw: "[" + copies + "]"}
var scheduleVal string
var copiesValue int
for _, copiesData := range copiesJSON.Array() {
count := copiesData.Get("count").String()
countVal, _ := strconv.Atoi(count)
schedule := copiesData.Get("schedule.name").ClonedString()
scheduleVal = scheduleVal + schedule + ":" + count + ","
copiesValue += countVal
}
instance.SetLabel("schedules", strings.TrimSuffix(scheduleVal, ","))
instance.SetLabel("copies", strconv.Itoa(copiesValue))
}

return nil, nil, nil
}
10 changes: 8 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 All @@ -19,6 +20,7 @@ import (
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/securityaccount"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/shelf"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/snapmirror"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/snapshotpolicy"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/svm"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/systemnode"
"github.com/netapp/harvest/v2/cmd/collectors/rest/plugins/volume"
Expand Down Expand Up @@ -474,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 All @@ -498,6 +502,8 @@ func (r *Rest) LoadPlugin(kind string, abc *plugin.AbstractPlugin) plugin.Plugin
return collectors.NewSensor(abc)
case "Shelf":
return shelf.New(abc)
case "SnapshotPolicy":
return snapshotpolicy.New(abc)
case "SecurityAccount":
return securityaccount.New(abc)
case "QosPolicyFixed":
Expand Down Expand Up @@ -630,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
Loading
Loading