Skip to content

Commit 3ed928e

Browse files
committed
Made MTTR example be flexible with the field to group by as parameter
1 parent fc2a9bd commit 3ed928e

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

client/incident.go

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ type Attachment struct {
2222
Description string `json:"description"`
2323
}
2424

25+
// CustomFields ...
26+
type CustomFields map[string]interface{}
27+
2528
// Incident details.
2629
// An incident can be opened by us algorithmically or arrive from an external source like SIEM.
2730
// If you add fields, make sure to add them to the mapping as well
@@ -74,6 +77,8 @@ type Incident struct {
7477
DueDate time.Time `json:"dueDate,omitempty"`
7578
// Should we automagically create the investigation
7679
CreateInvestigation bool `json:"createInvestigation"`
80+
// This field must have empty json key
81+
CustomFields `json:""`
7782
}
7883

7984
type idVersion struct {

mttr/mttr.go

+39-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"flag"
66
"fmt"
77
"os"
8+
"reflect"
89
"strconv"
10+
"strings"
911
"time"
1012

1113
"github.com/demisto/tools/client"
@@ -16,6 +18,7 @@ var (
1618
password = flag.String("p", "", "Password to login to the server")
1719
server = flag.String("s", "", "Demisto server URL")
1820
filter = flag.String("f", "status:=2 and closed:>"+defaultStartDate(), "Filter for the mttr query")
21+
group = flag.String("g", "owner", "Which field to group by")
1922
output = flag.String("o", "mttr.csv", "Output csv file path")
2023
)
2124

@@ -79,22 +82,50 @@ func main() {
7982
continue
8083
}
8184
delta := incidents.Data[i].Closed.Sub(incidents.Data[i].Created)
82-
owner := incidents.Data[i].OwnerID
83-
if owner == "" {
84-
owner = "dbot"
85+
field := incidents.Data[i].OwnerID
86+
if *group == "owner" {
87+
if field == "" {
88+
field = "dbot"
89+
}
90+
} else {
91+
found := false
92+
val := reflect.ValueOf(incidents.Data[i])
93+
typ := val.Type()
94+
for i := 0; i < typ.NumField(); i++ {
95+
tag := typ.Field(i).Tag
96+
jsonTag := tag.Get("json")
97+
if jsonTag == *group || strings.Title(*group) == typ.Field(i).Name {
98+
field = val.FieldByName(typ.Field(i).Name).String()
99+
found = true
100+
break
101+
}
102+
}
103+
if !found {
104+
for k, v := range incidents.Data[i].CustomFields {
105+
if k == *group {
106+
field = fmt.Sprintf("%v", v)
107+
found = true
108+
break
109+
}
110+
}
111+
}
112+
// If not found then it will default to owner
113+
if !found {
114+
field = ""
115+
}
85116
}
86-
if _, ok := mttr[owner]; ok {
87-
mttr[owner]["incidents"] = mttr[owner]["incidents"] + 1
88-
mttr[owner]["total"] = mttr[owner]["total"] + int64(delta)
117+
if _, ok := mttr[field]; ok {
118+
mttr[field]["incidents"] = mttr[field]["incidents"] + 1
119+
mttr[field]["total"] = mttr[field]["total"] + int64(delta)
89120
} else {
90-
mttr[owner] = map[string]int64{"incidents": 1, "total": int64(delta)}
121+
mttr[field] = map[string]int64{"incidents": 1, "total": int64(delta)}
91122
}
92123
}
93124
f, err := os.Create(*output)
94125
check(err)
95126
defer f.Close()
96127
w := csv.NewWriter(f)
97-
w.Write([]string{"Analyst", "Incidents", "MTTR"})
128+
w.Write([]string{strings.Title(*group), "Incidents", "MTTR"})
98129
for k, v := range mttr {
99130
w.Write([]string{k, strconv.FormatInt(v["incidents"], 10), strconv.FormatInt(int64(time.Duration(v["total"]/v["incidents"]).Minutes()), 10)})
100131
}

0 commit comments

Comments
 (0)