[Ovirt-devel] [PATCH server 07/10] use service layer for Network controller.
Scott Seago
sseago at redhat.com
Tue May 19 14:23:14 UTC 2009
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
More information about the ovirt-devel
mailing list