From 6eb1560abe636e65b8f6a2381f7fa24b4687510d Mon Sep 17 00:00:00 2001 From: Amos Benari Date: Mon, 12 Mar 2012 12:25:03 +0200 Subject: [PATCH] [oVirt] Added VM and Template network-interfaces crud. --- fog.gemspec | 2 +- lib/fog/ovirt/compute.rb | 17 ++++++++-- lib/fog/ovirt/models/compute/cluster.rb | 4 +-- lib/fog/ovirt/models/compute/interface.rb | 22 +++++++++++++ lib/fog/ovirt/models/compute/interfaces.rb | 32 +++++++++++++++++++ lib/fog/ovirt/models/compute/server.rb | 29 ++++++++++++++++- lib/fog/ovirt/models/compute/template.rb | 11 +++++++ .../ovirt/requests/compute/add_interface.rb | 23 +++++++++++++ .../requests/compute/destroy_interface.rb | 25 +++++++++++++++ .../ovirt/requests/compute/list_networks.rb | 17 ++++++++++ .../compute/list_template_interfaces.rb | 20 ++++++++++++ .../requests/compute/list_vm_interfaces.rb | 20 ++++++++++++ .../requests/compute/mock_files/nics.xml | 10 ++++++ .../requests/compute/update_interface.rb | 25 +++++++++++++++ tests/ovirt/compute_tests.rb | 8 +++-- tests/ovirt/models/compute/interface_tests.rb | 27 ++++++++++++++++ .../ovirt/models/compute/interfaces_tests.rb | 9 ++++++ 17 files changed, 291 insertions(+), 10 deletions(-) create mode 100644 lib/fog/ovirt/models/compute/interface.rb create mode 100644 lib/fog/ovirt/models/compute/interfaces.rb create mode 100644 lib/fog/ovirt/requests/compute/add_interface.rb create mode 100644 lib/fog/ovirt/requests/compute/destroy_interface.rb create mode 100644 lib/fog/ovirt/requests/compute/list_networks.rb create mode 100644 lib/fog/ovirt/requests/compute/list_template_interfaces.rb create mode 100644 lib/fog/ovirt/requests/compute/list_vm_interfaces.rb create mode 100644 lib/fog/ovirt/requests/compute/mock_files/nics.xml create mode 100644 lib/fog/ovirt/requests/compute/update_interface.rb create mode 100644 tests/ovirt/models/compute/interface_tests.rb create mode 100644 tests/ovirt/models/compute/interfaces_tests.rb diff --git a/fog.gemspec b/fog.gemspec index 2f693ba78..811f35a07 100644 --- a/fog.gemspec +++ b/fog.gemspec @@ -54,7 +54,7 @@ Gem::Specification.new do |s| s.add_development_dependency('rdoc') s.add_development_dependency('thor') s.add_development_dependency('rspec', '~>1.3.1') - s.add_development_dependency('rbovirt', '>=0.0.7') + s.add_development_dependency('rbovirt', '>=0.0.8') s.add_development_dependency('shindo', '~>0.3.4') s.add_development_dependency('virtualbox', '~>0.9.1') s.add_development_dependency('fission') diff --git a/lib/fog/ovirt/compute.rb b/lib/fog/ovirt/compute.rb index 571d34229..9c299109b 100644 --- a/lib/fog/ovirt/compute.rb +++ b/lib/fog/ovirt/compute.rb @@ -13,6 +13,8 @@ module Fog collection :templates model :cluster collection :clusters + model :interface + collection :interfaces request_path 'fog/ovirt/requests/compute' @@ -28,6 +30,12 @@ module Fog request :get_template request :list_clusters request :get_cluster + request :add_interface + request :destroy_interface + request :update_interface + request :list_vm_interfaces + request :list_template_interfaces + request :list_networks module Shared # converts an OVIRT object into an hash for fog to consume. @@ -42,6 +50,8 @@ module Fog opts[key] = case value when OVIRT::Link value.id + when Array + value when Hash value else @@ -54,7 +64,6 @@ module Fog class Mock include Shared - attr_reader :client def initialize(options={}) require 'rbovirt' @@ -64,6 +73,7 @@ module Fog end private + attr_reader :client #read mocks xml def read_xml(file_name) file_path = File.join(File.dirname(__FILE__),"requests","compute","mock_files",file_name) @@ -73,7 +83,7 @@ module Fog class Real include Shared - attr_reader :client + def initialize(options={}) require 'rbovirt' @@ -87,6 +97,9 @@ module Fog @client = OVIRT::Client.new(username, password, url, datacenter) end + + private + attr_reader :client end end end diff --git a/lib/fog/ovirt/models/compute/cluster.rb b/lib/fog/ovirt/models/compute/cluster.rb index 50dc10f82..815a9ece9 100644 --- a/lib/fog/ovirt/models/compute/cluster.rb +++ b/lib/fog/ovirt/models/compute/cluster.rb @@ -1,5 +1,3 @@ -require 'fog/compute/models/server' - module Fog module Compute class Ovirt @@ -12,7 +10,7 @@ module Fog attribute :raw def networks - connection.client.networks(:cluster_id => id) + connection.list_networks(id) end def to_s diff --git a/lib/fog/ovirt/models/compute/interface.rb b/lib/fog/ovirt/models/compute/interface.rb new file mode 100644 index 000000000..955193b69 --- /dev/null +++ b/lib/fog/ovirt/models/compute/interface.rb @@ -0,0 +1,22 @@ +module Fog + module Compute + class Ovirt + + class Interface < Fog::Model + attr_accessor :raw + identity :id + + attribute :name + attribute :network + attribute :interface + attribute :mac + + def to_s + name + end + + end + + end + end +end diff --git a/lib/fog/ovirt/models/compute/interfaces.rb b/lib/fog/ovirt/models/compute/interfaces.rb new file mode 100644 index 000000000..c663e3a7b --- /dev/null +++ b/lib/fog/ovirt/models/compute/interfaces.rb @@ -0,0 +1,32 @@ +require 'fog/core/collection' +require 'fog/ovirt/models/compute/interface' + +module Fog + module Compute + class Ovirt + + class Interfaces < Fog::Collection + + model Fog::Compute::Ovirt::Interface + + attr_accessor :vm + + def all(filters = {}) + requires :vm + if vm.is_a? Fog::Compute::Ovirt::Server + load connection.list_vm_interfaces(vm.id) + elsif vm.is_a? Fog::Compute::Ovirt::Template + load connection.list_template_interfaces(vm.id) + else + raise 'interfaces should have vm or template' + end + end + + def get(id) + new connection.get_interface(id) + end + + end + end + end +end diff --git a/lib/fog/ovirt/models/compute/server.rb b/lib/fog/ovirt/models/compute/server.rb index d7930a473..0f93eb8a5 100644 --- a/lib/fog/ovirt/models/compute/server.rb +++ b/lib/fog/ovirt/models/compute/server.rb @@ -24,18 +24,45 @@ module Fog attribute :host attribute :cluster attribute :template + attribute :interfaces attribute :raw def ready? !(status =~ /down/i) end + def locked? + !!(status =~ /locked/i) + end + def stopped? !!(status =~ /down/i) end def mac - raw.interfaces.first.mac if raw.interfaces + interfaces.first.mac unless interfaces.empty? + end + + def interfaces + attributes[:interfaces] ||= id.nil? ? [] : Fog::Compute::Ovirt::Interfaces.new( + :connection => connection, + :vm => self + ) + end + + def add_interface attrs + wait_for { stopped? } if attrs[:blocking] + connection.add_interface(id, attrs) + end + + def update_interface attrs + wait_for { stopped? } if attrs[:blocking] + connection.update_interface(id, attrs) + end + + def destroy_interface attrs + wait_for { stopped? } if attrs[:blocking] + connection.destroy_interface(id, attrs) end def start(options = {}) diff --git a/lib/fog/ovirt/models/compute/template.rb b/lib/fog/ovirt/models/compute/template.rb index 7e77eb228..48c3af4a5 100644 --- a/lib/fog/ovirt/models/compute/template.rb +++ b/lib/fog/ovirt/models/compute/template.rb @@ -6,6 +6,8 @@ module Fog identity :id + attr_accessor :raw + attribute :name attribute :description attribute :profile @@ -17,6 +19,15 @@ module Fog attribute :cores, :aliases => 'cpus' attribute :memory attribute :cluster + attribute :interfaces + + + def interfaces + attributes[:interfaces] ||= id.nil? ? [] : Fog::Compute::Ovirt::Interfaces.new( + :connection => connection, + :vm => self + ) + end def ready? !(status =~ /down/i) diff --git a/lib/fog/ovirt/requests/compute/add_interface.rb b/lib/fog/ovirt/requests/compute/add_interface.rb new file mode 100644 index 000000000..92c096ad8 --- /dev/null +++ b/lib/fog/ovirt/requests/compute/add_interface.rb @@ -0,0 +1,23 @@ +module Fog + module Compute + class Ovirt + class Real + + def add_interface(id, options = {}) + raise ArgumentError, "instance id is a required parameter" unless id + + client.add_interface(id, options) + end + + end + + class Mock + def add_interface(id, options = {}) + raise ArgumentError, "instance id is a required parameter" unless id + true + end + + end + end + end +end \ No newline at end of file diff --git a/lib/fog/ovirt/requests/compute/destroy_interface.rb b/lib/fog/ovirt/requests/compute/destroy_interface.rb new file mode 100644 index 000000000..00610c24e --- /dev/null +++ b/lib/fog/ovirt/requests/compute/destroy_interface.rb @@ -0,0 +1,25 @@ +module Fog + module Compute + class Ovirt + class Real + + def destroy_interface(id, options) + raise ArgumentError, "instance id is a required parameter" unless id + raise ArgumentError, "interface id is a required parameter for destroy-interface" unless options.has_key? :id + + client.destroy_interface(id, options[:id]) + end + + end + + class Mock + def destroy_interface(id, options) + raise ArgumentError, "instance id is a required parameter" unless id + raise ArgumentError, "interface id is a required parameter for destroy-interface" unless options.has_key? :id + true + end + + end + end + end +end diff --git a/lib/fog/ovirt/requests/compute/list_networks.rb b/lib/fog/ovirt/requests/compute/list_networks.rb new file mode 100644 index 000000000..f4af0d7ea --- /dev/null +++ b/lib/fog/ovirt/requests/compute/list_networks.rb @@ -0,0 +1,17 @@ +module Fog + module Compute + class Ovirt + class Real + def list_networks(cluster_id) + client.networks(:cluster_id => cluster_id) + end + + end + class Mock + def list_networks(cluster_id) + [] + end + end + end + end +end diff --git a/lib/fog/ovirt/requests/compute/list_template_interfaces.rb b/lib/fog/ovirt/requests/compute/list_template_interfaces.rb new file mode 100644 index 000000000..7467dbcd5 --- /dev/null +++ b/lib/fog/ovirt/requests/compute/list_template_interfaces.rb @@ -0,0 +1,20 @@ +module Fog + module Compute + class Ovirt + class Real + def list_template_interfaces(vm_id) + client.template_interfaces(vm_id).map {|ovirt_obj| ovirt_attrs ovirt_obj} + end + + end + class Mock + def list_template_interfaces(vm_id) + xml = read_xml 'nics.xml' + Nokogiri::XML(xml).xpath('/nics/nic').collect do |nic| + ovirt_attrs OVIRT::Interface::new(self, nic) + end + end + end + end + end +end diff --git a/lib/fog/ovirt/requests/compute/list_vm_interfaces.rb b/lib/fog/ovirt/requests/compute/list_vm_interfaces.rb new file mode 100644 index 000000000..9f744b52b --- /dev/null +++ b/lib/fog/ovirt/requests/compute/list_vm_interfaces.rb @@ -0,0 +1,20 @@ +module Fog + module Compute + class Ovirt + class Real + def list_vm_interfaces(vm_id) + client.vm_interfaces(vm_id).map {|ovirt_obj| ovirt_attrs ovirt_obj} + end + + end + class Mock + def list_vm_interfaces(vm_id) + xml = read_xml 'nics.xml' + Nokogiri::XML(xml).xpath('/nics/nic').collect do |nic| + ovirt_attrs OVIRT::Interface::new(self, nic) + end + end + end + end + end +end diff --git a/lib/fog/ovirt/requests/compute/mock_files/nics.xml b/lib/fog/ovirt/requests/compute/mock_files/nics.xml new file mode 100644 index 000000000..90b8738e8 --- /dev/null +++ b/lib/fog/ovirt/requests/compute/mock_files/nics.xml @@ -0,0 +1,10 @@ + + +nic1 + + + +virtio + + + \ No newline at end of file diff --git a/lib/fog/ovirt/requests/compute/update_interface.rb b/lib/fog/ovirt/requests/compute/update_interface.rb new file mode 100644 index 000000000..39c13e8ca --- /dev/null +++ b/lib/fog/ovirt/requests/compute/update_interface.rb @@ -0,0 +1,25 @@ +module Fog + module Compute + class Ovirt + class Real + + def update_interface(id, options) + raise ArgumentError, "instance id is a required parameter" unless id + raise ArgumentError, "interface id is a required parameter for update-interface" unless options.has_key? :id + + client.update_interface(id, options) + end + + end + + class Mock + def update_interface(id, options) + raise ArgumentError, "instance id is a required parameter" unless id + raise ArgumentError, "interface id is a required parameter for update-interface" unless options.has_key? :id + true + end + + end + end + end +end diff --git a/tests/ovirt/compute_tests.rb b/tests/ovirt/compute_tests.rb index 5d066c410..be3db650e 100644 --- a/tests/ovirt/compute_tests.rb +++ b/tests/ovirt/compute_tests.rb @@ -3,19 +3,21 @@ Shindo.tests('Fog::Compute[:ovirt]', ['ovirt']) do compute = Fog::Compute[:ovirt] tests("Compute attributes") do - %w{ client }.each do |attr| + %w{ ovirt_attrs }.each do |attr| test("it should respond to #{attr}") { compute.respond_to? attr } end end tests("Compute collections") do - %w{ servers templates clusters }.each do |collection| + %w{ servers templates clusters interfaces }.each do |collection| test("it should respond to #{collection}") { compute.respond_to? collection } end end tests("Compute requests") do - %w{ datacenters storage_domains vm_action destroy_vm }.each do |collection| + %w{ add_interface create_vm datacenters destroy_interface destroy_vm get_cluster get_template + get_virtual_machine list_clusters list_networks list_template_interfaces list_templates + list_virtual_machines list_vm_interfaces storage_domains update_interface update_vm vm_action }.each do |collection| test("it should respond to #{collection}") { compute.respond_to? collection } end end diff --git a/tests/ovirt/models/compute/interface_tests.rb b/tests/ovirt/models/compute/interface_tests.rb new file mode 100644 index 000000000..5fc836c09 --- /dev/null +++ b/tests/ovirt/models/compute/interface_tests.rb @@ -0,0 +1,27 @@ +Shindo.tests('Fog::Compute[:ovirt] | interface model', ['ovirt']) do + + interfaces = Fog::Compute[:ovirt].servers.last.interfaces + interface = interfaces.last + + tests('The interface model should') do + tests('have the action') do + test('reload') { interface.respond_to? 'reload' } + end + tests('have attributes') do + model_attribute_hash = interface.attributes + attributes = [ :id, :name, :network] + tests("The interface model should respond to") do + attributes.each do |attribute| + test("#{attribute}") { interface.respond_to? attribute } + end + end + tests("The attributes hash should have key") do + attributes.each do |attribute| + test("#{attribute}") { model_attribute_hash.has_key? attribute } + end + end + end + test('be a kind of Fog::Compute::Ovirt::Interface') { interface.kind_of? Fog::Compute::Ovirt::Interface } + end + +end diff --git a/tests/ovirt/models/compute/interfaces_tests.rb b/tests/ovirt/models/compute/interfaces_tests.rb new file mode 100644 index 000000000..9b2117b27 --- /dev/null +++ b/tests/ovirt/models/compute/interfaces_tests.rb @@ -0,0 +1,9 @@ +Shindo.tests('Fog::Compute[:ovirt] | interfaces collection', ['ovirt']) do + + interfaces = Fog::Compute[:ovirt].interfaces + + tests('The interfaces collection') do + test('should be a kind of Fog::Compute::Ovirt::Interfaces') { interfaces.kind_of? Fog::Compute::Ovirt::Interfaces } + end + +end