From 49f0a571a5663369d21f2abc229dd53973f3f5f1 Mon Sep 17 00:00:00 2001 From: Alejandro Huertas Herrero Date: Thu, 18 Oct 2018 15:20:47 +0200 Subject: [PATCH] F #2490: Add new unregister address range functionality * Modify the IPAM driver * Modify AddressRangePool to call the new action script * Add example dummy script (cherry picked from commit 7e36bc7c749aede6d706f9dcedda816d9931683d) --- include/AddressRange.h | 5 ++ include/IPAMManager.h | 14 +++-- include/IPAMManagerDriver.h | 8 +++ install.sh | 1 + src/ipamm/IPAMManager.cc | 20 +++++++ src/ipamm_mad/one_ipam.rb | 26 +++++---- .../remotes/dummy/unregister_address_range | 54 +++++++++++++++++++ src/vnm/AddressRangePool.cc | 27 ++++++++++ 8 files changed, 142 insertions(+), 13 deletions(-) create mode 100755 src/ipamm_mad/remotes/dummy/unregister_address_range diff --git a/include/AddressRange.h b/include/AddressRange.h index 1a9e440e4a..5a9c27c0f4 100644 --- a/include/AddressRange.h +++ b/include/AddressRange.h @@ -104,6 +104,11 @@ public: return (type & 0x00000008) != 0; } + bool is_ipam() const + { + return !attr->vector_value("IPAM_MAD").empty() && attr->vector_value("IPAM_MAD") != "internal"; + } + // ************************************************************************* // Address Range initialization functions // ************************************************************************* diff --git a/include/IPAMManager.h b/include/IPAMManager.h index 3a6c7bc025..6cc167bbe4 100644 --- a/include/IPAMManager.h +++ b/include/IPAMManager.h @@ -36,10 +36,11 @@ class IPMAction : public ActionRequest public: enum Actions { - REGISTER_ADDRESS_RANGE, /**< Register/Request a new IP network */ - ALLOCATE_ADDRESS, /**< Request a specific IP (or range) */ - GET_ADDRESS, /**< Request any free IP (or range) */ - FREE_ADDRESS /**< Frees a previously requested IP */ + REGISTER_ADDRESS_RANGE, /**< Register/Request a new IP network */ + UNREGISTER_ADDRESS_RANGE, /**< Unregister IP network */ + ALLOCATE_ADDRESS, /**< Request a specific IP (or range) */ + GET_ADDRESS, /**< Request any free IP (or range) */ + FREE_ADDRESS /**< Frees a previously requested IP */ }; IPMAction(Actions a, IPAMRequest *r):ActionRequest(ActionRequest::USER), @@ -187,6 +188,11 @@ private: */ void register_address_range_action(IPAMRequest * ir); + /** + * Unregisters an address range. + */ + void unregister_address_range_action(IPAMRequest * ir); + /** * Requests the IPAM a free address (or range) */ diff --git a/include/IPAMManagerDriver.h b/include/IPAMManagerDriver.h index ba4b1546f6..ce4f549861 100644 --- a/include/IPAMManagerDriver.h +++ b/include/IPAMManagerDriver.h @@ -67,6 +67,14 @@ private: send_message("REGISTER_ADDRESS_RANGE", id, arg); } + /** + * Unregister an AddressRange from the IPAM + */ + void unregister_address_range(int id, const std::string& arg) const + { + send_message("UNREGISTER_ADDRESS_RANGE", id, arg); + } + /** * Get a free address (or range) */ diff --git a/install.sh b/install.sh index 5e588ce6bf..84c6e44045 100755 --- a/install.sh +++ b/install.sh @@ -977,6 +977,7 @@ NETWORK_ETC_FILES="src/vnm_mad/remotes/OpenNebulaNetwork.conf" # IPAM drivers to be installed under $REMOTES_LOCATION/ipam #------------------------------------------------------------------------------- IPAM_DRIVER_DUMMY_SCRIPTS="src/ipamm_mad/remotes/dummy/register_address_range \ + src/ipamm_mad/remotes/dummy/unregister_address_range \ src/ipamm_mad/remotes/dummy/allocate_address \ src/ipamm_mad/remotes/dummy/get_address \ src/ipamm_mad/remotes/dummy/free_address" diff --git a/src/ipamm/IPAMManager.cc b/src/ipamm/IPAMManager.cc index 12293014df..b66daba2d1 100644 --- a/src/ipamm/IPAMManager.cc +++ b/src/ipamm/IPAMManager.cc @@ -89,6 +89,10 @@ void IPAMManager::user_action(const ActionRequest& ar) register_address_range_action(request); break; + case IPMAction::UNREGISTER_ADDRESS_RANGE: + unregister_address_range_action(request); + break; + case IPMAction::ALLOCATE_ADDRESS: allocate_address_action(request); break; @@ -140,6 +144,22 @@ void IPAMManager::register_address_range_action(IPAMRequest * ir) ipammd->register_address_range(ir->id, ir->to_xml64(action_data)); } + +/* -------------------------------------------------------------------------- */ + +void IPAMManager::unregister_address_range_action(IPAMRequest * ir) +{ + std::string action_data; + const IPAMManagerDriver * ipammd = setup_request(ir); + + if (ipammd == 0) + { + return; + } + + ipammd->unregister_address_range(ir->id, ir->to_xml64(action_data)); +} + /* -------------------------------------------------------------------------- */ void IPAMManager::get_address_action(IPAMRequest * ir) diff --git a/src/ipamm_mad/one_ipam.rb b/src/ipamm_mad/one_ipam.rb index 656e322185..ee895635bf 100755 --- a/src/ipamm_mad/one_ipam.rb +++ b/src/ipamm_mad/one_ipam.rb @@ -37,13 +37,13 @@ require 'shellwords' # IPAM Manager driver class IPAMDriver < OpenNebulaDriver - # IPAM Driver Protocol constants ACTION = { - :register_address_range => "REGISTER_ADDRESS_RANGE", - :allocate_address => "ALLOCATE_ADDRESS", - :get_address => "GET_ADDRESS", - :free_address => "FREE_ADDRESS" + :register_address_range => "REGISTER_ADDRESS_RANGE", + :unregister_address_range => "UNREGISTER_ADDRESS_RANGE", + :allocate_address => "ALLOCATE_ADDRESS", + :get_address => "GET_ADDRESS", + :free_address => "FREE_ADDRESS" } # Init the driver @@ -53,10 +53,11 @@ class IPAMDriver < OpenNebulaDriver :threaded => false, :retries => 0, :local_actions => { - ACTION[:register_address_range] => nil, - ACTION[:allocate_address] => nil, - ACTION[:get_address] => nil, - ACTION[:free_address] => nil + ACTION[:register_address_range] => nil, + ACTION[:unregister_address_range] => nil, + ACTION[:allocate_address] => nil, + ACTION[:get_address] => nil, + ACTION[:free_address] => nil } }.merge!(options) @@ -75,6 +76,9 @@ class IPAMDriver < OpenNebulaDriver register_action(ACTION[:register_address_range].to_sym, method("register_address_range")) + register_action(ACTION[:unregister_address_range].to_sym, + method("unregister_address_range")) + register_action(ACTION[:allocate_address].to_sym, method("allocate_address")) @@ -87,6 +91,10 @@ class IPAMDriver < OpenNebulaDriver do_ipam_action(id, :register_address_range, drv_message) end + def unregister_address_range(id, drv_message) + do_ipam_action(id, :unregister_address_range, drv_message) + end + def allocate_address(id, drv_message) do_ipam_action(id, :allocate_address, drv_message) end diff --git a/src/ipamm_mad/remotes/dummy/unregister_address_range b/src/ipamm_mad/remotes/dummy/unregister_address_range new file mode 100755 index 0000000000..0f3df1c738 --- /dev/null +++ b/src/ipamm_mad/remotes/dummy/unregister_address_range @@ -0,0 +1,54 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +############################################################################### +# This script is used to unregister an AddresRange from the IPAM. +# +# The IPAM driver must return 0 if no errors. +# +# Input Arguments: +# $1 - Base64 encoded XML with AR request +# $2 - Request ID +# +# XML format +# +# +# IP4 +# First IP in the network in '.' notation +# First MAC in the network in ':' notation +# Number of IPs in the network +# Base network address +# Network mask +# Default gateway for the network +# DNS servers, a space separated list of servers +# Sets the MTU for the NICs in this network +# for DNS client +# +################################################################################ + +# ----------- Set up the environment to source common tools & conf ------------ + +if [ -z "${ONE_LOCATION}" ]; then + LIB_LOCATION=/usr/lib/one +else + LIB_LOCATION=$ONE_LOCATION/lib +fi + +. $LIB_LOCATION/sh/scripts_common.sh + +exit 0 diff --git a/src/vnm/AddressRangePool.cc b/src/vnm/AddressRangePool.cc index bdc8c97d2b..f924d14482 100644 --- a/src/vnm/AddressRangePool.cc +++ b/src/vnm/AddressRangePool.cc @@ -19,6 +19,12 @@ #include "AddressRangeInternal.h" #include "AddressRangeIPAM.h" +#include "IPAMRequest.h" +#include "IPAMManager.h" + +#include "Nebula.h" +#include "NebulaUtil.h" + using namespace std; AddressRangePool::AddressRangePool():ar_template(false,'=',"AR_POOL"), @@ -196,6 +202,27 @@ int AddressRangePool::rm_ar(unsigned int ar_id, string& error_msg) AddressRange * ar_ptr = it->second; + if(ar_ptr->is_ipam()) + { + IPAMManager * ipamm = Nebula::instance().get_ipamm(); + + std::ostringstream ar_xml; + + ar_ptr->to_xml(ar_xml); + + IPAMRequest ir(ar_xml.str()); + + ipamm->trigger(IPMAction::UNREGISTER_ADDRESS_RANGE, &ir); + + ir.wait(); + + if (ir.result != true) + { + error_msg = ir.message; + return -1; + } + } + ar_pool.erase(it); delete ar_ptr;