forked from hashicorp/nomad
-
Notifications
You must be signed in to change notification settings - Fork 0
/
volume_register.go
130 lines (106 loc) · 2.9 KB
/
volume_register.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
package command
import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/hashicorp/hcl"
"github.com/hashicorp/hcl/hcl/ast"
"github.com/posener/complete"
)
type VolumeRegisterCommand struct {
Meta
}
func (c *VolumeRegisterCommand) Help() string {
helpText := `
Usage: nomad volume register [options] <input>
Creates or updates a volume in Nomad. The volume must exist on the remote
storage provider before it can be used by a task.
If the supplied path is "-" the volume file is read from stdin. Otherwise, it
is read from the file at the supplied path.
General Options:
` + generalOptionsUsage()
return strings.TrimSpace(helpText)
}
func (c *VolumeRegisterCommand) AutocompleteFlags() complete.Flags {
return c.Meta.AutocompleteFlags(FlagSetClient)
}
func (c *VolumeRegisterCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictFiles("*")
}
func (c *VolumeRegisterCommand) Synopsis() string {
return "Create or update a volume"
}
func (c *VolumeRegisterCommand) Name() string { return "volume register" }
func (c *VolumeRegisterCommand) Run(args []string) int {
flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
if err := flags.Parse(args); err != nil {
c.Ui.Error(fmt.Sprintf("Error parsing arguments %s", err))
return 1
}
// Check that we get exactly one argument
args = flags.Args()
if l := len(args); l != 1 {
c.Ui.Error("This command takes one argument: <input>")
c.Ui.Error(commandErrorText(c))
return 1
}
// Read the file contents
file := args[0]
var rawVolume []byte
var err error
if file == "-" {
rawVolume, err = ioutil.ReadAll(os.Stdin)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to read stdin: %v", err))
return 1
}
} else {
rawVolume, err = ioutil.ReadFile(file)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to read file: %v", err))
return 1
}
}
ast, volType, err := parseVolumeType(string(rawVolume))
if err != nil {
c.Ui.Error(fmt.Sprintf("Error parsing the volume type: %s", err))
return 1
}
volType = strings.ToLower(volType)
// Get the HTTP client
client, err := c.Meta.Client()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
return 1
}
switch volType {
case "csi":
code := c.csiRegister(client, ast)
if code != 0 {
return code
}
default:
c.Ui.Error(fmt.Sprintf("Error unknown volume type: %s", volType))
return 1
}
return 0
}
// parseVolume is used to parse the quota specification from HCL
func parseVolumeType(input string) (*ast.File, string, error) {
// Parse the AST first
ast, err := hcl.Parse(input)
if err != nil {
return nil, "", fmt.Errorf("parse error: %v", err)
}
// Decode the type, so we can dispatch on it
dispatch := &struct {
T string `hcl:"type"`
}{}
err = hcl.DecodeObject(dispatch, ast)
if err != nil {
return nil, "", fmt.Errorf("dispatch error: %v", err)
}
return ast, dispatch.T, nil
}