do_snapshot 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.gitignore +5 -2
- data/.rubocop.yml +3 -0
- data/.travis.yml +10 -0
- data/README.md +16 -0
- data/Rakefile +6 -0
- data/bin/do_snapshot +4 -1
- data/do_snapshot.gemspec +10 -4
- data/lib/do_snapshot.rb +47 -104
- data/lib/do_snapshot/api.rb +140 -0
- data/lib/do_snapshot/cli.rb +115 -48
- data/lib/do_snapshot/command.rb +71 -102
- data/lib/do_snapshot/core_ext/hash.rb +3 -2
- data/lib/do_snapshot/log.rb +59 -0
- data/lib/do_snapshot/mail.rb +70 -0
- data/lib/do_snapshot/version.rb +2 -1
- data/{test → log}/.keep +0 -0
- data/spec/.keep +0 -0
- data/spec/do_snapshot/api_spec.rb +218 -0
- data/spec/do_snapshot/cli_spec.rb +173 -0
- data/spec/do_snapshot/command_spec.rb +121 -0
- data/spec/do_snapshots_spec.rb +58 -0
- data/spec/fixtures/error_message.json +4 -0
- data/spec/fixtures/response_event.json +4 -0
- data/spec/fixtures/show_droplet.json +39 -0
- data/spec/fixtures/show_droplet_inactive.json +39 -0
- data/spec/fixtures/show_droplets.json +35 -0
- data/spec/fixtures/show_droplets_empty.json +4 -0
- data/spec/fixtures/show_event_done.json +10 -0
- data/spec/fixtures/show_event_start.json +10 -0
- data/spec/shared/api_helpers.rb +117 -0
- data/spec/shared/environment.rb +114 -0
- data/spec/shared/uri_helpers.rb +12 -0
- data/spec/spec_helper.rb +34 -0
- data/tmp/.keep +0 -0
- metadata +145 -23
@@ -0,0 +1,121 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe DoSnapshot::Command do
|
5
|
+
include_context 'spec'
|
6
|
+
include_context 'uri_helpers'
|
7
|
+
|
8
|
+
subject(:log) { DoSnapshot::Log }
|
9
|
+
|
10
|
+
describe '.snap' do
|
11
|
+
context 'when success' do
|
12
|
+
it 'sends success message' do
|
13
|
+
expect { snap_runner }
|
14
|
+
.not_to raise_error
|
15
|
+
expect(log.buffer)
|
16
|
+
.to include 'All operations has been finished.'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when snapshot not cleanup' do
|
21
|
+
it 'sends cleanup message' do
|
22
|
+
stub_image_destroy_fail(image_id)
|
23
|
+
stub_image_destroy_fail(image_id2)
|
24
|
+
|
25
|
+
expect { snap_runner }
|
26
|
+
.not_to raise_error
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when droplet not found' do
|
31
|
+
it 'raised by exception' do
|
32
|
+
stub_droplet_fail(droplet_id)
|
33
|
+
|
34
|
+
expect { snap_runner }
|
35
|
+
.to raise_error(DoSnapshot::DropletFindError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when failed to list droplets' do
|
40
|
+
it 'raised with droplet list error' do
|
41
|
+
stub_droplets_fail
|
42
|
+
|
43
|
+
expect { snap_runner }
|
44
|
+
.to raise_error(DoSnapshot::DropletListError)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# TODO: MUST HAVE! Now when this two works others can fail...
|
49
|
+
# context 'when droplet failed for shutdown' do
|
50
|
+
# it 'raised with shutdown error' do
|
51
|
+
# fail = stub_droplet_stop_fail(droplet_id)
|
52
|
+
#
|
53
|
+
# expect { snap_runner }
|
54
|
+
# .to raise_error(DoSnapshot::DropletShutdownError)
|
55
|
+
#
|
56
|
+
# remove_request_stub(fail)
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# context 'when no snapshot created' do
|
61
|
+
# it 'raised with snapshot create error' do
|
62
|
+
# no_snapshot = stub_droplet_snapshot_fail(droplet_id, snapshot_name)
|
63
|
+
#
|
64
|
+
# expect { snap_runner }
|
65
|
+
# .to raise_error(DoSnapshot::SnapshotCreateError)
|
66
|
+
#
|
67
|
+
# remove_request_stub(no_snapshot)
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '.fail_power_off' do
|
73
|
+
it 'when success' do
|
74
|
+
stub_droplet_inactive(droplet_id)
|
75
|
+
|
76
|
+
expect { @cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
|
77
|
+
.not_to raise_error
|
78
|
+
expect(log.buffer)
|
79
|
+
.to include 'Power On has been requested.'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'with request error' do
|
83
|
+
stub_droplet_fail(droplet_id)
|
84
|
+
|
85
|
+
expect { @cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
|
86
|
+
.to raise_error
|
87
|
+
expect(log.buffer)
|
88
|
+
.to include 'Droplet id: 100823 is Failed to Power Off.'
|
89
|
+
expect(log.buffer)
|
90
|
+
.to include 'Droplet Not Found'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'with start error' do
|
94
|
+
stub_droplet_inactive(droplet_id)
|
95
|
+
stub_droplet_start_fail(droplet_id)
|
96
|
+
stub_event_fail(event_id)
|
97
|
+
|
98
|
+
expect { @cmd.fail_power_off(DoSnapshot::DropletShutdownError.new(droplet_id)) }
|
99
|
+
.not_to raise_error
|
100
|
+
expect(log.buffer)
|
101
|
+
.to include 'Power On failed to request.'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
after(:each) do
|
106
|
+
# WebMock.reset!
|
107
|
+
stub_cleanup
|
108
|
+
end
|
109
|
+
|
110
|
+
before(:each) do
|
111
|
+
@cmd = DoSnapshot::Command.dup
|
112
|
+
stub_all_api(nil, true)
|
113
|
+
log.buffer = %w()
|
114
|
+
log.quiet = true
|
115
|
+
end
|
116
|
+
|
117
|
+
def snap_runner(options = nil)
|
118
|
+
options ||= default_options
|
119
|
+
@cmd.snap(options, [:log, :trace, :digital_ocean_client_id, :digital_ocean_api_key])
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe DoSnapshot do
|
5
|
+
include_context 'spec'
|
6
|
+
|
7
|
+
subject(:log) { DoSnapshot::Log }
|
8
|
+
|
9
|
+
describe DoSnapshot::DropletFindError do
|
10
|
+
subject(:error) { described_class }
|
11
|
+
|
12
|
+
it 'should work' do
|
13
|
+
error.new
|
14
|
+
expect(log.buffer)
|
15
|
+
.to include 'Droplet Not Found'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe DoSnapshot::DropletListError do
|
20
|
+
subject(:error) { described_class }
|
21
|
+
|
22
|
+
it 'should work' do
|
23
|
+
error.new
|
24
|
+
expect(log.buffer)
|
25
|
+
.to include 'Droplet Listing is failed to retrieve'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe DoSnapshot::SnapshotCleanupError do
|
30
|
+
subject(:error) { described_class }
|
31
|
+
|
32
|
+
it 'should be' do
|
33
|
+
|
34
|
+
expect { error.new }
|
35
|
+
.not_to raise_error
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe DoSnapshot::DropletShutdownError do
|
40
|
+
subject(:error) { described_class }
|
41
|
+
|
42
|
+
it 'should work' do
|
43
|
+
error.new(droplet_id)
|
44
|
+
expect(log.buffer)
|
45
|
+
.to include "Droplet id: #{droplet_id} is Failed to Power Off."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe DoSnapshot::SnapshotCreateError do
|
50
|
+
subject(:error) { described_class }
|
51
|
+
|
52
|
+
it 'should work' do
|
53
|
+
error.new(droplet_id)
|
54
|
+
expect(log.buffer)
|
55
|
+
.to include "Droplet id: #{droplet_id} is Failed to Snapshot."
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"status": "OK",
|
3
|
+
"droplet": {
|
4
|
+
"backups_active": null,
|
5
|
+
"id": 100823,
|
6
|
+
"image_id": 420,
|
7
|
+
"name": "foo",
|
8
|
+
"ip_address": "33.33.33.10",
|
9
|
+
"snapshots": [
|
10
|
+
{
|
11
|
+
"id": 5019770,
|
12
|
+
"name": "mrcr.ru_2014_07_19",
|
13
|
+
"slug": null,
|
14
|
+
"distribution": "CentOS"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"id": 5019903,
|
18
|
+
"name": "mrcr.ru_2014_07_19",
|
19
|
+
"slug": null,
|
20
|
+
"distribution": "CentOS"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"id": 5020783,
|
24
|
+
"name": "mrcr.ru_2014_07_19",
|
25
|
+
"slug": null,
|
26
|
+
"distribution": "CentOS"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"id": 5030783,
|
30
|
+
"name": "mrcr.ru_2014_07_19",
|
31
|
+
"slug": null,
|
32
|
+
"distribution": "CentOS"
|
33
|
+
}
|
34
|
+
],
|
35
|
+
"region_id": 1,
|
36
|
+
"size_id": 33,
|
37
|
+
"status": "active"
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"status": "OK",
|
3
|
+
"droplet": {
|
4
|
+
"backups_active": null,
|
5
|
+
"id": 100823,
|
6
|
+
"image_id": 420,
|
7
|
+
"name": "foo",
|
8
|
+
"ip_address": "33.33.33.10",
|
9
|
+
"snapshots": [
|
10
|
+
{
|
11
|
+
"id": 5019770,
|
12
|
+
"name": "mrcr.ru_2014_07_19",
|
13
|
+
"slug": null,
|
14
|
+
"distribution": "CentOS"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"id": 5019903,
|
18
|
+
"name": "mrcr.ru_2014_07_19",
|
19
|
+
"slug": null,
|
20
|
+
"distribution": "CentOS"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"id": 5020783,
|
24
|
+
"name": "mrcr.ru_2014_07_19",
|
25
|
+
"slug": null,
|
26
|
+
"distribution": "CentOS"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"id": 5030783,
|
30
|
+
"name": "mrcr.ru_2014_07_19",
|
31
|
+
"slug": null,
|
32
|
+
"distribution": "CentOS"
|
33
|
+
}
|
34
|
+
],
|
35
|
+
"region_id": 1,
|
36
|
+
"size_id": 33,
|
37
|
+
"status": "off"
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
{
|
2
|
+
"status": "OK",
|
3
|
+
"droplets": [
|
4
|
+
{
|
5
|
+
"ip_address": "33.33.33.10",
|
6
|
+
"backups_active": null,
|
7
|
+
"id": 100823,
|
8
|
+
"image_id": 420,
|
9
|
+
"name": "test222",
|
10
|
+
"region_id": 1,
|
11
|
+
"size_id": 33,
|
12
|
+
"status": "active"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"ip_address": "33.33.33.10",
|
16
|
+
"backups_active": null,
|
17
|
+
"id": 100824,
|
18
|
+
"image_id": 420,
|
19
|
+
"name": "test223",
|
20
|
+
"region_id": 1,
|
21
|
+
"size_id": 33,
|
22
|
+
"status": "active"
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"ip_address": "33.33.33.10",
|
26
|
+
"backups_active": null,
|
27
|
+
"id": 100825,
|
28
|
+
"image_id": 420,
|
29
|
+
"name": "foo",
|
30
|
+
"region_id": 1,
|
31
|
+
"size_id": 33,
|
32
|
+
"status": "active"
|
33
|
+
}
|
34
|
+
]
|
35
|
+
}
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
shared_context 'api_helpers' do
|
5
|
+
|
6
|
+
# List of droplets
|
7
|
+
#
|
8
|
+
def stub_droplets
|
9
|
+
stub_without_id(droplets_uri, 'show_droplets')
|
10
|
+
end
|
11
|
+
|
12
|
+
def stub_droplets_empty
|
13
|
+
stub_without_id(droplets_uri, 'show_droplets_empty')
|
14
|
+
end
|
15
|
+
|
16
|
+
def stub_droplets_fail
|
17
|
+
stub_without_id(droplets_uri, 'error_message')
|
18
|
+
end
|
19
|
+
|
20
|
+
# Droplet data
|
21
|
+
#
|
22
|
+
def stub_droplet(id)
|
23
|
+
stub_with_id(droplet_find_uri, id, 'show_droplet')
|
24
|
+
end
|
25
|
+
|
26
|
+
def stub_droplet_fail(id)
|
27
|
+
stub_with_id(droplet_find_uri, id, 'error_message')
|
28
|
+
end
|
29
|
+
|
30
|
+
def stub_droplet_inactive(id)
|
31
|
+
stub_with_id(droplet_find_uri, id, 'show_droplet_inactive')
|
32
|
+
end
|
33
|
+
|
34
|
+
# Droplet actions
|
35
|
+
#
|
36
|
+
def stub_droplet_stop(id)
|
37
|
+
stub_with_id(droplet_stop_uri, id, 'response_event')
|
38
|
+
end
|
39
|
+
|
40
|
+
def stub_droplet_stop_fail(id)
|
41
|
+
stub_with_id(droplet_stop_uri, id, 'error_message')
|
42
|
+
end
|
43
|
+
|
44
|
+
def stub_droplet_start(id)
|
45
|
+
stub_with_id(droplet_start_uri, id, 'response_event')
|
46
|
+
end
|
47
|
+
|
48
|
+
def stub_droplet_start_fail(id)
|
49
|
+
stub_with_id(droplet_start_uri, id, 'error_message')
|
50
|
+
end
|
51
|
+
|
52
|
+
# Snapshot
|
53
|
+
#
|
54
|
+
def stub_droplet_snapshot(id, name)
|
55
|
+
stub_with_id_name(snapshot_uri, id, name, 'response_event')
|
56
|
+
end
|
57
|
+
|
58
|
+
def stub_droplet_snapshot_fail(id, name)
|
59
|
+
stub_with_id_name(snapshot_uri, id, name, 'error_message')
|
60
|
+
end
|
61
|
+
|
62
|
+
# Event status
|
63
|
+
#
|
64
|
+
def stub_event_done(id)
|
65
|
+
stub_with_id(event_find_uri, id, 'show_event_done')
|
66
|
+
end
|
67
|
+
|
68
|
+
def stub_event_fail(id)
|
69
|
+
stub_with_id(event_find_uri, id, 'error_message')
|
70
|
+
end
|
71
|
+
|
72
|
+
def stub_event_running(id)
|
73
|
+
stub_with_id(event_find_uri, id, 'show_event_running')
|
74
|
+
end
|
75
|
+
|
76
|
+
# Image actions
|
77
|
+
#
|
78
|
+
def stub_image_destroy(id)
|
79
|
+
stub_with_id(image_destroy_uri, id, 'response_event')
|
80
|
+
end
|
81
|
+
|
82
|
+
def stub_image_destroy_fail(id)
|
83
|
+
stub_with_id(image_destroy_uri, id, 'error_message')
|
84
|
+
end
|
85
|
+
|
86
|
+
# Stub helpers
|
87
|
+
#
|
88
|
+
def stub_with_id(request, id, fixture, status = 200)
|
89
|
+
return unless request && fixture && id
|
90
|
+
stub_request(:get, url_with_id(request, id))
|
91
|
+
.to_return(status: status, body: fixture(fixture))
|
92
|
+
end
|
93
|
+
|
94
|
+
def stub_without_id(request, fixture, status = 200)
|
95
|
+
return unless request && fixture
|
96
|
+
stub_request(:get, request)
|
97
|
+
.to_return(status: status, body: fixture(fixture))
|
98
|
+
end
|
99
|
+
|
100
|
+
def stub_with_id_name(request, id, name, fixture, status = 200)
|
101
|
+
return unless request && fixture && id && name
|
102
|
+
stub_request(:get, url_with_id_name(request, id, name))
|
103
|
+
.to_return(status: status, body: fixture(fixture))
|
104
|
+
end
|
105
|
+
|
106
|
+
# Url helpers
|
107
|
+
#
|
108
|
+
def url_with_id(request, id)
|
109
|
+
return unless request && id
|
110
|
+
request.sub('[id]', id.to_s)
|
111
|
+
end
|
112
|
+
|
113
|
+
def url_with_id_name(request, id, name)
|
114
|
+
return unless request && id && name
|
115
|
+
request.sub('[id]', id.to_s).sub('[name]', name)
|
116
|
+
end
|
117
|
+
end
|