do_snapshot 0.6.4 → 1.0.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/README.md +9 -2
- data/bin/do_snapshot +1 -0
- data/lib/do_snapshot.rb +1 -0
- data/lib/do_snapshot/adapter.rb +10 -7
- data/lib/do_snapshot/adapter/abstract.rb +2 -1
- data/lib/do_snapshot/adapter/{digitalocean_v2.rb → droplet_kit.rb} +50 -33
- data/lib/do_snapshot/cli.rb +1 -0
- data/lib/do_snapshot/command.rb +1 -0
- data/lib/do_snapshot/configuration.rb +1 -0
- data/lib/do_snapshot/core_ext/hash.rb +1 -0
- data/lib/do_snapshot/distribution.rb +1 -0
- data/lib/do_snapshot/gem_ext/resource_kit.rb +30 -0
- data/lib/do_snapshot/helpers.rb +1 -0
- data/lib/do_snapshot/log.rb +1 -0
- data/lib/do_snapshot/mail.rb +1 -0
- data/lib/do_snapshot/rspec.rb +12 -0
- data/lib/do_snapshot/rspec/adapter.rb +265 -0
- data/lib/do_snapshot/rspec/api_helpers.rb +45 -0
- data/lib/do_snapshot/rspec/api_v2_helpers.rb +157 -0
- data/lib/do_snapshot/rspec/environment.rb +120 -0
- data/lib/do_snapshot/rspec/uri_helpers.rb +17 -0
- data/lib/do_snapshot/runner.rb +1 -0
- data/lib/do_snapshot/version.rb +2 -1
- data/spec/do_snapshot/adapter/abstract_spec.rb +2 -1
- data/spec/do_snapshot/adapter/droplet_kit_spec.rb +9 -0
- data/spec/do_snapshot/adapter_spec.rb +3 -2
- data/spec/do_snapshot/cli_spec.rb +4 -3
- data/spec/do_snapshot/command_spec.rb +4 -3
- data/spec/do_snapshot/configuration_spec.rb +1 -0
- data/spec/do_snapshot/log_spec.rb +2 -1
- data/spec/do_snapshot/mail_spec.rb +2 -1
- data/spec/do_snapshot/runner_spec.rb +3 -2
- data/spec/do_snapshot_spec.rb +2 -1
- data/spec/spec_helper.rb +2 -4
- data/spec/support/aruba.rb +1 -0
- data/spec/support/matchers.rb +1 -0
- metadata +47 -20
- data/spec/do_snapshot/adapter/digitalocean_v2_spec.rb +0 -264
- data/spec/shared/api_helpers.rb +0 -41
- data/spec/shared/api_v2_helpers.rb +0 -153
- data/spec/shared/environment.rb +0 -116
- data/spec/shared/uri_helpers.rb +0 -13
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DoSnapshot
|
3
|
+
module RSpec
|
4
|
+
module ApiHelpers # rubocop:disable Style/Documentation
|
5
|
+
extend ::RSpec::Core::SharedContext
|
6
|
+
|
7
|
+
# Stub helpers
|
8
|
+
#
|
9
|
+
def stub_with_id(request, id, fixture, status = 200)
|
10
|
+
return unless request && fixture && id
|
11
|
+
stub_request(:get, url_with_id(request, id))
|
12
|
+
.to_return(status: status, body: fixture(fixture))
|
13
|
+
end
|
14
|
+
|
15
|
+
def stub_without_id(request, fixture, status = 200)
|
16
|
+
return unless request && fixture
|
17
|
+
stub_request(:get, request)
|
18
|
+
.to_return(status: status, body: fixture(fixture))
|
19
|
+
end
|
20
|
+
|
21
|
+
def stub_with_id_name(request, id, name, fixture, status = 200)
|
22
|
+
return unless request && fixture && id && name
|
23
|
+
stub_request(:get, url_with_id_name(request, id, name))
|
24
|
+
.to_return(status: status, body: fixture(fixture))
|
25
|
+
end
|
26
|
+
|
27
|
+
# Url helpers
|
28
|
+
#
|
29
|
+
def url_with_id(request, id)
|
30
|
+
return unless request && id
|
31
|
+
request.sub('[id]', id.to_s)
|
32
|
+
end
|
33
|
+
|
34
|
+
def url_with_event_id(request, droplet_id, id)
|
35
|
+
return unless request && id && droplet_id
|
36
|
+
request.sub('[id]', id.to_s).sub('[droplet_id]', droplet_id.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
def url_with_id_name(request, id, name)
|
40
|
+
return unless request && id && name
|
41
|
+
request.sub('[id]', id.to_s).sub('[name]', name)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DoSnapshot
|
3
|
+
module RSpec
|
4
|
+
module ApiV2Helpers # rubocop:disable Style/Documentation,Metrics/ModuleLength
|
5
|
+
extend ::RSpec::Core::SharedContext
|
6
|
+
|
7
|
+
let(:api_base) { 'https://api.digitalocean.com/v2' }
|
8
|
+
let(:droplets_api_base) { "#{api_base}/droplets" }
|
9
|
+
let(:api_access_token) { "Bearer #{access_token}" }
|
10
|
+
let(:events_api_base) { "#{api_base}/droplets/[droplet_id]/actions" }
|
11
|
+
let(:actions_api_base) { "#{api_base}/actions" }
|
12
|
+
let(:images_api_base) { "#{api_base}/images" }
|
13
|
+
let(:image_destroy_uri) { "#{images_api_base}/[id]" }
|
14
|
+
let(:droplets_uri) { "#{droplets_api_base}?page=1&per_page=1000" }
|
15
|
+
let(:droplet_find_uri) { "#{droplets_api_base}/[id]" }
|
16
|
+
let(:droplet_stop_uri) { "#{droplets_api_base}/[id]/actions" }
|
17
|
+
let(:droplet_start_uri) { "#{droplets_api_base}/[id]/actions" }
|
18
|
+
let(:snapshot_uri) { "#{droplets_api_base}/[id]/actions" }
|
19
|
+
let(:event_find_uri) { "#{events_api_base}/[id]" }
|
20
|
+
let(:action_find_uri) { "#{actions_api_base}/[id]" }
|
21
|
+
|
22
|
+
# List of droplets
|
23
|
+
#
|
24
|
+
def stub_droplets
|
25
|
+
stub_without_id(droplets_uri, 'v2/show_droplets')
|
26
|
+
end
|
27
|
+
|
28
|
+
def stub_droplets_empty
|
29
|
+
stub_without_id(droplets_uri, 'v2/show_droplets_empty')
|
30
|
+
end
|
31
|
+
|
32
|
+
def stub_droplets_fail
|
33
|
+
stub_without_id(droplets_uri, 'v2/error_message')
|
34
|
+
end
|
35
|
+
|
36
|
+
# Droplet data
|
37
|
+
#
|
38
|
+
def stub_droplet(id)
|
39
|
+
stub_with_id(droplet_find_uri, id, 'v2/show_droplet')
|
40
|
+
end
|
41
|
+
|
42
|
+
def stub_droplet_fail(id)
|
43
|
+
stub_with_id(droplet_find_uri, id, 'v2/error_message')
|
44
|
+
end
|
45
|
+
|
46
|
+
def stub_droplet_inactive(id)
|
47
|
+
stub_with_id(droplet_find_uri, id, 'v2/show_droplet_inactive')
|
48
|
+
end
|
49
|
+
|
50
|
+
# Droplet actions
|
51
|
+
#
|
52
|
+
def stub_droplet_stop(id)
|
53
|
+
stub_with_id(droplet_stop_uri, id, 'v2/show_event_power_off_start', :post,
|
54
|
+
type: 'power_off'
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def stub_droplet_stop_fail(id)
|
59
|
+
stub_with_id(droplet_stop_uri, id, 'v2/error_message', :post,
|
60
|
+
{
|
61
|
+
type: 'power_off'
|
62
|
+
},
|
63
|
+
404
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
def stub_droplet_start(id)
|
68
|
+
stub_with_id(droplet_start_uri, id, 'v2/show_event_power_on_start', :post,
|
69
|
+
type: 'power_on'
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def stub_droplet_start_done(id)
|
74
|
+
stub_with_id(droplet_start_uri, id, 'v2/show_event_power_on_done', :post,
|
75
|
+
type: 'power_on'
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def stub_droplet_start_fail(id)
|
80
|
+
stub_with_id(droplet_start_uri, id, 'v2/error_message', :post,
|
81
|
+
type: 'power_on'
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Snapshot
|
86
|
+
#
|
87
|
+
def stub_droplet_snapshot(id, name)
|
88
|
+
stub_with_id_name(snapshot_uri, id, name, 'v2/response_event', :post,
|
89
|
+
type: 'snapshot',
|
90
|
+
name: name
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
def stub_droplet_snapshot_fail(id, name)
|
95
|
+
stub_with_id_name(snapshot_uri, id, name, 'v2/error_message', :post,
|
96
|
+
{
|
97
|
+
type: 'snapshot',
|
98
|
+
name: name
|
99
|
+
},
|
100
|
+
404
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Event status
|
105
|
+
#
|
106
|
+
def stub_event_done(id)
|
107
|
+
stub_with_id(action_find_uri, id, 'v2/show_event_done')
|
108
|
+
end
|
109
|
+
|
110
|
+
def stub_event_fail(id)
|
111
|
+
stub_with_id(action_find_uri, id, 'v2/error_message')
|
112
|
+
end
|
113
|
+
|
114
|
+
def stub_event_running(id)
|
115
|
+
stub_with_id(action_find_uri, id, 'v2/show_event_start')
|
116
|
+
end
|
117
|
+
|
118
|
+
# Image actions
|
119
|
+
#
|
120
|
+
def stub_image_destroy(id)
|
121
|
+
stub_with_id(image_destroy_uri, id, 'v2/empty', :delete, nil, 204)
|
122
|
+
end
|
123
|
+
|
124
|
+
def stub_image_destroy_fail(id)
|
125
|
+
stub_with_id(image_destroy_uri, id, 'v2/error_message', :delete, nil, 404)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Stub helpers
|
129
|
+
#
|
130
|
+
def stub_with_id(request, id, fixture, type = :get, body = nil, status = 200) # rubocop:disable Metrics/ParameterLists
|
131
|
+
return unless request && fixture && id
|
132
|
+
stub_request_body(type, url_with_id(request, id), body)
|
133
|
+
.to_return(status: status, body: fixture(fixture))
|
134
|
+
end
|
135
|
+
|
136
|
+
def stub_without_id(request, fixture, type = :get, body = nil, status = 200)
|
137
|
+
return unless request && fixture
|
138
|
+
stub_request_body(type, request, body)
|
139
|
+
.to_return(status: status, body: fixture(fixture))
|
140
|
+
end
|
141
|
+
|
142
|
+
def stub_with_id_name(request, id, name, fixture, type = :get, body = nil, status = 200) # rubocop:disable Metrics/ParameterLists
|
143
|
+
return unless request && fixture && id && name
|
144
|
+
stub_request_body(type, url_with_id_name(request, id, name), body)
|
145
|
+
.to_return(status: status, body: fixture(fixture))
|
146
|
+
end
|
147
|
+
|
148
|
+
# Body Helpers
|
149
|
+
#
|
150
|
+
def stub_request_body(type, request, body)
|
151
|
+
stub_response = stub_request(type, request).with(headers: { 'Authorization' => api_access_token })
|
152
|
+
return stub_response.with(body: body) if body
|
153
|
+
stub_response
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DoSnapshot
|
3
|
+
module RSpec
|
4
|
+
module Environment # rubocop:disable Style/Documentation
|
5
|
+
extend ::RSpec::Core::SharedContext
|
6
|
+
|
7
|
+
include ApiHelpers
|
8
|
+
|
9
|
+
def do_not_send_email
|
10
|
+
allow(Pony).to receive(:deliver) { |mail| mail }
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:client_key) { 'foo' }
|
14
|
+
let(:api_key) { 'bar' }
|
15
|
+
let(:access_token) { 'sometoken' }
|
16
|
+
let(:event_id) { '7499' }
|
17
|
+
let(:droplet_id) { '100823' }
|
18
|
+
let(:image_id) { '5019770' }
|
19
|
+
let(:image_id2) { '5019903' }
|
20
|
+
let(:cli_env_nil) { Hash['DIGITAL_OCEAN_CLIENT_ID' => nil, 'DIGITAL_OCEAN_API_KEY' => nil, 'DIGITAL_OCEAN_ACCESS_TOKEN' => nil] }
|
21
|
+
let(:cli_keys) { Thor::CoreExt::HashWithIndifferentAccess.new(digital_ocean_access_token: access_token) }
|
22
|
+
let(:cli_keys_other) { Thor::CoreExt::HashWithIndifferentAccess.new(digital_ocean_access_token: 'NOTTOK') }
|
23
|
+
let(:snapshot_name) { "example.com_#{DateTime.now.strftime('%Y_%m_%d')}" }
|
24
|
+
let(:default_options) { Hash[protocol: 2, only: %w( 100823 ), exclude: %w(), keep: 3, stop: false, trace: true, clean: true, delay: 0, shutdown: true, timeout: 600] }
|
25
|
+
let(:default_options_cli) { default_options.reject { |key, _| %w( droplets threads ).include?(key.to_s) } }
|
26
|
+
let(:no_exclude) { [] }
|
27
|
+
let(:exclude) { %w( 100824 100825 ) }
|
28
|
+
let(:no_only) { [] }
|
29
|
+
let(:only) { %w( 100823 100824 ) }
|
30
|
+
let(:stop) { true }
|
31
|
+
let(:no_stop) { false }
|
32
|
+
let(:quiet) { true }
|
33
|
+
let(:no_quiet) { false }
|
34
|
+
let(:clean) { true }
|
35
|
+
let(:no_clean) { false }
|
36
|
+
let(:shutdown) { true }
|
37
|
+
let(:timeout) { 600 }
|
38
|
+
let(:delay) { 0 }
|
39
|
+
let(:log_path) { "#{project_path}/log/test.log" }
|
40
|
+
let(:mail_options) { Thor::CoreExt::HashWithIndifferentAccess.new(to: 'mail@somehost.com', from: 'from@host.com') }
|
41
|
+
let(:smtp_options) { Thor::CoreExt::HashWithIndifferentAccess.new(address: 'smtp.gmail.com', port: '25', user_name: 'someuser', password: 'somepassword') }
|
42
|
+
let(:log) { Thor::CoreExt::HashWithIndifferentAccess.new(log: log_path) }
|
43
|
+
|
44
|
+
def stub_all_api(droplets = nil, active = false)
|
45
|
+
drops = []
|
46
|
+
droplets ||= [droplet_id]
|
47
|
+
droplets.each do |droplet|
|
48
|
+
drops.push Hash[
|
49
|
+
stub_droplet: (active ? stub_droplet(droplet) : stub_droplet_inactive(droplet))
|
50
|
+
].merge(stub_droplet_api(droplet))
|
51
|
+
end
|
52
|
+
stubs = Hash[drops: drops]
|
53
|
+
@stubs = stubs.merge(default_stub_api)
|
54
|
+
end
|
55
|
+
|
56
|
+
def stub_droplet_api(droplet)
|
57
|
+
{
|
58
|
+
stub_droplet_stop: stub_droplet_stop(droplet),
|
59
|
+
stub_droplet_start: stub_droplet_start(droplet),
|
60
|
+
stub_droplet_snapshot: stub_droplet_snapshot(droplet, snapshot_name)
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_stub_api
|
65
|
+
{
|
66
|
+
stub_event_done: stub_event_done(event_id),
|
67
|
+
stub_droplets: stub_droplets,
|
68
|
+
stub_image_destroy1: stub_image_destroy(image_id),
|
69
|
+
stub_image_destroy2: stub_image_destroy(image_id2)
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def stub_cleanup
|
74
|
+
@stubs ||= {}
|
75
|
+
@stubs.each_pair do |_k, v|
|
76
|
+
remove_request_stub(v) if v.class == WebMock::RequestStub
|
77
|
+
next unless v.class == Array
|
78
|
+
|
79
|
+
v.each do |d|
|
80
|
+
d.each_pair do |_dk, dv|
|
81
|
+
remove_request_stub(dv) if v.class == WebMock::RequestStub
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def reset_api_keys
|
88
|
+
ENV['DIGITAL_OCEAN_API_KEY'] = nil
|
89
|
+
ENV['DIGITAL_OCEAN_CLIENT_ID'] = nil
|
90
|
+
ENV['DIGITAL_OCEAN_ACCESS_TOKEN'] = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_api_keys
|
94
|
+
ENV['DIGITAL_OCEAN_API_KEY'] = api_key
|
95
|
+
ENV['DIGITAL_OCEAN_CLIENT_ID'] = client_key
|
96
|
+
ENV['DIGITAL_OCEAN_ACCESS_TOKEN'] = access_token
|
97
|
+
end
|
98
|
+
|
99
|
+
def reset_singletons
|
100
|
+
DoSnapshot.configure do |config|
|
101
|
+
# config.logger = Logger.new($stdout)
|
102
|
+
config.verbose = false
|
103
|
+
config.quiet = true
|
104
|
+
end
|
105
|
+
DoSnapshot.logger = DoSnapshot::Log.new
|
106
|
+
DoSnapshot.mailer = DoSnapshot.config.mailer
|
107
|
+
end
|
108
|
+
|
109
|
+
before(:all) do
|
110
|
+
WebMock.reset!
|
111
|
+
end
|
112
|
+
|
113
|
+
before(:each) do
|
114
|
+
do_not_send_email
|
115
|
+
set_api_keys
|
116
|
+
reset_singletons
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DoSnapshot
|
3
|
+
module RSpec
|
4
|
+
module UriHelpers # rubocop:disable Style/Documentation
|
5
|
+
extend ::RSpec::Core::SharedContext
|
6
|
+
|
7
|
+
let(:droplet_url) { url_with_id(droplet_find_uri, droplet_id) }
|
8
|
+
let(:droplet_stop_url) { url_with_id(droplet_stop_uri, droplet_id) }
|
9
|
+
let(:droplet_start_url) { url_with_id(droplet_start_uri, droplet_id) }
|
10
|
+
let(:event_find_url) { url_with_id(event_find_uri, event_id) }
|
11
|
+
let(:image_destroy_url) { url_with_id(image_destroy_uri, image_id) }
|
12
|
+
let(:image_destroy2_url) { url_with_id(image_destroy_uri, image_id2) }
|
13
|
+
let(:action_find_url) { url_with_id(action_find_uri, event_id) }
|
14
|
+
let(:droplet_snapshot_url) { url_with_id_name(snapshot_uri, droplet_id, snapshot_name) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/do_snapshot/runner.rb
CHANGED
data/lib/do_snapshot/version.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
require 'spec_helper'
|
3
4
|
|
4
5
|
RSpec.describe DoSnapshot::Adapter do
|
5
|
-
|
6
|
+
include DoSnapshot::RSpec::Environment
|
6
7
|
|
7
8
|
module DoSnapshot
|
8
9
|
module Adapter
|
@@ -17,7 +18,7 @@ RSpec.describe DoSnapshot::Adapter do
|
|
17
18
|
describe '#api' do
|
18
19
|
it 'when adapter' do
|
19
20
|
api = adapter.api(2)
|
20
|
-
expect(api).to be_a_kind_of(DoSnapshot::Adapter::
|
21
|
+
expect(api).to be_a_kind_of(DoSnapshot::Adapter::DropletKit)
|
21
22
|
end
|
22
23
|
|
23
24
|
it 'when custom adapter' do
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
require 'spec_helper'
|
3
4
|
|
4
5
|
RSpec.describe DoSnapshot::CLI do
|
5
|
-
|
6
|
-
|
6
|
+
include DoSnapshot::RSpec::Environment
|
7
|
+
include DoSnapshot::RSpec::ApiV2Helpers
|
7
8
|
|
8
9
|
subject(:cli) { described_class }
|
9
|
-
subject(:api) { DoSnapshot::Adapter::
|
10
|
+
subject(:api) { DoSnapshot::Adapter::DropletKit }
|
10
11
|
|
11
12
|
describe '.initialize' do
|
12
13
|
it 'with args & options' do
|
@@ -1,15 +1,16 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
require 'spec_helper'
|
3
4
|
|
4
5
|
RSpec.describe DoSnapshot::Command do
|
5
|
-
|
6
|
-
|
6
|
+
include DoSnapshot::RSpec::Environment
|
7
|
+
include DoSnapshot::RSpec::UriHelpers
|
7
8
|
|
8
9
|
subject(:cmd) { DoSnapshot::Command.new }
|
9
10
|
subject(:log) { DoSnapshot::Log }
|
10
11
|
|
11
12
|
describe 'V2' do
|
12
|
-
|
13
|
+
include DoSnapshot::RSpec::ApiV2Helpers
|
13
14
|
|
14
15
|
describe '.snap' do
|
15
16
|
context 'when success' do
|