github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/var_get.go (about) 1 package command 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "strings" 8 9 "github.com/hashicorp/nomad/api" 10 "github.com/mitchellh/cli" 11 "github.com/posener/complete" 12 ) 13 14 type VarGetCommand struct { 15 Meta 16 outFmt string 17 tmpl string 18 } 19 20 func (c *VarGetCommand) Help() string { 21 helpText := ` 22 Usage: nomad var get [options] <path> 23 24 The 'var get' command is used to get the contents of an existing variable. 25 26 If ACLs are enabled, this command requires a token with the 'variables:read' 27 capability for the target variable's namespace and path. 28 29 General Options: 30 31 ` + generalOptionsUsage(usageOptsDefault) + ` 32 33 Get Options: 34 35 -item <item key> 36 Print only the value of the given item. Specifying this option will 37 take precedence over other formatting directives. The result will not 38 have a trailing newline making it ideal for piping to other processes. 39 40 -out ( go-template | hcl | json | none | table ) 41 Format to render the variable in. When using "go-template", you must 42 provide the template content with the "-template" option. Defaults 43 to "table" when stdout is a terminal and to "json" when stdout is 44 redirected. 45 46 -template 47 Template to render output with. Required when output is "go-template". 48 49 ` 50 return strings.TrimSpace(helpText) 51 } 52 53 func (c *VarGetCommand) AutocompleteFlags() complete.Flags { 54 return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), 55 complete.Flags{ 56 "-out": complete.PredictSet("go-template", "hcl", "json", "none", "table"), 57 "-template": complete.PredictAnything, 58 }, 59 ) 60 } 61 62 func (c *VarGetCommand) AutocompleteArgs() complete.Predictor { 63 return VariablePathPredictor(c.Meta.Client) 64 } 65 66 func (c *VarGetCommand) Synopsis() string { 67 return "Read a variable" 68 } 69 70 func (c *VarGetCommand) Name() string { return "var get" } 71 72 func (c *VarGetCommand) Run(args []string) int { 73 var out, item string 74 75 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 76 flags.Usage = func() { c.Ui.Output(c.Help()) } 77 78 flags.StringVar(&item, "item", "", "") 79 flags.StringVar(&c.tmpl, "template", "", "") 80 81 if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) != 0 { 82 flags.StringVar(&c.outFmt, "out", "table", "") 83 } else { 84 flags.StringVar(&c.outFmt, "out", "json", "") 85 } 86 87 if err := flags.Parse(args); err != nil { 88 return 1 89 } 90 91 // Check that we got one argument 92 args = flags.Args() 93 if len(args) != 1 { 94 c.Ui.Error("This command takes one argument: <path>") 95 c.Ui.Error(commandErrorText(c)) 96 return 1 97 } 98 99 if err := c.validateOutputFlag(); err != nil { 100 c.Ui.Error(err.Error()) 101 c.Ui.Error(commandErrorText(c)) 102 return 1 103 } 104 105 if c.Meta.namespace == "*" { 106 c.Ui.Error(errWildcardNamespaceNotAllowed) 107 return 1 108 } 109 110 path := args[0] 111 112 // Get the HTTP client 113 client, err := c.Meta.Client() 114 if err != nil { 115 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 116 return 1 117 } 118 119 qo := &api.QueryOptions{ 120 Namespace: c.Meta.namespace, 121 } 122 123 sv, _, err := client.Variables().Read(path, qo) 124 if err != nil { 125 if err.Error() == "variable not found" { 126 c.Ui.Warn(errVariableNotFound) 127 return 1 128 } 129 c.Ui.Error(fmt.Sprintf("Error retrieving variable: %s", err)) 130 return 1 131 } 132 // If the user provided an item key, return that value instead of the whole 133 // object 134 if item != "" { 135 if v, ok := sv.Items[item]; ok { 136 fmt.Print(v) 137 return 0 138 } else { 139 c.Ui.Error(fmt.Sprintf("Variable does not contain %q item", args[1])) 140 return 1 141 } 142 } 143 144 // Output whole object 145 switch c.outFmt { 146 case "json": 147 out = sv.AsPrettyJSON() 148 case "hcl": 149 out = renderAsHCL(sv) 150 case "go-template": 151 if out, err = renderWithGoTemplate(sv, c.tmpl); err != nil { 152 c.Ui.Error(err.Error()) 153 return 1 154 } 155 case "none": 156 // exit without more output 157 return 0 158 default: 159 // the renderSVAsUiTable func writes directly to the ui and doesn't error. 160 renderSVAsUiTable(sv, c) 161 return 0 162 } 163 164 c.Ui.Output(out) 165 return 0 166 } 167 168 func (c *VarGetCommand) validateOutputFlag() error { 169 if c.outFmt != "go-template" && c.tmpl != "" { 170 return errors.New(errUnexpectedTemplate) 171 } 172 switch c.outFmt { 173 case "hcl", "json", "none", "table": 174 return nil 175 case "go-template": //noop - needs more validation 176 if c.tmpl == "" { 177 return errors.New(errMissingTemplate) 178 } 179 return nil 180 default: 181 return errors.New(errInvalidOutFormat) 182 } 183 } 184 185 func (c *VarGetCommand) GetConcurrentUI() cli.ConcurrentUi { 186 return cli.ConcurrentUi{Ui: c.Ui} 187 }