do_snapshot 0.0.6 → 0.0.7
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 +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
|