kitchen-linode 0.10.0 → 0.11.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/.codeclimate.yml +21 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +7 -7
- data/Gemfile +0 -3
- data/README.md +22 -29
- data/kitchen-linode.gemspec +2 -0
- data/lib/kitchen/driver/linode.rb +60 -43
- data/lib/kitchen/driver/linode_version.rb +1 -1
- data/spec/kitchen/driver/linode_spec.rb +170 -0
- data/spec/spec_helper.rb +14 -0
- metadata +37 -3
data/.travis.yml
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
language: ruby
|
|
2
2
|
|
|
3
3
|
rvm:
|
|
4
|
-
- 2.
|
|
5
|
-
- 1.
|
|
6
|
-
- 1.9.2
|
|
7
|
-
- ruby-head
|
|
4
|
+
- 2.3.0
|
|
5
|
+
- 2.1.5
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
script: "bundle exec rspec"
|
|
8
|
+
|
|
9
|
+
addons:
|
|
10
|
+
code_climate:
|
|
11
|
+
repo_token: e6d4bb7235b740943569bfe50196b620353970884a75f466d11cd37a2fc250f6
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
# <a name="title"></a> Kitchen::Linode
|
|
2
|
+
[](https://rubygems.org/gems/kitchen-linode)
|
|
3
|
+
[](https://rubygems.org/gems/kitchen-linode)
|
|
4
|
+
[](https://rubygems.org/gems/kitchen-linode)
|
|
5
|
+
[](https://codeclimate.com/github/ssplatt/kitchen-linode)
|
|
6
|
+
[](https://codeclimate.com/github/ssplatt/kitchen-linode/coverage)
|
|
7
|
+
[](https://travis-ci.org/ssplatt/kitchen-linode)
|
|
2
8
|
|
|
3
|
-
A Test Kitchen Driver for Linode.
|
|
9
|
+
A Test Kitchen Driver for [Linode](http://www.linode.com).
|
|
10
|
+
|
|
11
|
+
[](https://asciinema.org/a/44348)
|
|
4
12
|
|
|
5
13
|
## <a name="requirements"></a> Requirements
|
|
6
14
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
Requires [Test Kitchen](http://kitchen-ci.org) and a [Linode](http://www.linode.com) account.
|
|
16
|
+
```
|
|
17
|
+
gem install test-kitchen
|
|
18
|
+
```
|
|
10
19
|
|
|
11
20
|
## <a name="installation"></a> Installation and Setup
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
The gem file is hosted at [RubyGems](https://rubygems.org/gems/kitchen-linode). To install the gem file, run:
|
|
14
23
|
```
|
|
15
24
|
gem install kitchen-linode
|
|
16
25
|
```
|
|
26
|
+
Or, install with bundler if you have a Gemfile
|
|
17
27
|
Please read the [Driver usage][driver_usage] page for more details.
|
|
18
28
|
|
|
19
29
|
## <a name="config"></a> Configuration
|
|
@@ -21,12 +31,12 @@ Please read the [Driver usage][driver_usage] page for more details.
|
|
|
21
31
|
For many of these, you can specify an ID number, a full name, or a partial name that will try to match something in the list but may not match exactly what you want.
|
|
22
32
|
```
|
|
23
33
|
LINODE_API_KEY Linode API Key environment variable, default: nil
|
|
24
|
-
:username ssh user name, default:
|
|
34
|
+
:username ssh user name, default: "root"
|
|
25
35
|
:password password for user, default: randomly generated hash
|
|
26
|
-
:image Linux distribution, default: "Debian 8
|
|
36
|
+
:image Linux distribution, default: "Debian 8"
|
|
27
37
|
:data_center data center, default: "Atlanta"
|
|
28
38
|
:flavor linode type/amount of RAM, default: "Linode 1024"
|
|
29
|
-
:payment_terms if you happen to have legacy default: 1
|
|
39
|
+
:payment_terms if you happen to have legacy, default: 1
|
|
30
40
|
:kernel Linux kernel, default: "Latest 64 bit"
|
|
31
41
|
:private_key_path Location of your private key file, default: "~/.ssh/id_rsa"
|
|
32
42
|
:public_key_path Location of your public key file, default: "~/.ssh/id_rsa.pub"
|
|
@@ -65,7 +75,7 @@ then you're ready to run `kitchen test` or `kitchen converge`
|
|
|
65
75
|
```
|
|
66
76
|
$ kitchen test
|
|
67
77
|
```
|
|
68
|
-
If you want to create a second yaml config; one for using Vagrant locally but
|
|
78
|
+
If you want to create a second yaml config; one for using Vagrant locally but another to use the Linode driver when run on your CI server, create a config with a name like `.kitchen-ci.yml`:
|
|
69
79
|
```
|
|
70
80
|
---
|
|
71
81
|
driver:
|
|
@@ -89,9 +99,9 @@ Then you can run the second config by changing the KITCHEN_YAML environment vari
|
|
|
89
99
|
```
|
|
90
100
|
$ KITCHEN_YAML="./.kitchen-ci.yml" kitchen test
|
|
91
101
|
```
|
|
92
|
-
If you want to change any of the default settings, you can do
|
|
102
|
+
If you want to change any of the default settings, you can do so in the 'platforms' area:
|
|
93
103
|
```
|
|
94
|
-
|
|
104
|
+
...<snip>...
|
|
95
105
|
platforms:
|
|
96
106
|
- name: debian_jessie
|
|
97
107
|
driver:
|
|
@@ -99,25 +109,9 @@ platforms:
|
|
|
99
109
|
data_center: Dallas
|
|
100
110
|
kernel: 4.0.2-x86_64-linode56
|
|
101
111
|
image: Debian 7
|
|
102
|
-
|
|
112
|
+
...<snip>...
|
|
103
113
|
```
|
|
104
114
|
|
|
105
|
-
### <a name="config-require-chef-omnibus"></a> require\_chef\_omnibus
|
|
106
|
-
|
|
107
|
-
Determines whether or not a Chef [Omnibus package][chef_omnibus_dl] will be
|
|
108
|
-
installed. There are several different behaviors available:
|
|
109
|
-
|
|
110
|
-
* `true` - the latest release will be installed. Subsequent converges
|
|
111
|
-
will skip re-installing if chef is present.
|
|
112
|
-
* `latest` - the latest release will be installed. Subsequent converges
|
|
113
|
-
will always re-install even if chef is present.
|
|
114
|
-
* `<VERSION_STRING>` (ex: `10.24.0`) - the desired version string will
|
|
115
|
-
be passed the the install.sh script. Subsequent converges will skip if
|
|
116
|
-
the installed version and the desired version match.
|
|
117
|
-
* `false` or `nil` - no chef is installed.
|
|
118
|
-
|
|
119
|
-
The default value is unset, or `nil`.
|
|
120
|
-
|
|
121
115
|
## <a name="development"></a> Development
|
|
122
116
|
|
|
123
117
|
* Source hosted at [GitHub][repo]
|
|
@@ -147,4 +141,3 @@ Apache 2.0 (see [LICENSE][license])
|
|
|
147
141
|
[license]: https://github.com/ssplatt/kitchen-linode/blob/master/LICENSE
|
|
148
142
|
[repo]: https://github.com/ssplatt/kitchen-linode
|
|
149
143
|
[driver_usage]: http://docs.kitchen-ci.org/drivers/usage
|
|
150
|
-
[chef_omnibus_dl]: http://www.getchef.com/chef/install/
|
data/kitchen-linode.gemspec
CHANGED
|
@@ -23,4 +23,6 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
|
|
24
24
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
|
25
25
|
spec.add_development_dependency 'rake', '~> 10.4'
|
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
|
27
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 0.5'
|
|
26
28
|
end
|
|
@@ -32,29 +32,36 @@ module Kitchen
|
|
|
32
32
|
|
|
33
33
|
default_config :username, 'root'
|
|
34
34
|
default_config :password, nil
|
|
35
|
+
default_config :server_name, nil
|
|
35
36
|
default_config :image, 140
|
|
36
37
|
default_config :data_center, 4
|
|
37
38
|
default_config :flavor, 1
|
|
38
39
|
default_config :payment_terms, 1
|
|
39
|
-
default_config :ssh_key_name, nil
|
|
40
40
|
default_config :kernel, 138
|
|
41
41
|
|
|
42
42
|
default_config :sudo, true
|
|
43
|
-
default_config :port, 22
|
|
44
43
|
default_config :ssh_timeout, 600
|
|
45
44
|
|
|
46
|
-
default_config :
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
default_config :private_key_path do
|
|
46
|
+
%w(id_rsa).map do |k|
|
|
47
|
+
f = File.expand_path("~/.ssh/#{k}")
|
|
48
|
+
f if File.exist?(f)
|
|
49
|
+
end.compact.first
|
|
50
|
+
end
|
|
51
|
+
default_config :public_key_path do |driver|
|
|
52
|
+
driver[:private_key_path] + '.pub' if driver[:private_key_path]
|
|
53
|
+
end
|
|
50
54
|
|
|
51
55
|
default_config :api_key, ENV['LINODE_API_KEY']
|
|
52
56
|
|
|
53
57
|
required_config :api_key
|
|
58
|
+
required_config :private_key_path
|
|
59
|
+
required_config :public_key_path
|
|
54
60
|
|
|
55
61
|
def create(state)
|
|
56
62
|
# create and boot server
|
|
57
63
|
config_server_name
|
|
64
|
+
set_password
|
|
58
65
|
|
|
59
66
|
if state[:server_id]
|
|
60
67
|
info "#{config[:server_name]} (#{state[:server_id]}) already exists."
|
|
@@ -72,7 +79,7 @@ module Kitchen
|
|
|
72
79
|
info("Waiting for linode to boot...")
|
|
73
80
|
server.wait_for { ready? }
|
|
74
81
|
info("Linode <#{state[:server_id]}, #{state[:hostname]}> ready.")
|
|
75
|
-
setup_ssh(
|
|
82
|
+
setup_ssh(state) if bourne_shell?
|
|
76
83
|
rescue Fog::Errors::Error, Excon::Errors::Error => ex
|
|
77
84
|
raise ActionFailed, ex.message
|
|
78
85
|
end
|
|
@@ -94,26 +101,21 @@ module Kitchen
|
|
|
94
101
|
Fog::Compute.new(:provider => 'Linode', :linode_api_key => config[:api_key])
|
|
95
102
|
end
|
|
96
103
|
|
|
97
|
-
def
|
|
98
|
-
if config[:password].nil?
|
|
99
|
-
config[:password] = [*('a'..'z'),*('A'..'Z'),*('0'..'9')].shuffle[0,20].join
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# set datacenter
|
|
104
|
+
def get_dc
|
|
103
105
|
if config[:data_center].is_a? Integer
|
|
104
106
|
data_center = compute.data_centers.find { |dc| dc.id == config[:data_center] }
|
|
105
107
|
else
|
|
106
|
-
data_center = compute.data_centers.find { |dc| dc.location
|
|
107
|
-
if data_center.nil?
|
|
108
|
-
data_center = compute.data_centers.find { |dc| dc.location =~ /#{config[:data_center]}/ }
|
|
109
|
-
end
|
|
108
|
+
data_center = compute.data_centers.find { |dc| dc.location =~ /#{config[:data_center]}/ }
|
|
110
109
|
end
|
|
110
|
+
|
|
111
111
|
if data_center.nil?
|
|
112
112
|
fail(UserError, "No match for data_center: #{config[:data_center]}")
|
|
113
113
|
end
|
|
114
114
|
info "Got data center: #{data_center.location}..."
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
return data_center
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def get_flavor
|
|
117
119
|
if config[:flavor].is_a? Integer
|
|
118
120
|
if config[:flavor] < 1024
|
|
119
121
|
flavor = compute.flavors.find { |f| f.id == config[:flavor] }
|
|
@@ -121,51 +123,48 @@ module Kitchen
|
|
|
121
123
|
flavor = compute.flavors.find { |f| f.ram == config[:flavor] }
|
|
122
124
|
end
|
|
123
125
|
else
|
|
124
|
-
flavor = compute.flavors.find { |f| f.name
|
|
125
|
-
if flavor.nil?
|
|
126
|
-
flavor = compute.flavors.find { |f| f.name =~ /#{config[:flavor]}/ }
|
|
127
|
-
end
|
|
126
|
+
flavor = compute.flavors.find { |f| f.name =~ /#{config[:flavor]}/ }
|
|
128
127
|
end
|
|
128
|
+
|
|
129
129
|
if flavor.nil?
|
|
130
130
|
fail(UserError, "No match for flavor: #{config[:flavor]}")
|
|
131
131
|
end
|
|
132
132
|
info "Got flavor: #{flavor.name}..."
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
return flavor
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def get_image
|
|
135
137
|
if config[:image].is_a? Integer
|
|
136
138
|
image = compute.images.find { |i| i.id == config[:image] }
|
|
137
139
|
else
|
|
138
|
-
image = compute.images.find { |i| i.name
|
|
139
|
-
if image.nil?
|
|
140
|
-
image = compute.images.find { |i| i.name =~ /#{config[:image]}/ }
|
|
141
|
-
end
|
|
140
|
+
image = compute.images.find { |i| i.name =~ /#{config[:image]}/ }
|
|
142
141
|
end
|
|
143
142
|
if image.nil?
|
|
144
143
|
fail(UserError, "No match for image: #{config[:image]}")
|
|
145
144
|
end
|
|
146
145
|
info "Got image: #{image.name}..."
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
return image
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def get_kernel
|
|
149
150
|
if config[:kernel].is_a? Integer
|
|
150
151
|
kernel = compute.kernels.find { |k| k.id == config[:kernel] }
|
|
151
152
|
else
|
|
152
|
-
kernel = compute.kernels.find { |k| k.name
|
|
153
|
-
if kernel.nil?
|
|
154
|
-
kernel = compute.kernels.find { |k| k.name =~ /#{config[:kernel]}/ }
|
|
155
|
-
end
|
|
153
|
+
kernel = compute.kernels.find { |k| k.name =~ /#{config[:kernel]}/ }
|
|
156
154
|
end
|
|
157
155
|
if kernel.nil?
|
|
158
156
|
fail(UserError, "No match for kernel: #{config[:kernel]}")
|
|
159
157
|
end
|
|
160
158
|
info "Got kernel: #{kernel.name}..."
|
|
159
|
+
return kernel
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def create_server
|
|
163
|
+
data_center = get_dc
|
|
164
|
+
flavor = get_flavor
|
|
165
|
+
image = get_image
|
|
166
|
+
kernel = get_kernel
|
|
161
167
|
|
|
162
|
-
if config[:private_key_path]
|
|
163
|
-
config[:private_key_path] = File.expand_path(config[:private_key_path])
|
|
164
|
-
end
|
|
165
|
-
if config[:public_key_path]
|
|
166
|
-
config[:public_key_path] = File.expand_path(config[:public_key_path])
|
|
167
|
-
end
|
|
168
|
-
|
|
169
168
|
# submit new linode request
|
|
170
169
|
compute.servers.create(
|
|
171
170
|
:data_center => data_center,
|
|
@@ -179,7 +178,8 @@ module Kitchen
|
|
|
179
178
|
)
|
|
180
179
|
end
|
|
181
180
|
|
|
182
|
-
def setup_ssh(
|
|
181
|
+
def setup_ssh(state)
|
|
182
|
+
set_ssh_keys
|
|
183
183
|
state[:ssh_key] = config[:private_key_path]
|
|
184
184
|
do_ssh_setup(state, config)
|
|
185
185
|
end
|
|
@@ -220,6 +220,23 @@ module Kitchen
|
|
|
220
220
|
return if config[:server_name]
|
|
221
221
|
config[:server_name] = "kitchen_linode-#{rand.to_s.split('.')[1]}"
|
|
222
222
|
end
|
|
223
|
+
|
|
224
|
+
# ensure a password is set
|
|
225
|
+
def set_password
|
|
226
|
+
if config[:password].nil?
|
|
227
|
+
config[:password] = [*('a'..'z'),*('A'..'Z'),*('0'..'9')].sample(15).join
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# set ssh keys
|
|
232
|
+
def set_ssh_keys
|
|
233
|
+
if config[:private_key_path]
|
|
234
|
+
config[:private_key_path] = File.expand_path(config[:private_key_path])
|
|
235
|
+
end
|
|
236
|
+
if config[:public_key_path]
|
|
237
|
+
config[:public_key_path] = File.expand_path(config[:public_key_path])
|
|
238
|
+
end
|
|
239
|
+
end
|
|
223
240
|
end
|
|
224
241
|
end
|
|
225
242
|
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require_relative '../../spec_helper'
|
|
4
|
+
require_relative '../../../lib/kitchen/driver/linode'
|
|
5
|
+
|
|
6
|
+
require 'logger'
|
|
7
|
+
require 'stringio'
|
|
8
|
+
require 'rspec'
|
|
9
|
+
require 'kitchen'
|
|
10
|
+
require 'kitchen/driver/linode'
|
|
11
|
+
require 'kitchen/provisioner/dummy'
|
|
12
|
+
require 'kitchen/transport/dummy'
|
|
13
|
+
require 'kitchen/verifier/dummy'
|
|
14
|
+
require 'fog'
|
|
15
|
+
|
|
16
|
+
describe Kitchen::Driver::Linode do
|
|
17
|
+
let(:logged_output) { StringIO.new }
|
|
18
|
+
let(:logger) { Logger.new(logged_output) }
|
|
19
|
+
let(:config) { Hash.new }
|
|
20
|
+
let(:state) { Hash.new }
|
|
21
|
+
let(:rsa) { File.expand_path('~/.ssh/id_rsa') }
|
|
22
|
+
let(:instance_name) { 'the_thing' }
|
|
23
|
+
let(:transport) { Kitchen::Transport::Dummy.new }
|
|
24
|
+
let(:platform) { Kitchen::Platform.new(name: 'fake_platform') }
|
|
25
|
+
let(:driver) { Kitchen::Driver::Linode.new(config) }
|
|
26
|
+
|
|
27
|
+
let(:instance) do
|
|
28
|
+
double(
|
|
29
|
+
name: instance_name,
|
|
30
|
+
transport: transport,
|
|
31
|
+
logger: logger,
|
|
32
|
+
platform: platform,
|
|
33
|
+
to_str: 'instance'
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
let(:driver) { described_class.new(config) }
|
|
38
|
+
|
|
39
|
+
before(:each) do
|
|
40
|
+
allow_any_instance_of(described_class).to receive(:instance)
|
|
41
|
+
.and_return(instance)
|
|
42
|
+
allow(File).to receive(:exist?).and_call_original
|
|
43
|
+
allow(File).to receive(:exist?).with(rsa).and_return(true)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe '#finalize_config' do
|
|
47
|
+
before(:each) { allow(File).to receive(:exist?).and_return(false) }
|
|
48
|
+
|
|
49
|
+
context 'both private and public key info provided' do
|
|
50
|
+
let(:config) do
|
|
51
|
+
{ private_key_path: '/tmp/key', public_key_path: '/tmp/key.pub' }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'raises no error' do
|
|
55
|
+
expect(driver.finalize_config!(instance)).to be
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe '#initialize' do
|
|
61
|
+
context 'default options' do
|
|
62
|
+
context 'only a RSA SSH key available for the user' do
|
|
63
|
+
before(:each) do
|
|
64
|
+
allow(File).to receive(:exist?).and_return(false)
|
|
65
|
+
allow(File).to receive(:exist?).with(rsa).and_return(true)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'uses the local user\'s RSA private key' do
|
|
69
|
+
expect(driver[:private_key_path]).to eq(rsa)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'uses the local user\'s RSA public key' do
|
|
73
|
+
expect(driver[:public_key_path]).to eq(rsa + '.pub')
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
nils = [
|
|
78
|
+
:server_name,
|
|
79
|
+
:password
|
|
80
|
+
]
|
|
81
|
+
nils.each do |i|
|
|
82
|
+
it "defaults to no #{i}" do
|
|
83
|
+
expect(driver[i]).to eq(nil)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
context 'overridden options' do
|
|
89
|
+
let(:config) do
|
|
90
|
+
{
|
|
91
|
+
image: 139,
|
|
92
|
+
data_center: 10,
|
|
93
|
+
flavor: 2,
|
|
94
|
+
kernel: 215,
|
|
95
|
+
username: 'someuser',
|
|
96
|
+
server_name: 'thisserver',
|
|
97
|
+
private_key_path: '/path/to/id_rsa',
|
|
98
|
+
public_key_path: '/path/to/id_rsa.pub',
|
|
99
|
+
password: 'somepassword'
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'uses all the overridden options' do
|
|
104
|
+
drv = driver
|
|
105
|
+
config.each do |k, v|
|
|
106
|
+
expect(drv[k]).to eq(v)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'overrides server name prefix with explicit server name, if given' do
|
|
111
|
+
expect(driver[:server_name]).to eq(config[:server_name])
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe '#create' do
|
|
117
|
+
let(:server) do
|
|
118
|
+
double(id: 'test123', wait_for: true, public_ip_address: %w(1.2.3.4))
|
|
119
|
+
end
|
|
120
|
+
let(:driver) do
|
|
121
|
+
d = super()
|
|
122
|
+
allow(d).to receive(:create_server).and_return(server)
|
|
123
|
+
allow(d).to receive(:do_ssh_setup).and_return(true)
|
|
124
|
+
d
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context 'when a server is already created' do
|
|
128
|
+
it 'does not create a new instance' do
|
|
129
|
+
state[:server_id] = '1'
|
|
130
|
+
expect(driver).not_to receive(:create_server)
|
|
131
|
+
driver.create(state)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context 'required options provided' do
|
|
136
|
+
let(:config) do
|
|
137
|
+
{
|
|
138
|
+
username: 'someuser',
|
|
139
|
+
api_key: 'somekey',
|
|
140
|
+
disable_ssl_validation: false
|
|
141
|
+
}
|
|
142
|
+
end
|
|
143
|
+
let(:server) do
|
|
144
|
+
double(id: 'test123', wait_for: true, public_ip_address: %w(1.2.3.4))
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
let(:driver) do
|
|
148
|
+
d = described_class.new(config)
|
|
149
|
+
allow(d).to receive(:create_server).and_return(server)
|
|
150
|
+
allow(server).to receive(:id).and_return('test123')
|
|
151
|
+
|
|
152
|
+
allow(server).to receive(:wait_for)
|
|
153
|
+
.with(an_instance_of(Fixnum)).and_yield
|
|
154
|
+
allow(d).to receive(:bourne_shell?).and_return(false)
|
|
155
|
+
d
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it 'returns nil, but modifies the state' do
|
|
159
|
+
expect(driver.send(:create, state)).to eq(nil)
|
|
160
|
+
expect(state[:server_id]).to eq('test123')
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'throws an Action error when trying to create_server' do
|
|
164
|
+
allow(driver).to receive(:create_server).and_raise(Fog::Errors::Error)
|
|
165
|
+
expect { driver.send(:create, state) }.to raise_error(Kitchen::ActionFailed)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
end
|