Skip to content

Instantly share code, notes, and snippets.

@griggheo
Created October 13, 2015 23:28
Show Gist options
  • Save griggheo/c9362b2524499af44cf9 to your computer and use it in GitHub Desktop.
Save griggheo/c9362b2524499af44cf9 to your computer and use it in GitHub Desktop.
Golang program which integrates Pingdom checks into a Cachet status page
package main
import (
"github.com/russellcardullo/go-pingdom/pingdom"
"fmt"
"time"
)
const PINGDOM_USERNAME="xxxx"
const PINGDOM_PASS="xxxx"
const PINGDOM_API_KEY="xxxx"
const CACHET_API_KEY="xxxx"
const CACHET_INCIDENT_URL="https://status.mycompany.com/api/v1/incidents"
const CACHET_COMPONENT_URL="https://status.mycompany.com/api/v1/components"
const COMPONENT_OPERATIONAL = "1"
const COMPONENT_PERF_ISSUES = "2"
const COMPONENT_PARTIAL_OUTAGE = "3"
const COMPONENT_MAJOR_OUTAGE = "4"
const INCIDENT_SCHEDULED = "0"
const INCIDENT_INVESTIGATING = "1"
const INCIDENT_IDENTIFIED = "2"
const INCIDENT_WATCHING = "3"
const INCIDENT_FIXED = "4"
type CachetIncidentDetails struct {
Name string
Message string
Status string
ComponentID string
}
func list_pingdom_checks(client *pingdom.Client) {
checks, _ := client.Checks.List()
for _, check := range(checks) {
fmt.Println(check)
}
}
func get_pingdom_check_details(client *pingdom.Client, check_id int) (string, string, string) {
check_details, err := client.Checks.Read(check_id)
if err != nil {
fmt.Println(err)
return "", "", ""
}
/*
fmt.Println("ID:", check_details.ID)
fmt.Println("Name:", check_details.Name)
fmt.Println("Resolution:", check_details.Resolution)
fmt.Println("Created:", time.Unix(check_details.Created, 0))
fmt.Println("Hostname:", check_details.Hostname)
fmt.Println("Status:", check_details.Status)
fmt.Println("LastErrorTime:", time.Unix(check_details.LastErrorTime, 0))
fmt.Println("LastTestTime:", time.Unix(check_details.LastTestTime, 0))
fmt.Println("LastResponseTime:", check_details.LastResponseTime)
fmt.Println("Paused:", check_details.Paused)
fmt.Println("ContactIds:", check_details.ContactIds)
*/
hostname := check_details.Hostname
status := check_details.Status
message := fmt.Sprintf("LastErrorTime: %v\nLastTestTime: %v\n",
time.Unix(check_details.LastErrorTime, 0),
time.Unix(check_details.LastTestTime, 0))
return hostname, status, message
}
func get_cachet_component_status(component_id string) string {
url := fmt.Sprintf("%s/%s", CACHET_COMPONENT_URL, component_id)
token := CACHET_API_KEY
fmt.Printf("Sending request to %s\n", url)
status_code, json_data := send_http_req_query_string("GET", url, token, nil)
if status_code != 200 {
return ""
}
component_status := get_nested_item_property(json_data, "data", "status")
return component_status
}
func update_cachet_component_status(component_id, status string ) (int, map[string]interface{}) {
url := fmt.Sprintf("%s/%s", CACHET_COMPONENT_URL, component_id)
token := CACHET_API_KEY
fmt.Printf("Sending request to %s\n", url)
payload := map[string]string{
"id": component_id,
"status": status,
}
print_request(payload)
status_code, json_data := send_http_req_json_body("PUT", url, token, payload)
//print_response(status_code, json_data)
return status_code, json_data
}
func create_cachet_incident(details *CachetIncidentDetails ) (int, map[string]interface{}) {
url := CACHET_INCIDENT_URL
token := CACHET_API_KEY
fmt.Printf("Sending request to %s\n", url)
payload := map[string]string{
"name": details.Name,
"message": details.Message,
"visible": "1",
"status": details.Status,
"component_id": details.ComponentID,
}
print_request(payload)
status_code, json_data := send_http_req_json_body("POST", url, token, payload)
//print_response(status_code, json_data)
return status_code, json_data
}
func main() {
cachet_to_pingdom := map[string]int {
"1": 1783706,
}
for component_id, check_id := range cachet_to_pingdom {
component_status := get_cachet_component_status(component_id)
client := pingdom.NewClient(PINGDOM_USERNAME, PINGDOM_PASS, PINGDOM_API_KEY)
hostname, status, message := get_pingdom_check_details(client, check_id)
new_incident_status := INCIDENT_INVESTIGATING
updated_component_status := COMPONENT_OPERATIONAL
var incident_name string
if status == "down" {
new_incident_status = INCIDENT_IDENTIFIED
updated_component_status = COMPONENT_PARTIAL_OUTAGE
incident_name = fmt.Sprintf("Incident identified for %s", hostname)
}
if status == "up" {
if component_status == COMPONENT_OPERATIONAL {
fmt.Println("Component operational...skipping incident fixed status update")
continue
}
new_incident_status = INCIDENT_FIXED
incident_name = fmt.Sprintf("Incident fixed for %s", hostname)
}
status_code, json_data := update_cachet_component_status(component_id, updated_component_status)
print_response(status_code, json_data)
details := CachetIncidentDetails{
Name: incident_name,
Message: message,
Status: new_incident_status,
ComponentID: component_id,
}
status_code, json_data = create_cachet_incident(&details)
print_response(status_code, json_data)
}
}
package main
import (
"encoding/json"
"reflect"
"strings"
"fmt"
"github.com/levigross/grequests"
)
func _http_response(req_type, url string, ro *grequests.RequestOptions, resp *grequests.Response) (int, map[string]interface{}) {
switch req_type {
case "POST":
resp, _ = grequests.Post(url, ro)
case "PUT":
resp, _ = grequests.Put(url, ro)
case "PATCH":
resp, _ = grequests.Patch(url, ro)
case "DELETE":
resp, _ = grequests.Delete(url, ro)
case "GET":
resp, _ = grequests.Get(url, ro)
default:
fmt.Printf("HTTP method %s not recognized\n", req_type)
return 0, nil
}
fmt.Printf("Sending HTTP %s request to: %s\n", req_type, url)
var json_data map[string]interface{}
status_code := resp.StatusCode
err := resp.JSON(&json_data)
if err != nil {
fmt.Println("Unable to coerce to JSON", err)
return 0, nil
}
return status_code, json_data
}
func send_http_req_json_body(req_type, url, token string, json_body interface{}) (int, map[string]interface{}) {
ro := &grequests.RequestOptions{}
if json_body != nil {
ro.JSON = json_body
}
ro.Headers = map[string]string{"X-Cachet-Token":token}
var resp *grequests.Response
return _http_response(req_type, url, ro, resp)
}
func send_http_req_query_string(req_type, url, token string, query_string map[string]string) (int, map[string]interface{}) {
ro := &grequests.RequestOptions{}
ro.Headers = map[string]string{"X-Cachet-Token":token}
if query_string != nil {
ro.Params = query_string
}
var resp *grequests.Response
return _http_response(req_type, url, ro, resp)
}
func print_request(payload map[string]string) {
fmt.Println("HTTP request payload:")
PprintJsonMapString(payload)
}
func print_request_nested(payload map[string]interface{}) {
fmt.Println("HTTP request payload:")
PprintJsonMap(payload)
fmt.Println("*********************************************************")
}
func print_response(status_code int, json_data map[string]interface{}) {
fmt.Println("HTTP status code:", status_code)
fmt.Println("HTTP response:")
PprintJsonMap(json_data)
fmt.Println("*********************************************************")
}
func get_nested_item_property(json_data map[string]interface{}, item_name, item_property string) string {
item := json_data[item_name]
prop := item.(map[string]interface{})[item_property]
return prop.(string)
}
func get_item_property_from_list(json_data map[string]interface{}, list_name, item_property string, item_index int) string {
item_list := json_data[list_name]
//fmt.Println(reflect.TypeOf(item_list))
item := item_list.([]interface{})[item_index]
//fmt.Println(reflect.TypeOf(item))
prop := item.(map[string]interface{})[item_property]
return prop.(string)
}
func get_item_list_length(json_data map[string]interface{}, list_name string) int {
item_list := json_data[list_name]
return len(item_list.([]interface{}))
}
@taylorcam
Copy link

Hey, great script, how could I integrate get golang working on an ubuntu 14.04 box and get this working? Chris

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment