-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.go
317 lines (283 loc) · 9.3 KB
/
main.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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
package main
import (
"fmt"
"os"
"github.com/cloudfoundry/cli/plugin"
"github.com/ibmjstart/cf-object-storage/authenticate"
"github.com/ibmjstart/cf-object-storage/container"
"github.com/ibmjstart/cf-object-storage/dlo"
"github.com/ibmjstart/cf-object-storage/object"
"github.com/ibmjstart/cf-object-storage/slo"
w "github.com/ibmjstart/cf-object-storage/writer"
"github.com/ibmjstart/swiftlygo/auth"
)
const (
// Name of this plugin for use installing and uninstalling it
pluginName string = "cf-object-storage"
uninstallCommand string = "CLI-MESSAGE-UNINSTALL"
// Namespace for the plugin's subcommands
namespace string = "os"
// Name of the subcommand that provides help info for other subcommands
helpCommand string = "help"
// Name of the subcommand that fetches X-Auth Tokens
getAuthInfoCommand string = "auth"
// Names of the container subcommands
showContainersCommand string = "containers"
containerInfoCommand string = "container"
makeContainerCommand string = "create-container"
updateContainerCommand string = "update-container"
renameContainerCommand string = "rename-container"
deleteContainerCommand string = "delete-container"
// Names of the single object subcommands
showObjectsCommand string = "objects"
objectInfoCommand string = "object"
putObjectCommand string = "put-object"
getObjectCommand string = "get-object"
renameObjectCommand string = "rename-object"
copyObjectCommand string = "copy-object"
deleteObjectCommand string = "delete-object"
// Names of the subcommands that create large objects in object storage
makeDLOCommand string = "create-dynamic-object"
makeSLOCommand string = "put-large-object"
)
// ObjectStoragePlugin is the struct implementing the plugin interface.
// It has no public members.
type ObjectStoragePlugin struct {
subcommands map[string](command)
cliConnection plugin.CliConnection
writer *w.ConsoleWriter
}
// command contains the info needed to execute a subcommand.
type command struct {
name string
task string
numExpectedArgs int
execute func(auth.Destination, *w.ConsoleWriter, []string) (string, error)
}
// displayUserInfo shows the username, org and space corresponding to the requested service.
func displayUserInfo(cliConnection plugin.CliConnection, writer *w.ConsoleWriter, task string) error {
// Find username
username, err := cliConnection.Username()
if err != nil {
return fmt.Errorf("Failed to get username: %s", err)
}
// Find org
org, err := cliConnection.GetCurrentOrg()
if err != nil {
return fmt.Errorf("Failed to get organization: %s", err)
}
// Find space
space, err := cliConnection.GetCurrentSpace()
if err != nil {
return fmt.Errorf("Failed to get space: %s", err)
}
writer.Print("%s org %s / space %s as %s...\n", task, w.Cyan(org.Name), w.Cyan(space.Name), w.Cyan(username))
return nil
}
// executeCommand authenticates with Object Storage and runs a command
func (c *ObjectStoragePlugin) executeCommand(cmd command, args []string) error {
if len(args) < cmd.numExpectedArgs {
help, _ := getSubcommandHelp(cmd.name)
return fmt.Errorf("Missing required arguments\n%s", help)
}
err := displayUserInfo(c.cliConnection, c.writer, cmd.task)
if err != nil {
return err
}
go c.writer.Write()
serviceName := args[2]
destination, err := authenticate.Authenticate(c.cliConnection, c.writer, serviceName)
if err != nil {
return err
}
result, err := cmd.execute(destination, c.writer, args)
if err != nil {
return err
}
c.writer.Quit()
c.writer.Print(result)
return nil
}
// Run handles each invocation of the CLI plugin.
func (c *ObjectStoragePlugin) Run(cliConnection plugin.CliConnection, args []string) {
// Attach connection object to plugin struct
c.cliConnection = cliConnection
// Associate each subcommand with a handler function
c.subcommands = map[string](command){
// Authenticate command
getAuthInfoCommand: command{
name: getAuthInfoCommand,
task: "Authenticating with",
numExpectedArgs: 3,
execute: authenticate.DisplayAuthInfo,
},
// Container commands
showContainersCommand: command{
name: showContainersCommand,
task: "Displaying containers in",
numExpectedArgs: 3,
execute: container.ShowContainers,
},
containerInfoCommand: command{
name: containerInfoCommand,
task: "Fetching container info from",
numExpectedArgs: 4,
execute: container.GetContainerInfo,
},
makeContainerCommand: command{
name: makeContainerCommand,
task: "Creating container in",
numExpectedArgs: 4,
execute: container.MakeContainer,
},
updateContainerCommand: command{
name: updateContainerCommand,
task: "Updating container in",
numExpectedArgs: 4,
execute: container.UpdateContainer,
},
renameContainerCommand: command{
name: renameContainerCommand,
task: "Renaming container in",
numExpectedArgs: 5,
execute: container.RenameContainer,
},
deleteContainerCommand: command{
name: deleteContainerCommand,
task: "Removing container from",
numExpectedArgs: 4,
execute: container.DeleteContainer,
},
// Object commands
showObjectsCommand: command{
name: showObjectsCommand,
task: "Displaying objects in",
numExpectedArgs: 4,
execute: object.ShowObjects,
},
objectInfoCommand: command{
name: objectInfoCommand,
task: "Fetching object info from",
numExpectedArgs: 5,
execute: object.GetObjectInfo,
},
putObjectCommand: command{
name: putObjectCommand,
task: "Uploading object to",
numExpectedArgs: 5,
execute: object.PutObject,
},
getObjectCommand: command{
name: getObjectCommand,
task: "Downloading object from",
numExpectedArgs: 6,
execute: object.GetObject,
},
renameObjectCommand: command{
name: renameObjectCommand,
task: "Renaming object in",
numExpectedArgs: 6,
execute: object.RenameObject,
},
copyObjectCommand: command{
name: copyObjectCommand,
task: "Copying object in",
numExpectedArgs: 6,
execute: object.CopyObject,
},
deleteObjectCommand: command{
name: deleteObjectCommand,
task: "Removing object from",
numExpectedArgs: 5,
execute: object.DeleteObject,
},
// Large object commands
makeDLOCommand: command{
name: makeDLOCommand,
task: "Creating DLO in",
numExpectedArgs: 5,
execute: dlo.MakeDlo,
},
makeSLOCommand: command{
name: makeSLOCommand,
task: "Creating SLO in",
numExpectedArgs: 6,
execute: slo.MakeSlo,
},
}
// Create writer to provide output
c.writer = w.NewConsoleWriter()
// Dispatch the subcommand that the user wanted, if it exists
var err error
if len(args) == 1 && args[0] == uninstallCommand {
// Ensure nothing happens on an uninstall request
} else if len(args) < 2 || args[1] == helpCommand {
err = c.help(args)
} else {
subcommand, found := c.subcommands[args[1]]
if !found {
err = fmt.Errorf("%s is not a valid subcommand", args[1])
} else {
err = c.executeCommand(subcommand, args)
}
}
// Report any fatal errors returned by the subcommand
if err != nil {
c.writer.Print("\r%s\n%s\n%s\n", w.ClearLine, w.Red("FAILED"), err)
os.Exit(1)
}
}
// GetMetadata returns a PluginMetadata struct with information
// about the current version of this plugin and how to use it. This
// information is used to build the CF CLI helptext for this plugin's
// commands.
func (c *ObjectStoragePlugin) GetMetadata() plugin.PluginMetadata {
var usageContent = "cf " + namespace + " COMMAND [ARGS...] \n" +
"\n Object Storage commands:\n" +
" " + getAuthInfoCommand + "\n" +
" " + showContainersCommand + "\n" +
" " + containerInfoCommand + "\n" +
" " + makeContainerCommand + "\n" +
" " + updateContainerCommand + "\n" +
" " + renameContainerCommand + "\n" +
" " + deleteContainerCommand + "\n" +
" " + showObjectsCommand + "\n" +
" " + objectInfoCommand + "\n" +
" " + putObjectCommand + "\n" +
" " + getObjectCommand + "\n" +
" " + renameObjectCommand + "\n" +
" " + copyObjectCommand + "\n" +
" " + deleteObjectCommand + "\n" +
" " + makeDLOCommand + "\n" +
" " + makeSLOCommand + "\n" +
" For more detailed information on subcommands use 'cf os help subcommand'"
return plugin.PluginMetadata{
Name: pluginName,
Version: plugin.VersionType{
Major: 1,
Minor: 0,
Build: 1,
},
MinCliVersion: plugin.VersionType{
Major: 6,
Minor: 21,
Build: 0,
},
Commands: []plugin.Command{
{
Name: namespace,
HelpText: "Work with SoftLayer Object Storage",
UsageDetails: plugin.Usage{
Usage: usageContent,
},
},
},
}
}
// main initializes a plugin on install, but is not invoked when that plugin
// is run from the CLI. See Run() function for logic invoked when CLI plugin
// is actually used.
func main() {
// Any initialization for your plugin can be handled here
plugin.Start(new(ObjectStoragePlugin))
}