package main
import (
"fmt"
logpkg "log"
"os"
"strconv"
"github.com/DreamItGetIT/statuscake"
"strings"
)
var log *logpkg.Logger
type command func(*statuscake.Client, ...string) error
var commands map[string]command
func init() {
log = logpkg.New(os.Stderr, "", 0)
commands = map[string]command{
"list": cmdList,
"detail": cmdDetail,
"delete": cmdDelete,
"create": cmdCreate,
"update": cmdUpdate,
}
}
func colouredStatus(s string) string {
switch s {
case "Up":
return fmt.Sprintf("\033[0;32m%s\033[0m", s)
case "Down":
return fmt.Sprintf("\033[0;31m%s\033[0m", s)
default:
return s
}
}
func getEnv(name string) string {
v := os.Getenv(name)
if v == "" {
log.Fatalf("`%s` env variable is required", name)
}
return v
}
func cmdList(c *statuscake.Client, args ...string) error {
tt := c.Tests()
tests, err := tt.All()
if err != nil {
return err
}
for _, t := range tests {
var paused string
if t.Paused {
paused = "yes"
} else {
paused = "no"
}
fmt.Printf("* %d: %s\n", t.TestID, colouredStatus(t.Status))
fmt.Printf(" WebsiteName: %s\n", t.WebsiteName)
fmt.Printf(" TestType: %s\n", t.TestType)
fmt.Printf(" Paused: %s\n", paused)
fmt.Printf(" ContactGroup: %s\n", fmt.Sprint(t.ContactGroup))
fmt.Printf(" Uptime: %f\n", t.Uptime)
}
return nil
}
func cmdDetail(c *statuscake.Client, args ...string) error {
if len(args) != 1 {
return fmt.Errorf("command `detail` requires a single argument `TestID`")
}
id, err := strconv.Atoi(args[0])
if err != nil {
return err
}
tt := c.Tests()
t, err := tt.Detail(id)
if err != nil {
return err
}
var paused string
if t.Paused {
paused = "yes"
} else {
paused = "no"
}
fmt.Printf("* %d: %s\n", t.TestID, colouredStatus(t.Status))
fmt.Printf(" WebsiteName: %s\n", t.WebsiteName)
fmt.Printf(" WebsiteURL: %s\n", t.WebsiteURL)
fmt.Printf(" PingURL: %s\n", t.PingURL)
fmt.Printf(" TestType: %s\n", t.TestType)
fmt.Printf(" Paused: %s\n", paused)
fmt.Printf(" ContactGroup: %s\n", fmt.Sprint(t.ContactGroup))
fmt.Printf(" Uptime: %f\n", t.Uptime)
fmt.Printf(" NodeLocations: %s\n", fmt.Sprint(t.NodeLocations))
return nil
}
func cmdDelete(c *statuscake.Client, args ...string) error {
if len(args) != 1 {
return fmt.Errorf("command `delete` requires a single argument `TestID`")
}
id, err := strconv.Atoi(args[0])
if err != nil {
return err
}
return c.Tests().Delete(id)
}
func askString(name string) string {
var v string
fmt.Printf("%s: ", name)
_, err := fmt.Scanln(&v)
if err != nil {
log.Fatal(err)
}
return v
}
func askInt(name string) int {
v := askString(name)
i, err := strconv.Atoi(v)
if err != nil {
log.Fatalf("Invalid number `%s`", v)
}
return i
}
func cmdCreate(c *statuscake.Client, args ...string) error {
websiteName := askString("WebsiteName")
websiteURL := askString("WebsiteURL")
testType := askString("TestType")
checkRate := askInt("CheckRate")
contactGroupString := askString("ContactGroup (comma separated list)")
contactGroup := strings.Split(contactGroupString, ",")
nodeLocationsString := askString("NodeLocations (comma separated list)")
nodeLocations := strings.Split(nodeLocationsString, ",")
t := &statuscake.Test{
WebsiteName: websiteName,
WebsiteURL: websiteURL,
TestType: testType,
CheckRate: checkRate,
NodeLocations: nodeLocations,
ContactGroup: contactGroup,
}
t2, err := c.Tests().Update(t)
if err != nil {
return err
}
fmt.Printf("CREATED: \n%+v\n", t2)
return nil
}
func cmdUpdate(c *statuscake.Client, args ...string) error {
if len(args) != 1 {
return fmt.Errorf("command `update` requires a single argument `TestID`")
}
id, err := strconv.Atoi(args[0])
if err != nil {
return err
}
tt := c.Tests()
t, err := tt.Detail(id)
if err != nil {
return err
}
t.TestID = id
t.WebsiteName = askString(fmt.Sprintf("WebsiteName [%s]", t.WebsiteName))
t.WebsiteURL = askString(fmt.Sprintf("WebsiteURL [%s]", t.WebsiteURL))
t.TestType = askString(fmt.Sprintf("TestType [%s]", t.TestType))
t.CheckRate = askInt(fmt.Sprintf("CheckRate [%d]", t.CheckRate))
contactGroupString := askString("ContactGroup (comma separated list)")
t.ContactGroup = strings.Split(contactGroupString, ",")
nodeLocationsString := askString("NodeLocations (comma separated list)")
t.NodeLocations = strings.Split(nodeLocationsString, ",")
t2, err := c.Tests().Update(t)
if err != nil {
return err
}
fmt.Printf("UPDATED: \n%+v\n", t2)
return nil
}
func usage() {
fmt.Printf("Usage:\n")
fmt.Printf(" %s COMMAND\n", os.Args[0])
fmt.Printf("Available commands:\n")
for k := range commands {
fmt.Printf(" %+v\n", k)
}
}
func main() {
username := getEnv("STATUSCAKE_USERNAME")
apikey := getEnv("STATUSCAKE_APIKEY")
if len(os.Args) < 2 {
usage()
os.Exit(1)
}
var err error
c, err := statuscake.New(statuscake.Auth{Username: username, Apikey: apikey})
if err != nil {
log.Fatal(err)
}
if cmd, ok := commands[os.Args[1]]; ok {
err = cmd(c, os.Args[2:]...)
} else {
err = fmt.Errorf("Unknown command `%s`", os.Args[1])
}
if err != nil {
log.Fatalf("Error running command `%s`: %s", os.Args[1], err.Error())
}
}