fog-libvirt 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0ce7265a9a69c91518f2fe37a016da5cfd32a9c
4
- data.tar.gz: 4edaa2e8d544ecd728b96908c06ca54163016edf
3
+ metadata.gz: 8a924f47a387da6a04d3f10ca5528ad6df73153b
4
+ data.tar.gz: 9f578e6cfe50d4994a610e2b427e819d633d76ba
5
5
  SHA512:
6
- metadata.gz: bd061ded1d5c8a4b5910d059b3aaef646b9fdd4aa19828b6091f82e28143c9500fab5e490a49a5b314693828058d4848b2539110d3ec86488868fe51611d8571
7
- data.tar.gz: 71db7a647cf6fb292452530632caaa694dce24f69d9d93cfb466308d9925092f2c3f5adab9f036d659a3e14e31308549434dcf21f48115c5aa6474b0a2cb15c0
6
+ metadata.gz: 66e744dc9c9b7e0072b9f5c10912f0626e7355d3c1bacf2dad20a102033dc62213fd5bc9237ea66ac38d48115bc7bfa183043d59bff2f1faffa66a804e683c95
7
+ data.tar.gz: e2f735103f4af3889a9679f6ba5c8bf578e5ba2966c8bcb9a902996232bee239631d433092fa90ee88073e08af29902c54f18875ec0334a4c0552212108617e5
data/fog-libvirt.gemspec CHANGED
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
31
31
  s.add_dependency('ruby-libvirt','>= 0.7.0')
32
32
  s.add_dependency("json")
33
33
 
34
+ s.add_development_dependency("net-ssh")
34
35
  s.add_development_dependency("minitest", "~> 5.0")
35
36
  s.add_development_dependency("minitest-stub-const")
36
37
  s.add_development_dependency("pry")
@@ -45,6 +45,7 @@ module Fog
45
45
  request :destroy_interface
46
46
  request :get_node_info
47
47
  request :update_display
48
+ request :libversion
48
49
 
49
50
  module Shared
50
51
  include Fog::Compute::LibvirtUtil
@@ -258,11 +258,139 @@ module Fog
258
258
  private
259
259
  attr_accessor :volumes_path
260
260
 
261
- # This retrieves the ip address of the mac address
261
+ # This tests the library version before redefining the address
262
+ # method for this instance to use a method compatible with
263
+ # earlier libvirt libraries, or uses the dhcp method from more
264
+ # recent releases.
265
+ def addresses(service_arg=service, options={})
266
+ addresses_method = self.method(:addresses_dhcp)
267
+ # check if ruby-libvirt was compiled against a new enough version
268
+ # that can use dhcp_leases, as otherwise it will not provide the
269
+ # method dhcp_leases on any of the network objects.
270
+ has_dhcp_leases = true
271
+ begin
272
+ service.networks.first.dhcp_leases(self.mac)
273
+ rescue NoMethodError
274
+ has_dhcp_leases = false
275
+ rescue
276
+ # assume some other odd exception.
277
+ end
278
+
279
+ # if ruby-libvirt not compiled with support, or remote library is
280
+ # too old (must be newer than 1.2.8), then use old fallback
281
+ if not has_dhcp_leases or service.libversion() < 1002008
282
+ addresses_method = self.method(:addresses_ip_command)
283
+ end
284
+
285
+ # replace current definition for this instance with correct one for
286
+ # detected libvirt to perform check once for connection
287
+ (class << self; self; end).class_eval do
288
+ define_method(:addresses, addresses_method)
289
+ end
290
+ addresses(service_arg, options)
291
+ end
292
+
293
+ def ssh_ip_command(ip_command, uri)
294
+ # Retrieve the parts we need from the service to setup our ssh options
295
+ user=uri.user #could be nil
296
+ host=uri.host
297
+ keyfile=uri.keyfile
298
+ port=uri.port
299
+
300
+ # Setup the options
301
+ ssh_options={}
302
+ ssh_options[:keys]=[ keyfile ] unless keyfile.nil?
303
+ ssh_options[:port]=port unless keyfile.nil?
304
+ ssh_options[:paranoid]=true if uri.no_verify?
305
+
306
+ begin
307
+ result=Fog::SSH.new(host, user, ssh_options).run(ip_command)
308
+ rescue Errno::ECONNREFUSED
309
+ raise Fog::Errors::Error.new("Connection was refused to host #{host} to retrieve the ip_address for #{mac}")
310
+ rescue Net::SSH::AuthenticationFailed
311
+ raise Fog::Errors::Error.new("Error authenticating over ssh to host #{host} and user #{user}")
312
+ end
313
+
314
+ # Check for a clean exit code
315
+ if result.first.status == 0
316
+ return result.first.stdout.strip
317
+ else
318
+ # We got a failure executing the command
319
+ raise Fog::Errors::Error.new("The command #{ip_command} failed to execute with a clean exit code")
320
+ end
321
+ end
322
+
323
+ def local_ip_command(ip_command)
324
+ # Execute the ip_command locally
325
+ # Initialize empty ip_address string
326
+ ip_address=""
327
+
328
+ IO.popen("#{ip_command}") do |p|
329
+ p.each_line do |l|
330
+ ip_address+=l
331
+ end
332
+ status=Process.waitpid2(p.pid)[1].exitstatus
333
+ if status!=0
334
+ raise Fog::Errors::Error.new("The command #{ip_command} failed to execute with a clean exit code")
335
+ end
336
+ end
337
+
338
+ #Strip any new lines from the string
339
+ ip_address.chomp
340
+ end
341
+
342
+ # This retrieves the ip address of the mac address using ip_command
262
343
  # It returns an array of public and private ip addresses
