mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
Support JSON and template format with nomad CLI
This commit is contained in:
@@ -38,11 +38,17 @@ Alloc Status Options:
|
||||
-short
|
||||
Display short output. Shows only the most recent task event.
|
||||
|
||||
-stats
|
||||
Display detailed resource usage statistics
|
||||
-stats
|
||||
Display detailed resource usage statistics.
|
||||
|
||||
-verbose
|
||||
Show full information.
|
||||
|
||||
-format
|
||||
Display specified format, "json" or "template".
|
||||
|
||||
-t
|
||||
Sets the template with golang templates format.
|
||||
`
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
@@ -54,12 +60,15 @@ func (c *AllocStatusCommand) Synopsis() string {
|
||||
|
||||
func (c *AllocStatusCommand) Run(args []string) int {
|
||||
var short, displayStats, verbose bool
|
||||
var format, tmpl string
|
||||
|
||||
flags := c.Meta.FlagSet("alloc-status", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flags.BoolVar(&short, "short", false, "")
|
||||
flags.BoolVar(&verbose, "verbose", false, "")
|
||||
flags.BoolVar(&displayStats, "stats", false, "")
|
||||
flags.StringVar(&format, "format", "default", "")
|
||||
flags.StringVar(&tmpl, "t", "", "")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
@@ -130,6 +139,23 @@ func (c *AllocStatusCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// If output format is specified, format and output the data
|
||||
if format != "default" {
|
||||
f, err := DataFormat(format, tmpl)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting formatter: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
out, err := f.TransformData(alloc)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error transform the data: %s", err))
|
||||
return 1
|
||||
}
|
||||
c.Ui.Output(out)
|
||||
return 0
|
||||
}
|
||||
|
||||
var statsErr error
|
||||
var stats *api.AllocResourceUsage
|
||||
stats, statsErr = client.Allocations().Stats(alloc, nil)
|
||||
|
||||
58
command/data_format.go
Normal file
58
command/data_format.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
//DataFormatter is a transformer of the data.
|
||||
type DataFormatter interface {
|
||||
// TransformData should return transformed string data.
|
||||
TransformData(interface{}) (string, error)
|
||||
}
|
||||
|
||||
// DataFormat returns the data formatter specified format.
|
||||
func DataFormat(format, tmpl string) (DataFormatter, error) {
|
||||
switch format {
|
||||
case "json":
|
||||
return &JSONFormat{}, nil
|
||||
case "template":
|
||||
return &TemplateFormat{tmpl}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Unsupported format is specified.")
|
||||
}
|
||||
|
||||
type JSONFormat struct {
|
||||
}
|
||||
|
||||
// TransformData returns JSON format string data.
|
||||
func (p *JSONFormat) TransformData(data interface{}) (string, error) {
|
||||
out, err := json.MarshalIndent(&data, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
type TemplateFormat struct {
|
||||
tmpl string
|
||||
}
|
||||
|
||||
// TransformData returns template format string data.
|
||||
func (p *TemplateFormat) TransformData(data interface{}) (string, error) {
|
||||
var out io.Writer = new(bytes.Buffer)
|
||||
if len(p.tmpl) == 0 {
|
||||
return "", fmt.Errorf("template needs to be specified the golang templates.")
|
||||
}
|
||||
|
||||
t := template.Must(template.New("format").Parse(p.tmpl))
|
||||
err := t.Execute(out, data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprint(out), nil
|
||||
}
|
||||
41
command/data_format_test.go
Normal file
41
command/data_format_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testData struct {
|
||||
Region string
|
||||
ID string
|
||||
Name string
|
||||
}
|
||||
|
||||
const expectJSON = `{
|
||||
"Region": "global",
|
||||
"ID": "1",
|
||||
"Name": "example"
|
||||
}`
|
||||
|
||||
var (
|
||||
tData = testData{"global", "1", "example"}
|
||||
testFormat = map[string]string{"json": "", "template": "{{.Region}}"}
|
||||
expectOutput = map[string]string{"json": expectJSON, "template": "global"}
|
||||
)
|
||||
|
||||
func TestDataFormat(t *testing.T) {
|
||||
for k, v := range testFormat {
|
||||
fm, err := DataFormat(k, v)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
result, err := fm.TransformData(tData)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if result != expectOutput[k] {
|
||||
t.Fatalf("expected output: %s, actual: %s", expectOutput[k], result)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,12 @@ Eval Status Options:
|
||||
|
||||
-verbose
|
||||
Show full information.
|
||||
|
||||
-format
|
||||
Display specified format, "json" or "template".
|
||||
|
||||
-t
|
||||
Sets the template with golang templates format.
|
||||
`
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
@@ -42,11 +48,14 @@ func (c *EvalStatusCommand) Synopsis() string {
|
||||
|
||||
func (c *EvalStatusCommand) Run(args []string) int {
|
||||
var monitor, verbose bool
|
||||
var format, tmpl string
|
||||
|
||||
flags := c.Meta.FlagSet("eval-status", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flags.BoolVar(&monitor, "monitor", false, "")
|
||||
flags.BoolVar(&verbose, "verbose", false, "")
|
||||
flags.StringVar(&format, "format", "default", "")
|
||||
flags.StringVar(&tmpl, "t", "", "")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
@@ -124,6 +133,23 @@ func (c *EvalStatusCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// If output format is specified, format and output the data
|
||||
if format != "default" {
|
||||
f, err := DataFormat(format, tmpl)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting formatter: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
out, err := f.TransformData(eval)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error transform the data: %s", err))
|
||||
return 1
|
||||
}
|
||||
c.Ui.Output(out)
|
||||
return 0
|
||||
}
|
||||
|
||||
failureString, failures := evalFailureStatus(eval)
|
||||
triggerNoun, triggerSubj := getTriggerDetails(eval)
|
||||
statusDesc := eval.StatusDescription
|
||||
|
||||
@@ -30,6 +30,8 @@ type NodeStatusCommand struct {
|
||||
list_allocs bool
|
||||
self bool
|
||||
stats bool
|
||||
format string
|
||||
tmpl string
|
||||
}
|
||||
|
||||
func (c *NodeStatusCommand) Help() string {
|
||||
@@ -66,6 +68,12 @@ Node Status Options:
|
||||
|
||||
-verbose
|
||||
Display full information.
|
||||
|
||||
-format
|
||||
Display specified format, "json" or "template".
|
||||
|
||||
-t
|
||||
Sets the template with golang templates format.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
@@ -83,6 +91,8 @@ func (c *NodeStatusCommand) Run(args []string) int {
|
||||
flags.BoolVar(&c.list_allocs, "allocs", false, "")
|
||||
flags.BoolVar(&c.self, "self", false, "")
|
||||
flags.BoolVar(&c.stats, "stats", false, "")
|
||||
flags.StringVar(&c.format, "format", "default", "")
|
||||
flags.StringVar(&c.tmpl, "t", "", "")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
@@ -216,6 +226,23 @@ func (c *NodeStatusCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// If output format is specified, format and output the data
|
||||
if c.format != "default" {
|
||||
f, err := DataFormat(c.format, c.tmpl)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting formatter: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
out, err := f.TransformData(node)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error transform the data: %s", err))
|
||||
return 1
|
||||
}
|
||||
c.Ui.Output(out)
|
||||
return 0
|
||||
}
|
||||
|
||||
return c.formatNode(client, node)
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,12 @@ Status Options:
|
||||
|
||||
-verbose
|
||||
Display full information.
|
||||
|
||||
-format
|
||||
Display specified format, "json" or "template".
|
||||
|
||||
-t
|
||||
Sets the template with golang templates format.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
@@ -56,12 +62,15 @@ func (c *StatusCommand) Synopsis() string {
|
||||
|
||||
func (c *StatusCommand) Run(args []string) int {
|
||||
var short bool
|
||||
var format, tmpl string
|
||||
|
||||
flags := c.Meta.FlagSet("status", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flags.BoolVar(&short, "short", false, "")
|
||||
flags.BoolVar(&c.showEvals, "evals", false, "")
|
||||
flags.BoolVar(&c.verbose, "verbose", false, "")
|
||||
flags.StringVar(&format, "format", "default", "")
|
||||
flags.StringVar(&tmpl, "t", "", "")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
@@ -145,6 +154,23 @@ func (c *StatusCommand) Run(args []string) int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// If output format is specified, format and output the data
|
||||
if format != "default" {
|
||||
f, err := DataFormat(format, tmpl)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting formatter: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
out, err := f.TransformData(job)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error transform the data: %s", err))
|
||||
return 1
|
||||
}
|
||||
c.Ui.Output(out)
|
||||
return 0
|
||||
}
|
||||
|
||||
// Check if it is periodic
|
||||
sJob, err := convertApiJob(job)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user