Merge "adding robot unit testcases for alarmgo, cli based testing - alarmgo cli comma...
[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         "time"
12
13         "gerrit.o-ran-sc.org/r/ric-plt/alarm-go/alarm"
14         "github.com/jedib0t/go-pretty/table"
15         "github.com/thatisuday/commando"
16 )
17
18 type CliAlarmDefinitions struct {
19         AlarmDefinitions []*alarm.AlarmDefinition `json:"alarmdefinitions"`
20 }
21
22 type AlarmClient struct {
23         alarmer *alarm.RICAlarm
24 }
25
26 func main() {
27
28         // configure commando
29         commando.
30                 SetExecutableName("alarm-cli").
31                 SetVersion("1.0.0").
32                 SetDescription("This CLI tool provides management interface to SEP alarm system")
33
34         // Get active alarms
35         commando.
36                 Register("active").
37                 SetShortDescription("Displays the SEP active alarms").
38                 SetDescription("This command displays more information about the SEP active alarms").
39                 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
40                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
41                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
42                         displayAlarms(getAlarms(flags, "active"), false)
43                 })
44
45         // Get alarm history
46         commando.
47                 Register("history").
48                 SetShortDescription("Displays the SEP alarm history").
49                 SetDescription("This command displays more information about the SEP alarm history").
50                 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
51                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
52                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
53                         displayAlarms(getAlarms(flags, "history"), true)
54                 })
55
56         // Raise an alarm
57         commando.
58                 Register("raise").
59                 SetShortDescription("Raises alarm with given parameters").
60                 AddFlag("moid", "Managed object Id", commando.String, nil).
61                 AddFlag("apid", "Application Id", commando.String, nil).
62                 AddFlag("sp", "Specific problem Id", commando.Int, nil).
63                 AddFlag("severity", "Perceived severity", commando.String, nil).
64                 AddFlag("iinfo", "Application identifying info", commando.String, nil).
65                 AddFlag("aai", "Application additional info", commando.String, "-").
66                 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
67                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
68                 AddFlag("if", "http or rmr used as interface", commando.String, "http").
69                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
70                         postAlarm(flags, readAlarmParams(flags, false), alarm.AlarmActionRaise)
71                 })
72
73         // Clear an alarm
74         commando.
75                 Register("clear").
76                 SetShortDescription("Raises alarm with given parameters").
77                 AddFlag("moid", "Managed object Id", commando.String, nil).
78                 AddFlag("apid", "Application Id", commando.String, nil).
79                 AddFlag("sp", "Specific problem Id", commando.Int, nil).
80                 AddFlag("iinfo", "Application identifying info", commando.String, nil).
81                 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
82                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
83                 AddFlag("if", "http or rmr used as interface", commando.String, "http").
84                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
85                         postAlarm(flags, readAlarmParams(flags, true), alarm.AlarmActionClear)
86                 })
87
88         // Configure an alarm manager
89         commando.
90                 Register("configure").
91                 SetShortDescription("Configure alarm manager with given parameters").
92                 AddFlag("mal", "max active alarms", commando.Int, nil).
93                 AddFlag("mah", "max alarm history", commando.Int, nil).
94                 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
95                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
96                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
97                         postAlarmConfig(flags)
98                 })
99         // Create alarm definition
100         commando.
101                 Register("define").
102                 SetShortDescription("Define alarm with given parameters").
103                 AddFlag("aid", "alarm identifier", commando.Int, nil).
104                 AddFlag("atx", "alarm text", commando.String, nil).
105                 AddFlag("ety", "event type", commando.String, nil).
106                 AddFlag("oin", "operation instructions", commando.String, nil).
107                 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
108                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
109                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
110                         postAlarmDefinition(flags)
111                 })
112                 // Delete alarm definition
113         commando.
114                 Register("undefine").
115                 SetShortDescription("Define alarm with given parameters").
116                 AddFlag("aid", "alarm identifier", commando.Int, nil).
117                 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
118                 AddFlag("port", "Alarm manager host address", commando.String, "8080").
119                 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
120                         deleteAlarmDefinition(flags)
121                 })
122
123         // parse command-line arguments
124         commando.Parse(nil)
125 }
126
127 func readAlarmParams(flags map[string]commando.FlagValue, clear bool) (a alarm.Alarm) {
128         a.ManagedObjectId, _ = flags["moid"].GetString()
129         a.ApplicationId, _ = flags["apid"].GetString()
130         a.SpecificProblem, _ = flags["sp"].GetInt()
131         a.IdentifyingInfo, _ = flags["iinfo"].GetString()
132
133         if !clear {
134                 s, _ := flags["severity"].GetString()
135                 a.PerceivedSeverity = alarm.Severity(s)
136         }
137
138         if !clear {
139                 a.AdditionalInfo, _ = flags["aai"].GetString()
140         }
141         return
142 }
143
144 func getAlarms(flags map[string]commando.FlagValue, action alarm.AlarmAction) (alarms []alarm.AlarmMessage) {
145         host, _ := flags["host"].GetString()
146         port, _ := flags["port"].GetString()
147         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/%s", host, port, action)
148         resp, err := http.Get(targetUrl)
149         if err != nil || resp == nil || resp.Body == nil {
150                 fmt.Println("Couldn't fetch active alarm list due to error: %v", err)
151                 return alarms
152         }
153
154         defer resp.Body.Close()
155
156         body, err := ioutil.ReadAll(resp.Body)
157         if err != nil {
158                 fmt.Println("ioutil.ReadAll failed: %v", err)
159                 return alarms
160         }
161
162         json.Unmarshal([]byte(body), &alarms)
163         return alarms
164 }
165
166 func postAlarm(flags map[string]commando.FlagValue, a alarm.Alarm, action alarm.AlarmAction) {
167
168         // Check the interface to be used for raise or clear the alarm
169         rmr_or_http, _ := flags["if"].GetString()
170         if rmr_or_http == "rmr" {
171                 alarmClient := NewAlarmClient("my-pod", "my-app")
172                 if alarmClient == nil {
173                         return
174                 }
175
176                 // Wait until RMR is up-and-running
177                 for !alarmClient.alarmer.IsRMRReady() {
178                         time.Sleep(100 * time.Millisecond)
179                 }
180
181                 if action == alarm.AlarmActionRaise {
182                         alarmClient.alarmer.Raise(a)
183                 }
184
185                 if action == alarm.AlarmActionClear {
186                         alarmClient.alarmer.Clear(a)
187                 }
188                 return
189         }
190
191         host, _ := flags["host"].GetString()
192         port, _ := flags["port"].GetString()
193         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms", host, port)
194
195         m := alarm.AlarmMessage{Alarm: a, AlarmAction: action}
196         jsonData, err := json.Marshal(m)
197         if err != nil {
198                 fmt.Println("json.Marshal failed: %v", err)
199                 return
200         }
201
202         resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
203         if err != nil || resp == nil {
204                 fmt.Println("Couldn't fetch active alarm list due to error: %v", err)
205                 return
206         }
207 }
208
209 func displayAlarms(alarms []alarm.AlarmMessage, isHistory bool) {
210         t := table.NewWriter()
211         t.SetOutputMirror(os.Stdout)
212         if isHistory {
213                 t.AppendHeader(table.Row{"SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "ACTION", "TIME"})
214         } else {
215                 t.AppendHeader(table.Row{"SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "TIME"})
216         }
217
218         for _, a := range alarms {
219                 alarmTime := time.Unix(0, a.AlarmTime).Format("02/01/2006, 15:04:05")
220                 if isHistory {
221                         t.AppendRows([]table.Row{
222                                 {a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, a.AlarmAction, alarmTime},
223                         })
224                 } else {
225                         t.AppendRows([]table.Row{
226                                 {a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, alarmTime},
227                         })
228                 }
229         }
230
231         t.SetStyle(table.StyleColoredBright)
232         t.Render()
233 }
234
235 func postAlarmConfig(flags map[string]commando.FlagValue) {
236         host, _ := flags["host"].GetString()
237         port, _ := flags["port"].GetString()
238         maxactivealarms, _ := flags["mal"].GetInt()
239         maxalarmhistory, _ := flags["mah"].GetInt()
240         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/config", host, port)
241
242         m := alarm.AlarmConfigParams{MaxActiveAlarms: maxactivealarms, MaxAlarmHistory: maxalarmhistory}
243         jsonData, err := json.Marshal(m)
244         if err != nil {
245                 fmt.Println("json.Marshal failed: %v", err)
246                 return
247         }
248
249         resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
250         if err != nil || resp == nil {
251                 fmt.Println("Couldn't fetch post alarm configuration due to error: %v", err)
252                 return
253         }
254 }
255
256 func postAlarmDefinition(flags map[string]commando.FlagValue) {
257         host, _ := flags["host"].GetString()
258         port, _ := flags["port"].GetString()
259         alarmid, _ := flags["aid"].GetInt()
260         alarmtxt, _ := flags["atx"].GetString()
261         etype, _ := flags["ety"].GetString()
262         operation, _ := flags["oin"].GetString()
263         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define", host, port)
264
265         var alarmdefinition alarm.AlarmDefinition
266         alarmdefinition.AlarmId = alarmid
267         alarmdefinition.AlarmText = alarmtxt
268         alarmdefinition.EventType = etype
269         alarmdefinition.OperationInstructions = operation
270
271         m := CliAlarmDefinitions{AlarmDefinitions: []*alarm.AlarmDefinition{&alarmdefinition}}
272         jsonData, err := json.Marshal(m)
273         if err != nil {
274                 fmt.Println("json.Marshal failed: %v", err)
275                 return
276         }
277
278         resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
279         if err != nil || resp == nil {
280                 fmt.Println("Couldn't post alarm definition due to error: %v", err)
281                 return
282         }
283 }
284
285 func deleteAlarmDefinition(flags map[string]commando.FlagValue) {
286         host, _ := flags["host"].GetString()
287         port, _ := flags["port"].GetString()
288         alarmid, _ := flags["aid"].GetInt()
289         salarmid := strconv.FormatUint(uint64(alarmid), 10)
290         targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define/%s", host, port, salarmid)
291
292         client := &http.Client{}
293         req, err := http.NewRequest("DELETE", targetUrl, nil)
294         if err != nil || req == nil {
295                 fmt.Println("Couldn't make delete request due to error: %v", err)
296                 return
297         }
298         resp, errr := client.Do(req)
299         if errr != nil || resp == nil {
300                 fmt.Println("Couldn't send delete request due to error: %v", err)
301                 return
302         }
303 }
304
305 // NewAlarmClient returns a new AlarmClient.
306 func NewAlarmClient(moId, appId string) *AlarmClient {
307         alarmInstance, err := alarm.InitAlarm(moId, appId)
308         if err == nil {
309                 return &AlarmClient{
310                         alarmer: alarmInstance,
311                 }
312         }
313         fmt.Println("Failed to create alarmInstance", err)
314         return nil
315 }