Skip to content

Commit

Permalink
Fixes #9480 - multiple NICs integration with compute profiles
Browse files Browse the repository at this point in the history
From users point of view:
- interfaces setup in compute profiles is back
- interface related compute attrs get merged into host NICs upon compute
  profile selection
- NIC overview table displays details in the column "Type"
- UI for direct creation of VMs fixed
- fixed removing interfaces and volumes from compute profiles

From technical point of view:
- NIC overview table is always built by js
- templates for compute resources got more structure (split to partials
  "base", "interface", "volume")
- compute resources can provide custom implementation of
  'providerSpecificNICInfo' function
  • Loading branch information
Tomas Strachota authored and ares committed Mar 5, 2015
1 parent 3e75071 commit 6d05514
Show file tree
Hide file tree
Showing 57 changed files with 521 additions and 250 deletions.
6 changes: 6 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ function onContentLoad(){
$.cookie('timezone', tz.name(), { path: '/' });
}

function preserve_selected_options(elem) {
// mark the selected values to preserve them for form hiding
elem.find('option:not(:selected)').removeAttr('selected');
elem.find('option:selected').attr('selected', 'selected');
}

function remove_fields(link) {
$(link).prev("input[type=hidden]").val("1");
$(link).closest(".fields").hide();
Expand Down
7 changes: 7 additions & 0 deletions app/assets/javascripts/compute_resources/libvirt/nic_info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
providerSpecificNICInfo = function(form) {
if (form.find('.libvirt_network').val() == 'network') {
return Jed.sprintf(__('physical @ NAT %s'), form.find('.libvirt_nat').val());
} else {
return Jed.sprintf(__('physical @ bridge %s'), form.find('.libvirt_bridge').val());
}
}
3 changes: 3 additions & 0 deletions app/assets/javascripts/compute_resources/ovirt/nic_info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
providerSpecificNICInfo = function(form) {
return form.find('.ovirt_name').val() + ' @ ' + form.find('.ovirt_network').val();
}
3 changes: 3 additions & 0 deletions app/assets/javascripts/compute_resources/vmware/nic_info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
providerSpecificNICInfo = function(form) {
return form.find('.vmware_type').val() + ' @ ' + form.find('.vmware_network').val();
}
8 changes: 5 additions & 3 deletions app/assets/javascripts/host_edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ function update_nics(success_callback) {
$('#network').html(result);
if ($('#network').find('.alert-danger').length > 0)
$('#network_tab a').addClass('tab-error');
update_interface_table();
success_callback();
}
})
}

