Project

General

Profile

« Previous | Next » 

Revision 132a991c

Added by Ohad Levy almost 12 years ago

  • ID 132a991c8c441c86864a35c666dd41748213bdaf

basic openstack support

View differences:

app/helpers/compute_resources_vms_helper.rb
case value
when Array
value.to_sentence
when Fog::Time
when Fog::Time, Time
time_ago_in_words(value) + " ago"
when nil
"N/A"
else
value.to_s
end
app/models/compute_resource.rb
require 'fog_extensions'
class ComputeResource < ActiveRecord::Base
PROVIDERS = %w[ Libvirt Ovirt EC2 Vmware ].delete_if{|p| p == "Libvirt" && !SETTINGS[:libvirt]}
PROVIDERS = %w[ Libvirt Ovirt EC2 Vmware Openstack].delete_if{|p| p == "Libvirt" && !SETTINGS[:libvirt]}
audited :except => [:password, :attrs]
serialize :attrs, Hash
......
def provider_friendly_name
list = SETTINGS[:libvirt] ? ["Libvirt"] : []
list += %w[ oVirt EC2 VMWare ]
list += %w[ oVirt EC2 VMWare OpenStack ]
list[PROVIDERS.index(provider)] rescue ""
end
app/views/compute_resources/form/_openstack.html.erb
<%= text_f f, :url, :label => "Authentication URL", :class => "input-xlarge", :help_block => "e.g. http://openstack:5000/v2.0/tokens" %>
<%= text_f f, :user, :label => "Access Key" %>
<%= password_f f, :password, :label => "Secret Key" %>
<% tenants = f.object.tenants rescue [] %>
<%= selectable_f(f, :tenant, tenants, {}, {:label => 'Tenant', :disabled => tenants.empty?,
:help_inline => link_to_function(tenants.empty? ? "Load Tenants" : "Test Connection", "testConnection(this)",
:class => "btn + #{tenants.empty? ? "" : "btn-success"}",
:'data-url' => test_connection_compute_resources_path) + image_tag('spinner.gif', :id => 'test_connection_indicator', :class => 'hide').html_safe }) %>
app/views/compute_resources_vms/form/_openstack.html.erb
<%= select_f f, :flavor_ref, compute_resource.flavors, :id, :name, {}, :label => 'Flavor' %>
<div id='image_selection'><%= select_f f, :image_ref, compute_resource.images, :id, :name, {:include_blank =>'Please Select an Image'}, :label => "Image" %></div>
<%= select_f f, :tenant_id, compute_resource.tenants, :id, :name %>
<%= select_f f, :security_groups, compute_resource.security_groups, :name, :name, {}, :label => "Security Group" %>
app/views/compute_resources_vms/index/_openstack.html.erb
<table class="table table-bordered">
<tr>
<thead>
<th>Name</th>
<th>Type</th>
<th>Tenant</th>
<th>State</th>
<th></th>
</thead>
</tr>
<% @compute_resource.vms.each do |vm| -%>
<tr>
<td><%= link_to_if_authorized vm.name, hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.identity) %></td>
<td><%= vm.flavor_with_object %></td>
<td><%= vm.tenant %></td>
<td <%= vm_power_class(vm.ready?)%>> <%= vm_state(!vm.ready?) %> </td>
<td>
<%= action_buttons(vm_power_action(vm),
display_delete_if_authorized(hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.id))) %>
</td>
</tr>
<% end -%>
</table>
app/views/compute_resources_vms/show/_openstack.html.erb
<% title @vm.name %>
<div class='span12'>
<table class="table table-bordered table-striped">
<tr><th colspan="2">Properties</th></tr>
<%= prop :availability_zone %>
<%= prop :first_private_ip_address %>
<%= prop :state %>
<%= prop :created_at %>
<%= prop :tenant %>
<%= prop :flavor_with_object, "Flavor" %>
<%= prop :security_groups, "Security Groups" %>
</table>
</div>
lib/fog_extensions.rb
require 'fog/ovirt/models/compute/volume'
Fog::Compute::Ovirt::Volume.send(:include, FogExtensions::Ovirt::Volume)
require 'fog/openstack'
require 'fog/openstack/models/compute/server'
Fog::Compute::OpenStack::Server.send(:include, FogExtensions::Openstack::Server)
require 'fog/openstack/models/compute/flavor'
Fog::Compute::OpenStack::Flavor.send(:include, FogExtensions::Openstack::Flavor)
rescue LoadError
Rails.logger.info "Fog is not installed - unable to manage compute resources"
rescue => exception
Rails.logger.warn "Fog initialization failed - #{exception}"
Rails.logger.debug exception.join("\n")
Rails.logger.debug exception.backtrace.join("\n")
end
lib/fog_extensions/openstack/flavor.rb
module FogExtensions
module Openstack
module Flavor
def to_label
"#{id} - #{name}"
end
def to_s
name
end
end
end
end
lib/fog_extensions/openstack/server.rb
module FogExtensions
module Openstack
module Server
#TODO: get as much of this merged into fog 1.5
def tenant
connection.tenants.detect{|t| t.id == tenant_id }
end
# alias_method_chain :flavor, :object
def flavor_with_object
connection.flavors.get attributes[:flavor]['id']
end
def first_private_ip_address
private_ip_address["addr"]
end
def created_at
Time.parse attributes['created']
end
def security_groups
connection.security_groups.all
end
end
end
end
lib/foreman/model/openstack.rb
module Foreman::Model
class Openstack < ComputeResource
attr_accessor :tenant
has_one :key_pair, :foreign_key => :compute_resource_id
after_create :setup_key_pair
after_destroy :destroy_key_pair
delegate :flavors, :to => :client
delegate :tenants, :to => :client
delegate :security_groups, :to => :client
delegate :images, :to => :client
validates_presence_of :user, :password
def provided_attributes
super.merge({ :ip => :public_ip_address })
end
def self.model_name
ComputeResource.model_name
end
def capabilities
[:image]
end
def test_connection
super
errors[:user].empty? and errors[:password] and tenants
rescue => e
errors[:base] << e.message
end
private
def client
@client ||= ::Fog::Compute.new(:provider => :openstack, :openstack_api_key => password, :openstack_username => user, :openstack_auth_url => url)
end
def setup_key_pair
key = client.key_pairs.create :name => "foreman-#{id}#{Foreman.uuid}"
KeyPair.create! :name => key.name, :compute_resource_id => self.id, :secret => key.private_key
rescue => e
logger.warn "failed to generate key pair"
destroy_key_pair
raise
end
def destroy_key_pair
return unless key_pair
logger.info "removing OpenStack key #{key_pair.name}"
key = client.key_pairs.get(key_pair.name)
key.destroy if key
key_pair.destroy
true
rescue => e
logger.warn "failed to delete key pair from OpenStack, you might need to cleanup manually : #{e}"
end
def vm_instance_defaults
{
:name => "foreman-#{Foreman.uuid}",
:key_name => key_pair.name,
}
end
end
end

Also available in: Unified diff