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