"net/http"
"os"
"strconv"
+ "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"
- "sync"
)
type CliAlarmDefinitions struct {
AlarmObjects []*alarm.Alarm `json:"alarmobjects"`
}
+type AlarmNotification struct {
+ alarm.AlarmMessage
+ alarm.AlarmDefinition
+}
+
var CLIPerfAlarmObjects map[int]*alarm.Alarm
var wg sync.WaitGroup
)
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.
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").
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").
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").
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").
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)
})
+}
- // parse command-line arguments
- commando.Parse(nil)
+func registerAlertCmd(alertManagerHost string) {
+ // Get alerts from Prometheus Alert Manager
+ commando.
+ 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, alertManagerHost).
+ AddFlag("port", "Prometheus Alert Manager port", commando.String, "9093").
+ SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
+ displayAlerts(flags)
+ })
}
func readAlarmParams(flags map[string]commando.FlagValue, clear bool) (a alarm.Alarm) {
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)
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},
+ })
+ }
}
}
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
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)
} else {
fmt.Println("reading performance alarm definitions from json file failed ")
}
-
}
func peakPerformanceTest(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{}
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{}
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)
}
}
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
}
}
}
+
+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 {
+ fmt.Println(err)
+ return
+ }
+
+ if resp == nil {
+ fmt.Println("resp= nil")
+ return
+ }
+
+ t := table.NewWriter()
+ t.SetOutputMirror(os.Stdout)
+ t.AppendHeader(table.Row{"Alerts from Prometheus Alert Manager"})
+ 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()
+ silenced, _ := flags["silenced"].GetBool()
+ unprocessed, _ := flags["unprocessed"].GetBool()
+ amHost, _ := flags["host"].GetString()
+ amPort, _ := flags["port"].GetString()
+ amAddress := amHost + ":" + amPort
+ amBaseUrl := "api/v2"
+ amSchemes := []string{"http"}
+
+ alertParams := alert.NewGetAlertsParams()
+ alertParams.Active = &active
+ alertParams.Inhibited = &inhibited
+ alertParams.Silenced = &silenced
+ alertParams.Unprocessed = &unprocessed
+ resp, err := newAlertManagerClient(amAddress, amBaseUrl, amSchemes).Alert.GetAlerts(alertParams)
+ if err != nil {
+ err = fmt.Errorf("GetAlerts from amAddress = %s with amBaseUrl = %s failed with error: %v", amAddress, amBaseUrl, err)
+ }
+ return resp, err
+}
+
+func newAlertManagerClient(amAddress string, amBaseUrl string, amSchemes []string) *client.AlertmanagerAPI {
+ cr := clientruntime.New(amAddress, amBaseUrl, amSchemes)
+ return client.New(cr, strfmt.Default)
+}
+
+func getCurrentDirectory() string {
+ dir, err := os.Getwd()
+ if err != nil {
+ fmt.Println(err)
+ }
+ return dir
+}