diff --git a/SConstruct b/SConstruct index bf600f480b..7b33c8c1bc 100644 --- a/SConstruct +++ b/SConstruct @@ -83,6 +83,7 @@ main_env.Append(LIBPATH=[ cwd+'/src/zone', cwd+'/src/client', cwd+'/src/secgroup', + cwd+'/src/vdc', ]) # Compile flags @@ -239,6 +240,7 @@ build_scripts=[ 'src/document/SConstruct', 'src/zone/SConstruct', 'src/secgroup/SConstruct', + 'src/vdc/SConstruct', 'share/man/SConstruct', 'src/sunstone/locale/languages/SConstruct', 'share/rubygems/SConstruct', diff --git a/include/Nebula.h b/include/Nebula.h index 444310e55a..e02328c90b 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -33,6 +33,7 @@ #include "DocumentPool.h" #include "ZonePool.h" #include "SecurityGroupPool.h" +#include "VdcPool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -130,6 +131,11 @@ public: return secgrouppool; }; + VdcPool * get_vdcpool() + { + return vdcpool; + }; + // -------------------------------------------------------------- // Manager Accessors // -------------------------------------------------------------- @@ -652,7 +658,7 @@ private: "/DEFAULT_GROUP_QUOTAS/VM_QUOTA"), system_db(0), db(0), vmpool(0), hpool(0), vnpool(0), upool(0), ipool(0), gpool(0), tpool(0), - dspool(0), clpool(0), docpool(0), zonepool(0), secgrouppool(0), + dspool(0), clpool(0), docpool(0), zonepool(0), secgrouppool(0), vdcpool(0), lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0), aclm(0), imagem(0) { @@ -701,6 +707,7 @@ private: delete docpool; delete zonepool; delete secgrouppool; + delete vdcpool; delete vmm; delete lcm; delete im; @@ -779,6 +786,7 @@ private: DocumentPool * docpool; ZonePool * zonepool; SecurityGroupPool * secgrouppool; + VdcPool * vdcpool; // --------------------------------------------------------------- // Nebula Managers diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index ccb1fc899f..983a8af143 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -61,7 +61,8 @@ public: CLUSTER = 0x0000200000000000LL, DOCUMENT = 0x0000400000000000LL, ZONE = 0x0000800000000000LL, - SECGROUP = 0x0001000000000000LL + SECGROUP = 0x0001000000000000LL, + VDC = 0x0002000000000000LL }; static string type_to_str(ObjectType ob) @@ -81,6 +82,7 @@ public: case DOCUMENT: return "DOCUMENT" ; break; case ZONE: return "ZONE" ; break; case SECGROUP: return "SECGROUP" ; break; + case VDC: return "VDC" ; break; default: return ""; } }; diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 23abd40fdf..d0cfc8da90 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -542,6 +542,38 @@ public: RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VdcAllocate : public RequestManagerAllocate +{ +public: + VdcAllocate(): + RequestManagerAllocate("VdcAllocate", + "Allocates a new VDC", + "A:ss", + true) + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vdcpool(); + auth_object = PoolObjectSQL::VDC; + }; + + ~VdcAllocate(){}; + + /* --------------------------------------------------------------------- */ + + Template * get_object_template() + { + return new Template; + }; + + int pool_allocate(xmlrpc_c::paramList const& _paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att); +}; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index d462d82d61..4ab2f7c8f4 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -336,6 +336,26 @@ public: int drop(int oid, PoolObjectSQL * object, string& error_msg); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VdcDelete: public RequestManagerDelete +{ +public: + VdcDelete(): + RequestManagerDelete("VdcDelete", "Deletes a VDC") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vdcpool(); + auth_object = PoolObjectSQL::VDC; + auth_op = AuthRequest::ADMIN; + }; + + ~VdcDelete(){}; + + int drop(int oid, PoolObjectSQL * object, string& error_msg); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerInfo.h b/include/RequestManagerInfo.h index 62fc53f19c..e6346d216c 100644 --- a/include/RequestManagerInfo.h +++ b/include/RequestManagerInfo.h @@ -295,6 +295,24 @@ public: ~SecurityGroupInfo(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VdcInfo: public RequestManagerInfo +{ +public: + VdcInfo(): + RequestManagerInfo("VdcInfo", + "Returns VDC information") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vdcpool(); + auth_object = PoolObjectSQL::VDC; + }; + + ~VdcInfo(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerPoolInfoFilter.h b/include/RequestManagerPoolInfoFilter.h index 55369608eb..af26267325 100644 --- a/include/RequestManagerPoolInfoFilter.h +++ b/include/RequestManagerPoolInfoFilter.h @@ -470,6 +470,30 @@ public: ~SecurityGroupPoolInfo(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VdcPoolInfo : public RequestManagerPoolInfoFilter +{ +public: + VdcPoolInfo(): + RequestManagerPoolInfoFilter("VdcPoolInfo", + "Returns the VDC pool", + "A:s") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vdcpool(); + auth_object = PoolObjectSQL::VDC; + }; + + ~VdcPoolInfo(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerRename.h b/include/RequestManagerRename.h index 7e25b1b110..36722e3d60 100644 --- a/include/RequestManagerRename.h +++ b/include/RequestManagerRename.h @@ -317,6 +317,23 @@ public: }; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VdcRename : public RequestManagerRename +{ +public: + VdcRename(): + RequestManagerRename("VdcRename", "Renames a VDC") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vdcpool(); + auth_object = PoolObjectSQL::VDC; + }; + + ~VdcRename(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerUpdateTemplate.h b/include/RequestManagerUpdateTemplate.h index f6d509dfcc..d646f64ce7 100644 --- a/include/RequestManagerUpdateTemplate.h +++ b/include/RequestManagerUpdateTemplate.h @@ -268,6 +268,24 @@ public: ~SecurityGroupUpdateTemplate(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VdcUpdateTemplate : public RequestManagerUpdateTemplate +{ +public: + VdcUpdateTemplate(): + RequestManagerUpdateTemplate("VdcUpdateTemplate", + "Updates a VDC template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vdcpool(); + auth_object = PoolObjectSQL::VDC; + }; + + ~VdcUpdateTemplate(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/Vdc.h b/include/Vdc.h new file mode 100644 index 0000000000..5f7c5a1dcf --- /dev/null +++ b/include/Vdc.h @@ -0,0 +1,120 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------*/ + +#ifndef VDC_H_ +#define VDC_H_ + +#include "PoolObjectSQL.h" +#include "NebulaLog.h" + +using namespace std; + +/** + * The Vdc class. + */ +class Vdc : public PoolObjectSQL +{ +public: + + /** + * Function to print the Vdc object into a string in XML format + * @param xml the resulting XML string + * @return a reference to the generated string + */ + string& to_xml(string& xml) const; + + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str); + +private: + + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + + friend class VdcPool; + + // ************************************************************************* + // Constructor + // ************************************************************************* + + Vdc(int id, Template* vdc_template); + + ~Vdc(); + + // ************************************************************************* + // DataBase implementation (Private) + // ************************************************************************* + + static const char * db_names; + + static const char * db_bootstrap; + + static const char * table; + + /** + * Execute an INSERT or REPLACE Sql query. + * @param db The SQL DB + * @param replace Execute an INSERT or a REPLACE + * @param error_str Returns the error reason, if any + * @return 0 one success + */ + int insert_replace(SqlDB *db, bool replace, string& error_str); + + /** + * Bootstraps the database table(s) associated to the Vdc + * @return 0 on success + */ + static int bootstrap(SqlDB * db) + { + ostringstream oss(Vdc::db_bootstrap); + + return db->exec(oss); + }; + + /** + * Writes the Vdc in the database. + * @param db pointer to the db + * @return 0 on success + */ + int insert(SqlDB *db, string& error_str); + + /** + * Writes/updates the Vdc's data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + int update(SqlDB *db) + { + string error_str; + return insert_replace(db, true, error_str); + } + + /** + * Factory method for Vdc templates + */ + Template * get_new_template() const + { + return new Template; + } +}; + +#endif /*VDC_H_*/ diff --git a/include/VdcPool.h b/include/VdcPool.h new file mode 100644 index 0000000000..d583df8055 --- /dev/null +++ b/include/VdcPool.h @@ -0,0 +1,141 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#ifndef VDC_POOL_H_ +#define VDC_POOL_H_ + +#include "PoolSQL.h" +#include "Vdc.h" + +using namespace std; + +class VdcPool : public PoolSQL +{ +public: + VdcPool(SqlDB * db, + bool is_federation_slave); + + ~VdcPool(){}; + + /* ---------------------------------------------------------------------- */ + /* Methods for DB management */ + /* ---------------------------------------------------------------------- */ + + /** + * Allocates a new Vdc, writing it in the pool database. No memory is + * allocated for the object. + * @param vdc_template a Template object + * @param oid the id assigned to the Vdc + * @param error_str Returns the error reason, if any + * + * @return the oid assigned to the object, -1 in case of failure + */ + int allocate(Template * vdc_template, + int * oid, + string& error_str); + + /** + * Function to get a Vdc from the pool, if the object is not in memory + * it is loaded from the DB + * @param oid Vdc unique id + * @param lock locks the Vdc mutex + * @return a pointer to the Vdc, 0 if the Vdc could not be loaded + */ + Vdc * get(int oid, bool lock) + { + return static_cast(PoolSQL::get(oid,lock)); + }; + + /** + * Gets an object from the pool (if needed the object is loaded from the + * database). + * @param name of the object + * @param lock locks the object if true + * + * @return a pointer to the object, 0 in case of failure + */ + Vdc * get(const string& name, bool lock) + { + // The owner is set to -1, because it is not used in the key() method + return static_cast(PoolSQL::get(name,-1,lock)); + }; + + /** + * Generate an index key for the object + * @param name of the object + * @param uid owner of the object, only used if needed + * + * @return the key, a string + */ + string key(const string& name, int uid) + { + // Name is enough key because Vdcs can't repeat names. + return name; + }; + + /** Update a particular Vdc + * @param vdc pointer to Vdc + * @return 0 on success + */ + int update(Vdc * vdc); + + /** + * Drops the Vdc from the data base. The object mutex SHOULD be + * locked. + * @param objsql a pointer to a Vdc object + * @param error_msg Error reason, if any + * @return 0 on success, + * -1 DB error, + * -2 object is a default Vdc (ID < 100) + */ + int drop(PoolObjectSQL * objsql, string& error_msg); + + /** + * Bootstraps the database table(s) associated to the Vdc pool + * @return 0 on success + */ + static int bootstrap(SqlDB * _db) + { + return Vdc::bootstrap(_db); + }; + + /** + * Dumps the Vdc pool in XML format. A filter can be also added to the + * query + * @param oss the output stream to dump the pool contents + * @param where filter for the objects, defaults to all + * @param limit parameters used for pagination + * + * @return 0 on success + */ + int dump(ostringstream& oss, const string& where, const string& limit) + { + return PoolSQL::dump(oss, "VDC_POOL", Vdc::table, where, limit); + }; + +private: + + /** + * Factory method to produce objects + * @return a pointer to the new object + */ + PoolObjectSQL * create() + { + return new Vdc(-1,0); + }; +}; + +#endif /*VDC_POOL_H_*/ diff --git a/install.sh b/install.sh index b35f67b6f7..ce0d32dc48 100755 --- a/install.sh +++ b/install.sh @@ -607,6 +607,7 @@ BIN_FILES="src/nebula/oned \ src/cli/oneflow \ src/cli/oneflow-template \ src/cli/onesecgroup \ + src/cli/onevdc \ src/cli/onevcenter \ src/onedb/onedb \ src/mad/utils/tty_expect \ @@ -1286,6 +1287,7 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/opennebula/acl_pool.rb \ src/oca/ruby/opennebula/host.rb \ src/oca/ruby/opennebula/image_pool.rb \ src/oca/ruby/opennebula/image.rb \ + src/oca/ruby/opennebula/oneflow_client.rb \ src/oca/ruby/opennebula/pool_element.rb \ src/oca/ruby/opennebula/pool.rb \ src/oca/ruby/opennebula/security_group_pool.rb \ @@ -1295,8 +1297,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/opennebula/acl_pool.rb \ src/oca/ruby/opennebula/template.rb \ src/oca/ruby/opennebula/user_pool.rb \ src/oca/ruby/opennebula/user.rb \ - src/oca/ruby/opennebula/zone_pool.rb \ - src/oca/ruby/opennebula/zone.rb \ + src/oca/ruby/opennebula/vdc_pool.rb \ + src/oca/ruby/opennebula/vdc.rb \ src/oca/ruby/opennebula/virtual_machine_pool.rb \ src/oca/ruby/opennebula/virtual_machine.rb \ src/oca/ruby/opennebula/virtual_network_pool.rb \ @@ -1304,7 +1306,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/opennebula/acl_pool.rb \ src/oca/ruby/opennebula/xml_element.rb \ src/oca/ruby/opennebula/xml_pool.rb \ src/oca/ruby/opennebula/xml_utils.rb \ - src/oca/ruby/opennebula/oneflow_client.rb" + src/oca/ruby/opennebula/zone_pool.rb \ + src/oca/ruby/opennebula/zone.rb" #------------------------------------------------------------------------------- # Common Cloud Files @@ -1452,6 +1455,7 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \ src/cli/one_helper/onedatastore_helper.rb \ src/cli/one_helper/onecluster_helper.rb \ src/cli/one_helper/onezone_helper.rb \ + src/cli/one_helper/onevdc_helper.rb \ src/cli/one_helper/oneacct_helper.rb \ src/cli/one_helper/onesecgroup_helper.rb" @@ -1470,7 +1474,8 @@ CLI_BIN_FILES="src/cli/onevm \ src/cli/oneflow-template \ src/cli/oneacct \ src/cli/onesecgroup \ - src/cli/oneshowback" + src/cli/oneshowback \ + src/cli/onevdc" CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ src/cli/etc/onehost.yaml \ @@ -1485,7 +1490,8 @@ CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ src/cli/etc/onezone.yaml \ src/cli/etc/oneacct.yaml \ src/cli/etc/onesecgroup.yaml \ - src/cli/etc/oneshowback.yaml" + src/cli/etc/oneshowback.yaml \ + src/cli/etc/onevdc.yaml" #----------------------------------------------------------------------------- # Sunstone files @@ -1866,6 +1872,7 @@ MAN_FILES="share/man/oneacct.1.gz \ share/man/oneflow.1.gz \ share/man/oneflow-template.1.gz \ share/man/onesecgroup.1.gz \ + share/man/onevdc.1.gz \ share/man/econe-allocate-address.1.gz \ share/man/econe-associate-address.1.gz \ share/man/econe-attach-volume.1.gz \ diff --git a/share/man/SConstruct b/share/man/SConstruct index 5e2a0251c5..5426646aac 100644 --- a/share/man/SConstruct +++ b/share/man/SConstruct @@ -66,6 +66,9 @@ env.Man('onevcenter') # TODO #env.Man('onesecgroup') +# TODO +#env.Man('onevdc') + env.Man('oneflow') env.Man('oneflow-template') diff --git a/src/acl/AclRule.cc b/src/acl/AclRule.cc index bfe31c0e7f..c6733e772f 100644 --- a/src/acl/AclRule.cc +++ b/src/acl/AclRule.cc @@ -28,7 +28,7 @@ const long long AclRule::CLUSTER_ID = 0x0000000800000000LL; const long long AclRule::NONE_ID = 0x1000000000000000LL; -const int AclRule::num_pool_objects = 12; +const int AclRule::num_pool_objects = 13; const PoolObjectSQL::ObjectType AclRule::pool_objects[] = { PoolObjectSQL::VM, PoolObjectSQL::HOST, @@ -41,7 +41,8 @@ const PoolObjectSQL::ObjectType AclRule::pool_objects[] = { PoolObjectSQL::CLUSTER, PoolObjectSQL::DOCUMENT, PoolObjectSQL::ZONE, - PoolObjectSQL::SECGROUP + PoolObjectSQL::SECGROUP, + PoolObjectSQL::VDC }; const int AclRule::num_auth_operations = 4; @@ -56,15 +57,15 @@ const long long AclRule::INVALID_CLUSTER_OBJECTS = PoolObjectSQL::VM | PoolObjectSQL::IMAGE | PoolObjectSQL::USER | PoolObjectSQL::TEMPLATE | PoolObjectSQL::GROUP | PoolObjectSQL::ACL | PoolObjectSQL::CLUSTER | PoolObjectSQL::DOCUMENT | PoolObjectSQL::ZONE | - PoolObjectSQL::SECGROUP; + PoolObjectSQL::SECGROUP | PoolObjectSQL::VDC; const long long AclRule::INVALID_GROUP_OBJECTS = PoolObjectSQL::HOST | PoolObjectSQL::GROUP | PoolObjectSQL::CLUSTER | - PoolObjectSQL::ZONE; + PoolObjectSQL::ZONE | PoolObjectSQL::VDC; const long long AclRule::FEDERATED_OBJECTS = PoolObjectSQL::USER | PoolObjectSQL::GROUP | PoolObjectSQL::ZONE | - PoolObjectSQL::ACL; + PoolObjectSQL::ACL | PoolObjectSQL::VDC; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -183,8 +184,9 @@ bool AclRule::malformed(string& error_str) const oss << "[resource] GROUP(@) selector cannot be applied to " << PoolObjectSQL::type_to_str(PoolObjectSQL::HOST) << ", " << PoolObjectSQL::type_to_str(PoolObjectSQL::GROUP) << ", " - << PoolObjectSQL::type_to_str(PoolObjectSQL::CLUSTER) << " or " - << PoolObjectSQL::type_to_str(PoolObjectSQL::ZONE) << " types"; + << PoolObjectSQL::type_to_str(PoolObjectSQL::CLUSTER) << ", " + << PoolObjectSQL::type_to_str(PoolObjectSQL::ZONE) << " or " + << PoolObjectSQL::type_to_str(PoolObjectSQL::VDC) << " types"; } if ( (resource & 0xF00000000LL) == 0 ) diff --git a/src/cli/etc/onevdc.yaml b/src/cli/etc/onevdc.yaml new file mode 100644 index 0000000000..fb0d735148 --- /dev/null +++ b/src/cli/etc/onevdc.yaml @@ -0,0 +1,13 @@ +--- +:ID: + :desc: ONE identifier for the VDC + :size: 5 + +:NAME: + :desc: Name of the VDC + :size: 25 + :left: true + +:default: +- :ID +- :NAME \ No newline at end of file diff --git a/src/cli/one_helper/onevdc_helper.rb b/src/cli/one_helper/onevdc_helper.rb new file mode 100644 index 0000000000..e9c768d530 --- /dev/null +++ b/src/cli/one_helper/onevdc_helper.rb @@ -0,0 +1,74 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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. # +#--------------------------------------------------------------------------- # + +require 'one_helper' + +class OneVdcHelper < OpenNebulaHelper::OneHelper + + def self.rname + "VDC" + end + + def self.conf_file + "onevdc.yaml" + end + + def format_pool(options) + config_file = self.class.table_conf + + table = CLIHelper::ShowTable.new(config_file, self) do + column :ID, "ONE identifier for the VDC", :size=>5 do |d| + d["ID"] + end + + column :NAME, "Name of the VDC", :left, :size=>25 do |d| + d["NAME"] + end + + default :ID, :NAME + end + + table + end + + private + + def factory(id=nil) + if id + OpenNebula::Vdc.new_with_id(id, @client) + else + xml=OpenNebula::Vdc.build_xml + OpenNebula::Vdc.new(xml, @client) + end + end + + def factory_pool(user_flag=-2) + OpenNebula::VdcPool.new(@client) + end + + def format_resource(vdc, options = {}) + str="%-18s: %-20s" + str_h1="%-80s" + + CLIHelper.print_header(str_h1 % "VDC #{vdc['ID']} INFORMATION") + puts str % ["ID", vdc.id.to_s] + puts str % ["NAME", vdc.name] + puts + + CLIHelper.print_header(str_h1 % "VDC TEMPLATE", false) + puts vdc.template_str + end +end diff --git a/src/cli/onevdc b/src/cli/onevdc new file mode 100755 index 0000000000..3610071eb2 --- /dev/null +++ b/src/cli/onevdc @@ -0,0 +1,137 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" +end + +$: << RUBY_LIB_LOCATION +$: << RUBY_LIB_LOCATION+"/cli" + +require 'command_parser' +require 'one_helper/onevdc_helper' + +cmd=CommandParser::CmdParser.new(ARGV) do + usage "`onevdc` [] []" + version OpenNebulaHelper::ONE_VERSION + + helper = OneVdcHelper.new + + before_proc do + helper.set_client(options) + end + + ######################################################################## + # Global Options + ######################################################################## + set :option, CommandParser::OPTIONS+OpenNebulaHelper::CLIENT_OPTIONS + + list_options = CLIHelper::OPTIONS + list_options << OpenNebulaHelper::XML + list_options << OpenNebulaHelper::NUMERIC + list_options << OpenNebulaHelper::DESCRIBE + + ######################################################################## + # Formatters for arguments + ######################################################################## + set :format, :vdcid, OneVdcHelper.to_id_desc do |arg| + helper.to_id(arg) + end + + set :format, :vdcid_list, OneVdcHelper.list_to_id_desc do |arg| + helper.list_to_id(arg) + end + + ######################################################################## + # Commands + ######################################################################## + + create_desc = <<-EOT.unindent + Creates a new VDC + EOT + + command :create, create_desc, :file do + helper.create_resource(options) do |vdc| + begin + template = File.read(args[0]) + vdc.allocate(template) + rescue => e + STDERR.puts e.message + exit -1 + end + end + end + + rename_desc = <<-EOT.unindent + Renames the VDC + EOT + + command :rename, rename_desc, :vdcid, :name do + helper.perform_action(args[0],options,"renamed") do |o| + o.rename(args[1]) + end + end + + update_desc = <<-EOT.unindent + Update the template contents. If a path is not provided the editor will + be launched to modify the current content. + EOT + + command :update, update_desc, :vdcid, [:file, nil], + :options=>OpenNebulaHelper::APPEND do + helper.perform_action(args[0],options,"modified") do |obj| + if options[:append] + str = OpenNebulaHelper.append_template(args[0], obj, args[1]) + else + str = OpenNebulaHelper.update_template(args[0], obj, args[1]) + end + + obj.update(str, options[:append]) + end + end + + delete_desc = <<-EOT.unindent + Deletes the given VDC + EOT + + command :delete, delete_desc, [:range, :vdcid_list] do + helper.perform_actions(args[0],options,"deleted") do |obj| + obj.delete + end + end + + list_desc = <<-EOT.unindent + Lists VDCs in the pool + EOT + + command :list, list_desc, :options=>list_options do + helper.list_pool(options) + end + + show_desc = <<-EOT.unindent + Shows information for the given VDC + EOT + + command :show, show_desc,:vdcid, :options=>OpenNebulaHelper::XML do + helper.show_resource(args[0],options) + end +end diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 41839fd9d4..beea8eaf19 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -367,6 +367,7 @@ void Nebula::start(bool bootstrap_only) rc += UserPool::bootstrap(db); rc += AclManager::bootstrap(db); rc += ZonePool::bootstrap(db); + rc += VdcPool::bootstrap(db); // Create the system tables only if bootstrap went well if ( rc == 0 ) @@ -484,6 +485,7 @@ void Nebula::start(bool bootstrap_only) clpool = new ClusterPool(db); docpool = new DocumentPool(db); zonepool= new ZonePool(db, is_federation_slave()); + vdcpool = new VdcPool(db, is_federation_slave()); nebula_configuration->get("VM_HOOK", vm_hooks); nebula_configuration->get("HOST_HOOK", host_hooks); diff --git a/src/nebula/SConstruct b/src/nebula/SConstruct index 9dfb6a00d5..569873de07 100644 --- a/src/nebula/SConstruct +++ b/src/nebula/SConstruct @@ -63,6 +63,7 @@ env.Prepend(LIBS=[ 'nebula_client', 'nebula_xml', 'nebula_secgroup', + 'nebula_vdc', 'crypto', 'xml2' ]) diff --git a/src/oca/ruby/opennebula.rb b/src/oca/ruby/opennebula.rb index 12ce1b756a..08296a8897 100644 --- a/src/oca/ruby/opennebula.rb +++ b/src/oca/ruby/opennebula.rb @@ -53,6 +53,8 @@ require 'opennebula/zone' require 'opennebula/zone_pool' require 'opennebula/security_group' require 'opennebula/security_group_pool' +require 'opennebula/vdc' +require 'opennebula/vdc_pool' require 'opennebula/system' module OpenNebula diff --git a/src/oca/ruby/opennebula/vdc.rb b/src/oca/ruby/opennebula/vdc.rb new file mode 100644 index 0000000000..fe9b28b80f --- /dev/null +++ b/src/oca/ruby/opennebula/vdc.rb @@ -0,0 +1,107 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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. # +#--------------------------------------------------------------------------- # + + +require 'opennebula/pool_element' + +module OpenNebula + class Vdc < PoolElement + ####################################################################### + # Constants and Class Methods + ####################################################################### + + VDC_METHODS = { + :info => "vdc.info", + :allocate => "vdc.allocate", + :update => "vdc.update", + :rename => "vdc.rename", + :delete => "vdc.delete" + } + + # Creates a Vdc description with just its identifier + # this method should be used to create plain Vdc objects. + # @param id [Integer] the id of the Vdc + # + # Example: + # vdc = Vdc.new(Vdc.build_xml(3),rpc_client) + # + def Vdc.build_xml(pe_id=nil) + if pe_id + vdc_xml = "#{pe_id}" + else + vdc_xml = "" + end + + XMLElement.build_xml(vdc_xml,'VDC') + end + + # Class constructor + def initialize(xml, client) + super(xml,client) + end + + ####################################################################### + # XML-RPC Methods for the Vdc Object + ####################################################################### + + # Retrieves the information of the given Vdc. + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def info() + super(VDC_METHODS[:info], 'VDC') + end + + alias_method :info!, :info + + # Allocates a new Vdc in OpenNebula + # + # @param description [String] The template of the Vdc. + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def allocate(description) + super(VDC_METHODS[:allocate], description) + end + + # Replaces the template contents + # + # @param new_template [String] New template contents + # @param append [true, false] True to append new attributes instead of + # replace the whole template + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def update(new_template=nil, append=false) + super(VDC_METHODS[:update], new_template, append ? 1 : 0) + end + + # Deletes the Vdc + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def delete() + super(VDC_METHODS[:delete]) + end + + # Renames this Vdc + # + # @param name [String] New name for the Vdc. + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def rename(name) + return call(VDC_METHODS[:rename], @pe_id, name) + end + end +end diff --git a/src/oca/ruby/opennebula/vdc_pool.rb b/src/oca/ruby/opennebula/vdc_pool.rb new file mode 100644 index 0000000000..fae7f10c66 --- /dev/null +++ b/src/oca/ruby/opennebula/vdc_pool.rb @@ -0,0 +1,58 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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. # +#--------------------------------------------------------------------------- # + + +require 'opennebula/pool' + +module OpenNebula + class VdcPool < Pool + ####################################################################### + # Constants and Class attribute accessors + ####################################################################### + + VDC_POOL_METHODS = { + :info => "vdcpool.info" + } + + ####################################################################### + # Class constructor & Pool Methods + ####################################################################### + + # @param client [OpenNebula::Client] XML-RPC connection + def initialize(client) + super('VDC_POOL','VDC',client) + end + + # Factory method to create Vdc objects + # @return [Vdc] new Vdc object + def factory(element_xml) + OpenNebula::Vdc.new(element_xml,@client) + end + + ####################################################################### + # XML-RPC Methods for the Vdc Object + ####################################################################### + + # Retrieves all the VDCs in the pool. + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def info() + super(VDC_POOL_METHODS[:info]) + end + + alias_method :info!, :info + end +end diff --git a/src/rm/Request.cc b/src/rm/Request.cc index 88930c3ef7..8ec81a22e9 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -603,6 +603,8 @@ string Request::object_name(PoolObjectSQL::ObjectType ob) return "zone"; case PoolObjectSQL::SECGROUP: return "security group"; + case PoolObjectSQL::VDC: + return "VDC"; default: return "-"; } diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index ec55e5bc29..e35b3e62cd 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -747,6 +747,40 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.secgrouppool.info",secgpool_info); + /* Vdc related methods */ + + xmlrpc_c::method * vdc_allocate_pt; + xmlrpc_c::method * vdc_update_pt; + xmlrpc_c::method * vdc_delete_pt; + + if (nebula.is_federation_slave()) + { + vdc_allocate_pt = new RequestManagerProxy("one.vdc.allocate"); + vdc_update_pt = new RequestManagerProxy("one.vdc.update"); + vdc_delete_pt = new RequestManagerProxy("one.vdc.delete"); + } + else + { + vdc_allocate_pt = new VdcAllocate(); + vdc_update_pt = new VdcUpdateTemplate(); + vdc_delete_pt = new VdcDelete(); + } + + xmlrpc_c::methodPtr vdc_allocate(vdc_allocate_pt); + xmlrpc_c::methodPtr vdc_update(vdc_update_pt); + xmlrpc_c::methodPtr vdc_delete(vdc_delete_pt); + + xmlrpc_c::methodPtr vdc_info(new VdcInfo()); + xmlrpc_c::methodPtr vdc_rename(new VdcRename()); + xmlrpc_c::methodPtr vdcpool_info(new VdcPoolInfo()); + + RequestManagerRegistry.addMethod("one.vdc.allocate",vdc_allocate); + RequestManagerRegistry.addMethod("one.vdc.update", vdc_update); + RequestManagerRegistry.addMethod("one.vdc.delete", vdc_delete); + RequestManagerRegistry.addMethod("one.vdc.info", vdc_info); + RequestManagerRegistry.addMethod("one.vdc.rename", vdc_rename); + + RequestManagerRegistry.addMethod("one.vdcpool.info",vdcpool_info); /* System related methods */ RequestManagerRegistry.addMethod("one.system.version", system_version); diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index d55643525d..0d8e2dd894 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -699,3 +699,20 @@ int SecurityGroupAllocate::pool_allocate( return sgpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask, tmpl, &id, error_str); } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VdcAllocate::pool_allocate( + xmlrpc_c::paramList const& paramList, + Template * tmpl, + int& id, + string& error_str, + RequestAttributes& att) +{ + string name = xmlrpc_c::value_string(paramList.getString(1)); + + VdcPool * vdcpool = static_cast(pool); + + return vdcpool->allocate(tmpl, &id, error_str); +} diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index 95e4dd8c69..9618f2f263 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -401,3 +401,15 @@ int SecurityGroupDelete::drop(int oid, PoolObjectSQL * object, string& error_msg return RequestManagerDelete::drop(oid, object, error_msg); } + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +int VdcDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) +{ + int rc = RequestManagerDelete::drop(oid, object, error_msg); + + // TODO: extra operations to clean up, or error checking to restrict + + return rc; +} diff --git a/src/rm/RequestManagerPoolInfoFilter.cc b/src/rm/RequestManagerPoolInfoFilter.cc index 806cf2c0ba..f9421ff36a 100644 --- a/src/rm/RequestManagerPoolInfoFilter.cc +++ b/src/rm/RequestManagerPoolInfoFilter.cc @@ -542,3 +542,12 @@ void VirtualNetworkPoolInfo::request_execute( return; } +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +void VdcPoolInfo::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + dump(att, ALL, -1, -1, "", ""); +} diff --git a/src/vdc/SConstruct b/src/vdc/SConstruct new file mode 100644 index 0000000000..860cc0a74b --- /dev/null +++ b/src/vdc/SConstruct @@ -0,0 +1,30 @@ +# SConstruct for src/vdc + +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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. # +#--------------------------------------------------------------------------- # + +Import('env') + +lib_name='nebula_vdc' + +# Sources to generate the library +source_files=[ + 'VdcPool.cc', + 'Vdc.cc' +] + +# Build library +env.StaticLibrary(lib_name, source_files) diff --git a/src/vdc/Vdc.cc b/src/vdc/Vdc.cc new file mode 100644 index 0000000000..9fd1616172 --- /dev/null +++ b/src/vdc/Vdc.cc @@ -0,0 +1,240 @@ +/* ------------------------------------------------------------------------ */ +/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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. */ +/* ------------------------------------------------------------------------ */ + +#include "Vdc.h" + +/* ------------------------------------------------------------------------ */ + +const char * Vdc::table = "vdc_pool"; + +const char * Vdc::db_names = + "oid, name, body, uid, gid, owner_u, group_u, other_u"; + +const char * Vdc::db_bootstrap = "CREATE TABLE IF NOT EXISTS vdc_pool (" + "oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, " + "gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, " + "UNIQUE(name))"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +Vdc::Vdc(int id, Template* vdc_template): + PoolObjectSQL(id, VDC, "", -1, -1, "", "", table) +{ + if (vdc_template != 0) + { + obj_template = vdc_template; + } + else + { + obj_template = new Template; + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +Vdc::~Vdc() +{ + delete obj_template; +}; + +/* ************************************************************************ */ +/* Vdc :: Database Access Functions */ +/* ************************************************************************ */ + +int Vdc::insert(SqlDB *db, string& error_str) +{ + int rc; + + ostringstream oss; + + // --------------------------------------------------------------------- + // Check default attributes + // --------------------------------------------------------------------- + + erase_template_attribute("NAME", name); + + if ( name.empty() ) + { + oss << "vdc-" << oid; + name = oss.str(); + } + + // ------------------------------------------------------------------------ + // Insert the Vdc + // ------------------------------------------------------------------------ + + rc = insert_replace(db, false, error_str); + + return rc; + +error_common: + NebulaLog::log("VDC", Log::ERROR, error_str); + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Vdc::insert_replace(SqlDB *db, bool replace, string& error_str) +{ + ostringstream oss; + + int rc; + string xml_body; + + char * sql_name; + char * sql_xml; + + // Set oneadmin as the owner and group it belongs to + set_user(0,""); + set_group(0,""); + + // Update the vdc + + sql_name = db->escape_str(name.c_str()); + + if ( sql_name == 0 ) + { + goto error_name; + } + + sql_xml = db->escape_str(to_xml(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + goto error_body; + } + + if ( validate_xml(sql_xml) != 0 ) + { + goto error_xml; + } + + if ( replace ) + { + oss << "REPLACE"; + } + else + { + oss << "INSERT"; + } + + // Construct the SQL statement to Insert or Replace + + oss <<" INTO "<exec(oss); + + db->free_str(sql_name); + db->free_str(sql_xml); + + return rc; + +error_xml: + db->free_str(sql_name); + db->free_str(sql_xml); + + error_str = "Error transforming the VDC to XML."; + + goto error_common; + +error_body: + db->free_str(sql_name); + goto error_generic; + +error_name: + goto error_generic; + +error_generic: + error_str = "Error inserting VDC in DB."; +error_common: + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string& Vdc::to_xml(string& xml) const +{ + ostringstream oss; + string template_xml; + + oss << + "" << + "" << oid << "" << + "" << name << "" << + obj_template->to_xml(template_xml) << + ""; + + xml = oss.str(); + + return xml; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int Vdc::from_xml(const string& xml) +{ + vector content; + int rc = 0; + + // Initialize the internal XML object + update_from_str(xml); + + // Get class base attributes + rc += xpath(oid, "/VDC/ID", -1); + rc += xpath(name,"/VDC/NAME", "not_found"); + + // Get associated classes + ObjectXML::get_nodes("/VDC/TEMPLATE", content); + + if (content.empty()) + { + return -1; + } + + // Template contents + rc += obj_template->from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + content.clear(); + + if (rc != 0) + { + return -1; + } + + // Set oneadmin as the owner and group it belongs to + set_user(0,""); + set_group(0,""); + + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ diff --git a/src/vdc/VdcPool.cc b/src/vdc/VdcPool.cc new file mode 100644 index 0000000000..0159c375c9 --- /dev/null +++ b/src/vdc/VdcPool.cc @@ -0,0 +1,181 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#include "VdcPool.h" +#include "NebulaLog.h" +#include "Nebula.h" + +/* -------------------------------------------------------------------------- */ + +VdcPool::VdcPool(SqlDB * db, bool is_federation_slave) + :PoolSQL(db, Vdc::table, !is_federation_slave, true) +{ + string error_str; + + //Federation slaves do not need to init the pool + if (is_federation_slave) + { + return; + } + + //lastOID is set in PoolSQL::init_cb + if (get_lastOID() == -1) + { + ostringstream vdc_tmpl; + vdc_tmpl << "NAME=default"; + + int rc; + Template * tmpl; + + // Build the default vdc + tmpl = new Template; + rc = tmpl->parse_str_or_xml( + vdc_tmpl.str(), + error_str); + + if( rc < 0 ) + { + goto error_bootstrap; + } + + allocate(tmpl, &rc, error_str); + + if( rc < 0 ) + { + goto error_bootstrap; + } + + // The first 100 Vdc IDs are reserved for system Vdcs. + // Regular ones start from ID 100 + + set_update_lastOID(99); + } + + return; + +error_bootstrap: + ostringstream oss; + oss << "Error trying to create default vdc: " << error_str; + NebulaLog::log("VDC",Log::ERROR,oss); + + throw runtime_error(oss.str()); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VdcPool::allocate( + Template * vdc_template, + int * oid, + string& error_str) +{ + Vdc * vdc; + Vdc * vdc_aux = 0; + + string name; + + ostringstream oss; + + if (Nebula::instance().is_federation_slave()) + { + NebulaLog::log("ONE",Log::ERROR, + "VdcPool::allocate called, but this " + "OpenNebula is a federation slave"); + + return -1; + } + + vdc = new Vdc(-1, vdc_template); + + // ------------------------------------------------------------------------- + // Check name & duplicates + // ------------------------------------------------------------------------- + + vdc->get_template_attribute("NAME", name); + + if ( !PoolObjectSQL::name_is_valid(name, error_str) ) + { + goto error_name; + } + + vdc_aux = get(name,false); + + if( vdc_aux != 0 ) + { + goto error_duplicated; + } + + *oid = PoolSQL::allocate(vdc, error_str); + + return *oid; + +error_duplicated: + oss << "NAME is already taken by Vdc " << vdc_aux->get_oid() << "."; + error_str = oss.str(); + +error_name: + delete vdc; + *oid = -1; + + return *oid; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VdcPool::update(Vdc * vdc) +{ + if (Nebula::instance().is_federation_slave()) + { + NebulaLog::log("ONE",Log::ERROR, + "VdcPool::update called, but this " + "OpenNebula is a federation slave"); + + return -1; + } + + return vdc->update(db); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VdcPool::drop(PoolObjectSQL * objsql, string& error_msg) +{ + if (Nebula::instance().is_federation_slave()) + { + NebulaLog::log("ONE",Log::ERROR, + "VdcPool::drop called, but this " + "OpenNebula is a federation slave"); + + return -1; + } + + Vdc * vdc = static_cast(objsql); + + // Return error if the vdc is a default one. + if( vdc->get_oid() < 100 ) + { + error_msg = "System VDCs (ID < 100) cannot be deleted."; + NebulaLog::log("VDC", Log::ERROR, error_msg); + return -2; + } + + return PoolSQL::drop(objsql, error_msg); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */