diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index be02e86954..b398b8aee2 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -208,6 +208,11 @@ private: */ string vlan_id; + /** + * Whether or not to isolate this network with the vnm driver + */ + int vlan; + // ------------------------------------------------------------------------- // Virtual Network Description // ------------------------------------------------------------------------- diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 07a4dab8e9..6abd1a60dd 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -56,6 +56,11 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper puts str % ["USER", vn['UNAME']] puts str % ["GROUP", vn['GNAME']] puts str % ["PUBLIC", OpenNebulaHelper.boolean_to_str(vn['PUBLIC'])] + puts str % ["TYPE", vn.type_str] + puts str % ["BRIDGE", vn["BRIDGE"]] + puts str % ["VLAN", OpenNebulaHelper.boolean_to_str(vn['VLAN'])] + puts str % ["PHYSICAL DEVICE", vn["PHYDEV"]] if vn["PHYDEV"] + puts str % ["VLAN ID", vn["VLAN_ID"]] if vn["VLAN_ID"] puts str % ["USED LEASES", vn['TOTAL_LEASES']] puts diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 520ba533b5..77762d0830 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -25,6 +25,8 @@ #include "AuthManager.h" +#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) + /* ************************************************************************** */ /* Virtual Network :: Constructor/Destructor */ /* ************************************************************************** */ @@ -207,6 +209,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) int rc; string pub; + string vlan_attr; string s_type; unsigned int default_size = VirtualNetworkPool::default_size(); @@ -219,7 +222,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) // ------------ TYPE ---------------------- erase_template_attribute("TYPE",s_type); - transform(s_type.begin(),s_type.end(),s_type.begin(),(int(*)(int))toupper); + TO_UPPER(s_type); if (s_type == "RANGED") { @@ -255,6 +258,14 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) erase_template_attribute("VLAN_ID",vlan_id); + // ------------ VLAN ---------------------- + + erase_template_attribute("VLAN", vlan_attr); + + TO_UPPER(vlan_attr); + + vlan = (vlan_attr == "YES"); + // ------------ BRIDGE -------------------- erase_template_attribute("BRIDGE",bridge); @@ -272,7 +283,6 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) oss << "onebr" << oid; bridge = oss.str(); - replace_template_attribute("BRIDGE",bridge); } } @@ -280,7 +290,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) erase_template_attribute("PUBLIC", pub); - transform (pub.begin(), pub.end(), pub.begin(), (int(*)(int))toupper); + TO_UPPER(pub); public_obj = (pub == "YES"); @@ -515,7 +525,8 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const "" << gname << "" << "" << name << "" << "" << type << "" << - "" << bridge << ""; + "" << bridge << ""<< + "" << vlan << ""; if (!phydev.empty()) { @@ -566,6 +577,7 @@ int VirtualNetwork::from_xml(const string &xml_str) rc += xpath(int_type, "/VNET/TYPE", -1); rc += xpath(bridge, "/VNET/BRIDGE", "not_found"); rc += xpath(public_obj, "/VNET/PUBLIC", 0); + rc += xpath(vlan, "/VNET/VLAN", 0); xpath(phydev, "/VNET/PHYDEV", ""); xpath(vlan_id, "/VNET/VLAN_ID",""); @@ -636,6 +648,15 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) nic->replace("MAC" ,mac); nic->replace("IP" ,ip); + if ( vlan == 1 ) + { + nic->replace("VLAN", "YES"); + } + else + { + nic->replace("VLAN", "NO"); + } + if (!phydev.empty()) { nic->replace("PHYDEV", phydev); diff --git a/src/vnm/test/VirtualNetworkPoolTest.cc b/src/vnm/test/VirtualNetworkPoolTest.cc index e7854565e1..033a188943 100644 --- a/src/vnm/test/VirtualNetworkPoolTest.cc +++ b/src/vnm/test/VirtualNetworkPoolTest.cc @@ -71,18 +71,18 @@ const string templates[] = const string xmls[] = { - "01230the_useroneadminNet number one1br100130.10.0.150:20:20:20:20:200-1", + "01230the_useroneadminNet number one1br1000130.10.0.150:20:20:20:20:200-1", - "12610the_useroneadminA virtual network0br010", + "12610the_useroneadminA virtual network0br0010", - "01330the_useroneadminNet number two1br100130.10.2.150:20:20:20:20:200-1", + "01330the_useroneadminNet number two1br1000130.10.2.150:20:20:20:20:200-1", }; const string xml_dump = - "010the_useroneadminNet number one1br100120the_useroneadminA virtual network0br010"; + "010the_useroneadminNet number one1br1000120the_useroneadminA virtual network0br0010"; const string xml_dump_where = - "120the_useroneadminA virtual network0br010"; + "120the_useroneadminA virtual network0br0010"; /* ************************************************************************* */ /* ************************************************************************* */ @@ -310,8 +310,8 @@ public: }; string phydev_xml[] = { - "000the_useroneadminBRIDGE and PHYDEV1br0eth000130.10.0.150:20:20:20:20:200-1", - "100the_useroneadminNo BRIDGE only PHYDEV1onebr1eth000130.10.0.150:20:20:20:20:200-1" + "000the_useroneadminBRIDGE and PHYDEV1br00eth000130.10.0.150:20:20:20:20:200-1", + "100the_useroneadminNo BRIDGE only PHYDEV1onebr10eth000130.10.0.150:20:20:20:20:200-1" }; // test vm with bridge and phydev diff --git a/src/vnm_mad/remotes/802.1Q/HostManaged.rb b/src/vnm_mad/remotes/802.1Q/HostManaged.rb index 8d5194b869..47a65a3cce 100644 --- a/src/vnm_mad/remotes/802.1Q/HostManaged.rb +++ b/src/vnm_mad/remotes/802.1Q/HostManaged.rb @@ -64,7 +64,7 @@ class OpenNebulaHM < OpenNebulaNetwork def device_exists?(dev, vlan=nil) dev = "#{dev}.#{vlan}" if vlan - system("#{COMMANDS[:ip]} link show #{dev}") + OpenNebula.exec_and_log("#{COMMANDS[:ip]} link show #{dev}") end def create_dev_vlan(dev, vlan) diff --git a/src/vnm_mad/remotes/Firewall.rb b/src/vnm_mad/remotes/Firewall.rb index 586481ef05..2cc4f98eca 100644 --- a/src/vnm_mad/remotes/Firewall.rb +++ b/src/vnm_mad/remotes/Firewall.rb @@ -104,7 +104,7 @@ class OpenNebulaFirewall < OpenNebulaNetwork def run_rules(rules) rules.flatten.each do |rule| - system(rule) + OpenNebula.exec_and_log(rule) end end diff --git a/src/vnm_mad/remotes/OpenNebulaNetwork.rb b/src/vnm_mad/remotes/OpenNebulaNetwork.rb index 25cf31d8be..a6cb14ca55 100644 --- a/src/vnm_mad/remotes/OpenNebulaNetwork.rb +++ b/src/vnm_mad/remotes/OpenNebulaNetwork.rb @@ -42,11 +42,8 @@ COMMANDS = { :lsmod => "/sbin/lsmod" } -# -# -# class VM - attr_accessor :nics, :filtered_nics, :vm_info + attr_accessor :nics, :vm_info def initialize(vm_root, hypervisor) @vm_root = vm_root @@ -55,7 +52,7 @@ class VM nics = Nics.new(@hypervisor) - @vm_root.elements.each("TEMPLATE/NIC") do |nic_element| + @vm_root.elements.each("TEMPLATE/NIC[VLAN=YES]") do |nic_element| nic = nics.new_nic nic_element.elements.each('*') do |nic_attribute| @@ -69,21 +66,12 @@ class VM nics << nic end - @nics = nics - @filtered_nics = nics - end - - def filter(*filter) - @filtered_nics = @nics.get(*filter) - end - - def unfilter - @filtered_nics = @nics + @nics = nics end def each_nic(block) - if @filtered_nics != nil - @filtered_nics.each do |the_nic| + if @nics != nil + @nics.each do |the_nic| block.call(the_nic) end end @@ -110,7 +98,7 @@ class OpenNebulaNetwork def initialize(vm_tpl, hypervisor=nil) if !hypervisor - @hypervisor = detect_hypervisor + @hypervisor = detect_hypervisor else @hypervisor = hypervisor end @@ -118,16 +106,6 @@ class OpenNebulaNetwork @vm = VM.new(REXML::Document.new(vm_tpl).root, @hypervisor) end - def filter(*filter) - @vm.filter(*filter) - self - end - - def unfilter - @vm.unfilter - self - end - def process(&block) @vm.each_nic(block) end diff --git a/src/vnm_mad/remotes/OpenNebulaNic.rb b/src/vnm_mad/remotes/OpenNebulaNic.rb index d2916a91bd..84214bd154 100644 --- a/src/vnm_mad/remotes/OpenNebulaNic.rb +++ b/src/vnm_mad/remotes/OpenNebulaNic.rb @@ -28,59 +28,11 @@ class Nics < Array def new_nic @nicClass.new end - - # finds nics that match 'args' - # 'args' can be a Hash, or an array - # args example: - # {:mac => "02:00:C0:A8:01:01", :bridge => "br0"} - # :mac, "02:00:C0:A8:01:01" - # key values may also be an array: - # {:mac => "02:00:C0:A8:01:01", :bridge => ["br0","br1"]} - def get(*args) - if args.length == 2 - dict = Hash.new - dict[args[0]] = args[1] - elsif args.length == 1 - dict = args[0] - else - return nil - end - - matching = Array.new - self.each do |e| - e_filter = Hash.new - dict.each_key{|k| e_filter[k] = e[k]} - if compare(e_filter,dict) - matching << e - end - end - - if matching.empty? - nil - else - matching - end - end - - def compare(hash1, hash2) - #hash1 has a single value per key - #hash2 may contain an array of values - hash1.each do |k,v| - return false if !hash2[k] - v2 = hash2[k] - if hash2[k].kind_of?(Array) - return false if !v2.include? v - else - return false if v != v2 - end - end - true - end end -# A NIC using KVM. This class implements functions to get the physical interface -# that the NIC is using +# A NIC using KVM. This class implements functions to get the physical interface +# that the NIC is using class NicKVM < Hash def initialize super(nil) @@ -118,8 +70,8 @@ class NicKVM < Hash end -# A NIC using Xen. This class implements functions to get the physical interface -# that the NIC is using +# A NIC using Xen. This class implements functions to get the physical interface +# that the NIC is using class NicXen < Hash def initialize super(nil) diff --git a/src/vnm_mad/remotes/ebtables/post b/src/vnm_mad/remotes/ebtables/post index e69f291c26..c142e41a2f 100755 --- a/src/vnm_mad/remotes/ebtables/post +++ b/src/vnm_mad/remotes/ebtables/post @@ -21,10 +21,5 @@ $: << File.join(File.dirname(__FILE__), "..") require 'Ebtables' -# Uncomment to act only on the listed bridges. -#FILTERED_BRIDGES = ['br0'] - onevlan = EbtablesVLAN.from_base64(ARGV[0]) - -onevlan.filter(:bridge => FILTERED_BRIDGES) if defined? FILTERED_BRIDGES exit onevlan.activate diff --git a/src/vnm_mad/remotes/test/OpenNebulaNetwork_spec.rb b/src/vnm_mad/remotes/test/OpenNebulaNetwork_spec.rb index c8e7c14ccd..3875bd403f 100644 --- a/src/vnm_mad/remotes/test/OpenNebulaNetwork_spec.rb +++ b/src/vnm_mad/remotes/test/OpenNebulaNetwork_spec.rb @@ -1,18 +1,18 @@ #!/usr/bin/env ruby -$: << File.dirname(__FILE__) + '/..' \ - << './' +$: << File.dirname(__FILE__) +$: << File.join(File.dirname(__FILE__), '..') +$: << File.join(File.dirname(__FILE__),'../../../mad/ruby/') require 'rubygems' require 'rspec' -require 'SystemMock' require 'pp' require 'OpenNebulaNetwork' -require 'Ebtables' +require 'ebtables/Ebtables' require 'Firewall' -require 'HostManaged' -require 'OpenvSwitch' +require '802.1Q/HostManaged' +require 'ovswitch/OpenvSwitch' OUTPUT = Hash.new Dir[File.dirname(__FILE__) + "/output/**"].each do |f| @@ -20,6 +20,9 @@ Dir[File.dirname(__FILE__) + "/output/**"].each do |f| OUTPUT[key] = File.read(f) end +require 'scripts_common' +require 'SystemMock' +include OpenNebula include SystemMock RSpec.configure do |config| @@ -56,21 +59,6 @@ describe 'networking' do onevlan.vm.nics.should == nics_expected end - it "filter nics in kvm" do - $capture_commands = { - /virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml] - } - onevlan = OpenNebulaNetwork.new(OUTPUT[:onevm_show],"kvm") - onevlan.filter(:bridge => "br1") - nics_expected = [{:bridge=>"br1", - :ip=>"10.1.1.1", - :mac=>"02:00:0a:01:01:01", - :network=>"r1", - :network_id=>"1", - :tap=>"vnet1"}] - - onevlan.vm.filtered_nics.should == nics_expected - end end describe 'ebtables' do @@ -88,7 +76,10 @@ describe 'ebtables' do "sudo /sbin/ebtables -A FORWARD -s ! 02:00:0a:01:01:01 -i vnet1 -j DROP", "sudo /sbin/ebtables -A FORWARD -s ! 02:00:0a:01:02:00/ff:ff:ff:ff:ff:00 -o vnet2 -j DROP", "sudo /sbin/ebtables -A FORWARD -s ! 02:00:0a:01:02:01 -i vnet2 -j DROP"] - $collector[:system].should == ebtables_cmds + + ebtables_cmds.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd| + $collector[:backtick].include?(cmd).should == true + end end end @@ -106,7 +97,9 @@ describe 'openvswitch' do "sudo /usr/local/bin/ovs-vsctl set Port vnet2 tag=4" ] - $collector[:system].should == openvswitch_tags + openvswitch_tags.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd| + $collector[:backtick].include?(cmd).should == true + end end it "force VLAN_ID for Open vSwitch vlans in kvm" do @@ -117,12 +110,14 @@ describe 'openvswitch' do } onevlan = OpenvSwitchVLAN.new(OUTPUT[:onevm_show_vlan_id_kvm],"kvm") onevlan.activate - + onevlan_rules = ["sudo /usr/local/bin/ovs-vsctl set Port vnet0 tag=6", "sudo /usr/local/bin/ovs-vsctl set Port vnet1 tag=50", "sudo /usr/local/bin/ovs-vsctl set Port vnet1 tag=51"] - $collector[:system].should == onevlan_rules + onevlan_rules.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd| + $collector[:backtick].include?(cmd).should == true + end end end @@ -146,7 +141,9 @@ describe 'firewall' do "sudo /sbin/iptables -A one-36-3 -p icmp -m state --state ESTABLISHED -j ACCEPT", "sudo /sbin/iptables -A one-36-3 -p icmp -j DROP"] - $collector[:system].should == fw_activate_rules + fw_activate_rules.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd| + $collector[:backtick].include?(cmd).should == true + end end end @@ -155,20 +152,23 @@ describe 'host-managed' do $capture_commands = { /virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml_phydev], /brctl show/ => OUTPUT[:brctl_show], - /brctl add/ => nil, - /vconfig/ => nil, - /ip link/ => nil + /brctl add/ => nil, + /vconfig/ => nil, + /ip link/ => nil } hm = OpenNebulaHM.new(OUTPUT[:onevm_show_phydev_kvm],"kvm") hm.activate - hm_activate_rules = ["sudo /usr/sbin/brctl addbr onebr6", + hm_activate_rules = ["sudo /sbin/brctl addbr onebr6", "sudo /sbin/ip link set onebr6 up", "sudo /sbin/ip link show eth0.8", "sudo /sbin/vconfig add eth0 8", "sudo /sbin/ip link set eth0.8 up", - "sudo /usr/sbin/brctl addif onebr6 eth0.8"] - $collector[:system].should == hm_activate_rules + "sudo /sbin/brctl addif onebr6 eth0.8"] + + hm_activate_rules.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd| + $collector[:backtick].include?(cmd).should == true + end end it "force VLAN_ID for vlans in kvm" do @@ -182,19 +182,21 @@ describe 'host-managed' do hm = OpenNebulaHM.new(OUTPUT[:onevm_show_vlan_id_kvm],"kvm") hm.activate - hm_vlan_id = ["sudo /usr/sbin/brctl addbr onebr10", + hm_vlan_id = ["sudo /sbin/brctl addbr onebr10", "sudo /sbin/ip link set onebr10 up", "sudo /sbin/ip link show eth0.50", "sudo /sbin/vconfig add eth0 50", "sudo /sbin/ip link set eth0.50 up", - "sudo /usr/sbin/brctl addif onebr10 eth0.50", - "sudo /usr/sbin/brctl addbr specialbr", + "sudo /sbin/brctl addif onebr10 eth0.50", + "sudo /sbin/brctl addbr specialbr", "sudo /sbin/ip link set specialbr up", "sudo /sbin/ip link show eth0.51", "sudo /sbin/vconfig add eth0 51", "sudo /sbin/ip link set eth0.51 up", - "sudo /usr/sbin/brctl addif specialbr eth0.51"] + "sudo /sbin/brctl addif specialbr eth0.51"] - $collector[:system].should == hm_vlan_id + hm_vlan_id.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd| + $collector[:backtick].include?(cmd).should == true + end end end diff --git a/src/vnm_mad/remotes/test/SystemMock.rb b/src/vnm_mad/remotes/test/SystemMock.rb index 9c2d122d47..6e83e85411 100644 --- a/src/vnm_mad/remotes/test/SystemMock.rb +++ b/src/vnm_mad/remotes/test/SystemMock.rb @@ -1,14 +1,15 @@ module SystemMock - require 'open3' + def execute_cmd(cmd) if $capture_commands $capture_commands.each do |regex, output| if cmd.match(regex) + Kernel.send(:`,":;exit 0") return output end end end - Open3.popen3(cmd){|stdin, stdout, stderr| stdout.read} + Kernel.send(:`,cmd) end def `(cmd)