Skip to content

Commit

Permalink
Merge pull request #3121 from kruge002/ReconfigureNetwork
Browse files Browse the repository at this point in the history
Reconfigure VM: Add / Remove Network Adapters
  • Loading branch information
himdel committed Apr 6, 2018
2 parents fd58e92 + 47ee523 commit c747bdd
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ ManageIQ.angular.app.controller('reconfigureFormController', ['$http', '$scope',
hdUnit: 'MB',
new_controller_type: 'VirtualLsiLogicController',
cb_dependent: true,
nicsEnabled: false,
addEnabled: false,
enableAddDiskButton: true,
enableAddNetworkAdapterButton: true,
cb_bootable: false,
vmAddDisks: [],
vmRemoveDisks: [],
vmResizeDisks: [],
vLan_requested: '',
};
vm.cb_disks = false;
vm.cb_networkAdapters = false;
vm.hdpattern = '^[1-9][0-9]*$';
vm.reconfigureFormId = reconfigureFormId;
vm.afterGet = false;
Expand Down Expand Up @@ -61,6 +65,11 @@ ManageIQ.angular.app.controller('reconfigureFormController', ['$http', '$scope',
vm.reconfigureModel.enableAddDiskButton = (nrDisksAfterReconfigure < 4);
};

vm.setEnableAddNetworkAdapterButton = function() {
var nrNetworksAfterReconfigure = _.reject(vm.reconfigureModel.vmNetworkAdapters, { add_remove: 'remove' }).length;
vm.reconfigureModel.enableAddNetworkAdapterButton = (nrNetworksAfterReconfigure < 4);
};

vm.canValidateBasicInfo = function() {
if (vm.isBasicInfoValid()) {
return true;
Expand Down Expand Up @@ -187,6 +196,22 @@ ManageIQ.angular.app.controller('reconfigureFormController', ['$http', '$scope',
vm.setEnableAddDiskButton();
};

vm.updateNetworkAdaptersAddRemove = function() {
vm.reconfigureModel.vmAddNetworkAdapters = [];
vm.reconfigureModel.vmRemoveNetworkAdapters = [];
angular.forEach(vm.reconfigureModel.vmNetworkAdapters, function(networkAdapter) {
if (networkAdapter.add_remove === 'add') {
vm.reconfigureModel.vmAddNetworkAdapters.push({network: networkAdapter.vlan});
}
if (networkAdapter.add_remove === 'remove') {
vm.reconfigureModel.vmRemoveNetworkAdapters.push({network: networkAdapter});
}
});
vm.setEnableAddNetworkAdapterButton();
vm.cb_networkAdapters = vm.reconfigureModel.vmAddNetworkAdapters.length > 0 ||
vm.reconfigureModel.vmRemoveNetworkAdapters.length > 0;
};

vm.resetAddValues = function() {
vm.reconfigureModel.hdType = 'thin';
vm.reconfigureModel.hdMode = 'persistent';
Expand All @@ -198,6 +223,52 @@ ManageIQ.angular.app.controller('reconfigureFormController', ['$http', '$scope',
vm.reconfigureModel.cb_bootable = false;
};

vm.processAddSelectedNetwork = function() {
vm.reconfigureModel.vmNetworkAdapters.push(
{
name: __('to be determined'),
vlan: vm.reconfigureModel.vLan_requested,
mac: __('not available yet'),
add_remove: 'add',
});
vm.resetAddNetworkAdapterValues();
vm.updateNetworkAdaptersAddRemove();
};

vm.removeExistingNetworkAdapter = function(thisNetworkAdapter) {
thisNetworkAdapter.add_remove = 'remove';
vm.updateNetworkAdaptersAddRemove();
};

vm.enableAddNetworkAdapter = function() {
vm.reconfigureModel.nicsEnabled = true;
vm.reconfigureModel.enableAddNetworkAdapterButton = false;
vm.reconfigureModel.showDropDownNetwork = true;
vm.reconfigureModel.vLan_requested = '';
};

vm.hideAddNetworkAdapter = function() {
vm.resetAddNetworkAdapterValues();
};

vm.resetAddNetworkAdapterValues = function() {
vm.reconfigureModel.nicsEnabled = false;
vm.reconfigureModel.addNetworkAdapterEnabled = false;
vm.reconfigureModel.showDropDownNetwork = false;
vm.setEnableAddNetworkAdapterButton();
vm.reconfigureModel.vLan_requested = '';
};

vm.cancelAddRemoveNetworkAdapter = function(vmNetworkAdapter) {
if (vmNetworkAdapter.add_remove === "remove") {
vmNetworkAdapter.add_remove = "";
} else if (vmNetworkAdapter.add_remove === "add") {
var index = vm.reconfigureModel.vmNetworkAdapters.indexOf(vmNetworkAdapter);
vm.reconfigureModel.vmNetworkAdapters.splice(index, 1);
}
vm.updateNetworkAdaptersAddRemove();
};

vm.addDisk = function() {
vm.reconfigureModel.vmdisks.push({
hdFilename: '',
Expand Down Expand Up @@ -289,6 +360,8 @@ ManageIQ.angular.app.controller('reconfigureFormController', ['$http', '$scope',
vmAddDisks: vm.reconfigureModel.vmAddDisks,
vmRemoveDisks: vm.reconfigureModel.vmRemoveDisks,
vmResizeDisks: vm.reconfigureModel.vmResizeDisks,
vmAddNetworkAdapters: vm.reconfigureModel.vmAddNetworkAdapters,
vmRemoveNetworkAdapters: vm.reconfigureModel.vmRemoveNetworkAdapters,
});
}
};
Expand Down Expand Up @@ -334,7 +407,10 @@ ManageIQ.angular.app.controller('reconfigureFormController', ['$http', '$scope',
vm.cb_memory = data.cb_memory;
vm.cb_cpu = data.cb_cpu;
vm.reconfigureModel.vmdisks = angular.copy(data.disks);
vm.reconfigureModel.vmNetworkAdapters = angular.copy(data.network_adapters);
vm.updateDisksAddRemove();
vm.updateNetworkAdaptersAddRemove();

angular.forEach(vm.reconfigureModel.vmdisks, function(disk) {
if (typeof disk !== 'undefined') {
disk.orgHdSize = disk.hdSize;
Expand Down
1 change: 1 addition & 0 deletions app/controllers/application_controller/ci_processing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module ApplicationController::CiProcessing
include Mixins::Actions::VmActions::Reconfigure
helper_method(:supports_reconfigure_disks?)
helper_method(:supports_reconfigure_disksize?)
helper_method(:supports_reconfigure_network_adapters?)
include Mixins::Actions::VmActions::PolicySimulation
include Mixins::Actions::VmActions::Transform

Expand Down
53 changes: 52 additions & 1 deletion app/controllers/mixins/actions/vm_actions/reconfigure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ def reconfigure(reconfigure_ids = [])
@force_no_grid_xml = true
@view, @pages = get_view(Vm, :view_suffix => "VmReconfigureRequest", :selected_ids => reconfigure_ids) # Get the records (into a view) and the paginator
get_reconfig_limits(reconfigure_ids)

if @reconfigitems.size == 1
vm = Vm.find(@reconfigitems)
@vlan_options = get_vlan_options(vm.host_id)
end

unless @explorer
render :action => "show"
end
Expand Down Expand Up @@ -181,6 +187,21 @@ def reconfigure_calculations(mbsize)
return humansize.to_s, fmt
end

def get_vlan_options(host_id)
vlan_options = []

# determine available switches for this host...
switch_ids = []
Rbac.filtered(HostSwitch.where("host_id = ?", host_id)).each do |host_switch|
switch_ids << host_switch.switch_id
end

Rbac.filtered(Lan.where("switch_id IN (?)", switch_ids)).each do |lan|
vlan_options << lan.name
end
vlan_options
end

def get_reconfig_info(reconfigure_ids)
@reconfigureitems = Vm.find(reconfigure_ids).sort_by(&:name)
# set memory to nil if multiple items were selected with different mem_cpu values
Expand Down Expand Up @@ -208,12 +229,24 @@ def get_reconfig_info(reconfigure_ids)
:cb_bootable => disk.bootable}
end

# reconfiguring network adapters is only supported when one vm was selected
network_adapters = []
if @reconfigureitems.size == 1
vm = @reconfigureitems.first

vm.hardware.guest_devices.order(:device_name => 'asc').each do |guest_device|
lan = Lan.find_by(:id => guest_device.lan_id)
network_adapters << {:name => guest_device.device_name, :vlan => lan.name, :mac => guest_device.address, :add_remove => ''} unless lan.nil?
end
end

{:objectIds => reconfigure_ids,
:memory => memory,
:memory_type => memory_type,
:socket_count => socket_count.to_s,
:cores_per_socket_count => cores_per_socket.to_s,
:disks => vmdisks}
:disks => vmdisks,
:network_adapters => network_adapters}
end

def supports_reconfigure_disks?
Expand All @@ -224,6 +257,10 @@ def supports_reconfigure_disksize?
@reconfigitems && @reconfigitems.size == 1 && @reconfigitems.first.supports_reconfigure_disksize? && @reconfigitems.first.supports_reconfigure_disks?
end

def supports_reconfigure_network_adapters?
@reconfigitems && @reconfigitems.size == 1 && @reconfigitems.first.supports_reconfigure_network_adapters?
end

private

# 'true' => true
Expand Down Expand Up @@ -288,6 +325,20 @@ def reconfigure_handle_submit_button
options[:disk_remove] = params[:vmRemoveDisks].values
end

if params[:vmAddNetworkAdapters]
params[:vmAddNetworkAdapters].each_value do |p|
p.transform_values! { |v| eval_if_bool_string(v) }
end
options[:network_adapter_add] = params[:vmAddNetworkAdapters].values
end

if params[:vmRemoveNetworkAdapters]
params[:vmRemoveNetworkAdapters].each_value do |p|
p.transform_values! { |v| eval_if_bool_string(v) }
end
options[:network_adapter_remove] = params[:vmRemoveNetworkAdapters].values
end

if params[:id] && params[:id] != 'new'
@request_id = params[:id]
end
Expand Down
14 changes: 14 additions & 0 deletions app/views/miq_request/_reconfigure_show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@
= _("Resize Disks")
.col-md-8
= h(@options[:disk_resize].size)
- if @options[:network_adapter_add]
.form-group
%label.control-label.col-md-2
= _("Add Network Adapters")
.col-md-8
= h(@options[:network_adapter_add].size)
&nbsp;
- if @options[:network_adapter_remove]
.form-group
%label.control-label.col-md-2
= _("Remove Network Adapters")
.col-md-8
= h(@options[:network_adapter_remove].size)
&nbsp;
- if @options[:instance_type]
.form-group
%label.control-label.col-md-2
Expand Down
66 changes: 65 additions & 1 deletion app/views/vm_common/_reconfigure.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,70 @@
%button.btn.btn-default.btn-block.btn-sm{:type => "button",
"ng-if" => "disk.add_remove == 'resize'",
"ng-click" => "vm.cancelAddRemoveDisk(disk)"}= _('Cancel Resize')
- if supports_reconfigure_network_adapters?
%hr
%div
%h3
= _('Network Adapters')
%table{:width => "100%", :align => "bottom"}
%tr
%td#buttons_on_nics{:align => "right"}
%button.btn.btn-primary{:type => "button",
"ng-click" => "vm.enableAddNetworkAdapter()",
:align => "left",
"ng-show" => "!vm.reconfigureModel.nicsEnabled",
"ng-disabled" => "!vm.reconfigureModel.enableAddNetworkAdapterButton"}= _('Add Network')
%button.btn.btn-default.btn-sm{:type => "button",
"ng-click" => "vm.hideAddNetworkAdapter()",
"ng-show" => "vm.reconfigureModel.nicsEnabled"}= _('Cancel Add')
%table.table.table-striped.table-condensed.table-bordered
%thead
%th= _('Name')
%th= _('vLan')
%th= _('MAC Address')
%th{:colspan => 2}= _('Actions')
%tr{"ng-repeat" => "networkAdapter in vm.reconfigureModel.vmNetworkAdapters",
"ng-class" => "{'danger': networkAdapter.add_remove == 'remove', 'active': networkAdapter.add_remove == 'add'}"}
%td
{{networkAdapter.name}}
%td
{{networkAdapter.vlan}}
%td.narrow
{{networkAdapter.mac}}
%td.action-cell
%button.btn.btn-default.btn-block.btn-sm{:type => "button",
:style => "visibility:hidden"}= _('Intentionally left empty')
%td.action-cell
%button.btn.btn-default.btn-block.btn-sm{:type => "button",
"ng-if" => "networkAdapter.add_remove == ''",
"ng-click" => "vm.removeExistingNetworkAdapter(networkAdapter)"}= _('Delete')
%button.btn.btn-default.btn-block.btn-sm{:type => "button",
"ng-if" => "networkAdapter.add_remove == 'remove'",
"ng-disabled" => "!vm.reconfigureModel.enableAddNetworkAdapterButton",
"ng-click" => "vm.cancelAddRemoveNetworkAdapter(networkAdapter)"}= _('Cancel Delete')
%button.btn.btn-default.btn-block.btn-sm{:type => "button",
"ng-if" => "networkAdapter.add_remove == 'add'",
"ng-click" => "vm.cancelAddRemoveNetworkAdapter(networkAdapter)"}= _('Cancel Add')
%tr{"ng-if" => "vm.reconfigureModel.showDropDownNetwork",
"ng-form" => "rowForm"}
%td
%td
= select_tag('vLan',
options_for_select([["<#{_('Choose')}>", '']] + @vlan_options, :disabled => ["<#{_('Choose')}>", nil]),
"ng-model" => "vm.reconfigureModel.vLan_requested",
"ng-change" => "",
"data-width" => "auto",
"required" => "",
"selectpicker-for-select-tag" => "")
%td
%td.action-cell
%button.btn.btn-default.btn-block.btn-sm{:type => "button",
"ng-click" => "vm.processAddSelectedNetwork();rowForm.vLan.selectionpicker('refresh')",
"ng-disabled" => "rowForm.vLan.$invalid || !vm.reconfigureModel.vmNetworkAdapters.length >= 4"}= _('Confirm Add')
%td.action-cell
%button.btn.btn-default.btn-block.btn-sm{:type => "button",
"ng-click" => "vm.hideAddNetworkAdapter()"}= _('Cancel Add')
%hr
%table{:width => "100%", :align => "bottom"}
Expand All @@ -303,7 +367,7 @@
%miq-button{:name => t = _('Submit'),
:title => t,
:alt => t,
:enabled => "!((angularForm.$pristine && !vm.cb_disks) || angularForm.$invalid || (!vm.cb_memory && !vm.cb_cpu && !vm.cb_disks))",
:enabled => "!((angularForm.$pristine && !vm.cb_disks && !vm.cb_networkAdapters) || angularForm.$invalid || (!vm.cb_memory && !vm.cb_cpu && !vm.cb_disks && !vm.cb_networkAdapters))",
'on-click' => "vm.submitClicked()",
:primary => 'true'}
%miq-button{:name => t = _('Reset'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ describe('reconfigureFormController', function() {
cb_cpu: 'on',
socket_count: '2',
cores_per_socket_count: '3',
disks: [{hdFilename: "test_disk.vmdk", hdType: "thick", hdMode: "persistent", new_controller_type: "VirtualLsiLogicController", hdSize: "0", hdUnit: "MB", add_remove: ""}]};
disks: [{hdFilename: "test_disk.vmdk", hdType: "thick", hdMode: "persistent", new_controller_type: "VirtualLsiLogicController", hdSize: "0", hdUnit: "MB", add_remove: ""}],
network_adapters: [{name: "Network adapter 1", vlan: "test_network", mac: "00:00:00:00:00:00", add_remove: ""}]};

$httpBackend = _$httpBackend_;
$httpBackend.whenGET('reconfigure_form_fields/1000000000003,1000000000001,1000000000002').respond(reconfigureFormResponse);
Expand Down Expand Up @@ -56,6 +57,9 @@ describe('reconfigureFormController', function() {
it('initializes the delete_backing flag to false if not retrived', function() {
expect(vm.reconfigureModel.vmdisks[0].delete_backing).toEqual(false);
});
it('sets the network adapter data to the network adapter data returned with the http request', function() {
expect(vm.reconfigureModel.vmNetworkAdapters).toEqual([{name: "Network adapter 1", vlan: "test_network", mac: "00:00:00:00:00:00", add_remove: ""}]);
});
});

describe('#cancelClicked', function() {
Expand Down Expand Up @@ -95,7 +99,8 @@ describe('reconfigureFormController', function() {
memory_type: vm.reconfigureModel.memory_type,
socket_count: vm.reconfigureModel.socket_count,
cores_per_socket_count: vm.reconfigureModel.cores_per_socket_count,
vmAddDisks: [ ], vmRemoveDisks: [ ], vmResizeDisks: [ ] };
vmAddDisks: [ ], vmRemoveDisks: [ ], vmResizeDisks: [ ],
vmAddNetworkAdapters: [ ], vmRemoveNetworkAdapters: [ ]};

expect(miqService.miqAjaxButton).toHaveBeenCalledWith('reconfigure_update/1000000000003?button=submit', submitContent);
});
Expand Down

0 comments on commit c747bdd

Please sign in to comment.