diff --git a/include/Leases.h b/include/Leases.h index 5927f36f14..bb8453e53b 100644 --- a/include/Leases.h +++ b/include/Leases.h @@ -102,6 +102,26 @@ public: virtual int remove_leases(vector& vector_leases, string& error_msg) = 0; + /** + * Holds a Lease, marking it as used + * @param vector_leases vector of VectorAttribute objects. For the + * moment, the vector can only contain one LEASE. + * @param error_msg If the action fails, this message contains + * the reason. + * @return 0 on success + */ + int hold_leases(vector& vector_leases, string& error_msg); + + /** + * Releases a Lease on hold + * @param vector_leases vector of VectorAttribute objects. For the + * moment, the vector can only contain one LEASE. + * @param error_msg If the action fails, this message contains + * the reason. + * @return 0 on success + */ + int free_leases(vector& vector_leases, string& error_msg); + // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- diff --git a/include/RequestManagerVirtualNetwork.h b/include/RequestManagerVirtualNetwork.h index f402499ac2..4a6245754b 100644 --- a/include/RequestManagerVirtualNetwork.h +++ b/include/RequestManagerVirtualNetwork.h @@ -93,6 +93,44 @@ public: } }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualNetworkHold : public RequestManagerVirtualNetwork +{ +public: + VirtualNetworkHold(): + RequestManagerVirtualNetwork("VirtualNetworkHold", + "Holds a virtual network Lease as used"){}; + ~VirtualNetworkHold(){}; + + int leases_action(VirtualNetwork * vn, + VirtualNetworkTemplate * tmpl, + string& error_str) + { + return vn->hold_leases(tmpl, error_str); + } +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualNetworkRelease : public RequestManagerVirtualNetwork +{ +public: + VirtualNetworkRelease(): + RequestManagerVirtualNetwork("VirtualNetworkRelease", + "Releases a virtual network Lease on hold"){}; + ~VirtualNetworkRelease(){}; + + int leases_action(VirtualNetwork * vn, + VirtualNetworkTemplate * tmpl, + string& error_str) + { + return vn->free_leases(tmpl, error_str); + } +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 9146d69f97..6625c260b4 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -85,7 +85,7 @@ public: /** * Adds Leases to the virtual network (Only implemented for FIXED networks) - * @param leases_template template in the form LEASES = [IP=XX, MAC=XX]. + * @param leases template in the form LEASES = [IP=XX, MAC=XX]. * MAC is optional. The template can only contain one LEASE * definition. * @param error_msg If the action fails, this message contains the reason. @@ -96,7 +96,7 @@ public: /** * Removes Leases from the virtual network; if they are not used.(Only * implemented for FIXED networks) - * @param leases_template template in the form LEASES = [IP=XX]. + * @param leases template in the form LEASES = [IP=XX]. * The template can only contain one LEASE definition. * @param error_msg If the action fails, this message contains * the reason. @@ -104,6 +104,25 @@ public: */ int remove_leases(VirtualNetworkTemplate* leases, string& error_msg); + /** + * Holds a Lease, marking it as used + * @param leases template in the form LEASES = [IP=XX]. + * The template can only contain one LEASE definition. + * @param error_msg If the action fails, this message contains the reason. + * @return 0 on success + */ + int hold_leases(VirtualNetworkTemplate * leases, string& error_msg); + + /** + * Releases a Lease on hold + * @param leases template in the form LEASES = [IP=XX]. + * The template can only contain one LEASE definition. + * @param error_msg If the action fails, this message contains + * the reason. + * @return 0 on success + */ + int free_leases(VirtualNetworkTemplate* leases, string& error_msg); + /** * Gets a new lease for a specific VM * @param vid VM identifier diff --git a/src/cli/onevnet b/src/cli/onevnet index 72ab53716a..b2ba672371 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -93,8 +93,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do Adds a lease to the Virtual Network EOT - command :addleases, 'Adds a lease to the Virtual Network', :vnetid, :ip, - [:mac, nil] do + command :addleases, addleases_desc, :vnetid, :ip, [:mac, nil] do helper.perform_action(args[0],options,"lease added") do |vn| vn.addleases(args[1], args[2]) end @@ -110,6 +109,26 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + hold_desc = <<-EOT.unindent + Holds a Virtual Network lease, marking it as used + EOT + + command :hold, hold_desc, :vnetid, :ip do + helper.perform_action(args[0],options,"lease on hold") do |vn| + vn.hold(args[1]) + end + end + + release_desc = <<-EOT.unindent + Releases a Virtual Network lease on hold + EOT + + command :release, release_desc, :vnetid, :ip do + helper.perform_action(args[0],options,"lease released") do |vn| + vn.release(args[1]) + end + end + publish_desc = <<-EOT.unindent Publishes the given Virtual Network. A public Virtual Network can be seen and used by other Users in the Virtual Network's group diff --git a/src/oca/ruby/OpenNebula/VirtualNetwork.rb b/src/oca/ruby/OpenNebula/VirtualNetwork.rb index 7020bac0fc..b932d7cbe8 100644 --- a/src/oca/ruby/OpenNebula/VirtualNetwork.rb +++ b/src/oca/ruby/OpenNebula/VirtualNetwork.rb @@ -32,7 +32,9 @@ module OpenNebula :addleases => "vn.addleases", :rmleases => "vn.rmleases", :chown => "vn.chown", - :update => "vn.update" + :update => "vn.update", + :hold => "vn.hold", + :release => "vn.release" } VN_TYPES=%w{RANGED FIXED} @@ -128,6 +130,32 @@ module OpenNebula return rc end + # Holds a virtual network Lease as used + # @param ip [String] IP to hold + def hold(ip) + return Error.new('ID not defined') if !@pe_id + + lease_template = "LEASES = [ IP = #{ip} ]" + + rc = @client.call(VN_METHODS[:hold], @pe_id, lease_template) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + + # Releases a virtual network Lease on hold + # @param ip [String] IP to release + def release(ip) + return Error.new('ID not defined') if !@pe_id + + lease_template = "LEASES = [ IP = #{ip} ]" + + rc = @client.call(VN_METHODS[:release], @pe_id, lease_template) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # Changes the owner/group # uid:: _Integer_ the new owner id. Set to -1 to leave the current one # gid:: _Integer_ the new group id. Set to -1 to leave the current one diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 6c3ca96d3e..08dd938794 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -246,6 +246,8 @@ void RequestManager::register_xml_methods() // VirtualNetwork Methods xmlrpc_c::methodPtr vn_addleases(new VirtualNetworkAddLeases()); xmlrpc_c::methodPtr vn_rmleases(new VirtualNetworkRemoveLeases()); + xmlrpc_c::methodPtr vn_hold(new VirtualNetworkHold()); + xmlrpc_c::methodPtr vn_release(new VirtualNetworkRelease()); // Update Template Methods xmlrpc_c::methodPtr image_update(new ImageUpdateTemplate()); @@ -357,6 +359,8 @@ void RequestManager::register_xml_methods() /* Network related methods*/ RequestManagerRegistry.addMethod("one.vn.addleases", vn_addleases); RequestManagerRegistry.addMethod("one.vn.rmleases", vn_rmleases); + RequestManagerRegistry.addMethod("one.vn.hold", vn_hold); + RequestManagerRegistry.addMethod("one.vn.release", vn_release); RequestManagerRegistry.addMethod("one.vn.allocate", vn_allocate); RequestManagerRegistry.addMethod("one.vn.publish", vn_publish); RequestManagerRegistry.addMethod("one.vn.update", vn_update); diff --git a/src/rm/RequestManagerVirtualNetwork.cc b/src/rm/RequestManagerVirtualNetwork.cc index af410a025f..b3bb5ed0b8 100644 --- a/src/rm/RequestManagerVirtualNetwork.cc +++ b/src/rm/RequestManagerVirtualNetwork.cc @@ -80,7 +80,7 @@ void RequestManagerVirtualNetwork:: if ( rc < 0 ) { failure_response(INTERNAL, - request_error("Error modifiying network leases",error_str), + request_error("Error modifying network leases",error_str), att); vn->unlock(); diff --git a/src/vnm/Leases.cc b/src/vnm/Leases.cc index fa0eedabb1..c159294625 100644 --- a/src/vnm/Leases.cc +++ b/src/vnm/Leases.cc @@ -386,23 +386,11 @@ int Leases::update(SqlDB * db) bool Leases::check(const string& ip) { - map::iterator it; - unsigned int _ip; Leases::Lease::ip_to_number(ip,_ip); - - it=leases.find(_ip); - - if (it!=leases.end()) - { - return it->second->used; - } - else - { - return false; - } + return check(_ip); } /* -------------------------------------------------------------------------- */ @@ -424,6 +412,95 @@ bool Leases::check(unsigned int ip) } } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Leases::hold_leases(vector& vector_leases, + string& error_msg) +{ + const VectorAttribute * single_attr_lease = 0; + + int rc; + string ip; + string mac; + + if ( vector_leases.size() > 0 ) + { + single_attr_lease = + dynamic_cast(vector_leases[0]); + } + + if ( single_attr_lease == 0 ) + { + error_msg = "Empty lease description."; + return -1; + } + + ip = single_attr_lease->vector_value("IP"); + + if ( check(ip) ) + { + error_msg = "Lease is in use."; + return -1; + } + + rc = set(-1, ip, mac); + + if ( rc != 0 ) + { + error_msg = "Lease is not part of the NET."; + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Leases::free_leases(vector& vector_leases, + string& error_msg) +{ + const VectorAttribute * single_attr_lease = 0; + map::iterator it; + + unsigned int i_ip; + string st_ip; + string mac; + + if ( vector_leases.size() > 0 ) + { + single_attr_lease = + dynamic_cast(vector_leases[0]); + } + + if ( single_attr_lease == 0 ) + { + error_msg = "Empty lease description."; + return -1; + } + + st_ip = single_attr_lease->vector_value("IP"); + + if ( Leases::Lease::ip_to_number(st_ip,i_ip) != 0 ) + { + error_msg = "Wrong Lease format."; + return -1; + } + + it = leases.find(i_ip); + + if ( it == leases.end() || (it->second->used && it->second->vid != -1) ) + { + error_msg = "Lease is not on hold."; + return -1; + } + + release(st_ip); + + return 0; +} + /* ************************************************************************** */ /* Leases :: Misc */ /* ************************************************************************** */ diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 72a833d407..5fa53f2115 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -646,3 +646,29 @@ int VirtualNetwork::remove_leases(VirtualNetworkTemplate * leases_template, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +int VirtualNetwork::hold_leases(VirtualNetworkTemplate * leases_template, + string& error_msg) +{ + vector vector_leases; + + leases_template->get("LEASES", vector_leases); + + return leases->hold_leases(vector_leases, error_msg); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualNetwork::free_leases(VirtualNetworkTemplate * leases_template, + string& error_msg) +{ + vector vector_leases; + + leases_template->get("LEASES", vector_leases); + + return leases->free_leases(vector_leases, error_msg); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */