diff --git a/include/Nebula.h b/include/Nebula.h index ec709e3323..031d19039c 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -517,6 +517,15 @@ public: return get_conf_attribute("DS_MAD_CONF", ds_name, value); }; + /** + * Gets a VN configuration attribute + */ + int get_vn_conf_attribute(const std::string& vn_name, + const VectorAttribute* &value) const + { + return get_conf_attribute("VN_MAD_CONF", vn_name, value); + } + /** * Gets a TM configuration attribute */ diff --git a/include/NebulaTemplate.h b/include/NebulaTemplate.h index 29097eb5f8..201cb62c81 100644 --- a/include/NebulaTemplate.h +++ b/include/NebulaTemplate.h @@ -172,6 +172,12 @@ private: const std::string& driver_managed_groups, const std::string& max_token_time); + /** + * Sets a the defaults for a Network drivers + */ + void set_conf_vn(const std::string& name, + const std::string& bridge_type); + /** * Sets auth permissions for vm operations */ diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index bdb2a8b742..97fee71463 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -64,6 +64,13 @@ public: BRIDGE = 9 }; + enum BridgeType { + UNDEFINED = 0, + LINUX = 1, + OPENVSWITCH = 2, + VCENTER_PORT_GROUPS = 3 + }; + static string driver_to_str(VirtualNetworkDriver ob) { switch (ob) @@ -125,6 +132,41 @@ public: } }; + static string bridge_type_to_str(BridgeType ob) + { + switch (ob) + { + case UNDEFINED: + case LINUX: + return "linux"; + case OPENVSWITCH: + return "openvswitch"; + case VCENTER_PORT_GROUPS: + return "vcenter_port_groups"; + break; + } + }; + + static BridgeType str_to_bridge_type(const string& ob) + { + if ( ob == "linux" ) + { + return LINUX; + } + else if ( ob == "openvswitch" ) + { + return OPENVSWITCH; + } + else if ( ob == "vcenter_port_groups" ) + { + return VCENTER_PORT_GROUPS; + } + else + { + return UNDEFINED; + } + }; + // ************************************************************************* // Virtual Network Public Methods // ************************************************************************* @@ -575,6 +617,11 @@ private: */ ObjectCollection vrouters; + /** + * Bridge type of the VirtualNetwork + */ + string bridge_type; + // ************************************************************************* // VLAN ID functions // ************************************************************************* @@ -644,6 +691,17 @@ private: return ar_pool.allocate_by_ip6(ip, ot, oid, nic, inherit); } + // ************************************************************************* + // BRIDGE TYPE functions + // ************************************************************************* + + /** + * This function parses the BRIDGE TYPE attribute. + * + * @param br_type the bridge type associated to the nic + */ + int parse_bridge_type(const string &vn_mad, string &error_str); + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 941e621c98..651ecd4246 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -1388,3 +1388,56 @@ AUTH_MAD_CONF = [ MAX_TOKEN_TIME = "-1" ] +#******************************************************************************* +# Authentication Driver Behavior Definition +#******************************************************************************* +# The configuration for each driver is defined in VN_MAD_CONF. These +# values must not be modified since they define the driver behavior. +# name : name of the auth driver +# BRIDGE_TYPE : define the technology used by the driver +#******************************************************************************* + +VN_MAD_CONF = [ + NAME = "dummy", + BRIDGE_TYPE = "linux" +] + +VN_MAD_CONF = [ + NAME = "802.1Q", + BRIDGE_TYPE = "linux" +] + +VN_MAD_CONF = [ + NAME = "ebtables", + BRIDGE_TYPE = "linux" +] + +VN_MAD_CONF = [ + NAME = "fw", + BRIDGE_TYPE = "linux" +] + +VN_MAD_CONF = [ + NAME = "ovswitch", + BRIDGE_TYPE = "openvswitch" +] + +VN_MAD_CONF = [ + NAME = "vxlan", + BRIDGE_TYPE = "linux" +] + +VN_MAD_CONF = [ + NAME = "vcenter", + BRIDGE_TYPE = "vcenter_port_groups" +] + +VN_MAD_CONF = [ + NAME = "ovswitch_vxlan", + BRIDGE_TYPE = "openvswitch" +] + +VN_MAD_CONF = [ + NAME = "bridge", + BRIDGE_TYPE = "linux" +] diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index ce3ad67e95..d4034aee28 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -199,6 +199,34 @@ void OpenNebulaTemplate::set_multiple_conf_default() set_conf_auth("server_x509", "NO", "NO", "-1"); register_multiple_conf_default("AUTH_MAD_CONF"); + +/* +#******************************************************************************* +# Virtual Network Configuration +#******************************************************************************* +#dummy +#802.1Q +#ebtables +#fw +#ovswitch +#vxlan +#vcenter +#ovswitch_vxlan +#bridge +#****** +*/ + + set_conf_vn("dummy", "linux"); + set_conf_vn("802.1Q", "linux"); + set_conf_vn("ebtables", "linux"); + set_conf_vn("fw", "linux"); + set_conf_vn("ovswitch", "openvswitch"); + set_conf_vn("vxlan", "linux"); + set_conf_vn("vcenter", "vcenter_port_groups"); + set_conf_vn("ovswitch_vxlan", "openvswitch"); + set_conf_vn("bridge", "linux"); + + register_multiple_conf_default("VN_MAD_CONF"); } /* -------------------------------------------------------------------------- */ @@ -357,6 +385,23 @@ void OpenNebulaTemplate::set_conf_auth(const std::string& name, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void OpenNebulaTemplate::set_conf_vn(const std::string& name, + const std::string& bridge_type) +{ + VectorAttribute * vattribute; + std::map vvalue; + + vvalue.insert(make_pair("NAME", name)); + vvalue.insert(make_pair("BRIDGE_TYPE", bridge_type)); + + vattribute = new VectorAttribute("VN_MAD_CONF", vvalue); + conf_default.insert(make_pair(vattribute->name(), vattribute)); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + + void OpenNebulaTemplate::set_conf_default() { VectorAttribute * vattribute; diff --git a/src/onedb/local/5.6.0_to_5.7.8.rb b/src/onedb/local/5.6.0_to_5.7.8.rb new file mode 100644 index 0000000000..c31654ef48 --- /dev/null +++ b/src/onedb/local/5.6.0_to_5.7.8.rb @@ -0,0 +1,104 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +require 'set' +require 'base64' +require 'zlib' +require 'pathname' +require 'yaml' +require 'opennebula' + +$: << File.dirname(__FILE__) + +include OpenNebula + +module Migrator + + def db_version + "5.6.0" + end + + def one_version + "OpenNebula 5.6.0" + end + + def up + feature_2253() + + return true + end + + private + + def feature_2253() + @db.transaction do + # update virtual networks + @db.fetch("SELECT * FROM network_pool") do |row| + doc = Nokogiri::XML(row[:body], nil, NOKOGIRI_ENCODING) {|c| + c.default_xml.noblanks + } + + next unless doc.root.at_xpath("BRIDGE_TYPE").to_s.empty? + + vn_mad = doc.root.at_xpath("/VNET/VN_MAD").text + + bridge_type = doc.create_element("BRIDGE_TYPE") + bridge_type.add_child(bridge_type_by_vn_mad(vn_mad)) + + doc.root.at_xpath("/VNET").add_child(bridge_type) + + @db.run("UPDATE network_pool SET body = '#{doc.root.to_s}' "\ + "where oid = #{row[:oid]}") + end + end + + @db.transaction do + # updates VM's nics + @db.fetch("SELECT * FROM vm_pool") do |row| + doc = Nokogiri::XML(row[:body], nil, NOKOGIRI_ENCODING) {|c| + c.default_xml.noblanks + } + + next if doc.root.at_xpath("TEMPLATE/NIC").to_s.empty? + + doc.root.xpath("//NIC").map do |nic| + next unless nic.xpath("BRIDGE_TYPE").to_s.empty? + + vn_mad = nic.xpath("VN_MAD").text + + bridge_type = doc.create_element("BRIDGE_TYPE") + bridge_type.add_child(bridge_type_by_vn_mad(vn_mad)) + nic.add_child(bridge_type) + end + + @db.run("UPDATE vm_pool SET body = '#{doc.root.to_s}' where" \ + "oid = #{row[:oid]}") + end + end + end + + def bridge_type_by_vn_mad(vn_mad) + #TODO CASE + if vn_mad == "vcenter" + return "vcenter_port_groups" + elsif vn_mad == "ovswitch" || vn_mad == "ovswitch_vxlan" + return "openvswitch" + else + return "linux" + end + end + +end diff --git a/src/vmm/LibVirtDriverKVM.cc b/src/vmm/LibVirtDriverKVM.cc index 73b20b7ad5..91cc6aef91 100644 --- a/src/vmm/LibVirtDriverKVM.cc +++ b/src/vmm/LibVirtDriverKVM.cc @@ -270,6 +270,7 @@ int LibVirtDriver::deployment_description_kvm( string vrouter_ip = ""; string filter = ""; string virtio_queues = ""; + string bridge_type = ""; string i_avg_bw = ""; string i_peak_bw = ""; @@ -1036,6 +1037,7 @@ int LibVirtDriver::deployment_description_kvm( ip = nic[i]->vector_value("IP"); filter = nic[i]->vector_value("FILTER"); virtio_queues = nic[i]->vector_value("VIRTIO_QUEUES"); + bridge_type = nic[i]->vector_value("BRDIGE_TYPE"); vrouter_ip = nic[i]->vector_value("VROUTER_IP"); @@ -1055,8 +1057,7 @@ int LibVirtDriver::deployment_description_kvm( { file << "\t\t" << endl; - if (VirtualNetwork::str_to_driver(vn_mad) == VirtualNetwork::OVSWITCH || - VirtualNetwork::str_to_driver(vn_mad) == VirtualNetwork::OVSWITCH_VXLAN) + if (VirtualNetwork::str_to_bridge_type(bridge_type) == VirtualNetwork::OPENVSWITCH) { file << "\t\t\t" << endl; } diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index a3e901d3e2..a94a50711f 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -28,6 +28,8 @@ #include "NebulaUtil.h" +#include "Nebula.h" + #define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) /* ************************************************************************** */ @@ -299,6 +301,17 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) add_template_attribute("BRIDGE", bridge); + erase_template_attribute("BRIDGE_TYPE", bridge_type); + + rc = parse_bridge_type(vn_mad, error_str); + + if (rc != 0) + { + goto error_common; + } + + add_template_attribute("BRIDGE_TYPE", bridge_type); + //-------------------------------------------------------------------------- // Get the Address Ranges //-------------------------------------------------------------------------- @@ -564,7 +577,8 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended, lock_db_to_xml(lock_str) << perms_to_xml(perm_str) << Clusterable::to_xml(clusters_xml) << - "" << one_util::escape_xml(bridge) << ""; + "" << one_util::escape_xml(bridge) << "" + "" << one_util::escape_xml(bridge_type) << ""; if (parent_vid != -1) { @@ -663,6 +677,7 @@ int VirtualNetwork::from_xml(const string &xml_str) xpath(vn_mad, "/VNET/VN_MAD", ""); xpath(phydev, "/VNET/PHYDEV", ""); + xpath(bridge_type, "/VNET/BRIDGE_TYPE", ""); xpath(vlan_id, "/VNET/VLAN_ID", ""); xpath(outer_vlan_id, "/VNET/OUTER_VLAN_ID", ""); @@ -785,6 +800,12 @@ int VirtualNetwork::nic_attribute( nic->replace("CLUSTER_ID", one_util::join(cluster_ids, ',')); + + if (!bridge_type.empty()) + { + nic->replace("BRIDGE_TYPE", bridge_type); + } + for (it = inherit_attrs.begin(); it != inherit_attrs.end(); it++) { PoolObjectSQL::get_template_attribute((*it).c_str(), inherit_val); @@ -1309,3 +1330,46 @@ void VirtualNetwork::get_security_groups(set & sgs) ar_pool.get_all_security_groups(sgs); } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualNetwork::parse_bridge_type(const string &vn_mad, string &error_str) +{ + const VectorAttribute* vatt; + std::string br_type; + + ostringstream oss; + + if ( Nebula::instance().get_vn_conf_attribute(vn_mad, vatt) != 0 ) + { + goto error_conf; + } + + if ( vatt->vector_value("BRIDGE_TYPE", br_type) == -1) + { + goto error; + } + else + { + if (str_to_bridge_type(br_type) == UNDEFINED) + { + goto error; + } + bridge_type = br_type; + } + + return 0; + +error_conf: + oss << "VN_MAD named \"" << vn_mad << "\" is not defined in oned.conf"; + goto error_common; + +error: + oss << "Attribute bridge type in VN_MAD_CONF for " + << vn_mad << " is missing or has wrong value in oned.conf"; + +error_common: + error_str = oss.str(); + return -1; +}