From 4ff76424cbdc0390aa86bf8ebdb2b0f5277809b2 Mon Sep 17 00:00:00 2001 From: Diptanu Choudhury Date: Sun, 10 Apr 2016 01:13:25 -0700 Subject: [PATCH] Added a check command --- command/check.go | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ commands.go | 8 +++-- 2 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 command/check.go diff --git a/command/check.go b/command/check.go new file mode 100644 index 000000000..8bc559f98 --- /dev/null +++ b/command/check.go @@ -0,0 +1,93 @@ +package command + +import ( + "fmt" + "strconv" + "strings" +) + +const ( + HealthCritical = 1 + HealthWarn = 2 + HealthPass = 0 +) + +type AgentCheckCommand struct { + Meta +} + +func (c *AgentCheckCommand) Help() string { + helpText := ` +Usage: nomad check + + Display state of the Nomad agent. The exit code of the command is Nagios + compatible and could be used with alerting systems. + +General Options: + + ` + generalOptionsUsage() + ` + +Agent Check Options: + + -min-peers + Minimum number of peers that a server is expected to know. +` + + return strings.TrimSpace(helpText) +} + +func (c *AgentCheckCommand) Synopsis() string { + return "Displays health of the local Nomad agent" +} + +func (c *AgentCheckCommand) Run(args []string) int { + var minPeers int + + flags := c.Meta.FlagSet("check", FlagSetClient) + flags.Usage = func() { c.Ui.Output(c.Help()) } + flags.IntVar(&minPeers, "min-peers", 0, "") + + if err := flags.Parse(args); err != nil { + return 1 + } + + client, err := c.Meta.Client() + if err != nil { + c.Ui.Error(fmt.Sprintf("error initializing client: %s", err)) + return HealthCritical + } + + info, err := client.Agent().Self() + if err != nil { + c.Ui.Output(fmt.Sprintf("unable to query agent info: %v", err)) + return HealthCritical + } + if _, ok := info["stats"]["nomad"]; ok { + return c.checkServerHealth(info["stats"], minPeers) + } + + if _, ok := info["client"]; ok { + return c.checkClientHealth(info) + } + return HealthWarn +} + +// checkServerHealth returns the health of a server +func (c *AgentCheckCommand) checkServerHealth(info map[string]interface{}, minPeers int) int { + raft := info["raft"].(map[string]interface{}) + knownPeers, err := strconv.Atoi(raft["num_peers"].(string)) + if err != nil { + c.Ui.Output(fmt.Sprintf("unable to get known peers: %v", err)) + return HealthCritical + } + + if knownPeers < minPeers { + c.Ui.Output(fmt.Sprintf("known peers: %v, is less than expected number of peers: %v", knownPeers, minPeers)) + return HealthCritical + } + return HealthPass +} + +func (c *AgentCheckCommand) checkClientHealth(info map[string]map[string]interface{}) int { + return HealthPass +} diff --git a/commands.go b/commands.go index 2374dea06..1ebc1bd76 100644 --- a/commands.go +++ b/commands.go @@ -30,7 +30,6 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, - "agent": func() (cli.Command, error) { return &agent.Command{ Revision: GitCommit, @@ -40,13 +39,16 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { ShutdownCh: make(chan struct{}), }, nil }, - "agent-info": func() (cli.Command, error) { return &command.AgentInfoCommand{ Meta: meta, }, nil }, - + "check": func() (cli.Command, error) { + return &command.AgentCheckCommand{ + Meta: meta, + }, nil + }, "client-config": func() (cli.Command, error) { return &command.ClientConfigCommand{ Meta: meta,