1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-22 17:57:46 +03:00

Merge remote-tracking branch 'origin/master' into feature-3175

Conflicts:
	install.sh
This commit is contained in:
Carlos Martín 2014-10-03 15:55:29 +02:00
commit 49b94d12ea
101 changed files with 4331 additions and 633 deletions

View File

@ -174,6 +174,9 @@ public:
const set<int>& user_groups,
PoolObjectSQL::ObjectType obj_type,
AuthRequest::Operation op,
bool disable_all_acl,
bool disable_cluster_acl,
bool disable_group_acl,
bool& all,
vector<int>& oids,
vector<int>& gids,

View File

@ -116,8 +116,14 @@ public:
/**
* Builds an extended XML representation of the AR to send it back to
* clients
* @param oss stream to write the XML
* @param vm_ids list of VM the user can access VNET usage info from.
* A vector containing just -1 means all VMs.
* @param vnet_ids list of VNET the user can access reservation info from.
* A vector containing just -1 means all VNETs.
*/
void to_xml(ostringstream &oss) const;
void to_xml(ostringstream &oss, const vector<int>& vms,
const vector<int>& vnets) const;
// *************************************************************************
// Address allocation functions
@ -311,7 +317,10 @@ public:
* the reason.
* @return 0 on success
*/
int update_attributes(VectorAttribute *vup, string& error_msg);
int update_attributes(
VectorAttribute * vup,
bool keep_restricted,
string& error_msg);
/*
* add_ar from AddressRangePool needs to access the internal representation
@ -319,6 +328,8 @@ public:
*/
friend int AddressRangePool::add_ar(AddressRange * ar);
static void set_restricted_attributes(vector<const Attribute *>& rattrs);
private:
/* ---------------------------------------------------------------------- */
/* String to binary conversion functions for different address types */
@ -424,7 +435,15 @@ private:
/* ---------------------------------------------------------------------- */
bool check(string& rs_attr) const;
static void set_restricted_attributes(vector<const Attribute *>& rattrs);
/**
* Deletes all restricted attributes
*/
void remove_restricted(VectorAttribute* va);
/**
* Deletes all the attributes, except the restricted ones
*/
void remove_all_except_restricted(VectorAttribute* va);
/* ---------------------------------------------------------------------- */
/* Address Range data */

View File

@ -75,11 +75,13 @@ public:
* Updates the given address ranges
* @param ars vector of address ranges as VectorAttributes obtained from
* template in the form AR = [...]. Only one AR is processed.
* @param keep_restricted If true, the restricted attributes of the
* current template will override the new template
* @param error_msg If the action fails, this message contains
* the reason.
* @return 0 on success
*/
int update_ar(vector<Attribute *> ars, string& error_msg);
int update_ar(vector<Attribute *> ars, bool keep_restricted, string& error_msg);
/**
* Allocates a new *empty* address range. It is not added to the pool as it
@ -316,9 +318,14 @@ public:
* Generate a XML representation of the Address Range Pool
* @param sstream where the ARPool is written
* @param extended true to include lease information
* @param vm_ids list of VM the user can access VNET usage info from.
* A vector containing just -1 means all VMs.
* @param vnet_ids list of VNET the user can access reservation info from.
* A vector containing just -1 means all VNETs.
* @return the string with the XML
*/
string& to_xml(string& sstream, bool extended) const;
string& to_xml(string& sstream, bool extended, const vector<int>& vms,
const vector<int>& vnets) const;
private:
/**

View File

@ -163,13 +163,16 @@ public:
VectorAttribute * disk,
const vector<string>& inherit_attrs);
/**
* Replace template for this object. Object should be updated
* after calling this method
* @param tmpl string representation of the template
* @param tmpl_str new contents
* @param keep_restricted If true, the restricted attributes of the
* current template will override the new template
* @param error string describing the error if any
* @return 0 on success
*/
int replace_template(const string& tmpl_str, string& error);
int replace_template(const string& tmpl_str, bool keep_restricted, string& error);
/**
* Set monitor information for the Datastore

View File

@ -43,6 +43,22 @@ public:
return Template::check(rs_attr, restricted_attributes);
};
/**
* Deletes all restricted attributes
*/
void remove_restricted()
{
Template::remove_restricted(restricted_attributes);
};
/**
* Deletes all the attributes, except the restricted ones
*/
void remove_all_except_restricted()
{
Template::remove_all_except_restricted(restricted_attributes);
};
bool is_saving()
{
string saving;

84
include/LoginToken.h Normal file
View File

@ -0,0 +1,84 @@
/* -------------------------------------------------------------------------- */
/* 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 LOGIN_TOKEN_H_
#define LOGIN_TOKEN_H_
#include <string>
#include <time.h>
#include <libxml/tree.h>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* The login token class stores a generic token that can be used with any
* authentication driver and mechanism.
*/
class LoginToken
{
public:
LoginToken():expiration_time(0), token(""){};
~LoginToken(){};
/**
* Check if the token is valid (same as the one provided, and not expired)
* @param user_token provided by the user
* @return true if the token is valid
*/
bool is_valid(const std::string& user_token) const;
/**
* Register a new token, if not provided OpenNebula will generate one.
* @param valid time in seconds that the token will be considered valid
* @param user_token if provided externally (e.g. by an auth driver)
*/
const std::string& set(const std::string& user_token, time_t valid);
/**
* Clears the token if not valid
*/
void reset();
/**
* Function to print the LoginToken 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) const;
/**
* Builds the token from an xml pointer
* @param node the xml object with the token
*/
void from_xml_node(const xmlNodePtr node);
private:
/**
* Expiration time of the token, it will not be valid after it.
*/
time_t expiration_time;
/**
* Token value
*/
std::string token;
};
#endif /*LOGIN_TOKEN_H_*/

View File

@ -396,7 +396,7 @@ public:
*/
static string local_db_version()
{
return "4.7.80";
return "4.9.80";
}
/**

View File

@ -43,7 +43,10 @@ public:
group_a(0),
other_u(0),
other_m(0),
other_a(0) {};
other_a(0),
disable_all_acl(false),
disable_cluster_acl(false),
disable_group_acl(false) {};
void get_acl_rules(AclRule& owner_rule,
AclRule& group_rule,
@ -75,6 +78,10 @@ public:
int other_u;
int other_m;
int other_a;
bool disable_all_acl; // All objects of this type (e.g. NET/*)
bool disable_cluster_acl; // All objects in a cluster (e.g. NET/%100)
bool disable_group_acl; // All objects own by this group (e.g. NET/@101)
};
#endif /*POOL_OBJECT_AUTH_H_*/

View File

@ -563,24 +563,31 @@ public:
/**
* Replace template for this object. Object should be updated
* after calling this method
* @param tmpl string representation of the template
* @param tmpl_str new contents
* @param keep_restricted If true, the restricted attributes of the
* current template will override the new template
* @param error string describing the error if any
* @return 0 on success
*/
virtual int replace_template(const string& tmpl_str, string& error);
virtual int replace_template(const string& tmpl_str, bool keep_restricted, string& error);
/**
* Append new attributes to this object's template. Object should be updated
* after calling this method
* @param tmpl string representation of the template
* @param tmpl_str new contents
* @param keep_restricted If true, the restricted attributes of the
* current template will override the new template
* @param error string describing the error if any
* @return 0 on success
*/
virtual int append_template(const string& tmpl_str, string& error);
virtual int append_template(const string& tmpl_str, bool keep_restricted, string& error);
/**
* Fills a auth class to perform an authZ/authN request based on the object
* attributes
* @param auths to be filled
*/
void get_permissions(PoolObjectAuth& auths);
virtual void get_permissions(PoolObjectAuth& auths);
protected:

View File

@ -201,14 +201,20 @@ public:
* @param user_groups Set of group IDs that the user is part of
* @param auth_object object type
* @param all returns if the user can access all objects
* @param disable_all_acl e.g. NET\*
* @param disable_cluster_acl e.g. NET/%100
* @param disable_group_acl e.g. NET/@102
* @param filter the resulting filter string
*
*/
static void acl_filter(int uid,
const set<int>& user_groups,
PoolObjectSQL::ObjectType auth_object,
bool& all,
bool disable_all_acl,
bool disable_cluster_acl,
bool disable_group_acl,
string& filter);
/**
* Creates a filter for the objects owned by a given user/group
* @param uid the user id

View File

@ -45,7 +45,8 @@ protected:
/* -------------------------------------------------------------------- */
virtual void to_xml(PoolObjectSQL * object, string& str)
virtual void to_xml(RequestAttributes& att, PoolObjectSQL * object,
string& str)
{
object->to_xml(str);
};
@ -60,7 +61,7 @@ public:
VirtualMachineInfo():
RequestManagerInfo("VirtualMachineInfo",
"Returns virtual machine instance information")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_vmpool();
auth_object = PoolObjectSQL::VM;
@ -70,10 +71,9 @@ public:
/* -------------------------------------------------------------------- */
void to_xml(PoolObjectSQL * object, string& str)
void to_xml(RequestAttributes& att, PoolObjectSQL * object, string& str)
{
VirtualMachine * vm = static_cast<VirtualMachine *>(object);
vm->to_xml_extended(str);
static_cast<VirtualMachine *>(object)->to_xml_extended(str);
};
};
@ -86,7 +86,7 @@ public:
TemplateInfo():
RequestManagerInfo("TemplateInfo",
"Returns virtual machine template information")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_tpool();
auth_object = PoolObjectSQL::TEMPLATE;
@ -105,7 +105,7 @@ public:
VirtualNetworkInfo():
RequestManagerInfo("VirtualNetworkInfo",
"Returns virtual network information")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_vnpool();
auth_object = PoolObjectSQL::NET;
@ -115,11 +115,7 @@ public:
/* -------------------------------------------------------------------- */
void to_xml(PoolObjectSQL * object, string& str)
{
VirtualNetwork * vn = static_cast<VirtualNetwork*>(object);
vn->to_xml_extended(str);
};
void to_xml(RequestAttributes& att, PoolObjectSQL * object, string& str);
};
/* ------------------------------------------------------------------------- */
@ -131,7 +127,7 @@ public:
ImageInfo():
RequestManagerInfo("ImageInfo",
"Returns image information")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_ipool();
auth_object = PoolObjectSQL::IMAGE;
@ -150,7 +146,7 @@ public:
HostInfo():
RequestManagerInfo("HostInfo",
"Returns host information")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_hpool();
auth_object = PoolObjectSQL::HOST;
@ -178,10 +174,9 @@ public:
/* -------------------------------------------------------------------- */
void to_xml(PoolObjectSQL * object, string& str)
void to_xml(RequestAttributes& att, PoolObjectSQL * object, string& str)
{
Group * group = static_cast<Group*>(object);
group->to_xml_extended(str);
static_cast<Group*>(object)->to_xml_extended(str);
};
};
@ -204,10 +199,9 @@ public:
/* -------------------------------------------------------------------- */
void to_xml(PoolObjectSQL * object, string& str)
void to_xml(RequestAttributes& att, PoolObjectSQL * object, string& str)
{
User * user = static_cast<User*>(object);
user->to_xml_extended(str);
static_cast<User*>(object)->to_xml_extended(str);
};
};

View File

@ -39,6 +39,22 @@ public:
/** Specify user's + group objects (-1) */
static const int MINE_GROUP;
/**
* Set a where filter to get the oids of objects that a user can "USE"
* @param att the XML-RPC Attributes with user information
* @param auth_object the object type
* @param where_string will store the resulting SQL filter
* @return true if the use_filter is empty and access to all objects
* should be granted.
*/
static bool use_filter(RequestAttributes& att,
PoolObjectSQL::ObjectType aobj,
bool disable_all_acl,
bool disable_cluster_acl,
bool disable_group_acl,
const string& and_str,
string& where_str);
protected:
RequestManagerPoolInfoFilter(const string& method_name,
const string& help,
@ -56,12 +72,15 @@ protected:
/* -------------------------------------------------------------------- */
void where_filter(RequestAttributes& att,
int filter_flag,
int start_id,
int end_id,
const string& and_clause,
const string& or_clause,
string& where_string);
int filter_flag,
int start_id,
int end_id,
const string& and_clause,
const string& or_clause,
bool disable_all_acl,
bool disable_cluster_acl,
bool disable_group_acl,
string& where_string);
/* -------------------------------------------------------------------- */
@ -90,7 +109,7 @@ public:
RequestManagerPoolInfoFilter("VirtualMachinePoolInfo",
"Returns the virtual machine instances pool",
"A:siiii")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_vmpool();
auth_object = PoolObjectSQL::VM;
@ -164,7 +183,7 @@ public:
RequestManagerPoolInfoFilter("TemplatePoolInfo",
"Returns the virtual machine template pool",
"A:siii")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_tpool();
auth_object = PoolObjectSQL::TEMPLATE;
@ -183,13 +202,16 @@ public:
RequestManagerPoolInfoFilter("VirtualNetworkPoolInfo",
"Returns the virtual network pool",
"A:siii")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_vnpool();
auth_object = PoolObjectSQL::NET;
};
~VirtualNetworkPoolInfo(){};
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
@ -202,7 +224,7 @@ public:
RequestManagerPoolInfoFilter("ImagePoolInfo",
"Returns the image pool",
"A:siii")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_ipool();
auth_object = PoolObjectSQL::IMAGE;

View File

@ -84,14 +84,6 @@ public:
};
~VirtualMachineUpdateTemplate(){};
/* -------------------------------------------------------------------- */
int replace_template(PoolObjectSQL * object, const string & tmpl,
const RequestAttributes &att, string &error_str);
int append_template(PoolObjectSQL * object, const string & tmpl,
const RequestAttributes &att, string &error_str);
};
/* ------------------------------------------------------------------------- */
@ -144,7 +136,7 @@ public:
Nebula& nd = Nebula::instance();
pool = nd.get_vnpool();
auth_object = PoolObjectSQL::NET;
auth_op = AuthRequest::ADMIN;
auth_op = AuthRequest::MANAGE;
};
~VirtualNetworkUpdateTemplate(){};

View File

@ -132,6 +132,28 @@ public:
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class UserLogin : public Request
{
public:
UserLogin(): Request("UserLogin", "A:sssi", "Generates or sets a login token")
{
Nebula& nd = Nebula::instance();
pool = nd.get_upool();
auth_object = PoolObjectSQL::USER;
auth_op = AuthRequest::MANAGE;
};
virtual ~UserLogin(){};
void request_execute(
xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class UserEditGroup : public Request
{
public:

View File

@ -142,7 +142,7 @@ public:
RequestManagerVirtualNetwork("VirtualNetworkUpdateAddressRange",
"Updates address ranges to a virtual network")
{
auth_op = AuthRequest::ADMIN;
auth_op = AuthRequest::MANAGE;
};
~VirtualNetworkUpdateAddressRange(){};
@ -152,7 +152,14 @@ public:
RequestAttributes& att,
string& error_str)
{
return vn->update_ar(tmpl, error_str);
if (att.uid!=UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
{
return vn->update_ar(tmpl, true, error_str);
}
else
{
return vn->update_ar(tmpl, false, error_str);
}
};
};

View File

@ -380,6 +380,16 @@ public:
*/
int merge(const Template * from_tmpl, string& error_str);
/**
* Deletes all restricted attributes
*/
virtual void remove_restricted();
/**
* Deletes all the attributes, except the restricted ones
*/
virtual void remove_all_except_restricted();
protected:
/**
* The template attributes
@ -419,6 +429,16 @@ protected:
*/
bool check(string& rs_attr, const vector<string> &restricted_attributes);
/**
* Deletes all restricted attributes
*/
void remove_restricted(const vector<string> &restricted_attributes);
/**
* Deletes all the attributes, except the restricted ones
*/
void remove_all_except_restricted(const vector<string> &restricted_attributes);
/**
* Updates the xml root element name
*

View File

@ -21,6 +21,7 @@
#include "UserTemplate.h"
#include "ObjectCollection.h"
#include "QuotasSQL.h"
#include "LoginToken.h"
class UserQuotas;
@ -93,7 +94,9 @@ public:
void disable()
{
enabled = false;
invalidate_session();
session.reset();
login_token.reset();
};
/**
@ -133,7 +136,7 @@ public:
int set_auth_driver(const string& _auth_driver, string& error_str)
{
auth_driver = _auth_driver;
invalidate_session();
session.reset();
return 0;
};
@ -155,11 +158,6 @@ public:
return new UserTemplate;
}
/**
* Object quotas, provides set and check interface
*/
UserQuotas quota;
/**
* Returns the UMASK template attribute (read as an octal number), or the
* default UMASK from oned.conf if it does not exist
@ -220,6 +218,11 @@ public:
// Quotas
// *************************************************************************
/**
* Object quotas, provides set and check interface
*/
UserQuotas quota;
/**
* Writes/updates the User quotas fields in the database.
* @param db pointer to the db
@ -230,6 +233,15 @@ public:
return quota.update(oid, db);
};
// *************************************************************************
// Login token
// *************************************************************************
/**
* The login token object, provides the set & reset interface for the token
*/
LoginToken login_token;
private:
// -------------------------------------------------------------------------
// Friends
@ -260,50 +272,7 @@ private:
// Authentication session (Private)
// *************************************************************************
/**
* Until when the session_token is valid
*/
time_t session_expiration_time;
/**
* Last authentication token validated by the driver, can
* be trusted until the session_expiration_time
*/
string session_token;
/**
* Checks if a session token is authorized and still valid
*
* @param token The authentication token
* @return true if the token is still valid
*/
bool valid_session(const string& token)
{
return (( session_token == token ) &&
( time(0) < session_expiration_time ) );
};
/**
* Resets the authentication session
*/
void invalidate_session()
{
session_token.clear();
session_expiration_time = 0;
};
/**
* Stores the given session token for a limited time. This eliminates the
* need to call the external authentication driver until the time expires.
*
* @param token The authenticated token
* @param validity_time
*/
void set_session(const string& token, time_t validity_time)
{
session_token = token;
session_expiration_time = time(0) + validity_time;
};
LoginToken session;
// *************************************************************************
// DataBase implementation (Private)
@ -388,9 +357,7 @@ protected:
quota(),
password(_password),
auth_driver(_auth_driver),
enabled(_enabled),
session_expiration_time(0),
session_token("")
enabled(_enabled)
{
obj_template = new UserTemplate;
};

View File

@ -123,6 +123,17 @@ public:
int get_pending(
vector<int>& oids);
/**
* Gets the IDs of VMs matching the given SQL where string.
* @param oids a vector that contains the IDs
* @param where SQL clause
* @return 0 on success
*/
int search(vector<int>& oids, const string& where)
{
return PoolSQL::search(oids, VirtualMachine::table, where);
};
//--------------------------------------------------------------------------
// Virtual Machine DB access functions
//--------------------------------------------------------------------------

View File

@ -52,21 +52,27 @@ public:
return Template::check(rs_attr, restricted_attributes);
};
/**
* Deletes all restricted attributes
*/
void remove_restricted()
{
Template::remove_restricted(restricted_attributes);
};
/**
* Deletes all the attributes, except the restricted ones
*/
void remove_all_except_restricted()
{
Template::remove_all_except_restricted(restricted_attributes);
};
void set_xml_root(const char * _xml_root)
{
Template::set_xml_root(_xml_root);
};
/**
* Deletes all restricted attributes
*/
void remove_restricted();
/**
* Deletes all the attributes, excepts the restricted ones
*/
void remove_all_except_restricted();
/**
* Replaces the given image from the DISK attribute with a new one
* @param target_id IMAGE_ID the image to be replaced

View File

@ -56,6 +56,14 @@ public:
return new VirtualNetworkTemplate;
}
/**
* Fills a auth class to perform an authZ/authN request based on the object
* attributes. Disables the cluster and all NET rules (NET* and NET/%) for
* reservations.
* @param auths to be filled
*/
void get_permissions(PoolObjectAuth& auths);
// *************************************************************************
// Address Range management interface
// *************************************************************************
@ -108,11 +116,16 @@ public:
* Update an address range to the virtual network
* @param ars_tmpl template in the form AR = [AR_ID=...]. The address range
* is specified by the AR_ID attribute.
* @param keep_restricted If true, the restricted attributes of the
* current template will override the new template
* @param error_msg If the action fails, this message contains
* the reason.
* @return 0 on success
*/
int update_ar(VirtualNetworkTemplate * ars_tmpl, string& error_msg);
int update_ar(
VirtualNetworkTemplate* ars_tmpl,
bool keep_restricted,
string& error_msg);
// *************************************************************************
// Address hold/release interface
@ -291,6 +304,12 @@ public:
int reserve_addr_by_mac(VirtualNetwork *rvnet, unsigned int rsize,
unsigned int ar_id, const string& mac, string& error_str);
/**
* Returns true if this VNET is a reservation
* @return true if this VNET is a reservation
*/
bool is_reservation() const;
// *************************************************************************
// Formatting & Helper functions
// *************************************************************************
@ -338,29 +357,29 @@ public:
*/
string& to_xml(string& xml) const;
/**
* Function to print the object into a string in XML format
* base64 encoded
* @param xml64 the resulting XML string
* @param extended return the extended template or the simple one
* @return a reference to the generated string
*/
string& to_xml64(string &xml64, bool extended);
/**
* Function to print the VirtualNetwork object into a string in
* XML format. The extended XML includes the LEASES
* @param xml the resulting XML string
* @param vm_ids list of VM the user can access VNET usage info from.
* A vector containing just -1 means all VMs.
* @param vnet_ids list of VNET the user can access reservation info from.
* A vector containing just -1 means all VNETs.
* @return a reference to the generated string
*/
string& to_xml_extended(string& xml) const;
string& to_xml_extended(string& xml, const vector<int>& vms,
const vector<int>& vnets) const;
/**
* Replace the template of the virtual network it also updates the BRIDGE,
* PHY_DEV, VLAN_ID and VLAN attributes.
* @param tmpl string representation of the template
* @param tmpl_str new contents
* @param keep_restricted If true, the restricted attributes of the
* current template will override the new template
* @param error string describing the error if any
* @return 0 on success
*/
int replace_template(const string& tmpl_str, string& error);
int replace_template(const string& tmpl_str, bool keep_restricted, string& error);
/**
* Gets a string based attribute (single) from an address range. If the
@ -464,7 +483,8 @@ private:
* @param extended If true, leases are included
* @return a reference to the generated string
*/
string& to_xml_extended(string& xml, bool extended) const;
string& to_xml_extended(string& xml, bool extended,
const vector<int>& vm_ids, const vector<int>& vnet_oids) const;
/**
* Rebuilds the object from an xml formatted string

View File

@ -36,6 +36,7 @@ public:
VirtualNetworkPool(SqlDB * db,
const string& str_mac_prefix,
int default_size,
vector<const Attribute *>& restricted_attrs,
vector<const Attribute *> hook_mads,
const string& remotes_location,
const vector<const Attribute *>& _inherit_attrs);
@ -167,6 +168,17 @@ public:
return _default_size;
};
/**
* Gets the IDs of VNETs matching the given SQL where string.
* @param oids a vector that contains the IDs
* @param where SQL clause
* @return 0 on success
*/
int search(vector<int>& oids, const string& where)
{
return PoolSQL::search(oids, VirtualNetwork::table, where);
};
private:
/**
* Holds the system-wide MAC prefix

View File

@ -31,6 +31,48 @@ public:
Template(false,'=',"TEMPLATE"){};
~VirtualNetworkTemplate(){};
/**
* Checks the template for RESTRICTED ATTRIBUTES
* @param rs_attr the first restricted attribute found if any
* @return true if a restricted attribute is found in the template
*/
bool check(string& rs_attr)
{
return Template::check(rs_attr, restricted_attributes);
};
/**
* Deletes all restricted attributes
*/
void remove_restricted()
{
Template::remove_restricted(restricted_attributes);
};
/**
* Deletes all the attributes, except the restricted ones
*/
void remove_all_except_restricted()
{
Template::remove_all_except_restricted(restricted_attributes);
};
private:
friend class VirtualNetworkPool;
static vector<string> restricted_attributes;
/**
* Stores the attributes as restricted, these attributes will be used in
* VirtualMachineTemplate::check
* @param rattrs Attributes to restrict
*/
static void set_restricted_attributes(vector<const Attribute *>& rattrs)
{
Template::set_restricted_attributes(rattrs, restricted_attributes);
};
};
/* -------------------------------------------------------------------------- */

