diff --git a/nagios/nagios/nagios2opsgenie.go b/nagios/nagios/nagios2opsgenie.go index 1df9114..ef19934 100644 --- a/nagios/nagios/nagios2opsgenie.go +++ b/nagios/nagios/nagios2opsgenie.go @@ -1,65 +1,51 @@ package main import ( + "bufio" "bytes" + "crypto/tls" "encoding/json" "flag" - "net/http" + "fmt" + "io" + "io/ioutil" "net" - "time" + "net/http" + "net/url" "os" - "bufio" - "strings" - "io" "strconv" - "github.com/alexcesaro/log/golog" + "strings" + "time" + "github.com/alexcesaro/log" - "fmt" - "io/ioutil" - "crypto/tls" - "net/url" + "github.com/alexcesaro/log/golog" ) -var NAGIOS_SERVER = "default" +var VERSION = "1.1" var API_KEY = "" var TOTAL_TIME = 60 -var configParameters = map[string]string{"apiKey": API_KEY, - "nagios_server": NAGIOS_SERVER, - "nagios2opsgenie.logger":"warning", - "opsgenie.api.url":"https://api.opsgenie.com" , - "nagios2opsgenie.http.proxy.enabled" : "false", - "nagios2opsgenie.http.proxy.port" : "1111", - "nagios2opsgenie.http.proxy.host": "localhost", - "nagios2opsgenie.http.proxy.protocol":"http", +var configParameters = map[string]string{ + "apiKey": API_KEY, + "nagios_server": "", + "nagios2opsgenie.logger": "warning", + "opsgenie.api.url": "https://api.opsgenie.com", + "nagios2opsgenie.http.proxy.enabled": "false", + "nagios2opsgenie.http.proxy.port": "1111", + "nagios2opsgenie.http.proxy.host": "localhost", + "nagios2opsgenie.http.proxy.protocol": "http", "nagios2opsgenie.http.proxy.username": "", "nagios2opsgenie.http.proxy.password": ""} var parameters = make(map[string]string) var configPath = "/etc/opsgenie/conf/opsgenie-integration.conf" -var levels = map [string]log.Level{"info":log.Info,"debug":log.Debug,"warning":log.Warning,"error":log.Error} +var levels = map[string]log.Level{"info": log.Info, "debug": log.Debug, "warning": log.Warning, "error": log.Error} var logger log.Logger func main() { - configFile, err := os.Open(configPath) - if err == nil{ - readConfigFile(configFile) - }else{ - panic(err) - } - - version := flag.String("v","","") - parseFlags() - - logger = configureLogger() - printConfigToLog() - - if *version != ""{ - fmt.Println("Version: 1.1") - return - } + parseFlags_readConfig_setupLogging() if parameters["notification_type"] == "" { if logger != nil { - logger.Warning("Stopping, Nagios NOTIFICATIONTYPE param has no value, please make sure your Nagios and OpsGenie files pass necessary parameters") + logger.Error("Stopping, Nagios NOTIFICATIONTYPE param has no value, please make sure your Nagios and OpsGenie files pass necessary parameters") } return @@ -68,9 +54,9 @@ func main() { http_post() } -func printConfigToLog(){ +func printConfigToLog() { if logger != nil { - if (logger.LogDebug()) { + if logger.LogDebug() { logger.Debug("Config:") for k, v := range configParameters { if strings.Contains(k, "password") { @@ -83,19 +69,19 @@ func printConfigToLog(){ } } -func readConfigFile(file io.Reader){ +func readConfigFile(file io.Reader) { scanner := bufio.NewScanner(file) - for scanner.Scan(){ + for scanner.Scan() { line := scanner.Text() line = strings.TrimSpace(line) - if !strings.HasPrefix(line,"#") && line != "" { - l := strings.SplitN(line,"=",2) + if !strings.HasPrefix(line, "#") && line != "" { + l := strings.SplitN(line, "=", 2) l[0] = strings.TrimSpace(l[0]) l[1] = strings.TrimSpace(l[1]) - configParameters[l[0]]=l[1] - if l[0] == "nagios2opsgenie.timeout"{ - TOTAL_TIME,_ = strconv.Atoi(l[1]) + configParameters[l[0]] = l[1] + if l[0] == "nagios2opsgenie.timeout" { + TOTAL_TIME, _ = strconv.Atoi(l[1]) } } } @@ -104,7 +90,7 @@ func readConfigFile(file io.Reader){ } } -func configureLogger ()log.Logger{ +func configureLogger() log.Logger { level := configParameters["nagios2opsgenie.logger"] var logFilePath = parameters["logPath"] @@ -117,9 +103,9 @@ func configureLogger ()log.Logger{ file, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { - fmt.Println("Could not create log file \"" + logFilePath + "\", will log to \"/tmp/nagios2opsgenie.log\" file. Error: ", err) + fmt.Println("Could not create log file \""+logFilePath+"\", will log to \"/tmp/nagios2opsgenie.log\" file. Error: ", err) - fileTmp, errTmp := os.OpenFile("/tmp/nagios2opsgenie.log", os.O_CREATE | os.O_WRONLY | os.O_APPEND, 0666) + fileTmp, errTmp := os.OpenFile("/tmp/nagios2opsgenie.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if errTmp != nil { fmt.Println("Logging disabled. Reason: ", errTmp) @@ -133,7 +119,7 @@ func configureLogger ()log.Logger{ return tmpLogger } -func getHttpClient (timeout int) *http.Client { +func getHttpClient(timeout int) *http.Client { seconds := (TOTAL_TIME / 12) * 2 * timeout var proxyEnabled = configParameters["nagios2opsgenie.http.proxy.enabled"] var proxyHost = configParameters["nagios2opsgenie.http.proxy.host"] @@ -143,14 +129,13 @@ func getHttpClient (timeout int) *http.Client { var proxyPassword = configParameters["nagios2opsgenie.http.proxy.password"] proxy := http.ProxyFromEnvironment - if proxyEnabled == "true" { u := new(url.URL) u.Scheme = scheme - u.Host = proxyHost + ":" + proxyPort + u.Host = proxyHost + ":" + proxyPort if len(proxyUsername) > 0 { - u.User = url.UserPassword(proxyUsername,proxyPassword) + u.User = url.UserPassword(proxyUsername, proxyPassword) } if logger != nil { @@ -160,10 +145,10 @@ func getHttpClient (timeout int) *http.Client { } client := &http.Client{ Transport: &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify : true}, - Proxy: proxy, + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + Proxy: proxy, Dial: func(netw, addr string) (net.Conn, error) { - conn, err := net.DialTimeout(netw, addr, time.Second * time.Duration(seconds)) + conn, err := net.DialTimeout(netw, addr, time.Second*time.Duration(seconds)) if err != nil { if logger != nil { logger.Error("Error occurred while connecting: ", err) @@ -178,30 +163,29 @@ func getHttpClient (timeout int) *http.Client { return client } -func http_post() { +func http_post() { var logPrefix = "" - if parameters["entity_type"] == "host"{ - logPrefix = "[HostName: "+ parameters["host_name"] + ", HostState: "+ parameters["host_state"] +"]" - }else{ - logPrefix = "[HostName: "+ parameters["host_name"] + ", ServiceDesc: "+ parameters["service_desc"] + ", ServiceState: " + parameters["service_state"] +"]" + if parameters["entity_type"] == "host" { + logPrefix = "[HostName: " + parameters["host_name"] + ", HostState: " + parameters["host_state"] + "]" + } else { + logPrefix = "[HostName: " + parameters["host_name"] + ", ServiceDesc: " + parameters["service_desc"] + ", ServiceState: " + parameters["service_state"] + "]" } apiUrl := configParameters["opsgenie.api.url"] + "/v1/json/nagios" viaMaridUrl := configParameters["viaMaridUrl"] target := "" - if viaMaridUrl != ""{ + if viaMaridUrl != "" { apiUrl = viaMaridUrl target = "Marid" - }else{ + } else { target = "OpsGenie" } if logger != nil { logger.Debug("URL: ", apiUrl) - logger.Debug("Data to be posted:") - logger.Debug(parameters) + logger.Debug("Data to be posted:", parameters) } var buf, _ = json.Marshal(parameters) @@ -211,52 +195,55 @@ func http_post() { client := getHttpClient(i) if logger != nil { - logger.Debug(logPrefix + "Trying to send data to OpsGenie with timeout: ", (TOTAL_TIME / 12) * 2 * i) + logger.Debug(logPrefix+" Trying to send data to OpsGenie with timeout: ", (TOTAL_TIME/12)*2*i) } resp, error := client.Do(request) if error == nil { defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) - if err == nil{ - if resp.StatusCode == 200{ + if err == nil { + if resp.StatusCode == 200 { if logger != nil { - logger.Debug(logPrefix + " Response code: " + strconv.Itoa(resp.StatusCode)) - logger.Debug(logPrefix + "Response: " + string(body[:])) - logger.Info(logPrefix + "Data from Nagios posted to " + target + " successfully") } - }else{ + logger.Debug(logPrefix + " Response code: " + strconv.Itoa(resp.StatusCode) + ", Response Body: " + string(body[:])) + logger.Info(logPrefix + " Data from Nagios posted to " + target + " successfully") + } + } else { if logger != nil { - logger.Error(logPrefix + "Couldn't post data from Nagios to " + target + " successfully; Response code: " + strconv.Itoa(resp.StatusCode) + " Response Body: " + string(body[:])) + logger.Error(logPrefix + " Couldn't post data from Nagios to " + target + "; Response code: " + strconv.Itoa(resp.StatusCode) + ", Response Body: " + string(body[:])) } } - }else{ + } else { if logger != nil { - logger.Error(logPrefix + "Couldn't read the response from " + target, err) + logger.Error(logPrefix+" Couldn't read the response from "+target, err) } } break - }else if i < 3 { + } else if i < 3 { if logger != nil { - logger.Error(logPrefix + "Error occurred while sending data, will retry.", error) + logger.Error(logPrefix+" Error occurred while sending data, will retry.", error) } - }else { + } else { if logger != nil { - logger.Error(logPrefix + "Failed to post data from Nagios. ", error) + logger.Error(logPrefix+" Failed to post data from Nagios.", error) } } - if resp != nil{ + if resp != nil { defer resp.Body.Close() } } } -func parseFlags()map[string]string{ - apiKey := flag.String("apiKey","","api key") - nagiosServer := flag.String("ns","","nagios server") +func parseFlags_readConfig_setupLogging() { + version := flag.String("v", "", "") + configfile := flag.String("c", "", "Configuration file") + + apiKey := flag.String("apiKey", "", "api key") + nagiosServer := flag.String("ns", "", "nagios server") - entityType := flag.String("entityType","","") + entityType := flag.String("entityType", "", "") - notificationType := flag.String("t", "","NOTIFICATIONTYPE") + notificationType := flag.String("t", "", "NOTIFICATIONTYPE") longDateTime := flag.String("ldt", "", "LONGDATETIME") hostName := flag.String("hn", "", "HOSTNAME") @@ -265,21 +252,21 @@ func parseFlags()map[string]string{ hostAddress := flag.String("haddr", "", "HOSTADDRESS") hostState := flag.String("hs", "", "HOSTSTATE") hostStateId := flag.String("hsi", "", "HOSTSTATEID") - lastHostState := flag.String("lhs","","LASTHOSTSTATE") - lastHostStateId := flag.String("lhsi","","LASTHOSTSTATEID") - hostStateType := flag.String("hst","","HOSTSTATETYPE") + lastHostState := flag.String("lhs", "", "LASTHOSTSTATE") + lastHostStateId := flag.String("lhsi", "", "LASTHOSTSTATEID") + hostStateType := flag.String("hst", "", "HOSTSTATETYPE") hostAttempt := flag.String("ha", "", "HOSTATTEMPT") maxHostAttempts := flag.String("mha", "", "MAXHOSTATTEMPTS") - hostEventId := flag.String("hei","","HOSTEVENTID") - lastHostEventId := flag.String("lhei","","LASTHOSTEVENTID") - hostProblemId := flag.String("hpi","","HOSTPROBLEMID") - lastHostProblemId := flag.String("lhpi","","LASTHOSTPROBLEMID") + hostEventId := flag.String("hei", "", "HOSTEVENTID") + lastHostEventId := flag.String("lhei", "", "LASTHOSTEVENTID") + hostProblemId := flag.String("hpi", "", "HOSTPROBLEMID") + lastHostProblemId := flag.String("lhpi", "", "LASTHOSTPROBLEMID") hostLatency := flag.String("hl", "", "HOSTLATENCY") - hostExecutionTime := flag.String ("het","","HOSTEXECUTIONTIME") + hostExecutionTime := flag.String("het", "", "HOSTEXECUTIONTIME") hostDuration := flag.String("hd", "", "HOSTDURATION") hostDurationSec := flag.String("hds", "", "HOSTDURATIONSEC") - hostDownTime := flag.String("hdt","","HOSTDOWNTIME") - hostPercentChange := flag.String("hpc","","HOSTPERCENTCHANGE") + hostDownTime := flag.String("hdt", "", "HOSTDOWNTIME") + hostPercentChange := flag.String("hpc", "", "HOSTPERCENTCHANGE") hostGroupName := flag.String("hgn", "", "HOSTGROUPNAME") hostGroupNames := flag.String("hgns", "", "HOSTGROUPNAMES") lastHostCheck := flag.String("lhc", "", "LASTHOSTCHECK") @@ -293,7 +280,7 @@ func parseFlags()map[string]string{ hostPerfData := flag.String("hpd", "", "HOSTPERFDATA") serviceDesc := flag.String("s", "", "SERVICEDESC") - serviceDisplayName := flag.String("sdn","","SERVICEDISPLAYNAME") + serviceDisplayName := flag.String("sdn", "", "SERVICEDISPLAYNAME") serviceState := flag.String("ss", "", "SERVICESTATE") serviceStateId := flag.String("ssi", "", "SERVICESTATEID") lastServiceState := flag.String("lss", "", "LASTSERVICESTATE") @@ -301,63 +288,103 @@ func parseFlags()map[string]string{ serviceStateType := flag.String("sst", "", "SERVICESTATETYPE") serviceAttempt := flag.String("sa", "", "SERVICEATTEMPT") maxServiceAttempts := flag.String("msa", "", "MAXSERVICEATTEMPTS") - serviceIsVolatile := flag.String("siv","","SERVICEISVOLATILE") - serviceEventId := flag.String("sei","","SERVICEEVENTID") - lastServiceEventId := flag.String("lsei","","LASTSERVICEEVENTID") - serviceProblemId := flag.String("spi","","SERVICEPROBLEMID") - lastServiceProblemId := flag.String("lspi","","LASTSERVICEPROBLEMID") + serviceIsVolatile := flag.String("siv", "", "SERVICEISVOLATILE") + serviceEventId := flag.String("sei", "", "SERVICEEVENTID") + lastServiceEventId := flag.String("lsei", "", "LASTSERVICEEVENTID") + serviceProblemId := flag.String("spi", "", "SERVICEPROBLEMID") + lastServiceProblemId := flag.String("lspi", "", "LASTSERVICEPROBLEMID") serviceLatency := flag.String("sl", "", "SERVICELATENCY") - serviceExecutionTime := flag.String("set","","SERVICEEXECUTIONTIME") + serviceExecutionTime := flag.String("set", "", "SERVICEEXECUTIONTIME") serviceDuration := flag.String("sd", "", "SERVICEDURATION") serviceDurationSec := flag.String("sds", "", "SERVICEDURATIONSEC") - serviceDownTime := flag.String("sdt","","SERVICEDOWNTIME") - servicePercentChange := flag.String("spc","","SERVICEPERCENTCHANGE") + serviceDownTime := flag.String("sdt", "", "SERVICEDOWNTIME") + servicePercentChange := flag.String("spc", "", "SERVICEPERCENTCHANGE") serviceGroupName := flag.String("sgn", "", "SERVICEGROUPNAME") serviceGroupNames := flag.String("sgns", "", "SERVICEGROUPNAMES") lastServiceCheck := flag.String("lsch", "", "LASTSERVICECHECK") lastServiceStateChange := flag.String("lssc", "", "LASTSERVICESTATECHANGE") - lastServiceOk := flag.String("lsok","","LASTSERVICEOK") - lastServiceWarning := flag.String("lsw","","LASTSERVICEWARNING") - lastServiceUnknown := flag.String("lsu","","LASTSERVICEUNKNOWN") - lastServiceCritical := flag.String("lsc","","LASTSERVICECRITICAL") + lastServiceOk := flag.String("lsok", "", "LASTSERVICEOK") + lastServiceWarning := flag.String("lsw", "", "LASTSERVICEWARNING") + lastServiceUnknown := flag.String("lsu", "", "LASTSERVICEUNKNOWN") + lastServiceCritical := flag.String("lsc", "", "LASTSERVICECRITICAL") serviceOutput := flag.String("so", "", "SERVICEOUTPUT") longServiceOutput := flag.String("lso", "", "LONGSERVICEOUTPUT") serviceNotesUrl := flag.String("snu", "", "SERVICENOTESURL") servicePerfData := flag.String("spd", "", "SERVICEPERFDATA") logPath := flag.String("logPath", "", "LOGPATH") - responders := flag.String("responders","","Responders") - tags := flag.String("tags","","Tags") + responders := flag.String("responders", "", "Responders") + tags := flag.String("tags", "", "Tags") + priority := flag.String("priority", "", "Priority (P1...P5)") + saved_args := os.Args // save the arguments for logging once it is initialized flag.Parse() - if *apiKey != ""{ + if *version != "" { + fmt.Println("Version:", VERSION) + os.Exit(1) + } + + // Need config file parsed before setting up logging + if *configfile != "" { // Override default configfile based on commandline + configPath = *configfile + } + configFile, err := os.Open(configPath) + if err == nil { + readConfigFile(configFile) + } else { + panic(err) + } + + // Logging related commandline options + if *logPath != "" { + parameters["logPath"] = *logPath + } else { + parameters["logPath"] = configParameters["logPath"] + } + + // Logging needed to be setup before parsing further command line options below that could have errors to report + logger = configureLogger() + logger.Info("Invocation:", saved_args[0], `"`+strings.Join(saved_args[1:], `" "`)+`"`) + printConfigToLog() + + // Handle the remaining options from commandline and/or configuration file + if *apiKey != "" { parameters["apiKey"] = *apiKey - }else{ - parameters["apiKey"] = configParameters ["apiKey"] + } else { + parameters["apiKey"] = configParameters["apiKey"] } - if *nagiosServer != ""{ + // Nagios servername precedence: command line > config file > os.Hostname + if *nagiosServer != "" { parameters["nagios_server"] = *nagiosServer - }else{ + } else if configParameters["nagios_server"] != "" { parameters["nagios_server"] = configParameters["nagios_server"] + } else { + thisServerHostname, err := os.Hostname() + if err == nil { + parameters["nagios_server"] = thisServerHostname + } } - if *responders != ""{ + if *responders != "" { parameters["responders"] = *responders - }else{ - parameters["responders"] = configParameters ["responders"] + } else { + parameters["responders"] = configParameters["responders"] } - if *tags != ""{ + if *tags != "" { parameters["tags"] = *tags - }else{ - parameters["tags"] = configParameters ["tags"] + } else { + parameters["tags"] = configParameters["tags"] } - if *logPath != "" { - parameters["logPath"] = *logPath + if *priority == "" { + parameters["priority"] = "" + } else if IsValidPriority(*priority) { + parameters["priority"] = *priority } else { - parameters["logPath"] = configParameters["logPath"] + logger.Warning("Priority is not valid, needs to be one of P1, P2, P3, P4, P5.") + parameters["priority"] = "" } parameters["entity_type"] = *entityType @@ -433,17 +460,23 @@ func parseFlags()map[string]string{ args := flag.Args() for i := 0; i < len(args); i += 2 { - if(len(args)%2 != 0 && i==len(args)-1){ + if len(args)%2 != 0 && i == len(args)-1 { parameters[args[i]] = "" } else { parameters[args[i]] = args[i+1] } } - - return parameters } - - - - +func IsValidPriority(priority string) bool { + switch priority { + case + "P1", + "P2", + "P3", + "P4", + "P5": + return true + } + return false +}