brightbox-cli 4.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -2
- data/Gemfile.lock +7 -7
- data/brightbox-cli.gemspec +2 -2
- data/lib/brightbox-cli/commands/login.rb +5 -6
- data/lib/brightbox-cli/commands/volumes/attach.rb +36 -0
- data/lib/brightbox-cli/commands/volumes/copy.rb +45 -0
- data/lib/brightbox-cli/commands/volumes/create.rb +63 -0
- data/lib/brightbox-cli/commands/volumes/destroy.rb +26 -0
- data/lib/brightbox-cli/commands/volumes/detach.rb +23 -0
- data/lib/brightbox-cli/commands/volumes/list.rb +16 -0
- data/lib/brightbox-cli/commands/volumes/locking.rb +39 -0
- data/lib/brightbox-cli/commands/volumes/resize.rb +36 -0
- data/lib/brightbox-cli/commands/volumes/show.rb +18 -0
- data/lib/brightbox-cli/commands/volumes/update.rb +50 -0
- data/lib/brightbox-cli/detailed_server.rb +13 -0
- data/lib/brightbox-cli/version.rb +1 -1
- data/lib/brightbox-cli/volume.rb +81 -0
- data/lib/brightbox_cli.rb +1 -0
- data/locales/en.yml +59 -1
- data/spec/commands/volumes/attach_spec.rb +165 -0
- data/spec/commands/volumes/copy_spec.rb +74 -0
- data/spec/commands/volumes/create_spec.rb +217 -0
- data/spec/commands/volumes/destroy_spec.rb +173 -0
- data/spec/commands/volumes/detach_spec.rb +180 -0
- data/spec/commands/volumes/list_spec.rb +99 -0
- data/spec/commands/volumes/resize_spec.rb +96 -0
- data/spec/commands/volumes/show_spec.rb +95 -0
- data/spec/commands/volumes/update_spec.rb +188 -0
- data/spec/support/volume_helpers.rb +167 -0
- metadata +37 -6
data/locales/en.yml
CHANGED
|
@@ -136,6 +136,8 @@ en:
|
|
|
136
136
|
update:
|
|
137
137
|
desc: Update a load balancer
|
|
138
138
|
long_desc: All intervals and timeouts are in milliseconds
|
|
139
|
+
login:
|
|
140
|
+
desc: Authenticate using an email address
|
|
139
141
|
servers:
|
|
140
142
|
desc: Manage an account's servers
|
|
141
143
|
activate_console:
|
|
@@ -153,7 +155,7 @@ en:
|
|
|
153
155
|
reboot:
|
|
154
156
|
desc: Reboot servers (OS reboot issued)
|
|
155
157
|
reset:
|
|
156
|
-
desc: Reset servers (
|
|
158
|
+
desc: Reset servers (Hardware reset issued)
|
|
157
159
|
show:
|
|
158
160
|
desc: Show servers
|
|
159
161
|
shutdown:
|
|
@@ -243,3 +245,59 @@ en:
|
|
|
243
245
|
desc: Show users
|
|
244
246
|
update:
|
|
245
247
|
desc: Update a user
|
|
248
|
+
volumes:
|
|
249
|
+
desc: Manage an account's volumes
|
|
250
|
+
args:
|
|
251
|
+
one: <volume>
|
|
252
|
+
optional: [<volume>...]
|
|
253
|
+
many: <volume>...
|
|
254
|
+
specify_one_id_first: You must specify the volume ID as the first argument
|
|
255
|
+
specify_many_ids: You must specify volume IDs as arguments
|
|
256
|
+
unknown_id: Couldn't find %{volume}
|
|
257
|
+
options:
|
|
258
|
+
boot: Set this volume as boot volume on server
|
|
259
|
+
delete_with_server: Set volume to be deleted with a server if attached
|
|
260
|
+
encrypted: Encrypt the volume
|
|
261
|
+
fs_label: Filesystem label, visible from within some OS
|
|
262
|
+
fs_type: Filesystem type to use to create blank volume
|
|
263
|
+
image: Create volume from existing Image ID
|
|
264
|
+
serial: Customisable serial number for volume
|
|
265
|
+
size: Volume size in MB
|
|
266
|
+
attach:
|
|
267
|
+
desc: Attach a volume to an existing server
|
|
268
|
+
args: <volume> <server>
|
|
269
|
+
specify_server_id_second: "You must specify the server ID to attach to as the second argument"
|
|
270
|
+
acting: Attaching %{volume}
|
|
271
|
+
copy:
|
|
272
|
+
desc: Create a new volume from an existing one
|
|
273
|
+
acting: Copying %{volume}
|
|
274
|
+
create:
|
|
275
|
+
desc: Create a new volume
|
|
276
|
+
acting: Creating volume
|
|
277
|
+
image_or_type_required: An 'image' or 'fs-type' option must be passed
|
|
278
|
+
either_image_or_type: An 'image' and 'fs-type' can not be passed together
|
|
279
|
+
destroy:
|
|
280
|
+
desc: Destroy one or more volumes
|
|
281
|
+
acting: Destroying %{volume}
|
|
282
|
+
detach:
|
|
283
|
+
desc: Detach a volume from a server
|
|
284
|
+
acting: Detaching %{volume}
|
|
285
|
+
list:
|
|
286
|
+
desc: List all volumes or limit using passed IDs
|
|
287
|
+
lock:
|
|
288
|
+
desc: Lock volumes
|
|
289
|
+
acting: Locking %{volume}
|
|
290
|
+
resize:
|
|
291
|
+
desc: Resize a volume
|
|
292
|
+
size_option_needed: A 'size' option is required
|
|
293
|
+
acting: Resizing %{volume}
|
|
294
|
+
show:
|
|
295
|
+
desc: Show details about multiple volumes
|
|
296
|
+
unlock:
|
|
297
|
+
desc: Unlock volumes
|
|
298
|
+
acting: Unlocking %{volume}
|
|
299
|
+
update:
|
|
300
|
+
desc: Update a volume
|
|
301
|
+
acting: Updating %{volume}
|
|
302
|
+
|
|
303
|
+
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "brightbox volumes attach" do
|
|
4
|
+
include VolumeHelpers
|
|
5
|
+
|
|
6
|
+
let(:output) { FauxIO.new { Brightbox.run(argv) } }
|
|
7
|
+
let(:stdout) { output.stdout }
|
|
8
|
+
let(:stderr) { output.stderr }
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
config_from_contents(API_CLIENT_CONFIG_CONTENTS)
|
|
12
|
+
|
|
13
|
+
stub_request(:post, "http://api.brightbox.localhost/token")
|
|
14
|
+
.to_return(
|
|
15
|
+
status: 200,
|
|
16
|
+
body: JSON.dump(
|
|
17
|
+
access_token: "ACCESS-TOKEN",
|
|
18
|
+
refresh_token: "REFRESH_TOKEN"
|
|
19
|
+
)
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
Brightbox.config.reauthenticate
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "without arguments" do
|
|
26
|
+
let(:argv) { %w[volumes attach] }
|
|
27
|
+
|
|
28
|
+
it "does not error" do
|
|
29
|
+
expect { output }.to_not raise_error
|
|
30
|
+
|
|
31
|
+
expect(stderr).to eq("ERROR: You must specify the volume ID as the first argument\n")
|
|
32
|
+
|
|
33
|
+
expect(stdout).to match("")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context "without server arguments" do
|
|
38
|
+
let(:argv) { %w[volumes attach vol-32145] }
|
|
39
|
+
|
|
40
|
+
it "does not error" do
|
|
41
|
+
expect { output }.to_not raise_error
|
|
42
|
+
|
|
43
|
+
expect(stderr).to eq("ERROR: You must specify the server ID to attach to as the second argument\n")
|
|
44
|
+
|
|
45
|
+
expect(stdout).to match("")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context "with arguments" do
|
|
50
|
+
let(:argv) { %w[volumes attach vol-809s1 srv-03431] }
|
|
51
|
+
|
|
52
|
+
before do
|
|
53
|
+
stub_request(:get, "http://api.brightbox.localhost/1.0/volumes/vol-809s1")
|
|
54
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
55
|
+
.to_return(
|
|
56
|
+
status: 200,
|
|
57
|
+
body: volume_response(
|
|
58
|
+
id: "vol-809s1",
|
|
59
|
+
status: "detached",
|
|
60
|
+
boot: false,
|
|
61
|
+
server: nil
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
.to_return(
|
|
65
|
+
status: 200,
|
|
66
|
+
body: volume_response(
|
|
67
|
+
id: "vol-809s1",
|
|
68
|
+
status: "attached",
|
|
69
|
+
boot: false,
|
|
70
|
+
server: {
|
|
71
|
+
id: "srv-03431"
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
stub_request(:post, "http://api.brightbox.localhost/1.0/volumes/vol-809s1/attach")
|
|
77
|
+
.with(query: hash_including(account_id: "acc-12345"),
|
|
78
|
+
body: hash_including(
|
|
79
|
+
server: "srv-03431",
|
|
80
|
+
boot: false
|
|
81
|
+
))
|
|
82
|
+
.to_return(
|
|
83
|
+
status: 202,
|
|
84
|
+
body: volume_response(
|
|
85
|
+
id: "vol-809s1",
|
|
86
|
+
status: "attached",
|
|
87
|
+
server: {
|
|
88
|
+
id: "srv-03431"
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "does not error" do
|
|
95
|
+
expect { output }.to_not raise_error
|
|
96
|
+
|
|
97
|
+
expect(stderr).to eq("Attaching vol-809s1\n")
|
|
98
|
+
|
|
99
|
+
aggregate_failures do
|
|
100
|
+
expect(stdout).to match("vol-809s1")
|
|
101
|
+
expect(stdout).to match("attached")
|
|
102
|
+
expect(stdout).to match("false")
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context "with boot option" do
|
|
108
|
+
let(:argv) { %w[volumes attach --boot vol-90328 srv-03431] }
|
|
109
|
+
|
|
110
|
+
before do
|
|
111
|
+
stub_request(:get, "http://api.brightbox.localhost/1.0/volumes/vol-90328")
|
|
112
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
113
|
+
.to_return(
|
|
114
|
+
status: 200,
|
|
115
|
+
body: volume_response(
|
|
116
|
+
id: "vol-90328",
|
|
117
|
+
status: "detached",
|
|
118
|
+
boot: false,
|
|
119
|
+
server: nil
|
|
120
|
+
)
|
|
121
|
+
)
|
|
122
|
+
.to_return(
|
|
123
|
+
status: 200,
|
|
124
|
+
body: volume_response(
|
|
125
|
+
id: "vol-90328",
|
|
126
|
+
status: "attached",
|
|
127
|
+
boot: true,
|
|
128
|
+
server: {
|
|
129
|
+
id: "srv-03431"
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
stub_request(:post, "http://api.brightbox.localhost/1.0/volumes/vol-90328/attach")
|
|
135
|
+
.with(query: hash_including(account_id: "acc-12345"),
|
|
136
|
+
body: hash_including(
|
|
137
|
+
server: "srv-03431",
|
|
138
|
+
boot: true
|
|
139
|
+
))
|
|
140
|
+
.to_return(
|
|
141
|
+
status: 202,
|
|
142
|
+
body: volume_response(
|
|
143
|
+
id: "vol-90328",
|
|
144
|
+
boot: true,
|
|
145
|
+
status: "attached",
|
|
146
|
+
server: {
|
|
147
|
+
id: "srv-03431"
|
|
148
|
+
}
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "does not error" do
|
|
154
|
+
expect { output }.to_not raise_error
|
|
155
|
+
|
|
156
|
+
expect(stderr).to eq("Attaching vol-90328\n")
|
|
157
|
+
|
|
158
|
+
aggregate_failures do
|
|
159
|
+
expect(stdout).to match("vol-90328")
|
|
160
|
+
expect(stdout).to match("attached")
|
|
161
|
+
expect(stdout).to match("true")
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "brightbox volumes copy" do
|
|
4
|
+
include VolumeHelpers
|
|
5
|
+
|
|
6
|
+
let(:output) { FauxIO.new { Brightbox.run(argv) } }
|
|
7
|
+
let(:stdout) { output.stdout }
|
|
8
|
+
let(:stderr) { output.stderr }
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
config_from_contents(API_CLIENT_CONFIG_CONTENTS)
|
|
12
|
+
|
|
13
|
+
stub_request(:post, "http://api.brightbox.localhost/token")
|
|
14
|
+
.to_return(
|
|
15
|
+
status: 200,
|
|
16
|
+
body: JSON.dump(
|
|
17
|
+
access_token: "ACCESS-TOKEN",
|
|
18
|
+
refresh_token: "REFRESH_TOKEN"
|
|
19
|
+
)
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
Brightbox.config.reauthenticate
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "without arguments" do
|
|
26
|
+
let(:argv) { %w[volumes copy] }
|
|
27
|
+
|
|
28
|
+
it "does not error" do
|
|
29
|
+
expect { output }.to_not raise_error
|
|
30
|
+
|
|
31
|
+
expect(stderr).to eq("ERROR: You must specify the volume ID as the first argument\n")
|
|
32
|
+
|
|
33
|
+
expect(stdout).to match("")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context "with argument" do
|
|
38
|
+
let(:argv) { %w[volumes copy vol-909ds] }
|
|
39
|
+
|
|
40
|
+
before do
|
|
41
|
+
stub_request(:get, "http://api.brightbox.localhost/1.0/volumes/vol-909ds")
|
|
42
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
43
|
+
.to_return(
|
|
44
|
+
status: 200,
|
|
45
|
+
body: volume_response(
|
|
46
|
+
id: "vol-909ds"
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
.to_return(
|
|
50
|
+
status: 200,
|
|
51
|
+
body: volume_response(
|
|
52
|
+
id: "vol-909ds"
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
stub_request(:post, "http://api.brightbox.localhost/1.0/volumes/vol-909ds/copy")
|
|
57
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
58
|
+
.to_return(
|
|
59
|
+
status: 202,
|
|
60
|
+
body: volume_response(
|
|
61
|
+
id: "vol-909ds"
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "does not error" do
|
|
67
|
+
expect { output }.to_not raise_error
|
|
68
|
+
|
|
69
|
+
expect(stderr).to eq("Copying vol-909ds\n")
|
|
70
|
+
|
|
71
|
+
expect(stdout).to match("vol-909ds")
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "brightbox volumes create" do
|
|
4
|
+
include VolumeHelpers
|
|
5
|
+
|
|
6
|
+
let(:output) { FauxIO.new { Brightbox.run(argv) } }
|
|
7
|
+
let(:stdout) { output.stdout }
|
|
8
|
+
let(:stderr) { output.stderr }
|
|
9
|
+
|
|
10
|
+
let(:token) { SecureRandom.hex }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
config_from_contents(API_CLIENT_CONFIG_CONTENTS)
|
|
14
|
+
|
|
15
|
+
stub_request(:post, "http://api.brightbox.localhost/token")
|
|
16
|
+
.to_return(status: 200, body: JSON.dump(access_token: token))
|
|
17
|
+
|
|
18
|
+
Brightbox.config.reauthenticate
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "without options" do
|
|
22
|
+
let(:argv) { %w[volumes create] }
|
|
23
|
+
|
|
24
|
+
it "does not error" do
|
|
25
|
+
expect { output }.to_not raise_error
|
|
26
|
+
|
|
27
|
+
expect(stderr).to match("ERROR: An 'image' or 'fs-type' option must be passed")
|
|
28
|
+
|
|
29
|
+
expect(stdout).to eq("")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "with mutually exclusive options" do
|
|
34
|
+
let(:argv) { %w[volumes create --image img-12345 --fs-type ext4] }
|
|
35
|
+
|
|
36
|
+
it "does not error" do
|
|
37
|
+
expect { output }.to_not raise_error
|
|
38
|
+
|
|
39
|
+
expect(stderr).to match("ERROR: An 'image' and 'fs-type' can not be passed together")
|
|
40
|
+
|
|
41
|
+
expect(stdout).to eq("")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "with image identifier" do
|
|
46
|
+
let(:argv) { %w[volumes create --image img-12345] }
|
|
47
|
+
|
|
48
|
+
before do
|
|
49
|
+
stub_request(:post, "http://api.brightbox.localhost/1.0/volumes")
|
|
50
|
+
.with(headers: { "Content-Type" => "application/json" },
|
|
51
|
+
query: hash_including(account_id: "acc-12345"),
|
|
52
|
+
body: {
|
|
53
|
+
delete_with_server: false,
|
|
54
|
+
encrypted: false,
|
|
55
|
+
image: "img-12345"
|
|
56
|
+
})
|
|
57
|
+
.to_return(
|
|
58
|
+
status: 202,
|
|
59
|
+
body: volume_response(
|
|
60
|
+
id: "vol-12345",
|
|
61
|
+
storage_type: "network",
|
|
62
|
+
size: 10_240,
|
|
63
|
+
status: "detached"
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "does not error" do
|
|
69
|
+
expect { output }.to_not raise_error
|
|
70
|
+
|
|
71
|
+
expect(stderr).not_to match("ERROR")
|
|
72
|
+
|
|
73
|
+
aggregate_failures do
|
|
74
|
+
expect(stdout).to match("id.*type.*size.*status.*server.*boot")
|
|
75
|
+
|
|
76
|
+
expect(stdout).to match("vol-12345")
|
|
77
|
+
expect(stdout).to match("network")
|
|
78
|
+
expect(stdout).to match("10240")
|
|
79
|
+
expect(stdout).to match("detached")
|
|
80
|
+
expect(stdout).to match("false")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context "with image and size" do
|
|
86
|
+
let(:argv) { %w[volumes create --image img-12345 --size 20480] }
|
|
87
|
+
|
|
88
|
+
before do
|
|
89
|
+
stub_request(:post, "http://api.brightbox.localhost/1.0/volumes")
|
|
90
|
+
.with(headers: { "Content-Type" => "application/json" },
|
|
91
|
+
query: hash_including(account_id: "acc-12345"),
|
|
92
|
+
body: {
|
|
93
|
+
delete_with_server: false,
|
|
94
|
+
encrypted: false,
|
|
95
|
+
image: "img-12345",
|
|
96
|
+
size: 20_480
|
|
97
|
+
})
|
|
98
|
+
.to_return(
|
|
99
|
+
status: 202,
|
|
100
|
+
body: volume_response(
|
|
101
|
+
id: "vol-12345",
|
|
102
|
+
storage_type: "network",
|
|
103
|
+
size: 20_480,
|
|
104
|
+
status: "detached"
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "does not error" do
|
|
110
|
+
expect { output }.to_not raise_error
|
|
111
|
+
|
|
112
|
+
expect(stderr).not_to match("ERROR")
|
|
113
|
+
|
|
114
|
+
aggregate_failures do
|
|
115
|
+
expect(stdout).to match("id.*type.*size.*status.*server.*boot")
|
|
116
|
+
|
|
117
|
+
expect(stdout).to match("vol-12345")
|
|
118
|
+
expect(stdout).to match("network")
|
|
119
|
+
expect(stdout).to match("20480")
|
|
120
|
+
expect(stdout).to match("detached")
|
|
121
|
+
expect(stdout).to match("false")
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context "with filesystem type" do
|
|
127
|
+
let(:argv) { %w[volumes create --fs-type ext4] }
|
|
128
|
+
|
|
129
|
+
before do
|
|
130
|
+
stub_request(:post, "http://api.brightbox.localhost/1.0/volumes")
|
|
131
|
+
.with(headers: { "Content-Type" => "application/json" },
|
|
132
|
+
query: hash_including(account_id: "acc-12345"),
|
|
133
|
+
body: {
|
|
134
|
+
delete_with_server: false,
|
|
135
|
+
encrypted: false,
|
|
136
|
+
filesystem_type: "ext4"
|
|
137
|
+
})
|
|
138
|
+
.to_return(
|
|
139
|
+
status: 202,
|
|
140
|
+
body: volume_response(
|
|
141
|
+
id: "vol-12345",
|
|
142
|
+
storage_type: "network",
|
|
143
|
+
size: 10_240,
|
|
144
|
+
status: "detached"
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "does not error" do
|
|
150
|
+
expect { output }.to_not raise_error
|
|
151
|
+
|
|
152
|
+
expect(stderr).not_to match("ERROR")
|
|
153
|
+
|
|
154
|
+
aggregate_failures do
|
|
155
|
+
expect(stdout).to match("id.*type.*size.*status.*server.*boot")
|
|
156
|
+
|
|
157
|
+
expect(stdout).to match("vol-12345")
|
|
158
|
+
expect(stdout).to match("network")
|
|
159
|
+
expect(stdout).to match("10240")
|
|
160
|
+
expect(stdout).to match("detached")
|
|
161
|
+
expect(stdout).to match("false")
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
context "with most options" do
|
|
167
|
+
let(:argv) do
|
|
168
|
+
%w[volumes create --fs-label fnord --fs-type ext4 --delete-with-server --encrypted --name Nom -d Test --serial 12345 -s 20480]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
before do
|
|
172
|
+
stub_request(:post, "http://api.brightbox.localhost/1.0/volumes")
|
|
173
|
+
.with(headers: { "Content-Type" => "application/json" },
|
|
174
|
+
query: hash_including(account_id: "acc-12345"),
|
|
175
|
+
body: {
|
|
176
|
+
delete_with_server: true,
|
|
177
|
+
description: "Test",
|
|
178
|
+
encrypted: true,
|
|
179
|
+
filesystem_label: "fnord",
|
|
180
|
+
filesystem_type: "ext4",
|
|
181
|
+
name: "Nom",
|
|
182
|
+
serial: "12345",
|
|
183
|
+
size: 20_480
|
|
184
|
+
})
|
|
185
|
+
.to_return(
|
|
186
|
+
status: 202,
|
|
187
|
+
body: volume_response(
|
|
188
|
+
id: "vol-43251",
|
|
189
|
+
name: "Nom",
|
|
190
|
+
boot: false,
|
|
191
|
+
description: "Test",
|
|
192
|
+
encrypted: true,
|
|
193
|
+
serial: "12345",
|
|
194
|
+
storage_type: "network",
|
|
195
|
+
size: 20_480,
|
|
196
|
+
status: "detached"
|
|
197
|
+
)
|
|
198
|
+
)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it "does not error" do
|
|
202
|
+
expect { output }.to_not raise_error
|
|
203
|
+
|
|
204
|
+
expect(stderr).not_to match("ERROR")
|
|
205
|
+
|
|
206
|
+
aggregate_failures do
|
|
207
|
+
expect(stdout).to match("id.*type.*size.*status.*server.*boot")
|
|
208
|
+
|
|
209
|
+
expect(stdout).to match("vol-43251")
|
|
210
|
+
expect(stdout).to match("network")
|
|
211
|
+
expect(stdout).to match("20480")
|
|
212
|
+
expect(stdout).to match("detached")
|
|
213
|
+
expect(stdout).to match("false")
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "brightbox volumes destroy" do
|
|
4
|
+
include VolumeHelpers
|
|
5
|
+
|
|
6
|
+
let(:output) { FauxIO.new { Brightbox.run(argv) } }
|
|
7
|
+
let(:stdout) { output.stdout }
|
|
8
|
+
let(:stderr) { output.stderr }
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
config_from_contents(API_CLIENT_CONFIG_CONTENTS)
|
|
12
|
+
|
|
13
|
+
stub_request(:post, "http://api.brightbox.localhost/token")
|
|
14
|
+
.to_return(
|
|
15
|
+
status: 200,
|
|
16
|
+
body: JSON.dump(
|
|
17
|
+
access_token: "ACCESS-TOKEN",
|
|
18
|
+
refresh_token: "REFRESH_TOKEN"
|
|
19
|
+
)
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
Brightbox.config.reauthenticate
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "without arguments" do
|
|
26
|
+
let(:argv) { %w[volumes destroy] }
|
|
27
|
+
|
|
28
|
+
it "does not error" do
|
|
29
|
+
expect { output }.to_not raise_error
|
|
30
|
+
|
|
31
|
+
expect(stderr).to eq("ERROR: You must specify volume IDs as arguments\n")
|
|
32
|
+
|
|
33
|
+
expect(stdout).to match("")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context "with one argument" do
|
|
38
|
+
let(:argv) { %w[volumes destroy vol-ui342] }
|
|
39
|
+
|
|
40
|
+
before do
|
|
41
|
+
stub_request(:get, "http://api.brightbox.localhost/1.0/volumes/vol-ui342")
|
|
42
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
43
|
+
.to_return(
|
|
44
|
+
status: 200,
|
|
45
|
+
body: volume_response(
|
|
46
|
+
id: "vol-ui342",
|
|
47
|
+
status: "detached",
|
|
48
|
+
boot: false,
|
|
49
|
+
server: {
|
|
50
|
+
id: "srv-03431"
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
.to_return(
|
|
55
|
+
status: 200,
|
|
56
|
+
body: volume_response(
|
|
57
|
+
id: "vol-ui342",
|
|
58
|
+
status: "detached",
|
|
59
|
+
boot: false,
|
|
60
|
+
server: nil
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
stub_request(:delete, "http://api.brightbox.localhost/1.0/volumes/vol-ui342")
|
|
65
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
66
|
+
.to_return(
|
|
67
|
+
status: 202,
|
|
68
|
+
body: volume_response(
|
|
69
|
+
id: "vol-ui342",
|
|
70
|
+
status: "detached",
|
|
71
|
+
server: {
|
|
72
|
+
id: "srv-03431"
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "does not error" do
|
|
79
|
+
expect { output }.to_not raise_error
|
|
80
|
+
|
|
81
|
+
expect(stderr).to match("Destroying vol-ui342\n")
|
|
82
|
+
|
|
83
|
+
expect(stdout).to eq("")
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "with multiple arguments" do
|
|
88
|
+
let(:argv) { %w[volumes destroy vol-o2342 vol-3422f] }
|
|
89
|
+
|
|
90
|
+
before do
|
|
91
|
+
stub_request(:get, "http://api.brightbox.localhost/1.0/volumes/vol-o2342")
|
|
92
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
93
|
+
.to_return(
|
|
94
|
+
status: 200,
|
|
95
|
+
body: volume_response(
|
|
96
|
+
id: "vol-o2342",
|
|
97
|
+
status: "detached",
|
|
98
|
+
boot: false,
|
|
99
|
+
server: {
|
|
100
|
+
id: "srv-03431"
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
)
|
|
104
|
+
.to_return(
|
|
105
|
+
status: 200,
|
|
106
|
+
body: volume_response(
|
|
107
|
+
id: "vol-o2342",
|
|
108
|
+
status: "detached",
|
|
109
|
+
boot: false,
|
|
110
|
+
server: nil
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
stub_request(:delete, "http://api.brightbox.localhost/1.0/volumes/vol-o2342")
|
|
115
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
116
|
+
.to_return(
|
|
117
|
+
status: 202,
|
|
118
|
+
body: volume_response(
|
|
119
|
+
id: "vol-o2342",
|
|
120
|
+
status: "detached",
|
|
121
|
+
server: {
|
|
122
|
+
id: "srv-03431"
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
stub_request(:get, "http://api.brightbox.localhost/1.0/volumes/vol-3422f")
|
|
128
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
129
|
+
.to_return(
|
|
130
|
+
status: 200,
|
|
131
|
+
body: volume_response(
|
|
132
|
+
id: "vol-3422f",
|
|
133
|
+
status: "detached",
|
|
134
|
+
boot: false,
|
|
135
|
+
server: {
|
|
136
|
+
id: "srv-03431"
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
.to_return(
|
|
141
|
+
status: 200,
|
|
142
|
+
body: volume_response(
|
|
143
|
+
id: "vol-3422f",
|
|
144
|
+
status: "detached",
|
|
145
|
+
boot: false,
|
|
146
|
+
server: nil
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
stub_request(:delete, "http://api.brightbox.localhost/1.0/volumes/vol-3422f")
|
|
151
|
+
.with(query: hash_including(account_id: "acc-12345"))
|
|
152
|
+
.to_return(
|
|
153
|
+
status: 202,
|
|
154
|
+
body: volume_response(
|
|
155
|
+
id: "vol-3422f",
|
|
156
|
+
status: "detached",
|
|
157
|
+
server: {
|
|
158
|
+
id: "srv-03431"
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "does not error" do
|
|
165
|
+
expect { output }.to_not raise_error
|
|
166
|
+
|
|
167
|
+
expect(stderr).to match("Destroying vol-o2342\n")
|
|
168
|
+
expect(stderr).to match("Destroying vol-3422f\n")
|
|
169
|
+
|
|
170
|
+
expect(stdout).to eq("")
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|