kitchen-digitalocean 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore DELETED
@@ -1,20 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- .kitchen
19
- *.sw?
20
- *~
@@ -1,5 +0,0 @@
1
- Documentation:
2
- Enabled: false
3
-
4
- Semicolon:
5
- Enabled: false
@@ -1,13 +0,0 @@
1
- language: ruby
2
- cache: bundler
3
-
4
- sudo: false
5
-
6
- rvm:
7
- - 2.3.3
8
- - 2.4.0
9
- - ruby-head
10
-
11
- matrix:
12
- allow_failures:
13
- - rvm: ruby-head
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in kitchen-digitalocean.gemspec
4
- gemspec
5
-
6
- # vim: ai et ts=2 sts=2 sw=2 ft=ruby
data/README.md DELETED
@@ -1,212 +0,0 @@
1
- [![Gem Version](https://badge.fury.io/rb/kitchen-digitalocean.svg)](http://badge.fury.io/rb/kitchen-digitalocean)
2
- [![Build Status](https://travis-ci.org/test-kitchen/kitchen-digitalocean.png?branch=master)](https://travis-ci.org/test-kitchen/kitchen-digitalocean)
3
- [![Code Climate](https://codeclimate.com/github/test-kitchen/kitchen-digitalocean.png)](https://codeclimate.com/github/test-kitchen/kitchen-digitalocean)
4
- [![Coverage Status](https://coveralls.io/repos/test-kitchen/kitchen-digitalocean/badge.svg?branch=master)](https://coveralls.io/r/test-kitchen/kitchen-digitalocean?branch=master)
5
- [![Dependency Status](https://gemnasium.com/test-kitchen/kitchen-digitalocean.svg)](https://gemnasium.com/test-kitchen/kitchen-digitalocean)
6
-
7
- # Kitchen::Digitalocean
8
-
9
- A Test Kitchen Driver for Digital Ocean
10
-
11
- Shamelessly copied from [RoboticCheese](https://github.com/RoboticCheese)'s
12
- awesome work on an [Rackspace driver](https://github.com/RoboticCheese/kitchen-rackspace).
13
-
14
- # Upgrading
15
-
16
- From this version forward the driver uses [API V2](https://developers.digitalocean.com/) only.
17
- Use of image_id, flavor_id, and region_id have been replaced with image, size, and region.
18
- You can now use slugs instead of relying on the old data.json to translate IDs.
19
- Please refer to the examples below, and the API documentation for more information.
20
-
21
- # Requirements
22
-
23
- There are no external system requirements for this driver. However you will need access to an [DigitalOcean](https://digitalocean.com/) account.
24
-
25
- # Installation and Setup
26
-
27
- You'll need to install the gem on your development machine.
28
-
29
- ```Bash
30
- gem install kitchen-digitalocean
31
- ```
32
-
33
- or add it to your Gemfile if you are using [Bundler](http://bundler.io/)
34
-
35
- ```ruby
36
- source 'https://rubygems.org'
37
-
38
- gem 'test-kitchen'
39
- gem 'kitchen-digitalocean'
40
- ```
41
-
42
- At minimum, you'll need to tell test-kitchen to use the digitalocean driver.
43
-
44
- ```ruby
45
- ---
46
- driver:
47
- name: digitalocean
48
- platforms:
49
- - name: ubuntu-17
50
- ```
51
-
52
- You also have the option of providing your credentials from environment variables.
53
-
54
- ```bash
55
- export DIGITALOCEAN_ACCESS_TOKEN="1234"
56
- export DIGITALOCEAN_SSH_KEY_IDS="1234, 5678"
57
- ```
58
-
59
- Note that your `SSH_KEY_ID` must be the numeric id of your ssh key, not the symbolic name. To get the numeric ID
60
- of your keys, use something like to following command to get them from the digital ocean API:
61
-
62
- ```bash
63
- curl -X GET https://api.digitalocean.com/v2/account/keys -H "Authorization: Bearer $DIGITALOCEAN_ACCESS_TOKEN"
64
- ```
65
-
66
- Please refer to the [Getting Started Guide](http://kitchen.ci/) for any further documentation.
67
-
68
- # Default Configuration
69
-
70
- The driver now uses api v2 which provides slugs for image names, sizes, and regions.
71
-
72
- Example configuration:
73
-
74
- ```ruby
75
- ---
76
- platforms:
77
- - name: debian-7-0-x64
78
- driver_config:
79
- region: ams1
80
- - name: centos-6-4-x64
81
- driver_config:
82
- size: 2gb
83
- # ...
84
- ```
85
-
86
- # Private Networking
87
-
88
- Private networking is enabled by default, but will only work in certain regions. You can disable private networking by changing private_networking to
89
- false. Example below.
90
-
91
- ```ruby
92
- ---
93
- driver:
94
- - private_networking: false
95
- ```
96
-
97
- # IPv6
98
-
99
- IPv6 is disabled by default, you can enable this if needed. IPv6 is only available in limited regions.
100
-
101
-
102
- ```ruby
103
- ---
104
- driver:
105
- - ipv6: true
106
- ```
107
-
108
- # Image abbrevations we use
109
-
110
- This is a list of abbreviate image names we provide
111
-
112
- ```
113
- centos-6
114
- centos-7
115
- coreos-stable
116
- oreos-beta
117
- coreos-alpha
118
- debian-7
119
- debian-8
120
- debian-9
121
- fedora-27
122
- fedora-28
123
- reebsd-11.1
124
- freebsd-11.0
125
- freebsd-10.3
126
- ubuntu-14
127
- ubuntu-16
128
- ubuntu-17
129
- ubuntu-18
130
- ```
131
-
132
- # Regions
133
-
134
- ```
135
- nyc1 New York 1
136
- sfo1 San Francisco 1
137
- ams2 Amsterdam 2
138
- sgp1 Singapore 1
139
- lon1 London 1
140
- nyc3 New York 3
141
- ams3 Amsterdam 3
142
- fra1 Frankfurt 1
143
- tor1 Toronto 1
144
- sfo2 San Francisco 2
145
- blr1 Bangalore 1
146
- ```
147
-
148
-
149
- # Tags
150
-
151
- To add tags to the droplet, provide the tags attribute
152
-
153
- ```ruby
154
- driver:
155
- tags:
156
- - test-kitchen
157
- - this-is-a-tag
158
- ```
159
-
160
-
161
- # Firewall
162
-
163
- To create the droplet with firewalls, provide a pre-existing firewall ID as a
164
- string or list of string
165
-
166
- ```ruby
167
- driver:
168
- firewalls:
169
- - 7a489167-a3d5-4d93-9f4a-371bd02ea8a3
170
- - 624c1408-f101-4b59-af64-99c7f7560f7a
171
- ```
172
- or
173
- ```ruby
174
- driver:
175
- firewalls: 624c1408-f101-4b59-af64-99c7f7560f7a
176
- ```
177
-
178
- Note that your `firewalls` must be the numeric ids of your firewall. To get the
179
- numeric ID, use something like to following command to get them from the digital
180
- ocean API:
181
-
182
- ```bash
183
- curl -X GET https://api.digitalocean.com/v2/firewalls -H "Authorization: Bearer $DIGITALOCEAN_ACCESS_TOKEN"
184
- ```
185
-
186
-
187
- # Development
188
-
189
- * Source hosted at [GitHub](https://github.com/test-kitchen/kitchen-digitalocean)
190
- * Report issues/questions/feature requests on [GitHub Issues](https://github.com/test-kitchen/kitchen-digitalocean/issues)
191
-
192
- Pull requests are very welcome! Make sure your patches are well tested.
193
- Ideally create a topic branch for every separate change you make. For
194
- example:
195
-
196
- 1. Fork the repo
197
- 2. Create your feature branch (`git checkout -b my-new-feature`)
198
- 3. Commit your changes (`git commit -am 'Added some feature'`)
199
- 4. Push to the branch (`git push origin my-new-feature`)
200
- 5. Create new Pull Request
201
-
202
- # Authors
203
-
204
- Created and maintained by [Greg Fitzgerald](https://github.com/gregf/) (<greg@gregf.org>)
205
-
206
- ***Special Thanks:***
207
-
208
- [Will Farrington](https://github.com/wfarr/kitchen-digital_ocean), His fork was a help during the creation of my api v2 driver.
209
-
210
- # License
211
-
212
- Apache 2.0 (see [LICENSE](https://github.com/test-kitchen/kitchen-digitalocean/blob/master/LICENSE.txt))
data/Rakefile DELETED
@@ -1,27 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rubocop/rake_task'
3
- require 'cane/rake_task'
4
- require 'rspec/core/rake_task'
5
-
6
- desc 'Run Cane to check quality metrics'
7
- Cane::RakeTask.new
8
-
9
- desc 'Run RuboCop on the lib directory'
10
- RuboCop::RakeTask.new(:rubocop) do |task|
11
- task.patterns = ['lib/**/*.rb']
12
- # don't abort rake on failure
13
- task.fail_on_error = false
14
- end
15
-
16
- desc 'Display LOC stats'
17
- task :loc do
18
- puts "\n## LOC Stats"
19
- sh 'countloc -r lib/kitchen'
20
- end
21
-
22
- desc 'Run RSpec unit tests'
23
- RSpec::Core::RakeTask.new(:spec)
24
-
25
- task default: [:rubocop, :loc, :spec]
26
-
27
- # vim: ai et ts=2 sts=2 sw=2 ft=ruby fdm=marker
@@ -1,36 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'kitchen/driver/digitalocean_version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = 'kitchen-digitalocean'
8
- spec.version = Kitchen::Driver::DIGITALOCEAN_VERSION
9
- spec.authors = ['Greg Fitzgerald']
10
- spec.email = ['greg@gregf.org']
11
- spec.description = 'A Test Kitchen Driver for Digital Ocean'
12
- spec.summary = spec.description
13
- spec.homepage = 'https://github.com/test-kitchen/kitchen-digitalocean'
14
- spec.license = 'Apache 2.0'
15
-
16
- spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
- spec.executables = []
18
- spec.test_files = spec.files.grep(/^(test|spec|features)/)
19
- spec.require_paths = ['lib']
20
-
21
- spec.add_dependency 'test-kitchen', '~> 1.17'
22
- spec.add_dependency 'droplet_kit', '~> 2.3'
23
-
24
- spec.add_development_dependency 'bundler', '~> 1.0'
25
- spec.add_development_dependency 'rake', '~> 10.0'
26
- spec.add_development_dependency 'rubocop', '~> 0.57'
27
- spec.add_development_dependency 'cane', '~> 2.6'
28
- spec.add_development_dependency 'countloc', '~> 0.4'
29
- spec.add_development_dependency 'rspec', '~> 3.6'
30
- spec.add_development_dependency 'webmock', '~> 1.2'
31
- spec.add_development_dependency 'simplecov', '~> 0.9'
32
- spec.add_development_dependency 'simplecov-console', '~> 0.2'
33
- spec.add_development_dependency 'coveralls', '~> 0.8'
34
- end
35
-
36
- # vim: ai et ts=2 sts=2 sw=2 ft=ruby
@@ -1,314 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Jonathan Hartman (<j@p4nt5.com>)
4
- #
5
- # Copyright (C) 2013, Jonathan Hartman
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
-
19
- require_relative '../../spec_helper'
20
-
21
- require 'logger'
22
- require 'stringio'
23
- require 'rspec'
24
- require 'kitchen'
25
-
26
- describe Kitchen::Driver::Digitalocean do
27
- let(:logged_output) { StringIO.new }
28
- let(:logger) { Logger.new(logged_output) }
29
- let(:config) { Hash.new }
30
- let(:state) { Hash.new }
31
- let(:instance_name) { 'potatoes' }
32
- let(:platform_name) { 'ubuntu' }
33
-
34
- let(:instance) do
35
- double(
36
- name: instance_name,
37
- logger: logger,
38
- to_str: 'instance',
39
- platform: double(name: platform_name)
40
- )
41
- end
42
-
43
- let(:driver) { described_class.new(config) }
44
-
45
- before(:each) do
46
- allow_any_instance_of(described_class).to receive(:instance)
47
- .and_return(instance)
48
- ENV['DIGITALOCEAN_ACCESS_TOKEN'] = 'access_token'
49
- ENV['DIGITALOCEAN_SSH_KEY_IDS'] = '1234'
50
- end
51
-
52
- describe '#initialize'do
53
- context 'default options' do
54
- it 'defaults to the smallest size' do
55
- expect(driver[:size]).to eq('512mb')
56
- end
57
-
58
- it 'defaults to SSH with root user on port 22' do
59
- expect(driver[:username]).to eq('root')
60
- expect(driver[:port]).to eq('22')
61
- end
62
-
63
- it 'defaults to a random server name' do
64
- expect(driver[:server_name]).to be_a(String)
65
- end
66
-
67
- it 'defaults to region id 1' do
68
- expect(driver[:region]).to eq('nyc1')
69
- end
70
-
71
- it 'defaults to SSH Key Ids from $SSH_KEY_IDS' do
72
- expect(driver[:ssh_key_ids]).to eq('1234')
73
- end
74
-
75
- it 'defaults to Access Token from $DIGITALOCEAN_ACCESS_TOKEN' do
76
- expect(driver[:digitalocean_access_token]).to eq('access_token')
77
- end
78
- end
79
-
80
- context 'name is ubuntu-14-04-x64' do
81
- let(:platform_name) { 'ubuntu-14-04-x64' }
82
-
83
- it 'defaults to the correct image ID' do
84
- expect(driver[:image]).to eq('ubuntu-14-04-x64')
85
- end
86
- end
87
-
88
- context 'platform name matches a known platform => slug mapping' do
89
- let(:platform_name) { 'ubuntu-17' }
90
-
91
- it 'matches the correct image slug' do
92
- expect(driver[:image]).to eq('ubuntu-17-10-x64')
93
- end
94
- end
95
-
96
- context 'overridden options' do
97
- config = {
98
- image: 'debian-7-0-x64',
99
- size: '1gb',
100
- ssh_key_ids: '5678',
101
- username: 'admin',
102
- port: '2222',
103
- server_name: 'puppy',
104
- region: 'ams1'
105
- }
106
-
107
- let(:config) { config }
108
-
109
- config.each do |key, value|
110
- it "it uses the overridden #{key} option" do
111
- expect(driver[key]).to eq(value)
112
- end
113
- end
114
- end
115
- end
116
-
117
- describe '#create' do
118
- let(:server) do
119
- double(id: '1234', wait_for: true,
120
- public_ip_address: '1.2.3.4')
121
- end
122
-
123
- let(:driver) { described_class.new(config) }
124
-
125
- before(:each) do
126
- {
127
- default_name: 'a_monkey!',
128
- create_server: server,
129
- wait_for_sshd: '1.2.3.4'
130
- }.each do |k, v|
131
- allow_any_instance_of(described_class).to receive(k).and_return(v)
132
- end
133
- end
134
-
135
- context 'username and API key only provided' do
136
- let(:config) do
137
- {
138
- digitalocean_access_token: 'access_token'
139
- }
140
- end
141
-
142
- it 'generates a server name in the absence of one' do
143
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets/1234')
144
- .to_return(create)
145
- driver.create(state)
146
- expect(driver[:server_name]).to eq('a_monkey!')
147
- end
148
-
149
- it 'gets a proper server ID' do
150
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets/1234')
151
- .to_return(create)
152
- driver.create(state)
153
- expect(state[:server_id]).to eq('1234')
154
- end
155
-
156
- it 'gets a proper hostname (IP)' do
157
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets/1234')
158
- .to_return(create)
159
- driver.create(state)
160
- expect(state[:hostname]).to eq('1.2.3.4')
161
- end
162
- end
163
- end
164
-
165
- describe '#destroy' do
166
- let(:server_id) { '12345' }
167
- let(:hostname) { 'example.com' }
168
- let(:state) { { server_id: server_id, hostname: hostname } }
169
- let(:server) { double(:nil? => false, :destroy => true) }
170
- let(:servers) { double(get: server) }
171
- let(:compute) { double(servers: servers) }
172
-
173
- let(:driver) { described_class.new(config) }
174
-
175
- before(:each) do
176
- {
177
- compute: compute
178
- }.each do |k, v|
179
- allow_any_instance_of(described_class).to receive(k).and_return(v)
180
- end
181
- end
182
-
183
- context 'a live server that needs to be destroyed' do
184
- it 'destroys the server' do
185
- stub_request(:get, "https://api.digitalocean.com/v2/droplets/12345")
186
- .to_return(find)
187
- stub_request(:delete, 'https://api.digitalocean.com/v2/droplets/12345')
188
- .to_return(delete)
189
- expect(state).to receive(:delete).with(:server_id)
190
- expect(state).to receive(:delete).with(:hostname)
191
- driver.destroy(state)
192
- end
193
- end
194
-
195
- context 'no server ID present' do
196
- let(:state) { Hash.new }
197
-
198
- it 'does nothing' do
199
- allow(driver).to receive(:compute)
200
- expect(driver).not_to receive(:compute)
201
- expect(state).not_to receive(:delete)
202
- driver.destroy(state)
203
- end
204
- end
205
-
206
- context 'a server that was already destroyed' do
207
- let(:servers) do
208
- s = double('servers')
209
- allow(s).to receive(:get).with('12345').and_return(nil)
210
- s
211
- end
212
- let(:compute) { double(servers: servers) }
213
-
214
- let(:driver) { described_class.new(config) }
215
-
216
- before(:each) do
217
- {
218
- compute: compute
219
- }.each do |k, v|
220
- allow_any_instance_of(described_class).to receive(k).and_return(v)
221
- end
222
- end
223
-
224
- it 'does not try to destroy the server again' do
225
- stub_request(:get, "https://api.digitalocean.com/v2/droplets/12345")
226
- .to_return(find)
227
- stub_request(:delete, 'https://api.digitalocean.com/v2/droplets/12345')
228
- .to_return(delete)
229
- allow_message_expectations_on_nil
230
- driver.destroy(state)
231
- end
232
- end
233
- end
234
-
235
- describe '#create_server' do
236
- let(:config) do
237
- {
238
- server_name: 'hello',
239
- image: 'debian-7-0-x64',
240
- size: '1gb',
241
- region: 'nyc3'
242
- }
243
- end
244
- before(:each) do
245
- @expected = config.merge(name: config[:server_name])
246
- @expected.delete_if do |k, _|
247
- k == :server_name
248
- end
249
- end
250
- let(:droplets) do
251
- s = double('droplets')
252
- allow(s).to receive(:create) { |arg| arg }
253
- s
254
- end
255
- let(:client) { double(droplets: droplets) }
256
-
257
- before(:each) do
258
- allow_any_instance_of(described_class).to receive(:client)
259
- .and_return(client)
260
- end
261
-
262
- it 'creates the server using a compute connection' do
263
- expect(driver.send(:create_server).to_h).to include(@expected)
264
- end
265
- end
266
-
267
- describe '#default_name' do
268
- let(:login) { 'user' }
269
- let(:hostname) { 'host' }
270
-
271
- before(:each) do
272
- allow(Etc).to receive(:getlogin).and_return(login)
273
- allow(Socket).to receive(:gethostname).and_return(hostname)
274
- end
275
-
276
- it 'generates a name' do
277
- expect(driver.default_name).to match(/^potatoes-user-host-(\S*)/)
278
- end
279
-
280
- context 'local node with a long hostname' do
281
- let(:hostname) { 'ab.c' * 20 }
282
-
283
- it 'limits the generated name to 63 characters' do
284
- expect(driver.default_name.length).to be <= (63)
285
- end
286
- end
287
-
288
- context 'node with a long hostname, username, and base name' do
289
- let(:login) { 'abcd' * 20 }
290
- let(:hostname) { 'efgh' * 20 }
291
- let(:instance_name) { 'ijkl' * 20 }
292
-
293
- it 'limits the generated name to 63 characters' do
294
- expect(driver.default_name.length).to eq(63)
295
- end
296
- end
297
-
298
- context 'a login and hostname with punctuation in them' do
299
- let(:login) { 'some.u-se-r' }
300
- let(:hostname) { 'a.host-name' }
301
- let(:instance_name) { 'a.instance-name' }
302
-
303
- it 'strips out the dots to prevent bad server names' do
304
- expect(driver.default_name).to_not include('.')
305
- end
306
-
307
- it 'strips out all but the three hyphen separators' do
308
- expect(driver.default_name.count('-')).to eq(3)
309
- end
310
- end
311
- end
312
- end
313
-
314
- # vim: ai et ts=2 sts=2 sw=2 ft=ruby