kitchen-openstack 1.5.2 → 1.5.3

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 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"