Skip to content

Commit

Permalink
fixes #18064 - import host from compute resource
Browse files Browse the repository at this point in the history
  • Loading branch information
timogoebel authored and dLobatog committed Mar 22, 2017
1 parent e53fd8e commit 637da2f
Show file tree
Hide file tree
Showing 55 changed files with 585 additions and 148 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Metrics/MethodLength:
# Offense count: 22
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 420
Max: 424

# Offense count: 9
# Configuration parameters: CountKeywordArgs.
Expand Down
4 changes: 1 addition & 3 deletions app/assets/javascripts/host_edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,13 @@ function update_capabilities(capabilities){
var stop_pooling;

function submit_with_all_params(){
var url = window.location.pathname.replace(/\/edit$|\/new|\/\d+.*\/nest$/,'');
var url = $('form').attr('action');
if (url.match('hostgroups')) {
resource = 'hostgroup'
} else {
resource = 'host'
}
resources = resource + 's';
capitalized_resource = resource[0].toUpperCase + resource.slice(1);
if(/\/clone$/.test(window.location.pathname)){ url = foreman_url('/' + resources); }
$('form input[type="submit"]').attr('disabled', true);
stop_pooling = false;
$("body").css("cursor", "progress");
Expand Down
17 changes: 15 additions & 2 deletions app/controllers/api/v2/hosts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,13 @@ def show
param_group :host, :as => :create

def create
@host = Host.new(host_attributes(host_params))
@host.managed = true if (params[:host] && params[:host][:managed].nil?)
if params[:host][:uuid].present? && params[:host][:compute_resource_id].present?
@host = import_host
@host.assign_attributes(host_attributes(host_params))
else
@host = Host.new(host_attributes(host_params))
@host.managed = true if (params[:host] && params[:host][:managed].nil?)
end
apply_compute_profile(@host)
@host.suggest_default_pxe_loader if params[:host] && params[:host][:pxe_loader].nil?

Expand Down Expand Up @@ -379,6 +384,14 @@ def resource_class_join(association, scope)
resource_class_join = resource_class.joins(association.name)
resource_class_join.merge(scope).present? ? resource_class_join.merge(scope) : resource_class_join
end

def import_host
compute_resource = ComputeResource.authorized(:edit_compute_resources).find(params[:host][:compute_resource_id])
ComputeResourceHostImporter.new(
:compute_resource => compute_resource,
:uuid => params[:host][:uuid]
).host
end
end
end
end
59 changes: 34 additions & 25 deletions app/controllers/compute_resources_vms_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
class ComputeResourcesVmsController < ApplicationController
include Foreman::Controller::ComputeResourcesCommon
include ::Foreman::Controller::ActionPermissionDsl

before_action :find_compute_resource
before_action :find_vm, :only => [:import, :associate, :show, :console, :pause, :power]

helper :hosts

def controller_permission
return :compute_resources if params[:action] == 'associate'
super
end

def index
@compute_resource = find_compute_resource(:view_compute_resources_vms)
load_vms
@authorizer = Authorizer.new(User.current, :collection => [@compute_resource])
respond_to do |format|
Expand All @@ -20,13 +31,10 @@ def index
end

def new
@compute_resource = find_compute_resource
@vm = @compute_resource.new_vm
end

def create
@compute_resource = find_compute_resource

if (vm = @compute_resource.create_vm params[:vm])
@compute_resource.start_vm(vm.identity) if params[:vm][:start]=='1'
process_success :success_redirect => compute_resource_vms_path(@compute_resource)
Expand All @@ -36,44 +44,35 @@ def create
end

def associate
@compute_resource = find_compute_resource(:edit_compute_resources)
@vm = find_vm
if Host.for_vm(@compute_resource, @vm).any?
process_error(:error_msg => _("VM already associated with a host"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => @vm.identity))
return
end
host = @compute_resource.associated_host(@vm) if @compute_resource.respond_to?(:associated_host)
if host.present?
host.associate!(@compute_resource, @vm)
process_success(:success_msg => _("VM associated to host %s") % host.name, :success_redirect => host_path(host))
else
host = @compute_resource.associated_host(@vm) if @compute_resource.respond_to?(:associated_host)
if host.present?
host.associate!(@compute_resource, @vm)
process_success(:success_msg => _("VM associated to host %s") % host.name, :success_redirect => host_path(host))
else
process_error(:error_msg => _("No host found to associate this VM with"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => @vm.identity))
end
process_error(:error_msg => _("No host found to associate this VM with"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => @vm.identity))
end
end

def show
@compute_resource = find_compute_resource(:view_compute_resources_vms)
@vm = find_vm
respond_to do |format|
format.html
format.json { render :json => @vm }
end
end

def power
@compute_resource = find_compute_resource(:power_compute_resources_vms)
@vm = find_vm
run_vm_action(@vm.ready? ? :stop : :start)
end

def pause
@compute_resource = find_compute_resource(:power_compute_resources_vms)
@vm = find_vm
run_vm_action(@vm.ready? ? :pause : :start)
end

def destroy
@compute_resource = find_compute_resource(:destroy_compute_resources_vms)
if @compute_resource.destroy_vm params[:id]
process_success({ :success_redirect => compute_resource_vms_path(@compute_resource), :success_msg => _('The virtual machine is being deleted.') })
else
Expand All @@ -82,8 +81,6 @@ def destroy
end

def console
@compute_resource = find_compute_resource(:console_compute_resources_vms)
@vm = find_vm
@console = @compute_resource.console @vm.identity
@encrypt = Setting[:websockets_encrypt]
render case @console[:type]
Expand All @@ -98,14 +95,26 @@ def console
process_error :redirect => compute_resource_vm_path(@compute_resource, @vm.identity), :error_msg => (_("Failed to set console: %s") % e), :object => @vm
end

def import
@host = ComputeResourceHostImporter.new(
:compute_resource => @compute_resource,
:vm => @vm
).host
end

private

def find_compute_resource(permission = :view_compute_resources)
ComputeResource.authorized(permission).find(params[:compute_resource_id])
define_action_permission 'console', :console
define_action_permission ['pause', 'power'], :power
define_action_permission 'import', :view
define_action_permission 'edit', :associate # edit_compute_resources

def find_compute_resource
@compute_resource = ComputeResource.authorized(current_permission).find(params[:compute_resource_id])
end

def find_vm
@compute_resource.find_vm_by_uuid params[:id]
@vm = @compute_resource.find_vm_by_uuid(params[:id])
end

def run_vm_action(action)
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/hosts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ def show
end

def new
@host = Host.new :managed => true
@host = Host.new(
:managed => true,
:build => true
)
end

# Clone the host
Expand Down
21 changes: 15 additions & 6 deletions app/helpers/compute_resources_vms_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def openstack_available_actions(vm, authorizer = nil)
actions << vm_power_action(vm, authorizer)
end

actions << vm_import_action(vm)
actions << vm_delete_action(vm, authorizer)
end

Expand Down Expand Up @@ -171,13 +172,9 @@ def show_vm_name?
controller_name != 'hosts' && controller_name != 'compute_attributes'
end

def new_host?(host)
host.try(:new_record?)
end

def vsphere_resource_pools(form, compute_resource, new_host = false)
def vsphere_resource_pools(form, compute_resource, disabled = false)
resource_pools = compute_resource.available_resource_pools(:cluster_id => form.object.cluster) rescue []
selectable_f form, :resource_pool, resource_pools, { }, :class => "col-md-2", :label => _('Resource pool'), :disabled => !new_host
selectable_f form, :resource_pool, resource_pools, { }, :class => "col-md-2", :label => _('Resource pool'), :disabled => disabled
end

def vms_table
Expand Down Expand Up @@ -206,6 +203,7 @@ def ovirt_vms_data
number_to_human_size(vm.memory),
"<span #{vm_power_class(vm.ready?)}>#{vm_state(vm)}</span>",
action_buttons(vm_power_action(vm, authorizer),
vm_import_action(vm),
display_delete_if_authorized(hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.id).merge(:auth_object => @compute_resource, :authorizer => authorizer)))
]
end
Expand All @@ -215,4 +213,15 @@ def ovirt_vms_data
def vm_delete_action(vm, authorizer = nil)
display_delete_if_authorized(hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.identity).merge(:auth_object => @compute_resource, :authorizer => authorizer), :class => 'btn btn-danger')
end

def new_vm?(host)
return true unless host.present?
return true unless host.compute_object.present?
!host.compute_object.persisted?
end

def vm_import_action(vm)
return unless Host.for_vm(@compute_resource, vm).empty?
display_link_if_authorized(_("Import"), hash_for_import_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.identity))
end
end
5 changes: 5 additions & 0 deletions app/helpers/hosts_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -482,4 +482,9 @@ def randomize_mac_link
def power_status_visible?
SETTINGS[:unattended] && Setting[:host_power_status]
end

def host_or_hostgroup_path(method)
controller = controller_name == 'hostgroups' ? 'hostgroups' : 'hosts'
send("#{method}_#{controller}_path")
end
end
11 changes: 8 additions & 3 deletions app/models/compute_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -314,14 +314,19 @@ def compute_profile_attributes_for(id)

def vm_compute_attributes_for(uuid)
vm = find_vm_by_uuid(uuid)
return {} unless vm
vm_compute_attributes(vm)
rescue ActiveRecord::RecordNotFound
logger.warn("VM with UUID '#{uuid}' not found on #{self}")
{}
end

def vm_compute_attributes(vm)
vm_attrs = vm.attributes rescue {}
vm_attrs = vm_attrs.reject{|k,v| k == :id }

vm_attrs = set_vm_volumes_attributes(vm, vm_attrs)
vm_attrs
rescue ActiveRecord::RecordNotFound
logger.warn("VM with UUID '#{uuid}' not found on #{self}")
{}
end

