Created
October 13, 2015 23:28
-
-
Save griggheo/c9362b2524499af44cf9 to your computer and use it in GitHub Desktop.
Golang program which integrates Pingdom checks into a Cachet status page
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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{})) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey, great script, how could I integrate get golang working on an ubuntu 14.04 box and get this working? Chris