/* ------------------------------------------------------------------------ */ /* Copyright 2002-2020, 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. */ /* -------------------------------------------------------------------------*/ #ifndef VMGROUP_ROLE_H_ #define VMGROUP_ROLE_H_ #include "PoolObjectSQL.h" #include "NebulaUtil.h" class VMGroupPool; enum class VMGroupPolicy; /** * A VMGroupRole defines a VM type that typically implements a role in a * multi-vm application. * * ROLE = [ * NAME = "Web application servers", * ID = 12, * POLICY = AFFINED, * VMS = "1,2,45,21" * ] * */ class VMGroupRole { public: VMGroupRole(VectorAttribute *_va); virtual ~VMGroupRole(){}; /** * @return the role id */ int id() { int rid; va->vector_value("ID", rid); return rid; } /** * @return the role name */ std::string name() { return va->vector_value("NAME"); } /** * @return the set of VMs in a string in a comma separated list */ std::string vms_s() { return va->vector_value("VMS"); } /** * @return the policy of this role */ VMGroupPolicy policy(); std::string policy_s() { return va->vector_value("POLICY"); }; /* ---------------------------------------------------------------------- */ /* VMS set Interface */ /* ---------------------------------------------------------------------- */ const std::set& get_vms() { return vms; }; int size_vms() { return vms.size(); } void add_vm(int vm_id); void del_vm(int vm_id); /* ---------------------------------------------------------------------- */ /* Placement constraints */ /* ---------------------------------------------------------------------- */ /** * Generates a string with the boolean expression to conform the role * internal policy * @param vm_id of the VM to generate the requirements for * @param requirements */ void vm_role_requirements(int vm_id, std::string& requirements); /** * Generates a string with the boolean expression to conform an affinity * constraint policy * @param p policy to place VMs respect to this role VMs * @param requirements */ void role_requirements(VMGroupPolicy p, std::string& requirements); /** * Gets the placement requirements for the affined HOSTS * @param reqs string with the requirements expression */ void affined_host_requirements(std::string& reqs); /** * Gets the placement requirements for the antiaffined HOSTS * @param reqs string with the requirements expression */ void antiaffined_host_requirements(std::string& reqs); /** * Generate generic requirements for a set of hosts * @param hosts the set * @param op1 operator for each host requirement = or != * @param op2 operator to join host requirements & or | * @param oss stream where the requirement expression is output */ static void host_requirements(std::set& hosts, const std::string& op1, const std::string& op2, std::ostringstream& oss); private: /** * The set of vms in the role */ std::set vms; /** * The associated vector attribute */ VectorAttribute * va; /** * Set the VMS attribute for the role (list of VM IDs) */ void set_vms(); }; /** * The VMGroupRoles class represents a set of ROLES stored in a Template */ class VMGroupRoles { public: VMGroupRoles():roles_template(false,'=',"ROLES"), next_role(0){}; ~VMGroupRoles() { by_id.delete_roles(); }; /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /** * Max number of roles in a VMGroup */ const static int MAX_ROLES = 32; /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /** * Function to print the VMGroupRoles into a string in XML format * @param xml the resulting XML string * @return a reference to the generated string */ std::string& to_xml(std::string& xml_str) const { return roles_template.to_xml(xml_str); } /** * Builds the object from an xml node * @param node for the ROLES template * @return 0 on success, -1 otherwise */ int from_xml_node(const xmlNodePtr node); /** * Adds a new role to the set * @param vrole VectorAttribute of the role * @param error string if any * * @return 0 on success */ int add_role(VectorAttribute * vrole, string& error); /** * Generates the ids corresponding to a set of role names * @param rnames string with a comma separated list of role names * @param keyi the set of ids * * @return 0 if all the names were successfully translated */ int names_to_ids(const std::string& rnames, std::set& keyi); /** * Adds a VM to a role * @param role_name * @param vmid * * @return 0 if VM was successfully added, -1 otherwise */ int add_vm(const std::string& role_name, int vmid); /** * Deletes a VM from a role * @param role_name * @param vmid * * @return 0 if VM was successfully added, -1 otherwise */ int del_vm(const std::string& role_name, int vmid); /** * @return the total number of VMs in the group */ int vm_size(); /** * @return the a VMGroupRole by its name * @param rname role name */ VMGroupRole * get(const std::string& rname) { return by_name.get(rname); } /** * @return the a VMGroupRole by its id * @param rname role name */ VMGroupRole * get(int id) { return by_id.get(id); } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /** * Iterator for the roles in the group */ class RoleIterator { public: RoleIterator& operator=(const RoleIterator& rhs) { role_it = rhs.role_it; return *this; } RoleIterator& operator++() { ++role_it; return *this; } bool operator!=(const RoleIterator& rhs) { return role_it != rhs.role_it; } VMGroupRole * operator*() const { return role_it->second; } RoleIterator(){}; RoleIterator(const RoleIterator& rit):role_it(rit.role_it){}; RoleIterator(const std::map::iterator& _role_it) :role_it(_role_it){}; virtual ~RoleIterator(){}; private: std::map::iterator role_it; }; RoleIterator begin() { RoleIterator it(by_id.begin()); return it; } RoleIterator end() { RoleIterator it(by_id.end()); return it; } typedef class RoleIterator role_iterator; private: /** * A role map indexed by different key types */ template class RoleMap { public: /** * Inserts a new role in the map * @param k the key * @param r pointer to yhe VMGroupRole * @return true if the role was successfully inserted */ bool insert(const T& k, VMGroupRole * r) { std::pair rpair(k, r); std::pair rc; rc = roles.insert(rpair); return rc.second; } /** * Frees the memory associated to the map and clears it */ void delete_roles() { for (roles_it it = roles.begin() ; it != roles.end() ; ++it ) { delete it->second; } clear(); } VMGroupRole * get(T k) { typename std::map::iterator it; it = roles.find(k); if ( it == roles.end() ) { return 0; } return it->second; } /** * Clears the contents of the map */ void clear() { roles.clear(); } size_t erase(const T& k) { return roles.erase(k); } /** * Iterators for the map */ typedef typename std::map::iterator roles_it; roles_it begin() { return roles.begin(); } roles_it end() { return roles.end(); } private: std::map roles; }; /** * The role template to store the VMGroupRole */ Template roles_template; /** * The next role id */ int next_role; /** * Map to access the roles by their name */ RoleMap by_name; /** * Map to access the roles by their id */ RoleMap by_id; }; #endif /*VMGROUP_ROLE_H*/