kitchen-openstack 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dabecabfd7d572a681fb2a9ea51dcf01c3da1113
4
- data.tar.gz: 50c2d3cce5b1ec2ce75e15c798fc97e9dabef0d3
3
+ metadata.gz: 7616b4cab10679974a5948b4136caa7740e88154
4
+ data.tar.gz: 5fde868ddac4a5d8c64cc8b21d2cade8821588c6
5
5
  SHA512:
6
- metadata.gz: cfc8a647b20323221b6f6fb583f3d1b14a807fe8c2c0463e49b96046f97f43422f35204ba97146f5a4eacbd2935a284c9aa2b3f370c74f6c75d823f92e198478
7
- data.tar.gz: fc1505ee21df47332240e176753c66bde27628af421c598fefdee31f0a56c6f5af1eaa381fbcde465866d243219547310e88bc6a53c0b25282ba3069e604eace
6
+ metadata.gz: b39b884a8057e61c4891a7438a866aa6651372e65baf6a0e899a6ad96dc5e0737916dbc6314e0494ab4463d81d3244325677fc12d9a67f2d067755171d1a49d8
7
+ data.tar.gz: fcc37f270a4c08495604f6d5efcc0882c1056ae7e6626373107261f6de4d4f71f81254598479a33c4b527d1fe7f484e10d285deebd91923eb5f706e5be754c93
@@ -0,0 +1,8 @@
1
+ CyclomaticComplexity:
2
+ Enabled: false
3
+ MethodLength:
4
+ Enabled: false
5
+ ClassLength:
6
+ Enabled: false
7
+ ClassVars:
8
+ Enabled: false
@@ -7,5 +7,4 @@ rvm:
7
7
  - 1.9.2
8
8
  - 1.9.3
9
9
  - 2.0.0