263
344
  # Currently only one ip address is returned, but in the future this could be multiple
264
345
  # if the server has multiple network interface
265
- def addresses(service_arg=service, options={})
346
+ def addresses_ip_command(service_arg=service, options={})
347
+ mac=self.mac
348
+
349
+ # Aug 24 17:34:41 juno arpwatch: new station 10.247.4.137 52:54:00:88:5a:0a eth0.4
350
+ # Aug 24 17:37:19 juno arpwatch: changed ethernet address 10.247.4.137 52:54:00:27:33:00 (52:54:00:88:5a:0a) eth0.4
351
+ # Check if another ip_command string was provided
352
+ ip_command_global=service_arg.ip_command.nil? ? 'grep $mac /var/log/arpwatch.log|sed -e "s/new station//"|sed -e "s/changed ethernet address//g" |sed -e "s/reused old ethernet //" |tail -1 |cut -d ":" -f 4-| cut -d " " -f 3' : service_arg.ip_command
353
+ ip_command_local=options[:ip_command].nil? ? ip_command_global : options[:ip_command]
354
+
355
+ ip_command="mac=#{mac}; server_name=#{name}; "+ip_command_local
356
+
357
+ ip_address=nil
358
+
359
+ if service_arg.uri.ssh_enabled?
360
+ ip_address=ssh_ip_command(ip_command, service_arg.uri)
361
+ else
362
+ # It's not ssh enabled, so we assume it is
363
+ if service_arg.uri.transport=="tls"
364
+ raise Fog::Errors::Error.new("TlS remote transport is not currently supported, only ssh")
365
+ end
366
+ ip_address=local_ip_command(ip_command)
367
+ end
368
+
369
+ # The Ip-address command has been run either local or remote now
370
+
371
+ if ip_address==""
372
+ #The grep didn't find an ip address result"
373
+ ip_address=nil
374
+ else
375
+ # To be sure that the command didn't return another random string
376
+ # We check if the result is an actual ip-address
377
+ # otherwise we return nil
378
+ unless ip_address=~/^(\d{1,3}\.){3}\d{1,3}$/
379
+ raise Fog::Errors::Error.new(
380
+ "The result of #{ip_command} does not have valid ip-address format\n"+
381
+ "Result was: #{ip_address}\n"
382
+ )
383
+ end
384
+ end
385
+
386
+ return { :public => [ip_address], :private => [ip_address]}
387
+ end
388
+
389
+ # This retrieves the ip address of the mac address using dhcp_leases
390
+ # It returns an array of public and private ip addresses
391
+ # Currently only one ip address is returned, but in the future this could be multiple
392
+ # if the server has multiple network interface
393
+ def addresses_dhcp(service_arg=service, options={})
266
394
  mac=self.mac
267
395
 
268
396
  ip_address = nil
