From 20a3c258436baebeb32d30eb5b8a8dcf6c8e5053 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 23 May 2014 00:24:14 +0200 Subject: [PATCH] feature #2858: Update ARs. Core, OCA and CLI. Needs to implement attribute removal --- include/AddressRange.h | 8 +++++ include/AddressRangePool.h | 7 +++++ include/RequestManagerVirtualNetwork.h | 23 ++++++++++++++ include/VirtualNetwork.h | 7 +++++ src/cli/onevnet | 19 ++++++++++++ src/oca/ruby/opennebula/virtual_network.rb | 16 ++++++++-- src/rm/RequestManager.cc | 2 ++ src/rm/RequestManagerVirtualNetwork.cc | 1 - src/vnm/AddressRange.cc | 36 ++++++++++++++++++++++ src/vnm/AddressRangePool.cc | 35 +++++++++++++++++++++ src/vnm/VirtualNetwork.cc | 12 ++++++++ 11 files changed, 162 insertions(+), 4 deletions(-) diff --git a/include/AddressRange.h b/include/AddressRange.h index cda667500c..e0c6526a64 100644 --- a/include/AddressRange.h +++ b/include/AddressRange.h @@ -203,6 +203,14 @@ public: return attr->vector_value(name); } + /** + * Updates the Address Range with the attributes provided. The following + * CANNOT be updated: TYPE, SIZE, IP, MAC (plus the internal AR_ID and + * ALLOCATED) + * @param vup the new vector attributes for the address range + */ + void update_attributes(VectorAttribute *vup); + private: /* ---------------------------------------------------------------------- */ /* String to binary conversion functions for different address types */ diff --git a/include/AddressRangePool.h b/include/AddressRangePool.h index 600f3bb64f..cdf81b28a7 100644 --- a/include/AddressRangePool.h +++ b/include/AddressRangePool.h @@ -62,6 +62,13 @@ public: */ int rm_ar(unsigned int ar_id, string& error_msg); + /** + * Updates the given address ranges + * @param ars vector of address ranges as VectorAttributes obtined from + * template in the form AR = [...] + */ + void update_ar(vector ars); + /** * Generate a XML representation of the Address Range Pool * @param sstream where the ARPool is written diff --git a/include/RequestManagerVirtualNetwork.h b/include/RequestManagerVirtualNetwork.h index 1aeb3208fb..918e73397b 100644 --- a/include/RequestManagerVirtualNetwork.h +++ b/include/RequestManagerVirtualNetwork.h @@ -99,6 +99,29 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class VirtualNetworkUpdateAddressRange: public RequestManagerVirtualNetwork +{ +public: + VirtualNetworkUpdateAddressRange(): + RequestManagerVirtualNetwork("VirtualNetworkUpdateAddressRange", + "Updates address ranges to a virtual network"){}; + ~VirtualNetworkUpdateAddressRange(){}; + + int leases_action(VirtualNetwork * vn, + VirtualNetworkTemplate * tmpl, + string& error_str) + { + error_str.clear(); + + vn->update_ar(tmpl); + + return 0; + }; +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class VirtualNetworkHold : public RequestManagerVirtualNetwork { public: diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 180666bdd5..f8a1dbb920 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -72,6 +72,13 @@ public: */ int rm_ar(unsigned int ar_id, string& error_msg); + /** + * Update an address range to the virtual network + * @param ars_tmpl template in the form AR = [AR_ID=...]. The address range + * is specified by the AR_ID attribute. + */ + void update_ar(VirtualNetworkTemplate * ars_tmpl); + /** * Holds a Lease, marking it as used * @param leases template in the form LEASES = [IP=XX]. diff --git a/src/cli/onevnet b/src/cli/onevnet index 4ec03e3f1a..225dd9707c 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -251,6 +251,25 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + update_ar_desc = <<-EOT.unindent + Update Address Range variables. SIZE, IP, MAC and TYPE cannot be updated + EOT + + command :updatear, update_ar_desc, :vnetid, :ar_id, [:file, nil] do + helper.perform_action(args[0],options,"modified") do |obj| + + str = OpenNebulaHelper.update_template(args[0], obj, args[2], + "AR_POOL/AR[AR_ID=#{args[1]}]") + + str[-1]='' + str.gsub!(/AR_ID="\d+"\n/,'') + str.gsub!(/^\s*(#|$)/,'') + str.gsub!(/\n/,',') + + obj.update_ar("AR = [AR_ID=#{args[1]},#{str}]") + end + end + rename_desc = <<-EOT.unindent Renames the Virtual Network EOT diff --git a/src/oca/ruby/opennebula/virtual_network.rb b/src/oca/ruby/opennebula/virtual_network.rb index dfce718701..98a2d9435c 100644 --- a/src/oca/ruby/opennebula/virtual_network.rb +++ b/src/oca/ruby/opennebula/virtual_network.rb @@ -23,13 +23,13 @@ module OpenNebula # Constants and Class Methods ####################################################################### - VN_METHODS = { :info => "vn.info", :allocate => "vn.allocate", :delete => "vn.delete", :add_ar => "vn.add_ar", :rm_ar => "vn.rm_ar", + :update_ar => "vn.update_ar", :chown => "vn.chown", :chmod => "vn.chmod", :update => "vn.update", @@ -109,7 +109,7 @@ module OpenNebula super(VN_METHODS[:delete]) end - # Adds a lease to the VirtualNetwork + # Adds Address Ranges to the VirtualNetwork def add_ar(ar_template) return Error.new('ID not defined') if !@pe_id @@ -119,7 +119,7 @@ module OpenNebula return rc end - # Removes a lease from the VirtualNetwork + # Removes an Address Range from the VirtualNetwork def rm_ar(ar_id) return Error.new('ID not defined') if !@pe_id @@ -129,6 +129,16 @@ module OpenNebula return rc end + # Updates Address Ranges from the VirtualNetwork + def update_ar(ar_template) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(VN_METHODS[:update_ar], @pe_id, ar_template) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # Holds a virtual network address # @param ip [String] address to hold, if contains ":" a MAC address is assumed # @param ar_id [Integer] The address range to hold the lease. If not set diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 9384444c3a..046f59c745 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -278,6 +278,7 @@ void RequestManager::register_xml_methods() // VirtualNetwork Methods xmlrpc_c::methodPtr vn_add_ar(new VirtualNetworkAddAddressRange()); xmlrpc_c::methodPtr vn_rm_ar(new VirtualNetworkRmAddressRange()); + xmlrpc_c::methodPtr vn_update_ar(new VirtualNetworkUpdateAddressRange()); xmlrpc_c::methodPtr vn_hold(new VirtualNetworkHold()); xmlrpc_c::methodPtr vn_release(new VirtualNetworkRelease()); @@ -487,6 +488,7 @@ void RequestManager::register_xml_methods() /* Network related methods*/ RequestManagerRegistry.addMethod("one.vn.add_ar", vn_add_ar); RequestManagerRegistry.addMethod("one.vn.rm_ar", vn_rm_ar); + RequestManagerRegistry.addMethod("one.vn.update_ar", vn_update_ar); RequestManagerRegistry.addMethod("one.vn.hold", vn_hold); RequestManagerRegistry.addMethod("one.vn.release", vn_release); RequestManagerRegistry.addMethod("one.vn.allocate", vn_allocate); diff --git a/src/rm/RequestManagerVirtualNetwork.cc b/src/rm/RequestManagerVirtualNetwork.cc index ad8b7b8bc9..d49afa7942 100644 --- a/src/rm/RequestManagerVirtualNetwork.cc +++ b/src/rm/RequestManagerVirtualNetwork.cc @@ -96,7 +96,6 @@ void VirtualNetworkRmAddressRange:: VirtualNetwork * vn; string error_str; - int rc; if ( basic_authorization(id, att) == false ) { diff --git a/src/vnm/AddressRange.cc b/src/vnm/AddressRange.cc index c225be22b6..8523e3ed11 100644 --- a/src/vnm/AddressRange.cc +++ b/src/vnm/AddressRange.cc @@ -178,6 +178,42 @@ int AddressRange::from_vattr(VectorAttribute *vattr, string& error_msg) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void AddressRange::update_attributes(VectorAttribute *vup) +{ + /* Remove non-update attributes */ + + vup->remove("TYPE"); + + vup->remove("SIZE"); + + vup->remove("MAC"); + + vup->remove("IP"); + + /* Remove internal attributes */ + + vup->remove("AR_ID"); + + vup->remove("ALLOCATED"); + + vup->remove("USED_LEASES"); + + vup->remove("LEASES"); + + /* Copy the rest attributes to the address range */ + + const map new_attrs = vup->value(); + map ::const_iterator it; + + for (it = new_attrs.begin(); it != new_attrs.end(); it++) + { + attr->replace(it->first, it->second); + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRange::from_vattr_db(VectorAttribute *vattr) { string value; diff --git a/src/vnm/AddressRangePool.cc b/src/vnm/AddressRangePool.cc index 9f975f4df7..1f4ce78f20 100644 --- a/src/vnm/AddressRangePool.cc +++ b/src/vnm/AddressRangePool.cc @@ -74,6 +74,41 @@ int AddressRangePool::from_vattr(vector ars, string& error_msg) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void AddressRangePool::update_ar(vector ars) +{ + vector::iterator it; + map::iterator ar_it; + + unsigned int arid; + + for (it = ars.begin(); it != ars.end(); it++) + { + VectorAttribute * va = static_cast(*it); + + if (va == 0) + { + continue; + } + + if (va->vector_value("AR_ID", arid) != 0) + { + continue; + } + + ar_it = ar_pool.find(arid); + + if (ar_it == ar_pool.end()) + { + continue; + } + + ar_it->second->update_attributes(va); + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRangePool::from_xml_node(const xmlNodePtr node) { int rc = ar_template.from_xml_node(node); diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 0288ac899d..1d5db4bae6 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -608,6 +608,18 @@ int VirtualNetwork::add_ar(VirtualNetworkTemplate * ars_tmpl, string& error_msg) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void VirtualNetwork::update_ar(VirtualNetworkTemplate * ars_tmpl) +{ + vector tmp_ars; + + ars_tmpl->get("AR", tmp_ars); + + ar_pool.update_ar(tmp_ars); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int VirtualNetwork::rm_ar(unsigned int ar_id, string& error_msg) { return ar_pool.rm_ar(ar_id, error_msg);