10
-
11
- # vim: ai et ts=2 sts=2 sw=2 ft=yaml
10
+ - 2.1.1
@@ -1,3 +1,8 @@
1
+ # 1.5.3 / 2014-08-01
2
+
3
+ * PR [#53][] - Rework how server names are generated, disallowing possibly
4
+ error-causing punctuation in resultant names
5
+
1
6
  # 1.5.2 / 2014-05-31
2
7
 
3
8
  ### Bug Fixes
@@ -101,6 +106,7 @@ certain specified NICs; via [@monsterzz][]
101
106
 
102
107
  * Initial release! Woo!
103
108
 
109
+ [#53]: https://github.com/test-kitchen/kitchen-openstack/pull/53
104
110
  [#50]: https://github.com/test-kitchen/kitchen-openstack/pull/50
105
111
  [#49]: https://github.com/test-kitchen/kitchen-openstack/pull/49
106
112
  [#48]: https://github.com/test-kitchen/kitchen-openstack/pull/48
data/README.md CHANGED
@@ -34,7 +34,7 @@ Provide, at a minimum, the required driver options in your `.kitchen.yml` file:
34
34
  openstack_username: [YOUR OPENSTACK USERNAME]
35
35
  openstack_api_key: [YOUR OPENSTACK API KEY]
36
36
  openstack_auth_url: [YOUR OPENSTACK AUTH URL]
37
- require_chef_omnibus: latest (if you'll be using Chef)
37
+ require_chef_omnibus: [e.g. 'true' or a version number if you need Chef]
38
38
  image_ref: [SERVER IMAGE ID]
39
39
  flavor_ref: [SERVER FLAVOR ID]
40
40
 
data/Rakefile CHANGED
@@ -1,15 +1,13 @@
1
1
  # Encoding: UTF-8
2
2
 
3
3
  require 'bundler/setup'
4
- require 'tailor/rake_task'
4
+ require 'rubocop/rake_task'
5
5
  require 'cane/rake_task'
6
6
  require 'rspec/core/rake_task'
7
7
 
8
8
  Cane::RakeTask.new
9
9
 
10
- Tailor::RakeTask.new do |task|
11
- task.file_set '**/*.rb'
12
- end
10
+ RuboCop::RakeTask.new
13
11
 
14
12
  desc 'Display LOC stats'
15
13
  task :loc do
@@ -19,4 +17,4 @@ end
19
17
 
20
18
  RSpec::Core::RakeTask.new(:spec)
21
19
 
22
- task :default => [ :cane, :tailor, :loc, :spec ]
20
+ task default: [:cane, :rubocop, :loc, :spec]
@@ -9,14 +9,14 @@ Gem::Specification.new do |spec|
9
9
  spec.version = Kitchen::Driver::OPENSTACK_VERSION
10
10
  spec.authors = ['Jonathan Hartman']
11
11
  spec.email = ['j@p4nt5.com']
12
- spec.description = %q{A Test Kitchen OpenStack Nova driver}
12
+ spec.description = 'A Test Kitchen OpenStack Nova driver'
13
13
  spec.summary = spec.description
14
14
  spec.homepage = 'https://github.com/test-kitchen/kitchen-openstack'
15
15
  spec.license = 'Apache'
16
16
 
17
- spec.files = `git ls-files`.split($/)
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
20
20
  spec.require_paths = ['lib']
21
21
 
22
22
  spec.add_dependency 'test-kitchen', '~> 1.1'
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.add_development_dependency 'bundler'
29
29
  spec.add_development_dependency 'rake'
30
- spec.add_development_dependency 'tailor'
30
+ spec.add_development_dependency 'rubocop'
31
31
  spec.add_development_dependency 'cane'
32
32
  spec.add_development_dependency 'countloc'
33
33
  spec.add_development_dependency 'rspec'
@@ -34,10 +34,10 @@ module Kitchen
34
34
 
35
35
  default_config :server_name, nil
36
36
  default_config :key_name, nil
37
- default_config :private_key_path do |driver|
38
- %w{id_rsa id_dsa}.collect do |k|
37
+ default_config :private_key_path do
38
+ %w(id_rsa id_dsa).map do |k|
39
39
  f = File.expand_path "~/.ssh/#{k}"
40
- f if File.exists? f
40
+ f if File.exist?(f)
41
41
  end.compact.first
42
42
  end
43
43
  default_config :public_key_path do |driver|
@@ -57,11 +57,15 @@ module Kitchen
57
57
 
58
58
  def create(state)
59
59
  config[:server_name] ||= generate_name(instance.name)
60
- config[:disable_ssl_validation] and disable_ssl_validation
60
+ config[:disable_ssl_validation] && disable_ssl_validation
61
61
  server = create_server
62
62
  state[:server_id] = server.id
63
63
  info "OpenStack instance <#{state[:server_id]}> created."
64
- server.wait_for { print '.'; ready? } ; info "\n(server ready)"
64
+ server.wait_for do
65
+ print '.'
66
+ ready?
67
+ end
68
+ info "\n(server ready)"
65
69
  if config[:floating_ip_pool]
66
70
  attach_ip_from_pool(server, config[:floating_ip_pool])
67
71
  elsif config[:floating_ip]
@@ -69,17 +73,15 @@ module Kitchen
69
73
  end
70
74
  state[:hostname] = get_ip(server)
71
75
  state[:ssh_key] = config[:private_key_path]
72
- wait_for_sshd(state[:hostname], config[:username],
73
- { :port => config[:port] }) ; info '(ssh ready)'
76
+ wait_for_sshd(state[:hostname], config[:username], port: config[:port])
77
+ info '(ssh ready)'
74
78
  if config[:key_name]
75
79
  info "Using OpenStack keypair <#{config[:key_name]}>"
76
80
  end
77
81
  info "Using public SSH key <#{config[:public_key_path]}>"
78
82
  info "Using private SSH key <#{config[:private_key_path]}>"
79
- add_ohai_hint(state, config, server)
80
- unless config[:key_name]
81
- do_ssh_setup(state, config, server)
82
- end
83
+ add_ohai_hint(state)
84
+ do_ssh_setup(state, config, server) unless config[:key_name]
83
85
  rescue Fog::Errors::Error, Excon::Errors::Error => ex
84
86
  raise ActionFailed, ex.message
85
87
  end
@@ -87,7 +89,7 @@ module Kitchen
87
89
  def destroy(state)
88
90
  return if state[:server_id].nil?
89
91
 
90
- config[:disable_ssl_validation] and disable_ssl_validation
92
+ config[:disable_ssl_validation] && disable_ssl_validation
91
93
  server = compute.servers.get(state[:server_id])
92
94
  server.destroy unless server.nil?
93
95
  info "OpenStack instance <#{state[:server_id]}> destroyed."
@@ -99,20 +101,21 @@ module Kitchen
99
101
 
100
102
  def openstack_server
101
103
  server_def = {
102
- :provider => 'OpenStack',
103
- :openstack_username => config[:openstack_username],
104
- :openstack_api_key => config[:openstack_api_key],
105
- :openstack_auth_url => config[:openstack_auth_url]
104
+ provider: 'OpenStack'
106
105
  }
107
- optional = [
108
- :openstack_tenant, :openstack_region, :openstack_service_name
109
- ]
110
- optional.each do |o|
111
- config[o] and server_def[o] = config[o]
112
- end
106
+ required_server_settings.each { |s| server_def[s] = config[s] }
107
+ optional_server_settings.each { |s| server_def[s] = config[s] }
113
108
  server_def
114
109
  end
115
110
 
111
+ def required_server_settings
112
+ [:openstack_username, :openstack_api_key, :openstack_auth_url]
113
+ end
114
+
115
+ def optional_server_settings
116
+ [:openstack_tenant, :openstack_region, :openstack_service_name]
117
+ end
118
+
116
119
  def network
117
120
  Fog::Network.new(openstack_server)
118
121
  end
@@ -148,22 +151,18 @@ module Kitchen
148
151
 
149
152
  def init_config
150
153
  {
151
- :name => config[:server_name],
152
- :image_ref => find_image(config[:image_ref]).id,
153
- :flavor_ref => find_flavor(config[:flavor_ref]).id,
154
+ name: config[:server_name],
155
+ image_ref: find_image(config[:image_ref]).id,
156
+ flavor_ref: find_flavor(config[:flavor_ref]).id
154
157
  }
155
158
  end
156
159
 
157
160
  def optional_config(c)
158
161
  case c
159
162
  when :security_groups
160
- if config[c].kind_of?(Array)
161
- config[c]
162
- end
163
+ config[c] if config[c].is_a?(Array)
163
164
  when :user_data
164
- if File.exist?(config[c])
165
- File.open(config[c]) { |f| f.read }
166
- end
165
+ File.open(config[c]) { |f| f.read } if File.exist?(config[c])
167
166
  else
168
167
  config[c]
169
168
  end
@@ -171,61 +170,53 @@ module Kitchen
171
170
 
172
171
  def find_image(image_ref)
173
172
  image = find_matching(compute.images, image_ref)
174
- raise ActionFailed, 'Image not found' if !image
173
+ fail(ActionFailed, 'Image not found') unless image
175
174
  debug "Selected image: #{image.id} #{image.name}"
176
175
  image
177
176
  end
178
177
 
179
178
  def find_flavor(flavor_ref)
180
179
  flavor = find_matching(compute.flavors, flavor_ref)
181
- raise ActionFailed, 'Flavor not found' if !flavor
180
+ fail(ActionFailed, 'Flavor not found') unless flavor
182
181
  debug "Selected flavor: #{flavor.id} #{flavor.name}"
183
182
  flavor
184
183
  end
185
184
 
186
185
  def find_network(network_ref)
187
186
  net = find_matching(network.networks.all, network_ref)
188
- raise ActionFailed, 'Network not found' if !net
187
+ fail(ActionFailed, 'Network not found') unless net
189
188
  debug "Selected net: #{net.id} #{net.name}"
190
189
  net
191
190
  end
192
191
 
192
+ # Generate what should be a unique server name up to 63 total chars
193
+ # Base name: 15
194
+ # Username: 15
195
+ # Hostname: 23
196
+ # Random string: 7
197
+ # Separators: 3
198
+ # ================
199
+ # Total: 63
193
200
  def generate_name(base)
194
- # Generate what should be a unique server name up to 63 total chars
195
- # Base name: 15
196
- # Username: 15
197
- # Hostname: 23
198
- # Random string: 7
199
- # Separators: 3
200
- # ================
201
- # Total: 63
202
201
  sep = '-'
203
202
  pieces = [
204
- base,
205
- Etc.getlogin,
206
- Socket.gethostname,
203
+ base.gsub(/\W/, '')[0..14],
204
+ Etc.getlogin.gsub(/\W/, '')[0..14],
205
+ Socket.gethostname.gsub(/\W/, '')[0..22],
207
206
  Array.new(7) { rand(36).to_s(36) }.join
208
207
  ]
209
- until pieces.join(sep).length <= 63 do
210
- if pieces[2].length > 23
211
- pieces[2] = pieces[2][0..-2]
212
- elsif pieces[1].length > 15
213
- pieces[1] = pieces[1][0..-2]
214
- elsif pieces[0].length > 15
215
- pieces[0] = pieces[0][0..-2]
216
- end
217
- end
218
- pieces.join sep
208
+ puts "Name: #{pieces.join(sep)}"
209
+ pieces.join(sep)
219
210
  end
220
211
 
221
212
  def attach_ip_from_pool(server, pool)
222
213
  @@ip_pool_lock.synchronize do
223
214
  info "Attaching floating IP from <#{pool}> pool"
224
- free_addrs = compute.addresses.collect do |i|
225
- i.ip if i.fixed_ip.nil? and i.instance_id.nil? and i.pool == pool
215
+ free_addrs = compute.addresses.map do |i|
216
+ i.ip if i.fixed_ip.nil? && i.instance_id.nil? && i.pool == pool
226
217
  end.compact
227
218
  if free_addrs.empty?
228
- raise ActionFailed, "No available IPs in pool <#{pool}>"
219
+ fail ActionFailed, "No available IPs in pool <#{pool}>"
229
220
  end
230
221
  config[:floating_ip] = free_addrs[0]
231
222
  attach_ip(server, free_addrs[0])
@@ -252,11 +243,11 @@ module Kitchen
252
243
  rescue Fog::Compute::OpenStack::NotFound
253
244
  # See Fog issue: https://github.com/fog/fog/issues/2160
254
245
  addrs = server.addresses
255
- addrs['public'] and pub = addrs['public'].map { |i| i['addr'] }
256
- addrs['private'] and priv = addrs['private'].map { |i| i['addr'] }
246
+ addrs['public'] && pub = addrs['public'].map { |i| i['addr'] }
247
+ addrs['private'] && priv = addrs['private'].map { |i| i['addr'] }
257
248
  end
258
249
  pub, priv = parse_ips(pub, priv)
259
- pub.first || priv.first || raise(ActionFailed, 'Could not find an IP')
250
+ pub.first || priv.first || fail(ActionFailed, 'Could not find an IP')
260
251
  end
261
252
 
262
253
  def parse_ips(pub, priv)
@@ -266,27 +257,28 @@ module Kitchen
266
257
  else
267
258
  [pub, priv].each { |n| n.select! { |i| IPAddr.new(i).ipv4? } }
268
259
  end
269
- return pub, priv
260
+ [pub, priv]
270
261
  end
271
262
 
272
- def add_ohai_hint(state, config, server)
263
+ def add_ohai_hint(state)
273
264
  info 'Adding OpenStack hint for ohai'
274
265
  ssh = Fog::SSH.new(*build_ssh_args(state))
275
266
  ssh.run([
276
- %{sudo mkdir -p #{Ohai::Config[:hints_path][0]}},
277
- %{sudo touch #{Ohai::Config[:hints_path][0]}/openstack.json}
267
+ %(sudo mkdir -p #{Ohai::Config[:hints_path][0]}),
268
+ %(sudo touch #{Ohai::Config[:hints_path][0]}/openstack.json)
278
269
  ])
279
270
  end
280
271
 
281
272
  def do_ssh_setup(state, config, server)
282
273
  info "Setting up SSH access for key <#{config[:public_key_path]}>"
283
- ssh = Fog::SSH.new(state[:hostname], config[:username],
284
- { :password => server.password })
274
+ ssh = Fog::SSH.new(state[:hostname],
275
+ config[:username],
276
+ password: server.password)
285
277
  pub_key = open(config[:public_key_path]).read
286
278
  ssh.run([
287
- %{mkdir .ssh},
288
- %{echo "#{pub_key}" >> ~/.ssh/authorized_keys},
289
- %{passwd -l #{config[:username]}}
279
+ %(mkdir .ssh),
280
+ %(echo "#{pub_key}" >> ~/.ssh/authorized_keys),
281
+ %(passwd -l #{config[:username]})
290
282
  ])
291
283
  end
292
284
 
@@ -297,25 +289,18 @@ module Kitchen
297
289
 
298
290
  def find_matching(collection, name)
299
291
  name = name.to_s
300
- if name.start_with?('/')
301
- regex = eval(name)
292
+ if name.start_with?('/') && name.end_with?('/')
293
+ regex = Regexp.new(name[1...-1])
302
294
  # check for regex name match
303
- collection.each do |single|
304
- return single if regex =~ single.name
305
- end
295
+ collection.each { |single| return single if regex =~ single.name }
306
296
  else
307
297
  # check for exact id match
308
- collection.each do |single|
309
- return single if single.id == name
310
- end
298
+ collection.each { |single| return single if single.id == name }
311
299
  # check for exact name match
312
- collection.each do |single|
313
- return single if single.name == name
314
- end
300
+ collection.each { |single| return single if single.name == name }
315
301
  end
316
302
  nil
317
303
  end
318
-
319
304
  end
320
305
  end
321
306
  end
@@ -17,8 +17,10 @@
17
17
  # limitations under the License.
18
18
 
19
19
  module Kitchen
20
+ # Version string for OpenStack Kitchen driver
21
+ #
22
+ # @author Jonathan Hartman <j@p4nt5.com>
20
23
  module Driver
21
- # Version string for OpenStack Kitchen driver
22
- OPENSTACK_VERSION = '1.5.2'
24
+ OPENSTACK_VERSION = '1.5.3'
23
25
  end
24
26
  end
@@ -34,7 +34,7 @@ describe Kitchen::Driver::Openstack do
34
34
 
35
35
  let(:instance) do
36
36
  double(
37
- :name => 'potatoes', :logger => logger, :to_str => 'instance'
37
+ name: 'potatoes', logger: logger, to_str: 'instance'
38
38
  )
39
39
  end
40
40
 
@@ -45,9 +45,9 @@ describe Kitchen::Driver::Openstack do
45
45
  end
46
46
 
47
47
  before(:each) do
48
- File.stub(:exists?).and_call_original
49
- File.stub(:exists?).with(dsa).and_return(true)
50
- File.stub(:exists?).with(rsa).and_return(true)
48
+ allow(File).to receive(:exist?).and_call_original
49
+ allow(File).to receive(:exist?).with(dsa).and_return(true)
50
+ allow(File).to receive(:exist?).with(rsa).and_return(true)
51
51
  end
52
52
 
53
53
  describe '#initialize'do
@@ -64,9 +64,8 @@ describe Kitchen::Driver::Openstack do
64
64
 
65
65
  context 'only a DSA SSH key available for the user' do
66
66
  before(:each) do
67
- File.unstub(:exists?)
68
- File.stub(:exists?).and_return(false)
69
- File.stub(:exists?).with(dsa).and_return(true)
67
+ allow(File).to receive(:exist?).and_return(false)
68
+ allow(File).to receive(:exist?).with(dsa).and_return(true)
70
69
  end
71
70
 
72
71
  it 'uses the local user\'s DSA private key' do
@@ -80,9 +79,8 @@ describe Kitchen::Driver::Openstack do
80
79
 
81
80
  context 'only a RSA SSH key available for the user' do
82
81
  before(:each) do
83
- File.unstub(:exists?)
84
- File.stub(:exists?).and_return(false)
85
- File.stub(:exists?).with(rsa).and_return(true)
82
+ allow(File).to receive(:exist?).and_return(false)
83
+ allow(File).to receive(:exist?).with(rsa).and_return(true)
86
84
  end
87
85
 
88
86
  it 'uses the local user\'s RSA private key' do
@@ -118,19 +116,19 @@ describe Kitchen::Driver::Openstack do
118
116
  context 'overridden options' do
119
117
  let(:config) do
120
118
  {
121
- :image_ref => '22',
122
- :flavor_ref => '33',
123
- :public_key_path => '/tmp',
124
- :username => 'admin',
125
- :port => '2222',
126
- :server_name => 'puppy',
127
- :openstack_tenant => 'that_one',
128
- :openstack_region => 'atlantis',
129
- :openstack_service_name => 'the_service',
130
- :private_key_path => '/path/to/id_rsa',
131
- :floating_ip_pool => 'swimmers',
132
- :floating_ip => '11111',
133
- :network_ref => '0xCAFFE'
119
+ image_ref: '22',
120
+ flavor_ref: '33',
121
+ public_key_path: '/tmp',
122
+ username: 'admin',
123
+ port: '2222',
124
+ server_name: 'puppy',
125
+ openstack_tenant: 'that_one',
126
+ openstack_region: 'atlantis',
127
+ openstack_service_name: 'the_service',
128
+ private_key_path: '/path/to/id_rsa',
129
+ floating_ip_pool: 'swimmers',
130
+ floating_ip: '11111',
131
+ network_ref: '0xCAFFE'
134
132
  }
135
133
  end
136
134
 
@@ -145,31 +143,29 @@ describe Kitchen::Driver::Openstack do
145
143
 
146
144
  describe '#create' do
147
145
  let(:server) do
148
- double(:id => 'test123', :wait_for => true,
149
- :public_ip_addresses => %w{1.2.3.4})
146
+ double(id: 'test123', wait_for: true, public_ip_addresses: %w(1.2.3.4))
150
147
  end
151
148
  let(:driver) do
152
149
  d = Kitchen::Driver::Openstack.new(config)
153
150
  d.instance = instance
154
- d.stub(:generate_name).with('potatoes').and_return('a_monkey!')
155
- d.stub(:create_server).and_return(server)
156
- d.stub(:wait_for_sshd).with(
157
- '1.2.3.4',
158
- 'root',
159
- { :port => '22' }).and_return(true)
160
- d.stub(:get_ip).and_return('1.2.3.4')
161
- d.stub(:add_ohai_hint).and_return(true)
162
- d.stub(:do_ssh_setup).and_return(true)
151
+ allow(d).to receive(:generate_name).with('potatoes')
152
+ .and_return('a_monkey!')
153
+ allow(d).to receive(:create_server).and_return(server)
154
+ allow(d).to receive(:wait_for_sshd).with('1.2.3.4', 'root', port: '22')
155
+ .and_return(true)
156
+ allow(d).to receive(:get_ip).and_return('1.2.3.4')
157
+ allow(d).to receive(:add_ohai_hint).and_return(true)
158
+ allow(d).to receive(:do_ssh_setup).and_return(true)
163
159
  d
164
160
  end
165
161
 
166
162
  context 'required options provided' do
167
163
  let(:config) do
168
164
  {
169
- :openstack_username => 'hello',
170
- :openstack_api_key => 'world',
171
- :openstack_auth_url => 'http:',
172
- :openstack_tenant => 'www'
165
+ openstack_username: 'hello',
166
+ openstack_api_key: 'world',
167
+ openstack_auth_url: 'http:',
168
+ openstack_tenant: 'www'
173
169
  }
174
170
  end
175
171
 
@@ -189,16 +185,16 @@ describe Kitchen::Driver::Openstack do
189
185
  end
190
186
 
191
187
  it 'does not disable SSL validation' do
192
- driver.should_not_receive(:disable_ssl_validation)
188
+ expect(driver).to_not receive(:disable_ssl_validation)
193
189
  driver.create(state)
194
190
  end
195
191
  end
196
192
 
197
193
  context 'SSL validation disabled' do
198
- let(:config) { { :disable_ssl_validation => true } }
194
+ let(:config) { { disable_ssl_validation: true } }
199
195
 
200
196
  it 'disables SSL cert validation' do
201
- driver.should_receive(:disable_ssl_validation)
197
+ expect(driver).to receive(:disable_ssl_validation)
202
198
  driver.create(state)
203
199
  end
204
200
  end
@@ -207,27 +203,27 @@ describe Kitchen::Driver::Openstack do
207
203
  describe '#destroy' do
208
204
  let(:server_id) { '12345' }
209
205
  let(:hostname) { 'example.com' }
210
- let(:state) { { :server_id => server_id, :hostname => hostname } }
211
- let(:server) { double(:nil? => false, :destroy => true) }
212
- let(:servers) { double(:get => server) }
213
- let(:compute) { double(:servers => servers) }
206
+ let(:state) { { server_id: server_id, hostname: hostname } }
207
+ let(:server) { double(nil?: false, destroy: true) }
208
+ let(:servers) { double(get: server) }
209
+ let(:compute) { double(servers: servers) }
214
210
 
215
211
  let(:driver) do
216
212
  d = Kitchen::Driver::Openstack.new(config)
217
213
  d.instance = instance
218
- d.stub(:compute).and_return(compute)
214
+ allow(d).to receive(:compute).and_return(compute)
219
215
  d
220
216
  end
221
217
 
222
218
  context 'a live server that needs to be destroyed' do
223
219
  it 'destroys the server' do
224
- state.should_receive(:delete).with(:server_id)
225
- state.should_receive(:delete).with(:hostname)
220
+ expect(state).to receive(:delete).with(:server_id)
221
+ expect(state).to receive(:delete).with(:hostname)
226
222
  driver.destroy(state)
227
223
  end
228
224
 
229
225
  it 'does not disable SSL cert validation' do
230
- driver.should_not_receive(:disable_ssl_validation)
226
+ expect(driver).to_not receive(:disable_ssl_validation)
231
227
  driver.destroy(state)
232
228
  end
233
229
  end
@@ -236,9 +232,9 @@ describe Kitchen::Driver::Openstack do
236
232
  let(:state) { Hash.new }
237
233
 
238
234
  it 'does nothing' do
239
- driver.stub(:compute)
240
- driver.should_not_receive(:compute)
241
- state.should_not_receive(:delete)
235
+ allow(driver).to receive(:compute)
236
+ expect(driver).to_not receive(:compute)
237
+ expect(state).to_not receive(:delete)
242
238
  driver.destroy(state)
243
239
  end
244
240
  end
@@ -246,14 +242,14 @@ describe Kitchen::Driver::Openstack do
246
242
  context 'a server that was already destroyed' do
247
243
  let(:servers) do
248
244
  s = double('servers')
249
- s.stub(:get).with('12345').and_return(nil)
245
+ allow(s).to receive(:get).with('12345').and_return(nil)
250
246
  s
251
247
  end
252
- let(:compute) { double(:servers => servers) }
248
+ let(:compute) { double(servers: servers) }
253
249
  let(:driver) do
254
250
  d = Kitchen::Driver::Openstack.new(config)
255
251
  d.instance = instance
256
- d.stub(:compute).and_return(compute)
252
+ allow(d).to receive(:compute).and_return(compute)
257
253
  d
258
254
  end
259
255
 
@@ -264,43 +260,79 @@ describe Kitchen::Driver::Openstack do
264
260
  end
265
261
 
266
262
  context 'SSL validation disabled' do
267
- let(:config) { { :disable_ssl_validation => true } }
263
+ let(:config) { { disable_ssl_validation: true } }
268
264
 
269
265
  it 'disables SSL cert validation' do
270
- driver.should_receive(:disable_ssl_validation)
266
+ expect(driver).to receive(:disable_ssl_validation)
271
267
  driver.destroy(state)
272
268
  end
273
269
  end
274
270
  end
275
271
 
272
+ describe '#openstack_server' do
273
+ let(:config) do
274
+ {
275
+ openstack_username: 'a',
276
+ openstack_api_key: 'b',
277
+ openstack_auth_url: 'http://',
278
+ openstack_tenant: 'me',
279
+ openstack_region: 'ORD',
280
+ openstack_service_name: 'stack'
281
+ }
282
+ end
283
+
284
+ it 'returns a hash of server settings' do
285
+ expected = config.merge(provider: 'OpenStack')
286
+ expect(driver.send(:openstack_server)).to eq(expected)
287
+ end
288
+ end
289
+
290
+ describe '#required_server_settings' do
291
+ it 'returns the required settings for an OpenStack server' do
292
+ expected = [
293
+ :openstack_username, :openstack_api_key, :openstack_auth_url
294
+ ]
295
+ expect(driver.send(:required_server_settings)).to eq(expected)
296
+ end
297
+ end
298
+
299
+ describe '#optional_server_settings' do
300
+ it 'returns the optional settings for an OpenStack server' do
301
+ expected = [
302
+ :openstack_tenant, :openstack_region, :openstack_service_name
303
+ ]
304
+ expect(driver.send(:optional_server_settings)).to eq(expected)
305
+ end
306
+ end
307
+
276
308
  describe '#compute' do
277
309
  let(:config) do
278
310
  {
279
- :openstack_username => 'monkey',
280
- :openstack_api_key => 'potato',
281
- :openstack_auth_url => 'http:',
282
- :openstack_tenant => 'link',
283
- :openstack_region => 'ord',
284
- :openstack_service_name => 'the_service'
311
+ openstack_username: 'monkey',
312
+ openstack_api_key: 'potato',
313
+ openstack_auth_url: 'http:',
314
+ openstack_tenant: 'link',
315
+ openstack_region: 'ord',
316
+ openstack_service_name: 'the_service'
285
317
  }
286
318
  end
287
319
 
288
320
  context 'all requirements provided' do
289
321
  it 'creates a new compute connection' do
290
- Fog::Compute.stub(:new) { |arg| arg }
291
- res = config.merge({ :provider => 'OpenStack' })
322
+ allow(Fog::Compute).to receive(:new) { |arg| arg }
323
+ res = config.merge(provider: 'OpenStack')
292
324
  expect(driver.send(:compute)).to eq(res)
293
325
  end
294
326
 
295
327
  it 'creates a new network connection' do
296
- Fog::Network.stub(:new) { |arg| arg }
297
- res = config.merge({ :provider => 'OpenStack' })
328
+ allow(Fog::Network).to receive(:new) { |arg| arg }
329
+ res = config.merge(provider: 'OpenStack')
298
330
  expect(driver.send(:network)).to eq(res)
299
331
  end
300
332
  end
301
333
 
302
334
  context 'only an API key provided' do
303
- let(:config) { { :openstack_api_key => '1234' } }
335
+ let(:config) { { openstack_api_key: '1234' } }
304
336
 
305
337
  it 'raises an error' do
306
338
  expect { driver.send(:compute) }.to raise_error(ArgumentError)
@@ -308,7 +340,7 @@ describe Kitchen::Driver::Openstack do
308
340
  end
309
341
 
310
342
  context 'only a username provided' do
311
- let(:config) { { :openstack_username => 'monkey' } }
343
+ let(:config) { { openstack_username: 'monkey' } }
312
344
 
313
345
  it 'raises an error' do
314
346
  expect { driver.send(:compute) }.to raise_error(ArgumentError)
@@ -319,51 +351,45 @@ describe Kitchen::Driver::Openstack do
319
351
  describe '#create_server' do
320
352
  let(:config) do
321
353
  {
322
- :server_name => 'hello',
323
- :image_ref => '111',
324
- :flavor_ref => '1',
325
- :public_key_path => 'tarpals'
354
+ server_name: 'hello',
355
+ image_ref: '111',
356
+ flavor_ref: '1',
357
+ public_key_path: 'tarpals'
326
358
  }
327
359
  end
328
360
  let(:servers) do
329
361
  s = double('servers')
330
- s.stub(:create) { |arg| arg }
362
+ allow(s).to receive(:create) { |arg| arg }
331
363
  s
332
364
  end
333
- let(:vlan1_net) { double(:id => '1', :name => 'vlan1') }
334
- let(:vlan2_net) { double(:id => '2', :name => 'vlan2') }
335
- let(:ubuntu_image) { double(:id => '111', :name => 'ubuntu') }
336
- let(:fedora_image) { double(:id => '222', :name => 'fedora') }
337
- let(:tiny_flavor) { double(:id => '1', :name => 'tiny') }
338
- let(:small_flavor) { double(:id => '2', :name => 'small') }
365
+ let(:vlan1_net) { double(id: '1', name: 'vlan1') }
366
+ let(:vlan2_net) { double(id: '2', name: 'vlan2') }
367
+ let(:ubuntu_image) { double(id: '111', name: 'ubuntu') }
368
+ let(:fedora_image) { double(id: '222', name: 'fedora') }
369
+ let(:tiny_flavor) { double(id: '1', name: 'tiny') }
370
+ let(:small_flavor) { double(id: '2', name: 'small') }
339
371
  let(:compute) do
340
372
  double(
341
- :servers => servers,
342
- :images => [ubuntu_image, fedora_image],
343
- :flavors => [tiny_flavor, small_flavor],
373
+ servers: servers,
374
+ images: [ubuntu_image, fedora_image],
375
+ flavors: [tiny_flavor, small_flavor]
344
376
  )
345
377
  end
346
378
  let(:network) do
347
- double(
348
- :networks => double(
349
- :all => [vlan1_net, vlan2_net]
350
- )
351
- )
379
+ double(networks: double(all: [vlan1_net, vlan2_net]))
352
380
  end
353
381
  let(:driver) do
354
382
  d = Kitchen::Driver::Openstack.new(config)
355
383
  d.instance = instance
356
- d.stub(:compute).and_return(compute)
357
- d.stub(:network).and_return(network)
384
+ allow(d).to receive(:compute).and_return(compute)
385
+ allow(d).to receive(:network).and_return(network)
358
386
  d
359
387
  end
360
388
 
361
389
  context 'a default config' do
362
390
  before(:each) do
363
- @expected = config.merge(:name => config[:server_name])
364
- @expected.delete_if do |k, v|
365
- k == :server_name
366
- end
391
+ @expected = config.merge(name: config[:server_name])
392
+ @expected.delete_if { |k, _| k == :server_name }
367
393
  end
368
394
 
369
395
  it 'creates the server using a compute connection' do
@@ -374,17 +400,15 @@ describe Kitchen::Driver::Openstack do
374
400
  context 'a provided public key path' do
375
401
  let(:config) do
376
402
  {
377
- :server_name => 'hello',
378
- :image_ref => '111',
379
- :flavor_ref => '1',
380
- :public_key_path => 'tarpals'
403
+ server_name: 'hello',
404
+ image_ref: '111',
405
+ flavor_ref: '1',
406
+ public_key_path: 'tarpals'
381
407
  }
382
408
  end
383
409
  before(:each) do
384
- @expected = config.merge(:name => config[:server_name])
385
- @expected.delete_if do |k, v|
386
- k == :server_name
387
- end
410
+ @expected = config.merge(name: config[:server_name])
411
+ @expected.delete_if { |k, _| k == :server_name }
388
412
  end
389
413
 
390
414
  it 'passes that public key path to Fog' do
@@ -395,19 +419,17 @@ describe Kitchen::Driver::Openstack do
395
419
  context 'a provided key name' do
396
420
  let(:config) do
397
421
  {
398
- :server_name => 'hello',
399
- :image_ref => '111',
400
- :flavor_ref => '1',
401
- :public_key_path => 'montgomery',
402
- :key_name => 'tarpals'
422
+ server_name: 'hello',
423
+ image_ref: '111',
424
+ flavor_ref: '1',
425
+ public_key_path: 'montgomery',
426
+ key_name: 'tarpals'
403
427
  }
404
428
  end
405
429
 
406
430
  before(:each) do
407
- @expected = config.merge(:name => config[:server_name])
408
- @expected.delete_if do |k, v|
409
- k == :server_name
410
- end
431
+ @expected = config.merge(name: config[:server_name])
432
+ @expected.delete_if { |k, _| k == :server_name }
411
433
  end
412
434
 
413
435
  it 'passes that key name to Fog' do
@@ -418,20 +440,18 @@ describe Kitchen::Driver::Openstack do
418
440
  context 'a provided security group' do
419
441
  let(:config) do
420
442
  {
421
- :server_name => 'hello',
422
- :image_ref => '111',
423
- :flavor_ref => '1',
424
- :public_key_path => 'montgomery',
425
- :key_name => 'tarpals',
426
- :security_groups => ['ping-and-ssh']
443
+ server_name: 'hello',
444
+ image_ref: '111',
445
+ flavor_ref: '1',
446
+ public_key_path: 'montgomery',
447
+ key_name: 'tarpals',
448
+ security_groups: ['ping-and-ssh']
427
449
  }
428
450
  end
429
451
 
430
452
  before(:each) do
431
- @expected = config.merge(:name => config[:server_name])
432
- @expected.delete_if do |k, v|
433
- k == :server_name
434
- end
453
+ @expected = config.merge(name: config[:server_name])
454
+ @expected.delete_if { |k, _| k == :server_name }
435
455
  end
436
456
 
437
457
  it 'passes that security group to Fog' do
@@ -442,17 +462,18 @@ describe Kitchen::Driver::Openstack do
442
462
  context 'image/flavor specifies id' do
443
463
  let(:config) do
444
464
  {
445
- :server_name => 'hello',
446
- :image_ref => '111',
447
- :flavor_ref => '1',
448
- :public_key_path => 'tarpals'
465
+ server_name: 'hello',
466
+ image_ref: '111',
467
+ flavor_ref: '1',
468
+ public_key_path: 'tarpals'
449
469
  }
450
470
  end
451
471
 
452
472
  it 'exact id match' do
453
- servers.should_receive(:create).with(:name => 'hello',
454
- :image_ref => '111', :flavor_ref => '1',
455
- :public_key_path => 'tarpals')
473
+ expect(servers).to receive(:create).with(name: 'hello',
474
+ image_ref: '111',
475
+ flavor_ref: '1',
476
+ public_key_path: 'tarpals')
456
477
  driver.send(:create_server)
457
478
  end
458
479
  end
@@ -460,17 +481,18 @@ describe Kitchen::Driver::Openstack do
460
481
  context 'image/flavor specifies name' do
461
482
  let(:config) do
462
483
  {
463
- :server_name => 'hello',
464
- :image_ref => 'fedora',
465
- :flavor_ref => 'small',
466
- :public_key_path => 'tarpals'
484
+ server_name: 'hello',
485
+ image_ref: 'fedora',
486
+ flavor_ref: 'small',
487
+ public_key_path: 'tarpals'
467
488
  }
468
489
  end
469
490
 
470
491
  it 'exact name match' do
471
- servers.should_receive(:create).with(:name => 'hello',
472
- :image_ref => '222', :flavor_ref => '2',
473
- :public_key_path => 'tarpals')
492
+ expect(servers).to receive(:create).with(name: 'hello',
493
+ image_ref: '222',
494
+ flavor_ref: '2',
495
+ public_key_path: 'tarpals')
474
496
  driver.send(:create_server)
475
497
  end
476
498
  end
@@ -478,18 +500,19 @@ describe Kitchen::Driver::Openstack do
478
500
  context 'image/flavor specifies regex' do
479
501
  let(:config) do
480
502
  {
481
- :server_name => 'hello',
503
+ server_name: 'hello',
482
504
  # pass regex as string as yml returns string values
483
- :image_ref => '/edo/',
484
- :flavor_ref => '/in/',
485
- :public_key_path => 'tarpals'
505
+ image_ref: '/edo/',
506
+ flavor_ref: '/in/',
507
+ public_key_path: 'tarpals'
486
508
  }
487
509
  end
488
510
 
489
511
  it 'regex name match' do
490
- servers.should_receive(:create).with(:name => 'hello',
491
- :image_ref => '222', :flavor_ref => '1',
492
- :public_key_path => 'tarpals')
512
+ expect(servers).to receive(:create).with(name: 'hello',
513
+ image_ref: '222',
514
+ flavor_ref: '1',
515
+ public_key_path: 'tarpals')
493
516
  driver.send(:create_server)
494
517
  end
495
518
  end
@@ -497,11 +520,11 @@ describe Kitchen::Driver::Openstack do
497
520
  context 'network specifies id' do
498
521
  let(:config) do
499
522
  {
500
- :server_name => 'hello',
501
- :image_ref => '111',
502
- :flavor_ref => '1',
503
- :public_key_path => 'tarpals',
504
- :network_ref => '1'
523
+ server_name: 'hello',
524
+ image_ref: '111',
525
+ flavor_ref: '1',
526
+ public_key_path: 'tarpals',
527
+ network_ref: '1'
505
528
  }
506
529
  end
507
530
 
@@ -509,12 +532,12 @@ describe Kitchen::Driver::Openstack do
509
532
  networks = [
510
533
  { 'net_id' => '1' }
511
534
  ]
512
- servers.should_receive(:create).with(
513
- :name => 'hello',
514
- :image_ref => '111',
515
- :flavor_ref => '1',
516
- :public_key_path => 'tarpals',
517
- :nics => networks
535
+ expect(servers).to receive(:create).with(
536
+ name: 'hello',
537
+ image_ref: '111',
538
+ flavor_ref: '1',
539
+ public_key_path: 'tarpals',
540
+ nics: networks
518
541
  )
519
542
  driver.send(:create_server)
520
543
  end
@@ -523,11 +546,11 @@ describe Kitchen::Driver::Openstack do
523
546
  context 'network specifies name' do
524
547
  let(:config) do
525
548
  {
526
- :server_name => 'hello',
527
- :image_ref => '111',
528
- :flavor_ref => '1',
529
- :public_key_path => 'tarpals',
530
- :network_ref => 'vlan1'
549
+ server_name: 'hello',
550
+ image_ref: '111',
551
+ flavor_ref: '1',
552
+ public_key_path: 'tarpals',
553
+ network_ref: 'vlan1'
531
554
  }
532
555
  end
533
556
 
@@ -535,12 +558,12 @@ describe Kitchen::Driver::Openstack do
535
558
  networks = [
536
559
  { 'net_id' => '1' }
537
560
  ]
538
- servers.should_receive(:create).with(
539
- :name => 'hello',
540
- :image_ref => '111',
541
- :flavor_ref => '1',
542
- :public_key_path => 'tarpals',
543
- :nics => networks
561
+ expect(servers).to receive(:create).with(
562
+ name: 'hello',
563
+ image_ref: '111',
564
+ flavor_ref: '1',
565
+ public_key_path: 'tarpals',
566
+ nics: networks
544
567
  )
545
568
  driver.send(:create_server)
546
569
  end
@@ -549,25 +572,25 @@ describe Kitchen::Driver::Openstack do
549
572
  context 'multiple networks specifies id' do
550
573
  let(:config) do
551
574
  {
552
- :server_name => 'hello',
553
- :image_ref => '111',
554
- :flavor_ref => '1',
555
- :public_key_path => 'tarpals',
556
- :network_ref => %w(1 2)
575
+ server_name: 'hello',
576
+ image_ref: '111',
577
+ flavor_ref: '1',
578
+ public_key_path: 'tarpals',
579
+ network_ref: %w(1 2)
557
580
  }
558
581
  end
559
582
 
560
583
  it 'exact id match' do
561
584
  networks = [
562
585
  { 'net_id' => '1' },
563
- { 'net_id' => '2' },
586
+ { 'net_id' => '2' }
564
587
  ]
565
- servers.should_receive(:create).with(
566
- :name => 'hello',
567
- :image_ref => '111',
568
- :flavor_ref => '1',
569
- :public_key_path => 'tarpals',
570
- :nics => networks
588
+ expect(servers).to receive(:create).with(
589
+ name: 'hello',
590
+ image_ref: '111',
591
+ flavor_ref: '1',
592
+ public_key_path: 'tarpals',
593
+ nics: networks
571
594
  )
572
595
  driver.send(:create_server)
573
596
  end
@@ -576,27 +599,27 @@ describe Kitchen::Driver::Openstack do
576
599
  context 'user_data specified' do
577
600
  let(:config) do
578
601
  {
579
- :server_name => 'hello',
580
- :image_ref => '111',
581
- :flavor_ref => '1',
582
- :public_key_path => 'tarpals',
583
- :user_data => 'cloud-init.txt'
602
+ server_name: 'hello',
603
+ image_ref: '111',
604
+ flavor_ref: '1',
605
+ public_key_path: 'tarpals',
606
+ user_data: 'cloud-init.txt'
584
607
  }
585
608
  end
586
609
  let(:data) { "#cloud-config\n" }
587
610
 
588
611
  before(:each) do
589
- File.stub(:exist?).and_return(true)
590
- File.stub(:open).and_return(data)
612
+ allow(File).to receive(:exist?).and_return(true)
613
+ allow(File).to receive(:open).and_return(data)
591
614
  end
592
615
 
593
- it 'should pass file contents' do
594
- servers.should_receive(:create).with(
595
- :name => 'hello',
596
- :image_ref => '111',
597
- :flavor_ref => '1',
598
- :public_key_path => 'tarpals',
599
- :user_data => data)
616
+ it 'passes file contents' do
617
+ expect(servers).to receive(:create).with(
618
+ name: 'hello',
619
+ image_ref: '111',
620
+ flavor_ref: '1',
621
+ public_key_path: 'tarpals',
622
+ user_data: data)
600
623
  driver.send(:create_server)
601
624
  end
602
625
  end
@@ -604,8 +627,8 @@ describe Kitchen::Driver::Openstack do
604
627
 
605
628
  describe '#generate_name' do
606
629
  before(:each) do
607
- Etc.stub(:getlogin).and_return('user')
608
- Socket.stub(:gethostname).and_return('host')
630
+ allow(Etc).to receive(:getlogin).and_return('user')
631
+ allow(Socket).to receive(:gethostname).and_return('host')
609
632
  end
610
633
 
611
634
  it 'generates a name' do
@@ -615,41 +638,55 @@ describe Kitchen::Driver::Openstack do
615
638
 
616
639
  context 'local node with a long hostname' do
617
640
  before(:each) do
618
- Socket.unstub(:gethostname)
619
- Socket.stub(:gethostname).and_return('ab.c' * 20)
641
+ allow(Socket).to receive(:gethostname).and_return('ab.c' * 20)
620
642
  end
621
643
 
622
644
  it 'limits the generated name to 63 characters' do
623
- expect(driver.send(:generate_name, 'long').length).to eq(63)
645
+ expect(driver.send(:generate_name, 'long').length).to be <= (63)
624
646
  end
625
647
  end
626
648
 
627
649
  context 'node with a long hostname, username, and base name' do
628
650
  before(:each) do
629
- Socket.unstub(:gethostname)
630
- Socket.stub(:gethostname).and_return('ab.c' * 20)
631
-
632
- Etc.unstub(:getlogin)
633
- Etc.stub(:getlogin).and_return('user' * 20)
651
+ allow(Socket).to receive(:gethostname).and_return('abc' * 20)
652
+ allow(Etc).to receive(:getlogin).and_return('user' * 20)
634
653
  end
635
654
 
636
655
  it 'limits the generated name to 63 characters' do
637
656
  expect(driver.send(:generate_name, 'long' * 20).length).to eq(63)
638
657
  end
639
658
  end
659
+
660
+ context 'a login and hostname with punctuation in them' do
661
+ let(:base) { 'a.base-name' }
662
+
663
+ before(:each) do
664
+ allow(Etc).to receive(:getlogin).and_return('some.u-se-r' * 20)
665
+ allow(Socket).to receive(:gethostname).and_return('a.host-name' * 20)
666
+ end
667
+
668
+ it 'strips out the dots to prevent bad server names' do
669
+ expect(driver.send(:generate_name, base)).to_not include('.')
670
+ end
671
+
672
+ it 'strips out all but the three hyphen separators' do
673
+ expect(driver.send(:generate_name, base).count('-')).to eq(3)
674
+ end
675
+ end
640
676
  end
641
677
 
642
678
  describe '#attach_ip_from_pool' do
643
679
  let(:server) { nil }
644
680
  let(:pool) { 'swimmers' }
645
681
  let(:ip) { '1.1.1.1' }
646
- let(:address) { double(:ip => ip, :fixed_ip => nil, :instance_id => nil,
647
- :pool => pool) }
648
- let(:compute) { double(:addresses => [address]) }
682
+ let(:address) do
683
+ double(ip: ip, fixed_ip: nil, instance_id: nil, pool: pool)
684
+ end
685
+ let(:compute) { double(addresses: [address]) }
649
686
 
650
687
  before(:each) do
651
- driver.stub(:attach_ip).with(server, ip).and_return('bing!')
652
- driver.stub(:compute).and_return(compute)
688
+ allow(driver).to receive(:attach_ip).with(server, ip).and_return('bing!')
689
+ allow(driver).to receive(:compute).and_return(compute)
653
690
  end
654
691
 
655
692
  it 'determines an IP to attempt to attach' do
@@ -657,8 +694,10 @@ describe Kitchen::Driver::Openstack do
657
694
  end
658
695
 
659
696
  context 'no free addresses in the specified pool' do
660
- let(:address) { double(:ip => ip, :fixed_ip => nil, :instance_id => nil,
661
- :pool => 'some_other_pool') }
697
+ let(:address) do
698
+ double(ip: ip, fixed_ip: nil, instance_id: nil,
699
+ pool: 'some_other_pool')
700
+ end
662
701
 
663
702
  it 'raises an exception' do
664
703
  expect { driver.send(:attach_ip_from_pool, server, pool) }.to \
@@ -672,8 +711,8 @@ describe Kitchen::Driver::Openstack do
672
711
  let(:addresses) { {} }
673
712
  let(:server) do
674
713
  s = double('server')
675
- s.should_receive(:associate_address).with(ip).and_return(true)
676
- s.stub(:addresses).and_return(addresses)
714
+ expect(s).to receive(:associate_address).with(ip).and_return(true)
715
+ allow(s).to receive(:addresses).and_return(addresses)
677
716
  s
678
717
  end
679
718
 
@@ -691,19 +730,19 @@ describe Kitchen::Driver::Openstack do
691
730
  let(:driver) do
692
731
  d = Kitchen::Driver::Openstack.new(config)
693
732
  d.instance = instance
694
- d.stub(:parse_ips).and_return(parsed_ips)
733
+ allow(d).to receive(:parse_ips).and_return(parsed_ips)
695
734
  d
696
735
  end
697
736
  let(:server) do
698
- double(:addresses => addresses,
699
- :public_ip_addresses => public_ip_addresses,
700
- :private_ip_addresses => private_ip_addresses)
737
+ double(addresses: addresses,
738
+ public_ip_addresses: public_ip_addresses,
739
+ private_ip_addresses: private_ip_addresses)
701
740
  end
702
741
 
703
742
  context 'both public and private IPs' do
704
- let(:public_ip_addresses) { %w{1::1 1.2.3.4} }
705
- let(:private_ip_addresses) { %w{5.5.5.5} }
706
- let(:parsed_ips) { [%w{1.2.3.4}, %w{5.5.5.5}] }
743
+ let(:public_ip_addresses) { %w(1::1 1.2.3.4) }
744
+ let(:private_ip_addresses) { %w(5.5.5.5) }
745
+ let(:parsed_ips) { [%w(1.2.3.4), %w(5.5.5.5)] }
707
746
 
708
747
  it 'returns a public IPv4 address' do
709
748
  expect(driver.send(:get_ip, server)).to eq('1.2.3.4')
@@ -711,8 +750,8 @@ describe Kitchen::Driver::Openstack do
711
750
  end
712
751
 
713
752
  context 'only public IPs' do
714
- let(:public_ip_addresses) { %w{4.3.2.1 2::1} }
715
- let(:parsed_ips) { [%w{4.3.2.1}, []] }
753
+ let(:public_ip_addresses) { %w(4.3.2.1 2::1) }
754
+ let(:parsed_ips) { [%w(4.3.2.1), []] }
716
755
 
717
756
  it 'returns a public IPv4 address' do
718
757
  expect(driver.send(:get_ip, server)).to eq('4.3.2.1')
@@ -720,8 +759,8 @@ describe Kitchen::Driver::Openstack do
720
759
  end
721
760
 
722
761
  context 'only private IPs' do
723
- let(:private_ip_addresses) { %w{3::1 5.5.5.5} }
724
- let(:parsed_ips) { [[], %w{5.5.5.5}] }
762
+ let(:private_ip_addresses) { %w(3::1 5.5.5.5) }
763
+ let(:parsed_ips) { [[], %w(5.5.5.5)] }
725
764
 
726
765
  it 'returns a private IPv4 address' do
727
766
  expect(driver.send(:get_ip, server)).to eq('5.5.5.5')
@@ -729,7 +768,7 @@ describe Kitchen::Driver::Openstack do
729
768
  end
730
769
 
731
770
  context 'IPs in user-defined network group' do
732
- let(:config) { { :openstack_network_name => 'mynetwork' } }
771
+ let(:config) { { openstack_network_name: 'mynetwork' } }
733
772
  let(:addresses) do
734
773
  {
735
774
  'mynetwork' => [
@@ -747,10 +786,10 @@ describe Kitchen::Driver::Openstack do
747
786
  context 'an OpenStack deployment without the floating IP extension' do
748
787
  let(:server) do
749
788
  s = double('server')
750
- s.stub(:addresses).and_return(addresses)
751
- s.stub(:public_ip_addresses).and_raise(
789
+ allow(s).to receive(:addresses).and_return(addresses)
790
+ allow(s).to receive(:public_ip_addresses).and_raise(
752
791
  Fog::Compute::OpenStack::NotFound)
753
- s.stub(:private_ip_addresses).and_raise(
792
+ allow(s).to receive(:private_ip_addresses).and_raise(
754
793
  Fog::Compute::OpenStack::NotFound)
755
794
  s
756
795
  end
@@ -762,7 +801,7 @@ describe Kitchen::Driver::Openstack do
762
801
  'private' => [{ 'addr' => '8.8.8.8' }, { 'addr' => '9.9.9.9' }]
763
802
  }
764
803
  end
765
- let(:parsed_ips) { [%w{6.6.6.6 7.7.7.7}, %w{8.8.8.8 9.9.9.9}] }
804
+ let(:parsed_ips) { [%w(6.6.6.6 7.7.7.7), %w(8.8.8.8 9.9.9.9)] }
766
805
 
767
806
  it 'selects the first public IP' do
768
807
  expect(driver.send(:get_ip, server)).to eq('6.6.6.6')
@@ -773,7 +812,7 @@ describe Kitchen::Driver::Openstack do
773
812
  let(:addresses) do
774
813
  { 'public' => [{ 'addr' => '6.6.6.6' }, { 'addr' => '7.7.7.7' }] }
775
814
  end
776
- let(:parsed_ips) { [%w{6.6.6.6 7.7.7.7}, []] }
815
+ let(:parsed_ips) { [%w(6.6.6.6 7.7.7.7), []] }
777
816
 
778
817
  it 'selects the first public IP' do
779
818
  expect(driver.send(:get_ip, server)).to eq('6.6.6.6')
@@ -784,7 +823,7 @@ describe Kitchen::Driver::Openstack do
784
823
  let(:addresses) do
785
824
  { 'private' => [{ 'addr' => '8.8.8.8' }, { 'addr' => '9.9.9.9' }] }
786
825
  end
787
- let(:parsed_ips) { [[], %w{8.8.8.8 9.9.9.9}] }
826
+ let(:parsed_ips) { [[], %w(8.8.8.8 9.9.9.9)] }
788
827
 
789
828
  it 'selects the first private IP' do
790
829
  expect(driver.send(:get_ip, server)).to eq('8.8.8.8')
@@ -800,10 +839,10 @@ describe Kitchen::Driver::Openstack do
800
839
  end
801
840
 
802
841
  describe '#parse_ips' do
803
- let(:pub_v4) { %w{1.1.1.1 2.2.2.2} }
804
- let(:pub_v6) { %w{1::1 2::2} }
805
- let(:priv_v4) { %w{3.3.3.3 4.4.4.4} }
806
- let(:priv_v6) { %w{3::3 4::4} }
842
+ let(:pub_v4) { %w(1.1.1.1 2.2.2.2) }
843
+ let(:pub_v6) { %w(1::1 2::2) }
844
+ let(:priv_v4) { %w(3.3.3.3 4.4.4.4) }
845
+ let(:priv_v6) { %w(3::3 4::4) }
807
846
  let(:pub) { pub_v4 + pub_v6 }
808
847
  let(:priv) { priv_v4 + priv_v6 }
809
848
 
@@ -815,7 +854,7 @@ describe Kitchen::Driver::Openstack do
815
854
  end
816
855
 
817
856
  context 'IPv6' do
818
- let(:config) { { :use_ipv6 => true } }
857
+ let(:config) { { use_ipv6: true } }
819
858
 
820
859
  it 'returns only the v6 IPs' do
821
860
  expect(driver.send(:parse_ips, pub, priv)).to eq([pub_v6, priv_v6])
@@ -833,7 +872,7 @@ describe Kitchen::Driver::Openstack do
833
872
  end
834
873
 
835
874
  context 'IPv6' do
836
- let(:config) { { :use_ipv6 => true } }
875
+ let(:config) { { use_ipv6: true } }
837
876
 
838
877
  it 'returns only the v6 IPs' do
839
878
  expect(driver.send(:parse_ips, pub, priv)).to eq([pub_v6, []])
@@ -851,7 +890,7 @@ describe Kitchen::Driver::Openstack do
851
890
  end
852
891
 
853
892
  context 'IPv6' do
854
- let(:config) { { :use_ipv6 => true } }
893
+ let(:config) { { use_ipv6: true } }
855
894
 
856
895
  it 'returns only the v6 IPs' do
857
896
  expect(driver.send(:parse_ips, pub, priv)).to eq([[], priv_v6])
@@ -870,7 +909,7 @@ describe Kitchen::Driver::Openstack do
870
909
  end
871
910
 
872
911
  context 'IPv6' do
873
- let(:config) { { :use_ipv6 => true } }
912
+ let(:config) { { use_ipv6: true } }
874
913
 
875
914
  it 'returns empty lists' do
876
915
  expect(driver.send(:parse_ips, nil, nil)).to eq([[], []])
@@ -880,21 +919,21 @@ describe Kitchen::Driver::Openstack do
880
919
  end
881
920
 
882
921
  describe '#do_ssh_setup' do
883
- let(:config) { { :public_key_path => '/pub_key' } }
884
- let(:server) { double(:password => 'aloha') }
885
- let(:state) { { :hostname => 'host' } }
886
- let(:read) { double(:read => 'a_key') }
922
+ let(:config) { { public_key_path: '/pub_key' } }
923
+ let(:server) { double(password: 'aloha') }
924
+ let(:state) { { hostname: 'host' } }
925
+ let(:read) { double(read: 'a_key') }
887
926
  let(:ssh) do
888
927
  s = double('ssh')
889
- s.stub(:run) { |args| args }
928
+ allow(s).to receive(:run) { |args| args }
890
929
  s
891
930
  end
892
931
 
893
932
  it 'opens an SSH session to the server' do
894
- Fog::SSH.stub(:new).with('host', 'root',
895
- { :password => 'aloha' }).and_return(ssh)
896
- driver.stub(:open).with('/pub_key').and_return(read)
897
- read.stub(:read).and_return('a_key')
933
+ allow(Fog::SSH).to receive(:new).with('host', 'root', password: 'aloha')
934
+ .and_return(ssh)
935
+ allow(driver).to receive(:open).with('/pub_key').and_return(read)
936
+ allow(read).to receive(:read).and_return('a_key')
898
937
  res = driver.send(:do_ssh_setup, state, config, server)
899
938
  expected = [
900
939
  'mkdir .ssh',
@@ -906,18 +945,16 @@ describe Kitchen::Driver::Openstack do
906
945
  end
907
946
 
908
947
  describe '#add_ohai_hint' do
909
- let(:config) { { :public_key_path => '/pub_key' } }
910
- let(:server) { double(:password => 'aloha') }
911
- let(:state) { { :hostname => 'host' } }
948
+ let(:state) { { hostname: 'host' } }
912
949
  let(:ssh) do
913
950
  s = double('ssh')
914
- s.stub(:run) { |args| args }
951
+ allow(s).to receive(:run) { |args| args }
915
952
  s
916
953
  end
917
954
  it 'opens an SSH session to the server' do
918
- Fog::SSH.stub(:new).with('host', 'root',
919
- anything()).and_return(ssh)
920
- res = driver.send(:add_ohai_hint, state, config, server)
955
+ allow(Fog::SSH).to receive(:new).with('host', 'root', anything)
956
+ .and_return(ssh)
957
+ res = driver.send(:add_ohai_hint, state)
921
958
  expected = [
922
959
  "sudo mkdir -p #{Ohai::Config[:hints_path][0]}",
923
960
  "sudo touch #{Ohai::Config[:hints_path][0]}/openstack.json"