- go version updated
[ric-plt/alarm-go.git] / cli / alarm-cli.go
1 package main
2
3 import (
4         "bytes"
5         "encoding/json"
6         "fmt"
7         "io/ioutil"
8         "net/http"
9         "os"
10         "strconv"
11         "sync"
12         "time"
13
14         "gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm"
15         clientruntime "github.com/go-openapi/runtime/client"
16         "github.com/go-openapi/strfmt"
17         "github.com/jedib0t/go-pretty/table"
18         "github.com/prometheus/alertmanager/api/v2/client"
19         "github.com/prometheus/alertmanager/api/v2/client/alert"
20         "github.com/prometheus/alertmanager/api/v2/models"
21         "github.com/thatisuday/commando"
22 )
23
24 type CliAlarmDefinitions struct {
25         AlarmDefinitions []*alarm.AlarmDefinition `json:"alarmdefinitions"`
26 }
27
28 type AlarmClient struct {
29         alarmer *alarm.RICAlarm
30 }
31
32 type RicPerfAlarmObjects struct {
33         AlarmObjects []*alarm.Alarm `json:"alarmobjects"`
34 }
35
36 type AlarmNotification struct {
37         alarm.AlarmMessage
38         alarm.AlarmDefinition
39 }
40
41 var CLIPerfAlarmObjects map[int]*alarm.Alarm
42
43 var wg sync.WaitGroup
44
45 var CliPerfAlarmDefinitions CliAlarmDefinitions
46
47 const (
48         Raise             string = "RAISE"
49         Clear             string = "CLEAR"
50         End               string = "END"
51         PeakTestDuration  int    = 60
52         OneSecondDuration int    = 1
53 )
54
55 func main() {
56         alarmManagerHost := "localhost"
57         if h := os.Getenv("ALARM_MANAGER_HOST"); h != "" {
58                 alarmManagerHost = h
59         }
60
61         alertManagerHost := "localhost"
62         if h := os.Getenv("ALERT_MANAGER_HOST"); h != "" {
63                 alertManagerHost = h
64         }
65
66         // configure commando
67         commando.
68                 SetExecutableName("alarm-cli").
69                 SetVersion("1.0.0").
70                 SetDescription("This CLI tool provides management interface to SEP alarm system")
71
72         registerActiveCmd(alarmManagerHost)
73         registerHistoryCmd(alarmManagerHost)
74         registerRaiseCmd(alarmManagerHost)
75         registerClearCmd(alarmManagerHost)
76         registerDefineCmd(alarmManagerHost)
77         registerUndefineCmd(alarmManagerHost)
78         registerConfigureCmd(alarmManagerHost)
79         registerPerfCmd(alarmManagerHost)
80         registerAlertCmd(alertManagerHost)
81
82         // parse command-line arguments
83         commando.Parse(nil)
84 }
85
86 func registerActiveCmd(alarmManagerHost string) {
87         commando.
88                 Register("active").
89                 SetShortDescription("Displays the SEP active alarms").
90                 SetDescription("This command displays more information about the SEP active alarms").
91                 AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost).
92                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
93                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
94                         displayAlarms(getAlarms(flags, "active"), false)
95                 })
96 }
97
98 func registerHistoryCmd(alarmManagerHost string) {
99         // Get alarm history
100         commando.
101                 Register("history").
102                 SetShortDescription("Displays the SEP alarm history").
103                 SetDescription("This command displays more information about the SEP alarm history").
104                 AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost).
105                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
106                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
107                         displayAlarms(getAlarms(flags, "history"), true)
108                 })
109 }
110
111 func registerRaiseCmd(alarmManagerHost string) {
112         // Raise an alarm
113         commando.
114                 Register("raise").
115                 SetShortDescription("Raises alarm with given parameters").
116                 AddFlag("moid", "Managed object Id", commando.String, nil).
117                 AddFlag("apid", "Application Id", commando.String, nil).
118                 AddFlag("sp", "Specific problem Id", commando.Int, nil).
119                 AddFlag("severity", "Perceived severity", commando.String, nil).
120                 AddFlag("iinfo", "Application identifying info", commando.String, nil).
121                 AddFlag("aai", "Application additional info", commando.String, "-").
122                 AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost).
123                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
124                 AddFlag("if", "http or rmr used as interface", commando.String, "http").
125                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
126                         postAlarm(flags, readAlarmParams(flags, false), alarm.AlarmActionRaise, nil)
127                 })
128
129 }
130
131 func registerClearCmd(alarmManagerHost string) {
132         // Clear an alarm
133         commando.
134                 Register("clear").
135                 SetShortDescription("Raises alarm with given parameters").
136                 AddFlag("moid", "Managed object Id", commando.String, nil).
137                 AddFlag("apid", "Application Id", commando.String, nil).
138                 AddFlag("sp", "Specific problem Id", commando.Int, nil).
139                 AddFlag("iinfo", "Application identifying info", commando.String, nil).
140                 AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost).
141                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
142                 AddFlag("if", "http or rmr used as interface", commando.String, "http").
143                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
144                         postAlarm(flags, readAlarmParams(flags, true), alarm.AlarmActionClear, nil)
145                 })
146
147 }
148
149 func registerConfigureCmd(alarmManagerHost string) {
150         // Configure an alarm manager
151         commando.
152                 Register("configure").
153                 SetShortDescription("Configure alarm manager with given parameters").
154                 AddFlag("mal", "max active alarms", commando.Int, nil).
155                 AddFlag("mah", "max alarm history", commando.Int, nil).
156                 AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost).
157                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
158                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
159                         postAlarmConfig(flags)
160                 })
161 }
162
163 func registerDefineCmd(alarmManagerHost string) {
164         // Create alarm definition
165         commando.
166                 Register("define").
167                 SetShortDescription("Define alarm with given parameters").
168                 AddFlag("aid", "alarm identifier", commando.Int, nil).
169                 AddFlag("atx", "alarm text", commando.String, nil).
170                 AddFlag("ety", "event type", commando.String, nil).
171                 AddFlag("oin", "operation instructions", commando.String, nil).
172                 AddFlag("rad", "Raise alarm delay", commando.Int, 0).
173                 AddFlag("cad", "Clear alarm delay", commando.Int, 0).
174                 AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost).
175                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
176                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
177                         postAlarmDefinition(flags)
178                 })
179 }
180
181 func registerUndefineCmd(alarmManagerHost string) {
182         // Delete alarm definition
183         commando.
184                 Register("undefine").
185                 SetShortDescription("Define alarm with given parameters").
186                 AddFlag("aid", "alarm identifier", commando.Int, nil).
187                 AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost).
188                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
189                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
190                         deleteAlarmDefinition(flags)
191                 })
192 }
193
194 func registerPerfCmd(alarmManagerHost string) {
195         // Conduct performance test for alarm-go
196         commando.
197                 Register("perf").
198                 SetShortDescription("Conduct performance test with given parameters").
199                 AddFlag("prf", "performance profile id", commando.Int, nil).
200                 AddFlag("nal", "number of alarms", commando.Int, nil).
201                 AddFlag("aps", "alarms per sec", commando.Int, nil).
202                 AddFlag("tim", "total time of test", commando.Int, nil).
203                 AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost).
204                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
205                 AddFlag("if", "http or rmr used as interface", commando.String, "http").
206                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
207                         conductperformancetest(flags)
208                 })
209 }
210
211 func registerAlertCmd(alertManagerHost string) {
212         // Get alerts from Prometheus Alert Manager
213         commando.
214                 Register("alerts").
215                 SetShortDescription("Get alerts from Prometheus Alert Manager").
216                 AddFlag("active", "Active alerts in Prometheus Alert Manager", commando.Bool, true).
217                 AddFlag("inhibited", "Inhibited alerts in Prometheus Alert Manager", commando.Bool, true).
218                 AddFlag("silenced", "Silenced alerts in Prometheus Alert Manager", commando.Bool, true).
219                 AddFlag("unprocessed", "Unprocessed alerts in Prometheus Alert Manager", commando.Bool, true).
220                 AddFlag("host", "Prometheus Alert Manager host address", commando.String, alertManagerHost).
221                 AddFlag("port", "Prometheus Alert Manager port", commando.String, "9093").
222                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
223                         displayAlerts(flags)
224                 })
225 }
226
227 func readAlarmParams(flags map[string]commando.FlagValue, clear bool) (a alarm.Alarm) {
228         a.ManagedObjectId, _ = flags["moid"].GetString()
229         a.ApplicationId, _ = flags["apid"].GetString()
230         a.SpecificProblem, _ = flags["sp"].GetInt()
231         a.IdentifyingInfo, _ = flags["iinfo"].GetString()
232
233         if !clear {
234                 s, _ := flags["severity"].GetString()
235                 a.PerceivedSeverity = alarm.Severity(s)
236         }
237
238         if !clear {
239                 a.AdditionalInfo, _ = flags["aai"].GetString()
240         }
241         return
242 }
243
244 func getAlarms(flags map[string]commando.FlagValue, action alarm.AlarmAction) (alarms []AlarmNotification) {
245         host, _ := flags["host"].GetString()
246         port, _ := flags["port"].GetString()
247         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/%s", host, port, action)
248         resp, err := http.Get(targetUrl)
249         if err != nil || resp == nil || resp.Body == nil {
250                 fmt.Println("Couldn't fetch active alarm list due to error: ", err)
251                 return alarms
252         }
253
254         defer resp.Body.Close()
255
256         body, err := ioutil.ReadAll(resp.Body)
257         if err != nil {
258                 fmt.Println("ioutil.ReadAll failed: ", err)
259                 return alarms
260         }
261
262         json.Unmarshal([]byte(body), &alarms)
263         return alarms
264 }
265
266 func postAlarmWithRmrIf(a alarm.Alarm, action alarm.AlarmAction, alarmClient *AlarmClient) {
267         if alarmClient == nil {
268                 alarmClient = NewAlarmClient("my-pod", "my-app")
269         }
270         if alarmClient == nil {
271                 return
272         }
273
274         // Wait until RMR is up-and-running
275         for !alarmClient.alarmer.IsRMRReady() {
276                 time.Sleep(100 * time.Millisecond)
277         }
278
279         if action == alarm.AlarmActionRaise {
280                 alarmClient.alarmer.Raise(a)
281         }
282
283         if action == alarm.AlarmActionClear {
284                 alarmClient.alarmer.Clear(a)
285         }
286         return
287 }
288
289 func postAlarmWithHttpIf(targetUrl string, a alarm.Alarm, action alarm.AlarmAction) {
290         m := alarm.AlarmMessage{Alarm: a, AlarmAction: action}
291         jsonData, err := json.Marshal(m)
292         if err != nil {
293                 fmt.Println("json.Marshal failed: ", err)
294                 return
295         }
296
297         resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
298         if err != nil || resp == nil {
299                 fmt.Println("Couldn't fetch active alarm list due to error: ", err)
300                 return
301         }
302 }
303
304 func postAlarm(flags map[string]commando.FlagValue, a alarm.Alarm, action alarm.AlarmAction, alarmClient *AlarmClient) {
305         // Check the interface to be used for raise or clear the alarm
306         rmr_or_http, _ := flags["if"].GetString()
307         if rmr_or_http == "rmr" {
308                 postAlarmWithRmrIf(a, action, alarmClient)
309         } else {
310
311                 host, _ := flags["host"].GetString()
312                 port, _ := flags["port"].GetString()
313                 targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms", host, port)
314                 postAlarmWithHttpIf(targetUrl, a, action)
315         }
316         fmt.Println("command executed successfully!")
317 }
318
319 func displayAlarms(alarms []AlarmNotification, isHistory bool) {
320         t := table.NewWriter()
321         t.SetOutputMirror(os.Stdout)
322         if isHistory {
323                 t.AppendHeader(table.Row{"ID", "SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "ACTION", "TIME"})
324         } else {
325                 t.AppendHeader(table.Row{"ID", "SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "TIME"})
326         }
327
328         for _, a := range alarms {
329                 // Do not show alarm before raiseDelay has elapsed
330                 alarmTime := time.Unix(0, a.AlarmTime).Format("02/01/2006, 15:04:05")
331                 if isHistory {
332                         t.AppendRows([]table.Row{
333                                 {a.AlarmId, a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, a.AlarmAction, alarmTime},
334                         })
335                 } else {
336                         if a.AlarmDefinition.RaiseDelay == 0 {
337                                 t.AppendRows([]table.Row{
338                                         {a.AlarmId, a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, alarmTime},
339                                 })
340                         }
341                 }
342         }
343
344         t.SetStyle(table.StyleColoredBright)
345         t.Render()
346 }
347
348 func postAlarmConfig(flags map[string]commando.FlagValue) {
349         host, _ := flags["host"].GetString()
350         port, _ := flags["port"].GetString()
351         maxactivealarms, _ := flags["mal"].GetInt()
352         maxalarmhistory, _ := flags["mah"].GetInt()
353         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/config", host, port)
354
355         m := alarm.AlarmConfigParams{MaxActiveAlarms: maxactivealarms, MaxAlarmHistory: maxalarmhistory}
356         jsonData, err := json.Marshal(m)
357         if err != nil {
358                 fmt.Println("json.Marshal failed: ", err)
359                 return
360         }
361
362         resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
363         if err != nil || resp == nil {
364                 fmt.Println("Couldn't fetch post alarm configuration due to error: ", err)
365                 return
366         }
367 }
368
369 func postAlarmDefinition(flags map[string]commando.FlagValue) {
370         host, _ := flags["host"].GetString()
371         port, _ := flags["port"].GetString()
372         alarmid, _ := flags["aid"].GetInt()
373         alarmtxt, _ := flags["atx"].GetString()
374         etype, _ := flags["ety"].GetString()
375         operation, _ := flags["oin"].GetString()
376         raiseDelay, _ := flags["rad"].GetInt()
377         clearDelay, _ := flags["cad"].GetInt()
378
379         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define", host, port)
380
381         var alarmdefinition alarm.AlarmDefinition
382         alarmdefinition.AlarmId = alarmid
383         alarmdefinition.AlarmText = alarmtxt
384         alarmdefinition.EventType = etype
385         alarmdefinition.OperationInstructions = operation
386         alarmdefinition.RaiseDelay = raiseDelay
387         alarmdefinition.ClearDelay = clearDelay
388
389         m := CliAlarmDefinitions{AlarmDefinitions: []*alarm.AlarmDefinition{&alarmdefinition}}
390         jsonData, err := json.Marshal(m)
391         if err != nil {
392                 fmt.Println("json.Marshal failed: ", err)
393                 return
394         }
395
396         resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
397         if err != nil || resp == nil {
398                 fmt.Println("Couldn't post alarm definition due to error: ", err)
399                 return
400         }
401 }
402
403 func deleteAlarmDefinition(flags map[string]commando.FlagValue) {
404         host, _ := flags["host"].GetString()
405         port, _ := flags["port"].GetString()
406         alarmid, _ := flags["aid"].GetInt()
407         salarmid := strconv.FormatUint(uint64(alarmid), 10)
408         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define/%s", host, port, salarmid)
409
410         client := &http.Client{}
411         req, err := http.NewRequest("DELETE", targetUrl, nil)
412         if err != nil || req == nil {
413                 fmt.Println("Couldn't make delete request due to error: ", err)
414                 return
415         }
416         resp, errr := client.Do(req)
417         if errr != nil || resp == nil {
418                 fmt.Println("Couldn't send delete request due to error: ", err)
419                 return
420         }
421 }
422
423 // NewAlarmClient returns a new AlarmClient.
424 func NewAlarmClient(moId, appId string) *AlarmClient {
425         alarmInstance, err := alarm.InitAlarm(moId, appId)
426         if err == nil {
427                 return &AlarmClient{
428                         alarmer: alarmInstance,
429                 }
430         }
431         fmt.Println("Failed to create alarmInstance", err)
432         return nil
433 }
434
435 // Conduct performance testing
436 func conductperformancetest(flags map[string]commando.FlagValue) {
437         var readerror error
438         var senderror error
439         var readobjerror error
440         host, _ := flags["host"].GetString()
441         port, _ := flags["port"].GetString()
442         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define", host, port)
443         readerror = readPerfAlarmDefinitionFromJson()
444         if readerror == nil {
445                 senderror = sendPerfAlarmDefinitionToAlarmManager(targetUrl)
446                 if senderror == nil {
447                         fmt.Println("sent performance alarm definitions to alarm manager")
448                         CLIPerfAlarmObjects = make(map[int]*alarm.Alarm)
449                         readobjerror = readPerfAlarmObjectFromJson()
450                         if readobjerror == nil {
451                                 profile, _ := flags["prf"].GetInt()
452                                 if profile == 1 {
453                                         fmt.Println("starting peak performance test")
454                                         peakPerformanceTest(flags)
455                                 } else if profile == 2 {
456                                         fmt.Println("starting endurance test")
457                                         enduranceTest(flags)
458                                 } else {
459                                         fmt.Println("Unknown profile, received profile = ", profile)
460                                 }
461                         } else {
462                                 fmt.Println("reading performance alarm objects from json file failed ")
463                         }
464                 } else {
465                         fmt.Println("sending performance alarm definitions to alarm manager failed ")
466                 }
467
468         } else {
469                 fmt.Println("reading performance alarm definitions from json file failed ")
470         }
471 }
472
473 func peakPerformanceTest(flags map[string]commando.FlagValue) {
474         nalarms, _ := flags["nal"].GetInt()
475         var count int = 0
476         for aid, obj := range CLIPerfAlarmObjects {
477                 count = count + 1
478                 if count <= nalarms {
479                         fmt.Println("peakPerformanceTest: invoking worker routine ", count, aid, *obj)
480                         wg.Add(1)
481                         go raiseClearAlarmOnce(obj, flags)
482                 } else {
483                         break
484                 }
485         }
486         fmt.Println("peakPerformanceTest: Waiting for workers to finish")
487         wg.Wait()
488         fmt.Println("peakPerformanceTest: Wait completed")
489 }
490
491 func enduranceTest(flags map[string]commando.FlagValue) {
492         alarmspersec, _ := flags["aps"].GetInt()
493         var count int = 0
494         for aid, obj := range CLIPerfAlarmObjects {
495                 count = count + 1
496                 if count <= alarmspersec {
497                         fmt.Println("enduranceTest: invoking worker routine ", count, aid, *obj)
498                         wg.Add(1)
499                         go raiseClearAlarmOverPeriod(obj, flags)
500                 } else {
501                         break
502                 }
503         }
504         fmt.Println("enduranceTest: Waiting for workers to finish")
505         wg.Wait()
506         fmt.Println("enduranceTest: Wait completed")
507 }
508
509 func readPerfAlarmObjectFromJson() error {
510
511         filename := os.Getenv("PERF_OBJ_FILE")
512         fmt.Printf("readPerfAlarmObjectFromJson: filename = %s\n", filename)
513
514         file, err := ioutil.ReadFile(filename)
515         if err == nil {
516                 data := RicPerfAlarmObjects{}
517                 err = json.Unmarshal([]byte(file), &data)
518                 if err == nil {
519                         for _, alarmObject := range data.AlarmObjects {
520                                 ricAlarmObject := new(alarm.Alarm)
521                                 ricAlarmObject.ManagedObjectId = alarmObject.ManagedObjectId
522                                 ricAlarmObject.ApplicationId = alarmObject.ApplicationId
523                                 ricAlarmObject.SpecificProblem = alarmObject.SpecificProblem
524                                 ricAlarmObject.PerceivedSeverity = alarmObject.PerceivedSeverity
525                                 ricAlarmObject.AdditionalInfo = alarmObject.AdditionalInfo
526                                 ricAlarmObject.IdentifyingInfo = alarmObject.IdentifyingInfo
527                                 CLIPerfAlarmObjects[alarmObject.SpecificProblem] = ricAlarmObject
528                         }
529                 } else {
530                         fmt.Println("readPerfAlarmObjectFromJson: json.Unmarshal failed with error: ", err)
531                         return err
532                 }
533         } else {
534                 fmt.Printf("readPerfAlarmObjectFromJson: ioutil.ReadFile failed with error: %v, filename: %s\n", err, filename)
535                 fmt.Printf("readPerfAlarmObjectFromJson: current directory: %s\n", getCurrentDirectory())
536                 return err
537         }
538         return nil
539 }
540
541 func readPerfAlarmDefinitionFromJson() error {
542
543         filename := os.Getenv("PERF_DEF_FILE")
544         fmt.Printf("ReadPerfAlarmDefinitionFromJson: filename = %s\n", filename)
545
546         file, err := ioutil.ReadFile(filename)
547         if err == nil {
548                 data := CliAlarmDefinitions{}
549                 err = json.Unmarshal([]byte(file), &data)
550                 if err == nil {
551                         for _, alarmDefinition := range data.AlarmDefinitions {
552                                 _, exists := alarm.RICAlarmDefinitions[alarmDefinition.AlarmId]
553                                 if exists {
554                                         fmt.Println("ReadPerfAlarmDefinitionFromJson: alarm definition already exists for ", alarmDefinition.AlarmId)
555                                 } else {
556                                         fmt.Println("ReadPerfAlarmDefinitionFromJson: alarm ", alarmDefinition.AlarmId)
557                                         ricAlarmDefintion := new(alarm.AlarmDefinition)
558                                         ricAlarmDefintion.AlarmId = alarmDefinition.AlarmId
559                                         ricAlarmDefintion.AlarmText = alarmDefinition.AlarmText
560                                         ricAlarmDefintion.EventType = alarmDefinition.EventType
561                                         ricAlarmDefintion.OperationInstructions = alarmDefinition.OperationInstructions
562                                         ricAlarmDefintion.RaiseDelay = alarmDefinition.RaiseDelay
563                                         ricAlarmDefintion.ClearDelay = alarmDefinition.ClearDelay
564                                         CliPerfAlarmDefinitions.AlarmDefinitions = append(CliPerfAlarmDefinitions.AlarmDefinitions, ricAlarmDefintion)
565                                 }
566                         }
567                 } else {
568                         fmt.Println("ReadPerfAlarmDefinitionFromJson: json.Unmarshal failed with error: ", err)
569                         return err
570                 }
571         } else {
572                 fmt.Printf("ReadPerfAlarmDefinitionFromJson: ioutil.ReadFile failed with error: %v, filename: %s\n", err, filename)
573                 fmt.Printf("ReadPerfAlarmDefinitionFromJson: current directory: %s\n", getCurrentDirectory())
574
575                 return err
576         }
577         return nil
578 }
579
580 func sendPerfAlarmDefinitionToAlarmManager(targetUrl string) error {
581
582         jsonData, err := json.Marshal(CliPerfAlarmDefinitions)
583         if err != nil {
584                 fmt.Println("sendPerfAlarmDefinitionToAlarmManager: json.Marshal failed: ", err)
585                 return err
586         }
587
588         resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
589         if err != nil || resp == nil {
590                 fmt.Println("sendPerfAlarmDefinitionToAlarmManager: Couldn't post alarm definition to targeturl due to error: ", targetUrl, err)
591                 return err
592         }
593         return nil
594 }
595
596 func wakeUpAfterTime(timeinseconds int, chn chan string, action string) {
597         time.Sleep(time.Second * time.Duration(timeinseconds))
598         chn <- action
599 }
600
601 func raiseClearAlarmOnce(alarmobject *alarm.Alarm, flags map[string]commando.FlagValue) {
602         var alarmClient *AlarmClient = nil
603         defer wg.Done()
604         chn := make(chan string, 1)
605         rmr_or_http, _ := flags["if"].GetString()
606         if rmr_or_http == "rmr" {
607                 alarmClient = NewAlarmClient("my-pod", "my-app")
608         }
609         postAlarm(flags, *alarmobject, alarm.AlarmActionRaise, alarmClient)
610         go wakeUpAfterTime(PeakTestDuration, chn, Clear)
611         select {
612         case res := <-chn:
613                 if res == Clear {
614                         postAlarm(flags, *alarmobject, alarm.AlarmActionClear, alarmClient)
615                         go wakeUpAfterTime(PeakTestDuration, chn, End)
616                 } else if res == End {
617                         return
618                 }
619         }
620 }
621
622 func raiseClearAlarmOverPeriod(alarmobject *alarm.Alarm, flags map[string]commando.FlagValue) {
623         var alarmClient *AlarmClient = nil
624         defer wg.Done()
625         timeinminutes, _ := flags["tim"].GetInt()
626         timeinseconds := timeinminutes * 60
627         chn := make(chan string, 1)
628         rmr_or_http, _ := flags["if"].GetString()
629         if rmr_or_http == "rmr" {
630                 alarmClient = NewAlarmClient("my-pod", "my-app")
631         }
632         postAlarm(flags, *alarmobject, alarm.AlarmActionRaise, alarmClient)
633         go wakeUpAfterTime(OneSecondDuration, chn, Clear)
634         go wakeUpAfterTime(timeinseconds, chn, End)
635         for {
636                 select {
637                 case res := <-chn:
638                         if res == Raise {
639                                 postAlarm(flags, *alarmobject, alarm.AlarmActionRaise, alarmClient)
640                                 go wakeUpAfterTime(OneSecondDuration, chn, Clear)
641                         } else if res == Clear {
642                                 postAlarm(flags, *alarmobject, alarm.AlarmActionClear, alarmClient)
643                                 go wakeUpAfterTime(OneSecondDuration, chn, Raise)
644                         } else if res == End {
645                                 return
646                         }
647                 }
648         }
649 }
650
651 func dispalyAlertAnnotations(t table.Writer, gettableAlert *models.GettableAlert) {
652         var annotationmap map[string]string
653         annotationmap = make(map[string]string)
654         for key, item := range gettableAlert.Annotations {
655                 annotationmap[key] = item
656         }
657         t.AppendRow([]interface{}{"alarm_id", annotationmap["alarm_id"]})
658         t.AppendRow([]interface{}{"specific_problem", annotationmap["specific_problem"]})
659         t.AppendRow([]interface{}{"timestamp", annotationmap["timestamp"]})
660         t.AppendRow([]interface{}{"event_type", annotationmap["event_type"]})
661         t.AppendRow([]interface{}{"description", annotationmap["description"]})
662         t.AppendRow([]interface{}{"additional_info", annotationmap["additional_info"]})
663         t.AppendRow([]interface{}{"identifying_info", annotationmap["identifying_info"]})
664         t.AppendRow([]interface{}{"instructions", annotationmap["instructions"]})
665 }
666
667 func displayAlertLabels(t table.Writer, gettableAlert *models.GettableAlert) {
668         var labelmap map[string]string
669         labelmap = make(map[string]string)
670         for key, item := range gettableAlert.Alert.Labels {
671                 labelmap[key] = item
672         }
673         t.AppendRow([]interface{}{"alertname", labelmap["alertname"]})
674         t.AppendRow([]interface{}{"status", labelmap["status"]})
675         t.AppendRow([]interface{}{"severity", labelmap["severity"]})
676         t.AppendRow([]interface{}{"system_name", labelmap["system_name"]})
677         t.AppendRow([]interface{}{"service", labelmap["service"]})
678 }
679
680 func displaySingleAlert(t table.Writer, gettableAlert *models.GettableAlert) {
681         t.AppendRow([]interface{}{"------------------------------------"})
682         dispalyAlertAnnotations(t, gettableAlert)
683         if gettableAlert.EndsAt != nil {
684                 t.AppendRow([]interface{}{"EndsAt", *gettableAlert.EndsAt})
685         }
686         if gettableAlert.Fingerprint != nil {
687                 t.AppendRow([]interface{}{"Fingerprint", *gettableAlert.Fingerprint})
688         }
689         for key, item := range gettableAlert.Receivers {
690                 if gettableAlert.Receivers != nil {
691                         t.AppendRow([]interface{}{key, *item.Name})
692                 }
693         }
694         if gettableAlert.StartsAt != nil {
695                 t.AppendRow([]interface{}{"StartsAt", *gettableAlert.StartsAt})
696         }
697         if gettableAlert.Status != nil {
698                 t.AppendRow([]interface{}{"InhibitedBy", gettableAlert.Status.InhibitedBy})
699                 t.AppendRow([]interface{}{"SilencedBy", gettableAlert.Status.SilencedBy})
700                 t.AppendRow([]interface{}{"State", *gettableAlert.Status.State})
701         }
702         if gettableAlert.UpdatedAt != nil {
703                 t.AppendRow([]interface{}{"UpdatedAt", *gettableAlert.UpdatedAt})
704         }
705         t.AppendRow([]interface{}{"GeneratorURL", gettableAlert.Alert.GeneratorURL})
706         displayAlertLabels(t, gettableAlert)
707 }
708
709 func displayAlerts(flags map[string]commando.FlagValue) {
710         resp, err := getAlerts(flags)
711         if err != nil {
712                 fmt.Println(err)
713                 return
714         }
715
716         if resp == nil {
717                 fmt.Println("resp= nil")
718                 return
719         }
720
721         t := table.NewWriter()
722         t.SetOutputMirror(os.Stdout)
723         t.AppendHeader(table.Row{"Alerts from Prometheus Alert Manager"})
724         for _, gettableAlert := range resp.Payload {
725                 if gettableAlert == nil {
726                         continue
727                 }
728
729                 displaySingleAlert(t, gettableAlert)
730         }
731         t.SetStyle(table.StyleColoredBright)
732         t.Render()
733 }
734
735 func getAlerts(flags map[string]commando.FlagValue) (*alert.GetAlertsOK, error) {
736         active, _ := flags["active"].GetBool()
737         inhibited, _ := flags["inhibited"].GetBool()
738         silenced, _ := flags["silenced"].GetBool()
739         unprocessed, _ := flags["unprocessed"].GetBool()
740         amHost, _ := flags["host"].GetString()
741         amPort, _ := flags["port"].GetString()
742         amAddress := amHost + ":" + amPort
743         amBaseUrl := "api/v2"
744         amSchemes := []string{"http"}
745
746         alertParams := alert.NewGetAlertsParams()
747         alertParams.Active = &active
748         alertParams.Inhibited = &inhibited
749         alertParams.Silenced = &silenced
750         alertParams.Unprocessed = &unprocessed
751         resp, err := newAlertManagerClient(amAddress, amBaseUrl, amSchemes).Alert.GetAlerts(alertParams)
752         if err != nil {
753                 err = fmt.Errorf("GetAlerts from amAddress = %s with amBaseUrl = %s failed with error: %v", amAddress, amBaseUrl, err)
754         }
755         return resp, err
756 }
757
758 func newAlertManagerClient(amAddress string, amBaseUrl string, amSchemes []string) *client.AlertmanagerAPI {
759         cr := clientruntime.New(amAddress, amBaseUrl, amSchemes)
760         return client.New(cr, strfmt.Default)
761 }
762
763 func getCurrentDirectory() string {
764         dir, err := os.Getwd()
765         if err != nil {
766                 fmt.Println(err)
767         }
768         return dir
769 }