@@ -0,0 +1,18 @@
1
+
2
+ module Fog
3
+ module Compute
4
+ class Libvirt
5
+ class Real
6
+ def libversion()
7
+ client.libversion
8
+ end
9
+ end
10
+
11
+ class Mock
12
+ def libversion()
13
+ return 1002009
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Libvirt
3
- VERSION = '0.4.2'
3
+ VERSION = '0.5.0'
4
4
  end
5
5
  end
@@ -0,0 +1,64 @@
1
+ require 'test_helper'
2
+
3
+ class ServerTest < Minitest::Test
4
+ def setup
5
+ @compute = Fog::Compute[:libvirt]
6
+ @server = @compute.servers.new(:name => "test")
7
+ end
8
+
9
+ def test_addresses_calls_compat_version_for_no_dhcp_leases_support
10
+ network = Libvirt::Network.new
11
+ @compute.expects(:networks).returns([network])
12
+ network.expects(:dhcp_leases).raises(NoMethodError)
13
+ @server.expects(:addresses_ip_command).returns(true)
14
+
15
+ @server.send(:addresses)
16
+ end
17
+
18
+ def test_addresses_calls_compat_version_for_older_libvirt
19
+ network = Libvirt::Network.new
20
+ @compute.expects(:libversion).returns(1002007)
21
+ @compute.expects(:networks).returns([network])
22
+ network.expects(:dhcp_leases).returns(true)
23
+ @server.expects(:addresses_ip_command).returns(true)
24
+
25
+ @server.send(:addresses)
26
+ end
27
+
28
+ def test_addresses_calls_compat_version_for_newer_libvirt
29
+ network = Libvirt::Network.new
30
+ @compute.expects(:libversion).returns(1002008)
31
+ @compute.expects(:networks).returns([network])
32
+ network.expects(:dhcp_leases).returns(true)
33
+ @server.expects(:addresses_dhcp).returns(true)
34
+
35
+ @server.send(:addresses)
36
+ end
37
+
38
+ def test_ssh_ip_command_success
39
+ fog_ssh = MiniTest::Mock.new
40
+ result = MiniTest::Mock.new
41
+ result.expect(:status, 0)
42
+ result.expect(:stdout, "any_ip")
43
+ fog_ssh.expect(:run, [result], [String])
44
+ uri = ::Fog::Compute::LibvirtUtil::URI.new('qemu+ssh://localhost:22?keyfile=nofile')
45
+ Fog::SSH.stub(:new, fog_ssh) do
46
+ @server.send(:ssh_ip_command, "test command", uri)
47
+ end
48
+ fog_ssh.verify
49
+ end
50
+
51
+ def test_local_ip_command_success
52
+ proc_info = MiniTest::Mock.new
53
+ proc_info.expect(:each_line, "127.0.0.1")
54
+ proc_info.expect(:pid, 0)
55
+ status = MiniTest::Mock.new
56
+ status.expect(:exitstatus, 0)
57
+ Process.stubs(:waitpid2).returns([0, status])
58
+ IO.stub(:popen, true, proc_info) do
59
+ @server.send(:local_ip_command, "test command")
60
+ end
61
+ proc_info.verify
62
+ status.verify
63
+ end
64
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-libvirt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - geemus (Wesley Beary)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-13 00:00:00.000000000 Z
11
+ date: 2018-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog-core
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: net-ssh
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: minitest
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -259,6 +273,7 @@ files:
259
273
  - lib/fog/libvirt/requests/compute/destroy_network.rb
260
274
  - lib/fog/libvirt/requests/compute/dhcp_leases.rb
261
275
  - lib/fog/libvirt/requests/compute/get_node_info.rb
276
+ - lib/fog/libvirt/requests/compute/libversion.rb
262
277
  - lib/fog/libvirt/requests/compute/list_domains.rb
263
278
  - lib/fog/libvirt/requests/compute/list_interfaces.rb
264
279
  - lib/fog/libvirt/requests/compute/list_networks.rb
@@ -272,6 +287,7 @@ files:
272
287
  - lib/fog/libvirt/requests/compute/vm_action.rb
273
288
  - lib/fog/libvirt/requests/compute/volume_action.rb
274
289
  - lib/fog/libvirt/version.rb
290
+ - minitests/server/server_test.rb
275
291
  - minitests/server/user_data_iso_test.rb
276
292
  - minitests/test_helper.rb
277
293
  - tests/helper.rb