def user_data_supported?
Expand Down
37 changes: 21 additions & 16 deletions app/models/compute_resources/foreman/model/vmware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class Vmware < ComputeResource
validates :user, :password, :server, :datacenter, :presence => true
before_create :update_public_key

alias_attribute :server, :url
alias_attribute :datacenter, :uuid

def self.available?
Fog::Compute.providers.include?(:vsphere)
end
Expand Down Expand Up @@ -472,22 +475,6 @@ def clone_vm(raw_args)
client.servers.get(client.vm_clone(opts)['new_vm']['id'])
end

def server
url
end

def server=(value)
self.url = value
end

def datacenter
uuid
end

def datacenter=(value)
self.uuid = value
end

def console(uuid)
vm = find_vm_by_uuid(uuid)
raise "VM is not running!" unless vm.ready?
Expand Down Expand Up @@ -526,6 +513,24 @@ def self.provider_friendly_name
"VMware"
end

def vm_compute_attributes(vm)
vm_attrs = super
dc_networks = networks
interfaces = vm.interfaces || []
vm_attrs[:interfaces_attributes] = interfaces.each_with_index.inject({}) do |hsh, (interface, index)|
network = dc_networks.detect { |n| [n.id, n.name].include?(interface.network) }
raise Foreman::Exception.new(N_("Could not find network %s on VMWare compute resource"), interface.network) unless network
interface_attrs = {}
interface_attrs[:compute_attributes] = {}
interface_attrs[:mac] = interface.mac
interface_attrs[:compute_attributes][:network] = network.name
interface_attrs[:compute_attributes][:type] = interface.type.to_s.split('::').last
hsh[index.to_s] = interface_attrs
hsh
end
vm_attrs
end

private

def dc
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/fog_extensions/aws/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Server
attr_accessor :managed_ip

def to_s
tags["Name"] || identity
tags.try([], 'Name') || identity
end

def name
Expand Down
15 changes: 11 additions & 4 deletions app/models/concerns/orchestration/compute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def vm_name

def queue_compute
return unless compute? && errors.empty?
new_record? ? queue_compute_create : queue_compute_update
# Create a new VM if it doesn't already exist or update an existing vm
vm_exists? ? queue_compute_create : queue_compute_update
end

def queue_compute_create
Expand All @@ -52,7 +53,7 @@ def queue_compute_create
queue.create(:name => _("Set IP addresses for %s") % self, :priority => 5,
:action => [self, :setComputeIPAM]) if compute_provides?(:mac) && (mac_based_ipam?(:subnet) || mac_based_ipam?(:subnet6))
queue.create(:name => _("Power up compute instance %s") % self, :priority => 1000,
:action => [self, :setComputePowerUp]) if compute_attributes[:start] == '1'
:action => [self, :setComputePowerUp]) if compute_attributes && compute_attributes[:start] == '1'
end

def queue_compute_update
Expand Down Expand Up @@ -215,8 +216,9 @@ def delComputeUpdate

def compute_update_required?
return false unless compute_resource.supports_update? && !compute_attributes.nil?
old.compute_attributes = compute_resource.vm_compute_attributes_for(uuid)
compute_resource.update_required?(old.compute_attributes, compute_attributes)
attrs = compute_resource.vm_compute_attributes_for(uuid)
old.compute_attributes = attrs if old
compute_resource.update_required?(attrs, compute_attributes.symbolize_keys)
end

def find_image
Expand Down Expand Up @@ -345,4 +347,9 @@ def match_macs_to_nics(fog_attr)
end
true
end

def vm_exists?
return true unless compute_object
!compute_object.persisted?
end
end
2 changes: 1 addition & 1 deletion app/services/authorizer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def can?(permission, subject = nil, cache = true)

def find_collection(resource_class, options = {})
permission = options.delete :permission
Foreman::Logging.logger('permissions').debug "checking permission #{permission}"
Foreman::Logging.logger('permissions').debug "checking permission #{permission} for class #{resource_class}"

# retrieve all filters relevant to this permission for the user
base = user.filters.joins(:permissions).where(["#{Permission.table_name}.resource_type = ?", resource_name(resource_class)])
Expand Down
Loading

0 comments on commit 637da2f

Please sign in to comment.