foreman/app/models/compute_resource.rb @ 132a991c
1c81c2b9 | Ohad Levy | require 'fog_extensions'
|
|
334d0359 | Amos Benari | class ComputeResource < ActiveRecord::Base
|
|
132a991c | Ohad Levy | PROVIDERS = %w[ Libvirt Ovirt EC2 Vmware Openstack].delete_if{|p| p == "Libvirt" && !SETTINGS[:libvirt]}
|
|
3da587a3 | Ohad Levy | audited :except => [:password, :attrs]
|
|
serialize :attrs, Hash
|
|||
334d0359 | Amos Benari | ||
# to STI avoid namespace issues when loading the class, we append Foreman::Model in our database type column
|
|||
STI_PREFIX= "Foreman::Model"
|
|||
ad824a4d | Ohad Levy | before_destroy EnsureNotUsedBy.new(:hosts)
|
|
334d0359 | Amos Benari | include Authorization
|
|
e170c321 | Olivier Favre | has_and_belongs_to_many :users, :join_table => "user_compute_resources"
|
|
334d0359 | Amos Benari | validates_format_of :name, :with => /\A(\S+)\Z/, :message => "can't be blank or contain white spaces."
|
|
validates_uniqueness_of :name
|
|||
validates_presence_of :provider, :in => PROVIDERS
|
|||
validates_presence_of :url
|
|||
scoped_search :on => :name, :complete_value => :true
|
|||
before_save :sanitize_url
|
|||
has_many :hosts
|
|||
dd42df0a | Ohad Levy | has_many :images, :dependent => :destroy
|
|
3da587a3 | Ohad Levy | before_validation :set_attributes_hash
|
|
334d0359 | Amos Benari | ||
e170c321 | Olivier Favre | default_scope :order => 'LOWER(compute_resources.name)'
|
|
scope :my_compute_resources, lambda {
|
|||
user = User.current
|
|||
if user.admin?
|
|||
conditions = { }
|
|||
else
|
|||
conditions = sanitize_sql_for_conditions([" (compute_resources.id in (?))", user.compute_resources.map(&:id)])
|
|||
conditions.sub!(/\s*\(\)\s*/, "")
|
|||
conditions.sub!(/^(?:\(\))?\s?(?:and|or)\s*/, "")
|
|||
conditions.sub!(/\(\s*(?:or|and)\s*\(/, "((")
|
|||
end
|
|||
{:conditions => conditions}
|
|||
}
|
|||
334d0359 | Amos Benari | # allows to create a specific compute class based on the provider.
|
|
def self.new_provider args
|
|||
e170c321 | Olivier Favre | raise "must provide a provider" unless provider = args[:provider]
|
|
334d0359 | Amos Benari | PROVIDERS.each do |p|
|
|
return eval("#{STI_PREFIX}::#{p}").new(args) if p.downcase == provider.downcase
|
|||
end
|
|||
raise "unknown Provider"
|
|||
end
|
|||
dd42df0a | Ohad Levy | def capabilities
|
|
[]
|
|||
end
|
|||
# attributes that this provider can provide back to the host object
|
|||
def provided_attributes
|
|||
{:uuid => :identity}
|
|||
end
|
|||
334d0359 | Amos Benari | def test_connection
|
|
valid?
|
|||
end
|
|||
def save_vm uuid, attr
|
|||
vm = find_vm_by_uuid(uuid)
|
|||
vm.attributes.merge!(attr.symbolize_keys)
|
|||
vm.save
|
|||
end
|
|||
def to_param
|
|||
"#{id}-#{name.parameterize}"
|
|||
end
|
|||
f37934af | Ohad Levy | def to_label
|
|
"#{name} (#{provider_friendly_name})"
|
|||
end
|
|||
def provider_friendly_name
|
|||
a08af7d8 | Ohad Levy | list = SETTINGS[:libvirt] ? ["Libvirt"] : []
|
|
132a991c | Ohad Levy | list += %w[ oVirt EC2 VMWare OpenStack ]
|
|
09ce1364 | Amos Benari | list[PROVIDERS.index(provider)] rescue ""
|
|
f37934af | Ohad Levy | end
|
|
4213d2be | Ohad Levy | # returns a new fog server instance
|
|
334d0359 | Amos Benari | def new_vm attr={}
|
|
client.servers.new vm_instance_defaults.merge(attr)
|
|||
end
|
|||
# return fog new interface ( network adapter )
|
|||
def new_interface attr={}
|
|||
client.interfaces.new attr
|
|||
end
|
|||
# return a list of virtual machines
|
|||
def vms
|
|||
client.servers
|
|||
end
|
|||
def find_vm_by_uuid uuid
|
|||
client.servers.get(uuid) || raise(ActiveRecord::RecordNotFound)
|
|||
end
|
|||
def start_vm uuid
|
|||
find_vm_by_uuid(uuid).start
|
|||
end
|
|||
def stop_vm uuid
|
|||
find_vm_by_uuid(uuid).stop
|
|||
end
|
|||
def create_vm args = {}
|
|||
client.servers.create vm_instance_defaults.merge(args.to_hash)
|
|||
rescue Fog::Errors::Error => e
|
|||
9c2b6c72 | David Swift | logger.debug "Fog error: #{e.message}\n " + e.backtrace.join("\n ")
|
|
errors.add(:base, e.message.to_s)
|
|||
334d0359 | Amos Benari | false
|
|
end
|
|||
def destroy_vm uuid
|
|||
find_vm_by_uuid(uuid).destroy
|
|||
end
|
|||
def provider
|
|||
read_attribute(:type).to_s.gsub("#{STI_PREFIX}::","")
|
|||
end
|
|||
def provider=(value)
|
|||
if PROVIDERS.include? value
|
|||
self.type = "#{STI_PREFIX}::#{value}"
|
|||
end
|
|||
end
|
|||
def vm_instance_defaults
|
|||
{
|
|||
'name' => "foreman_#{Time.now.to_i}",
|
|||
}
|
|||
end
|
|||
def hardware_profiles(opts={})
|
|||
end
|
|||
def hardware_profile(id,opts={})
|
|||
end
|
|||
def update_required?(old_attrs, new_attrs)
|
|||
old_attrs.merge(new_attrs) do |k,old_v,new_v|
|
|||
update_required?(old_v, new_v) if old_v.is_a?(Hash)
|
|||
return true unless old_v == new_v
|
|||
new_v
|
|||
end
|
|||
false
|
|||
end
|
|||
def as_json(options={})
|
|||
super({:except => [:password]}.merge(options))
|
|||
end
|
|||
f37934af | Ohad Levy | def console uuid = nil
|
|
raise "#{provider} console is not supported at this time"
|
|||
end
|
|||
334d0359 | Amos Benari | protected
|
|
def client
|
|||
raise "Not implemented"
|
|||
end
|
|||
def sanitize_url
|
|||
self.url.chomp!("/") unless url.empty?
|
|||
end
|
|||
f37934af | Ohad Levy | ||
def random_password
|
|||
n = 8
|
|||
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
|
|||
(0...n).map { chars[rand(chars.length)].chr }.join
|
|||
end
|
|||
96ede451 | Amos Benari | def nested_attributes_for type, opts
|
|
return [] unless opts
|
|||
opts = opts.dup #duplicate to prevent changing the origin opts.
|
|||
opts.delete("new_#{type}") # delete template
|
|||
# convert our options hash into a sorted array (e.g. to preserve nic / disks order)
|
|||
opts = opts.sort { |l, r| l[0].sub('new_','').to_i <=> r[0].sub('new_','').to_i }.map { |e| Hash[e[1]] }
|
|||
opts.map do |v|
|
|||
2a08c26b | Amos Benari | if v[:"_delete"] == '1' && v[:id].blank?
|
|
96ede451 | Amos Benari | nil
|
|
else
|
|||
v.symbolize_keys # convert to symbols deeper hashes
|
|||
end
|
|||
end.compact
|
|||
end
|
|||
e170c321 | Olivier Favre | private
|
|
def enforce_permissions operation
|
|||
# We get called again with the operation being set to create
|
|||
return true if operation == "edit" and new_record?
|
|||
current = User.current
|
|||
if current.allowed_to?("#{operation}_compute_resources".to_sym)
|
|||
# If you can create compute resources then you can create them anywhere
|
|||
return true if operation == "create"
|
|||
# edit or delete
|
|||
if current.allowed_to?("#{operation}_compute_resources".to_sym)
|
|||
return true if ComputeResource.my_compute_resources(current).include? self
|
|||
end
|
|||
end
|
|||
errors.add :base, "You do not have permission to #{operation} this compute resource"
|
|||
false
|
|||
end
|
|||
3da587a3 | Ohad Levy | def set_attributes_hash
|
|
self.attrs ||= {}
|
|||
end
|
|||
334d0359 | Amos Benari | end
|