From b49a2499435cefefd202829954bdfa9e7fba1a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 29 Feb 2012 18:09:47 +0100 Subject: [PATCH] Feature #1112: Associate VNets to Clusters. New VNets are created in the "default" cluster --- include/RequestManagerAllocate.h | 13 ++++++-- include/RequestManagerCluster.h | 40 +++++++++++++++++++++++++ include/RequestManagerDelete.h | 15 +++++++++- include/VirtualNetwork.h | 5 +++- include/VirtualNetworkPool.h | 6 +++- src/cli/one_helper/onecluster_helper.rb | 5 ++++ src/cli/onecluster | 11 +++++++ src/oca/ruby/OpenNebula/Cluster.rb | 39 +++++++++++++++++++++++- src/rm/RequestManager.cc | 2 ++ src/rm/RequestManagerAllocate.cc | 30 +++++++++++++++---- src/vnm/VirtualNetwork.cc | 28 ++++++++++------- src/vnm/VirtualNetworkPool.cc | 5 +++- 12 files changed, 175 insertions(+), 24 deletions(-) diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 53bd5299a1..cc33edf888 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -156,6 +156,7 @@ public: RequestManagerAllocate("VirtualNetworkAllocate", "Allocates a new virtual network", "A:ss", + true, true) { Nebula& nd = Nebula::instance(); @@ -172,11 +173,17 @@ public: return new VirtualNetworkTemplate; }; - int pool_allocate(xmlrpc_c::paramList const& _paramList, + int pool_allocate(xmlrpc_c::paramList const& _paramList, Template * tmpl, - int& id, + int& id, string& error_str, - RequestAttributes& att); + RequestAttributes& att, + int cluster_id, + const string& cluster_name); + + int get_cluster_id(xmlrpc_c::paramList const& paramList); + + int add_to_cluster(Cluster* cluster, int id, string& error_msg); }; /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerCluster.h b/include/RequestManagerCluster.h index c90cb124e4..10215710a5 100644 --- a/include/RequestManagerCluster.h +++ b/include/RequestManagerCluster.h @@ -38,6 +38,7 @@ protected: clpool = nd.get_clpool(); hpool = nd.get_hpool(); dspool = nd.get_dspool(); + vnpool = nd.get_vnpool(); auth_object = PoolObjectSQL::CLUSTER; auth_op = AuthRequest::ADMIN; @@ -50,6 +51,7 @@ protected: ClusterPool * clpool; HostPool * hpool; DatastorePool * dspool; + VirtualNetworkPool * vnpool; /* --------------------------------------------------------------------- */ @@ -145,6 +147,44 @@ public: }; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterAddVNet : public RequestManagerCluster +{ +public: + ClusterAddVNet(): + RequestManagerCluster("ClusterAddVNet", + "Adds a virtual network to the cluster", + "A:sii"){}; + + ~ClusterAddVNet(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att) + { + return add_generic(_paramList, att, vnpool, PoolObjectSQL::NET); + } + + virtual int add_object(Cluster* cluster, int id, string& error_msg) + { + return cluster->add_vnet(id, error_msg); + }; + + virtual int del_object(Cluster* cluster, int id, string& error_msg) + { + return cluster->del_vnet(id, error_msg); + }; + + virtual void get(int oid, bool lock, PoolObjectSQL ** object, Clusterable ** cluster_obj) + { + VirtualNetwork * vnet = vnpool->get(oid, lock); + + *object = static_cast(vnet); + *cluster_obj = static_cast(vnet); + }; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 62e1b5073f..9be4b1e616 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -105,7 +105,8 @@ class VirtualNetworkDelete: public RequestManagerDelete public: VirtualNetworkDelete(): RequestManagerDelete("VirtualNetworkDelete", - "Deletes a virtual network") + "Deletes a virtual network", + true) { Nebula& nd = Nebula::instance(); pool = nd.get_vnpool(); @@ -113,6 +114,18 @@ public: }; ~VirtualNetworkDelete(){}; + + /* -------------------------------------------------------------------- */ + + int get_cluster_id(PoolObjectSQL * object) + { + return static_cast(object)->get_cluster_id(); + }; + + int del_from_cluster(Cluster* cluster, int id, string& error_msg) + { + return cluster->del_vnet(id, error_msg); + }; }; /* ------------------------------------------------------------------------- */ diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 6fa7df2024..161bdd77b8 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -21,6 +21,7 @@ #include "PoolSQL.h" #include "Leases.h" #include "VirtualNetworkTemplate.h" +#include "Clusterable.h" #include #include @@ -39,7 +40,7 @@ using namespace std; * leases. One lease is formed by one IP and one MAC address. * MAC address are derived from IP addresses. */ -class VirtualNetwork : public PoolObjectSQL +class VirtualNetwork : public PoolObjectSQL, public Clusterable { public: @@ -287,6 +288,8 @@ private: int gid, const string& _uname, const string& _gname, + int _cluster_id, + const string& _cluster_name, VirtualNetworkTemplate * _vn_template = 0); ~VirtualNetwork(); diff --git a/include/VirtualNetworkPool.h b/include/VirtualNetworkPool.h index 431f55c49d..9c0446c018 100644 --- a/include/VirtualNetworkPool.h +++ b/include/VirtualNetworkPool.h @@ -45,6 +45,8 @@ public: * @param gid the id of the group this object is assigned to * @param vn_template a VirtualNetworkTemplate describing the VNET * @param oid the id assigned to the VM (output) + * @param cluster_id the id of the cluster this VNET will belong to + * @param cluster_name the name of the cluster this VNET will belong to * @param error_str Returns the error reason, if any * @return oid on success, -1 error */ @@ -55,6 +57,8 @@ public: const string& gname, VirtualNetworkTemplate * vn_template, int * oid, + int cluster_id, + const string& cluster_name, string& error_str); /** @@ -163,7 +167,7 @@ private: */ PoolObjectSQL * create() { - return new VirtualNetwork(-1,-1,"","",0); + return new VirtualNetwork(-1,-1,"","",-1,"",0); }; /** diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index bc72c25193..d709b4808c 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -78,5 +78,10 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper puts "%-15s" % [id] end + puts + CLIHelper.print_header("%-15s" % ["VNETS"]) + cluster.vnet_ids.each do |id| + puts "%-15s" % [id] + end end end diff --git a/src/cli/onecluster b/src/cli/onecluster index f74837f06f..7b4bd58df4 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -117,4 +117,15 @@ cmd=CommandParser::CmdParser.new(ARGV) do cluster.adddatastore(args[1].to_i) end end + + addvnet_desc = <<-EOT.unindent + Adds a Virtual Network to the given Cluster + EOT + + # TODO: allow the second param to be [:range, :vnetid_list] + command :addvnet, addvnet_desc,:clusterid, :vnetid do + helper.perform_actions(args[0],options,"updated") do |cluster| + cluster.addvnet(args[1].to_i) + end + end end diff --git a/src/oca/ruby/OpenNebula/Cluster.rb b/src/oca/ruby/OpenNebula/Cluster.rb index 70888465b4..1190594d24 100644 --- a/src/oca/ruby/OpenNebula/Cluster.rb +++ b/src/oca/ruby/OpenNebula/Cluster.rb @@ -28,7 +28,8 @@ module OpenNebula :allocate => "cluster.allocate", :delete => "cluster.delete", :addhost => "cluster.addhost", - :adddatastore => "cluster.adddatastore" + :adddatastore => "cluster.adddatastore", + :addvnet => "cluster.addvnet" } # Creates a Cluster description with just its identifier @@ -100,6 +101,19 @@ module OpenNebula return rc end + # Adds a VNet to this Cluster + # @param vnet_id [Integer] VNet ID + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def addvnet(vnet_id) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(CLUSTER_METHODS[:addvnet], @pe_id, vnet_id) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- @@ -149,5 +163,28 @@ module OpenNebula return array end + + # Returns whether or not the vnet with 'id' is part of this cluster + # @param id [Integer] vnet ID + # @return [Boolean] true if found + def contains_vnet(id) + #This doesn't work in ruby 1.8.5 + #return self["HOSTS/ID[.=#{uid}]"] != nil + + id_array = retrieve_elements('VNETS/ID') + return id_array != nil && id_array.include?(id.to_s) + end + + # Returns an array with the numeric vnet ids + # @return [Array] + def vnet_ids + array = Array.new + + self.each("VNETS/ID") do |id| + array << id.text.to_i + end + + return array + end end end diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 81122d3dfd..83f22f7965 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -328,6 +328,7 @@ void RequestManager::register_xml_methods() // Cluster Methods xmlrpc_c::methodPtr cluster_addhost(new ClusterAddHost()); xmlrpc_c::methodPtr cluster_addds(new ClusterAddDatastore()); + xmlrpc_c::methodPtr cluster_addvnet(new ClusterAddVNet()); /* VM related methods */ RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); @@ -424,6 +425,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost); RequestManagerRegistry.addMethod("one.cluster.adddatastore", cluster_addds); + RequestManagerRegistry.addMethod("one.cluster.addvnet", cluster_addvnet); RequestManagerRegistry.addMethod("one.clusterpool.info",clusterpool_info); }; diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index d23dc5af5f..5e43f72567 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -218,17 +218,35 @@ int VirtualMachineAllocate::pool_allocate(xmlrpc_c::paramList const& paramList, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualNetworkAllocate::pool_allocate(xmlrpc_c::paramList const& _paramList, - Template * tmpl, - int& id, - string& error_str, - RequestAttributes& att) +int VirtualNetworkAllocate::pool_allocate( + xmlrpc_c::paramList const& paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att, + int cluster_id, + const string& cluster_name) { VirtualNetworkPool * vpool = static_cast(pool); VirtualNetworkTemplate * vtmpl=static_cast(tmpl); return vpool->allocate(att.uid, att.gid, att.uname, att.gname, vtmpl, &id, - error_str); + cluster_id, cluster_name, error_str); +} + +/* -------------------------------------------------------------------------- */ + +int VirtualNetworkAllocate::get_cluster_id(xmlrpc_c::paramList const& paramList) +{ + return ClusterPool::DEFAULT_CLUSTER_ID; +} + +/* -------------------------------------------------------------------------- */ + +int VirtualNetworkAllocate::add_to_cluster( + Cluster* cluster, int id, string& error_msg) +{ + return cluster->add_vnet(id, error_msg); } /* -------------------------------------------------------------------------- */ diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 38a8366746..81faa2928c 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -35,8 +35,11 @@ VirtualNetwork::VirtualNetwork(int _uid, int _gid, const string& _uname, const string& _gname, + int _cluster_id, + const string& _cluster_name, VirtualNetworkTemplate * _vn_template): PoolObjectSQL(-1,NET,"",_uid,_gid,_uname,_gname,table), + Clusterable(_cluster_id, _cluster_name), bridge(""), type(UNINITIALIZED), leases(0) @@ -474,16 +477,18 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const os << "" << - "" << oid << "" << - "" << uid << "" << - "" << gid << "" << - "" << uname << "" << - "" << gname << "" << - "" << name << "" << - perms_to_xml(perm_str) << - "" << type << "" << - "" << bridge << ""<< - "" << vlan << ""; + "" << oid << "" << + "" << uid << "" << + "" << gid << "" << + "" << uname << "" << + "" << gname << "" << + "" << name << "" << + perms_to_xml(perm_str) << + "" << cluster_id << "" << + "" << cluster << "" << + "" << type << "" << + "" << bridge << ""<< + "" << vlan << ""; if (!phydev.empty()) { @@ -566,6 +571,9 @@ int VirtualNetwork::from_xml(const string &xml_str) rc += xpath(bridge, "/VNET/BRIDGE", "not_found"); rc += xpath(vlan, "/VNET/VLAN", 0); + rc += xpath(cluster_id, "/VNET/CLUSTER_ID", -1); + rc += xpath(cluster, "/VNET/CLUSTER", "not_found"); + // Permissions rc += perms_from_xml(); diff --git a/src/vnm/VirtualNetworkPool.cc b/src/vnm/VirtualNetworkPool.cc index 123a8882bd..348863b813 100644 --- a/src/vnm/VirtualNetworkPool.cc +++ b/src/vnm/VirtualNetworkPool.cc @@ -78,6 +78,8 @@ int VirtualNetworkPool::allocate ( const string& gname, VirtualNetworkTemplate * vn_template, int * oid, + int cluster_id, + const string& cluster_name, string& error_str) { VirtualNetwork * vn; @@ -85,7 +87,8 @@ int VirtualNetworkPool::allocate ( string name; ostringstream oss; - vn = new VirtualNetwork(uid, gid, uname, gname, vn_template); + vn = new VirtualNetwork(uid, gid, uname, gname, + cluster_id, cluster_name, vn_template); // Check name vn->get_template_attribute("NAME", name);