-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
recommendation_info.go
172 lines (136 loc) · 4.31 KB
/
recommendation_info.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package command
import (
"fmt"
"sort"
"strings"
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
// Ensure RecommendationInfoCommand satisfies the cli.Command interface.
var _ cli.Command = &RecommendationInfoCommand{}
// RecommendationInfoCommand implements cli.Command.
type RecommendationInfoCommand struct {
RecommendationAutocompleteCommand
}
// Help satisfies the cli.Command Help function.
func (r *RecommendationInfoCommand) Help() string {
helpText := `
Usage: nomad recommendation info [options] <recommendation_id>
Info is used to read the specified recommendation.
When ACLs are enabled, this command requires a token with the 'read-job'
capability for the recommendation's namespace.
General Options:
` + generalOptionsUsage(usageOptsDefault) + `
Recommendation Info Options:
-json
Output the recommendation in its JSON format.
-t
Format and display the recommendation using a Go template.
`
return strings.TrimSpace(helpText)
}
// Synopsis satisfies the cli.Command Synopsis function.
func (r *RecommendationInfoCommand) Synopsis() string {
return "Display an individual Nomad recommendation"
}
func (r *RecommendationInfoCommand) AutocompleteFlags() complete.Flags {
return mergeAutocompleteFlags(r.Meta.AutocompleteFlags(FlagSetClient),
complete.Flags{
"-json": complete.PredictNothing,
"-t": complete.PredictAnything,
})
}
// Name returns the name of this command.
func (r *RecommendationInfoCommand) Name() string { return "recommendation info" }
// Run satisfies the cli.Command Run function.
func (r *RecommendationInfoCommand) Run(args []string) int {
var json bool
var tmpl string
flags := r.Meta.FlagSet(r.Name(), FlagSetClient)
flags.Usage = func() { r.Ui.Output(r.Help()) }
flags.BoolVar(&json, "json", false, "")
flags.StringVar(&tmpl, "t", "", "")
if err := flags.Parse(args); err != nil {
return 1
}
if args = flags.Args(); len(args) != 1 {
r.Ui.Error("This command takes one argument: <recommendation_id>")
r.Ui.Error(commandErrorText(r))
return 1
}
// Get the recommendation ID.
recID := args[0]
// Get the HTTP client.
client, err := r.Meta.Client()
if err != nil {
r.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
return 1
}
rec, _, err := client.Recommendations().Info(recID, nil)
if err != nil {
r.Ui.Error(fmt.Sprintf("Error reading recommendation: %s", err))
return 1
}
// If the user has specified to output the recommendation as JSON or using
// a template then perform this action for the entire object and exit the
// command.
if json || len(tmpl) > 0 {
out, err := Format(json, tmpl, rec)
if err != nil {
r.Ui.Error(err.Error())
return 1
}
r.Ui.Output(out)
return 0
}
info := []string{
fmt.Sprintf("ID|%s", rec.ID),
fmt.Sprintf("Namespace|%s", rec.Namespace),
fmt.Sprintf("Job ID|%s", rec.JobID),
fmt.Sprintf("Task Group|%s", rec.Group),
fmt.Sprintf("Task|%s", rec.Task),
fmt.Sprintf("Resource|%s", rec.Resource),
fmt.Sprintf("Value|%v", rec.Value),
fmt.Sprintf("Current|%v", rec.Current),
}
r.Ui.Output(formatKV(info))
// If we have stats, format and output these.
if len(rec.Stats) > 0 {
// Sort the stats keys into an alphabetically ordered list to provide
// consistent outputs.
keys := []string{}
for k := range rec.Stats {
keys = append(keys, k)
}
sort.Strings(keys)
// We will only need two rows; key:value.
output := make([]string, 2)
for _, stat := range keys {
output[0] += fmt.Sprintf("%s|", stat)
output[1] += fmt.Sprintf("%.2f|", rec.Stats[stat])
}
// Trim any trailing pipes so we can use the formatList function thus
// providing a nice clean output.
output[0] = strings.TrimRight(output[0], "|")
output[1] = strings.TrimRight(output[1], "|")
r.Ui.Output(r.Colorize().Color("\n[bold]Stats[reset]"))
r.Ui.Output(formatList(output))
}
// If we have meta, format and output the entries.
if len(rec.Meta) > 0 {
// Sort the meta keys into an alphabetically ordered list to provide
// consistent outputs.
keys := []string{}
for k := range rec.Meta {
keys = append(keys, k)
}
sort.Strings(keys)
output := make([]string, len(rec.Meta))
for i, key := range keys {
output[i] = fmt.Sprintf("%s|%v", key, rec.Meta[key])
}
r.Ui.Output(r.Colorize().Color("\n[bold]Meta[reset]"))
r.Ui.Output(formatKV(output))
}
return 0
}