Scott Seago
2009-May-15 15:13 UTC
[Ovirt-devel] [PATCH server] use service layer for Network controller.
There's still room for additional refactoring as we may want to eventually split out nic, bonding, and ip address manipulation into their own controller/svc module, but that would be a much more extensive redesign than we want to deal with for the overall service layer creation refactoring. Signed-off-by: Scott Seago <sseago at redhat.com> --- src/app/controllers/network_controller.rb | 521 ++++++----------------------- src/app/models/ip_address.rb | 11 + src/app/models/network.rb | 12 + src/app/models/physical_network.rb | 4 + src/app/models/vlan.rb | 5 + src/app/services/network_service.rb | 392 ++++++++++++++++++++++ 6 files changed, 534 insertions(+), 411 deletions(-) create mode 100644 src/app/services/network_service.rb diff --git a/src/app/controllers/network_controller.rb b/src/app/controllers/network_controller.rb index 244d041..5af0a73 100644 --- a/src/app/controllers/network_controller.rb +++ b/src/app/controllers/network_controller.rb @@ -18,471 +18,170 @@ # class NetworkController < ApplicationController + include NetworkService ########################## Networks related actions - before_filter :pre_list, :only => [:list] - - def authorize_admin - # TODO more robust permission system - # either by subclassing network from pool - # or by extending permission model to accomodate - # any object - @default_pool = HardwarePool.get_default_pool - set_perms(@default_pool) - super('You do not have permission to access networks') - end - - def pre_list - @networks = Network.find(:all) - authorize_admin - end - - def list - respond_to do |format| - format.html { - render :layout => 'tabs-and-content' if params[:ajax] - render :layout => 'help-and-content' if params[:nolayout] - } - format.xml { - render :xml => @pool.to_xml(XML_OPTS) - } - end - end - - def networks_json - json_list(Network.find(:all), [:id, :name, :type, [:boot_type, :label]]) - end + def list + svc_list() + respond_to do |format| + format.html { + render :layout => 'tabs-and-content' if params[:ajax] + render :layout => 'help-and-content' if params[:nolayout] + } + format.xml { + render :xml => @pool.to_xml(XML_OPTS) + } + end + end - def pre_show - @network = Network.find(params[:id]) - authorize_admin - end + def networks_json + svc_list + json_list(@networks, [:id, :name, :type, [:boot_type, :label]]) + end - def show + def show + svc_show(params[:id]) respond_to do |format| format.html { render :layout => 'selection' } format.xml { render :xml => @network.to_xml } end - end + end - def new + def new + svc_new() @boot_types = BootType.find(:all) @usage_types = Usage.find(:all) render :layout => 'popup' - end + end - def create - begin - @network = PhysicalNetwork.new(params[:network]) if params[:network][:type] == 'PhysicalNetwork' - @network = Vlan.new(params[:network]) if params[:network][:type] == 'Vlan' - @network.save! - alert = "Network was successfully created." - render :json => { :object => "network", :success => true, - :alert => alert } - rescue - render :json => { :object => "network", :success => false, - :errors => - @network.errors.localize_error_messages.to_a } - end - end + def create + alert = svc_create(params[:network]) + render :json => { :object => "network", :success => true, :alert => alert } + end - def edit - @network = Network.find(params[:id]) + def edit + svc_modify(params[:id]) @usage_types = Usage.find(:all) @boot_types = BootType.find(:all) render :layout => 'popup' - end - - def update - begin - @network = Network.find(params[:id]) - if @network.type == 'PhysicalNetwork' - @network = PhysicalNetwork.find(params[:id]) - else - @network = Vlan.find(params[:id]) - end + end - @network.usages.delete_all - @network.update_attributes!(params[:network]) + def update + alert = svc_update(params[:id], params[:network]) + render :json => { :object => "network", :success => true, :alert => alert } + end - alert = "Network was successfully updated." - render :json => { :object => "network", :success => true, - :alert => alert } - rescue Exception => e - render :json => { :object => "network", :success => false, - :errors => - @network.errors.localize_error_messages.to_a } + def delete + network_ids = params[:network_ids].split(",") + successes = [] + failures = {} + network_ids.each do |network_id| + begin + svc_destroy(network_id) + successes << @network + rescue PermissionError => perm_error + failures[@network] = perm_error.message + rescue ActionError => ex + failures[@network] = ex.message + rescue Exception => ex + failures[@network] = ex.message + end end - end - - def delete - failed_networks = [] - networks_ids_str = params[:network_ids] - network_ids = networks_ids_str.split(",").collect {|x| x.to_i} - network_ids.each{ |x| - network = Network.find(x) - unless network.type.to_s == 'Vlan' && - Vlan.find(x).bondings.size != 0 || - network.type.to_s == 'PhysicalNetwork' && - PhysicalNetwork.find(x).nics.size != 0 - begin - Network.destroy(x) - rescue - failed_networks.push x - end - else - failed_networks.push x - end - } - if failed_networks.size == 0 - render :json => { :object => "network", - :success => true, - :alert => "Successfully deleted networks" } - else - render :json => { :object => "network", - :success => false, - :alert => "Failed deleting " + - failed_networks.size.to_s + - " networks due to existing bondings/nics" } - end - end + unless failures.empty? + raise PartialSuccessError.new("Delete failed for some networks", + failures, successes) + end + render :json => { :object => "network", :success => true, + :alert => "Networks were successfully deleted." } + end - def edit_network_ip_addresses - @network = Network.find(params[:id]) + def edit_network_ip_addresses + svc_modify(params[:id]) render :layout => 'popup' - end + end ########################## Ip Address related actions - def ip_addresses_json - @parent_type = params[:parent_type] - if @parent_type == 'network' - ip_addresses = Network.find(params[:id]).ip_addresses - elsif @parent_type == 'nic' - ip_addresses = Nic.find(params[:id]).ip_addresses - elsif @parent_type == 'bonding' and params[:id] - ip_addresses = Bonding.find(params[:id]).ip_addresses - else - ip_addresses = [] - end - + def ip_addresses_json + svc_ip_addresses(params[:parent_type], params[:id]) ip_addresses_json = [] - ip_addresses.each{ |x| + @ip_addresses.each{ |x| ip_addresses_json.push({:id => x.id, :name => x.address}) } render :json => ip_addresses_json end def new_ip_address - @parent_type = params[:parent_type] - @network = Network.find(params[:id]) if @parent_type == 'network' - @nic = Nic.find(params[:id]) if @parent_type == 'nic' - @bonding = Bonding.find(params[:id]) if @parent_type == 'bonding' and params[:id] - + svc_ip_addresses(params[:parent_type], params[:id]) render :layout => false end - def _create_ip_address - if params[:ip_address][:type] == "IpV4Address" - @ip_address = IpV4Address.new(params[:ip_address]) - else - @ip_address = IpV6Address.new(params[:ip_address]) - end - @ip_address.save! - end - def create_ip_address - begin - _create_ip_address - alert = "Ip Address was successfully created." - render :json => { :object => "ip_address", :success => true, - :alert => alert } - rescue - render :json => { :object => "ip_address", :success => false, - :errors => - @ip_address.errors.localize_error_messages.to_a } - end - end - - def edit_ip_address - @ip_address = IpAddress.find(params[:id]) - - @parent_type = params[:parent_type] - @network = @ip_address.network if @ip_address.network_id - @nic = @ip_address.nic if @ip_address.nic_id - @bonding = @ip_address.bonding if @ip_address.bonding_id + alert = svc_create_ip_address(params[:ip_address]) + render :json => {:object => "ip_address", :success => true, :alert => alert} + end + def edit_ip_address + svc_modify_ip_address(params[:parent_type], params[:id]) render :layout => false - end - - def _update_ip_address(id) - @ip_address = IpAddress.find(id) - - # special case if we are switching types - if @ip_address.type != params[:ip_address][:type] - if params[:ip_address][:type] == 'IpV4Address' - @ip_address = IpV4Address.new(params[:ip_address]) - @ip_address.save! - IpV6Address.delete(id) - else - @ip_address = IpV6Address.new(params[:ip_address]) - @ip_address.save! - IpV4Address.delete(id) - end - else - if @ip_address.type == 'IpV4Address' - @ip_address = IpV4Address.find(id) - else - @ip_address = IpV6Address.find(id) - end - @ip_address.update_attributes!(params[:ip_address]) - end - - end - - def update_ip_address - begin - _update_ip_address(params[:id]) - alert = "IpAddress was successfully updated." - render :json => { :object => "network", :success => true, - :alert => alert } - rescue - render :json => { :object => "ip_address", :success => false, - :errors => - @ip_address.errors.localize_error_messages.to_a } - end - end + end - def destroy_ip_address - begin - IpAddress.delete(params[:id]) - alert = "Ip Address was successfully deleted." - render :json => { :object => "ip_address", :success => true, - :alert => alert } - rescue - render :json => { :object => "ip_address", :success => false, - :alert => 'Ip Address Deletion Failed' } - end - end + def update_ip_address + alert = svc_update_ip_address(params[:id], params[:ip_address]) + render :json => {:object => "ip_address", :success => true, :alert => alert} + end + def destroy_ip_address + alert = svc_destroy_ip_address(params[:id]) + render :json => {:object => "ip_address", :success => true, :alert => alert} + end ########################## NICs related actions - def edit_nic - @nic = Nic.find(params[:id]) - @network = @nic.physical_network - - # filter out networks already assigned to nics on host - network_conditions = [] - @nic.host.nics.each { |nic| - unless nic.physical_network.nil? || nic.id == @nic.id - network_conditions.push(" id != " + nic.physical_network.id.to_s) - end - } - network_conditions = network_conditions.join(" AND ") - - @networks = PhysicalNetwork.find(:all, :conditions => network_conditions) - network_options - - render :layout => false - end - - def update_nic - begin - network_options - - unless params[:nic][:physical_network_id].nil? || params[:nic][:physical_network_id].to_i == 0 - @network = Network.find(params[:nic][:physical_network_id]) - if @network.boot_type.id == @static_boot_type.id - if params[:ip_address][:id] == "New" - _create_ip_address - elsif params[:ip_address][:id] != "" - _update_ip_address(params[:ip_address][:id]) - end - end - end - - @nic = Nic.find(params[:id]) - @nic.update_attributes!(params[:nic]) + def edit_nic + svc_modify_nic(params[:id]) + render :layout => false + end - alert = "Nic was successfully updated." - render :json => { :object => "nic", :success => true, - :alert => alert } - rescue Exception => e - if @ip_address and @ip_address.errors.size != 0 - render :json => { :object => "ip_address", :success => false, - :errors => - @ip_address.errors.localize_error_messages.to_a} - else - render :json => { :object => "nic", :success => false, - :errors => - @nic.errors.localize_error_messages.to_a } - end - end - end + def update_nic + alert = svc_update_nic(params[:id], params[:nic], params[:ip_address]) + render :json => { :object => "nic", :success => true, :alert => alert} + end ########################## Bonding related actions - def new_bonding - unless params[:host_id] - flash[:notice] = "Host is required." - redirect_to :controller => 'dashboard' - end - - @host = Host.find(params[:host_id]) - - # FIXME when bonding_nics table is removed, and - # bondings_id column added to nics table, simplify - # (select where bonding.nil?) - @nics = [] - @host.nics.each{ |nic| - @nics.push(nic) if nic.bondings.nil? || nic.bondings.size == 0 - } - - # filter out networks already assigned to bondings on host - network_conditions = [] - @host.bondings.each { |bonding| - unless bonding.vlan.nil? - network_conditions.push(" id != " + bonding.vlan.id.to_s) - end - } - network_conditions = network_conditions.join(" AND ") - - @networks = Vlan.find(:all, :conditions => network_conditions) - network_options - + def new_bonding + raise ActionError.new("Host is required") unless params[:host_id] + svc_new_bonding(params[:host_id]) render :layout => false end - def create_bonding - begin - network_options - - unless params[:bonding][:vlan_id].nil? || params[:bonding][:vlan_id].to_i == 0 - @network = Network.find(params[:bonding][:vlan_id]) - if @network.boot_type.id == @static_boot_type.id - if params[:ip_address][:id] == "New" - _create_ip_address - elsif params[:ip_address][:id] != "" - _update_ip_address(params[:ip_address][:id]) - end - end - end - - @bonding = Bonding.new(params[:bonding]) - @bonding.ip_addresses << @ip_address if @ip_address - @bonding.save! - - if @ip_address - @ip_address.bonding_id = @bonding.id - @ip_address.save! - end - - alert = "Bonding was successfully created." - render :json => { :object => "bonding", :success => true, - :alert => alert } - rescue - if @ip_address and @ip_address.errors.size != 0 - render :json => { :object => "ip_address", :success => false, - :errors => - @ip_address.errors.localize_error_messages.to_a} - else - render :json => { :object => "bonding", :success => false, - :errors => - @bonding.errors.localize_error_messages.to_a } - end - end - end - - def edit_bonding - @bonding = Bonding.find(params[:id]) - @network = @bonding.vlan - - @host = @bonding.host - - # FIXME when bonding_nics table is removed, and - # bondings_id column added to nics table, simplify - # (select where bonding.nil? or bonding has nic) - @nics = [] - @host.nics.each{ |nic| - if nic.bondings.nil? || - nic.bondings.size == 0 || - nic.bondings[0].id == @bonding.id - @nics.push(nic) - end - } - - # filter out networks already assigned to bondings on host - network_conditions = [] - @host.bondings.each { |bonding| - unless bonding.vlan.nil? || bonding.id == @bonding.id - network_conditions.push(" id != " + bonding.vlan.id.to_s) - end - } - network_conditions = network_conditions.join(" AND ") - - @networks = Vlan.find(:all, :conditions => network_conditions) - network_options - - render :layout => false - end - - def update_bonding - begin - network_options - - unless params[:bonding][:vlan_id].nil? || params[:bonding][:vlan_id].to_i == 0 - @network = Network.find(params[:bonding][:vlan_id]) - if @network.boot_type.id == @static_boot_type.id - if params[:ip_address][:id] == "New" - _create_ip_address - elsif params[:ip_address][:id] != "" - _update_ip_address(params[:ip_address][:id]) - end - end - end - - @bonding = Bonding.find(params[:id]) - @bonding.nics.delete_all - @bonding.update_attributes!(params[:bonding]) - - alert = "Bonding was successfully updated." - render :json => { :object => "bonding", :success => true, - :alert => alert } - rescue Exception => e - if @ip_address and @ip_address.errors.size != 0 - render :json => { :object => "ip_address", :success => false, - :errors => - @ip_address.errors.localize_error_messages.to_a} - else - render :json => { :object => "bonding", :success => false, - :errors => - @bonding.errors.localize_error_messages.to_a } - end - end - end - - def destroy_bonding - begin - Bonding.destroy(params[:id]) - alert = "Bonding was successfully deleted." - render :json => { :object => "bonding", :success => true, - :alert => alert } - rescue - render :json => { :object => "bonding", :success => false, - :alert => 'Bonding Deletion Failed' } - end + def create_bonding + alert = svc_create_bonding(params[:bonding], params[:ip_address]) + render :json => { :object => "bonding", :success => true, :alert => alert} + end - end + def edit_bonding + svc_modify_bonding(params[:id]) + render :layout => false + end + def update_bonding + alert = svc_update_bonding(params[:id], params[:bonding], params[:ip_address]) + render :json => { :object => "bonding", :success => true, :alert => alert} + end - ########################## Misc methods + def destroy_bonding + alert = svc_destroy_bonding(params[:id]) + render :json => {:object => "bonding", :success => true, :alert => alert} + end protected - def network_options - @bonding_types = BondingType.find(:all) - @static_boot_type = BootType.find(:first, - :conditions => { :proto => 'static' }) - end + # FIXME: remove these when service transition is complete. these are here + # to keep from running permissions checks and other setup steps twice + def tmp_pre_update + end + def tmp_authorize_admin + end end diff --git a/src/app/models/ip_address.rb b/src/app/models/ip_address.rb index 5d2e6af..4e4c7d3 100644 --- a/src/app/models/ip_address.rb +++ b/src/app/models/ip_address.rb @@ -24,4 +24,15 @@ class IpAddress < ActiveRecord::Base belongs_to :network belongs_to :nic belongs_to :bonding + + def self.factory(params = {}) + case params[:type] + when "IpV4Address" + return IpV4Address.new(params) + when "IpV6Address" + return IpV6Address.new(params) + else + return nil + end + end end diff --git a/src/app/models/network.rb b/src/app/models/network.rb index 0ad38bb..1c6fe97 100644 --- a/src/app/models/network.rb +++ b/src/app/models/network.rb @@ -31,4 +31,16 @@ class Network < ActiveRecord::Base validates_presence_of :boot_type_id, :message => 'A boot type must be specified.' + def self.factory(params = {}) + case params[:type] + when 'PhysicalNetwork' + return PhysicalNetwork.new(params) + when 'Vlan' + return Vlan.new(params) + else + return nil + end + end + + end diff --git a/src/app/models/physical_network.rb b/src/app/models/physical_network.rb index 6923e40..52a748a 100644 --- a/src/app/models/physical_network.rb +++ b/src/app/models/physical_network.rb @@ -18,4 +18,8 @@ class PhysicalNetwork < Network has_many :nics + + def is_destroyable? + nics.empty? + end end diff --git a/src/app/models/vlan.rb b/src/app/models/vlan.rb index f7889f4..2f6acba 100644 --- a/src/app/models/vlan.rb +++ b/src/app/models/vlan.rb @@ -21,4 +21,9 @@ class Vlan < Network validates_presence_of :number, :message => 'A number must be specified.' + + def is_destroyable? + bondings.empty? + end + end diff --git a/src/app/services/network_service.rb b/src/app/services/network_service.rb new file mode 100644 index 0000000..551b60c --- /dev/null +++ b/src/app/services/network_service.rb @@ -0,0 +1,392 @@ +# +# Copyright (C) 2009 Red Hat, Inc. +# Written by Scott Seago <sseago at redhat.com>, +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. +# Mid-level API: Business logic around networks +module NetworkService + include ApplicationService + + # Loads a list of networks for viewing + # + # === Instance variables + # [<tt>@networks</tt>] stores a list of all Networks + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_list() + authorize + @networks = Network.find(:all) + end + + # Load the Network with +id+ for viewing + # + # === Instance variables + # [<tt>@network</tt>] stores the Network with +id+ + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_show(id) + authorize(id) + end + + # Load the Network with +id+ for editing + # + # === Instance variables + # [<tt>@network</tt>] stores the Network with +id+ + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on default HW pool + def svc_modify(id) + authorize(id) + end + + # update attributes for the Network with +id+ + # + # === Instance variables + # [<tt>@network</tt>] stores the Network with +id+ + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on default HW pool + def svc_update(id, network_hash) + authorize(id) + @network.usages.delete_all + @network.update_attributes!(network_hash) + return "Network was successfully updated." + end + + # Load a new Network for creating + # + # === Instance variables + # [<tt>@network</tt>] loads a new Network object into memory + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on default HW pool + def svc_new() + authorize + end + + # Save a new Network + # + # === Instance variables + # [<tt>@network</tt>] the newly-created Network + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on default HW pool + def svc_create(network_hash) + authorize + @network = Network.factory(network_hash) + @network.save! + return "Network was successfully created." + end + + # Destroys the Network with +id+ + # + # === Instance variables + # [<tt>@network</tt>] stores the network with +id+ + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on default HW pool + def svc_destroy(id) + authorize(id) + unless @network.is_destroyable? + raise ActionError.new("Network has existing bondings or NICs") + end + @network.destroy + return "Network was successfully deleted." + end + + # Load the IP addresses for object of type +parent_type+ and +id+ + # + # === Instance variables + # [<tt>@parent_type</tt>] +parent_type+ + # [<tt>@ip_addresses</tt>] IP addresses for selected object + # [<tt>@network</tt>] network with +id+ if <tt>@parent_type</tt> is network + # [<tt>@nic</tt>] nic with +id+ if <tt>@parent_type</tt> is nic + # [<tt>@bonding</tt>] bonding with +id+ if <tt>@parent_type</tt> is bonding + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_ip_addresses(parent_type, id) + authorize + @parent_type = parent_type + if @parent_type == 'network' + @network = Network.find(id) + @ip_addresses = @network.ip_addresses + elsif @parent_type == 'nic' + @nic = Nic.find(id) + @ip_addresses = @nic.ip_addresses + elsif @parent_type == 'bonding' and id + @bonding = Bonding.find(id) + @ip_addresses = @bonding.ip_addresses + else + @ip_addresses = [] + end + end + + # create new IP address + # + # === Instance variables + # [<tt>@ip_address</tt>] create new IP address + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_create_ip_address(ip_hash) + authorize + @ip_address = IpAddress.factory(ip_hash) + @ip_address.save! + return "Ip Address was successfully created." + end + + # Load IP address +id+ for editing + # + # === Instance variables + # [<tt>@ip_address</tt>] IP Address with +id+ + # [<tt>@network</tt>] network for <tt>@ip_address</tt> if it exists + # [<tt>@nic</tt>] nic for <tt>@ip_address</tt> if it exists + # [<tt>@bonding</tt>] bonding for <tt>@ip_address</tt> if it exists + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_modify_ip_address(parent_type, id) + authorize + @ip_address = IpAddress.find(id) + @parent_type = parent_type + @network = @ip_address.network if @ip_address.network_id + @nic = @ip_address.nic if @ip_address.nic_id + @bonding = @ip_address.bonding if @ip_address.bonding_id + end + + # Update IP address +id+ + # + # === Instance variables + # [<tt>@ip_address</tt>] IP Address with +id+ + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_update_ip_address(id, ip_hash) + authorize + @ip_address = IpAddress.find(id) + # special case if we are switching types + # FIXME: this doesn't work if all attributes aren't specified + # We should probably not support changing type here but instead require + # deletion and re-creation -- either that or don't use inheritence for + # IP address type + if @ip_address.type != ip_hash[:type] + @ip_address = IpAddress.factory(ip_hash) + @ip_address.save! + IpAddress.delete(id) + else + @ip_address.update_attributes!(ip_hash) + end + return "IpAddress was successfully updated." + end + + # Destroys the IP Address with +id+ + # + # === Instance variables + # [<tt>@ip_address</tt>] stores the IP Address with +id+ + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on default HW pool + def svc_destroy_ip_address(id) + authorize + IpAddress.destroy(id) + return "IP Address was successfully deleted." + end + + # Load NIC +id+ for editing + # + # === Instance variables + # [<tt>@nic</tt>] NIC with +id+ + # [<tt>@network</tt>] network for <tt>@nic</tt> + # [<tt>@networks</tt>] available networks for <tt>@nic</tt> + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_modify_nic(id) + authorize + @nic = Nic.find(id) + @network = @nic.physical_network + network_options + # filter out networks already assigned to nics on host + network_conditions = [] + @nic.host.nics.each { |nic| + unless nic.physical_network.nil? || nic.id == @nic.id + network_conditions.push(" id != " + nic.physical_network.id.to_s) + end + } + network_conditions = network_conditions.join(" AND ") + @networks = PhysicalNetwork.find(:all, :conditions => network_conditions) + end + + # Update NIC +id+ + # + # === Instance variables + # [<tt>@nic</tt>] NIC with +id+ + # [<tt>@network</tt>] network for <tt>@nic</tt> + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_update_nic(id, nic_hash, ip_hash) + authorize + network_options + unless nic_hash[:physical_network_id].to_i == 0 + @network = Network.find(nic_hash[:physical_network_id]) + if @network.boot_type.id == @static_boot_type.id + if ip_hash[:id] == "New" + svc_create_ip_address(ip_hash) + elsif ip_hash[:id] != "" + svc_update_ip_address(ip_hash[:id], ip_hash) + end + end + end + @nic = Nic.find(id) + @nic.update_attributes!(nic_hash) + return "Nic was successfully updated." + end + + # load new bonding for creation + # + # === Instance variables + # [<tt>@host</tt>] Host with +host_id+ + # [<tt>@nics</tt>] available nics on <tt>@host</tt> + # [<tt>@networks</tt>] available networks + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_new_bonding(host_id) + authorize + network_options + @host = Host.find(host_id) + # FIXME when bonding_nics table is removed, and + # bondings_id column added to nics table, simplify + # (select where bonding.nil?) + @nics = [] + @host.nics.each{ |nic| @nics.push(nic) if nic.bondings.empty? } + # filter out networks already assigned to bondings on host + network_conditions = [] + @host.bondings.each { |bonding| + unless bonding.vlan.nil? + network_conditions.push(" id != " + bonding.vlan.id.to_s) + end + } + network_conditions = network_conditions.join(" AND ") + @networks = Vlan.find(:all, :conditions => network_conditions) + end + + # create new bonding + # + # === Instance variables + # [<tt>@bonding</tt>] newly created bonding + # [<tt>@network</tt>] network for newly created bonding (if vlan specified) + # [<tt>@ip_address</tt>] ip address for newly created bonding (if vlan + # and static boot type specified) + # [<tt>@host</tt>] Host with +host_id+ + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_create_bonding(bonding_hash, ip_hash) + pre_create_or_update_bonding(bonding_hash, ip_hash) + @bonding = Bonding.new(bonding_hash) + @bonding.ip_addresses << @ip_address if @ip_address + @bonding.save! + if @ip_address + @ip_address.bonding_id = @bonding.id + @ip_address.save! + end + return "Bonding was successfully created." + end + + # Load Bonding +id+ for editing + # + # === Instance variables + # [<tt>@bonding</tt>] bonding with +id+ + # [<tt>@host</tt>] host for <tt>@bonding</tt> + # [<tt>@network</tt>] network for <tt>@bonding</tt> + # [<tt>@networks</tt>] available networks + # [<tt>@nics</tt>] available nics + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_modify_bonding(id) + authorize + @bonding = Bonding.find(id) + @network = @bonding.vlan + @host = @bonding.host + + # FIXME when bonding_nics table is removed, and + # bondings_id column added to nics table, simplify + # (select where bonding.nil? or bonding has nic) + @nics = [] + @host.nics.each{ |nic| + if nic.bondings.empty? || + nic.bondings[0].id == @bonding.id + @nics.push(nic) + end + } + + # filter out networks already assigned to bondings on host + network_conditions = [] + @host.bondings.each { |bonding| + unless bonding.vlan.nil? || bonding.id == @bonding.id + network_conditions.push(" id != " + bonding.vlan.id.to_s) + end + } + network_conditions = network_conditions.join(" AND ") + + @networks = Vlan.find(:all, :conditions => network_conditions) + network_options + end + + # Update Bonding +id+ + # + # === Instance variables + # [<tt>@bonding</tt>] bonding with +id+ + # [<tt>@network</tt>] network for <tt>@bonding</tt> + # [<tt>@ip_address</tt>] ip address for newly created bonding (if vlan + # and static boot type specified) + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on the default HW pool + def svc_update_bonding(id, bonding_hash, ip_hash) + pre_create_or_update_bonding(bonding_hash, ip_hash) + @bonding = Bonding.find(id) + @bonding.nics.delete_all + @bonding.update_attributes!(bonding_hash) + return "Bonding was successfully updated." + end + + # Destroys the Bonding with +id+ + # + # === Instance variables + # [<tt>@bonding</tt>] stores the Bonding with +id+ + # === Required permissions + # [<tt>Privilege::MODIFY</tt>] on default HW pool + def svc_destroy_bonding(id) + authorize + Bonding.destroy(id) + return "Bonding was successfully deleted." + end + + private + # for now we only check for deafult pool admin auth + def authorize(id=nil) + authorized!(Privilege::MODIFY,HardwarePool.get_default_pool) + @network = Network.find(id) if id + end + def network_options + @bonding_types = BondingType.find(:all) + @static_boot_type = BootType.find(:first, + :conditions => { :proto => 'static' }) + end + def pre_create_or_update_bonding(bonding_hash, ip_hash) + authorize + network_options + unless bonding_hash[:vlan_id].to_i == 0 + @network = Network.find(bonding_hash[:vlan_id]) + if @network.boot_type.id == @static_boot_type.id + if ip_hash[:id] == "New" + svc_create_ip_address(ip_hash) + elsif ip_hash[:id] != "" + svc_update_ip_address(ip_hash[:id], ip_hash) + end + end + end + end +end -- 1.6.0.6
Apparently Analagous Threads
- [PATCH server] permit many-to-many vms / networks relationship
- [PATCH server] suggest ip address for nics/bondings on edit host/vm network forms
- [PATCH server] new host networking wui
- permit many-to-many vms / networks relationship redux
- permit many-to-many vms / networks relationship