Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add alert trigalert #20

Merged
merged 6 commits into from
Feb 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ _testmain.go
*.exe
*.test
*.prof

# IDE
.idea
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ before_install:
- go get github.com/mattn/goveralls
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
script:
- $HOME/gopath/bin/goveralls -service=travis-ci
- $HOME/gopath/bin/goveralls -service=travis-ci -ignore=sample
76 changes: 75 additions & 1 deletion sample/sample.go → sample/sample.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,68 @@ func randString(n int) string {
}

func main() {
zeus := &Zeus{ApiServ: "http://api.ciscozeus.io", Token: "{Your token}"}
zeus := &Zeus{ApiServ: "https://api.ciscozeus.io", Token: "{Your token}"}

postAlert := Alert{
Alert_name: randString(5),
Username: randString(5),
Token: "databucket",
Alerts_type: "metric",
Alert_expression: "cpu.value > 20",
Alert_severity: "S1",
Metric_name: "cpu.value",
Emails: "blah@blah.com",
Status: "active",
Frequency: 30,
}
fmt.Printf("Test Alerts API with alert_name: %s, username : %s\n", postAlert.Alert_name, postAlert.Username)
successful, err := zeus.PostAlert(postAlert)
fmt.Println("PostAlert: ", successful, err)
if err != nil {
panic("PostAlert is failed")
}

total, alerts, err := zeus.GetAlerts()
fmt.Println("GetAlerts: ", total, alerts, err)
if err != nil {
panic("GetAlerts Failed")
}
postId := alerts[len(alerts)-1].Id
fmt.Printf("(postId: %d)\n", postId)

putAlert := Alert{
Alert_name: randString(5),
Username: randString(5),
Token: "databucket",
Alerts_type: "metric",
Alert_expression: "cpu.value > 20",
Alert_severity: "S1",
Metric_name: "cpu.value",
Emails: "blah@blah.com",
Status: "active",
Frequency: 32,
}
successful, err = zeus.PutAlert(postId, putAlert)
if err != nil {
panic("PutAlert is failed")
} else if successful != 1 {
panic("PutAlert is failed (HTTP-request is succeeded)")
}
fmt.Println("PostAlert: ", successful, err)
fmt.Printf("The Alert is changed to alert_name: %s, username : %s\n", putAlert.Alert_name, putAlert.Username)

alert, err := zeus.GetAlert(postId)
if err != nil {
panic("GetAlert is failed")
}
fmt.Println("GetAlert: ", alert, err)

successful, err = zeus.DeleteAlert(postId)
if err != nil {
panic("DeleteAelrt is failed")
} else if successful != 1 {
panic("DeleteAlert is failed (HTTP-request is succeeded)")
}

logs := LogList{
Name: randString(5),
Expand Down Expand Up @@ -69,6 +130,7 @@ func main() {
}
fmt.Printf("sent 2 metrics, %d successful\n", suc)


fmt.Println("\nsleep for 20 seconds")
time.Sleep(20 * time.Second)
name, err := zeus.GetMetricNames(metrics.Name, 0, 0)
Expand All @@ -89,4 +151,16 @@ func main() {
panic("failed to delete one series")
}
fmt.Println("deleted")

trigalert, err := zeus.GetTrigalert()
fmt.Println("GetTrigalert: ", trigalert, err)
if err != nil {
panic("GetTrigalert is failed")
}

trigalert, err = zeus.GetTrigalertLast24()
fmt.Println("GetTrigalertLast24: ", trigalert, err)
if err != nil {
panic("GetTrigalertLast24 is failed")
}
}
226 changes: 223 additions & 3 deletions zeus.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,58 @@ import (
"strings"
)

// Alert contains properties of a alert in a key-value way
type Alert struct {
Id int64 `json:"id"`
Alert_name string `json:"alert_name"`
Created string `json:"created"`
Username string `json:"username"`
Token string `json:"token"`
Alerts_type string `json:"alerts_type"`
Alert_expression string `json:"alert_expression"`
Alert_severity string `json:"alert_severity"`
Metric_name string `json:"metric_name"`
Emails string `json:"emails"`
Status string `json:"status"`
Frequency float64 `json:"frequency"`
Last_updated string `json:"last_updated"`
}

func setAlertToUrlValues(alert Alert, data *url.Values) (errString string){
if len(alert.Alert_name) > 0 {
(*data).Add("alert_name", alert.Alert_name)
} else {
return "Alert_name is required"
}
if len(alert.Username) > 0 {
(*data).Add("username", alert.Username)
}
if len(alert.Alerts_type) > 0 {
(*data).Add("alerts_type", alert.Alerts_type)
}
if len(alert.Alert_expression) > 0 {
(*data).Add("alert_expression", alert.Alert_expression)
} else {
return "Alert_expression is required"
}
if len(alert.Alert_severity) > 0 {
(*data).Add("alert_severity", alert.Alert_severity)
}
if len(alert.Metric_name) > 0 {
(*data).Add("metric_name", alert.Metric_name)
}
if len(alert.Emails) > 0 {
(*data).Add("emails", alert.Emails)
}
if len(alert.Status) > 0 {
(*data).Add("status", alert.Status)
}
if alert.Frequency > 0 {
(*data).Add("frequency", strconv.FormatFloat(alert.Frequency, 'f', 6, 64))
}
return ""
}

// Log contains properties of a log in a key-value way
// Note that Zeus doesn't support nested json, the value has to be string or
// number.
Expand Down Expand Up @@ -134,7 +186,7 @@ func buildUrl(urls ...string) string {
}

func (zeus *Zeus) request(method, urlStr string, data *url.Values) (
body []byte, status int, err error) {
body []byte, status int, err error) {
if data == nil {
data = &url.Values{}
}
Expand All @@ -143,8 +195,15 @@ func (zeus *Zeus) request(method, urlStr string, data *url.Values) (
resp, err = http.PostForm(urlStr, *data)
} else if method == "GET" {
resp, err = http.Get(urlStr + "?" + data.Encode())
} else if method == "PUT" {
req, err := http.NewRequest("PUT", urlStr, strings.NewReader(data.Encode()))
if err != nil {
return []byte{}, 0, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err = http.DefaultClient.Do(req)
} else if method == "DELETE" {
req, err := http.NewRequest("DELETE", urlStr, nil)
req, err := http.NewRequest("DELETE", urlStr, strings.NewReader(data.Encode()))
if err != nil {
return []byte{}, 0, err
}
Expand All @@ -163,6 +222,121 @@ func (zeus *Zeus) request(method, urlStr string, data *url.Values) (
return
}

// PostAlert sends a alert.
// It returns number of successfully sent logs or an error.
func (zeus *Zeus) PostAlert(alert Alert) (successful int, err error) {
if len(zeus.Token) == 0 {
return 0, errors.New("API token is empty")
}
urlStr := buildUrl(zeus.ApiServ, "alerts", zeus.Token)

data := make(url.Values)
errString := setAlertToUrlValues(alert, &data)
if errString != "" {
return 0, err
}

_, status, err := zeus.request("POST", urlStr, &data)
if err != nil {
return 0, err
}
if status == 201 {
successful = 1
}

return
}

// GetAlerts returns list of alert
func (zeus *Zeus) GetAlerts() (total int, alerts []Alert, err error) {
if len(zeus.Token) == 0 {
return 0, []Alert{}, errors.New("API token is empty")
}
urlStr := buildUrl(zeus.ApiServ, "alerts", zeus.Token)
data := make(url.Values)

body, status, err := zeus.request("GET", urlStr, &data)
if err != nil {
return 0, []Alert{}, err
}

if status == 200 {
if err := json.Unmarshal(body, &alerts); err != nil {
return 0, []Alert{}, err
}
total = len(alerts)
} else if status == 400 {
return 0, []Alert{}, errors.New("Bad request")
}
return
}

// PutAlert update alert which is specified with id
func (zeus *Zeus) PutAlert(id int64, alert Alert) (successful int, err error) {
if len(zeus.Token) == 0 {
return 0, errors.New("API token is empty")
}
urlStr := buildUrl(zeus.ApiServ, "alerts", zeus.Token, strconv.FormatInt(id, 10))

data := make(url.Values)
errString := setAlertToUrlValues(alert, &data)
if errString != "" {
return 0, err
}

_, status, err := zeus.request("PUT", urlStr, &data)
if err != nil {
return 0, err
}
if status == 200 {
successful = 1
}

return
}

// GetAlert returns a alert by id
func (zeus *Zeus) GetAlert(id int64) (alert Alert, err error) {
if len(zeus.Token) == 0 {
return Alert{}, errors.New("API token is empty")
}
urlStr := buildUrl(zeus.ApiServ, "alerts", zeus.Token, strconv.FormatInt(id, 10))

data := make(url.Values)
body, status, err := zeus.request("GET", urlStr, &data)
if err != nil {
return Alert{}, err
}

if status == 200 {
if err := json.Unmarshal(body, &alert); err != nil {
return Alert{}, err
}
} else if status == 400 {
return Alert{}, errors.New("Bad request")
}
return
}

// DeleteAlert delete a alert which is specified with id
func (zeus *Zeus) DeleteAlert(id int64) (successful int, err error) {
if len(zeus.Token) == 0 {
return 0, errors.New("API token is empty")
}
urlStr := buildUrl(zeus.ApiServ, "alerts", zeus.Token, strconv.FormatInt(id, 10))
data := make(url.Values)

_, status, err := zeus.request("DELETE", urlStr, &data)
if err != nil {
return 0, err
}
if status == 204 {
successful = 1
}

return
}

// GetLogs returns a list of logs that math given constrains. logName is the
// name(or category) of the log. Pattern is a expression to match given log
// field. From and to are the starting and ending timestamp of logs in unix
Expand All @@ -171,7 +345,7 @@ func (zeus *Zeus) request(method, urlStr string, data *url.Values) (
// worry, limit(10 by default) controls the up limit of number of logs
// returned. Please use offset and limit to get the rest logs.
func (zeus *Zeus) GetLogs(logName, field, pattern string, from, to int64,
offset, limit int) (total int, logs LogList, err error) {
offset, limit int) (total int, logs LogList, err error) {
if len(zeus.Token) == 0 {
return 0, LogList{}, errors.New("API token is empty")
}
Expand Down Expand Up @@ -405,3 +579,49 @@ func (zeus *Zeus) DeleteMetrics(metricName string) (bool, error) {
}
return false, nil
}

// GetTrigalert returns a trigalert
func (zeus *Zeus) GetTrigalert() (trigalert map[string]interface{}, err error) {
if len(zeus.Token) == 0 {
return map[string]interface{}{}, errors.New("API token is empty")
}
urlStr := buildUrl(zeus.ApiServ, "trigalerts", zeus.Token)

data := make(url.Values)
body, status, err := zeus.request("GET", urlStr, &data)
if err != nil {
return map[string]interface{}{}, err
}

if status == 200 {
if err := json.Unmarshal(body, &trigalert); err != nil {
return map[string]interface{}{}, err
}
} else if status == 400 {
return map[string]interface{}{}, errors.New("Bad request")
}
return
}

// GetTrigalert returns a trigalert of last24
func (zeus *Zeus) GetTrigalertLast24() (trigalert map[string]interface{}, err error) {
if len(zeus.Token) == 0 {
return map[string]interface{}{}, errors.New("API token is empty")
}
urlStr := buildUrl(zeus.ApiServ, "trigalerts", zeus.Token, "last24")

data := make(url.Values)
body, status, err := zeus.request("GET", urlStr, &data)
if err != nil {
return map[string]interface{}{}, err
}

if status == 200 {
if err := json.Unmarshal(body, &trigalert); err != nil {
return map[string]interface{}{}, err
}
} else if status == 400 {
return map[string]interface{}{}, errors.New("Bad request")
}
return
}
Loading