X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=cli%2Falarm-cli.go;h=0b4af6bcfd024c639e51a95c8792e1db604fb96d;hb=63b5df0f4b2cb5f9d979501bf28f27d1ee36769f;hp=f666292277f0144b19c9e5254484c403527261c3;hpb=00894a4120ea2c93bc58327fbb7c526a6f607bde;p=ric-plt%2Falarm-go.git diff --git a/cli/alarm-cli.go b/cli/alarm-cli.go index f666292..0b4af6b 100755 --- a/cli/alarm-cli.go +++ b/cli/alarm-cli.go @@ -11,14 +11,14 @@ import ( "sync" "time" - "gerrit.o-ran-sc.org/r/ric-plt/alarm-go/alarm" + "gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm" clientruntime "github.com/go-openapi/runtime/client" "github.com/go-openapi/strfmt" "github.com/jedib0t/go-pretty/table" "github.com/prometheus/alertmanager/api/v2/client" "github.com/prometheus/alertmanager/api/v2/client/alert" + "github.com/prometheus/alertmanager/api/v2/models" "github.com/thatisuday/commando" - "github.com/spf13/viper" ) type CliAlarmDefinitions struct { @@ -33,6 +33,11 @@ type RicPerfAlarmObjects struct { AlarmObjects []*alarm.Alarm `json:"alarmobjects"` } +type AlarmNotification struct { + alarm.AlarmMessage + alarm.AlarmDefinition +} + var CLIPerfAlarmObjects map[int]*alarm.Alarm var wg sync.WaitGroup @@ -48,6 +53,15 @@ const ( ) func main() { + alarmManagerHost := "localhost" + if h := os.Getenv("ALARM_MANAGER_HOST"); h != "" { + alarmManagerHost = h + } + + alertManagerHost := "localhost" + if h := os.Getenv("ALERT_MANAGER_HOST"); h != "" { + alertManagerHost = h + } // configure commando commando. @@ -55,28 +69,46 @@ func main() { SetVersion("1.0.0"). SetDescription("This CLI tool provides management interface to SEP alarm system") - // Get active alarms + registerActiveCmd(alarmManagerHost) + registerHistoryCmd(alarmManagerHost) + registerRaiseCmd(alarmManagerHost) + registerClearCmd(alarmManagerHost) + registerDefineCmd(alarmManagerHost) + registerUndefineCmd(alarmManagerHost) + registerConfigureCmd(alarmManagerHost) + registerPerfCmd(alarmManagerHost) + registerAlertCmd(alertManagerHost) + + // parse command-line arguments + commando.Parse(nil) +} + +func registerActiveCmd(alarmManagerHost string) { commando. Register("active"). SetShortDescription("Displays the SEP active alarms"). SetDescription("This command displays more information about the SEP active alarms"). - AddFlag("host", "Alarm manager host address", commando.String, "localhost"). + AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost). AddFlag("port", "Alarm manager host address", commando.String, "8080"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { displayAlarms(getAlarms(flags, "active"), false) }) +} +func registerHistoryCmd(alarmManagerHost string) { // Get alarm history commando. Register("history"). SetShortDescription("Displays the SEP alarm history"). SetDescription("This command displays more information about the SEP alarm history"). - AddFlag("host", "Alarm manager host address", commando.String, "localhost"). + AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost). AddFlag("port", "Alarm manager host address", commando.String, "8080"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { displayAlarms(getAlarms(flags, "history"), true) }) +} +func registerRaiseCmd(alarmManagerHost string) { // Raise an alarm commando. Register("raise"). @@ -87,13 +119,16 @@ func main() { AddFlag("severity", "Perceived severity", commando.String, nil). AddFlag("iinfo", "Application identifying info", commando.String, nil). AddFlag("aai", "Application additional info", commando.String, "-"). - AddFlag("host", "Alarm manager host address", commando.String, "localhost"). + AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost). AddFlag("port", "Alarm manager host address", commando.String, "8080"). AddFlag("if", "http or rmr used as interface", commando.String, "http"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { postAlarm(flags, readAlarmParams(flags, false), alarm.AlarmActionRaise, nil) }) +} + +func registerClearCmd(alarmManagerHost string) { // Clear an alarm commando. Register("clear"). @@ -102,24 +137,30 @@ func main() { AddFlag("apid", "Application Id", commando.String, nil). AddFlag("sp", "Specific problem Id", commando.Int, nil). AddFlag("iinfo", "Application identifying info", commando.String, nil). - AddFlag("host", "Alarm manager host address", commando.String, "localhost"). + AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost). AddFlag("port", "Alarm manager host address", commando.String, "8080"). AddFlag("if", "http or rmr used as interface", commando.String, "http"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { postAlarm(flags, readAlarmParams(flags, true), alarm.AlarmActionClear, nil) }) +} + +func registerConfigureCmd(alarmManagerHost string) { // Configure an alarm manager commando. Register("configure"). SetShortDescription("Configure alarm manager with given parameters"). AddFlag("mal", "max active alarms", commando.Int, nil). AddFlag("mah", "max alarm history", commando.Int, nil). - AddFlag("host", "Alarm manager host address", commando.String, "localhost"). + AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost). AddFlag("port", "Alarm manager host address", commando.String, "8080"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { postAlarmConfig(flags) }) +} + +func registerDefineCmd(alarmManagerHost string) { // Create alarm definition commando. Register("define"). @@ -128,22 +169,30 @@ func main() { AddFlag("atx", "alarm text", commando.String, nil). AddFlag("ety", "event type", commando.String, nil). AddFlag("oin", "operation instructions", commando.String, nil). - AddFlag("host", "Alarm manager host address", commando.String, "localhost"). + AddFlag("rad", "Raise alarm delay", commando.Int, 0). + AddFlag("cad", "Clear alarm delay", commando.Int, 0). + AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost). AddFlag("port", "Alarm manager host address", commando.String, "8080"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { postAlarmDefinition(flags) }) - // Delete alarm definition +} + +func registerUndefineCmd(alarmManagerHost string) { + // Delete alarm definition commando. Register("undefine"). SetShortDescription("Define alarm with given parameters"). AddFlag("aid", "alarm identifier", commando.Int, nil). - AddFlag("host", "Alarm manager host address", commando.String, "localhost"). + AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost). AddFlag("port", "Alarm manager host address", commando.String, "8080"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { deleteAlarmDefinition(flags) }) - // Conduct performance test for alarm-go +} + +func registerPerfCmd(alarmManagerHost string) { + // Conduct performance test for alarm-go commando. Register("perf"). SetShortDescription("Conduct performance test with given parameters"). @@ -151,29 +200,28 @@ func main() { AddFlag("nal", "number of alarms", commando.Int, nil). AddFlag("aps", "alarms per sec", commando.Int, nil). AddFlag("tim", "total time of test", commando.Int, nil). - AddFlag("host", "Alarm manager host address", commando.String, "localhost"). + AddFlag("host", "Alarm manager host address", commando.String, alarmManagerHost). AddFlag("port", "Alarm manager host address", commando.String, "8080"). AddFlag("if", "http or rmr used as interface", commando.String, "http"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { conductperformancetest(flags) }) +} +func registerAlertCmd(alertManagerHost string) { // Get alerts from Prometheus Alert Manager commando. - Register("gapam"). + Register("alerts"). SetShortDescription("Get alerts from Prometheus Alert Manager"). AddFlag("active", "Active alerts in Prometheus Alert Manager", commando.Bool, true). AddFlag("inhibited", "Inhibited alerts in Prometheus Alert Manager", commando.Bool, true). AddFlag("silenced", "Silenced alerts in Prometheus Alert Manager", commando.Bool, true). AddFlag("unprocessed", "Unprocessed alerts in Prometheus Alert Manager", commando.Bool, true). - AddFlag("host", "Prometheus Alert Manager host address", commando.String, nil). + AddFlag("host", "Prometheus Alert Manager host address", commando.String, alertManagerHost). AddFlag("port", "Prometheus Alert Manager port", commando.String, "9093"). SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) { displayAlerts(flags) }) - - // parse command-line arguments - commando.Parse(nil) } func readAlarmParams(flags map[string]commando.FlagValue, clear bool) (a alarm.Alarm) { @@ -193,7 +241,7 @@ func readAlarmParams(flags map[string]commando.FlagValue, clear bool) (a alarm.A return } -func getAlarms(flags map[string]commando.FlagValue, action alarm.AlarmAction) (alarms []alarm.AlarmMessage) { +func getAlarms(flags map[string]commando.FlagValue, action alarm.AlarmAction) (alarms []AlarmNotification) { host, _ := flags["host"].GetString() port, _ := flags["port"].GetString() targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/%s", host, port, action) @@ -265,27 +313,31 @@ func postAlarm(flags map[string]commando.FlagValue, a alarm.Alarm, action alarm. targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms", host, port) postAlarmWithHttpIf(targetUrl, a, action) } + fmt.Println("command executed successfully!") } -func displayAlarms(alarms []alarm.AlarmMessage, isHistory bool) { +func displayAlarms(alarms []AlarmNotification, isHistory bool) { t := table.NewWriter() t.SetOutputMirror(os.Stdout) if isHistory { - t.AppendHeader(table.Row{"SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "ACTION", "TIME"}) + t.AppendHeader(table.Row{"ID", "SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "ACTION", "TIME"}) } else { - t.AppendHeader(table.Row{"SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "TIME"}) + t.AppendHeader(table.Row{"ID", "SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "TIME"}) } for _, a := range alarms { + // Do not show alarm before raiseDelay has elapsed alarmTime := time.Unix(0, a.AlarmTime).Format("02/01/2006, 15:04:05") if isHistory { t.AppendRows([]table.Row{ - {a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, a.AlarmAction, alarmTime}, + {a.AlarmId, a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, a.AlarmAction, alarmTime}, }) } else { - t.AppendRows([]table.Row{ - {a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, alarmTime}, - }) + if a.AlarmDefinition.RaiseDelay == 0 { + t.AppendRows([]table.Row{ + {a.AlarmId, a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, alarmTime}, + }) + } } } @@ -321,6 +373,9 @@ func postAlarmDefinition(flags map[string]commando.FlagValue) { alarmtxt, _ := flags["atx"].GetString() etype, _ := flags["ety"].GetString() operation, _ := flags["oin"].GetString() + raiseDelay, _ := flags["rad"].GetInt() + clearDelay, _ := flags["cad"].GetInt() + targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define", host, port) var alarmdefinition alarm.AlarmDefinition @@ -328,6 +383,8 @@ func postAlarmDefinition(flags map[string]commando.FlagValue) { alarmdefinition.AlarmText = alarmtxt alarmdefinition.EventType = etype alarmdefinition.OperationInstructions = operation + alarmdefinition.RaiseDelay = raiseDelay + alarmdefinition.ClearDelay = clearDelay m := CliAlarmDefinitions{AlarmDefinitions: []*alarm.AlarmDefinition{&alarmdefinition}} jsonData, err := json.Marshal(m) @@ -411,7 +468,6 @@ func conductperformancetest(flags map[string]commando.FlagValue) { } else { fmt.Println("reading performance alarm definitions from json file failed ") } - } func peakPerformanceTest(flags map[string]commando.FlagValue) { @@ -451,7 +507,10 @@ func enduranceTest(flags map[string]commando.FlagValue) { } func readPerfAlarmObjectFromJson() error { + filename := os.Getenv("PERF_OBJ_FILE") + fmt.Printf("readPerfAlarmObjectFromJson: filename = %s\n", filename) + file, err := ioutil.ReadFile(filename) if err == nil { data := RicPerfAlarmObjects{} @@ -468,18 +527,22 @@ func readPerfAlarmObjectFromJson() error { CLIPerfAlarmObjects[alarmObject.SpecificProblem] = ricAlarmObject } } else { - fmt.Println("readPerfAlarmObjectFromJson: json.Unmarshal failed with error ", err) + fmt.Println("readPerfAlarmObjectFromJson: json.Unmarshal failed with error: ", err) return err } } else { - fmt.Println("readPerfAlarmObjectFromJson: ioutil.ReadFile failed with error ", err) + fmt.Printf("readPerfAlarmObjectFromJson: ioutil.ReadFile failed with error: %v, filename: %s\n", err, filename) + fmt.Printf("readPerfAlarmObjectFromJson: current directory: %s\n", getCurrentDirectory()) return err } return nil } func readPerfAlarmDefinitionFromJson() error { + filename := os.Getenv("PERF_DEF_FILE") + fmt.Printf("ReadPerfAlarmDefinitionFromJson: filename = %s\n", filename) + file, err := ioutil.ReadFile(filename) if err == nil { data := CliAlarmDefinitions{} @@ -496,6 +559,8 @@ func readPerfAlarmDefinitionFromJson() error { ricAlarmDefintion.AlarmText = alarmDefinition.AlarmText ricAlarmDefintion.EventType = alarmDefinition.EventType ricAlarmDefintion.OperationInstructions = alarmDefinition.OperationInstructions + ricAlarmDefintion.RaiseDelay = alarmDefinition.RaiseDelay + ricAlarmDefintion.ClearDelay = alarmDefinition.ClearDelay CliPerfAlarmDefinitions.AlarmDefinitions = append(CliPerfAlarmDefinitions.AlarmDefinitions, ricAlarmDefintion) } } @@ -504,7 +569,9 @@ func readPerfAlarmDefinitionFromJson() error { return err } } else { - fmt.Println("ReadPerfAlarmDefinitionFromJson: ioutil.ReadFile failed with error: ", err) + fmt.Printf("ReadPerfAlarmDefinitionFromJson: ioutil.ReadFile failed with error: %v, filename: %s\n", err, filename) + fmt.Printf("ReadPerfAlarmDefinitionFromJson: current directory: %s\n", getCurrentDirectory()) + return err } return nil @@ -581,6 +648,64 @@ func raiseClearAlarmOverPeriod(alarmobject *alarm.Alarm, flags map[string]comman } } +func dispalyAlertAnnotations(t table.Writer, gettableAlert *models.GettableAlert) { + var annotationmap map[string]string + annotationmap = make(map[string]string) + for key, item := range gettableAlert.Annotations { + annotationmap[key] = item + } + t.AppendRow([]interface{}{"alarm_id", annotationmap["alarm_id"]}) + t.AppendRow([]interface{}{"specific_problem", annotationmap["specific_problem"]}) + t.AppendRow([]interface{}{"timestamp", annotationmap["timestamp"]}) + t.AppendRow([]interface{}{"event_type", annotationmap["event_type"]}) + t.AppendRow([]interface{}{"description", annotationmap["description"]}) + t.AppendRow([]interface{}{"additional_info", annotationmap["additional_info"]}) + t.AppendRow([]interface{}{"identifying_info", annotationmap["identifying_info"]}) + t.AppendRow([]interface{}{"instructions", annotationmap["instructions"]}) +} + +func displayAlertLabels(t table.Writer, gettableAlert *models.GettableAlert) { + var labelmap map[string]string + labelmap = make(map[string]string) + for key, item := range gettableAlert.Alert.Labels { + labelmap[key] = item + } + t.AppendRow([]interface{}{"alertname", labelmap["alertname"]}) + t.AppendRow([]interface{}{"status", labelmap["status"]}) + t.AppendRow([]interface{}{"severity", labelmap["severity"]}) + t.AppendRow([]interface{}{"system_name", labelmap["system_name"]}) + t.AppendRow([]interface{}{"service", labelmap["service"]}) +} + +func displaySingleAlert(t table.Writer, gettableAlert *models.GettableAlert) { + t.AppendRow([]interface{}{"------------------------------------"}) + dispalyAlertAnnotations(t, gettableAlert) + if gettableAlert.EndsAt != nil { + t.AppendRow([]interface{}{"EndsAt", *gettableAlert.EndsAt}) + } + if gettableAlert.Fingerprint != nil { + t.AppendRow([]interface{}{"Fingerprint", *gettableAlert.Fingerprint}) + } + for key, item := range gettableAlert.Receivers { + if gettableAlert.Receivers != nil { + t.AppendRow([]interface{}{key, *item.Name}) + } + } + if gettableAlert.StartsAt != nil { + t.AppendRow([]interface{}{"StartsAt", *gettableAlert.StartsAt}) + } + if gettableAlert.Status != nil { + t.AppendRow([]interface{}{"InhibitedBy", gettableAlert.Status.InhibitedBy}) + t.AppendRow([]interface{}{"SilencedBy", gettableAlert.Status.SilencedBy}) + t.AppendRow([]interface{}{"State", *gettableAlert.Status.State}) + } + if gettableAlert.UpdatedAt != nil { + t.AppendRow([]interface{}{"UpdatedAt", *gettableAlert.UpdatedAt}) + } + t.AppendRow([]interface{}{"GeneratorURL", gettableAlert.Alert.GeneratorURL}) + displayAlertLabels(t, gettableAlert) +} + func displayAlerts(flags map[string]commando.FlagValue) { resp, err := getAlerts(flags) if err != nil { @@ -596,44 +721,17 @@ func displayAlerts(flags map[string]commando.FlagValue) { t := table.NewWriter() t.SetOutputMirror(os.Stdout) t.AppendHeader(table.Row{"Alerts from Prometheus Alert Manager"}) - for _, gettableAlert := range resp.Payload{ - t.AppendRow([]interface{}{"------------------------------------"}) - if gettableAlert != nil { - for key, item := range gettableAlert.Annotations { - t.AppendRow([]interface{}{key, item}) - } - if gettableAlert.EndsAt != nil { - t.AppendRow([]interface{}{"EndsAt", *gettableAlert.EndsAt}) - } - if gettableAlert.Fingerprint != nil { - t.AppendRow([]interface{}{"Fingerprint", *gettableAlert.Fingerprint}) - } - for key, item := range gettableAlert.Receivers { - if gettableAlert.Receivers != nil { - t.AppendRow([]interface{}{key, *item.Name}) - } - } - if gettableAlert.StartsAt != nil { - t.AppendRow([]interface{}{"StartsAt", *gettableAlert.StartsAt}) - } - if gettableAlert.Status != nil { - t.AppendRow([]interface{}{"InhibitedBy", gettableAlert.Status.InhibitedBy}) - t.AppendRow([]interface{}{"SilencedBy", gettableAlert.Status.SilencedBy}) - t.AppendRow([]interface{}{"State", *gettableAlert.Status.State}) - } - if gettableAlert.UpdatedAt != nil { - t.AppendRow([]interface{}{"UpdatedAt", *gettableAlert.UpdatedAt}) - } - t.AppendRow([]interface{}{"GeneratorURL", gettableAlert.Alert.GeneratorURL}) - for key, item := range gettableAlert.Alert.Labels { - t.AppendRow([]interface{}{key, item}) - } + for _, gettableAlert := range resp.Payload { + if gettableAlert == nil { + continue } + + displaySingleAlert(t, gettableAlert) } t.SetStyle(table.StyleColoredBright) t.Render() } - + func getAlerts(flags map[string]commando.FlagValue) (*alert.GetAlertsOK, error) { active, _ := flags["active"].GetBool() inhibited, _ := flags["inhibited"].GetBool() @@ -641,23 +739,18 @@ func getAlerts(flags map[string]commando.FlagValue) (*alert.GetAlertsOK, error) unprocessed, _ := flags["unprocessed"].GetBool() amHost, _ := flags["host"].GetString() amPort, _ := flags["port"].GetString() - var amAddress string - if amHost == "" { - amAddress = viper.GetString("controls.promAlertManager.address") - } else { - amAddress = amHost + ":" + amPort - } + amAddress := amHost + ":" + amPort + amBaseUrl := "api/v2" + amSchemes := []string{"http"} alertParams := alert.NewGetAlertsParams() alertParams.Active = &active alertParams.Inhibited = &inhibited alertParams.Silenced = &silenced alertParams.Unprocessed = &unprocessed - amBaseUrl := viper.GetString("controls.promAlertManager.baseUrl") - amSchemes := []string{viper.GetString("controls.promAlertManager.schemes")} resp, err := newAlertManagerClient(amAddress, amBaseUrl, amSchemes).Alert.GetAlerts(alertParams) if err != nil { - err = fmt.Errorf("GetAlerts from '%s%s' failed with error: %v", amAddress, amBaseUrl, err) + err = fmt.Errorf("GetAlerts from amAddress = %s with amBaseUrl = %s failed with error: %v", amAddress, amBaseUrl, err) } return resp, err } @@ -667,3 +760,10 @@ func newAlertManagerClient(amAddress string, amBaseUrl string, amSchemes []strin return client.New(cr, strfmt.Default) } +func getCurrentDirectory() string { + dir, err := os.Getwd() + if err != nil { + fmt.Println(err) + } + return dir +}