-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 292052f
Showing
8 changed files
with
746 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/jinzhu/configor" | ||
) | ||
|
||
type Config struct { | ||
Server struct { | ||
Address string `toml:"address" required:"true"` | ||
Username string `toml:"username" required:"true"` | ||
Password string `toml:"password" required:"true"` | ||
} `toml:"server"` | ||
} | ||
|
||
func NewConfig(path string) (*Config, error) { | ||
config := &Config{} | ||
err := configor.Load(config, path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return config, nil | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/kovetskiy/lorg" | ||
) | ||
|
||
func getLogger(verbosity int) lorg.Logger { | ||
logger := lorg.NewLog() | ||
logger.SetFormat(lorg.NewFormat("${level:[%s]:left:true} %s")) | ||
if verbosity == 1 { | ||
logger.SetLevel(lorg.LevelDebug) | ||
} else if verbosity == 2 { | ||
logger.SetLevel(lorg.LevelTrace) | ||
} | ||
|
||
return logger | ||
} | ||
|
||
func fatalf(format string, values ...interface{}) { | ||
logger.Fatalf(wrapNewLines(format, values...)) | ||
} | ||
|
||
func fatalln(value interface{}) { | ||
logger.Fatal(wrapNewLines("%s", value)) | ||
} | ||
|
||
func debugf(format string, values ...interface{}) { | ||
logger.Debugf(wrapNewLines(format, values...)) | ||
} | ||
|
||
func debugln(value interface{}) { | ||
logger.Debug(wrapNewLines("%s", value)) | ||
} | ||
|
||
func tracef(format string, values ...interface{}) { | ||
logger.Trace(wrapNewLines(format, values...)) | ||
} | ||
|
||
func wrapNewLines(format string, values ...interface{}) string { | ||
contents := fmt.Sprintf(format, values...) | ||
contents = strings.TrimSuffix(contents, "\n") | ||
contents = strings.Replace( | ||
contents, | ||
"\n", | ||
"\n"+strings.Repeat(" ", 8), | ||
-1, | ||
) | ||
|
||
return contents | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/kovetskiy/godocs" | ||
"github.com/kovetskiy/lorg" | ||
"github.com/zazab/hierr" | ||
) | ||
|
||
var ( | ||
version = "1.0" | ||
usage = `zabbixctl ` + version + os.ExpandEnv(` | ||
zabbixctl is tool for working with zabbix server using command line | ||
interface, it provides effective waay for operating on zabbix triggers and | ||
their statuses, i.e. searching, sorting, showing and acknowledging triggers. | ||
zabbixctl must be configurated before using, configuration file usually locates | ||
in ~/.config/zabbixctl.conf and must be written with following syntax: | ||
[server] | ||
address = "zabbix.hostname" | ||
username = "e.kovetskiy" | ||
password = "pa$$word" | ||
Usage: | ||
zabbixctl [-v]... [options] -T [-x]... [<search>]... | ||
zabbixctl -h | --help | ||
zabbixctl --version | ||
Workflow options: | ||
-T --triggers Operate on zabbix triggers. | ||
-k --only-nack Show unacknowledged triggers only. | ||
-x --severity Specify minimum trigger severity. | ||
Once for information, twice for warning, | ||
three for disaster, four for high, five for disaster. | ||
-p --problem Show triggers that have a problem state. | ||
-r --recent Show triggers that have recently been in a problem state. | ||
-s --since <date> Show triggers that have changed their state after | ||
the given time. | ||
[default: 7 days ago] | ||
-u --until <date> Show triggers that have changed their state before | ||
the given time. | ||
-m --maintenance Show hosts in maintenance. | ||
-i --sort <fields> Show triggers sorted by specified fields. | ||
[default: lastchange,priority] | ||
-o --order <order> Show triggers in specified order. | ||
[default: DESC] | ||
-n --limit <count> Show specified amount of triggers. | ||
[default: 0] | ||
-f --noconfirm Do not prompt acknowledge confirmation dialog. | ||
-a --acknowledge Acknowledge triggers. | ||
Common options: | ||
-c --config <path> Use specified configuration file . | ||
[default: $HOME/.config/zabbixctl.conf] | ||
-v --verbosity Specify program output verbosity. | ||
Once for debug, twice for trace. | ||
-h --help Show this screen. | ||
--version Show version. | ||
`) | ||
) | ||
|
||
var ( | ||
logger lorg.Logger | ||
) | ||
|
||
func main() { | ||
args, err := godocs.Parse(usage, version, godocs.UsePager) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
var ( | ||
verbosity = args["--verbosity"].(int) | ||
configPath = args["--config"].(string) | ||
) | ||
|
||
logger = getLogger(verbosity) | ||
|
||
config, err := NewConfig(configPath) | ||
if err != nil { | ||
fatalln( | ||
hierr.Errorf( | ||
err, | ||
"problem with configuration file using %s", | ||
configPath, | ||
), | ||
) | ||
} | ||
|
||
zabbix, err := NewZabbix( | ||
config.Server.Address, | ||
config.Server.Username, | ||
config.Server.Password, | ||
) | ||
if err != nil { | ||
fatalln(err) | ||
} | ||
|
||
switch { | ||
case args["--triggers"].(bool): | ||
err = handleModeTriggers(zabbix, config, args) | ||
} | ||
|
||
if err != nil { | ||
fatalln(err) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package main | ||
|
||
import "github.com/seletskiy/hierr" | ||
|
||
type Response interface { | ||
Error() error | ||
} | ||
|
||
type ResponseRaw struct { | ||
Err struct { | ||
Data string `json:"data"` | ||
Message string `json:"message"` | ||
} `json:"error"` | ||
|
||
Result interface{} `json:"result"` | ||
} | ||
|
||
func (response *ResponseRaw) Error() error { | ||
if response.Err.Data != "" && response.Err.Message != "" { | ||
return hierr.Push( | ||
response.Err.Message, | ||
response.Err.Data, | ||
) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
type ResponseTriggersList struct { | ||
ResponseRaw | ||
Data map[string]Trigger `json:"result"` | ||
} | ||
|
||
type ResponseLogin struct { | ||
ResponseRaw | ||
Token string `json:"result"` | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package main | ||
|
||
type Severity int | ||
|
||
var ( | ||
SeverityInformation Severity = 1 | ||
SeverityWarning Severity = 2 | ||
SeverityAverage Severity = 3 | ||
SeverityHigh Severity = 4 | ||
SeverityDisaster Severity = 5 | ||
) | ||
|
||
func (priority Severity) String() string { | ||
switch priority { | ||
case SeverityInformation: | ||
return "INFO" | ||
case SeverityWarning: | ||
return "WARN" | ||
case SeverityAverage: | ||
return "AVG" | ||
case SeverityHigh: | ||
return "HIGH" | ||
case SeverityDisaster: | ||
return "DISASTER" | ||
default: | ||
return "UNKNOWN" | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package main | ||
|
||
import ( | ||
"strconv" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type Trigger struct { | ||
ID string `json:"triggerid"` | ||
Description string `json:"description"` | ||
Hostname string `json:"host"` | ||
Value string `json:"value"` | ||
LastChange string `json:"lastchange"` | ||
LastEvent struct { | ||
ID string `json:"eventid"` | ||
Acknowledged string `json:"acknowledged"` | ||
} `json:"lastEvent"` | ||
Priority string `json:"priority"` | ||
} | ||
|
||
func (trigger *Trigger) String() string { | ||
return trigger.LastEvent.ID + " " + | ||
trigger.Hostname + " " + trigger.Description | ||
} | ||
|
||
func (trigger *Trigger) StatusAcknowledge() string { | ||
if trigger.LastEvent.Acknowledged == "1" { | ||
return "ACK" | ||
} | ||
|
||
return "NACK" | ||
} | ||
|
||
func (trigger *Trigger) StatusProblem() string { | ||
if trigger.Value == "1" { | ||
return "PROBLEM" | ||
} | ||
|
||
return "OK" | ||
} | ||
|
||
func (trigger *Trigger) Severity() Severity { | ||
value, _ := strconv.Atoi(trigger.Priority) | ||
return Severity(value) | ||
} | ||
|
||
func (trigger *Trigger) DateTime() string { | ||
return trigger.date().Format("2006-01-02 15:04:05") | ||
} | ||
|
||
func (trigger *Trigger) Age() string { | ||
date := time.Now().Sub(trigger.date()) | ||
|
||
var ( | ||
seconds = int(date.Seconds()) % 60 | ||
minutes = int(date.Minutes()) % 60 | ||
hours = int(date.Hours()) | ||
days = hours / 24 | ||
months = days / 30. | ||
) | ||
|
||
var units []string | ||
|
||
units = addUnit(units, months, "mon") | ||
units = addUnit(units, days%7, "d") | ||
units = addUnit(units, hours%24, "h") | ||
units = addUnit(units, minutes, "m") | ||
units = addUnit(units, seconds, "s") | ||
|
||
return strings.Join(units, " ") | ||
} | ||
|
||
func (trigger *Trigger) date() time.Time { | ||
date, _ := strconv.ParseInt(trigger.LastChange, 10, 64) | ||
return time.Unix(date, 0) | ||
} | ||
|
||
func addUnit(units []string, value int, unit string) []string { | ||
if value > 1 { | ||
units = append(units, strconv.Itoa(value)+unit) | ||
} | ||
|
||
return units | ||
} |
Oops, something went wrong.