1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-30 22:50:10 +03:00

Feature #4215: VRs have NICs defined

VRs can request vnet leases. If a vm template has a
VROUTER_ID, the NICs from that VR are merged into
the template. If the VR NIC has a floating IP, it
is added as VROUTER_IP.
This commit is contained in:
Carlos Martín 2015-12-16 12:32:19 +01:00
parent 3991404826
commit 4c68cd7c9e
16 changed files with 501 additions and 98 deletions

View File

@ -1262,12 +1262,11 @@ public:
*
* @param nic NIC to be released
* @param vmid Virtual Machine oid
* @param vrid Virtual Router id if the VM is a VR, or -1
*
* @return 0 on success, -1 otherwise
*/
static int release_network_leases(
VectorAttribute const * nic, int vmid, int vrid);
VectorAttribute const * nic, int vmid);
/**
* Releases all disk images taken by this Virtual Machine
@ -1329,6 +1328,12 @@ public:
*/
int get_vrouter_id();
/**
* Returns true if this VM is a Virtual Router
* @return true if this VM is a Virtual Router
*/
bool is_vrouter();
// ------------------------------------------------------------------------
// Context related functions
// ------------------------------------------------------------------------
@ -1544,7 +1549,6 @@ public:
*
* @param vm_id Id of the VM where this nic will be attached
* @param vm_sgs the securty group ids already present in the VM
* @param vm_vrid Virtual Router id if the VM is a VR, or -1
* @param new_nic New NIC vector attribute, obtained from get_attach_nic_info
* @param rules Security Group rules will be added at the end of this
* vector. If not used, the VectorAttributes must be freed by the calling
@ -1557,7 +1561,6 @@ public:
static int set_up_attach_nic(
int vm_id,
set<int>& vm_sgs,
int vm_vrid,
VectorAttribute * new_nic,
vector<VectorAttribute*> &rules,
int max_nic_id,

View File

@ -157,75 +157,79 @@ public:
/**
* Gets a new address lease for a specific VM
* @param vid VM identifier
* @param ot the type of the object requesting the address
* @param oid the id of the object requesting the address
* @param nic the VM NIC attribute to be filled with the lease info.
* @param inherit attributes from the address range to include in the NIC
* @return 0 if success
*/
int allocate_addr(int vid, VectorAttribute * nic,
const vector<string>& inherit)
int allocate_addr(PoolObjectSQL::ObjectType ot, int oid,
VectorAttribute * nic, const vector<string>& inherit)
{
return ar_pool.allocate_addr(PoolObjectSQL::VM, vid, nic, inherit);
return ar_pool.allocate_addr(ot, oid, nic, inherit);
}
/**
* Gets a new address lease for a specific VM by MAC
* @param vid VM identifier
* @param ot the type of the object requesting the address
* @param oid the id of the object requesting the address
* @param mac the MAC address requested
* @param nic the VM NIC attribute to be filled with the lease info.
* @param inherit attributes from the address range to include in the NIC
* @return 0 if success
*/
int allocate_by_mac(int vid, const string& mac, VectorAttribute * nic,
const vector<string>& inherit)
int allocate_by_mac(PoolObjectSQL::ObjectType ot, int oid, const string& mac,
VectorAttribute * nic, const vector<string>& inherit)
{
return ar_pool.allocate_by_mac(mac, PoolObjectSQL::VM, vid, nic, inherit);
return ar_pool.allocate_by_mac(mac, ot, oid, nic, inherit);
}
/**
* Gets a new address lease for a specific VM by IP
* @param vid VM identifier
* @param ot the type of the object requesting the address
* @param oid the id of the object requesting the address
* @param ip the IP address requested
* @param nic the VM NIC attribute to be filled with the lease info.
* @param inherit attributes from the address range to include in the NIC
* @return 0 if success
*/
int allocate_by_ip(int vid, const string& ip, VectorAttribute * nic,
const vector<string>& inherit)
int allocate_by_ip(PoolObjectSQL::ObjectType ot, int oid, const string& ip,
VectorAttribute * nic, const vector<string>& inherit)
{
return ar_pool.allocate_by_ip(ip, PoolObjectSQL::VM, vid, nic, inherit);
return ar_pool.allocate_by_ip(ip, ot, oid, nic, inherit);
}
/**
* Release previously given address lease
* @param arid of the address range where the address was leased from
* @param vid the ID of the VM
* @param vrid Virtual Router id if the VM is a VR, or -1
* @param ot the type of the object requesting the address
* @param oid the id of the object requesting the address
* @param mac MAC address identifying the lease
*/
void free_addr(unsigned int arid, int vid, int vrid, const string& mac)
void free_addr(unsigned int arid, PoolObjectSQL::ObjectType ot, int oid,
const string& mac)
{
ar_pool.free_addr(arid, PoolObjectSQL::VM, vid, mac);
ar_pool.free_addr(arid, ot, oid, mac);
if (vrid != -1)
if (ot == PoolObjectSQL::VROUTER)
{
vrouters.del_collection_id(vrid);
vrouters.del_collection_id(oid);
}
}
/**
* Release previously given address lease
* @param vid the ID of the VM
* @param vrid Virtual Router id if the VM is a VR, or -1
* @param ot the type of the object requesting the address
* @param oid the id of the object requesting the address
* @param mac MAC address identifying the lease
*/
void free_addr(int vid, int vrid, const string& mac)
void free_addr(PoolObjectSQL::ObjectType ot, int oid, const string& mac)
{
ar_pool.free_addr(PoolObjectSQL::VM, vid, mac);
ar_pool.free_addr(ot, oid, mac);
if (vrid != -1)
if (ot == PoolObjectSQL::VROUTER)
{
vrouters.del_collection_id(vrid);
vrouters.del_collection_id(oid);
}
}
@ -259,7 +263,6 @@ public:
* * BRIDGE: for this virtual network
* @param nic attribute for the VM template
* @param vid of the VM getting the lease
* @param vrid Virtual Router id if the VM is a VR, or -1
* @param inherit_attrs Attributes to be inherited from the vnet template
* into the nic
* @return 0 on success
@ -267,6 +270,20 @@ public:
int nic_attribute(
VectorAttribute * nic,
int vid,
const vector<string>& inherit_attrs);
/**
* Modifies the given nic attribute adding the following attributes:
* * IP: leased from network
* * MAC: leased from network
* @param nic attribute for the VRouter template
* @param vrid of the VRouter getting the lease
* @param inherit_attrs Attributes to be inherited from the vnet template
* into the nic
* @return 0 on success
*/
int vrouter_nic_attribute(
VectorAttribute * nic,
int vrid,
const vector<string>& inherit_attrs);

View File

@ -107,7 +107,6 @@ public:
* @param nic_id the id for this NIC
* @param uid of the VM owner
* @param vid of the VM requesting the lease
* @param vrid Virtual Router id if the VM is a VR, or -1
* @param error_str string describing the error
* @return 0 on success,
* -1 error,
@ -118,6 +117,22 @@ public:
int nic_id,
int uid,
int vid,
string& error_str);
/**
* Generates a NIC attribute for VRouters using the VirtualNetwork
* metadata
* @param nic the nic attribute to be generated
* @param uid of the VM owner
* @param vrid of the VRouter requesting the lease
* @param error_str string describing the error
* @return 0 on success,
* -1 error,
* -2 not using the pool
*/
int vrouter_nic_attribute(
VectorAttribute * nic,
int uid,
int vrid,
string& error_str);