function computeResourceSelected(item){
providerSpecificNICInfo = null;
var compute = $(item).val();
if (compute == '' && /compute_resource/.test($(item).attr('name'))) {
//Bare metal compute resource
Expand Down Expand Up @@ -440,6 +442,7 @@ function load_with_placeholder(target, url, data){
}

function onHostEditLoad(){
update_interface_table();
$("#host-conflicts-modal").modal({show: "true", backdrop: "static"});
$('#host-conflicts-modal').click(function(){
$('#host-conflicts-modal').modal('hide');
Expand Down Expand Up @@ -504,7 +507,7 @@ $(document).on('change', '.interface_type', function () {

function interface_domain_selected(element) {
// mark the selected value to preserve it for form hiding
$(element).find('option:selected').attr('selected', 'selected')
preserve_selected_options($(element));

var domain_id = element.value;
var subnet_options = $(element).closest('fieldset').find('[id$=_subnet_id]').empty();
Expand Down Expand Up @@ -545,7 +548,7 @@ function interface_domain_selected(element) {

function interface_subnet_selected(element) {
// mark the selected value to preserve it for form hiding
$(element).find('option:selected').attr('selected', 'selected')
preserve_selected_options($(element));

var subnet_id = $(element).val();
if (subnet_id == '') return;
Expand Down Expand Up @@ -627,7 +630,6 @@ function disable_vm_form_fields() {
$("[id^=host_compute_attributes]").each(function () {
$(this).attr("disabled", "disabled");
});
$("a.disable-unsupported").remove();
}

function resizeTextareas (elem) {
Expand Down
53 changes: 51 additions & 2 deletions app/assets/javascripts/host_edit_interfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function save_interface_modal() {
var interface_id = modal_window.data('current-id');

// mark the selected values to preserve them for form hiding
modal_window.find('option:selected').attr('selected', 'selected');
preserve_selected_options(modal_window);

var modal_form = modal_window.find('.modal-body').contents();
if (modal_form.find('.interface_primary').is(':checked')) {
Expand Down Expand Up @@ -138,7 +138,19 @@ function fqdn(name, domain) {
}

function update_interface_row(row, interface_form) {
row.find('.type').html(interface_form.find('.interface_type option:selected').text());

var has_errors = (interface_form.find('.has-error').length > 0)
row.toggleClass('has-error', has_errors);

var virtual = interface_form.find('.virtual').is(':checked');
var attached = interface_form.find('.attached').val();

var type = interface_form.find('.interface_type option:selected').text();
type += '<div class="additional-info">'
type += nic_info(interface_form);
type += '</div>'
row.find('.type').html(type);

row.find('.identifier').html(interface_form.find('.interface_identifier').val());
row.find('.mac').html(interface_form.find('.interface_mac').val());
row.find('.ip').html(interface_form.find('.interface_ip').val());
Expand Down Expand Up @@ -256,6 +268,43 @@ $(document).on('click', '.provision-flag', function () {
update_interface_table();
});

var providerSpecificNICInfo = null;

function nic_info(form) {
var info = "";
if (form.find('.virtual').is(':checked') || form.find('.interface_type').val() == "Nic::Bond") {

// common virtual
var attached = form.find('.attached').val();
if (attached != "")
info = Jed.sprintf(__("virtual attached to %s"), attached);
else
info = __("virtual");

} else {

// provider specific
if (typeof(providerSpecificNICInfo) == "function")
info = providerSpecificNICInfo(form);
else
info = __("physical")

}
return info;
}

$(document).on('change', '.compute_attributes', function () {
// remove "from profile" note if any of the fields changes
$(this).closest('.compute_attributes').find('.profile').html('');
});

$(document).on('change', '.virtual', function () {
var is_virtual = $(this).is(':checked');

$(this).closest('fieldset').find('.virtual_form').toggle(is_virtual);
$(this).closest('fieldset').find('.compute_attributes').toggle(!is_virtual);
});

function update_fqdn() {
var host_name = $('#host_name').val();
var domain_name = primary_nic_form().find('.interface_domain option:selected').text();
Expand Down
6 changes: 6 additions & 0 deletions app/assets/javascripts/lookup_keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ function remove_child_node(item) {
return false;
}

function delete_child_node(item) {
$(item).closest('.fields').remove();
$(item).closest("form").trigger('nested:fieldRemoved');
return false;
}

function undo_remove_child_node(item){
var container = $('.lookup-keys-container:visible');
var link = container.find($(item).attr("data-pill"));
Expand Down
17 changes: 17 additions & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ table {

}

.additional-info {
font-size: 75%;
}

.autocomplete-input {
display:inline-block !important;
}
Expand Down Expand Up @@ -473,3 +477,16 @@ table {
}
}
}

.children_fields {
margin-bottom: 10px;
}

.remove-button {
float: right;
margin-right: 30px;
}

.removable-item {
margin-bottom: 25px;
}
4 changes: 2 additions & 2 deletions app/controllers/compute_attributes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def create
if @set.save
process_success :success_redirect => request.referer || compute_profile_path(@set.compute_profile)
else
process_error
process_error :object => @set
end
end

Expand All @@ -22,7 +22,7 @@ def update
if @set.update_attributes!(params[:compute_attribute])
process_success :success_redirect => request.referer || compute_profile_path(@set.compute_profile)
else
process_error
process_error :object => @set
end
end
end
4 changes: 4 additions & 0 deletions app/controllers/hosts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ def compute_resource_selected

def interfaces
@host = Host.new params[:host]

merge = InterfaceMerge.new
merge.run(@host.interfaces, @host.compute_resource.try(:compute_profile_for, @host.compute_profile_id))

render :partial => "interfaces_tab"
end

Expand Down
20 changes: 12 additions & 8 deletions app/helpers/hosts_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ module HostsHelper
include ComputeResourcesVmsHelper
include BmcHelper

def nic_provider_attributes_exist?(host)
return false unless host.compute_resource
def provider_partial_exist?(compute_resource, partial)
return false unless compute_resource

compute_resource_name = host.compute_resource.provider_friendly_name.downcase
real_path = File.join(Rails.root, 'app', 'views', 'compute_resources_vms', 'form', compute_resource_name, '_network.html.erb')
compute_resource_name = compute_resource.provider_friendly_name.downcase
real_path = File.join(Rails.root, 'app', 'views', 'compute_resources_vms', 'form', compute_resource_name, "_#{partial}.html.erb")

File.exist?(real_path)
end

def nic_provider_partial(host)
return nil unless host.compute_resource
def provider_partial(compute_resource, partial)
return nil unless compute_resource

compute_resource_name = host.compute_resource.provider_friendly_name.downcase
"compute_resources_vms/form/#{compute_resource_name}/network"
compute_resource_name = compute_resource.provider_friendly_name.downcase
"compute_resources_vms/form/#{compute_resource_name}/#{partial}"
end

def nic_info_js(compute_resource)
javascript_include_tag("compute_resources/#{compute_resource.provider_friendly_name.downcase}/nic_info.js")
end

def host_taxonomy_select(f, taxonomy)
Expand Down
5 changes: 5 additions & 0 deletions app/helpers/lookup_keys_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ def remove_child_link(name, f, opts = {})
f.hidden_field(opts[:method]||:_destroy) + link_to_function(name, "remove_child_node(this);", opts)
end

def delete_child_link(name, f, opts = {})
opts[:class] = [opts[:class], "remove_nested_fields"].compact.join(" ")
link_to_function(name, "delete_child_node(this);", opts)
end

def add_child_link(name, association, opts = {})
opts[:class] = [opts[:class], "add_nested_fields btn btn-success"].compact.join(" ")
opts[:"data-association"] = association
Expand Down
13 changes: 13 additions & 0 deletions app/models/compute_attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def method_missing(method, *args, &block)
raise Foreman::Exception.new(N_('%s is an unknown attribute'), method)
end

def vm_interfaces
attribute_values(compute_resource.interfaces_attrs_name)
end

def new_vm
compute_resource.new_vm(vm_attrs) if vm_attrs
end
Expand All @@ -30,4 +34,13 @@ def pretty_vm_attrs
def update_name
self.name = pretty_vm_attrs if pretty_vm_attrs.present?
end

def attribute_values(attr_name)
attr_key = "#{attr_name}_attributes"
if vm_attrs[attr_key]
vm_attrs[attr_key].select { |k,v| k.to_s != "new_#{attr_name}" }.values
else
[]
end
end
end
8 changes: 6 additions & 2 deletions app/models/compute_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def image_param_name
end

def interfaces_attrs_name
"interfaces_attributes"
"interfaces"
end

# returns a new fog server instance
Expand Down Expand Up @@ -234,8 +234,12 @@ def set_console_password=(setpw)
self.attrs[:setpw] = nil
end

def compute_profile_for(id)
compute_attributes.find_by_compute_profile_id(id)
end

def compute_profile_attributes_for(id)
compute_attributes.find_by_compute_profile_id(id).try(:vm_attrs) || {}
compute_profile_for(id).try(:vm_attrs) || {}
end

def vm_compute_attributes_for(uuid)
Expand Down
7 changes: 6 additions & 1 deletion app/models/compute_resources/foreman/model/libvirt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def provided_attributes
end

def interfaces_attrs_name
"nics_attributes"
"nics"
end

def capabilities
Expand Down Expand Up @@ -68,6 +68,11 @@ def new_nic(attr = { })
client.nics.new attr
end

def new_interface(attr = {})
# fog compatibility
new_nic(attr)
end

def new_volume(attr = { })
client.volumes.new(attrs.merge(:allocation => '0G'))
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/compute_resources/foreman/model/vmware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def create_vm(args = { })
raise e
end

def new_vm(args)
def new_vm(args = {})
args = parse_args args
opts = vm_instance_defaults.symbolize_keys.merge(args.symbolize_keys)
client.servers.new opts
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/orchestration/compute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def ssh_open?(ip)
def add_interfaces_to_compute_attrs
# We now store vm fields in the Nic model, so we need to add them to
# compute_attrs before creating the vm
attrs_name = compute_resource.interfaces_attrs_name
attrs_name = "#{compute_resource.interfaces_attrs_name}_attributes"
return unless compute_attributes[attrs_name].blank?
compute_attributes[attrs_name] = {}
self.interfaces.each do |nic|
Expand Down
6 changes: 5 additions & 1 deletion app/models/nic/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,15 @@ def belongs_to_counter_cache_before_destroy_for_domain
serialize :compute_attributes, Hash

class Jail < ::Safemode::Jail
allow :managed?, :subnet, :virtual?, :mac, :ip, :identifier, :attached_to,
allow :managed?, :subnet, :virtual?, :physical?, :mac, :ip, :identifier, :attached_to,
:link, :tag, :domain, :vlanid, :bond_options, :attached_devices, :mode,
:attached_devices_identifiers, :primary, :provision, :inheriting_mac
end

def physical?
!virtual?
end

def type_name
type.split("::").last
end
Expand Down
27 changes: 27 additions & 0 deletions app/services/interface_merge.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class InterfaceMerge
def run(interfaces, compute_attrs)
return if compute_attrs.nil?

vm_interfaces = compute_attrs.vm_interfaces

# merge with existing
interfaces.select(&:physical?).each do |nic|
vm_nic = vm_interfaces.shift
return if vm_nic.nil?
merge(nic, vm_nic, compute_attrs)
end

# create additional if there are some attributes left
vm_interfaces.each do |vm_nic|
interfaces << merge(Nic::Managed.new, vm_nic, compute_attrs)
end
end

private

def merge(nic, vm_nic, compute_attrs)
nic.compute_attributes = vm_nic
nic.compute_attributes['from_profile'] = compute_attrs.compute_profile.name
nic
end
end
Loading

0 comments on commit 6d05514

Please sign in to comment.