View File

@ -47,9 +47,13 @@ public:
/**
* Replace template for this object. Object should be updated
* after calling this method
* @param tmpl string representation of the template
* @param tmpl_str new contents
* @param keep_restricted If true, the restricted attributes of the
* current template will override the new template
* @param error string describing the error if any
* @return 0 on success
*/
int replace_template(const string& tmpl_str, string& error);
int replace_template(const string& tmpl_str, bool keep_restricted, string& error);
private:

View File

@ -247,6 +247,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/im/xen3-probes.d \
$VAR_LOCATION/remotes/im/xen4-probes.d \
$VAR_LOCATION/remotes/im/vmware.d \
$VAR_LOCATION/remotes/im/vcenter.d \
$VAR_LOCATION/remotes/im/ec2.d \
$VAR_LOCATION/remotes/im/sl.d \
$VAR_LOCATION/remotes/im/az.d \
@ -255,6 +256,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/vmm/xen3 \
$VAR_LOCATION/remotes/vmm/xen4 \
$VAR_LOCATION/remotes/vmm/vmware \
$VAR_LOCATION/remotes/vmm/vcenter \
$VAR_LOCATION/remotes/vmm/ec2 \
$VAR_LOCATION/remotes/vmm/sl \
$VAR_LOCATION/remotes/vmm/az \
@ -408,6 +410,7 @@ INSTALL_FILES=(
IM_PROBES_XEN4_FILES:$VAR_LOCATION/remotes/im/xen4.d
IM_PROBES_XEN4_PROBES_FILES:$VAR_LOCATION/remotes/im/xen4-probes.d
IM_PROBES_VMWARE_FILES:$VAR_LOCATION/remotes/im/vmware.d
IM_PROBES_VCENTER_FILES:$VAR_LOCATION/remotes/im/vcenter.d
IM_PROBES_EC2_FILES:$VAR_LOCATION/remotes/im/ec2.d
IM_PROBES_SL_FILES:$VAR_LOCATION/remotes/im/sl.d
IM_PROBES_AZ_FILES:$VAR_LOCATION/remotes/im/az.d
@ -423,6 +426,7 @@ INSTALL_FILES=(
VMM_EXEC_XEN3_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen3
VMM_EXEC_XEN4_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen4
VMM_EXEC_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/vmm/vmware
VMM_EXEC_VCENTER_SCRIPTS:$VAR_LOCATION/remotes/vmm/vcenter
VMM_EXEC_EC2_SCRIPTS:$VAR_LOCATION/remotes/vmm/ec2
VMM_EXEC_SL_SCRIPTS:$VAR_LOCATION/remotes/vmm/sl
VMM_EXEC_AZ_SCRIPTS:$VAR_LOCATION/remotes/vmm/az
@ -602,6 +606,7 @@ BIN_FILES="src/nebula/oned \
src/cli/oneflow \
src/cli/oneflow-template \
src/cli/onesecgroup \
src/cli/onevcenter \
src/onedb/onedb \
src/mad/utils/tty_expect \
share/scripts/one"
@ -762,6 +767,28 @@ VMM_EXEC_VMWARE_SCRIPTS="src/vmm_mad/remotes/vmware/cancel \
src/vmm_mad/remotes/vmware/vmware_driver.rb \
src/vmm_mad/remotes/vmware/vi_driver.rb"
#-------------------------------------------------------------------------------
# VMM Driver vCenter scripts, installed under $REMOTES_LOCATION/vmm/vcenter
#-------------------------------------------------------------------------------
VMM_EXEC_VCENTER_SCRIPTS="src/vmm_mad/remotes/vcenter/cancel \
src/vmm_mad/remotes/vcenter/attach_disk \
src/vmm_mad/remotes/vcenter/detach_disk \
src/vmm_mad/remotes/vcenter/attach_nic \
src/vmm_mad/remotes/vcenter/detach_nic \
src/vmm_mad/remotes/vcenter/snapshot_create \
src/vmm_mad/remotes/vcenter/snapshot_revert \
src/vmm_mad/remotes/vcenter/snapshot_delete \
src/vmm_mad/remotes/vcenter/deploy \
src/vmm_mad/remotes/vcenter/migrate \
src/vmm_mad/remotes/vcenter/restore \
src/vmm_mad/remotes/vcenter/reboot \
src/vmm_mad/remotes/vcenter/reset \
src/vmm_mad/remotes/vcenter/save \
src/vmm_mad/remotes/vcenter/poll \
src/vmm_mad/remotes/vcenter/shutdown \
src/vmm_mad/remotes/vcenter/vcenter_driver.rb"
#------------------------------------------------------------------------------
# VMM Driver EC2 scripts, to be installed under $REMOTES_LOCATION/vmm/ec2
#------------------------------------------------------------------------------
@ -873,6 +900,8 @@ IM_PROBES_XEN4_PROBES_FILES="src/im_mad/remotes/xen-probes.d/xen.rb \
IM_PROBES_VMWARE_FILES="src/im_mad/remotes/vmware.d/vmware.rb"
IM_PROBES_VCENTER_FILES="src/im_mad/remotes/vcenter.d/vcenter.rb"
IM_PROBES_EC2_FILES="src/im_mad/remotes/ec2.d/poll"
IM_PROBES_SL_FILES="src/im_mad/remotes/sl.d/poll"
@ -1158,7 +1187,8 @@ ONEDB_SHARED_MIGRATOR_FILES="src/onedb/shared/2.0_to_2.9.80.rb \
src/onedb/shared/4.4.1_to_4.5.80.rb\
src/onedb/shared/4.5.80_to_4.6.0.rb"
ONEDB_LOCAL_MIGRATOR_FILES="src/onedb/local/4.5.80_to_4.7.80.rb"
ONEDB_LOCAL_MIGRATOR_FILES="src/onedb/local/4.5.80_to_4.7.80.rb \
src/onedb/local/4.7.80_to_4.9.80.rb"
#-------------------------------------------------------------------------------
# Configuration files for OpenNebula, to be installed under $ETC_LOCATION
@ -1472,7 +1502,8 @@ SUNSTONE_ETC_FILES="src/sunstone/etc/sunstone-server.conf \
SUNSTONE_ETC_VIEW_FILES="src/sunstone/etc/sunstone-views/admin.yaml \
src/sunstone/etc/sunstone-views/user.yaml \
src/sunstone/etc/sunstone-views/cloud.yaml \
src/sunstone/etc/sunstone-views/vdcadmin.yaml"
src/sunstone/etc/sunstone-views/vdcadmin.yaml \
src/sunstone/etc/sunstone-views/vcenter.yaml"
SUNSTONE_MODELS_FILES="src/sunstone/models/OpenNebulaJSON.rb \
src/sunstone/models/SunstoneServer.rb \
@ -1531,7 +1562,8 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\
src/sunstone/public/js/plugins/zones-tab.js \
src/sunstone/public/js/plugins/secgroups-tab.js"
SUNSTONE_ROUTES_FILES="src/sunstone/routes/oneflow.rb"
SUNSTONE_ROUTES_FILES="src/sunstone/routes/oneflow.rb \
src/sunstone/routes/vcenter.rb"
# begin bower

View File

@ -310,6 +310,17 @@ IM_MAD = [
# arguments = "-c -t 15 -r 0 vmware" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# vCenter Information Driver Manager Configuration
# -r number of retries when monitoring a host
# -t number of threads, i.e. number of hosts monitored at the same time
#-------------------------------------------------------------------------------
#IM_MAD = [
# name = "vcenter",
# executable = "one_im_sh",
# arguments = "-c -t 15 -r 0 vcenter" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# EC2 Information Driver Manager Configuration
# -r number of retries when monitoring a host
@ -431,6 +442,19 @@ VM_MAD = [
# type = "vmware" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# vCenter Virtualization Driver Manager Configuration
# -r number of retries when monitoring a host
# -t number of threads, i.e. number of hosts monitored at the same time
#-------------------------------------------------------------------------------
#VM_MAD = [
# name = "vcenter",
# executable = "one_vmm_sh",
# arguments = "-p -t 15 -r 0 vcenter -s sh",
# type = "xml" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# EC2 Virtualization Driver Manager Configuration
# -r number of retries when monitoring a host
@ -731,6 +755,21 @@ VM_RESTRICTED_ATTR = "DISK/WRITE_IOPS_SEC"
IMAGE_RESTRICTED_ATTR = "SOURCE"
#*******************************************************************************
# The following restricted attributes only apply to VNets that are a reservation.
# Normal VNets do not have restricted attributes.
#*******************************************************************************
VNET_RESTRICTED_ATTR = "PHYDEV"
VNET_RESTRICTED_ATTR = "VLAN_ID"
VNET_RESTRICTED_ATTR = "VLAN"
VNET_RESTRICTED_ATTR = "BRIDGE"
VNET_RESTRICTED_ATTR = "AR/PHYDEV"
VNET_RESTRICTED_ATTR = "AR/VLAN_ID"
VNET_RESTRICTED_ATTR = "AR/VLAN"
VNET_RESTRICTED_ATTR = "AR/BRIDGE"
#*******************************************************************************
# Inherited Attributes Configuration
#*******************************************************************************

View File

@ -222,7 +222,7 @@ const bool AclManager::authorize(
long long resource_gid_req;
if ( obj_perms.gid >= 0 )
if ((obj_perms.gid >= 0) && (!obj_perms.disable_group_acl))
{
resource_gid_req = obj_perms.obj_type |
AclRule::GROUP_ID |
@ -235,7 +235,7 @@ const bool AclManager::authorize(
long long resource_cid_req;
if ( obj_perms.cid >= 0 )
if ((obj_perms.cid >= 0) && (!obj_perms.disable_cluster_acl))
{
resource_cid_req = obj_perms.obj_type |
AclRule::CLUSTER_ID |
@ -246,7 +246,17 @@ const bool AclManager::authorize(
resource_cid_req = AclRule::NONE_ID;
}
long long resource_all_req = obj_perms.obj_type | AclRule::ALL_ID;
long long resource_all_req ;
if (!obj_perms.disable_all_acl)
{
resource_all_req = obj_perms.obj_type | AclRule::ALL_ID;
}
else
{
resource_all_req = AclRule::NONE_ID;
}
long long rights_req = op;
long long resource_oid_mask = obj_perms.obj_type |
@ -907,6 +917,9 @@ void AclManager::reverse_search(int uid,
const set<int>& user_groups,
PoolObjectSQL::ObjectType obj_type,
AuthRequest::Operation op,
bool disable_all_acl,
bool disable_cluster_acl,
bool disable_group_acl,
bool& all,
vector<int>& oids,
vector<int>& gids,
@ -999,30 +1012,29 @@ void AclManager::reverse_search(int uid,
NebulaLog::log("ACL",Log::DDEBUG,oss);
// Rule grants permission for all objects of this type
if ( ( it->second->resource & resource_all_req ) == resource_all_req )
if ((!disable_all_acl) &&
((it->second->resource & resource_all_req) == resource_all_req))
{
all = true;
break;
}
// Rule grants permission for all objects of a group
if ( ( it->second->resource & resource_gid_mask ) == resource_gid_req )
else if ((!disable_group_acl) &&
((it->second->resource & resource_gid_mask) == resource_gid_req))
{
gids.push_back(it->second->resource_id());
}
// Rule grants permission for an individual object
else if ( ( it->second->resource & resource_oid_mask ) == resource_oid_req )
{
oids.push_back(it->second->resource_id());
}
// Rule grants permission for all objects of a cluster
if ( ( it->second->resource & resource_cid_mask ) == resource_cid_req )
else if ((!disable_cluster_acl) &&
((it->second->resource & resource_cid_mask) == resource_cid_req))
{
cids.push_back(it->second->resource_id());
}
// Rule grants permission for an individual object
else if ((it->second->resource & resource_oid_mask) == resource_oid_req)
{
oids.push_back(it->second->resource_id());
}
}
}

View File

@ -26,8 +26,6 @@ module OpenNebula; end
# as auth method is defined. It also holds some helper methods to be used
# by oneauth command
class OpenNebula::SshAuth
LOGIN_PATH = ENV['HOME']+'/.one/one_ssh'
# Initialize SshAuth object
#
# @param [Hash] default options for path
@ -66,35 +64,13 @@ class OpenNebula::SshAuth
@public_key_rsa = OpenSSL::PKey::RSA.new(Base64::decode64(@public_key))
end
# Creates the login file for ssh authentication at ~/.one/one_ssh.
# Creates a login token for ssh authentication.
# By default it is valid for 1 hour but it can be changed to any number
# of seconds with expire parameter (in seconds)
def login(user, expire=3600)
def login_token(user, expire=3600)
expire ||= 3600
# Init proxy file path and creates ~/.one directory if needed
proxy_dir = File.dirname(LOGIN_PATH)
begin
FileUtils.mkdir_p(proxy_dir)
rescue Errno::EEXIST
end
# Generate security token
time = Time.now.to_i + expire.to_i
secret_plain = "#{user}:#{time}"
secret_crypted = encrypt(secret_plain)
proxy = "#{user}:#{secret_crypted}"
file = File.open(LOGIN_PATH, "w")
file.write(proxy)
file.close
File.chmod(0600,LOGIN_PATH)
secret_crypted
return encrypt("#{user}:#{Time.now.to_i + expire.to_i}")
end
# Returns a valid password string to create a user using this auth driver.

View File

@ -34,8 +34,6 @@ class OpenNebula::X509Auth
ETC_LOCATION = ENV["ONE_LOCATION"] + "/etc"
end
LOGIN_PATH = ENV['HOME']+'/.one/one_x509'
X509_AUTH_CONF_PATH = ETC_LOCATION + "/auth/x509_auth.conf"
X509_DEFAULTS = {
@ -79,13 +77,6 @@ class OpenNebula::X509Auth
# Client side
###########################################################################
# Creates the login file for x509 authentication at ~/.one/one_x509.
# By default it is valid as long as the certificate is valid. It can
# be changed to any number of seconds with expire parameter (sec.)
def login(user, expire=0)
write_login(login_token(user,expire))
end
# Returns a valid password string to create a user using this auth driver.
# In this case the dn of the user certificate.
def password
@ -95,8 +86,10 @@ class OpenNebula::X509Auth
# Generates a login token in the form:
# user_name:x509:user_name:time_expires:cert_chain
# - user_name:time_expires is encrypted with the user certificate
# - user_name:time_expires:cert_chain is base64 encoded
def login_token(user, expire)
# - user_name:time_expires:cert_chain is base64 encoded.
# By default it is valid as long as the certificate is valid. It can
# be changed to any number of seconds with expire parameter (sec.)
def login_token(user, expire=0)
if expire != 0
expires = Time.now.to_i + expire.to_i
else
@ -107,13 +100,9 @@ class OpenNebula::X509Auth
signed_text = encrypt(text_to_sign)
certs_pem = @cert_chain.collect{|cert| cert.to_pem}.join(":")
token = "#{signed_text}:#{certs_pem}"
token64 = Base64::encode64(token).strip.delete("\n")
login_out = "#{user}:#{token64}"
login_out
return Base64::encode64(token).strip.delete("\n")
end
###########################################################################
@ -150,25 +139,6 @@ class OpenNebula::X509Auth
end
private
# Writes a login_txt to the login file as defined in LOGIN_PATH
# constant
def write_login(login_txt)
# Inits login file path and creates ~/.one directory if needed
# Set instance variables
login_dir = File.dirname(LOGIN_PATH)
begin
FileUtils.mkdir_p(login_dir)
rescue Errno::EEXIST
end
file = File.open(LOGIN_PATH, "w")
file.write(login_txt)
file.close
File.chmod(0600,LOGIN_PATH)
end
# Load class options form a configuration file (yaml syntax)
def load_options(conf_file)
if File.readable?(conf_file)

View File

@ -17,7 +17,17 @@
require 'one_helper'
require 'one_helper/onequota_helper'
# Interface for OpenNebula generated tokens.
class TokenAuth
def login_token(username, expire)
return OpenNebulaHelper::OneHelper.get_password
end
end
class OneUserHelper < OpenNebulaHelper::OneHelper
ONE_AUTH = ENV['HOME']+'/.one/one_auth'
def self.rname
"USER"
end
@ -90,7 +100,14 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
return 0, auth.password
end
def self.login(username, options)
############################################################################
# Generates a token and stores it in ONE_AUTH path as defined in this class
############################################################################
def login(username, options)
#-----------------------------------------------------------------------
# Init the associated Authentication class to generate the token.
#-----------------------------------------------------------------------
case options[:driver]
when OpenNebula::User::SSH_AUTH
require 'opennebula/ssh_auth'
@ -102,6 +119,7 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
rescue Exception => e
return -1, e.message
end
when OpenNebula::User::X509_AUTH
require 'opennebula/x509_auth'
@ -116,6 +134,7 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
rescue Exception => e
return -1, e.message
end
when OpenNebula::User::X509_PROXY_AUTH
require 'opennebula/x509_auth'
@ -134,15 +153,47 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
rescue => e
return -1, e.message
end
else
return -1, "You have to specify an Auth method"
auth = TokenAuth.new() #oned generated token
end
options[:time] ||= 3600
#-----------------------------------------------------------------------
# Authenticate with oned using the token/passwd and set/generate the
# authentication token for the user
#-----------------------------------------------------------------------
token = auth.login_token(username, options[:time])
login_client = OpenNebula::Client.new("#{username}:#{token}")
auth.login(username, options[:time])
user = OpenNebula::User.new(User.build_xml, login_client)
return 0, 'export ONE_AUTH=' << auth.class::LOGIN_PATH
token_oned = user.login(username, token, options[:time])
return -1, token_oned.message if OpenNebula.is_error?(token_oned)
#-----------------------------------------------------------------------
# Check that ONE_AUTH target can be written
#-----------------------------------------------------------------------
if File.file?(ONE_AUTH) && !options[:force]
return 0, "File #{ONE_AUTH} exists, use --force to overwrite."\
"\nAuthentication Token is:\n#{username}:#{token_oned}"
end
#-----------------------------------------------------------------------
# Store the token in ONE_AUTH.
#-----------------------------------------------------------------------
begin
FileUtils.mkdir_p(File.dirname(ONE_AUTH))
rescue Errno::EEXIST
end
file = File.open(ONE_AUTH, "w")
file.write("#{username}:#{token_oned}")
file.close
File.chmod(0600, ONE_AUTH)
return 0, ''
end
def format_pool(options)
@ -299,6 +350,20 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
puts str % ["PASSWORD", user['PASSWORD']]
puts str % ["AUTH_DRIVER", user['AUTH_DRIVER']]
if !user['LOGIN_TOKEN/TOKEN'].nil?
puts str % ["LOGIN_TOKEN", user['LOGIN_TOKEN/TOKEN']]
etime = user['LOGIN_TOKEN/EXPIRATION_TIME']
validity_str = case etime
when nil then ""
when "-1" then "forever"
else "not after #{Time.at(etime.to_i)}"
end
puts str % ["TOKEN VALIDITY", validity_str ]
end
puts str % ["ENABLED",
OpenNebulaHelper.boolean_to_str(user['ENABLED'])]

View File

@ -121,7 +121,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do
:name => "time",
:large => "--time x",
:format => Integer,
:description => "Token duration in seconds, defaults to 3600 (1 h)"
:description => "Token duration in seconds, defaults to 36000 (10 h). "\
"To reset the token set time to 0." \
"To generate a non-expiring token use -1"\
" (not valid for ssh and x509 tokens). "\
}
DRIVER={
@ -131,8 +134,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
:description => "Driver to autehnticate this user"
}
FORCE = {
:name => "force",
:large => "--force" ,
:description => "Force one_auth file rewrite"
}
create_options = [READ_FILE, SHA1, SSH, X509, KEY, CERT, DRIVER]
login_options = [SSH, X509, X509_PROXY, KEY, CERT, PROXY, TIME]
login_options = [SSH, X509, X509_PROXY, KEY, CERT, PROXY, TIME, FORCE]
########################################################################
# Formatters for arguments
@ -206,7 +215,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
quota_desc = <<-EOT.unindent
Set the quota limits for the user. If a path is not provided the editor
Set the quota limits for the user. If a path is not provided the editor
will be launched to modify the current quotas.
EOT
@ -311,17 +320,31 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
login_desc = <<-EOT.unindent
Creates the Login token for authentication
Examples:
Creates the login token for authentication. The token can be used
together with any authentication driver. The token will be stored in
$HOME/.one/one_auth, and can be used subsequently to authenticate with
oned through API, CLI or Sunstone.
Example, request a valid token for a generic driver (e.g. core auth, LDAP...):
oneuser login my_user --time 3600
Example, generate and set a token for SSH based authentication:
oneuser login my_user --ssh --key /tmp/id_rsa --time 72000
Example, same using X509 certificates:
oneuser login my_user --x509 --cert /tmp/my_cert.pem
--key /tmp/my_key.pk --time 72000
Example, now with a X509 proxy certificate
oneuser login my_user --x509_proxy --proxy /tmp/my_cert.pem
--time 72000
EOT
command :login, login_desc, :username, :options=>login_options do
OneUserHelper.login(args[0], options)
options[:time] ||= 36000
helper.login(args[0], options)
end
key_desc = <<-EOT.unindent

217
src/cli/onevcenter Normal file
View File

@ -0,0 +1,217 @@
#!/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"
REMOTES_LOCATION="/var/lib/one/remotes/"
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
REMOTES_LOCATION=ONE_LOCATION+"/var/remotes/"
end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cli"
$: << REMOTES_LOCATION+"vmm/vcenter/"
require 'command_parser'
require 'one_helper/onehost_helper'
require 'one_helper/onecluster_helper'
require 'vcenter_driver'
cmd=CommandParser::CmdParser.new(ARGV) do
usage "`onevcenter` <command> [<args>] [<options>]"
version OpenNebulaHelper::ONE_VERSION
helper = OneHostHelper.new
before_proc do
helper.set_client(options)
end
########################################################################
# Global Options
########################################################################
cmd_options=CommandParser::OPTIONS-[CommandParser::VERBOSE]
set :option, cmd_options+OpenNebulaHelper::CLIENT_OPTIONS
VCENTER = {
:name => "vcenter",
:large => "--vcenter vCenter" ,
:description => "The vCenter hostname",
:format => String
}
USER = {
:name => "vuser",
:large => "--vuser username" ,
:description => "The username to interact with vCenter",
:format => String
}
PASS = {
:name => "vpass",
:large => "--vpass password",
:description => "The password for the user",
:format => String
}
############################################################################
# Import clusters
############################################################################
hosts_desc = <<-EOT.unindent
Import vCenter clusters as OpenNebula hosts
EOT
command :hosts, hosts_desc, :options=>[ VCENTER, USER, PASS ] do
if options[:vuser].nil? ||
options[:vpass].nil? ||
options[:vcenter].nil?
STDERR.puts "vCenter connection parameters are mandatory to import"\
" host:\n"\
"\t --vcenter vCenter hostname\n"\
"\t --vuser username to login in vcenter\n"\
"\t --vpass password for the user"
exit -1
end
begin
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
vc = VCenterDriver::VIClient.new_connection(
:user => options[:vuser],
:password => options[:vpass],
:host => options[:vcenter])
STDOUT.print "done!\n\n"
STDOUT.print "Exploring vCenter resources..."
rs = vc.hierarchy
STDOUT.print "done!\n\n"
rs.each {|dc, cluster|
STDOUT.print "Do you want to process datacenter #{dc} [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
if cluster.empty?
STDOUT.puts " No clusters found in #{dc}..."
next
end
cluster.each{ |c|
STDOUT.print " * Import cluster #{c} [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
r, m = VCenterDriver::VCenterHost.to_one(c, vc)
if r == 0
STDOUT.puts " OpenNebula host #{c} with id #{m}"\
" successfully created."
else
STDOUT.puts " Error: #{m}"
end
STDOUT.puts
}
}
rescue Exception => e
STDOUT.puts "error: #{e.message}"
exit -1
end
exit 0
end
templates_desc = <<-EOT.unindent
Import vCenter VM Templates into OpenNebula
EOT
command :templates, templates_desc, :options=>[ VCENTER, USER, PASS ] do
if options[:vuser].nil? ||
options[:vpass].nil? ||
options[:vcenter].nil?
STDERR.puts "vCenter connection parameters are mandatory to import"\
" VM templates:\n"\
"\t --vcenter vCenter hostname\n"\
"\t --vuser username to login in vcenter\n"\
"\t --vpass password for the user"
exit -1
end
begin
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
vc = VCenterDriver::VIClient.new_connection(
:user => options[:vuser],
:password => options[:vpass],
:host => options[:vcenter])
STDOUT.print "done!\n\n"
STDOUT.print "Looking for VM Templates..."
rs = vc.vm_templates
STDOUT.print "done!\n"
rs.each {|dc, tmps|
STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
if tmps.empty?
STDOUT.print " No VM Templates found in #{dc}...\n\n"
next
end
tmps.each{ |t|
STDOUT.print "\n * VM Template found:\n"\
" - Name : #{t[:name]}\n"\
" - UUID : #{t[:uuid]}\n"\
" - Cluster: #{t[:host]}\n"\
" Import this VM template [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
one_t = ::OpenNebula::Template.new(
::OpenNebula::Template.build_xml, vc.one)
rc = one_t.allocate(t[:one])
if ::OpenNebula.is_error?(rc)
STDOUT.puts " Error creating template: #{rc.message}\n"
else
STDOUT.puts " OpenNebula template #{one_t.id} created!\n"
end
}
}
rescue Exception => e
STDOUT.puts "error: #{e.message}"
exit -1
end
exit 0
end
end

View File

@ -128,7 +128,8 @@ module Instance
end
}
else
template_pool = TemplatePool.new(@client)
user_flag = OpenNebula::Pool::INFO_ALL
template_pool = TemplatePool.new(@client, user_flag)
rc = template_pool.info
if OpenNebula::is_error?(rc)
return rc

View File

@ -584,7 +584,8 @@ int Datastore::from_xml(const string& xml)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Datastore::replace_template(const string& tmpl_str, string& error_str)
int Datastore::replace_template(
const string& tmpl_str, bool keep_restricted, string& error_str)
{
string new_ds_mad;
string new_tm_mad;
@ -609,6 +610,19 @@ int Datastore::replace_template(const string& tmpl_str, string& error_str)
return -1;
}
if (keep_restricted)
{
new_tmpl->remove_restricted();
if (obj_template != 0)
{
obj_template->remove_all_except_restricted();
string aux_error;
new_tmpl->merge(obj_template, aux_error);
}
}
/* ---------------------------------------------------------------------- */
/* Set the TYPE of the Datastore (class & template) */
/* ---------------------------------------------------------------------- */

View File

@ -0,0 +1,48 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << "../../vmm/vcenter/"
require 'vcenter_driver'
host_id = ARGV[4]
if !host_id
exit -1
end
vi_client = VCenterDriver::VIClient.new host_id
vcenter_host = VCenterDriver::VCenterHost.new vi_client
cluster_info = vcenter_host.monitor_cluster
cluster_info << vcenter_host.monitor_host_systems
vm_monitor_info = vcenter_host.monitor_vms
cluster_info << "\nVM_POLL=YES"
cluster_info << "#{vm_monitor_info}" if !vm_monitor_info.empty?
puts cluster_info

View File

@ -112,7 +112,7 @@ class ActionManager
end
arity=@actions[aname][:method].arity
if arity < 0
# Last parameter is an array
arity = -arity - 1
@ -145,7 +145,7 @@ class ActionManager
else
thread = nil
end
if thread
thread.kill
@ -173,17 +173,17 @@ class ActionManager
}
end
end
private
protected
def delete_running_action(action_id)
@action_running.delete(action_id)
end
def get_runable_action
@action_queue.shift
end
def empty_queue
@action_queue.size==0
end
@ -228,13 +228,13 @@ if __FILE__ == $0
@am.register_action(:SLEEP,method("sleep_action"))
# @am.register_action(:SLEEP,Proc.new{|s,i| p s ; sleep(s)})
@am.register_action(:NOP,method("nop_action"))
def @am.get_runable_action
action = super
puts "getting: #{action.inspect}"
action
end
def @am.delete_running_action(action_id)
puts "deleting: #{action_id}"
super(action_id)
@ -250,7 +250,7 @@ if __FILE__ == $0
def nop_action
p " - Just an action"
end
end
s = Sample.new
@ -264,7 +264,7 @@ if __FILE__ == $0
}
s.am.trigger_action(:SLEEP,301,5,301)
s.am.cancel_action(301)
s.am.trigger_action(:FINALIZE,0)

View File

@ -77,7 +77,8 @@ class VirtualMachineDriver < OpenNebulaDriver
# @option options [Boolean] :threaded (true) enables or disables threads
def initialize(directory, options={})
@options={
:threaded => true
:threaded => true,
:single_host => true
}.merge!(options)
super(directory, @options)
@ -214,8 +215,17 @@ class VirtualMachineDriver < OpenNebulaDriver
end
private
# Interface to handle the pending events from the ActionManager Interface
def delete_running_action(action_id)
if @options[:single_host]
delete_running_action_single_host(action_id)
else
super(action_id)
end
end
def delete_running_action_single_host(action_id)
action=@action_running[action_id]
if action
@hosts.delete(action[:host])
@ -224,6 +234,14 @@ private
end
def get_first_runable
if @options[:single_host]
get_first_runable_single_host
else
super
end
end
def get_first_runable_single_host
action_index=nil
@action_queue.each_with_index do |action, index|
if !action.keys.include?(:host)
@ -255,6 +273,14 @@ private
end
def get_runable_action
if @options[:single_host]
get_runable_action_single_host
else
super
end
end
def get_runable_action_single_host
action_index=get_first_runable
if action_index
@ -272,6 +298,14 @@ private
end
def empty_queue
if @options[:single_host]
empty_queue_single_host
else
super
end
end
def empty_queue_single_host
get_first_runable==nil
end
end

View File

@ -464,6 +464,7 @@ void Nebula::start(bool bootstrap_only)
vector<const Attribute *> vm_restricted_attrs;
vector<const Attribute *> img_restricted_attrs;
vector<const Attribute *> vnet_restricted_attrs;
vector<const Attribute *> inherit_image_attrs;
vector<const Attribute *> inherit_datastore_attrs;
@ -483,6 +484,7 @@ void Nebula::start(bool bootstrap_only)
nebula_configuration->get("VM_RESTRICTED_ATTR", vm_restricted_attrs);
nebula_configuration->get("IMAGE_RESTRICTED_ATTR", img_restricted_attrs);
nebula_configuration->get("VNET_RESTRICTED_ATTR", vnet_restricted_attrs);
nebula_configuration->get("INHERIT_IMAGE_ATTR", inherit_image_attrs);
nebula_configuration->get("INHERIT_DATASTORE_ATTR", inherit_datastore_attrs);
@ -512,6 +514,7 @@ void Nebula::start(bool bootstrap_only)
vnpool = new VirtualNetworkPool(db,
mac_prefix,
size,
vnet_restricted_attrs,
vnet_hooks,
remotes_location,
inherit_vnet_attrs);

View File

@ -38,6 +38,7 @@ public class User extends PoolElement{
private static final String QUOTA = METHOD_PREFIX + "quota";
private static final String ADDGROUP = METHOD_PREFIX + "addgroup";
private static final String DELGROUP = METHOD_PREFIX + "delgroup";
private static final String LOGIN = METHOD_PREFIX + "login";
/**
* Creates a new User representation.
@ -221,6 +222,24 @@ public class User extends PoolElement{
return client.call(QUOTA, id, quota_template);
}
/**
* Sets the LOGIN_TOKEN for the user
*
* @param username of the user
* @param token the login token, if empty OpenNebula will
* generate one
* @param expire valid period of the token in secs. If <= 0
* the token will be reset
* @return token in case of success, Error otherwise
*/
public static OneResponse login(Client client,
String username,
String token,
int expire)
{
return client.call(LOGIN, username, token, expire);
}
// =================================
// Instanced object XML-RPC methods
// =================================
@ -352,6 +371,20 @@ public class User extends PoolElement{
return setQuota(client, id, quota_template);
}
/**
* Sets the LOGIN_TOKEN for the user. The method info() must be called before.
*
* @param token the login token, if empty OpenNebula will
* generate one
* @param expire valid period of the token in secs. If <= 0
* the token will be reset
* @return token in case of success, Error otherwise
*/
public OneResponse login(String token, int expire)
{
return client.call(LOGIN, getName(), token, expire);
}
// =================================
// Helpers
// =================================

View File

@ -33,7 +33,8 @@ module OpenNebula
:delgroup => "user.delgroup",
:update => "user.update",
:chauth => "user.chauth",
:quota => "user.quota"
:quota => "user.quota",
:login => "user.login"
}
SELF = -1
@ -185,6 +186,19 @@ module OpenNebula
return rc
end
# Sets the LOGIN_TOKEN for the user
#
# @param username [String] of the user
# @param token [String] the login token, if empty OpenNebula will
# generate one
# @param expire [String] valid period of the token in secs. If <= 0
# the token will be reset
# @return [String, OpenNebula::Error] token in case of success, Error
# otherwise
def login(username, token, expire)
return @client.call(USER_METHODS[:login], username, token, expire)
end
#######################################################################
# Helpers to get User information
#######################################################################

View File

@ -202,9 +202,9 @@ module OpenNebula
# @return [String] The USER_TEMPLATE
def user_template_xml
if NOKOGIRI
@xml.xpath('TEMPLATE').to_s
@xml.xpath('USER_TEMPLATE').to_s
else
@xml.elements['TEMPLATE'].to_s
@xml.elements['USER_TEMPLATE'].to_s
end
end
@ -224,7 +224,11 @@ module OpenNebula
def deploy(host_id, enforce=false, ds_id=-1)
enforce ||= false
ds_id ||= -1
return call(VM_METHODS[:deploy], @pe_id, host_id.to_i, enforce, ds_id.to_i)
return call(VM_METHODS[:deploy],
@pe_id,
host_id.to_i,
enforce,
ds_id.to_i)
end
# Shutdowns an already deployed VM
@ -587,6 +591,11 @@ module OpenNebula
self['GID'].to_i
end
# Returns the deploy_id of the VirtualMachine (numeric value)
def deploy_id
self['DEPLOY_ID']
end
private
def action(name)
return Error.new('ID not defined') if !@pe_id

View File

@ -0,0 +1,68 @@
# -------------------------------------------------------------------------- #
# 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 'nokogiri'
module Migrator
def db_version
"4.9.80"
end
def one_version
"OpenNebula 4.9.80"
end
def up
init_log_time()
########################################################################
# Networks
########################################################################
@db.run "ALTER TABLE network_pool RENAME TO old_network_pool;"
@db.run "CREATE TABLE network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, cid INTEGER, pid INTEGER, UNIQUE(name,uid));"
@db.fetch("SELECT * FROM old_network_pool") do |row|
doc = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks}
parent_st = doc.root.at_xpath("PARENT_NETWORK_ID").text
parent_i = -1
if parent_st != ""
parent_i = parent_st.to_i
end
@db[:network_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => row[:body],
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u],
:cid => row[:cid],
:pid => parent_i)
end
@db.run "DROP TABLE old_network_pool;"
log_time()
return true
end
end

View File

@ -167,7 +167,8 @@ void PoolObjectSQL::clear_template_error_message()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int PoolObjectSQL::replace_template(const string& tmpl_str, string& error)
int PoolObjectSQL::replace_template(
const string& tmpl_str, bool keep_restricted, string& error)
{
Template * new_tmpl = get_new_template();
@ -183,6 +184,19 @@ int PoolObjectSQL::replace_template(const string& tmpl_str, string& error)
return -1;
}
if (keep_restricted)
{
new_tmpl->remove_restricted();
if (obj_template != 0)
{
obj_template->remove_all_except_restricted();
string aux_error;
new_tmpl->merge(obj_template, aux_error);
}
}
delete obj_template;
obj_template = new_tmpl;
@ -193,7 +207,8 @@ int PoolObjectSQL::replace_template(const string& tmpl_str, string& error)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int PoolObjectSQL::append_template(const string& tmpl_str, string& error)
int PoolObjectSQL::append_template(
const string& tmpl_str, bool keep_restricted, string& error)
{
Template * new_tmpl = get_new_template();
@ -209,6 +224,11 @@ int PoolObjectSQL::append_template(const string& tmpl_str, string& error)
return -1;
}
if (keep_restricted)
{
new_tmpl->remove_restricted();
}
if ( obj_template != 0 )
{
obj_template->merge(new_tmpl, error);

View File

@ -695,6 +695,9 @@ void PoolSQL::acl_filter(int uid,
const set<int>& user_groups,
PoolObjectSQL::ObjectType auth_object,
bool& all,
bool disable_all_acl,
bool disable_cluster_acl,
bool disable_group_acl,
string& filter)
{
filter.clear();
@ -719,6 +722,9 @@ void PoolSQL::acl_filter(int uid,
user_groups,
auth_object,
AuthRequest::USE,
disable_all_acl,
disable_cluster_acl,
disable_group_acl,
all,
oids,
gids,

View File

@ -524,6 +524,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::method * user_add_group_pt;
xmlrpc_c::method * user_del_group_pt;
xmlrpc_c::method * user_change_auth_pt;
xmlrpc_c::method * user_login_pt;
if (nebula.is_federation_slave())
{
@ -535,6 +536,7 @@ void RequestManager::register_xml_methods()
user_add_group_pt = new RequestManagerProxy("one.user.addgroup");
user_del_group_pt = new RequestManagerProxy("one.user.delgroup");
user_change_auth_pt = new RequestManagerProxy("one.user.chauth");
user_login_pt = new RequestManagerProxy("one.user.login");
static_cast<RequestManagerProxy*>(user_allocate_pt)->hide_argument(2);
static_cast<RequestManagerProxy*>(user_change_password_pt)->hide_argument(2);
@ -550,6 +552,7 @@ void RequestManager::register_xml_methods()
user_add_group_pt = new UserAddGroup();
user_del_group_pt = new UserDelGroup();
user_change_auth_pt = new UserChangeAuth();
user_login_pt = new UserLogin();
}
xmlrpc_c::methodPtr user_allocate(user_allocate_pt);
@ -560,6 +563,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr user_add_group(user_add_group_pt);
xmlrpc_c::methodPtr user_del_group(user_del_group_pt);
xmlrpc_c::methodPtr user_change_auth(user_change_auth_pt);
xmlrpc_c::methodPtr user_login(user_login_pt);
xmlrpc_c::methodPtr user_info(new UserInfo());
xmlrpc_c::methodPtr user_set_quota(new UserSetQuota());
@ -577,6 +581,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.user.delgroup", user_del_group);
RequestManagerRegistry.addMethod("one.user.chauth", user_change_auth);
RequestManagerRegistry.addMethod("one.user.quota", user_set_quota);
RequestManagerRegistry.addMethod("one.user.login", user_login);
RequestManagerRegistry.addMethod("one.userpool.info", userpool_info);

View File

@ -15,6 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "RequestManagerInfo.h"
#include "RequestManagerPoolInfoFilter.h"
using namespace std;
@ -47,15 +48,15 @@ void RequestManagerInfo::request_execute(xmlrpc_c::paramList const& paramList,
object = pool->get(oid,true);
if ( object == 0 )
{
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
return;
}
}
to_xml(object, str);
to_xml(att, object, str);
object->unlock();
@ -64,3 +65,41 @@ void RequestManagerInfo::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void VirtualNetworkInfo::to_xml(RequestAttributes& att, PoolObjectSQL * object,
string& str)
{
vector<int> vms;
vector<int> vnets;
string where_vnets;
string where_vms;
bool all_reservations = RequestManagerPoolInfoFilter::use_filter(att,
PoolObjectSQL::NET, true, true, false, "(pid != -1)", where_vnets);
bool all_vms = RequestManagerPoolInfoFilter::use_filter(att,
PoolObjectSQL::VM, false, false, false, "", where_vms);
if ( all_reservations == true )
{
vnets.push_back(-1);
}
else
{
Nebula::instance().get_vnpool()->search(vnets, where_vnets);
}
if ( all_vms == true )
{
vms.push_back(-1);
}
else
{
Nebula::instance().get_vmpool()->search(vms, where_vms);
}
static_cast<VirtualNetwork*>(object)->to_xml_extended(str, vms, vnets);
};

View File

@ -23,7 +23,7 @@ using namespace std;
const int RequestManagerPoolInfoFilter::ALL = -2;
const int RequestManagerPoolInfoFilter::MINE = -3;
const int RequestManagerPoolInfoFilter::MINE = -3;
const int RequestManagerPoolInfoFilter::MINE_GROUP = -1;
@ -31,7 +31,7 @@ const int RequestManagerPoolInfoFilter::MINE_GROUP = -1;
const int VirtualMachinePoolInfo::ALL_VM = -2;
const int VirtualMachinePoolInfo::NOT_DONE = -1;
const int VirtualMachinePoolInfo::NOT_DONE = -1;
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
@ -50,6 +50,40 @@ void RequestManagerPoolInfoFilter::request_execute(
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
bool RequestManagerPoolInfoFilter::use_filter(RequestAttributes& att,
PoolObjectSQL::ObjectType aobj,
bool disable_all_acl,
bool disable_cluster_acl,
bool disable_group_acl,
const string& and_str,
string& where_str)
{
bool all;
string acl_str;
string usr_str;
PoolSQL::acl_filter(att.uid, att.group_ids, aobj, all,
disable_all_acl, disable_cluster_acl, disable_group_acl, acl_str);
PoolSQL::usr_filter(att.uid, att.group_ids, ALL, all, acl_str, where_str);
if (!and_str.empty())
{
ostringstream filter;
filter << "( " << where_str << " ) AND ( " << and_str << " )";
where_str = filter.str();
}
return all;
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void VirtualMachinePoolInfo::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
@ -111,11 +145,11 @@ void VirtualMachinePoolAccounting::request_execute(
return;
}
where_filter(att, filter_flag, -1, -1, "", "", where);
where_filter(att, filter_flag, -1, -1, "", "", false, false, false, where);
rc = (static_cast<VirtualMachinePool *>(pool))->dump_acct(oss,
where,
time_start,
where,
time_start,
time_end);
if ( rc != 0 )
{
@ -149,7 +183,7 @@ void VirtualMachinePoolMonitoring::request_execute(
return;
}
where_filter(att, filter_flag, -1, -1, "", "", where);
where_filter(att, filter_flag, -1, -1, "", "", false, false, false, where);
rc = (static_cast<VirtualMachinePool *>(pool))->dump_monitoring(oss, where);
@ -185,7 +219,7 @@ void HostPoolMonitoring::request_execute(
string where;
int rc;
where_filter(att, ALL, -1, -1, "", "", where);
where_filter(att, ALL, -1, -1, "", "", false, false, false, where);
rc = (static_cast<HostPool *>(pool))->dump_monitoring(oss, where);
@ -278,6 +312,9 @@ void RequestManagerPoolInfoFilter::where_filter(
int end_id,
const string& and_clause,
const string& or_clause,
bool disable_all_acl,
bool disable_cluster_acl,
bool disable_group_acl,
string& filter_str)
{
bool empty = true;
@ -289,14 +326,15 @@ void RequestManagerPoolInfoFilter::where_filter(
ostringstream filter;
PoolSQL::acl_filter(att.uid, att.group_ids, auth_object, all, acl_str);
PoolSQL::acl_filter(att.uid, att.group_ids, auth_object, all,
disable_all_acl, disable_cluster_acl, disable_group_acl, acl_str);
PoolSQL::usr_filter(att.uid, att.group_ids, filter_flag, all, acl_str, uid_str);
PoolSQL::oid_filter(start_id, end_id, oid_str);
// -------------------------------------------------------------------------
// Compound WHERE clause
// -------------------------------------------------------------------------
// Compound WHERE clause
// WHERE ( id_str ) AND ( uid_str ) AND ( and_clause ) OR ( or_clause )
// -------------------------------------------------------------------------
@ -370,6 +408,9 @@ void RequestManagerPoolInfoFilter::dump(
end_id,
and_clause,
or_clause,
false,
false,
false,
where_string);
if ( end_id < -1 )
@ -391,3 +432,69 @@ void RequestManagerPoolInfoFilter::dump(
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void VirtualNetworkPoolInfo::request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
{
int filter_flag = xmlrpc_c::value_int(paramList.getInt(1));
int start_id = xmlrpc_c::value_int(paramList.getInt(2));
int end_id = xmlrpc_c::value_int(paramList.getInt(3));
if ( filter_flag < MINE )
{
failure_response(XML_RPC_API,
request_error("Incorrect filter_flag",""),
att);
return;
}
/* ---------------------------------------------------------------------- */
/* Build where filters to get ois from: */
/* - vnets (owner, permissions & ACL) */
/* - reservations (owner, permission & not VNET\* nor VNET/% ACLs) */
/* ---------------------------------------------------------------------- */
string where_vnets, where_reserv;
ostringstream where_string;
where_filter(att, filter_flag, start_id, end_id, "pid == -1", "", false,
false, false, where_vnets);
where_filter(att, filter_flag, -1, -1, "pid != -1", "", true, true, false,
where_reserv);
where_string << "( " << where_vnets << " ) OR ( " << where_reserv << " ) ";
/* ---------------------------------------------------------------------- */
/* Build pagination limits */
/* ---------------------------------------------------------------------- */
ostringstream limit_clause;
if ( end_id < -1 )
{
limit_clause << start_id << "," << -end_id;
}
/* ---------------------------------------------------------------------- */
/* Get the VNET pool */
/* ---------------------------------------------------------------------- */
ostringstream pool_oss;
int rc = pool->dump(pool_oss, where_string.str(), limit_clause.str());
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
return;
}
success_response(pool_oss.str(), att);
return;
}

View File

@ -27,7 +27,14 @@ int RequestManagerUpdateTemplate::replace_template(
const RequestAttributes &att,
string &error_str)
{
return object->replace_template(tmpl, error_str);
if (att.uid!=UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
{
return object->replace_template(tmpl, true, error_str);
}
else
{
return object->replace_template(tmpl, false, error_str);
}
}
/* ------------------------------------------------------------------------- */
@ -39,49 +46,13 @@ int RequestManagerUpdateTemplate::append_template(
const RequestAttributes &att,
string &error_str)
{
return object->append_template(tmpl, error_str);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
int VirtualMachineUpdateTemplate::replace_template(
PoolObjectSQL * object,
const string & tmpl,
const RequestAttributes & att,
string & error_str)
{
VirtualMachine* vm = static_cast<VirtualMachine*>(object);
if (att.uid!=UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
{
return vm->replace_template(tmpl, true, error_str);
return object->append_template(tmpl, true, error_str);
}
else
{
return vm->replace_template(tmpl, false, error_str);
}
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
int VirtualMachineUpdateTemplate::append_template(
PoolObjectSQL * object,
const string & tmpl,
const RequestAttributes & att,
string & error_str)
{
VirtualMachine* vm = static_cast<VirtualMachine*>(object);
if (att.uid!=UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
{
return vm->append_template(tmpl, true, error_str);
}
else
{
return vm->append_template(tmpl, false, error_str);
return object->append_template(tmpl, false, error_str);
}
}

View File

@ -387,3 +387,89 @@ int UserDelGroup::secondary_group_action(
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void UserLogin::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
string uname = xmlrpc_c::value_string(paramList.getString(1));
string token = xmlrpc_c::value_string(paramList.getString(2));
time_t valid = xmlrpc_c::value_int(paramList.getInt(3));
User * user;
string error_str;
PoolObjectAuth perms;
if (att.uid != 0)
{
user = static_cast<UserPool *>(pool)->get(uname,true);
if ( user == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),-1),
att);
return;
}
user->get_permissions(perms);
user->unlock();
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(auth_op, perms);
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
return;
}
}
user = static_cast<UserPool *>(pool)->get(uname,true);
if ( user == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),-1),
att);
return;
}
if (valid == 0) //Reset token
{
user->login_token.reset();
token = "";
}
else if (valid > 0 || valid == -1)
{
token = user->login_token.set(token, valid);
}
else
{
failure_response(XML_RPC_API,
request_error("Wrong valid period for token",""), att);
user->unlock();
return;
}
pool->update(user);
user->unlock();
success_response(token, att);
}

View File

@ -38,6 +38,7 @@ sched_env.Prepend(LIBS=[
'nebula_common',
'nebula_core',
'nebula_template',
'nebula_vm',
'crypto',
'xml2'
])

View File

@ -172,9 +172,13 @@ class OpenNebulaVNC
end
# Proxy data
host = vm_resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']
vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT']
vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD']
host = vm_resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']
vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT']
vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD']
if vm_resource['TEMPLATE/ESX_HOST'] # It is behind a vCenter
host = vm_resource['TEMPLATE/ESX_HOST']
end
# Generate token random_str: host:port
random_str = rand(36**20).to_s(36) #random string a-z0-9 length 20

View File

@ -63,7 +63,7 @@
# opennebula, the authentication will be done by the opennebula core using the
# driver defined for the user
#
:auth: sunstone
:auth: opennebula
# Authentication driver to communicate with OpenNebula core
# cipher, for symmetric cipher encryption of tokens
@ -189,3 +189,4 @@
:routes:
- oneflow
- vcenter

View File

@ -30,5 +30,6 @@ groups:
- vdcadmin
- user
- cloud
- vcenter
default:
- cloud

View File

@ -327,7 +327,7 @@ tabs:
Datastore.delete: false
vnets-tab:
panel_tabs:
vnet_info_tab: false
vnet_info_tab: true
vnet_ar_list_tab: true
vnet_leases_tab: true
table_columns:
@ -353,7 +353,7 @@ tabs:
Network.release_lease: true
Network.add_ar: false
Network.remove_ar: true
Network.update_ar: false
Network.update_ar: true
marketplace-tab:
panel_tabs:
marketplace_info_tab: true

View File

@ -0,0 +1,460 @@
small_logo: images/opennebula-sunstone-v4.0-small.png
provision_logo: images/one_small_logo.png
enabled_tabs:
dashboard-tab: true
system-tab: true
users-tab: true
groups-tab: true
acls-tab: true
vresources-tab: true
vms-tab: true
templates-tab: true
images-tab: false
files-tab: false
infra-tab: true
clusters-tab: true
hosts-tab: true
datastores-tab: false
vnets-tab: false
marketplace-tab: true
oneflow-dashboard: true
oneflow-services: true
oneflow-templates: true
support-tab: true
doc-tab: true
community-tab: true
enterprise-tab: true
zones-tab: true
autorefresh: true
tabs:
dashboard-tab:
panel_tabs:
actions:
Dashboard.refresh: false
Sunstone.toggle_top: false
widgets_three_per_row:
- storage
- users
- network
widgets_two_per_row:
# - user_quotas
# - group_quotas
widgets_one_per_row:
- vms
- hosts
widgets_one_footer:
# - accounting
system-tab:
panel_tabs:
actions:
users-tab:
panel_tabs:
user_info_tab: true
user_quotas_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Name
- 3 # Group
- 4 # Auth driver
- 5 # VMs
- 6 # Memory
- 7 # CPU
#- 8 # Group ID
#- 9 # Hidden User Data
actions:
User.refresh: true
User.create_dialog: true
User.update_password: true
User.quotas_dialog: true
User.chgrp: true
User.addgroup: true
User.delgroup: true
User.chauth: true
User.delete: true
groups-tab:
panel_tabs:
group_quotas_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Name
- 3 # Users
- 4 # VMs
- 5 # Memory
- 6 # CPU
actions:
Group.refresh: true
Group.create_dialog: true
Group.quotas_dialog: true
Group.delete: true
acls-tab:
panel_tabs:
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Applies to
- 3 # Affected resources
- 4 # Resource ID / Owned by
- 5 # Allowed operations
- 6 # Zone
#- 7 # ACL String
actions:
Acl.refresh: true
Acl.create_dialog: true
Acl.delete: true
vresources-tab:
panel_tabs:
actions:
vms-tab:
panel_tabs:
vm_info_tab: true
vm_capacity_tab: true
vm_hotplugging_tab: false
vm_network_tab: false
vm_snapshot_tab: true
vm_placement_tab: true
vm_actions_tab: true
vm_template_tab: true
vm_log_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Owner
- 3 # Group
- 4 # Name
- 5 # Status
#- 6 # Used CPU
#- 7 # Used Memory
- 8 # Host
- 9 # IPs
#- 10 # Start Time
- 11 # VNC
actions:
VM.refresh: true
VM.create_dialog: true
VM.chown: true
VM.chgrp: true
VM.chmod: true
VM.deploy: true
VM.migrate: false
VM.migrate_live: false
VM.hold: true
VM.release: true
VM.suspend: true
VM.resume: true
VM.stop: true
VM.recover: true
VM.boot: true
VM.reboot: true
VM.reboot_hard: true
VM.poweroff: true
VM.poweroff_hard: true
VM.undeploy: true
VM.undeploy_hard: true
VM.shutdown: true
VM.shutdown_hard: true
VM.delete: true
VM.delete_recreate: true
VM.resize: true
VM.attachdisk: true
VM.detachdisk: true
VM.saveas: false
VM.attachnic: false
VM.detachnic: false
VM.snapshot_create: true
VM.snapshot_revert: true
VM.snapshot_delete: true
VM.resched: true
VM.unresched: true
templates-tab:
panel_tabs:
template_info_tab: true
template_template_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Owner
- 3 # Group
- 4 # Name
- 5 # Registration time
actions:
Template.refresh: true
Template.create_dialog: true
Template.update_dialog: true
Template.instantiate_vms: true
Template.chown: true
Template.chgrp: true
Template.chmod: true
Template.clone_dialog: true
Template.delete: true
template_creation_tabs:
general: true
storage: true
network: true
os_booting: true
features: true
input_output: true
context: true
scheduling: true
other: true
images-tab:
panel_tabs:
image_info_tab: true
image_vms_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Owner
- 3 # Group
- 4 # Name
- 5 # Datastore
#- 6 # Size
- 7 # Type
#- 8 # Registration time
#- 9 # Persistent
- 10 # Status
- 11 # #VMs
#- 12 # Target
actions:
Image.refresh: true
Image.create_dialog: true
Image.chown: true
Image.chgrp: true
Image.chmod: true
Image.enable: true
Image.disable: true
Image.persistent: true
Image.nonpersistent: true
Image.clone_dialog: true
Image.delete: true
files-tab:
panel_tabs:
file_info_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Owner
- 3 # Group
- 4 # Name
- 5 # Datastore
#- 6 # Size
- 7 # Type
#- 8 # Registration time
#- 9 # Persistent
- 10 # Status
#- 11 # #VMs
#- 12 # Target
actions:
File.refresh: true
File.create_dialog: true
File.chown: true
File.chgrp: true
File.chmod: true
File.enable: true
File.disable: true
File.delete: true
infra-tab:
panel_tabs:
actions:
clusters-tab:
panel_tabs:
cluster_info_tab: true
cluster_host_tab: true
cluster_vnet_tab: true
cluster_datastore_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Name
- 3 # Hosts
- 4 # VNets
- 5 # Datastores
actions:
Cluster.refresh: true
Cluster.create_dialog: true
Cluster.update_dialog: true
Cluster.delete: true
hosts-tab:
panel_tabs:
host_info_tab: true
host_monitoring_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Name
- 3 # Cluster
- 4 # RVMs
#- 5 # Real CPU
- 6 # Allocated CPU
#- 7 # Real MEM
- 8 # Allocated MEM
- 9 # Status
#- 10 # IM MAD
#- 11 # VM MAD
#- 12 # Last monitored on
actions:
Host.refresh: true
Host.create_dialog: true
Host.addtocluster: true
Host.enable: true
Host.disable: true
Host.delete: true
datastores-tab:
panel_tabs:
datastore_info_tab: true
datastore_image_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Owner
- 3 # Group
- 4 # Name
- 5 # Capacity
- 6 # Cluster
#- 7 # Basepath
#- 8 # TM
#- 9 # DS
- 10 # Type
actions:
Datastore.refresh: true
Datastore.create_dialog: true
Datastore.addtocluster: true
Datastore.chown: true
Datastore.chgrp: true
Datastore.chmod: true
Datastore.delete: true
vnets-tab:
panel_tabs:
vnet_info_tab: true
vnet_ar_list_tab: true
vnet_leases_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Owner
- 3 # Group
- 4 # Name
- 5 # Reservation
- 6 # Cluster
#- 7 # Bridge
- 8 # Leases
#- 9 # VLAN ID
actions:
Network.refresh: true
Network.create_dialog: true
Network.addtocluster: true
Network.chown: true
Network.chgrp: true
Network.chmod: true
Network.delete: true
Network.hold_lease: true
Network.release_lease: true
Network.add_ar: true
Network.remove_ar: true
Network.update_ar: true
marketplace-tab:
panel_tabs:
marketplace_info_tab: true
table_columns:
- 0 # Checkbox
#- 1 # ID
- 2 # Name
- 3 # Publisher
- 4 # Hypervisor
- 5 # Arch
- 6 # Format
#- 7 # Tags
actions:
Marketplace.refresh: true
Marketplace.import: true
oneflow-dashboard:
panel_tabs:
table_columns:
actions:
oneflow-services:
panel_tabs:
service_info_tab: true
service_roles_tab: true
service_log_tab: true
panel_tabs_actions:
service_roles_tab:
Role.scale: true
Role.hold: true
Role.release: true
Role.suspend: true
Role.resume: true
Role.stop: true
Role.boot: true
Role.reboot: true
Role.reboot_hard: true
Role.poweroff: true
Role.poweroff_hard: true
Role.shutdown: true
Role.shutdown_hard: true
Role.delete: true
Role.delete_recreate: true
RoleVM.hold: true
RoleVM.release: true
RoleVM.suspend: true
RoleVM.resume: true
RoleVM.stop: true
RoleVM.boot: true
RoleVM.reboot: true
RoleVM.reboot_hard: true
RoleVM.poweroff: true
RoleVM.poweroff_hard: true
RoleVM.undeploy: true
RoleVM.undeploy_hard: true
RoleVM.shutdown: true
RoleVM.shutdown_hard: true
RoleVM.delete: true
RoleVM.delete_recreate: true
RoleVM.resched: true
RoleVM.unresched: true
RoleVM.recover: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Owner
- 3 # Group
- 4 # Name
- 5 # State
actions:
Service.refresh: true
Service.chown: true
Service.chgrp: true
Service.chmod: true
Service.shutdown: true
Service.recover: true
Service.delete: true
oneflow-templates:
panel_tabs:
service_template_info_tab: true
service_template_roles_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Owner
- 3 # Group
- 4 # Name
actions:
ServiceTemplate.refresh: true
ServiceTemplate.create_dialog: true
ServiceTemplate.instantiate: true
ServiceTemplate.chown: true
ServiceTemplate.chgrp: true
ServiceTemplate.chmod: true
ServiceTemplate.delete: true
zones-tab:
panel_tabs:
zone_info_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Name
- 3 # Endpoint
actions:
Zone.refresh: true
Zone.create_dialog: true
Zone.delete: true

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -28,8 +28,18 @@ var create_host_tmpl =
<form id="create_host_form" action="" class="">\
<div class="row">\
<div class="large-6 columns">\
<label for="name">' + tr("Hostname") + '</label>\
<input type="text" name="name" id="name" />\
<label for="host_type">' + tr("Type") + '</label>\
<select id="host_type_mad" name="host_type">\
<option value="kvm">' + tr("KVM") + '</option>\
<option value="xen">' + tr("XEN") + '</option>\
<option value="vmware">' + tr("VMware") + '</option>\
<option value="vcenter">' + tr("vCenter") + '</option>\
<option value="az">' + tr("Microsoft Azure") + '</option>\
<option value="ec2">' + tr("Amazon EC2") + '</option>\
<option value="sl">' + tr("IBM Softlayer") + '</option>\
<option value="dummy">' + tr("Dummy") + '</option>\
<option value="custom">' + tr("Custom") + '</option>\
</select>\
</div>\
<div class="large-6 columns" id="cluster_select">\
<label for="host_cluster_id">' + tr("Cluster") + '</label>\
@ -38,18 +48,9 @@ var create_host_tmpl =
</div>\
</div>\
<div class="row">\
<div class="large-6 columns">\
<label for="host_type">' + tr("Type") + '</label>\
<select id="host_type_mad" name="host_type">\
<option value="kvm">' + tr("KVM") + '</option>\
<option value="xen">' + tr("XEN") + '</option>\
<option value="vmware">' + tr("VMware") + '</option>\
<option value="az">' + tr("Microsoft Azure") + '</option>\
<option value="ec2">' + tr("Amazon EC2") + '</option>\
<option value="sl">' + tr("IBM Softlayer") + '</option>\
<option value="dummy">' + tr("Dummy") + '</option>\
<option value="custom">' + tr("Custom") + '</option>\
</select>\
<div class="large-6 columns" id="name_container">\
<label for="name">' + tr("Hostname") + '</label>\
<input type="text" name="name" id="name" />\
</div>\
<div class="large-6 columns">\
<div class="manager clear row" id="vnm_mads">\
@ -84,6 +85,7 @@ var create_host_tmpl =
<option value="kvm">' + tr("KVM") + '</option>\
<option value="xen">' + tr("XEN") + '</option>\
<option value="vmware">' + tr("VMware") + '</option>\
<option value="vcenter">' + tr("vCenter") + '</option>\
<option value="az">' + tr("Microsoft Azure") + '</option>\
<option value="ec2">' + tr("Amazon EC2") + '</option>\
<option value="sl">' + tr("IBM Softlayer") + '</option>\
@ -105,6 +107,7 @@ var create_host_tmpl =
<option value="kvm">' + tr("KVM") + '</option>\
<option value="xen">' + tr("XEN") + '</option>\
<option value="vmware">' + tr("VMware") + '</option>\
<option value="vcenter">' + tr("vCenter") + '</option>\
<option value="az">' + tr("Microsoft Azure") + '</option>\
<option value="ec2">' + tr("Amazon EC2") + '</option>\
<option value="sl">' + tr("IBM Softlayer") + '</option>\
@ -121,6 +124,39 @@ var create_host_tmpl =
</div>\
</fieldset>\
</div>\
<div class="row vcenter_credentials hidden">\
<fieldset>\
<legend>'+tr("vCenter")+'</legend>\
<div class="row">\
<div class="large-6 columns">\
<label for="vcenter_user">' + tr("User") + '</label>\
<input type="text" name="vcenter_user" id="vcenter_user" />\
</div>\
<div class="large-6 columns">\
<label for="vcenter_host">' + tr("Hostname") + '</label>\
<input type="text" name="vcenter_host" id="vcenter_host" />\
</div>\
</div>\
<div class="row">\
<div class="large-6 columns">\
<label for="vcenter_password">' + tr("Password") + '</label>\
<input type="password" name="vcenter_password" id="vcenter_password" />\
</div>\
<div class="large-6 columns">\
<br>\
<a class="button radius small right" id="get_vcenter_clusters">'+tr("Get vCenter Clusters")+'</a>\
</div>\
</div>\
<div class="vcenter_clusters">\
</div>\
<div class="row import_vcenter_clusters_div hidden">\
<div class="large-12 columns">\
<br>\
<a class="button radius small right success" id="import_vcenter_clusters">'+tr("Import vCenter Clusters and Templates")+'</a>\
</div>\
</div>\
</fieldset>\
</div>\
<br>\
<div class="form_buttons row">\
<button id="wizard_host_reset_button" class="button secondary radius" type="reset" value="reset">' + tr("Reset") + '</button>\
@ -145,10 +181,6 @@ var host_actions = {
call : OpenNebula.Host.create,
callback : function(request, response) {
// Reset the create wizard
$create_host_dialog.foundation('reveal', 'close');
$create_host_dialog.empty();
setupCreateHostDialog();
addHostElement(request, response);
notifyCustom(tr("Host created"), " ID: " + response.HOST.ID, false);
},
@ -431,65 +463,79 @@ function hostElements(){
return getSelectedNodes(dataTable_hosts);
}
function generateCPUProgressBar(host) {
var max_cpu = parseInt(host.HOST_SHARE.MAX_CPU);
function generateCPUProgressBar(host, host_share_flag) {
var host_share = host_share_flag ? host : host.HOST_SHARE;
var max_cpu = parseInt(host_share.MAX_CPU);
var info_str;
var allocated_cpu = parseInt(host.HOST_SHARE.CPU_USAGE);
var pb_allocated_cpu
if (host_share.CPU_USAGE) {
var allocated_cpu = parseInt(host_share.CPU_USAGE);
if (max_cpu > 0) {
var ratio_allocated_cpu = Math.round((allocated_cpu / max_cpu) * 100);
info_str = allocated_cpu + ' / ' + max_cpu + ' (' + ratio_allocated_cpu + '%)';
} else {
info_str = "";
if (max_cpu > 0) {
var ratio_allocated_cpu = Math.round((allocated_cpu / max_cpu) * 100);
info_str = allocated_cpu + ' / ' + max_cpu + ' (' + ratio_allocated_cpu + '%)';
} else {
info_str = "";
}
pb_allocated_cpu = quotaBarHtml(allocated_cpu, max_cpu, info_str);
}
var pb_allocated_cpu = quotaBarHtml(allocated_cpu, max_cpu, info_str);
var pb_real_cpu
if (host_share.USED_CPU) {
var real_cpu = parseInt(host_share.USED_CPU);
var real_cpu = parseInt(host.HOST_SHARE.USED_CPU);
if (max_cpu > 0) {
var ratio_real_cpu = Math.round((real_cpu / max_cpu) * 100);
info_str = real_cpu + ' / ' + max_cpu + ' (' + ratio_real_cpu + '%)';
} else {
info_str = "";
}
if (max_cpu > 0) {
var ratio_real_cpu = Math.round((real_cpu / max_cpu) * 100);
info_str = real_cpu + ' / ' + max_cpu + ' (' + ratio_real_cpu + '%)';
} else {
info_str = "";
pb_real_cpu = quotaBarHtml(real_cpu, max_cpu, info_str);
}
var pb_real_cpu = quotaBarHtml(real_cpu, max_cpu, info_str);
return {
real: pb_real_cpu,
allocated: pb_allocated_cpu
}
}
function generateMEMProgressBar(host){
function generateMEMProgressBar(host, host_share_flag) {
var host_share = host_share_flag ? host : host.HOST_SHARE;
// Generate MEM progress bars
var max_mem = parseInt(host.HOST_SHARE.MAX_MEM);
var max_mem = parseInt(host_share.MAX_MEM);
var allocated_mem = parseInt(host.HOST_SHARE.MEM_USAGE);
var pb_allocated_mem;
if (host_share.MEM_USAGE) {
var allocated_mem = parseInt(host_share.MEM_USAGE);
if (max_mem > 0) {
var ratio_allocated_mem = Math.round((allocated_mem / max_mem) * 100);
info_str = humanize_size(allocated_mem) + ' / ' + humanize_size(max_mem) + ' (' + ratio_allocated_mem + '%)';
} else {
info_str = humanize_size(allocated_mem) + ' / -';
if (max_mem > 0) {
var ratio_allocated_mem = Math.round((allocated_mem / max_mem) * 100);
info_str = humanize_size(allocated_mem) + ' / ' + humanize_size(max_mem) + ' (' + ratio_allocated_mem + '%)';
} else {
info_str = humanize_size(allocated_mem) + ' / -';
}
pb_allocated_mem = quotaBarHtml(allocated_mem, max_mem, info_str);
}
var pb_allocated_mem = quotaBarHtml(allocated_mem, max_mem, info_str);
var pb_real_mem;
if (host_share.USED_MEM) {
var real_mem = parseInt(host_share.USED_MEM);
var real_mem = parseInt(host.HOST_SHARE.USED_MEM);
if (max_mem > 0) {
var ratio_real_mem = Math.round((real_mem / max_mem) * 100);
info_str = humanize_size(real_mem) + ' / ' + humanize_size(max_mem) + ' (' + ratio_real_mem + '%)';
} else {
info_str = humanize_size(real_mem) + ' / -';
}
if (max_mem > 0) {
var ratio_real_mem = Math.round((real_mem / max_mem) * 100);
info_str = humanize_size(real_mem) + ' / ' + humanize_size(max_mem) + ' (' + ratio_real_mem + '%)';
} else {
info_str = humanize_size(real_mem) + ' / -';
pb_real_mem = quotaBarHtml(real_mem, max_mem, info_str);
}
var pb_real_mem = quotaBarHtml(real_mem, max_mem, info_str);
return {
real: pb_real_mem,
allocated: pb_allocated_mem
@ -859,13 +905,61 @@ function updateHostInfo(request,host){
</div>'
}
var esx_info_tab = {
title: tr("ESX"),
icon: "fa-hdd-o",
content : '<div id="datatable_host_esx_info_div" class="row">\
<div class="large-12 columns">\
<table id="datatable_host_esx" class="datatable twelve">\
<thead>\
<tr>\
<th>' + tr("Hostname") + '</th>\
<th>' + tr("Status") + '</th>\
<th>' + tr("Real CPU") + '</th>\
<th>' + tr("Real Memory") + '</th>\
</tr>\
</thead>\
<tbody id="tbody_host_esx">\
</tbody>\
</table>\
</div>\
</div>'
}
//Sunstone.updateInfoPanelTab(info_panel_name,tab_name, new tab object);
Sunstone.updateInfoPanelTab("host_info_panel","host_info_tab",info_tab);
Sunstone.updateInfoPanelTab("host_info_panel","host_monitoring_tab",monitor_tab);
Sunstone.updateInfoPanelTab("host_info_panel","host_vms_tab",vms_info_tab);
if (host_info.TEMPLATE.HYPERVISOR == "vcenter") {
Sunstone.updateInfoPanelTab("host_info_panel","host_esx_tab",esx_info_tab);
}
Sunstone.popUpInfoPanel("host_info_panel", "hosts-tab");
if (host_info.TEMPLATE.HYPERVISOR == "vcenter") {
var dataTable_esx_hosts = $("#datatable_host_esx",main_tabs_context).dataTable({
"bSortClasses" : false,
"bDeferRender": true
});
var host_list_array = [];
$.each(host_info.TEMPLATE.HOST, function(){
var cpu_bars = generateCPUProgressBar(this, true);
var mem_bars = generateMEMProgressBar(this, true);
host_list_array.push([
this.HOSTNAME,
this.STATE,
cpu_bars.real,
mem_bars.real
]);
});
dataTable_esx_hosts.fnAddData(host_list_array);
delete host_info.TEMPLATE.HOST;
}
var dataTable_host_vMachines = $("#datatable_host_vms", $("#host_info_panel")).dataTable({
"bSortClasses" : false,
"bDeferRender": true,
@ -931,6 +1025,12 @@ function setupCreateHostDialog(){
$create_host_dialog.addClass("reveal-modal medium").attr("data-reveal", "");
$create_host_dialog.foundation()
$("#wizard_host_reset_button", $create_host_dialog).on("click", function(){
$('#create_host_dialog').html("");
setupCreateHostDialog();
popUpCreateHostDialog();
})
$(".drivers", $create_host_dialog).hide();
$("#host_type_mad", $create_host_dialog).on("change", function(){
@ -938,12 +1038,276 @@ function setupCreateHostDialog(){
$("#im_mad", $create_host_dialog).val(this.value).change();
if (this.value == "custom") {
$(".vcenter_credentials", $create_host_dialog).hide();
$("#vnm_mads", $create_host_dialog).show();
$("#name_container", $create_host_dialog).show();
$("#create_host_submit", $create_host_dialog).show();
$(".drivers", $create_host_dialog).show();
} else if (this.value == "vcenter") {
$("#vnm_mads", $create_host_dialog).hide();
$("#name_container", $create_host_dialog).hide();
$(".vcenter_credentials", $create_host_dialog).show();
$("#create_host_submit", $create_host_dialog).hide();
$(".drivers", $create_host_dialog).hide();
} else {
$(".vcenter_credentials", $create_host_dialog).hide();
$("#vnm_mads", $create_host_dialog).show();
$("#name_container", $create_host_dialog).show();
$("#create_host_submit", $create_host_dialog).show();
$(".drivers", $create_host_dialog).hide();
}
})
$("#get_vcenter_clusters", $create_host_dialog).on("click", function(){
// TODO notify if credentials empty
$(".vcenter_clusters", $create_host_dialog).html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>')
$.ajax({
url: '/vcenter',
type: "GET",
data: {timeout: false},
dataType: "json",
headers: {
"X_VCENTER_USER": $("#vcenter_user", $create_host_dialog).val(),
"X_VCENTER_PASSWORD": $("#vcenter_password", $create_host_dialog).val(),
"X_VCENTER_HOST": $("#vcenter_host", $create_host_dialog).val()
},
success: function(response){
$("#vcenter_user", $create_host_dialog).attr("disabled", "disabled")
$("#vcenter_password", $create_host_dialog).attr("disabled", "disabled")
$("#vcenter_host", $create_host_dialog).attr("disabled", "disabled")
$("#get_vcenter_clusters", $create_host_dialog).hide();
$(".import_vcenter_clusters_div", $create_host_dialog).show();
var vcenter_container = $(".vcenter_clusters", $create_host_dialog);
vcenter_container.html("");
$('<div class="row">' +
'<div class="large-12 columns">' +
'<p style="color: #999">' + tr("Please select the vCenter Clusters to be imported to OpenNebula. Each vCenter Cluster will be included as a new OpenNebula Host") + '</p>' +
'</div>' +
'</div>').appendTo(vcenter_container)
$.each(response, function(datacenter_name, clusters){
$('<div class="row">' +
'<div class="large-12 columns">' +
'<h5>' +
datacenter_name + ' ' + tr("Clusters") +
'</h5>' +
'</div>' +
'</div>').appendTo(vcenter_container)
if (clusters.length == 0) {
$('<div class="row">' +
'<div class="large-12 columns">' +
'<label>' +
tr("No clusters found in this DataCenter") +
'</label>' +
'</div>' +
'</div>').appendTo(vcenter_container)
} else {
$.each(clusters, function(id, cluster_name){
var row = $('<div class="vcenter_cluster">' +
'<div class="row">' +
'<div class="large-10 columns">' +
'<label>' +
'<input type="checkbox" class="cluster_name"/> ' +
cluster_name +
'</label>' +
'<div class="large-12 columns vcenter_host_response">'+
'</div>'+
'</div>' +
'<div class="large-2 columns vcenter_host_result">'+
'</div>'+
'</div>'+
'<div class="vcenter_templates">'+
'</div>'+
'</div>').appendTo(vcenter_container)
$(".cluster_name", row).data("cluster_name", cluster_name)
$(".cluster_name", row).data("datacenter_name", datacenter_name)
$(".cluster_name", row).on("change", function(){
var templates_container = $(".vcenter_templates", $(this).closest(".vcenter_cluster"));
if ($(this).is(":checked")) {
var path = '/vcenter/' + $(this).data("datacenter_name") + '/cluster/' + $(this).data("cluster_name");
templates_container.html(generateAdvancedSection({
html_id: path,
title: tr("Templates"),
content: '<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>'
}))
$('a', templates_container).trigger("click")
$.ajax({
url: path,
type: "GET",
data: {timeout: false},
dataType: "json",
headers: {
"X_VCENTER_USER": $("#vcenter_user", $create_host_dialog).val(),
"X_VCENTER_PASSWORD": $("#vcenter_password", $create_host_dialog).val(),
"X_VCENTER_HOST": $("#vcenter_host", $create_host_dialog).val()
},
success: function(response){
$(".content", templates_container).html("");
$.each(response, function(id, template){
var trow = $('<div class="vcenter_template">' +
'<div class="row">' +
'<div class="large-10 columns">' +
'<label>' +
'<input type="checkbox" class="template_name" checked/> ' +
template.name + '&emsp;<span style="color: #999">' + template.uuid + '</span>' +
'</label>' +
'<div class="large-12 columns vcenter_template_response">'+
'</div>'+
'</div>' +
'<div class="large-2 columns vcenter_template_result">'+
'</div>'+
'</div>'+
'<div class="vcenter_templates">'+
'</div>'+
'</div>').appendTo($(".content", templates_container))
$(".template_name", trow).data("template_name", template.name)
$(".template_name", trow).data("one_template", template.one)
});
},
error: function(response){
templates_container.html("");
onError({}, OpenNebula.Error(response));
}
});
} else {
templates_container.html("");
}
})
});
}
});
},
error: function(response){
$(".vcenter_clusters", $create_host_dialog).html('')
onError({}, OpenNebula.Error(response));
}
});
return false;
})
$("#import_vcenter_clusters", $create_host_dialog).on("click", function(){
$(this).hide();
var cluster_id = $('#host_cluster_id .resource_list_select', $create_host_dialog).val();
if (!cluster_id) cluster_id = "-1";
$.each($(".cluster_name:checked", $create_host_dialog), function(){
var cluster_context = $(this).closest(".vcenter_cluster");
$(".vcenter_host_result:not(.success)", cluster_context).html('<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>');
var host_json = {
"host": {
"name": $(this).data("cluster_name"),
"vm_mad": "vcenter",
"vnm_mad": "dummy",
"im_mad": "vcenter",
"cluster_id": cluster_id
}
};
OpenNebula.Host.create({
timeout: true,
data: host_json,
success: function(request, response) {
OpenNebula.Helper.clear_cache("HOST");
$(".vcenter_host_result", cluster_context).addClass("success").html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-check fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_host_response", cluster_context).html('<p style="font-size:12px" class="running-color">'+
tr("Host created successfully")+' ID:'+response.HOST.ID+
'</p>');
var template_raw =
"VCENTER_USER=\"" + $("#vcenter_user", $create_host_dialog).val() + "\"\n" +
"VCENTER_PASSWORD=\"" + $("#vcenter_password", $create_host_dialog).val() + "\"\n" +
"VCENTER_HOST=\"" + $("#vcenter_host", $create_host_dialog).val() + "\"\n";
Sunstone.runAction("Host.update_template", response.HOST.ID, template_raw);
addHostElement(request, response);
$.each($(".template_name:checked", cluster_context), function(){
var template_context = $(this).closest(".vcenter_template");
$(".vcenter_template_result:not(.success)", template_context).html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>');
var template_json = {
"vmtemplate": {
"template_raw": $(this).data("one_template")
}
};
OpenNebula.Template.create({
timeout: true,
data: template_json,
success: function(request, response) {
OpenNebula.Helper.clear_cache("VMTEMPLATE");
$(".vcenter_template_result", template_context).addClass("success").html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-check fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_template_response", template_context).html('<p style="font-size:12px" class="running-color">'+
tr("Template created successfully")+' ID:'+response.VMTEMPLATE.ID+
'</p>');
},
error: function (request, error_json){
$(".vcenter_template_result", template_context).html('<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-warning fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_template_response", template_context).html('<p style="font-size:12px" class="error-color">'+
(error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+
'</p>');
}
});
})
},
error: function (request, error_json){
$(".vcenter_host_result", context).html('<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-warning fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_host_response", context).html('<p style="font-size:12px" class="error-color">'+
(error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+
'</p>');
}
});
})
return false
});
// Show custom driver input only when custom is selected in selects
$('input[name="custom_vmm_mad"],'+
'input[name="custom_im_mad"],'+
@ -1007,13 +1371,17 @@ function setupCreateHostDialog(){
//Open creation dialogs
function popUpCreateHostDialog(){
$create_host_dialog.foundation('reveal', 'close');
$create_host_dialog.empty();
setupCreateHostDialog();
var cluster_id = $('#host_cluster_id .resource_list_select',$('div#create_host_dialog')).val();
if (!cluster_id) cluster_id = "-1";
insertSelectOptions('#host_cluster_id',$('div#create_host_dialog'), "Cluster", cluster_id, false);
$('div#create_host_dialog').foundation('reveal', 'open');
$("input#name",$('div#create_host_dialog')).focus();
$("#create_host_dialog").foundation('reveal', 'open');
$("input#name",$("#create_host_dialog")).focus();
return false;
}

View File

@ -104,7 +104,7 @@ var market_actions = {
'<div class="large-2 columns market_image_result">'+
'</div>'+
'</div>'+
'<div class="large-10 large-centered columns market_image_response">'+
'<div class="large-10 columns market_image_response">'+
'</div>'+
'</div>').appendTo($("#market_import_dialog_content"));
})
@ -132,7 +132,7 @@ var market_actions = {
'<div class="large-2 columns market_template_result">'+
'</div>'+
'</div>'+
'<div class="large-10 large-centered columns market_template_response">'+
'<div class="large-10 columns market_template_response">'+
'</div>'+
'</div>').appendTo($("#market_import_dialog_content"));
}

View File

@ -1498,7 +1498,7 @@ function provision_list_vms(opts_arg){
'<div id="provision_list_vm_accordion'+list_vms_accordion_id+'" class="content '+ (opts.active ? 'active' : '') +'">'+
'<div class="row">'+
'<div class="large-12 large-centered columns">'+
'<table class="provision_vms_table" '+ (opts.data ? "data='"+JSON.stringify(opts.data)+"'" : "") +'>'+
'<table class="provision_vms_table">'+
'<thead class="hidden">'+
'<tr>'+
'<th>'+tr("ID")+'</th>'+
@ -2092,8 +2092,8 @@ function generate_provision_instance_type_accordion(context, capacity) {
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var data = aData;
$(".provision_instance_types_ul", context).append('<li>'+
'<ul class="provision-pricing-table hoverable only-one" cpu="'+data.cpu+'" memory="'+data.memory+'" data=\''+JSON.stringify(data)+'\'>'+
var li = $('<li>'+
'<ul class="provision-pricing-table hoverable only-one" cpu="'+data.cpu+'" memory="'+data.memory+'">'+
'<li class="provision-title" title="'+data.name+'">'+
data.name+
'</li>'+
@ -2112,7 +2112,9 @@ function generate_provision_instance_type_accordion(context, capacity) {
(data.description || '')+
'</li>'+
'</ul>'+
'</li>');
'</li>').appendTo($(".provision_instance_types_ul", context));
$(".provision-pricing-table", li).data("opennebula", data)
return nRow;
}
@ -3063,10 +3065,9 @@ function update_provision_vms_datatable(datatable, timeout) {
'</span>'+
'</div>');
if (datatable.attr('data')) {
fill_provision_vms_datatable(
datatable,
JSON.parse(datatable.attr('data')))
var data = datatable.data('opennebula');
if (data) {
fill_provision_vms_datatable(datatable, data)
} else {
setTimeout( function(){
OpenNebula.VM.list({
@ -4066,6 +4067,11 @@ function setup_provision_vms_list(context, opts) {
function generate_provision_vms_list(context, opts) {
context.off();
context.html(provision_list_vms(opts));
if (opts.data) {
$(".provision_vms_table", context).data("opennebula", opts.data)
}
setup_provision_vms_list(context, opts);
setup_info_vm(context);
}
@ -4492,9 +4498,9 @@ function setup_info_flow(context) {
percentage : Math.floor((role.nodes ? role.nodes.length : 0) / role.cardinality)*100
}
$(".provision_roles_ul", context).append(
var li = $(
'<li>'+
'<ul class="provision_role_ul provision-pricing-table" role=\''+JSON.stringify(role)+'\'>'+
'<ul class="provision_role_ul provision-pricing-table">'+
'<li class="provision-title text-left">'+
'<i class="fa fa-fw fa-cube"/>&emsp;'+
role.name+
@ -4522,7 +4528,9 @@ function setup_info_flow(context) {
'</a>'+
'</li>'+
'</ul>'+
'</li>');
'</li>').appendTo($(".provision_roles_ul", context));
$(".provision_role_ul", li).data("role", role);
});
}
@ -4548,12 +4556,14 @@ function setup_info_flow(context) {
'</span>'+
'</div>');
var role_json = $(this).closest(".provision_role_ul").attr('role');
var role = JSON.parse(role_json);
var role = $(this).closest(".provision_role_ul").data('role');
var vms = []
$.each(role.nodes, function(index, node){
vms.push(node.vm_info);
})
if (role.nodes.length > 0) {
$.each(role.nodes, function(index, node){
vms.push(node.vm_info);
})
}
generate_provision_vms_list(
$(".provision_role_vms_container", context),
@ -4568,8 +4578,7 @@ function setup_info_flow(context) {
})
context.on("click", ".provision_role_cardinality_button", function(){
var role_json = $(this).closest(".provision_role_ul").attr('role');
var role = JSON.parse(role_json);
var role = $(this).closest(".provision_role_ul").data('role');
var min_vms = (role.min_vms||1);
var max_vms = (role.max_vms||100);
@ -5910,8 +5919,8 @@ $(document).ready(function(){
'</span>';
}
$("#provision_system_templates_ul").append('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'" data=\''+JSON.stringify(aData)+'\'>'+
var li = $('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'">'+
'<li class="provision-title" title="'+data.NAME+'">'+
data.NAME+
'</li>'+
@ -5922,7 +5931,9 @@ $(document).ready(function(){
(data.TEMPLATE.DESCRIPTION || '...')+
'</li>'+
'</ul>'+
'</li>');
'</li>').appendTo($("#provision_system_templates_ul"));
$(".provision-pricing-table", li).data("opennebula", aData);
return nRow;
}
@ -5976,8 +5987,8 @@ $(document).ready(function(){
'</span>';
}
$("#provision_vdc_templates_ul").append('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'" data=\''+JSON.stringify(aData)+'\'>'+
var li = ('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'">'+
'<li class="provision-title" title="'+data.NAME+'">'+
data.NAME+
'</li>'+
@ -5988,7 +5999,9 @@ $(document).ready(function(){
(data.TEMPLATE.DESCRIPTION || '...')+
'</li>'+
'</ul>'+
'</li>');
'</li>').appendTo($("#provision_vdc_templates_ul"));
$(".provision-pricing-table", li).data("opennebula", aData);
return nRow;
}
@ -6043,8 +6056,8 @@ $(document).ready(function(){
'</span>';
}
$("#provision_saved_templates_ul").append('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'" data=\''+JSON.stringify(aData)+'\'>'+
var li = $('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'">'+
'<li class="provision-title" title="'+data.NAME+'">'+
data.NAME+
'</li>'+
@ -6055,7 +6068,9 @@ $(document).ready(function(){
(data.TEMPLATE.DESCRIPTION || '...')+
'</li>'+
'</ul>'+
'</li>');
'</li>').appendTo($("#provision_saved_templates_ul"));
$(".provision-pricing-table", li).data("opennebula", aData);
return nRow;
}
@ -6093,7 +6108,7 @@ $(document).ready(function(){
$(".provision_accordion_template .select_template").show();
} else {
var template_id = $(this).attr("opennebula_id");
var template_json = JSON.parse($(this).attr("data"));
var template_json = $(this).data("opennebula");
var template_nic = template_json.VMTEMPLATE.TEMPLATE.NIC
var nics = []
@ -6180,10 +6195,10 @@ $(document).ready(function(){
}
if (instance_type.length > 0) {
var instance_typa_data = instance_type.attr("data");
var instance_typa_data = instance_type.data("opennebula");
delete instance_typa_data.name;
$.extend(extra_info.template, JSON.parse(instance_type.attr("data")))
$.extend(extra_info.template, instance_typa_data)
}
var missing_attr = false;
@ -6283,8 +6298,8 @@ $(document).ready(function(){
'</span>';
}
$("#provision_flow_templates_ul").append('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'" data=\''+JSON.stringify(aData)+'\'>'+
var li = $('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'">'+
'<li class="provision-title" title="'+data.NAME+'">'+
data.NAME+
'</li>'+
@ -6296,7 +6311,9 @@ $(document).ready(function(){
(data.TEMPLATE.DESCRIPTION || '')+
'</li>'+
'</ul>'+
'</li>');
'</li>').appendTo($("#provision_flow_templates_ul"));
$(".provision-pricing-table", li).data("opennebula", aData);
return nRow;
}
@ -6331,7 +6348,7 @@ $(document).ready(function(){
$("#provision_customize_flow_template").show();
$("#provision_customize_flow_template").html("");
var data = JSON.parse($(this).attr("data"));
var data = $(this).data("opennebula");
var body = data.DOCUMENT.TEMPLATE.BODY;
$(".provision_accordion_flow_template .selected_template").show();
@ -6392,7 +6409,7 @@ $(document).ready(function(){
}
$.each(body.roles, function(index, role){
var context = $('<div id="provision_create_flow_role_'+index+'" class="provision_create_flow_role" data=\''+JSON.stringify(role)+'\'>'+
var context = $('<div id="provision_create_flow_role_'+index+'" class="provision_create_flow_role">'+
'<div class="row">'+
'<div class="large-10 large-centered columns">'+
'<h2 class="subheader">'+
@ -6415,6 +6432,8 @@ $(document).ready(function(){
'<br>'+
'<br>').appendTo($("#provision_customize_flow_template"))
context.data("opennebula", role);
var template_id = role.vm_template;
var role_html_id = "#provision_create_flow_role_"+index;
@ -6510,7 +6529,7 @@ $(document).ready(function(){
})
}
var role_template = JSON.parse($(this).attr("data"));
var role_template = $(this).data("opennebula");
roles.push($.extend(role_template, {
"cardinality": $(".cardinality_value", $(this)).text(),
"user_inputs_values": user_inputs_values

View File

@ -776,24 +776,25 @@ function generate_capacity_tab_content() {
'<div id="template_name_form" class="large-6 columns vm_param">'+
'<label for="NAME">'+tr("Name")+'\
<span class="tip">'+tr("Name that the VM will get for description purposes.")+'</span>\
</label>'+
'<input type="text" id="NAME" name="name" required/>'+
<input type="text" id="NAME" name="name" required/></label>'+
''+
'</div>'+
'<div id="template_hypervisor_form" class="large-6 columns">'+
'<label>'+tr("Hypervisor")+'</label>'+
'<input type="radio" name="hypervisor" value="kvm" id="kvmRadio"><label for="kvmRadio">'+tr("KVM")+'</label>'+
'<input type="radio" name="hypervisor" value="vmware" id="vmwareRadio"><label for="vmwareRadio">'+tr("VMware")+'</label>'+
'<input type="radio" name="hypervisor" value="xen" id="xenRadio"><label for="xenRadio">'+tr("Xen")+'</label>'+
'<input type="radio" name="hypervisor" value="vcenter" id="vcenterRadio"><label for="vcenterRadio">'+tr("vCenter")+'</label>'+
'</div>'+
'</div>'+
'<div class="row vm_param">'+
'<div class="large-8 columns">'+
'<div class="large-6 columns">'+
'<label for="DESCRIPTION">'+tr("Description")+'\
<span class="tip">'+tr("Description of the template")+'</span>\
</label>'+
'<textarea type="text" id="DESCRIPTION" name="DESCRIPTION" style="height: 70px;"/>'+
'</div>'+
'<div class="large-4 columns">'+
'<div class="large-6 columns">'+
'<div class="row">'+
'<div class="large-6 columns">'+
'<label for="LOGO">'+tr("Logo")+'\
@ -818,6 +819,14 @@ function generate_capacity_tab_content() {
'</div>'+
'</div>'+
'</div>'+
'<div class="row hypervisor only_vcenter" style="display: none;">'+
'<div class="large-6 columns">'+
'<label for="vcenter_template_uuid">'+tr("vCenter Template UUID")+'\
<span class="tip">'+tr("")+'</span>\
</label>'+
'<input type="text" id="vcenter_template_uuid" name="name"/>'+
'</div>'+
'</div>'+
'<br>'+
generate_capacity_inputs();
@ -2038,15 +2047,15 @@ function wizard_tab_dd(){
}
if (Config.isTemplateCreationTabEnabled('storage')){
str += "<dd><a href='#storageTab'><i class='fa fa-tasks'></i><br>"+tr("Storage")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#storageTab'><i class='fa fa-tasks'></i><br>"+tr("Storage")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('network')){
str += "<dd><a href='#networkTab'><i class='fa fa-globe'></i><br>"+tr("Network")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#networkTab'><i class='fa fa-globe'></i><br>"+tr("Network")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('os_booting')){
str += "<dd><a href='#osTab'><i class='fa fa-power-off'></i><br>"+tr("OS Booting")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#osTab'><i class='fa fa-power-off'></i><br>"+tr("OS Booting")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('input_output')){
@ -2054,7 +2063,7 @@ function wizard_tab_dd(){
}
if (Config.isTemplateCreationTabEnabled('context')){
str += "<dd><a href='#contextTab'><i class='fa fa-folder'></i><br>"+tr("Context")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#contextTab'><i class='fa fa-folder'></i><br>"+tr("Context")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('scheduling')){
@ -2542,8 +2551,8 @@ function wizard_tab_content(){
'<div class="row">'+
'<div class="large-12 columns text-center">'+
'<input type="radio" name="graphics_type" ID="radioVncType" value="VNC"><label for="radioVncType"> VNC </label>'+
'<input type="radio" name="graphics_type" ID="radioSdlType" value="SDL"><label for="radioSdlType"> SDL </label>'+
'<input type="radio" name="graphics_type" ID="radioSpiceType" value="SPICE"><label for="radioSpiceType"> SPICE </label>'+
'<input type="radio" name="graphics_type" ID="radioSdlType" value="SDL" class="hypervisor only_kvm only_vmware only_xen" ><label class="hypervisor only_kvm only_vmware only_xen" for="radioSdlType"> SDL </label>'+
'<input type="radio" name="graphics_type" ID="radioSpiceType" value="SPICE" class="hypervisor only_kvm only_vmware only_xen" ><label class="hypervisor only_kvm only_vmware only_xen" for="radioSpiceType"> SPICE </label>'+
'</div>'+
'</div>'+
'<br>'+
@ -2563,14 +2572,14 @@ function wizard_tab_content(){
'</label>'+
'<input type="text" id="PORT" name="port" />'+
'</div>'+
'<div class="large-6 columns">'+
'<div class="large-6 columns hypervisor only_kvm only_vmware only_xen">'+
'<label for="KEYMAP">'+tr("Keymap")+
'<span class="tip">'+tr("Keyboard configuration locale to use in the VNC/SPICE display")+'</span>'+
'</label>'+
'<input type="text" id="KEYMAP" name="keymap" />'+
'</div>'+
'</div>'+
'<div class="row vm_param">'+
'<div class="row hypervisor only_kvm only_vmware only_xen">'+
'<div class="large-12 columns">'+
'<label for="PASSWD">'+tr("Password")+
'<span class="tip">'+tr("Password for the VNC/SPICE server")+'</span>'+
@ -2580,7 +2589,7 @@ function wizard_tab_content(){
'</div>'+
'</fieldset>'+
'</div>'+
'<div class="large-6 columns inputs">'+
'<div class="large-6 columns inputs hypervisor only_kvm only_vmware only_xen">'+
'<fieldset>'+
'<legend>'+tr("Inputs")+'</legend>'+
'<div class="row">'+
@ -2905,7 +2914,7 @@ function wizard_tab_content(){
'</div>'+
'</div>'+
'</fieldset>'+
'<fieldset>'+
'<fieldset class="hypervisor only_kvm only_vmware only_xen">'+
'<legend>'+tr("Datastore Requirements")+'</legend>'+
'<div class="row vm_param">'+
'<div class="large-12 columns">'+
@ -2943,7 +2952,7 @@ function wizard_tab_content(){
'</div>'+
'</div>'+
'</fieldset>'+
'<fieldset class="ds_rank">'+
'<fieldset class="ds_rank hypervisor only_kvm only_vmware only_xen">'+
'<legend>'+tr("Datastore Rank")+'</legend>'+
'<div class="row">'+
'<div class="large-12 columns text-center">'+
@ -2986,7 +2995,7 @@ function wizard_tab_content(){
'<div id="rawTab" class="wizard_tab content">'+
'<div class="row">'+
'<div class="large-12 columns">'+
'<fieldset>'+
'<fieldset class="hypervisor only_xen only_kvm only_vmware">'+
'<legend>'+tr("RAW data")+'</legend>'+
'<div class="row">'+
'<div class="large-4 columns">'+
@ -3960,10 +3969,10 @@ function initialize_create_template_dialog(dialog) {
//$('button',dialog).button();
//Process form
$('#create_template_form_wizard',dialog).on('invalid', function () {
$('#create_template_form_wizard',dialog).on('invalid.fndtn.abide', function () {
notifyError(tr("One or more required fields are missing or malformed."));
popFormDialog("create_template_form", $("#templates-tab"));
}).on('valid', function() {
}).on('valid.fndtn.abide', function() {
if ($('#create_template_form_wizard',dialog).attr("action") == "create") {
var vm_json = build_template(this);
vm_json = {vmtemplate: vm_json};
@ -3981,10 +3990,10 @@ function initialize_create_template_dialog(dialog) {
}
});
$('#create_template_form_advanced',dialog).on('invalid', function () {
$('#create_template_form_advanced',dialog).on('invalid.fndtn.abide', function () {
notifyError(tr("One or more required fields are missing or malformed."));
popFormDialog("create_template_form", $("#templates-tab"));
}).on('valid', function() {
}).on('valid.fndtn.abide', function() {
if ($('#create_template_form_advanced',dialog).attr("action") == "create") {
var template = $('textarea#template',this).val();
@ -4023,7 +4032,14 @@ function build_template(dialog){
addSectionJSON(vm_json,$('#capacityTab',dialog));
vm_json["DESCRIPTION"] = $('#DESCRIPTION',$('#capacityTab',dialog)).val();
vm_json["LOGO"] = $('#LOGO',$('#capacityTab',dialog)).val();
vm_json["HYPERVISOR"] = $('input[name="hypervisor"]:checked', $('#capacityTab',dialog)).val();
var hypervisor = $('input[name="hypervisor"]:checked', $('#capacityTab',dialog)).val();
vm_json["HYPERVISOR"] = hypervisor;
if (hypervisor == "vcenter") {
vm_json["PUBLIC_CLOUD"] = {
"TYPE": "vcenter",
"VM_TEMPLATE": $("#vcenter_template_uuid", dialog).val()
}
}
//
// OS
@ -4097,7 +4113,10 @@ function build_template(dialog){
// HYBRID
vm_json["PUBLIC_CLOUD"] = [];
if ($.isEmptyObject(vm_json["PUBLIC_CLOUD"])) {
vm_json["PUBLIC_CLOUD"] = [];
}
vm_json["EC2"] = [];
$('.provider',dialog).each(function(){
@ -4418,16 +4437,21 @@ var fillTemplatePopUp = function(template, dialog){
//
function fillProviderTab(provider, provider_type){
if (provider_type == "vcenter") {
$("#vcenter_template_uuid", dialog).val(provider["VM_TEMPLATE"])
} else {
if (number_of_providers > 0) {
$("#tf_btn_hybrid", dialog).trigger("click");
}
number_of_providers++;
}
var context = $(".provider", dialog).last();
$("input.hybridRadio[value='"+provider_type+"']", context).trigger("click");
autoFillInputs(provider, context);
number_of_providers++;
}
var number_of_providers = 0;
@ -4441,7 +4465,7 @@ var fillTemplatePopUp = function(template, dialog){
});
}
else if (providers instanceof Object) {
fillProviderTab(providers, this.TYPE.toLowerCase());
fillProviderTab(providers, providers.TYPE.toLowerCase());
}
delete template.PUBLIC_CLOUD

View File

@ -820,18 +820,8 @@ function updateVNetworkInfo(request,vn){
$(this).addClass('markrowchecked');
});
if (get_ar(vn_info, id).PARENT_NETWORK_AR_ID != undefined &&
get_ar(vn_info, id).PARENT_NETWORK_AR_ID.length > 0){
$("#update_ar_button", $("#vnet_info_panel")).prop("disabled", true);
$("#update_ar_button", $("#vnet_info_panel")).addClass("has-tip");
$("#update_ar_button", $("#vnet_info_panel")).attr("title", tr("This address range is a reservation"));
} else{
$("#update_ar_button", $("#vnet_info_panel")).attr("ar_id", id);
$("#update_ar_button", $("#vnet_info_panel")).prop("disabled", false);
$("#update_ar_button", $("#vnet_info_panel")).removeClass("has-tip");
$("#update_ar_button", $("#vnet_info_panel")).removeAttr("title");
}
$("#update_ar_button", $("#vnet_info_panel")).attr("ar_id", id);
$("#update_ar_button", $("#vnet_info_panel")).prop("disabled", false);
$("#rm_ar_button", $("#vnet_info_panel")).attr("ar_id", id).removeAttr('disabled');

View File

@ -174,6 +174,10 @@ var Sunstone = {
setTimeout(function() {
if (reset) {
if (!action) {
action = $("#"+form_name+"_wizard", context).attr("action")
}
$("#"+form_name+"_wizard", context).remove();
$("#"+form_name+"_advanced", context).remove();
}
@ -780,7 +784,7 @@ function insertButtonsInTab(tab_name, panel_name, panel_buttons, custom_context)
"</ul>"+
'</span>'+
"<span id='"+custom_id+"form_buttons' class='only-right-form'>"+
"<span id='"+custom_id+"form_buttons' class='only-right-form' style='display: none'>"+
'<span id="'+custom_id+'reset_button" class="left" style="margin-left: 10px;">'+
'<a class="button small secondary radius" href="submit">'+tr("Reset")+'</a>'+
'</span>'+

View File

@ -337,7 +337,7 @@ $button-font-weight: normal;
// $button-function-factor: 5%;
// We use these to control button border styles.
$button-border-width: 1px;
$button-border-width: 0px;
$button-border-style: solid;
$secondary-button-border-color: #efefef;
// We use this to set the default radius used throughout the core.

View File

@ -221,10 +221,10 @@ input.search {
}
a {
color: #999 !important;
color: #777 !important;
&:hover {
color: #555;
color: #555 !important;
}
}
}

View File

@ -0,0 +1,89 @@
# -------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L. #
# #
# 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. #
#--------------------------------------------------------------------------- #
if !ONE_LOCATION
REMOTES_LOCATION="/var/lib/one/remotes"
else
REMOTES_LOCATION=ONE_LOCATION+"/var/remotes"
end
# TODO vcenter_driver should be stored in RUBY_LIB_LOCATION
$: << REMOTES_LOCATION+"/vmm/vcenter/"
require 'vcenter_driver'
helpers do
def vcenter_client
vuser = request.env['HTTP_X_VCENTER_USER']
vpass = request.env['HTTP_X_VCENTER_PASSWORD']
vhost = request.env['HTTP_X_VCENTER_HOST']
if vuser.nil? || vpass.nil? || vhost.nil?
msg = "You have to provide the vCenter username, password and hostname"
logger.error("[vCenter] " + msg)
error = Error.new(msg)
error 404, error.to_json
end
return VCenterDriver::VIClient.new_connection(
:user => vuser,
:password => vpass,
:host => vhost)
end
# def af_format_response(resp)
# if CloudClient::is_error?(resp)
# logger.error("[OneFlow] " + resp.to_s)
#
# error = Error.new(resp.to_s)
# error resp.code.to_i, error.to_json
# else
# body resp.body.to_s
# end
# end
end
get '/vcenter' do
begin
rs = vcenter_client.hierarchy
[200, rs.to_json]
rescue Exception => e
logger.error("[vCenter] " + e.message)
error = Error.new(e.message)
error 403, error.to_json
end
end
get '/vcenter/:datacenter/cluster/:name' do
begin
rs = vcenter_client.vm_templates
templates = rs[params[:datacenter]]
if templates.nil?
msg = "Datacenter " + params[:datacenter] + "not found"
logger.error("[vCenter] " + msg)
error = Error.new(msg)
error 404, error.to_json
end
ctemplates = templates.select{|t| t[:host] == params[:name]}
[200, ctemplates.to_json]
rescue Exception => e
logger.error("[vCenter] " + e.message)
error = Error.new(e.message)
error 403, error.to_json
end
end

View File

@ -860,3 +860,125 @@ bool Template::check(string& rs_attr, const vector<string> &restricted_attribute
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Template::remove_restricted()
{}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Template::remove_all_except_restricted()
{}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Template::remove_restricted(const vector<string> &restricted_attributes)
{
size_t pos;
string avector, vattr;
vector<Attribute *> values;
for (unsigned int i=0; i < restricted_attributes.size(); i++)
{
pos = restricted_attributes[i].find("/");
if (pos != string::npos) //Vector Attribute
{
int num;
avector = restricted_attributes[i].substr(0,pos);
vattr = restricted_attributes[i].substr(pos+1);
if ((num = get(avector,values)) > 0 ) //Template contains the attr
{
VectorAttribute * attr;
for (int j=0; j<num ; j++ )
{
attr = dynamic_cast<VectorAttribute *>(values[j]);
if (attr == 0)
{
continue;
}
attr->remove(vattr);
}
}
}
else //Single Attribute
{
erase(restricted_attributes[i]);
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Template::remove_all_except_restricted(const vector<string> &restricted_attributes)
{
size_t pos;
string avector, vattr;
vector<Attribute *> values;
vector<Attribute *> restricted;
for (unsigned int i=0; i < restricted_attributes.size(); i++)
{
pos = restricted_attributes[i].find("/");
if (pos != string::npos) //Vector Attribute
{
int num;
avector = restricted_attributes[i].substr(0,pos);
vattr = restricted_attributes[i].substr(pos+1);
if ((num = get(avector,values)) > 0 ) //Template contains the attr
{
VectorAttribute * attr;
for (int j=0; j<num ; j++ )
{
attr = dynamic_cast<VectorAttribute *>(values[j]);
if (attr == 0)
{
continue;
}
if ( !attr->vector_value(vattr.c_str()).empty() )
{
restricted.push_back(attr);
}
}
}
}
else //Single Attribute
{
this->get(restricted_attributes[i], restricted);
}
}
vector<Attribute *>::iterator res_it;
for (res_it = restricted.begin(); res_it != restricted.end(); res_it++)
{
remove(*res_it);
}
multimap<string,Attribute *>::iterator att_it;
for ( att_it = attributes.begin(); att_it != attributes.end(); att_it++)
{
delete att_it->second;
}
attributes.clear();
for (res_it = restricted.begin(); res_it != restricted.end(); res_it++)
{
set(*res_it);
}
}

103
src/um/LoginToken.cc Normal file
View File

@ -0,0 +1,103 @@
/* -------------------------------------------------------------------------- */
/* 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 <sstream>
#include "LoginToken.h"
#include "NebulaUtil.h"
#include "ObjectXML.h"
using namespace std;
bool LoginToken::is_valid(const string& user_token) const
{
return ((user_token == token) &&
((expiration_time == -1) || (time(0) < expiration_time)));
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const std::string& LoginToken::set(const std::string& user_token, time_t valid)
{
if (valid == -1)
{
expiration_time = -1;
}
else if (valid > 0 )
{
expiration_time = time(0) + valid;
}
else
{
expiration_time = 0;
}
if (user_token.empty())
{
token = user_token;
}
else
{
token = one_util::random_password();
}
return token;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LoginToken::reset()
{
token.clear();
expiration_time = 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
std::string& LoginToken::to_xml(std::string& sxml) const
{
std::ostringstream xml;
if ( expiration_time == 0 )
{
xml << "<LOGIN_TOKEN/>";
}
else
{
xml << "<LOGIN_TOKEN>"
<< "<TOKEN>" << token << "</TOKEN>"
<< "<EXPIRATION_TIME>" << expiration_time << "</EXPIRATION_TIME>"
<< "</LOGIN_TOKEN>";
}
sxml = xml.str();
return sxml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LoginToken::from_xml_node(const xmlNodePtr node)
{
ObjectXML oxml(node);
oxml.xpath(token, "/LOGIN_TOKEN/TOKEN", "" );
oxml.xpath(expiration_time, "/LOGIN_TOKEN/EXPIRATION_TIME", 0 );
}

View File

@ -31,7 +31,8 @@ source_files=[
'QuotaImage.cc',
'Quotas.cc',
'DefaultQuotas.cc',
'QuotasSQL.cc'
'QuotasSQL.cc',
'LoginToken.cc'
]
# Build library

View File

@ -223,6 +223,7 @@ string& User::to_xml_extended(string& xml, bool extended) const
string template_xml;
string collection_xml;
string token_xml;
ObjectCollection::to_xml(collection_xml);
@ -238,6 +239,7 @@ string& User::to_xml_extended(string& xml, bool extended) const
"<PASSWORD>" << password <<"</PASSWORD>" <<
"<AUTH_DRIVER>" << auth_driver <<"</AUTH_DRIVER>"<<
"<ENABLED>" << enabled_int <<"</ENABLED>" <<
login_token.to_xml(token_xml) <<
obj_template->to_xml(template_xml);
if (extended)
@ -281,6 +283,16 @@ int User::from_xml(const string& xml)
// Set itself as the owner
set_user(oid, name);
ObjectXML::get_nodes("/USER/LOGIN_TOKEN", content);
if (!content.empty())
{
login_token.from_xml_node(content[0]);
}
ObjectXML::free_nodes(content);
content.clear();
// Get associated metadata for the user
ObjectXML::get_nodes("/USER/TEMPLATE", content);
@ -354,7 +366,9 @@ int User::set_password(const string& passwd, string& error_str)
password = passwd;
}
invalidate_session();
session.reset();
login_token.reset();
}
else
{

View File

@ -446,13 +446,19 @@ bool UserPool::authenticate_internal(User * user,
auth_driver = user->auth_driver;
result = user->valid_session(token);
//Check if token is a login token
result = user->login_token.is_valid(token);
if (!result) //Not a login token check if the token is a session token
{
result = user->session.is_valid(token);
}
umask = user->get_umask();
user->unlock();
if (result)
if (result) //Good either a valid session or login_token
{
return true;
}
@ -494,7 +500,7 @@ bool UserPool::authenticate_internal(User * user,
if (user != 0)
{
user->set_session(token, _session_expiration_time);
user->session.set(token, _session_expiration_time);
user->unlock();
}
@ -589,7 +595,7 @@ bool UserPool::authenticate_server(User * user,
uname = user->name;
gname = user->gname;
result = user->valid_session(second_token);
result = user->session.is_valid(second_token);
umask = user->get_umask();
@ -623,7 +629,7 @@ bool UserPool::authenticate_server(User * user,
if (user != 0)
{
user->set_session(second_token, _session_expiration_time);
user->session.set(second_token, _session_expiration_time);
user->unlock();
}

View File

@ -15,128 +15,12 @@
/* -------------------------------------------------------------------------- */
#include "VirtualMachineTemplate.h"
#include "Host.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
vector<string> VirtualMachineTemplate::restricted_attributes;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineTemplate::remove_restricted()
{
size_t pos;
string avector, vattr;
vector<Attribute *> values;
for (unsigned int i=0; i < restricted_attributes.size(); i++)
{
pos = restricted_attributes[i].find("/");
if (pos != string::npos) //Vector Attribute
{
int num;
avector = restricted_attributes[i].substr(0,pos);
vattr = restricted_attributes[i].substr(pos+1);
if ((num = get(avector,values)) > 0 ) //Template contains the attr
{
VectorAttribute * attr;
for (int j=0; j<num ; j++ )
{
attr = dynamic_cast<VectorAttribute *>(values[j]);
if (attr == 0)
{
continue;
}
attr->remove(vattr);
}
}
}
else //Single Attribute
{
erase(restricted_attributes[i]);
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineTemplate::remove_all_except_restricted()
{
size_t pos;
string avector, vattr;
vector<Attribute *> values;
vector<Attribute *> restricted;
for (unsigned int i=0; i < restricted_attributes.size(); i++)
{
pos = restricted_attributes[i].find("/");
if (pos != string::npos) //Vector Attribute
{
int num;
avector = restricted_attributes[i].substr(0,pos);
vattr = restricted_attributes[i].substr(pos+1);
if ((num = get(avector,values)) > 0 ) //Template contains the attr
{
VectorAttribute * attr;
for (int j=0; j<num ; j++ )
{
attr = dynamic_cast<VectorAttribute *>(values[j]);
if (attr == 0)
{
continue;
}
if ( !attr->vector_value(vattr.c_str()).empty() )
{
restricted.push_back(attr);
}
}
}
}
else //Single Attribute
{
this->get(restricted_attributes[i], restricted);
}
}
vector<Attribute *>::iterator res_it;
for (res_it = restricted.begin(); res_it != restricted.end(); res_it++)
{
remove(*res_it);
}
multimap<string,Attribute *>::iterator att_it;
for ( att_it = attributes.begin(); att_it != attributes.end(); att_it++)
{
delete att_it->second;
}
attributes.clear();
for (res_it = restricted.begin(); res_it != restricted.end(); res_it++)
{
set(*res_it);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -284,7 +284,7 @@ void get_network_attribute(VirtualMachine * vm,
if (attr_name == "TEMPLATE")
{
attr_value = vn->to_xml64(attr_value, true);
attr_value = vn->to_xml64(attr_value);
}
else
{

View File

@ -229,7 +229,7 @@ void get_network_attribute(VirtualMachine * vm,
if (attr_name == "TEMPLATE")
{
attr_value = vn->to_xml64(attr_value, true);
attr_value = vn->to_xml64(attr_value);
}
else
{

View File

@ -901,7 +901,8 @@ opts = GetoptLong.new(
[ '--retries', '-r', GetoptLong::OPTIONAL_ARGUMENT ],
[ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ],
[ '--local', '-l', GetoptLong::REQUIRED_ARGUMENT ],
[ '--shell', '-s', GetoptLong::REQUIRED_ARGUMENT ]
[ '--shell', '-s', GetoptLong::REQUIRED_ARGUMENT ],
[ '--parallel', '-p', GetoptLong::NO_ARGUMENT ]
)
hypervisor = ''
@ -909,6 +910,7 @@ retries = 0
threads = 15
shell = 'bash'
local_actions = {}
single_host = true
begin
opts.each do |opt, arg|
@ -921,6 +923,8 @@ begin
local_actions=OpenNebulaDriver.parse_actions_list(arg)
when '--shell'
shell = arg
when '--parallel'
single_host = false
end
end
rescue Exception => e
@ -937,6 +941,7 @@ exec_driver = ExecDriver.new(hypervisor,
:concurrency => threads,
:retries => retries,
:local_actions => local_actions,
:shell => shell)
:shell => shell,
:single_host => single_host)
exec_driver.start_driver

View File

@ -25,6 +25,6 @@ fi
LOCAL_ACTIONS="deploy,shutdown,reboot,cancel,save,restore,migrate,poll,pre"
LOCAL_ACTIONS="${LOCAL_ACTIONS},post,clean"
LOCAL_ACTIONS="${LOCAL_ACTIONS},snapshotcreate,snapshotrevert,snapshotdelete"
LOCAL_ACTIONS="${LOCAL_ACTIONS},attach_nic,detach_nic"
LOCAL_ACTIONS="${LOCAL_ACTIONS},attach_nic,detach_nic,reset"
exec $MAD_LOCATION/one_vmm_exec -l $LOCAL_ACTIONS $*

View File

@ -327,10 +327,16 @@ class EC2Driver
vms_info = "VM_POLL=YES\n"
usedcpu = 0
#
# Add information for running VMs (running and pending).
#
usedcpu = 0
usedmemory = 0
begin
AWS.ec2.instances.each do |i|
next if i.status != :pending && i.status != :running
poll_data=parse_poll(i)
one_id = i.tags['ONE_ID']

View File

@ -332,14 +332,16 @@ private
sl = nil
all_sl_elements = xml.root.get_elements("//USER_TEMPLATE/PUBLIC_CLOUD")
all_sl_elements = all_sl_elements.select { |element|
element.elements["TYPE"].text.downcase.eql? "softlayer"
}
# First, let's see if we have an SoftLayer site that matches
# our desired host name
all_sl_elements.each { |element|
cloud_host = element.elements["DATACENTER"]
type = element.elements["TYPE"].text
next if !type.downcase.eql? "softlayer"
if cloud_host and cloud_host.text.upcase.eql? host.upcase
sl = element
end
@ -348,14 +350,14 @@ private
if !sl
# If we don't find the SoftLayer site, and ONE just
# knows about one SoftLayer site, let's use that
if all_sl_elements.size == 1 and
all_sl_elements[0].elements["TYPE"].text.upcase.eql? "SOFTLAYER"
if all_sl_elements.size == 1
sl = all_sl_elements[0]
else
STDERR.puts(
"Cannot find SoftLayer element in VM template "<<
"or couldn't find any SoftLayer site matching "<<
"one of the templates.")
"or ambigous definition of SofLayer templates "<<
"(for instance, two SoftLayer sections without " <<
"a DATACENTER defined)")
exit(-1)
end
end

View File

@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2

View File

@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2

View File

@ -0,0 +1,47 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
host = ARGV[1]
vm_id = ARGV[-2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
begin
VCenterDriver::VCenterVm.cancel(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Cancel of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,53 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
require 'opennebula'
dfile = ARGV[0]
host = ARGV[1]
vm_id = ARGV[2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
deploy_id = vm.deploy_id
begin
puts VCenterDriver::VCenterVm.deploy(File.read(dfile),
lcm_state,
deploy_id,
host)
rescue Exception => e
STDERR.puts "Deploy of VM #{vm_id} on host #{host} with #{dfile} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2

View File

@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2

View File

@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2

View File

@ -0,0 +1,43 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
host = ARGV[1]
host_id = VCenterDriver::VIClient.translate_hostname(host)
vi_client = VCenterDriver::VIClient.new host_id
vm = vi_client.find_vm_template(deploy_id)
vm = VCenterDriver::VCenterVm.new(vi_client, vm)
vm.monitor
puts vm.info

View File

@ -0,0 +1,41 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
host = ARGV[1]
begin
VCenterDriver::VCenterVm.reboot(deploy_id, host)
rescue Exception => e
STDERR.puts "Guest reboot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,41 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
host = ARGV[1]
begin
VCenterDriver::VCenterVm.reset(deploy_id, host)
rescue Exception => e
STDERR.puts "Reset of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,41 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
host = ARGV[-1]
deploy_id = ARGV[2]
begin
VCenterDriver::VCenterVm.resume(deploy_id, host)
rescue Exception => e
STDERR.puts "Restore of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,49 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
require 'opennebula'
deploy_id = ARGV[0]
file = ARGV[1]
host = ARGV[2]
vm_id = ARGV[-2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
begin
puts VCenterDriver::VCenterVm.save(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Save of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,48 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
require 'opennebula'
deploy_id = ARGV[0]
host = ARGV[1]
vm_id = ARGV[-2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
begin
VCenterDriver::VCenterVm.shutdown(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Shutdown of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,44 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
snapshot_name = ARGV[1]
host = ARGV[3]
begin
puts VCenterDriver::VCenterVm.create_snapshot(deploy_id,
host,
snapshot_name)
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,44 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
snapshot_name = ARGV[1]
host = ARGV[3]
begin
VCenterDriver::VCenterVm.delete_snapshot(deploy_id,
host,
snapshot_name)
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,44 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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 !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
snapshot_name = ARGV[1]
host = ARGV[3]
begin
VCenterDriver::VCenterVm.revert_snapshot(deploy_id,
host,
snapshot_name)
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} could not be " +
"reverted due to \"#{e.message}\""
exit -1
end

View File

@ -0,0 +1,783 @@
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# 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. #
# ---------------------------------------------------------------------------- #
# -------------------------------------------------------------------------#
# Set up the environment for the driver #
# -------------------------------------------------------------------------#
ONE_LOCATION = ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
if !ONE_LOCATION
BIN_LOCATION = "/usr/bin" if !defined?(BIN_LOCATION)
LIB_LOCATION = "/usr/lib/one" if !defined?(LIB_LOCATION)
ETC_LOCATION = "/etc/one/" if !defined?(ETC_LOCATION)
VAR_LOCATION = "/var/lib/one" if !defined?(VAR_LOCATION)
else
BIN_LOCATION = ONE_LOCATION + "/bin" if !defined?(BIN_LOCATION)
LIB_LOCATION = ONE_LOCATION + "/lib" if !defined?(LIB_LOCATION)
ETC_LOCATION = ONE_LOCATION + "/etc/" if !defined?(ETC_LOCATION)
VAR_LOCATION = ONE_LOCATION + "/var/" if !defined?(VAR_LOCATION)
end
ENV['LANG'] = 'C'
$: << LIB_LOCATION+'/ruby/vendors/rbvmomi/lib'
$: << LIB_LOCATION+'/ruby'
require 'rbvmomi'
require 'yaml'
require 'opennebula'
module VCenterDriver
################################################################################
# This class represents a VCenter connection and an associated OpenNebula client
# The connection is associated to the VCenter backing a given OpenNebula host.
# For the VCenter driver each OpenNebula host represents a VCenter cluster
################################################################################
class VIClient
attr_reader :vim, :one, :root, :cluster, :user, :pass, :host
############################################################################
# Initializr the VIClient, and creates an OpenNebula client. The parameters
# are obtained from the associated OpenNebula host
# @param hid [Integer] The OpenNebula host id with VCenter attributes
############################################################################
def initialize(hid)
initialize_one
@one_host = ::OpenNebula::Host.new_with_id(hid, @one)
rc = @one_host.info
if ::OpenNebula.is_error?(rc)
raise "Error getting host information: #{rc.message}"
end
connection = {
:host => @one_host["TEMPLATE/VCENTER_HOST"],
:user => @one_host["TEMPLATE/VCENTER_USER"],
:password => @one_host["TEMPLATE/VCENTER_PASSWORD"]
}
initialize_vim(connection)
@root.childEntity.each {|dc|
ccrs = dc.hostFolder.childEntity.grep(
RbVmomi::VIM::ClusterComputeResource)
next if ccrs.nil?
@cluster = ccrs.find{ |ccr| @one_host.name == ccr.name }
(@dc = dc; break) if @cluster
}
if @dc.nil? || @cluster.nil?
raise "Cannot find DataCenter or ClusterComputeResource for host."
end
end
########################################################################
# Initialize a VIConnection based just on the VIM parameters. The
# OpenNebula client is also initilialize
########################################################################
def self.new_connection(user_opts)
conn = allocate
conn.initialize_one
conn.initialize_vim(user_opts)
return conn
end
########################################################################
# The associated resource pool for this connection
########################################################################
def resource_pool
return @cluster.resourcePool
end
########################################################################
# Searches the associated vmFolder of the DataCenter for the current
# connection. Returns a RbVmomi::VIM::VirtualMachine or nil if not found
# @param uuid [String] the UUID of the VM or VM Template
########################################################################
def find_vm_template(uuid)
vms = @dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine)
return vms.find{ |v| v.config.uuid == uuid }
end
########################################################################
# Builds a hash with the DataCenter / ClusterComputeResource hierarchy
# for this VCenter.
# @return [Hash] in the form
# {dc_name [String] => ClusterComputeResources Names [Array - String]}
########################################################################
def hierarchy
vc_hosts = {}
@root.childEntity.each { |dc|
ccrs = dc.hostFolder.childEntity.grep(
RbVmomi::VIM::ClusterComputeResource)
vc_hosts[dc.name] = ccrs.collect { |c| c.name }
}
return vc_hosts
end
########################################################################
# Builds a hash with the Datacenter / VM Templates for this VCenter
# @return [Hash] in the form
# { dc_name [String] => }
########################################################################
def vm_templates
vm_templates = {}
@root.childEntity.each { |dc|
vms = dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine)
tmp = vms.select { |v| v.config.template == true }
one_tmp = []
tmp.each { |t|
vi_tmp = VCenterVm.new(self, t)
one_tmp << {
:name => vi_tmp.vm.name,
:uuid => vi_tmp.vm.config.uuid,
:host => vi_tmp.vm.runtime.host.parent.name,
:one => vi_tmp.to_one
}
}
vm_templates[dc.name] = one_tmp
}
return vm_templates
end
def self.translate_hostname(hostname)
host_pool = OpenNebula::HostPool.new(::OpenNebula::Client.new())
rc = host_pool.info
raise "Could not find host #{hostname}" if OpenNebula.is_error?(rc)
host = host_pool.select {|host_element| host_element.name==hostname }
return host.first.id
end
############################################################################
# Initialize an OpenNebula connection with the default ONE_AUTH
############################################################################
def initialize_one
begin
@one = ::OpenNebula::Client.new()
rescue Exception => e
raise "Error initializing OpenNebula client: #{e.message}"
end
end
############################################################################
# Initialize a connection with vCenter. Options
# @param options[Hash] with:
# :user => The vcenter user
# :password => Password for the user
# :host => vCenter hostname or IP
# :insecure => SSL (optional, defaults to true)
############################################################################
def initialize_vim(user_opts={})
opts = {
:insecure => true
}.merge(user_opts)
@user = opts[:user]
@pass = opts[:password]
@host = opts[:host]
begin
@vim = RbVmomi::VIM.connect(opts)
@root = @vim.root
rescue Exception => e
raise "Error connecting to #{@host}: #{e.message}"
end
end
end
################################################################################
# This class is an OpenNebula hosts that abstracts a vCenter cluster. It
# includes the functionality needed to monitor the cluster and report the ESX
# hosts and VM status of the cluster.
################################################################################
class VCenterHost < ::OpenNebula::Host
attr_reader :vc_client, :vc_root, :cluster, :host, :client
############################################################################
# Initialize the VCenterHost by looking for the associated objects of the
# VIM hierarchy
# client [VIClient] to interact with the associated vCenter
############################################################################
def initialize(client)
@client = client
@cluster = client.cluster
@resource_pool = client.resource_pool
end
########################################################################
# Creates an OpenNebula host representing a cluster in this VCenter
# @param cluster_name[String] the name of the cluster in the vcenter
# @param client [VIClient] to create the host
# @return In case of success [0, host_id] or [-1, error_msg]
########################################################################
def self.to_one(cluster_name, client)
one_host = ::OpenNebula::Host.new(::OpenNebula::Host.build_xml,
client.one)
rc = one_host.allocate(cluster_name, 'vcenter', 'vcenter', 'dummy',
::OpenNebula::ClusterPool::NONE_CLUSTER_ID)
return -1, rc.message if ::OpenNebula.is_error?(rc)
template = "VCENTER_HOST=\"#{client.host}\"\n"\
"VCENTER_PASSWORD=\"#{client.pass}\"\n"\
"VCENTER_USER=\"#{client.user}\"\n"
rc = one_host.update(template, false)
if ::OpenNebula.is_error?(rc)
error = rc.message
rc = one_host.delete
if ::OpenNebula.is_error?(rc)
error << ". Host #{cluster_name} could not be"\
" deleted: #{rc.message}."
end
return -1, error
end
return 0, one_host.id
end
############################################################################
# Generate an OpenNebula monitor string for this host. Reference:
# https://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/vim.ComputeResource.Summary.html
# - effectiveCpu: Effective CPU resources (in MHz) available to run
# VMs. This is the aggregated from all running hosts excluding hosts in
# maintenance mode or unresponsive are not counted.
# - effectiveMemory: Effective memory resources (in MB) available to run
# VMs. Equivalente to effectiveCpu.
# - numCpuCores: Number of physical CPU cores.
# - numEffectiveHosts: Total number of effective hosts.
# - numHosts:Total number of hosts.
# - totalCpu: Aggregated CPU resources of all hosts, in MHz.
# - totalMemory: Aggregated memory resources of all hosts, in bytes.
############################################################################
def monitor_cluster
#Load the host systems
summary = @cluster.summary
mhz_core = summary.totalCpu.to_f / summary.numCpuCores.to_f
eff_core = summary.effectiveCpu.to_f / mhz_core
free_cpu = sprintf('%.2f', eff_core * 100).to_f
total_cpu = summary.numCpuCores.to_f * 100
used_cpu = sprintf('%.2f', total_cpu - free_cpu).to_f
total_mem = summary.totalMemory.to_i / 1024
free_mem = summary.effectiveMemory.to_i * 1024
str_info = ""
# System
str_info << "HYPERVISOR=vcenter\n"
str_info << "PUBLIC_CLOUD=YES\n"
str_info << "TOTALHOST=" << summary.numHosts.to_s << "\n"
str_info << "AVAILHOST=" << summary.numEffectiveHosts.to_s << "\n"
# CPU
str_info << "CPUSPEED=" << mhz_core.to_s << "\n"
str_info << "TOTALCPU=" << total_cpu.to_s << "\n"
str_info << "USEDCPU=" << used_cpu.to_s << "\n"
str_info << "FREECPU=" << free_cpu.to_s << "\n"
# Memory
str_info << "TOTALMEMORY=" << total_mem.to_s << "\n"
str_info << "FREEMEMORY=" << free_mem.to_s << "\n"
str_info << "USEDMEMORY=" << (total_mem - free_mem).to_s
end
############################################################################
# Generate a template with information for each ESX Host. Reference:
# http://pubs.vmware.com/vi-sdk/visdk250/ReferenceGuide/vim.HostSystem.html
# - Summary: Basic information about the host, including connection state
# - hardware: Hardware configuration of the host. This might not be
# available for a disconnected host.
# - quickStats: Basic host statistics.
############################################################################
def monitor_host_systems
host_info = ""
@cluster.host.each{|h|
next if h.runtime.connectionState != "connected"
summary = h.summary
hw = summary.hardware
stats = summary.quickStats
total_cpu = hw.numCpuCores * 100
used_cpu = (stats.overallCpuUsage.to_f / hw.cpuMhz.to_f) * 100
used_cpu = sprintf('%.2f', used_cpu).to_f # Trim precission
free_cpu = total_cpu - used_cpu
total_memory = hw.memorySize/1024
used_memory = stats.overallMemoryUsage*1024
free_memory = total_memory - used_memory
host_info << "\nHOST=["
host_info << "STATE=on,"
host_info << "HOSTNAME=\"" << h.name.to_s << "\","
host_info << "MODELNAME=\"" << hw.cpuModel.to_s << "\","
host_info << "CPUSPEED=" << hw.cpuMhz.to_s << ","
host_info << "MAX_CPU=" << total_cpu.to_s << ","
host_info << "USED_CPU=" << used_cpu.to_s << ","
host_info << "FREE_CPU=" << free_cpu.to_s << ","
host_info << "MAX_MEM=" << total_memory.to_s << ","
host_info << "USED_MEM=" << used_memory.to_s << ","
host_info << "FREE_MEM=" << free_memory.to_s
host_info << "]"
}
return host_info
end
def monitor_vms
str_info = ""
@resource_pool.vm.each { |v|
name = v.name
number = -1
number = name.split('-').last if (name =~ /^one-\d*$/)
vm = VCenterVm.new(@client, v)
vm.monitor
str_info << "\nVM = ["
str_info << "ID=#{number},"
str_info << "DEPLOY_ID=\"#{name}\","
str_info << "POLL=\"#{vm.info}\"]"
}
return str_info
end
end
################################################################################
# This class is a high level abstraction of a VI VirtualMachine class with
# OpenNebula semantics.
################################################################################
class VCenterVm
attr_reader :vm
############################################################################
# Creates a new VIVm using a RbVmomi::VirtualMachine object
# @param client [VCenterClient] client to connect to vCenter
# @param vm_vi [RbVmomi::VirtualMachine] it will be used if not nil
########################################################################
def initialize(client, vm_vi )
@vm = vm_vi
@client = client
@used_cpu = 0
@used_memory = 0
@net_rx = 0
@net_tx = 0
end
############################################################################
# Deploys a VM
# @xml_text XML repsentation of the VM
############################################################################
def self.deploy(xml_text, lcm_state, deploy_id, hostname)
if lcm_state == "BOOT"
return clone_vm(xml_text)
else
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.PowerOnVM_Task.wait_for_completion
return vm.config.uuid
end
end
############################################################################
# Cancels a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.cancel(deploy_id, hostname, lcm_state)
case lcm_state
when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY"
shutdown(deploy_id, hostname, lcm_state)
when "CANCEL", "LCM_INIT"
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
begin
vm.PowerOffVM_Task.wait_for_completion
rescue
end
vm.Destroy_Task.wait_for_completion
end
end
############################################################################
# Saves a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.save(deploy_id, hostname, lcm_state)
case lcm_state
when "SAVE_MIGRATE"
raise "Migration between vCenters cluster not supported"
when "SAVE_SUSPEND", "SAVE_STOP"
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.SuspendVM_Task.wait_for_completion
end
end
############################################################################
# Resumes a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.resume(deploy_id, hostname)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.PowerOnVM_Task.wait_for_completion
end
############################################################################
# Reboots a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.reboot(deploy_id, hostname)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.RebootGuest.wait_for_completion
end
############################################################################
# Resets a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.reset(deploy_id, hostname)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.ResetVM_Task.wait_for_completion
end
############################################################################
# Shutdown a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.shutdown(deploy_id, hostname, lcm_state)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
case lcm_state
when "SHUTDOWN"
begin
vm.ShutdownGuest.wait_for_completion
rescue
end
vm.PowerOffVM_Task.wait_for_completion
vm.Destroy_Task.wait_for_completion
when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY"
begin
vm.ShutdownGuest.wait_for_completion
rescue
end
vm.PowerOffVM_Task.wait_for_completion
end
end
############################################################################
# Create VM snapshot
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
# @param snaphot_name name of the snapshot
############################################################################
def self.create_snapshot(deploy_id, hostname, snapshot_name)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
snapshot_hash = {
:name => snapshot_name,
:description => "OpenNebula Snapshot of VM #{deploy_id}",
:memory => true,
:quiesce => true
}
vm = connection.find_vm_template(deploy_id)
vm.CreateSnapshot_Task(snapshot_hash).wait_for_completion
return snapshot_name
end
############################################################################
# Delete VM snapshot
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
# @param snaphot_name name of the snapshot
############################################################################
def self.delete_snapshot(deploy_id, hostname, snapshot_name)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
snapshot = vm.snapshot.rootSnapshotList.find {|s|
s.name == snapshot_name
}.snapshot
delete_snapshot_hash = {
:_this => snapshot,
:removeChildren => true
}
snapshot.RemoveSnapshot_Task(delete_snapshot_hash).wait_for_completion
end
############################################################################
# Revert VM snapshot
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
# @param snaphot_name name of the snapshot
############################################################################
def self.revert_snapshot(deploy_id, hostname, snapshot_name)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
snapshot = vm.snapshot.rootSnapshotList.find {|s|
s.name == snapshot_name
}.snapshot
revert_snapshot_hash = {
:_this => snapshot
}
snapshot.RevertToSnapshot_Task(revert_snapshot_hash).wait_for_completion
end
########################################################################
# Initialize the vm monitor information
########################################################################
def monitor
@summary = @vm.summary
@state = state_to_c(@summary.runtime.powerState)
if @state != 'a'
@used_cpu = 0
@used_memory = 0
@net_rx = 0
@net_tx = 0
return
end
@used_memory = @summary.quickStats.hostMemoryUsage * 1024
host = @vm.runtime.host
cpuMhz = host.summary.hardware.cpuMhz.to_f
@used_cpu =
((@summary.quickStats.overallCpuUsage.to_f / cpuMhz) * 100).to_s
@used_cpu = sprintf('%.2f',@used_cpu).to_s
# Check for negative values
@used_memory = 0 if @used_memory.to_i < 0
@used_cpu = 0 if @used_cpu.to_i < 0
@esx_host = @vm.summary.runtime.host.name
@guest_ip = @vm.guest.ipAddress
@guest_state = @vm.guest.guestState
@vmware_tools = @vm.guest.toolsRunningStatus
@vmtools_ver = @vm.guest.toolsVersion
@vmtools_verst = @vm.guest.toolsVersionStatus
end
########################################################################
# Generates a OpenNebula IM Driver valid string with the monitor info
########################################################################
def info
return 'STATE=d' if @state == 'd'
str_info = ""
str_info << "GUEST_IP=" << @guest_ip.to_s << " " if @guest_ip
str_info << "STATE=" << @state << " "
str_info << "USEDCPU=" << @used_cpu.to_s << " "
str_info << "USEDMEMORY=" << @used_memory.to_s << " "
str_info << "NETRX=" << @net_rx.to_s << " "
str_info << "NETTX=" << @net_tx.to_s << " "
str_info << "ESX_HOST=" << @esx_host.to_s << " "
str_info << "GUEST_STATE=" << @guest_state.to_s << " "
str_info << "VMWARETOOLS_RUNNING_STATUS=" << @vmware_tools.to_s << " "
str_info << "VMWARETOOLS_VERSION=" << @vmtools_ver.to_s << " "
str_info << "VMWARETOOLS_VERSION_STATUS=" << @vmtools_verst.to_s << " "
end
########################################################################
# Generates an OpenNebula Template for this VCenterVm
#
#
########################################################################
def to_one
str = "NAME = \"#{@vm.name}\"\n"\
"CPU = \"#{@vm.config.hardware.numCPU}\"\n"\
"vCPU = \"#{@vm.config.hardware.numCPU}\"\n"\
"MEMORY = \"#{@vm.config.hardware.memoryMB}\"\n"\
"HYPERVISOR = \"vcenter\"\n"\
"PUBLIC_CLOUD = [\n"\
" TYPE =\"vcenter\",\n"\
" VM_TEMPLATE =\"#{@vm.config.uuid}\"\n"\
"]\n"\
"GRAPHICS = [\n"\
" TYPE =\"vnc\",\n"\
" LISTEN =\"0.0.0.0\"\n"\
"]\n"\
"SCHED_REQUIREMENTS=\"NAME=\\\"#{@vm.runtime.host.parent.name}\\\"\"\n"
end
private
########################################################################
# Converts the VI string state to OpenNebula state convention
########################################################################
def state_to_c(state)
case state
when 'poweredOn'
'a'
when 'suspended'
'p'
else
'd'
end
end
########################################################################
# Clone a vCenter VM Template and leaves it powered on
########################################################################
def self.clone_vm(xml_text)
xml = REXML::Document.new xml_text
pcs = xml.root.get_elements("//USER_TEMPLATE/PUBLIC_CLOUD")
raise "Cannot find VCenter element in VM template." if pcs.nil?
template = pcs.find { |t|
type = t.elements["TYPE"]
!type.nil? && type.text.downcase == "vcenter"
}
raise "Cannot find VCenter element in VM template." if template.nil?
uuid = template.elements["VM_TEMPLATE"]
raise "Cannot find VM_TEMPLATE in VCenter element." if uuid.nil?
uuid = uuid.text
vmid = xml.root.elements["/VM/ID"].text
hid = xml.root.elements["//HISTORY_RECORDS/HISTORY/HID"]
raise "Cannot find host id in deployment file history." if hid.nil?
connection = VIClient.new(hid)
vc_template = connection.find_vm_template(uuid)
relocate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(
:diskMoveType => :moveChildMostDiskBacking,
:pool => connection.resource_pool)
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
:location => relocate_spec,
:powerOn => true,
:template => false)
rc = vc_template.CloneVM_Task(
:folder => vc_template.parent,
:name => "one-#{vmid}",
:spec => clone_spec).wait_for_completion
vm_uuid = rc.config.uuid
vnc_port = xml.root.elements["/VM/TEMPLATE/GRAPHICS/PORT"]
vnc_listen = xml.root.elements["/VM/TEMPLATE/GRAPHICS/LISTEN"]
if !vnc_listen
vnc_listen = "0.0.0.0"
else
vnc_listen = vnc_listen.text
end
if vnc_port
spec = RbVmomi::VIM.VirtualMachineConfigSpec(:extraConfig =>
[{:key=>"remotedisplay.vnc.enabled", :value=>"TRUE"},
{:key=>"remotedisplay.vnc.port", :value=>vnc_port.text},
{:key=>"remotedisplay.vnc.ip", :value=>vnc_listen}])
rc.ReconfigVM_Task(:spec => spec).wait_for_completion
end
return vm_uuid
end
end
end

View File

@ -20,6 +20,7 @@
#include "NebulaUtil.h"
#include <arpa/inet.h>
#include <algorithm>
using namespace std;
@ -199,13 +200,21 @@ int AddressRange::from_vattr(VectorAttribute *vattr, string& error_msg)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int AddressRange::update_attributes(VectorAttribute *vup, string& error_msg)
int AddressRange::update_attributes(
VectorAttribute * vup,
bool keep_restricted,
string& error_msg)
{
/* --------------- Do not allow to modify a reservation ------- */
int pid;
bool is_reservation = (get_attribute("PARENT_NETWORK_AR_ID", pid) == 0);
if (keep_restricted)
{
remove_restricted(vup);
}
/* --------------- Copy non-update attributes ----------------- */
vup->replace("TYPE", attr->vector_value("TYPE"));
@ -237,6 +246,14 @@ int AddressRange::update_attributes(VectorAttribute *vup, string& error_msg)
attr->vector_value("PARENT_NETWORK_AR_ID"));
}
/* ----------------- restricted attributes ----------------- */
if (keep_restricted)
{
remove_all_except_restricted(attr);
vup->merge(attr, true);
}
/* ----------------- update known attributes ----------------- */
@ -336,11 +353,15 @@ int AddressRange::from_vattr_db(VectorAttribute *vattr)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AddressRange::to_xml(ostringstream &oss) const
void AddressRange::to_xml(ostringstream &oss, const vector<int>& vms,
const vector<int>& vns) const
{
const map<string,string>& ar_attrs = attr->value();
map<string,string>::const_iterator it;
bool all_vms = (vms.size() == 1 && vms[0] == -1);
bool all_vns = (vns.size() == 1 && vns[0] == -1);
oss << "<AR>";
for (it=ar_attrs.begin(); it != ar_attrs.end(); it++)
@ -363,7 +384,9 @@ void AddressRange::to_xml(ostringstream &oss) const
else
{
map<unsigned int, long long>::const_iterator it;
VectorAttribute lease("LEASE");
bool is_in;
oss << "<LEASES>";
@ -371,6 +394,34 @@ void AddressRange::to_xml(ostringstream &oss) const
{
lease.clear();
is_in = false;
if (it->second & PoolObjectSQL::VM)
{
int vmid = it->second & 0x00000000FFFFFFFFLL;
if (all_vms || (find(vms.begin(),vms.end(),vmid) != vms.end()))
{
lease.replace("VM", vmid);
is_in = true;
}
}
else if (it->second & PoolObjectSQL::NET)
{
int vnid = it->second & 0x00000000FFFFFFFFLL;
if (all_vns || (find(vns.begin(),vns.end(),vnid) != vns.end()))
{
lease.replace("VNET", vnid);
is_in = true;
}
}
if (!is_in)
{
continue;
}
set_mac(it->first, &lease);
if (type & 0x00000002 )
@ -383,19 +434,6 @@ void AddressRange::to_xml(ostringstream &oss) const
set_ip6(it->first, &lease);
}
if (it->second & PoolObjectSQL::VM)
{
int vmid = it->second & 0x00000000FFFFFFFFLL;
lease.replace("VM", vmid);
}
else if (it->second & PoolObjectSQL::NET)
{
int vnid = it->second & 0x00000000FFFFFFFFLL;
lease.replace("VNET", vnid);
}
lease.to_xml(oss);
}
@ -1318,3 +1356,44 @@ void AddressRange::set_restricted_attributes(
restricted_attributes.insert(one_util::toupper(attr_s));
}
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AddressRange::remove_restricted(VectorAttribute* va)
{
set<string>::const_iterator it;
size_t pos;
for (it=restricted_attributes.begin(); it!=restricted_attributes.end(); it++)
{
pos = it->find("AR/");
if (pos != string::npos)
{
va->remove( it->substr(pos+3) );
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AddressRange::remove_all_except_restricted(VectorAttribute* va)
{
map<string,string>::iterator it;
map<string,string> vals = va->value();
ostringstream oss;
for(it = vals.begin(); it != vals.end(); it++)
{
oss.str("");
oss << "AR/" << it->first;
if (restricted_attributes.count(oss.str()) == 0)
{
va->remove(it->first);
}
}
}

View File

@ -81,7 +81,10 @@ int AddressRangePool::add_ar(AddressRange * ar)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int AddressRangePool::update_ar(vector<Attribute *> ars, string& error_msg)
int AddressRangePool::update_ar(
vector<Attribute *> ars,
bool keep_restricted,
string& error_msg)
{
vector<Attribute *>::iterator it;
map<unsigned int, AddressRange *>::iterator ar_it;
@ -115,7 +118,7 @@ int AddressRangePool::update_ar(vector<Attribute *> ars, string& error_msg)
return -1;
}
return ar_it->second->update_attributes(va, error_msg);
return ar_it->second->update_attributes(va, keep_restricted, error_msg);
}
error_msg = "Wrong AR definition. AR vector attribute is missing.";
@ -225,7 +228,8 @@ int AddressRangePool::rm_ar(unsigned int ar_id, string& error_msg)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& AddressRangePool::to_xml(string& sstream, bool extended) const
string& AddressRangePool::to_xml(string& sstream, bool extended,
const vector<int>& vms, const vector<int>& vnets) const
{
if (extended)
{
@ -236,7 +240,7 @@ string& AddressRangePool::to_xml(string& sstream, bool extended) const
for (it=ar_pool.begin(); it!=ar_pool.end(); it++)
{
it->second->to_xml(oss);
it->second->to_xml(oss, vms, vnets);
}
oss << "</AR_POOL>";

View File

@ -25,7 +25,8 @@ source_files=[
'VirtualNetwork.cc',
'VirtualNetworkPool.cc',
'AddressRange.cc',
'AddressRangePool.cc'
'AddressRangePool.cc',
'VirtualNetworkTemplate.cc'
]
# Build library

View File

@ -19,6 +19,7 @@
#include "VirtualNetworkPool.h"
#include "VirtualNetworkTemplate.h"
#include "AddressRange.h"
#include "PoolObjectAuth.h"
#include "NebulaLog.h"
@ -67,6 +68,20 @@ VirtualNetwork::~VirtualNetwork()
delete obj_template;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualNetwork::get_permissions(PoolObjectAuth& auths)
{
PoolObjectSQL::get_permissions(auths);
if (parent_vid != -1)
{
auths.disable_cluster_acl = true;
auths.disable_all_acl = true;
}
}
/* ************************************************************************** */
/* Virtual Network :: Database Access Functions */
/* ************************************************************************** */
@ -74,13 +89,13 @@ VirtualNetwork::~VirtualNetwork()
const char * VirtualNetwork::table = "network_pool";
const char * VirtualNetwork::db_names =
"oid, name, body, uid, gid, owner_u, group_u, other_u, cid";
"oid, name, body, uid, gid, owner_u, group_u, other_u, cid, pid";
const char * VirtualNetwork::db_bootstrap = "CREATE TABLE IF NOT EXISTS"
" network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128),"
" body MEDIUMTEXT, uid INTEGER, gid INTEGER,"
" owner_u INTEGER, group_u INTEGER, other_u INTEGER,"
" cid INTEGER, UNIQUE(name,uid))";
" cid INTEGER, pid INTEGER, UNIQUE(name,uid))";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -206,7 +221,8 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualNetwork::replace_template(const string& tmpl_str, string& error_str)
int VirtualNetwork::replace_template(
const string& tmpl_str, bool keep_restricted, string& error_str)
{
string new_bridge;
bool b_vlan;
@ -229,6 +245,19 @@ int VirtualNetwork::replace_template(const string& tmpl_str, string& error_str)
return -1;
}
if (keep_restricted && is_reservation())
{
new_tmpl->remove_restricted();
if (obj_template != 0)
{
obj_template->remove_all_except_restricted();
string aux_error;
new_tmpl->merge(obj_template, aux_error);
}
}
delete obj_template;
obj_template = new_tmpl;
@ -325,7 +354,8 @@ int VirtualNetwork::insert_replace(SqlDB *db, bool replace, string& error_str)
<< owner_u << ","
<< group_u << ","
<< other_u << ","
<< cluster_id << ")";
<< cluster_id << ","
<< parent_vid << ")";
rc = db->exec(oss);
@ -361,39 +391,25 @@ error_common:
string& VirtualNetwork::to_xml(string& xml) const
{
return to_xml_extended(xml,false);
const vector<int> empty;
return to_xml_extended(xml,false, empty, empty);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& VirtualNetwork::to_xml64(string &xml64, bool extended)
string& VirtualNetwork::to_xml_extended(string& xml, const vector<int>& vms,
const vector<int>& vnets) const
{
string *str64;
to_xml_extended(xml64, extended);
str64 = one_util::base64_encode(xml64);
xml64 = *str64;
delete str64;
return xml64;
return to_xml_extended(xml,true, vms, vnets);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& VirtualNetwork::to_xml_extended(string& xml) const
{
return to_xml_extended(xml,true);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const
string& VirtualNetwork::to_xml_extended(string& xml, bool extended,
const vector<int>& vms, const vector<int>& vnets) const
{
ostringstream os;
@ -445,7 +461,7 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const
os << obj_template->to_xml(template_xml);
os << ar_pool.to_xml(leases_xml, extended);
os << ar_pool.to_xml(leases_xml, extended, vms, vnets);
os << "</VNET>";
@ -683,7 +699,10 @@ int VirtualNetwork::add_ar(VirtualNetworkTemplate * ars_tmpl, string& error_msg)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualNetwork::update_ar(VirtualNetworkTemplate * ars_tmpl, string& error_msg)
int VirtualNetwork::update_ar(
VirtualNetworkTemplate* ars_tmpl,
bool keep_restricted,
string& error_msg)
{
vector<Attribute *> tmp_ars;
@ -694,7 +713,9 @@ int VirtualNetwork::update_ar(VirtualNetworkTemplate * ars_tmpl, string& error_m
return -1;
}
return ar_pool.update_ar(tmp_ars, error_msg);
keep_restricted = keep_restricted && is_reservation();
return ar_pool.update_ar(tmp_ars, keep_restricted, error_msg);
}
/* -------------------------------------------------------------------------- */
@ -997,3 +1018,8 @@ int VirtualNetwork::reserve_addr_by_mac(VirtualNetwork *rvnet,
return 0;
}
bool VirtualNetwork::is_reservation() const
{
return parent_vid != -1;
}

View File

@ -20,6 +20,7 @@
#include "Nebula.h"
#include "PoolObjectAuth.h"
#include "AuthManager.h"
#include "AddressRange.h"
#include <sstream>
#include <ctype.h>
@ -35,6 +36,7 @@ VirtualNetworkPool::VirtualNetworkPool(
SqlDB * db,
const string& prefix,
int __default_size,
vector<const Attribute *>& restricted_attrs,
vector<const Attribute *> hook_mads,
const string& remotes_location,
const vector<const Attribute *>& _inherit_attrs):
@ -73,14 +75,17 @@ VirtualNetworkPool::VirtualNetworkPool(
_mac_prefix <<= 8;
_mac_prefix += tmp;
register_hooks(hook_mads, remotes_location);
VirtualNetworkTemplate::set_restricted_attributes(restricted_attrs);
AddressRange::set_restricted_attributes(restricted_attrs);
for (it = _inherit_attrs.begin(); it != _inherit_attrs.end(); it++)
{
const SingleAttribute* sattr = static_cast<const SingleAttribute *>(*it);
register_hooks(hook_mads, remotes_location);
inherit_attrs.push_back(sattr->value());
}
for (it = _inherit_attrs.begin(); it != _inherit_attrs.end(); it++)
{
const SingleAttribute* sattr = static_cast<const SingleAttribute *>(*it);
inherit_attrs.push_back(sattr->value());
}
}
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,25 @@
/* -------------------------------------------------------------------------- */
/* 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 "VirtualNetworkTemplate.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
vector<string> VirtualNetworkTemplate::restricted_attributes;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

Some files were not shown because too many files have changed in this diff Show More