View File

@ -65,6 +65,8 @@ public:
*(static_cast<Template *>(obj_template)));
};
Template * get_nics() const;
private:
// -------------------------------------------------------------------------
// Friends
@ -111,8 +113,6 @@ private:
*/
int from_xml(const string &xml_str);
protected:
// *************************************************************************
// Constructor
// *************************************************************************
@ -144,6 +144,13 @@ protected:
*/
int insert(SqlDB *db, string& error_str);
/**
* Drops object from the database
* @param db pointer to the db
* @return 0 on success
*/
virtual int drop(SqlDB *db);
/**
* Writes/updates the VirtualRouter data fields in the database.
* @param db pointer to the db
@ -154,6 +161,30 @@ protected:
string err;
return insert_replace(db, true, err);
};
// -------------------------------------------------------------------------
// NIC Management
// -------------------------------------------------------------------------
/**
* Get all network leases for this Virtual Router
* @return 0 onsuccess
*/
int get_network_leases(string& estr);
/**
* Releases all network leases taken by this Virtual Router
*/
void release_network_leases();
/**
* Releases the network lease taken by this NIC
*
* @param nic NIC to be released
*
* @return 0 on success, -1 otherwise
*/
int release_network_leases(VectorAttribute const * nic);
};
#endif /*VIRTUAL_ROUTER_H_*/

