From ae29d968c6e7a62e328655334784ccd3a97dee38 Mon Sep 17 00:00:00 2001 From: Amos Benari Date: Sun, 22 Jan 2012 17:38:02 +0200 Subject: [PATCH] Adds Supprt for oVirt (http://ovirt.org). Signed-off-by: Ohad Levy --- lib/fog/compute.rb | 3 + lib/fog/ovirt.rb | 17 +++++ lib/fog/ovirt/compute.rb | 52 +++++++++++++ lib/fog/ovirt/models/compute/cluster.rb | 26 +++++++ lib/fog/ovirt/models/compute/clusters.rb | 26 +++++++ .../compute/helpers/collection_helper.rb | 32 ++++++++ lib/fog/ovirt/models/compute/server.rb | 76 +++++++++++++++++++ lib/fog/ovirt/models/compute/servers.rb | 33 ++++++++ lib/fog/ovirt/models/compute/template.rb | 42 ++++++++++ lib/fog/ovirt/models/compute/templates.rb | 26 +++++++ lib/fog/ovirt/requests/compute/datacenters.rb | 19 +++++ lib/fog/ovirt/requests/compute/destroy_vm.rb | 22 ++++++ .../ovirt/requests/compute/storage_domains.rb | 19 +++++ lib/fog/ovirt/requests/compute/vm_action.rb | 26 +++++++ lib/fog/providers.rb | 1 + 15 files changed, 420 insertions(+) create mode 100644 lib/fog/ovirt.rb create mode 100644 lib/fog/ovirt/compute.rb create mode 100644 lib/fog/ovirt/models/compute/cluster.rb create mode 100644 lib/fog/ovirt/models/compute/clusters.rb create mode 100644 lib/fog/ovirt/models/compute/helpers/collection_helper.rb create mode 100644 lib/fog/ovirt/models/compute/server.rb create mode 100644 lib/fog/ovirt/models/compute/servers.rb create mode 100644 lib/fog/ovirt/models/compute/template.rb create mode 100644 lib/fog/ovirt/models/compute/templates.rb create mode 100644 lib/fog/ovirt/requests/compute/datacenters.rb create mode 100644 lib/fog/ovirt/requests/compute/destroy_vm.rb create mode 100644 lib/fog/ovirt/requests/compute/storage_domains.rb create mode 100644 lib/fog/ovirt/requests/compute/vm_action.rb diff --git a/lib/fog/compute.rb b/lib/fog/compute.rb index 1f7b941b4..74b454c15 100644 --- a/lib/fog/compute.rb +++ b/lib/fog/compute.rb @@ -47,6 +47,9 @@ module Fog when :openstack require 'fog/openstack/compute' Fog::Compute::OpenStack.new(attributes) + when :ovirt + require 'fog/ovirt/compute' + Fog::Compute::Ovirt.new(attributes) when :rackspace require 'fog/rackspace/compute' Fog::Compute::Rackspace.new(attributes) diff --git a/lib/fog/ovirt.rb b/lib/fog/ovirt.rb new file mode 100644 index 000000000..268437db9 --- /dev/null +++ b/lib/fog/ovirt.rb @@ -0,0 +1,17 @@ +require 'fog/core' + +module Fog + module Ovirt + + extend Fog::Provider + + module Errors + class ServiceError < Fog::Errors::Error; end + class SecurityError < ServiceError; end + class NotFound < ServiceError; end + end + + service(:compute, 'ovirt/compute', 'Compute') + + end +end diff --git a/lib/fog/ovirt/compute.rb b/lib/fog/ovirt/compute.rb new file mode 100644 index 000000000..b01789d27 --- /dev/null +++ b/lib/fog/ovirt/compute.rb @@ -0,0 +1,52 @@ + +module Fog + module Compute + class Ovirt < Fog::Service + + requires :ovirt_username, :ovirt_password + recognizes :ovirt_url, :ovirt_server, :ovirt_port, :ovirt_api_path, :ovirt_datacenter + + model_path 'fog/ovirt/models/compute' + model :server + collection :servers + model :template + collection :templates + model :cluster + collection :clusters + + request_path 'fog/ovirt/requests/compute' + + request :vm_action + request :destroy_vm + request :datacenters + request :storage_domains + + class Mock + + def initialize(options={}) + username = options[:ovirt_username] + password = options[:password] + url = options[:ovirt_url] + end + + end + + class Real + attr_reader :client + + def initialize(options={}) + require 'rbovirt' + username = options[:ovirt_username] + password = options[:ovirt_password] + server = options[:ovirt_server] + port = options[:ovirt_port] || 8080 + api_path = options[:ovirt_api_path] || '/api' + url = options[:ovirt_url] || "#{@scheme}://#{@ovirt_server}:#{@ovirt_port}#{@ovirt_api_path}" + datacenter = options[:ovirt_datacenter] + + @client = OVIRT::Client.new(username, password, url, datacenter) + end + end + end + end +end diff --git a/lib/fog/ovirt/models/compute/cluster.rb b/lib/fog/ovirt/models/compute/cluster.rb new file mode 100644 index 000000000..50dc10f82 --- /dev/null +++ b/lib/fog/ovirt/models/compute/cluster.rb @@ -0,0 +1,26 @@ +require 'fog/compute/models/server' + +module Fog + module Compute + class Ovirt + + class Cluster < Fog::Model + + identity :id + + attribute :name + attribute :raw + + def networks + connection.client.networks(:cluster_id => id) + end + + def to_s + name + end + + end + + end + end +end diff --git a/lib/fog/ovirt/models/compute/clusters.rb b/lib/fog/ovirt/models/compute/clusters.rb new file mode 100644 index 000000000..1bf2306d6 --- /dev/null +++ b/lib/fog/ovirt/models/compute/clusters.rb @@ -0,0 +1,26 @@ +require 'fog/core/collection' +require 'fog/ovirt/models/compute/cluster' +require 'fog/ovirt/models/compute/helpers/collection_helper' + +module Fog + module Compute + class Ovirt + + class Clusters < Fog::Collection + + include Fog::Compute::Ovirt::Helpers::CollectionHelper + model Fog::Compute::Ovirt::Cluster + + def all(filters = {}) + attrs = connection.client.clusters(filters).map { |cluster| ovirt_attrs(cluster) } + load attrs + end + + def get(id) + new ovirt_attrs(connection.client.cluster(id)) + end + + end + end + end +end diff --git a/lib/fog/ovirt/models/compute/helpers/collection_helper.rb b/lib/fog/ovirt/models/compute/helpers/collection_helper.rb new file mode 100644 index 000000000..66a0a952a --- /dev/null +++ b/lib/fog/ovirt/models/compute/helpers/collection_helper.rb @@ -0,0 +1,32 @@ +module Fog + module Compute + class Ovirt + module Helpers + module CollectionHelper + + # converts an OVIRT object into an hash for fog to consume. + def ovirt_attrs obj + opts = {:raw => obj} + obj.instance_variables.each do |v| + key = v.gsub("@","").to_sym + value = obj.instance_variable_get(v) + #ignore nil values + next if value.nil? + + opts[key] = case value.class + when OVIRT::Link + value.id + when Hash + value + else + value.to_s.strip + end + end + opts + end + + end + end + end + end +end diff --git a/lib/fog/ovirt/models/compute/server.rb b/lib/fog/ovirt/models/compute/server.rb new file mode 100644 index 000000000..7059f30de --- /dev/null +++ b/lib/fog/ovirt/models/compute/server.rb @@ -0,0 +1,76 @@ +require 'fog/compute/models/server' + +module Fog + module Compute + class Ovirt + + class Server < Fog::Compute::Server + + # This will be the instance uuid which is globally unique across + # a oVirt deployment. + identity :id + + attribute :name + attribute :description + attribute :profile + attribute :display + attribute :storage, :aliases => 'disk_size' + attribute :creation_time + attribute :os + attribute :ip + attribute :status + attribute :cores, :aliases => 'cpus' + attribute :memory + attribute :host + attribute :cluster + attribute :template + attribute :raw + + def ready? + !(status =~ /down/i) + end + + def stopped? + !!(status =~ /down/i) + end + + def mac + raw.interfaces.first.mac if raw.interfaces + end + + def start(options = {}) + connection.client.vm_action(id, :start) + reload + end + + def stop(options = {}) + connection.client.vm_action(id, :stop) + reload + end + + def reboot(options = {}) + connection.client.vm_action(id, :reboot) + reload + end + + def destroy(options = {}) + stop unless stopped? + wait_for { stopped? } + connection.client.destroy_vm(id) + end + + def save + raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if identity + self.id = connection.client.create_vm(attributes).id + reload + end + + def to_s + name + end + + end + + end + end +end diff --git a/lib/fog/ovirt/models/compute/servers.rb b/lib/fog/ovirt/models/compute/servers.rb new file mode 100644 index 000000000..d02b1a974 --- /dev/null +++ b/lib/fog/ovirt/models/compute/servers.rb @@ -0,0 +1,33 @@ +require 'fog/core/collection' +require 'fog/ovirt/models/compute/server' +require 'fog/ovirt/models/compute/helpers/collection_helper' + +module Fog + module Compute + class Ovirt + + class Servers < Fog::Collection + + include Fog::Compute::Ovirt::Helpers::CollectionHelper + model Fog::Compute::Ovirt::Server + + def all(filters = {}) + attrs = connection.client.vms(filters).map { |server| ovirt_attrs(server) } + load attrs + end + + def get(id) + new ovirt_attrs(connection.client.vm(id)) + end + + def bootstrap(new_attributes = {}) + server = create(new_attributes) + server.wait_for { stopped? } + server.start + server + end + + end + end + end +end diff --git a/lib/fog/ovirt/models/compute/template.rb b/lib/fog/ovirt/models/compute/template.rb new file mode 100644 index 000000000..7e77eb228 --- /dev/null +++ b/lib/fog/ovirt/models/compute/template.rb @@ -0,0 +1,42 @@ +module Fog + module Compute + class Ovirt + + class Template < Fog::Model + + identity :id + + attribute :name + attribute :description + attribute :profile + attribute :display + attribute :storage, :aliases => 'disk_size' + attribute :creation_time + attribute :os + attribute :status + attribute :cores, :aliases => 'cpus' + attribute :memory + attribute :cluster + + def ready? + !(status =~ /down/i) + end + + def destroy(options = {}) + connection.client.destroy_template(id) + end + + def save + raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if identity + connection.client.create_template(attributes) + end + + def to_s + name + end + + end + + end + end +end diff --git a/lib/fog/ovirt/models/compute/templates.rb b/lib/fog/ovirt/models/compute/templates.rb new file mode 100644 index 000000000..f69d18a09 --- /dev/null +++ b/lib/fog/ovirt/models/compute/templates.rb @@ -0,0 +1,26 @@ +require 'fog/core/collection' +require 'fog/ovirt/models/compute/template' +require 'fog/ovirt/models/compute/helpers/collection_helper' + +module Fog + module Compute + class Ovirt + + class Templates < Fog::Collection + + include Fog::Compute::Ovirt::Helpers::CollectionHelper + model Fog::Compute::Ovirt::Template + + def all(filters = {}) + attrs = connection.client.templates(filters).map { |template| ovirt_attrs(template) } + load attrs + end + + def get(id) + new ovirt_attrs(connection.client.template(id)) + end + + end + end + end +end diff --git a/lib/fog/ovirt/requests/compute/datacenters.rb b/lib/fog/ovirt/requests/compute/datacenters.rb new file mode 100644 index 000000000..7978fef8d --- /dev/null +++ b/lib/fog/ovirt/requests/compute/datacenters.rb @@ -0,0 +1,19 @@ +module Fog + module Compute + class Ovirt + class Real + + def datacenters filter={} + client.datacenters(filter) + end + + end + + class Mock + def datacenters filter={} + [ "Solutions", "Solutions2", "Solutions3" ] + end + end + end + end +end diff --git a/lib/fog/ovirt/requests/compute/destroy_vm.rb b/lib/fog/ovirt/requests/compute/destroy_vm.rb new file mode 100644 index 000000000..8bc221104 --- /dev/null +++ b/lib/fog/ovirt/requests/compute/destroy_vm.rb @@ -0,0 +1,22 @@ +module Fog + module Compute + class Ovirt + class Real + + def destroy_vm(options = {}) + raise ArgumentError, "instance id is a required parameter" unless options.has_key? :id + client.destroy_vm(options[:id]) + end + + end + + class Mock + def destroy_vm(options = {}) + raise ArgumentError, "instance id is a required parameter" unless options.has_key? :id + true + end + + end + end + end +end diff --git a/lib/fog/ovirt/requests/compute/storage_domains.rb b/lib/fog/ovirt/requests/compute/storage_domains.rb new file mode 100644 index 000000000..05380f9d3 --- /dev/null +++ b/lib/fog/ovirt/requests/compute/storage_domains.rb @@ -0,0 +1,19 @@ +module Fog + module Compute + class Ovirt + class Real + + def storage_domains filter={} + client.storage_domains(filter) + end + + end + + class Mock + def storage_domains filter={} + [ "Storage", "Storage2", "Storage3" ] + end + end + end + end +end diff --git a/lib/fog/ovirt/requests/compute/vm_action.rb b/lib/fog/ovirt/requests/compute/vm_action.rb new file mode 100644 index 000000000..d71be381c --- /dev/null +++ b/lib/fog/ovirt/requests/compute/vm_action.rb @@ -0,0 +1,26 @@ +module Fog + module Compute + class Ovirt + class Real + + def vm_action(options = {}) + raise ArgumentError, "instance id is a required parameter" unless options.has_key? :id + raise ArgumentError, "action is a required parameter" unless options.has_key? :action + + client.vm_action options[:id], options[:action] + end + + end + + class Mock + + def vm_action(options = {}) + raise ArgumentError, "id is a required parameter" unless options.has_key? :id + raise ArgumentError, "action is a required parameter" unless options.has_key? :action + true + end + + end + end + end +end diff --git a/lib/fog/providers.rb b/lib/fog/providers.rb index f456b04c8..303f2c32e 100644 --- a/lib/fog/providers.rb +++ b/lib/fog/providers.rb @@ -17,6 +17,7 @@ require 'fog/new_servers' require 'fog/ninefold' require 'fog/rackspace' require 'fog/openstack' +require 'fog/ovirt' require 'fog/slicehost' require 'fog/storm_on_demand' require 'fog/vcloud'