View File

@ -51,6 +51,14 @@ EOT
"information, such as the SIZE for each DISK"
}
VROUTER={
:name => "vrouter",
:large => "--vrouter vrid",
:format => Integer,
:description => "Creates a VM associated to the given Virtual Router. "+
"The NIC elements defined in the Virtual Router will be used"
}
def self.rname
"VMTEMPLATE"
end

View File

@ -308,6 +308,8 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
"V:#{d['VM']}"
elsif d['VNET']
"N:#{d['VNET']}"
elsif d['VROUTER']
"R:#{d['VROUTER']}"
end
end

View File

@ -55,7 +55,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do
OneTemplateHelper::VM_NAME,
OneTemplateHelper::MULTIPLE,
OneTemplateHelper::USERDATA,
OneVMHelper::HOLD
OneVMHelper::HOLD,
OneTemplateHelper::VROUTER,
]
########################################################################
@ -232,6 +233,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do
extra_template << "\n" << user_inputs
if !options[:vrouter].nil?
extra_template << "\n" << "VROUTER_ID = \"#{options[:vrouter]}\""
end
res = t.instantiate(name, on_hold, extra_template)
if !OpenNebula.is_error?(res)

View File

@ -1442,7 +1442,6 @@ int DispatchManager::attach_nic(
int max_nic_id;
int uid;
int oid;
int vrid;
int rc;
set<int> vm_sgs;
@ -1477,6 +1476,19 @@ int DispatchManager::attach_nic(
return -1;
}
if (vm->is_vrouter())
{
oss << "Could not add a new NIC to VM " << vid
<< ", it is associated to the Virtual Router "
<< vm->get_vrouter_id() << ".";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
nic = vm->get_attach_nic_info(tmpl, max_nic_id, error_str);
if ( nic == 0 )
@ -1499,7 +1511,6 @@ int DispatchManager::attach_nic(
uid = vm->get_uid();
oid = vm->get_oid();
vrid = vm->get_vrouter_id();
vmpool->update(vm);
@ -1507,7 +1518,6 @@ int DispatchManager::attach_nic(
rc = VirtualMachine::set_up_attach_nic(oid,
vm_sgs,
vrid,
nic,
sg_rules,
max_nic_id,
@ -1521,7 +1531,7 @@ int DispatchManager::attach_nic(
if ( rc == 0 )
{
VirtualMachine::release_network_leases(nic, vid, vrid);
VirtualMachine::release_network_leases(nic, vid);
vector<VectorAttribute*>::iterator it;
for(it = sg_rules.begin(); it != sg_rules.end(); it++)
@ -1647,6 +1657,19 @@ int DispatchManager::detach_nic(
return -1;
}
if (vm->is_vrouter())
{
oss << "Could not detach NIC from VM " << vid
<< ", it is associated to the Virtual Router "
<< vm->get_vrouter_id() << ".";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
if ( vm->set_attach_nic(nic_id) == -1 )
{
oss << "Could not detach NIC with NIC_ID " << nic_id

View File

@ -35,11 +35,14 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
ostringstream sid;
PoolObjectAuth perms;
PoolObjectAuth vr_perms;
Nebula& nd = Nebula::instance();
VirtualMachinePool* vmpool = nd.get_vmpool();
VMTemplatePool * tpool = static_cast<VMTemplatePool *>(pool);
VirtualRouterPool* vrpool = nd.get_vrouterpool();
VirtualRouter * vr;
VirtualMachineTemplate * tmpl;
VirtualMachineTemplate * extended_tmpl = 0;
@ -48,6 +51,8 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
string error_str;
string aname;
bool has_vrouter_id;
int vrid;
string tmpl_name;
@ -136,28 +141,39 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
tmpl->set(new SingleAttribute("NAME",name));
}
//--------------------------------------------------------------------------
// Temporary code to create Virtual Routers from regular VM Templates
bool is_vrouter;
bool has_vrouter_id;
int vrid;
string vr_error_str;
VirtualRouterPool* vrpool = Nebula::instance().get_vrouterpool();
tmpl->get("VROUTER", is_vrouter);
/* ---------------------------------------------------------------------- */
/* If it is a Virtual Router, get the NICs */
/* ---------------------------------------------------------------------- */
has_vrouter_id = tmpl->get("VROUTER_ID", vrid);
if (is_vrouter && !has_vrouter_id)
if ( has_vrouter_id )
{
Template * vr_tmpl = new Template;
vr = vrpool->get(vrid, true);
vrpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
vr_tmpl, &vrid, vr_error_str);
if (vr == 0)
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::VROUTER),vrid),
att);
tmpl->replace("VROUTER_ID", vrid);
delete tmpl;
return;
}
vr->get_permissions(vr_perms);
tmpl->erase("NIC");
rc = tmpl->merge(vr->get_nics(), error_str);
vr->unlock();
if ( rc != 0 )
{
failure_response(INTERNAL, error_str, att);
delete tmpl;
return;
}
}
//--------------------------------------------------------------------------
@ -180,6 +196,11 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
VirtualMachine::set_auth_request(att.uid, ar, tmpl);
if (has_vrouter_id)
{
ar.add_auth(AuthRequest::MANAGE, vr_perms); // MANAGE VROUTER
}
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
@ -223,23 +244,19 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
delete extended_tmpl;
//--------------------------------------------------------------------------
// Temporary code to create Virtual Routers from regular VM Templates
// Final code would need rollback to delete the new VR on error
VirtualRouter * vr;
vr = vrpool->get(vrid, true);
if (vr != 0)
if ( has_vrouter_id )
{
vr->add_vmid(vid);
vr = vrpool->get(vrid, true);
vrpool->update(vr);
if (vr != 0)
{
vr->add_vmid(vid);
vr->unlock();
vrpool->update(vr);
vr->unlock();
}
}
//--------------------------------------------------------------------------
success_response(vid, att);
}

View File

@ -91,6 +91,9 @@ define(function(require) {
} else if (lease.VNET != undefined) { //used by a VNET
col0HTML = '<span type="text" class="radius label "></span>';
col1HTML = Locale.tr("NET:") + lease.VNET;
} else if (lease.VROUTER != undefined) { //used by a VR
col0HTML = '<span type="text" class="radius label "></span>';
col1HTML = Locale.tr("VR:") + lease.VROUTER;
} else {
col0HTML = '<span type="text" class="radius label "></span>';
col1HTML = '--';

View File

@ -842,13 +842,6 @@ int VirtualMachine::parse_vrouter(string& error_str)
{
string st;
user_obj_template->get("VROUTER", st);
if (!st.empty())
{
obj_template->replace("VROUTER", st);
}
user_obj_template->get("VROUTER_ID", st);
if (!st.empty())
@ -856,7 +849,6 @@ int VirtualMachine::parse_vrouter(string& error_str)
obj_template->replace("VROUTER_ID", st);
}
user_obj_template->erase("VROUTER");
user_obj_template->erase("VROUTER_ID");
return 0;
@ -2589,7 +2581,6 @@ VectorAttribute * VirtualMachine::get_attach_nic_info(
int VirtualMachine::set_up_attach_nic(
int vm_id,
set<int>& vm_sgs,
int vm_vrid,
VectorAttribute * new_nic,
vector<VectorAttribute*> &rules,
int max_nic_id,
@ -2601,8 +2592,7 @@ int VirtualMachine::set_up_attach_nic(
set<int> nic_sgs;
int rc = vnpool->nic_attribute(new_nic, max_nic_id+1, uid, vm_id,
vm_vrid, error_str);
int rc = vnpool->nic_attribute(new_nic, max_nic_id+1, uid, vm_id, error_str);
if ( rc == -1 ) //-2 is not using a pre-defined network
{
@ -3002,7 +2992,7 @@ int VirtualMachine::get_network_leases(string& estr)
merge_nic_defaults(nic);
rc = vnpool->nic_attribute(nic, i, uid, oid, get_vrouter_id(), estr);
rc = vnpool->nic_attribute(nic, i, uid, oid, estr);
if (rc == -1)
{
@ -3068,7 +3058,7 @@ void VirtualMachine::release_network_leases()
VectorAttribute const * nic =
dynamic_cast<VectorAttribute const * >(nics[i]);
release_network_leases(nic, oid, get_vrouter_id());
release_network_leases(nic, oid);
}
}
@ -3076,7 +3066,7 @@ void VirtualMachine::release_network_leases()
/* -------------------------------------------------------------------------- */
int VirtualMachine::release_network_leases(
VectorAttribute const * nic, int vmid, int vrid)
VectorAttribute const * nic, int vmid)
{
VirtualNetworkPool* vnpool = Nebula::instance().get_vnpool();
VirtualNetwork* vn;
@ -3114,11 +3104,11 @@ int VirtualMachine::release_network_leases(
if (nic->vector_value("AR_ID", ar_id) == 0)
{
vn->free_addr(ar_id, vmid, vrid, mac);
vn->free_addr(ar_id, PoolObjectSQL::VM, vmid, mac);
}
else
{
vn->free_addr(vmid, vrid, mac);
vn->free_addr(PoolObjectSQL::VM, vmid, mac);
}
vnpool->update(vn);
@ -3263,6 +3253,14 @@ int VirtualMachine::get_vrouter_id()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool VirtualMachine::is_vrouter()
{
return get_vrouter_id() != -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::generate_context(string &files, int &disk_id,
string& token_password)
{

View File

@ -1119,7 +1119,6 @@ void VirtualMachinePool::delete_attach_nic(int vid)
int uid;
int gid;
int oid;
int vrid;
vm = get(vid,true);
@ -1132,7 +1131,6 @@ void VirtualMachinePool::delete_attach_nic(int vid)
uid = vm->get_uid();
gid = vm->get_gid();
oid = vm->get_oid();
vrid = vm->get_vrouter_id();
update(vm);
@ -1146,6 +1144,6 @@ void VirtualMachinePool::delete_attach_nic(int vid)
Quotas::quota_del(Quotas::NETWORK, uid, gid, &tmpl);
VirtualMachine::release_network_leases(nic, oid, vrid);
VirtualMachine::release_network_leases(nic, oid);
}
}

View File

@ -508,6 +508,14 @@ void AddressRange::to_xml(ostringstream &oss, const vector<int>& vms,
is_in = true;
}
}
else if (it->second & PoolObjectSQL::VROUTER)
{
int oid = it->second & 0x00000000FFFFFFFFLL;
// TODO: all_vrouters?
lease.replace("VROUTER", oid);
is_in = true;
}
if (!is_in)
{

View File

@ -569,7 +569,6 @@ int VirtualNetwork::from_xml(const string &xml_str)
int VirtualNetwork::nic_attribute(
VectorAttribute * nic,
int vid,
int vrid,
const vector<string>& inherit_attrs)
{
string inherit_val;
@ -630,15 +629,15 @@ int VirtualNetwork::nic_attribute(
if (!ip.empty())
{
rc = allocate_by_ip(vid, ip, nic, inherit_attrs);
rc = allocate_by_ip(PoolObjectSQL::VM, vid, ip, nic, inherit_attrs);
}
else if (!mac.empty())
{
rc = allocate_by_mac(vid, mac, nic, inherit_attrs);
rc = allocate_by_mac(PoolObjectSQL::VM, vid, mac, nic, inherit_attrs);
}
else
{
rc = allocate_addr(vid, nic, inherit_attrs);
rc = allocate_addr(PoolObjectSQL::VM, vid, nic, inherit_attrs);
}
//--------------------------------------------------------------------------
@ -659,7 +658,53 @@ int VirtualNetwork::nic_attribute(
nic->replace("SECURITY_GROUPS",
one_util::join(nic_sgs.begin(), nic_sgs.end(), ','));
if (rc == 0 && vrid != -1)
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualNetwork::vrouter_nic_attribute(
VectorAttribute * nic,
int vrid,
const vector<string>& inherit_attrs)
{
int rc = 0;
bool floating;
vector<string>::const_iterator it;
//--------------------------------------------------------------------------
// Set default values from the Virtual Network
//--------------------------------------------------------------------------
nic->replace("NETWORK", name);
nic->replace("NETWORK_ID", oid);
//--------------------------------------------------------------------------
// Get the lease from the Virtual Network
//--------------------------------------------------------------------------
nic->vector_value("FLOATING_IP", floating);
if (floating)
{
string ip = nic->vector_value("IP");
string mac = nic->vector_value("MAC");
if (!ip.empty())
{
rc = allocate_by_ip(PoolObjectSQL::VROUTER, vrid, ip, nic, inherit_attrs);
}
else if (!mac.empty())
{
rc = allocate_by_mac(PoolObjectSQL::VROUTER, vrid, mac, nic, inherit_attrs);
}
else
{
rc = allocate_addr(PoolObjectSQL::VROUTER, vrid, nic, inherit_attrs);
}
}
if (rc == 0)
{
vrouters.add_collection_id(vrid);
}

View File

@ -243,7 +243,6 @@ int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
int nic_id,
int uid,
int vid,
int vrid,
string& error)
{
string network;
@ -269,7 +268,7 @@ int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
return -1;
}
int rc = vnet->nic_attribute(nic, vid, vrid, inherit_attrs);
int rc = vnet->nic_attribute(nic, vid, inherit_attrs);
if ( rc == 0 )
{
@ -292,6 +291,56 @@ int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualNetworkPool::vrouter_nic_attribute(
VectorAttribute * nic,
int uid,
int vrid,
string& error_str)
{
string network;
VirtualNetwork * vnet = 0;
if (!(network = nic->vector_value("NETWORK")).empty())
{
vnet = get_nic_by_name (nic, network, uid, error_str);
}
else if (!(network = nic->vector_value("NETWORK_ID")).empty())
{
vnet = get_nic_by_id(network, error_str);
}
else //Not using a pre-defined network
{
return -2;
}
if (vnet == 0)
{
return -1;
}
int rc = vnet->vrouter_nic_attribute(nic, vrid, inherit_attrs);
if ( rc == 0 )
{
update(vnet);
}
else
{
ostringstream oss;
oss << "Cannot get IP/MAC lease from virtual network " << vnet->get_oid() << ".";
error_str = oss.str();
}
vnet->unlock();
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualNetworkPool::authorize_nic(VectorAttribute * nic,
int uid,
AuthRequest * ar)

View File

@ -15,6 +15,8 @@
/* ------------------------------------------------------------------------ */
#include "VirtualRouter.h"
#include "VirtualNetworkPool.h"
#include "Nebula.h"
/* ************************************************************************ */
/* VirtualRouter :: Constructor/Destructor */
@ -78,15 +80,20 @@ int VirtualRouter::insert(SqlDB *db, string& error_str)
erase_template_attribute("NAME", name);
if ( name.empty() == true )
if ( !PoolObjectSQL::name_is_valid(name, error_str) )
{
oss << "vrouter-" << oid;
name = oss.str();
goto error_name;
}
else if ( name.length() > 128 )
// ------------------------------------------------------------------------
// Get network leases
// ------------------------------------------------------------------------
rc = get_network_leases(error_str);
if ( rc != 0 )
{
error_str = "NAME is too long; max length is 128 chars.";
return -1;
goto error_leases_rollback;
}
// ------------------------------------------------------------------------
@ -96,6 +103,63 @@ int VirtualRouter::insert(SqlDB *db, string& error_str)
rc = insert_replace(db, false, error_str);
return rc;
error_leases_rollback:
release_network_leases();
goto error_common;
error_name:
error_common:
//NebulaLog::log("ONE",Log::ERROR, error_str);
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualRouter::drop(SqlDB * db)
{
int rc;
rc = PoolObjectSQL::drop(db);
if ( rc == 0 )
{
release_network_leases();
}
return rc;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VirtualRouter::get_network_leases(string& estr)
{
int num_nics, rc;
vector<Attribute * > nics;
VirtualNetworkPool * vnpool;
VectorAttribute * nic;
Nebula& nd = Nebula::instance();
vnpool = nd.get_vnpool();
num_nics = obj_template->get("NIC",nics);
for(int i=0; i<num_nics; i++)
{
nic = static_cast<VectorAttribute * >(nics[i]);
rc = vnpool->vrouter_nic_attribute(nic, uid, oid, estr);
if (rc == -1)
{
return -1;
}
}
return 0;
}
/* ------------------------------------------------------------------------ */
@ -264,3 +328,120 @@ int VirtualRouter::from_xml(const string& xml)
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualRouter::release_network_leases()
{
string vnid;
string ip;
int num_nics;
vector<Attribute const * > nics;
num_nics = get_template_attribute("NIC",nics);
for(int i=0; i<num_nics; i++)
{
VectorAttribute const * nic =
dynamic_cast<VectorAttribute const * >(nics[i]);
release_network_leases(nic);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualRouter::release_network_leases(VectorAttribute const * nic)
{
VirtualNetworkPool* vnpool = Nebula::instance().get_vnpool();
VirtualNetwork* vn;
int vnid;
int ar_id;
string mac;
string error_msg;
if ( nic == 0 )
{
return -1;
}
if (nic->vector_value("NETWORK_ID", vnid) != 0)
{
return -1;
}
mac = nic->vector_value("MAC");
vn = vnpool->get(vnid, true);
if ( vn == 0 )
{
return -1;
}
if (nic->vector_value("AR_ID", ar_id) == 0)
{
vn->free_addr(ar_id, PoolObjectSQL::VROUTER, oid, mac);
}
else
{
vn->free_addr(PoolObjectSQL::VROUTER, oid, mac);
}
vnpool->update(vn);
vn->unlock();
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Template * VirtualRouter::get_nics() const
{
Template * tmpl = new Template();
int num_nics;
bool floating;
string ip;
vector<Attribute * > nics;
VectorAttribute * nic;
num_nics = obj_template->get("NIC",nics);
for(int i=0; i<num_nics; i++)
{
nic = static_cast<VectorAttribute * >(nics[i]);
if (nic == 0)
{
continue;
}
nic = nic->clone();
floating = false;
nic->vector_value("FLOATING_IP", floating);
if (floating)
{
// TODO: this is IPv4 only
nic->remove("MAC");
if (nic->vector_value("IP", ip) == 0)
{
nic->remove("IP");
nic->replace("VROUTER_IP", ip);
}
// TODO: remove all other attrs, such as AR, BRIDGE, etc?
}
tmpl->set(nic);
}
return tmpl;
}