1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

Merge branch 'feature-4215' into feature-4217

This commit is contained in:
Ruben S. Montero 2016-02-02 14:17:20 +01:00
commit b01e2336c5
110 changed files with 4561 additions and 2075 deletions

View File

@ -121,9 +121,11 @@ public:
* 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.
* @param vrs list of VRouter the user can access VNET usage info from.
* A vector containing just -1 means all VRouters.
*/
void to_xml(ostringstream &oss, const vector<int>& vms,
const vector<int>& vnets) const;
const vector<int>& vnets, const vector<int>& vrs) const;
// *************************************************************************
// Address allocation functions

View File

@ -341,10 +341,12 @@ public:
* 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.
* @param vrs list of VRouter the user can access VNET usage info from.
* A vector containing just -1 means all VRouters.
* @return the string with the XML
*/
string& to_xml(string& sstream, bool extended, const vector<int>& vms,
const vector<int>& vnets) const;
const vector<int>& vnets, const vector<int>& vrs) const;
private:
/**

View File

@ -201,6 +201,17 @@ namespace one_util
* @return trimed string
*/
std::string trim(const std::string& str);
/**
* Returns a copy of st with the all occurrences of "find" substituted
* for "replacement"
* @param st string input
* @param sfind string to search for
* @param replacement string to replace occurrences with
* @return a string copy
*/
std::string gsub(const std::string& st, const std::string& sfind,
const std::string& replacement);
};
#endif /* _NEBULA_UTIL_H_ */

View File

@ -80,11 +80,19 @@ public:
/**
* Returns a copy of the IDs set
*/
set<int> get_collection_copy()
set<int> get_collection_copy() const
{
return set<int> (collection_set);
};
/**
* Returns a reference to the IDs set
*/
const set<int>& get_collection() const
{
return collection_set;
};
/**
* Returns true if the collection contains the given id
* @param id ID to search

View File

@ -49,6 +49,7 @@ public:
*/
enum ObjectType
{
NONE = 0x0000000000000000LL,
VM = 0x0000001000000000LL,
HOST = 0x0000002000000000LL,
NET = 0x0000004000000000LL,

View File

@ -49,7 +49,7 @@ public:
* @param error string
* @return true if the operation can be performed
*/
virtual bool check(Template* tmpl, Quotas& default_quotas, string& error) = 0;
//virtual bool check(Template* tmpl, Quotas& default_quotas, string& error) = 0;
/**
* Check if a resource update in usage counters will exceed the
@ -69,7 +69,7 @@ public:
* Decrement usage counters when deallocating image
* @param tmpl template for the resource
*/
virtual void del(Template* tmpl) = 0;
//virtual void del(Template* tmpl) = 0;
/**
* Returns the name that identifies the quota in a template

View File

@ -18,6 +18,7 @@
#define QUOTA_NETWORK_H_
#include "Quota.h"
#include "PoolObjectSQL.h"
/**
* DataStore Quotas, defined as:
@ -47,18 +48,21 @@ public:
/**
* Check if the resource allocation will exceed the quota limits. If not
* the usage counters are updated
* @param otype object type, VM or VRouter
* @param tmpl template for the resource
* @param default_quotas Quotas that contain the default limits
* @param error string
* @return true if the operation can be performed
*/
bool check(Template* tmpl, Quotas& default_quotas, string& error);
bool check(PoolObjectSQL::ObjectType otype, Template* tmpl,
Quotas& default_quotas, string& error);
/**
* Decrement usage counters when deallocating image
* @param otype object type, VM or VRouter
* @param tmpl template for the resource
*/
void del(Template* tmpl);
void del(PoolObjectSQL::ObjectType otype, Template* tmpl);
protected:

View File

@ -35,7 +35,8 @@ public:
VM, /**< Checks VM usage (MEMORY, CPU and VMS) */
NETWORK, /**< Checks Network usage (leases) */
IMAGE, /**< Checks Image usage (RVMs using it) */
VIRTUALMACHINE /**< Checks all VM associated resources VM, NETWORK, IMAGE */
VIRTUALMACHINE, /**< Checks all VM associated resources VM, NETWORK, IMAGE */
VIRTUALROUTER /**< Checks the Virtual Router NETWORK usage (leases) */
};
/**
@ -69,17 +70,6 @@ public:
return datastore_quota.get_quota(id, va);
}
/**
* Delete VM related usage (network, image and compute) from quota counters.
* @param tmpl template for the image, with usage
*/
void vm_del(Template * tmpl)
{
network_quota.del(tmpl);
vm_quota.del(tmpl);
image_quota.del(tmpl);
}
/**
* Gets a VM quota identified by its ID.
*

View File

@ -27,6 +27,77 @@
using namespace std;
/**
* This class represents the dynamic attributes: specific for a request of the
* same method.
*/
struct RequestAttributes
{
public:
int uid; /**< id of the user */
int gid; /**< id of the user's group */
string uname; /**< name of the user */
string gname; /**< name of the user's group */
string password; /**< password of the user */
set<int> group_ids; /**< set of user's group ids */
string session; /**< Session from ONE XML-RPC API */
int req_id; /**< Request ID for log messages */
int umask; /**< User umask for new objects */
xmlrpc_c::value * retval; /**< Return value from libxmlrpc-c */
PoolObjectSQL::ObjectType resp_obj; /**< object type */
int resp_id; /**< Id of the object */
string resp_msg; /**< Additional response message */
RequestAttributes(){};
RequestAttributes(const RequestAttributes& ra)
{
uid = ra.uid;
gid = ra.gid;
uname = ra.uname;
gname = ra.gname;
password = ra.password;
session = ra.session;
retval = ra.retval;
umask = ra.umask;
resp_obj = ra.resp_obj;
resp_id = ra.resp_id;
resp_msg = ra.resp_msg;
};
RequestAttributes(int _uid, int _gid, const RequestAttributes& ra)
{
uid = _uid;
gid = _gid;
password = "";
uname = "";
gname = "";
umask = 0;
session = ra.session;
retval = ra.retval;
resp_obj = PoolObjectSQL::NONE;
resp_id = -1;
resp_msg = "";
};
};
/**
* The Request Class represents the basic abstraction for the OpenNebula
* XML-RPC API. This interface must be implemented by any XML-RPC API call
@ -34,16 +105,6 @@ using namespace std;
class Request: public xmlrpc_c::method
{
public:
/**
* Wraps the actual execution function by authorizing the user
* and calling the request_execute virtual function
* @param _paramlist list of XML parameters
* @param _retval value to be returned to the client
*/
virtual void execute(
xmlrpc_c::paramList const& _paramList,
xmlrpc_c::value * const _retval);
/**
* Error codes for the XML-RPC API
*/
@ -55,8 +116,17 @@ public:
ACTION = 0x0800,
XML_RPC_API = 0x1000,
INTERNAL = 0x2000,
ALLOCATE = 0x4000
};
/**
* Gets a string representation for the Auth object in the
* request.
* @param ob object for the auth operation
* @return string equivalent of the object
*/
static string object_name(PoolObjectSQL::ObjectType ob);
/**
* Sets the format string to log xml-rpc method calls. The format string
* interprets the following sequences:
@ -77,69 +147,9 @@ public:
}
protected:
/* ---------------------------------------------------------------------*/
/* Attributes of the Request */
/* ---------------------------------------------------------------------*/
/* -------- Dynamic (specific for a request of the same method) -------- */
struct RequestAttributes
{
int uid; /**< id of the user */
int gid; /**< id of the user's group */
string uname; /**< name of the user */
string gname; /**< name of the user's group */
string password; /**< password of the user */
set<int> group_ids; /**< set of user's group ids */
string session; /**< Session from ONE XML-RPC API */
int req_id; /**< Request ID for log messages */
int umask; /**< User umask for new objects */
xmlrpc_c::value * retval; /**< Return value from libxmlrpc-c */
RequestAttributes(){};
RequestAttributes(const RequestAttributes& ra)
{
uid = ra.uid;
gid = ra.gid;
uname = ra.uname;
gname = ra.gname;
password = ra.password;
session = ra.session;
retval = ra.retval;
umask = ra.umask;
};
RequestAttributes(int _uid, int _gid, const RequestAttributes& ra)
{
uid = _uid;
gid = _gid;
password = "";
uname = "";
gname = "";
umask = 0;
session = ra.session;
retval = ra.retval;
};
};
/* -------- Static (shared among request of the same method) -------- */
/* ---------------------------------------------------------------------- */
/* Static Request Attributes: shared among request of the same method */
/* ---------------------------------------------------------------------- */
PoolSQL * pool; /**< Pool of objects */
string method_name; /**< The name of the XML-RPC method */
@ -150,11 +160,11 @@ protected:
static string format_str;
/* -------------------- Constructors ---------------------------------- */
Request(const string& mn,
const string& signature,
const string& help): pool(0),method_name(mn)
/* ---------------------------------------------------------------------- */
/* Class Constructors */
/* ---------------------------------------------------------------------- */
Request(const string& mn, const string& signature, const string& help):
pool(0),method_name(mn)
{
_signature = signature;
_help = help;
@ -164,9 +174,88 @@ protected:
virtual ~Request(){};
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* Methods to execute the request when received at the server */
/* ---------------------------------------------------------------------- */
/**
* Wraps the actual execution function by authorizing the user
* and calling the request_execute virtual function
* @param _paramlist list of XML parameters
* @param _retval value to be returned to the client
*/
virtual void execute(xmlrpc_c::paramList const& _paramList,
xmlrpc_c::value * const _retval);
/**
* Actual Execution method for the request. Must be implemented by the
* XML-RPC requests
* @param _paramlist of the XML-RPC call (complete list)
* @param att the specific request attributes
*/
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att) = 0;
/**
* Locks the requested object, gets information, and unlocks it
*
* @param pool object pool
* @param id of the object
* @param type of the object
* @param att the specific request attributes
*
* @param perms returns the object's permissions
* @param name returns the object's name
* @param throw_error send error response to client if object not found
*
* @return 0 on success, -1 otherwise
*/
int get_info(PoolSQL * pool,
int id,
PoolObjectSQL::ObjectType type,
RequestAttributes& att,
PoolObjectAuth& perms,
string& name,
bool throw_error);
/* ---------------------------------------------------------------------- */
/* Methods to send response to xml-rpc client */
/* ---------------------------------------------------------------------- */
/**
* Builds an XML-RPC response updating retval. After calling this function
* the xml-rpc excute method should return
* @param val to be returned to the client
* @param att the specific request attributes
*/
void success_response(int val, RequestAttributes& att);
/**
* Builds an XML-RPC response updating retval. After calling this function
* the xml-rpc excute method should return
* @param val string to be returned to the client
* @param att the specific request attributes
*/
void success_response(const string& val, RequestAttributes& att);
/**
* Builds an XML-RPC response updating retval. After calling this function
* the xml-rpc execute method should return
* @param val to be returned to the client
* @param att the specific request attributes
*/
void success_response(bool val, RequestAttributes& att);
/**
* Builds an XML-RPC response updating retval. After calling this function
* the xml-rpc excute method should return. A descriptive error message
* is constructed using att.resp_obj, att.resp_id and/or att.resp_msg and
* the ErrorCode
* @param ec error code for this call
* @param ra the specific request attributes
*/
void failure_response(ErrorCode ec, RequestAttributes& ra);
/* ---------------------------------------------------------------------- */
/* Authorization methods for requests */
/* ---------------------------------------------------------------------- */
/**
* Performs a basic authorization for this request using the uid/gid
* from the request. The function gets the object from the pool to get
@ -196,7 +285,7 @@ protected:
* @return true if the user is authorized.
*/
bool basic_authorization(int oid, AuthRequest::Operation op,
RequestAttributes& att);
RequestAttributes& att);
/**
* Performs a basic quota check for this request using the uid/gid
@ -209,10 +298,8 @@ protected:
*
* @return true if the user is authorized.
*/
bool quota_authorization(
Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att);
bool quota_authorization(Template * tmpl, Quotas::QuotaType qtype,
RequestAttributes& att);
/**
* Performs a basic quota check for this request using the uid/gid
@ -227,11 +314,8 @@ protected:
* @param error_str Error reason, if any
* @return true if the user is authorized.
*/
bool quota_authorization(
Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att,
string& error_str);
static bool quota_authorization(Template * tmpl, Quotas::QuotaType qtype,
RequestAttributes& att, string& error_str);
/**
* Performs rollback on usage counters for a previous quota check operation
@ -239,136 +323,53 @@ protected:
* @param tmpl describing the object
* @param att the specific request attributes
*/
void quota_rollback(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att);
static void quota_rollback(Template * tmpl, Quotas::QuotaType qtype,
RequestAttributes& att);
/**
* Actual Execution method for the request. Must be implemented by the
* XML-RPC requests
* @param _paramlist of the XML-RPC call (complete list)
* @param att the specific request attributes
*/
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att) = 0;
private:
/* ---------------------------------------------------------------------- */
/* Functions to manage user and group quotas */
/* ---------------------------------------------------------------------- */
static bool user_quota_authorization(Template * tmpl, Quotas::QuotaType qtype,
RequestAttributes& att, string& error_str);
/**
* Builds an XML-RPC response updating retval. After calling this function
* the xml-rpc excute method should return
* @param val to be returned to the client
* @param att the specific request attributes
*/
void success_response(int val, RequestAttributes& att);
static bool group_quota_authorization(Template * tmpl, Quotas::QuotaType qtype,
RequestAttributes& att, string& error_str);
/**
* Builds an XML-RPC response updating retval. After calling this function
* the xml-rpc excute method should return
* @param val string to be returned to the client
* @param att the specific request attributes
*/
void success_response(const string& val, RequestAttributes& att);
static void user_quota_rollback(Template * tmpl, Quotas::QuotaType qtype,
RequestAttributes& att);
/**
* Builds an XML-RPC response updating retval. After calling this function
* the xml-rpc execute method should return
* @param val to be returned to the client
* @param att the specific request attributes
*/
void success_response(bool val, RequestAttributes& att);
static void group_quota_rollback(Template * tmpl, Quotas::QuotaType qtype,
RequestAttributes& att);
/**
* Builds an XML-RPC response updating retval. After calling this function
* the xml-rpc excute method should return
* @param ec error code for this call
* @param val string representation of the error
* @param att the specific request attributes
* @param va string representation of the error
* @param ra the specific request attributes
*/
void failure_response(ErrorCode ec,
const string& val,
RequestAttributes& att);
void failure_response(ErrorCode ec, const string& va, RequestAttributes& ra);
/**
* Gets a string representation for the Auth object in the
* request.
* @param ob object for the auth operation
* @return string equivalent of the object
*/
static string object_name(PoolObjectSQL::ObjectType ob);
/**
* Logs authorization errors
* @param message with the authorization error details
* @return string for logging
* @param att the specific request attributes
*/
string authorization_error (const string &message, RequestAttributes& att);
/**
* Logs authenticate errors
* @return string for logging
*/
string authenticate_error ();
/**
* Logs get object errors
* @param object over which the get failed
* @param id of the object over which the get failed
* @return string for logging
*/
string get_error (const string &object, int id);
/**
* Logs action errors
* @param err_desc brief description of the error
* @param err_detail additional error details from Managers & Pools
* @return string for logging
*/
string request_error (const string &err_desc, const string &err_detail);
/**
* Logs allocate errors
* @param message with the allocate error details
* @return string for logging
*/
string allocate_error (const string& error);
/**
* Logs allocate errors for a given resource
* @param obj the resource
* @param message with the allocate error details
* @return string for logging
*/
string allocate_error (PoolObjectSQL::ObjectType obj, const string& error);
/**
* Locks the requested object, gets information, and unlocks it
*
* @param pool object pool
* @param id of the object
* @param type of the object
* Logs the method invocation, including the arguments
* @param att the specific request attributes
*
* @param perms returns the object's permissions
* @param name returns the object's name
* @param throw_error send error response to client if object not found
*
* @return 0 on success, -1 otherwise
* @param paramList list of XML parameters
* @param format_str for the log
* @param hidden_params params not to be shown
*/
int get_info (PoolSQL * pool,
int id,
PoolObjectSQL::ObjectType type,
RequestAttributes& att,
PoolObjectAuth& perms,
string& name,
bool throw_error);
static void log_method_invoked(const RequestAttributes& att,
const xmlrpc_c::paramList& paramList, const string& format_str,
const std::string& method_name, const std::set<int>& hidden_params);
/**
* Logs the method result, including the output data or error message
*
* @param att the specific request attributes
* @param method_name that produced the error
*/
virtual void log_result(
const RequestAttributes& att);
static void log_result(const RequestAttributes& att,
const std::string& method_name);
/**
* Formats and adds a xmlrpc_c::value to oss.
@ -376,41 +377,7 @@ protected:
* @param v value to format
* @param oss stream to write v
*/
virtual void log_xmlrpc_value(
const xmlrpc_c::value& v,
ostringstream& oss);
private:
/**
* Logs the method invocation, including the arguments
*
* @param att the specific request attributes
* @param paramList list of XML parameters
*/
void log_method_invoked(
const RequestAttributes& att,
const xmlrpc_c::paramList& paramList);
/* ------------- Functions to manage user and group quotas -------------- */
bool user_quota_authorization(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att,
string& error_str);
bool group_quota_authorization(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att,
string& error_str);
void user_quota_rollback(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att);
void group_quota_rollback(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att);
static void log_xmlrpc_value(const xmlrpc_c::value& v, std::ostringstream& oss);
};
/* -------------------------------------------------------------------------- */

View File

@ -64,7 +64,6 @@ protected:
virtual int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
return -1;
@ -73,12 +72,11 @@ protected:
virtual int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att,
int cluster_id,
const string& cluster_name)
{
return pool_allocate(_paramList, tmpl, id, error_str, att);
return pool_allocate(_paramList, tmpl, id, att);
};
virtual int get_cluster_id(xmlrpc_c::paramList const& paramList)
@ -138,7 +136,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
bool allocate_authorization(Template * obj_template,
@ -175,7 +172,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att,
int cluster_id,
const string& cluster_name);
@ -249,7 +245,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
bool allocate_authorization(Template * obj_template,
@ -281,7 +276,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att,
int cluster_id,
const string& cluster_name);
@ -325,7 +319,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
};
@ -353,7 +346,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
private:
@ -389,7 +381,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att,
int cluster_id,
const string& cluster_name);
@ -445,7 +436,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
};
@ -478,7 +468,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
};
@ -514,7 +503,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
};
@ -547,7 +535,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
};
@ -580,7 +567,6 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
};
@ -614,8 +600,11 @@ public:
int pool_allocate(xmlrpc_c::paramList const& _paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att);
bool allocate_authorization(Template * obj_template,
RequestAttributes& att,
PoolObjectAuth * cluster_perms);
};
/* ------------------------------------------------------------------------- */

View File

@ -48,7 +48,6 @@ protected:
int source_id,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att) = 0;
};
@ -82,7 +81,6 @@ public:
int source_id,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
VMTemplatePool * tpool = static_cast<VMTemplatePool *>(pool);
@ -91,7 +89,7 @@ public:
static_cast<VirtualMachineTemplate *>(tmpl);
return tpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
ttmpl, &id, error_str);
ttmpl, &id, att.resp_msg);
};
};
@ -126,14 +124,13 @@ public:
int source_id,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
DocumentPool * docpool = static_cast<DocumentPool *>(pool);
Document * doc = docpool->get(source_id, true);
return docpool->allocate(att.uid, att.gid, att.uname, att.gname,
att.umask, doc->get_document_type(), tmpl, &id, error_str);
att.umask, doc->get_document_type(), tmpl, &id, att.resp_msg);
};
};
@ -167,13 +164,12 @@ public:
int source_id,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
SecurityGroupPool * secgrouppool = static_cast<SecurityGroupPool *>(pool);
return secgrouppool->allocate(att.uid, att.gid, att.uname, att.gname,
att.umask, tmpl, &id, error_str);
att.umask, tmpl, &id, att.resp_msg);
};
};
/* -------------------------------------------------------------------------- */

View File

@ -66,6 +66,24 @@ public:
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
/**
* Instantiates the VM Template, checking permissions, quotas, etc
* @param id VM Template ID
* @param name Name for the new VM. Can be empty
* @param on_hold True to start the VM on HOLD state
* @param str_uattrs Template supplied by user to merge with the original
* contents. Can be empty
* @param extra_attrs Template to be merged. It should contain internal
* configuration, and it won't be authenticated or checked for restricted
* attributes. Can be 0
* @param vmid on success of the new VM
* @param att the specific request attributes
*
* @return ErroCode for the request.
*/
static ErrorCode instantiate(int id, string name, bool on_hold,
string str_uattrs, Template* extra_attrs, int& vid, RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */

View File

@ -253,8 +253,16 @@ public:
~VirtualMachineAttachNic(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
void request_execute(xmlrpc_c::paramList const& pl, RequestAttributes& ra);
/**
* Process a NIC attahment request to a Virtual Machine
* @param id of the VirtualMachine
* @param tmpl with the new NIC description
* @param att attributes of this request
* @return ErroCode as defined in Request
*/
static ErrorCode attach(int id, VirtualMachineTemplate& tmpl, RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
@ -272,6 +280,15 @@ public:
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
/**
* Process a NIC detach request to a Virtual Machine
* @param id of the VirtualMachine
* @param nic_id id of the NIC
* @param att attributes of this request
* @return ErroCode as defined in Request
*/
static ErrorCode detach(int id, int nic_id, RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,118 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef REQUEST_MANAGER_VIRTUAL_ROUTER_H
#define REQUEST_MANAGER_VIRTUAL_ROUTER_H
#include "Request.h"
#include "Nebula.h"
using namespace std;
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class RequestManagerVirtualRouter: public Request
{
protected:
RequestManagerVirtualRouter(const string& method_name,
const string& help,
const string& params)
:Request(method_name,params,help)
{
Nebula& nd = Nebula::instance();
pool = nd.get_vrouterpool();
auth_object = PoolObjectSQL::VROUTER;
};
~RequestManagerVirtualRouter(){};
/* -------------------------------------------------------------------- */
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att) = 0;
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualRouterInstantiate : public RequestManagerVirtualRouter
{
public:
VirtualRouterInstantiate():
RequestManagerVirtualRouter("VirtualRouterInstantiate",
"Instantiates a new virtual machine associated to a virtual router",
"A:siiisbs")
{
auth_op = AuthRequest::MANAGE;
};
~VirtualRouterInstantiate(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualRouterAttachNic : public RequestManagerVirtualRouter
{
public:
VirtualRouterAttachNic():
RequestManagerVirtualRouter("VirtualRouterAttachNic",
"Attaches a new NIC to the virtual router, and its virtual machines",
"A:sis")
{
auth_op = AuthRequest::MANAGE;
};
~VirtualRouterAttachNic(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualRouterDetachNic : public RequestManagerVirtualRouter
{
public:
VirtualRouterDetachNic():
RequestManagerVirtualRouter("VirtualRouterDetachNic",
"Detaches a NIC from a virtual router, and its virtual machines",
"A:sii")
{
auth_op = AuthRequest::MANAGE;
};
~VirtualRouterDetachNic(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#endif

View File

@ -301,6 +301,34 @@ public:
const string& name,
vector<Attribute*>& values);
/**
* Gets the first VectorAttribute with the given name
* @param name the attribute name.
* @param vatt stores the first vector attribute found, or 0
* @return true if a vector attribute was found
*/
virtual bool get(
const string& name,
VectorAttribute*& vatt);
/**
* Gets all the Vector Attributes with the given name
* @param name the attribute name.
* @return the number of elements in the vector
*/
virtual int get(
const string& name,
vector<const VectorAttribute*>& values) const;
/**
* Gets all the Vector Attributes with the given name, non-const version
* @param name the attribute name.
* @return the number of elements in the vector
*/
virtual int get(
const string& name,
vector<VectorAttribute*>& values);
/**
* Gets the value of a Single attributes (string) with the given name.
* @param name the attribute name.

View File

@ -123,6 +123,22 @@ public:
ostream& xfr,
ostringstream& error);
/**
* Inserts a context command in the xfs stream
*
* @param vm The VM
* @param token_password Owner user's token password
* @param system_tm_mad The Transfer Manager for the system datastore
* @param xfr Stream where the transfer command will be written
*
* @return 0 on success
*/
int prolog_context_command(
VirtualMachine * vm,
const string& token_password,
string& system_tm_mad,
ostream& xfr);
/**
* Inserts a transfer command in the xfs stream
*

View File

@ -1318,6 +1318,8 @@ public:
*/
const VectorAttribute* get_disk(int disk_id) const;
const VectorAttribute* get_nic(int nic_id) const;
// ------------------------------------------------------------------------
// Virtual Router related functions
// ------------------------------------------------------------------------
@ -1334,6 +1336,13 @@ public:
*/
bool is_vrouter();
/**
* Checks if the given action is supported for Virtual Router VMs
* @param action VM action to check
* @return true if the action is supported for Virtual Router VMs
*/
static bool is_vrouter_action_supported(History::VMAction action);
// ------------------------------------------------------------------------
// Context related functions
// ------------------------------------------------------------------------
@ -1345,7 +1354,15 @@ public:
* @param token_password Password to encrypt the token, if it is set
* @return -1 in case of error, 0 if the VM has no context, 1 on success
*/
int generate_context(string &files, int &disk_id, string& token_password);
int generate_context(string &files, int &disk_id, const string& token_password);
const VectorAttribute* get_context_disk() const;
/**
* Returns the CREATED_BY template attribute, or the uid if it does not exist
* @return uid
*/
int get_created_by_uid() const;
// -------------------------------------------------------------------------
// "Save as" Disk related functions (save_as hot)
@ -1567,18 +1584,6 @@ public:
int uid,
string& error_str);
/**
* Cleans the ATTACH = YES attribute from the NICs
*/
void clear_attach_nic();
/**
* Deletes the NIC that was in the process of being attached
*
* @return the deleted NIC or 0 if none was deleted
*/
VectorAttribute * delete_attach_nic();
/**
* Adds a new NIC to the virtual machine template. The NIC should be
* generated by the build_attach_nic
@ -1587,12 +1592,37 @@ public:
*/
void set_attach_nic(VectorAttribute * new_nic, vector<VectorAttribute*> &rules);
/**
* Cleans the ATTACH = YES attribute from the NICs
*/
void attach_nic_success();
/**
* Deletes the NIC that was in the process of being attached
*
* @return the deleted NIC or 0 if none was deleted
*/
VectorAttribute * attach_nic_failure();
/**
* Sets the attach attribute to the given NIC
* @param nic_id of the NIC
* @return 0 if the nic_id was found, -1 otherwise
*/
int set_attach_nic(int nic_id);
int set_detach_nic(int nic_id);
/**
* Deletes the NIC that was in the process of being detached
*
* @return the deleted NIC or 0 if none was deleted
*/
VectorAttribute * detach_nic_success();
/**
* Cleans the ATTACH = YES attribute from the NIC, restores the NIC context
* variables
*/
void detach_nic_failure();
// ------------------------------------------------------------------------
// Snapshot related functions
@ -1711,7 +1741,6 @@ public:
*/
void delete_snapshots();
private:
// -------------------------------------------------------------------------
@ -1978,6 +2007,13 @@ private:
*/
int parse_vrouter(string& error_str);
/**
* Known Virtual Router attributes, to be moved from the user template
* to the template
*/
static const char* VROUTER_ATTRIBUTES[];
static const int NUM_VROUTER_ATTRIBUTES;
/**
* Known attributes for network contextualization rendered as:
* ETH_<nicid>_<context[0]> = $NETWORK[context[1], vnet_name]
@ -2021,6 +2057,15 @@ private:
*/
int parse_context(string& error_str);
/**
* Parses the current contents of the context vector attribute,
* without adding any attributes. Substitutes $VARIABLE,
* $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE]
*
* @return 0 on success
*/
int reparse_context();
/**
* Parse the "SCHED_REQUIREMENTS" attribute of the template by substituting
* $VARIABLE, $VARIABLE[ATTR] and $VARIABLE[ATTR, ATTR = VALUE]
@ -2123,6 +2168,13 @@ private:
static_cast<const VirtualMachine&>(*this).get_disk(disk_id));
};
/**
* Returns the NIC that is waiting for an attachment action
*
* @return the NIC waiting for an attachment action, or 0
*/
VectorAttribute* get_attach_nic();
// ------------------------------------------------------------------------
// Public cloud templates related functions
// ------------------------------------------------------------------------

View File

@ -359,7 +359,14 @@ public:
*
* @param vid VM id
*/
void delete_attach_nic(int vid);
void attach_nic_failure(int vid);
/**
* Deletes the NIC that was in the process of being detached
*
* @param vid VM id
*/
void detach_nic_success(int vid);
/**
* Deletes an entry in the HV-2-vmid mapping table for imported VMs
@ -417,6 +424,15 @@ private:
* @return 0 on success
*/
int insert_index(const string& deploy_id, int vm_id, bool replace);
// -------------------------------------------------------------------------
/**
* Helper method for delete attach/detach
* @param vid VM id
* @param attach true for an attach action, false for detach
*/
void delete_hotplug_nic(int vid, bool attach);
};
#endif /*VIRTUAL_MACHINE_POOL_H_*/

View File

@ -409,10 +409,12 @@ public:
* 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.
* @param vrs list of VRouter the user can access reservation info from.
* A vector containing just -1 means all VRouters.
* @return a reference to the generated string
*/
string& to_xml_extended(string& xml, const vector<int>& vms,
const vector<int>& vnets) const;
const vector<int>& vnets, const vector<int>& vrs) const;
/**
* Gets a string based attribute (single) from an address range. If the
@ -527,7 +529,8 @@ private:
* @return a reference to the generated string
*/
string& to_xml_extended(string& xml, bool extended,
const vector<int>& vm_ids, const vector<int>& vnet_oids) const;
const vector<int>& vm_ids, const vector<int>& vnet_oids,
const vector<int>& vr_ids) const;
/**
* Rebuilds the object from an xml formatted string

View File

@ -113,35 +113,23 @@ public:
* -2 not using the pool
*/
int nic_attribute(
VectorAttribute* nic,
int nic_id,
int uid,
int vid,
string& error_str);
/**
* Generates a NIC attribute for VRouters using the VirtualNetwork
* metadata
* @param nic the nic attribute to be generated
* @param uid of the VM owner
* @param vrid of the VRouter requesting the lease
* @param error_str string describing the error
* @return 0 on success,
* -1 error,
* -2 not using the pool
*/
int vrouter_nic_attribute(
VectorAttribute * nic,
int uid,
int vrid,
string& error_str);
PoolObjectSQL::ObjectType ot,
VectorAttribute* nic,
int nic_id,
int uid,
int vid,
string& error_str);
/**
* Generates an Authorization token for a NIC attribute
* @param nic the nic to be authorized
* @param ar the AuthRequest
*/
void authorize_nic(VectorAttribute * nic, int uid, AuthRequest * ar);
void authorize_nic(
PoolObjectSQL::ObjectType ot,
VectorAttribute * nic,
int uid,
AuthRequest * ar);
/**
* Bootstraps the database table(s) associated to the VirtualNetwork pool

View File

@ -20,6 +20,8 @@
#include "PoolObjectSQL.h"
#include "Template.h"
#include "ObjectCollection.h"
#include "VirtualMachineTemplate.h"
#include "AuthRequest.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -38,10 +40,14 @@ public:
*/
string& to_xml(string& xml) const;
int add_vmid(int vmid)
{
return vms.add_collection_id(vmid);
}
int add_vmid(int vmid);
bool has_vmids() const;
/**
* Returns a copy of the VM IDs set
*/
set<int> get_vms() const;
// ------------------------------------------------------------------------
// Template Contents
@ -65,7 +71,44 @@ public:
*(static_cast<Template *>(obj_template)));
};
Template * get_nics() const;
Template * get_vm_template() const;
// ------------------------------------------------------------------------
// Attach and detach NIC
// ------------------------------------------------------------------------
/**
* Adds a new NIC to the virtual router template.
* @param tmpl Template, should contain only one NIC
* @param error_str error reason, if any
*
* @return 0 on failure, the NIC to attach to each VM on success
*/
VectorAttribute * attach_nic(
VirtualMachineTemplate * tmpl, string& error_str);
/**
* Deletes the NIC from the virtual router template.
*
* @param nic_id of the NIC
* @return 0 if the nic_id was found, -1 otherwise
*/
int detach_nic(int nic_id);
// ------------------------------------------------------------------------
// Authorization related functions
// ------------------------------------------------------------------------
/**
* Sets an authorization request for a Virtual Router template based on
* the networks used
* @param uid for template owner
* @param ar the AuthRequest object
* @param tmpl the virtual router template
*/
static void set_auth_request(int uid,
AuthRequest& ar,
Template *tmpl);
private:
// -------------------------------------------------------------------------
@ -185,6 +228,24 @@ private:
* @return 0 on success, -1 otherwise
*/
int release_network_leases(VectorAttribute const * nic);
/**
* Returns the nic with the giver nic_id, or 0
* @param nic_id
* @return nic if found, 0 if not found
*/
VectorAttribute* get_nic(int nic_id) const;
// -------------------------------------------------------------------------
// VM Management
// -------------------------------------------------------------------------
/**
* Tries to shutdown, or delete, all this Virtual Router's VMs
*
* @return 0 on success, -1 otherwise
*/
int shutdown_vms();
};
#endif /*VIRTUAL_ROUTER_H_*/

View File

@ -27,7 +27,14 @@ class VirtualRouterPool : public PoolSQL
{
public:
VirtualRouterPool(SqlDB * db) : PoolSQL(db, VirtualRouter::table, true, true){};
VirtualRouterPool(
SqlDB * db,
vector<const Attribute *> hook_mads,
const string& remotes_location)
: PoolSQL(db, VirtualRouter::table, true, true)
{
register_hooks(hook_mads, remotes_location);
};
~VirtualRouterPool(){};
@ -112,6 +119,17 @@ public:
return VirtualRouter::bootstrap(_db);
};
/**
* Gets the IDs of objects 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, VirtualRouter::table, where);
};
private:
/**
* Factory method to produce objects

View File

@ -688,7 +688,9 @@ VMM_EXEC_KVM_SCRIPTS="src/vmm_mad/remotes/kvm/cancel \
src/vmm_mad/remotes/kvm/snapshot_create \
src/vmm_mad/remotes/kvm/snapshot_revert \
src/vmm_mad/remotes/kvm/snapshot_delete \
src/vmm_mad/remotes/kvm/shutdown"
src/vmm_mad/remotes/kvm/shutdown \
src/vmm_mad/remotes/kvm/reconfigure \
src/vmm_mad/remotes/kvm/prereconfigure"
#-------------------------------------------------------------------------------
# VMM SH Driver Xen scripts, to be installed under $REMOTES_LOCATION/vmm/xen
@ -1277,7 +1279,8 @@ ONEDB_LOCAL_MIGRATOR_FILES="src/onedb/local/4.5.80_to_4.7.80.rb \
src/onedb/local/4.9.80_to_4.10.3.rb \
src/onedb/local/4.10.3_to_4.11.80.rb \
src/onedb/local/4.11.80_to_4.13.80.rb \
src/onedb/local/4.13.80_to_4.13.85.rb"
src/onedb/local/4.13.80_to_4.13.85.rb \
src/onedb/local/4.13.85_to_4.90.0.rb"
ONEDB_PATCH_FILES="src/onedb/patches/4.14_monitoring.rb \
src/onedb/patches/history_times.rb"

View File

@ -746,6 +746,7 @@ MARKET_MAD = [
# - NO, The hook is executed in the OpenNebula server (default)
#
# Virtual Network (VNET_HOOK)
# Virtual Router (VROUTER_HOOK)
# User (USER_HOOK)
# Group (GROUP_HOOK)
# Image (IMAGE_HOOK)

100
share/man/onevrouter.1 Normal file
View File

@ -0,0 +1,100 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEVROUTER" "1" "January 2016" "" "onevrouter(1) -- manages OpenNebula Virtual Routers"
.
.SH "NAME"
\fBonevrouter\fR \- manages OpenNebula Virtual Routers
.
.SH "SYNOPSIS"
\fBonevrouter\fR \fIcommand\fR [\fIargs\fR] [\fIoptions\fR]
.
.SH "OPTIONS"
.
.nf
\-a, \-\-append Append new attributes to the current template
\-l, \-\-list x,y,z Selects columns to display with list command
\-d, \-\-delay x Sets the delay in seconds for top command
\-f, \-\-filter x,y,z Filter data\. An array is specified with
column=value pairs\.
\-\-csv Write table in csv format
\-x, \-\-xml Show the resource in xml format
\-n, \-\-numeric Do not translate user and group IDs
\-\-describe Describe list columns
\-v, \-\-verbose Verbose mode
\-h, \-\-help Show this message
\-V, \-\-version Show version and copyright information
\-\-user name User name used to connect to OpenNebula
\-\-password password Password to authenticate with OpenNebula
\-\-endpoint endpoint URL of OpenNebula xmlrpc frontend
.
.fi
.
.SH "COMMANDS"
.
.IP "\(bu" 4
create \fIfile\fR Creates a new Virtual Router from the given description
.
.IP "\(bu" 4
delete \fIrange|vrouterid_list\fR Deletes the given Virtual Router
.
.IP "\(bu" 4
chgrp \fIrange|vrouterid_list\fR \fIgroupid\fR Changes the Virtual Router group
.
.IP "\(bu" 4
chown \fIrange|vrouterid_list\fR \fIuserid\fR [\fIgroupid\fR] Changes the Virtual Router owner and group
.
.IP "\(bu" 4
chmod \fIrange|vrouterid_list\fR \fIoctet\fR Changes the Virtual Router permissions
.
.IP "\(bu" 4
update \fIvrouterid\fR [\fIfile\fR] Update the Virtual Router contents\. If a path is not provided the editor will be launched to modify the current content\. valid options: append
.
.IP "\(bu" 4
rename \fIvrouterid\fR \fIname\fR Renames the Virtual Router
.
.IP "\(bu" 4
list [\fIfilterflag\fR] Lists the Virtual Routers in the pool valid options: list, delay, filter, csv, xml, numeric, describe
.
.IP "\(bu" 4
show \fIsecgroupid\fR Shows information for the given Virtual Router valid options: xml
.
.IP "\(bu" 4
top [\fIfilterflag\fR] Lists Virtual Routers continuously valid options: list, delay, filter, csv, xml, numeric, describe
.
.IP "" 0
.
.SH "ARGUMENT FORMATS"
.
.IP "\(bu" 4
file Path to a file
.
.IP "\(bu" 4
range List of id\'s in the form 1,8\.\.15
.
.IP "\(bu" 4
text String
.
.IP "\(bu" 4
groupid OpenNebula GROUP name or id
.
.IP "\(bu" 4
userid OpenNebula USER name or id
.
.IP "\(bu" 4
vrouterid OpenNebula VROUTER name or id
.
.IP "\(bu" 4
vrouterid_list Comma\-separated list of OpenNebula VROUTER names or ids
.
.IP "\(bu" 4
filterflag a, all all the known VROUTERs m, mine the VROUTER belonging to the user in ONE_AUTH g, group \'mine\' plus the VROUTER belonging to the groups the user is member of uid VROUTER of the user identified by this uid user VROUTER of the user identified by the username
.
.IP "" 0
.
.SH "LICENSE"
OpenNebula 4\.14\.1 Copyright 2002\-2015, OpenNebula Project, OpenNebula Systems
.
.P
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

View File

@ -964,7 +964,7 @@ EOT
end
end
def self.create_template(options)
def self.create_template(options, template_obj=nil)
template=''
template<<"NAME=\"#{options[:name]}\"\n" if options[:name]
@ -1021,6 +1021,17 @@ EOT
context=create_context(options)
template<<context if context
if options[:userdata] && !template_obj.nil?
if template_obj.has_elements?('TEMPLATE/EC2')
template_obj.add_element(
'TEMPLATE/EC2',
'USERDATA' => options[:userdata])
template << template_obj.template_like_str(
'TEMPLATE', false, 'EC2')
end
end
[0, template]
end

View File

@ -51,14 +51,6 @@ EOT
"information, such as the SIZE for each DISK"
}
VROUTER={
:name => "vrouter",
:large => "--vrouter vrid",
:format => Integer,
:description => "Creates a VM associated to the given Virtual Router. "+
"The NIC elements defined in the Virtual Router will be used"
}
def self.rname
"VMTEMPLATE"
end
@ -119,7 +111,7 @@ EOT
table
end
def get_user_inputs(template)
def self.get_user_inputs(template)
user_inputs = template['VMTEMPLATE']['TEMPLATE']['USER_INPUTS']
return "" if !user_inputs

View File

@ -84,6 +84,14 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
}
}
IP={
:name => "ip",
:short => "-i ip",
:large => "--ip ip",
:format => String,
:description => "IP address for the new NIC"
}
FILE = {
:name => "file",
:short => "-f file",
@ -170,16 +178,11 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
end
vm_nics.each do |nic|
if nic.has_key?("IP")
ips.push(nic["IP"])
end
if nic.has_key?("IP6_GLOBAL")
ips.push(nic["IP6_GLOBAL"])
end
if nic.has_key?("IP6_ULA")
ips.push(nic["IP6_ULA"])
["IP", "IP6_GLOBAL", "IP6_ULA",
"VROUTER_IP", "VROUTER_IP6_GLOBAL", "VROUTER_IP6_ULA"].each do |attr|
if nic.has_key?(attr)
ips.push(nic[attr])
end
end
end
@ -517,6 +520,8 @@ in the frontend machine.
OpenNebulaHelper.time_to_str(vm['/VM/ETIME'])]
value=vm['DEPLOY_ID']
puts str % ["DEPLOY ID", value=="" ? "-" : value]
value=vm['TEMPLATE/VROUTER_ID']
puts str % ["VIRTUAL ROUTER ID", value] if value
puts
@ -735,37 +740,31 @@ in the frontend machine.
next if nic.has_key?("CLI_DONE")
if nic.has_key?("IP6_LINK")
shown_ips << nic["IP6_LINK"]
["IP6_LINK", "IP6_ULA", "IP6_GLOBAL"].each do |attr|
if nic.has_key?(attr)
shown_ips << nic[attr]
ip6_link = {"IP" => nic.delete("IP6_LINK"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
ipstr = {"IP" => nic.delete(attr),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ipstr)
array_id += 1
array_id += 1
end
end
if nic.has_key?("IP6_ULA")
shown_ips << nic["IP6_ULA"]
["VROUTER_IP", "VROUTER_IP6_LINK",
"VROUTER_IP6_ULA", "VROUTER_IP6_GLOBAL"].each do |attr|
if nic.has_key?(attr)
shown_ips << nic[attr]
ip6_link = {"IP" => nic.delete("IP6_ULA"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
ipstr = {"IP" => nic.delete(attr) + " (VRouter)",
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ipstr)
array_id += 1
end
if nic.has_key?("IP6_GLOBAL")
shown_ips << nic["IP6_GLOBAL"]
ip6_link = {"IP" => nic.delete("IP6_GLOBAL"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
array_id += 1
array_id += 1
end
end
shown_ips << nic["IP"] if nic.has_key?("IP")

View File

@ -17,6 +17,13 @@
require 'one_helper'
class OneVirtualRouterHelper < OpenNebulaHelper::OneHelper
ALL_TEMPLATE = {
:name => "all",
:large => "--all",
:description => "Show all template data"
}
def self.rname
"VROUTER"
end
@ -164,6 +171,14 @@ class OneVirtualRouterHelper < OpenNebulaHelper::OneHelper
}
CLIHelper::ShowTable.new(nil, self) do
column :ID, "", :size=>3 do |d|
if d["DOUBLE_ENTRY"]
""
else
d["NIC_ID"]
end
end
column :NETWORK, "", :left, :size=>20 do |d|
if d["DOUBLE_ENTRY"]
""
@ -172,6 +187,19 @@ class OneVirtualRouterHelper < OpenNebulaHelper::OneHelper
end
end
column :MANAGEMENT, "", :left, :size=>10 do |d|
if d["DOUBLE_ENTRY"]
""
else
if !d["VROUTER_MANAGEMENT"].nil?
d["VROUTER_MANAGEMENT"]
else
"NO"
end
end
end
column :IP, "",:left, :donottruncate, :size=>15 do |d|
d["IP"]
end
@ -180,7 +208,7 @@ class OneVirtualRouterHelper < OpenNebulaHelper::OneHelper
while obj.has_elements?("/VROUTER/TEMPLATE/NIC")
obj.delete_element("/VROUTER/TEMPLATE/NIC")
end
end if !options[:all]
puts

View File

@ -55,8 +55,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
OneTemplateHelper::VM_NAME,
OneTemplateHelper::MULTIPLE,
OneTemplateHelper::USERDATA,
OneVMHelper::HOLD,
OneTemplateHelper::VROUTER,
OneVMHelper::HOLD
]
########################################################################
@ -209,17 +208,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do
if args[1]
extra_template = File.read(args[1])
elsif options[:userdata]
if t.has_elements?('TEMPLATE/EC2')
t.add_element(
'TEMPLATE/EC2',
'USERDATA' => options[:userdata])
extra_template = t.template_like_str(
'TEMPLATE', false, 'EC2')
end
else
res = OpenNebulaHelper.create_template(options)
res = OpenNebulaHelper.create_template(options, t)
if res.first != 0
STDERR.puts res.last
@ -229,14 +219,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do
extra_template = res.last
end
user_inputs = helper.get_user_inputs(t.to_hash) unless user_inputs
user_inputs = OneTemplateHelper.get_user_inputs(t.to_hash) unless user_inputs
extra_template << "\n" << user_inputs
if !options[:vrouter].nil?
extra_template << "\n" << "VROUTER_ID = \"#{options[:vrouter]}\""
end
res = t.instantiate(name, on_hold, extra_template)
if !OpenNebula.is_error?(res)

View File

@ -63,14 +63,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
:description => "Overrides the DEV_PREFIX of the image"
}
IP={
:name => "ip",
:short => "-i ip",
:large => "--ip ip",
:format => String,
:description => "IP address for the new NIC"
}
CACHE={
:name => "cache",
:large => "--cache cache_mode",
@ -666,7 +658,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
EOT
command :"nic-attach", nic_attach_desc, :vmid,
:options => [OneVMHelper::FILE, OneVMHelper::NETWORK, IP] do
:options => [OneVMHelper::FILE, OneVMHelper::NETWORK, OneVMHelper::IP] do
if options[:file].nil? and options[:network].nil?
STDERR.puts "Provide a template file or a network:"

View File

@ -29,6 +29,7 @@ $: << RUBY_LIB_LOCATION+"/cli"
require 'command_parser'
require 'one_helper/onevrouter_helper'
require 'one_helper/onetemplate_helper'
require 'one_helper/onevm_helper'
cmd=CommandParser::CmdParser.new(ARGV) do
@ -74,6 +75,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do
helper.filterflag_to_i(arg)
end
set :format, :templateid, OpenNebulaHelper.rname_to_id_desc("VMTEMPLATE") do |arg|
OpenNebulaHelper.rname_to_id(arg, "VMTEMPLATE")
end
########################################################################
# Commands
########################################################################
@ -95,24 +100,69 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
# TODO: implement or remove
=begin
clone_desc = <<-EOT.unindent
Creates a new Virtual Router from an existing one
instantiate_desc = <<-EOT.unindent
Creates a new VM instance from the given Template. This VM can be
managed with the 'onevm' command.
The NIC elements defined in the Virtual Router will be used. The
source Template can be modified adding or replacing attributes with
the optional file argument, or with the options.
EOT
command :clone, clone_desc, :vrouterid, :name do
helper.perform_action(args[0],options,"cloned") do |t|
res = t.clone(args[1])
instantiate_options = [
OneTemplateHelper::VM_NAME,
OneTemplateHelper::MULTIPLE,
OneVMHelper::HOLD
]
if !OpenNebula.is_error?(res)
puts "ID: #{res}"
else
puts res.message
command :instantiate, instantiate_desc, :vrouterid, :templateid, [:file, nil],
:options=>instantiate_options+OpenNebulaHelper::TEMPLATE_OPTIONS do
exit_code=0
if args[1] && OpenNebulaHelper.create_template_options_used?(options)
STDERR.puts "You cannot use both template file and template"<<
" creation options."
next -1
end
number = options[:multiple] || 1
user_inputs = nil
helper.perform_action(args[0], options, "instantiated") do |vr|
name = options[:name] || ""
t = OpenNebula::Template.new_with_id(args[1], helper.client)
on_hold = options[:hold] != nil
extra_template = ""
rc = t.info
if OpenNebula.is_error?(rc)
STDERR.puts rc.message
exit(-1)
end
if args[2]
extra_template = File.read(args[2])
else
res = OpenNebulaHelper.create_template(options, t)
if res.first != 0
STDERR.puts res.last
next -1
end
extra_template = res.last
end
user_inputs = OneTemplateHelper.get_user_inputs(t.to_hash) unless user_inputs
extra_template << "\n" << user_inputs
vr.instantiate(number, args[1], name, on_hold, extra_template)
end
end
=end
delete_desc = <<-EOT.unindent
Deletes the given Virtual Router
@ -184,6 +234,50 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
nic_attach_desc = <<-EOT.unindent
Attaches a NIC to a VirtualRouter, and each one of its VMs. When using
--file add only one NIC instance.
EOT
command :"nic-attach", nic_attach_desc, :vrouterid,
:options => [OneVMHelper::FILE, OneVMHelper::NETWORK, OneVMHelper::IP] do
if options[:file].nil? and options[:network].nil?
STDERR.puts "Provide a template file or a network:"
STDERR.puts "\t--file <file>"
STDERR.puts "\t--network <network>"
exit -1
end
if options[:file]
template = File.read(options[:file])
else
network_id = options[:network]
ip = options[:ip]
if ip
template = "NIC = [ NETWORK_ID = #{network_id}, IP = #{ip} ]"
else
template = "NIC = [ NETWORK_ID = #{network_id} ]"
end
end
helper.perform_action(args[0],options,"Attach NIC") do |vr|
vr.nic_attach(template)
end
end
nic_detach_desc = <<-EOT.unindent
Detaches a NIC from a VirtualRouter, and each one of its VMs
EOT
command :"nic-detach", nic_detach_desc, :vrouterid, :nicid do
nicid = args[1].to_i
helper.perform_action(args[0],options,"Detach NIC") do |vr|
vr.nic_detach(nicid)
end
end
list_desc = <<-EOT.unindent
Lists the Virtual Routers in the pool
EOT
@ -196,7 +290,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do
Shows information for the given Virtual Router
EOT
command :show, show_desc, :secgroupid, :options=>OpenNebulaHelper::XML do
command :show, show_desc, :vrouterid,
:options=>[OpenNebulaHelper::XML, OneVMHelper::ALL_TEMPLATE] do
helper.show_resource(args[0],options)
end

View File

@ -25,6 +25,7 @@
#include <string>
#include <sstream>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <math.h>
@ -306,3 +307,29 @@ std::string one_util::trim(const std::string& str)
return tstr;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
std::string one_util::gsub(const std::string& st, const std::string& sfind,
const std::string& srepl)
{
std::string result = st;
std::string::size_type pos = 0;
size_t srepl_len = srepl.length();
size_t sfind_len = sfind.length();
pos = result.find(sfind, pos);
while(pos != std::string::npos)
{
result.replace(pos, sfind_len , srepl);
pos += srepl_len;
pos = result.find(sfind, pos);
}
return result;
}

View File

@ -1443,6 +1443,7 @@ int DispatchManager::attach_nic(
int uid;
int oid;
int rc;
string tmp_error;
set<int> vm_sgs;
@ -1476,19 +1477,6 @@ int DispatchManager::attach_nic(
return -1;
}
if (vm->is_vrouter())
{
oss << "Could not add a new NIC to VM " << vid
<< ", it is associated to the Virtual Router "
<< vm->get_vrouter_id() << ".";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
nic = vm->get_attach_nic_info(tmpl, max_nic_id, error_str);
if ( nic == 0 )
@ -1527,8 +1515,6 @@ int DispatchManager::attach_nic(
if ( vm == 0 )
{
delete nic;
if ( rc == 0 )
{
VirtualMachine::release_network_leases(nic, vid);
@ -1540,6 +1526,8 @@ int DispatchManager::attach_nic(
}
}
delete nic;
oss << "Could not attach a new NIC to VM " << vid
<< ", VM does not exist after setting its state to HOTPLUG." ;
error_str = oss.str();
@ -1612,7 +1600,7 @@ int DispatchManager::attach_nic(
{
vm->log("DiM", Log::INFO, "VM NIC Successfully attached.");
vm->clear_attach_nic();
vm->attach_nic_success();
}
vmpool->update(vm);
@ -1631,6 +1619,7 @@ int DispatchManager::detach_nic(
string& error_str)
{
ostringstream oss;
string tmp_error;
VirtualMachine * vm = vmpool->get(vid, true);
@ -1657,20 +1646,7 @@ int DispatchManager::detach_nic(
return -1;
}
if (vm->is_vrouter())
{
oss << "Could not detach NIC from VM " << vid
<< ", it is associated to the Virtual Router "
<< vm->get_vrouter_id() << ".";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
if ( vm->set_attach_nic(nic_id) == -1 )
if ( vm->set_detach_nic(nic_id) == -1 )
{
oss << "Could not detach NIC with NIC_ID " << nic_id
<< ", it does not exist.";
@ -1724,9 +1700,11 @@ int DispatchManager::detach_nic(
}
else
{
vmpool->update(vm);
vm->unlock();
vmpool->delete_attach_nic(vid);
vmpool->detach_nic_success(vid);
vm->log("DiM", Log::INFO, "VM NIC Successfully detached.");
}

View File

@ -333,7 +333,24 @@ int ImagePool::acquire_disk(int vm_id,
*snap = 0;
if (!(source = disk->vector_value("IMAGE")).empty())
if (!(source = disk->vector_value("IMAGE_ID")).empty())
{
iid = get_disk_id(source);
if ( iid == -1)
{
error_str = "Wrong ID set in IMAGE_ID";
return -1;
}
img = imagem->acquire_image(vm_id, iid, error_str);
if ( img == 0 )
{
return -1;
}
}
else if (!(source = disk->vector_value("IMAGE")).empty())
{
int uiid = get_disk_uid(disk,uid);
@ -357,23 +374,6 @@ int ImagePool::acquire_disk(int vm_id,
iid = img->get_oid();
}
else if (!(source = disk->vector_value("IMAGE_ID")).empty())
{
iid = get_disk_id(source);
if ( iid == -1)
{
error_str = "Wrong ID set in IMAGE_ID";
return -1;
}
img = imagem->acquire_image(vm_id, iid, error_str);
if ( img == 0 )
{
return -1;
}
}
else //Not using the image repository (volatile DISK)
{
string type = disk->vector_value("TYPE");
@ -505,16 +505,7 @@ void ImagePool::disk_attribute(
Nebula& nd = Nebula::instance();
DatastorePool * ds_pool = nd.get_dspool();
if (!(source = disk->vector_value("IMAGE")).empty())
{
int uiid = get_disk_uid(disk,uid);
if ( uiid != -1)
{
img = get(source, uiid, true);
}
}
else if (!(source = disk->vector_value("IMAGE_ID")).empty())
if (!(source = disk->vector_value("IMAGE_ID")).empty())
{
int iid = get_disk_id(source);
@ -523,6 +514,15 @@ void ImagePool::disk_attribute(
img = get(iid, true);
}
}
else if (!(source = disk->vector_value("IMAGE")).empty())
{
int uiid = get_disk_uid(disk,uid);
if ( uiid != -1)
{
img = get(source, uiid, true);
}
}
if ( img != 0 )
{

View File

@ -956,7 +956,8 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
break;
case VirtualMachine::HOTPLUG_NIC:
vm->clear_attach_nic();
vm->attach_nic_success();
vm->detach_nic_success();
vmpool->update(vm);
vm->set_running_etime(the_time);

View File

@ -1542,7 +1542,7 @@ void LifeCycleManager::attach_nic_success_action(int vid)
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC )
{
vm->clear_attach_nic();
vm->attach_nic_success();
vm->set_state(VirtualMachine::RUNNING);
@ -1574,7 +1574,7 @@ void LifeCycleManager::attach_nic_failure_action(int vid)
{
vm->unlock();
vmpool->delete_attach_nic(vid);
vmpool->attach_nic_failure(vid);
vm = vmpool->get(vid,true);
@ -1601,7 +1601,39 @@ void LifeCycleManager::attach_nic_failure_action(int vid)
void LifeCycleManager::detach_nic_success_action(int vid)
{
attach_nic_failure_action(vid);
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC )
{
vm->unlock();
vmpool->detach_nic_success(vid);
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->unlock();
}
else
{
vm->log("LCM",Log::ERROR,"detach_nic_success_action, VM in a wrong state");
vm->unlock();
}
}
/* -------------------------------------------------------------------------- */
@ -1609,7 +1641,29 @@ void LifeCycleManager::detach_nic_success_action(int vid)
void LifeCycleManager::detach_nic_failure_action(int vid)
{
attach_nic_success_action(vid);
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC )
{
vm->detach_nic_failure();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"detach_nic_failure_action, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */

View File

@ -475,6 +475,7 @@ void Nebula::start(bool bootstrap_only)
vector<const Attribute *> vm_hooks;
vector<const Attribute *> host_hooks;
vector<const Attribute *> vrouter_hooks;
vector<const Attribute *> vnet_hooks;
vector<const Attribute *> user_hooks;
vector<const Attribute *> group_hooks;
@ -499,12 +500,13 @@ void Nebula::start(bool bootstrap_only)
marketpool = new MarketPlacePool(db);
apppool = new MarketPlaceAppPool(db);
nebula_configuration->get("VM_HOOK", vm_hooks);
nebula_configuration->get("HOST_HOOK", host_hooks);
nebula_configuration->get("VNET_HOOK", vnet_hooks);
nebula_configuration->get("USER_HOOK", user_hooks);
nebula_configuration->get("GROUP_HOOK", group_hooks);
nebula_configuration->get("IMAGE_HOOK", image_hooks);
nebula_configuration->get("VM_HOOK", vm_hooks);
nebula_configuration->get("HOST_HOOK", host_hooks);
nebula_configuration->get("VROUTER_HOOK", vrouter_hooks);
nebula_configuration->get("VNET_HOOK", vnet_hooks);
nebula_configuration->get("USER_HOOK", user_hooks);
nebula_configuration->get("GROUP_HOOK", group_hooks);
nebula_configuration->get("IMAGE_HOOK", image_hooks);
nebula_configuration->get("VM_RESTRICTED_ATTR", vm_restricted_attrs);
nebula_configuration->get("IMAGE_RESTRICTED_ATTR", img_restricted_attrs);
@ -570,6 +572,10 @@ void Nebula::start(bool bootstrap_only)
remotes_location,
host_expiration);
vrouterpool = new VirtualRouterPool(db,
vrouter_hooks,
remotes_location);
nebula_configuration->get("MAC_PREFIX", mac_prefix);
nebula_configuration->get("NETWORK_SIZE", size);

View File

@ -25,14 +25,15 @@ module OpenNebula
VIRTUAL_ROUTER_METHODS = {
:allocate => "vrouter.allocate",
:instantiate => "vrouter.instantiate",
:info => "vrouter.info",
:update => "vrouter.update",
:delete => "vrouter.delete",
:chown => "vrouter.chown",
:chmod => "vrouter.chmod",
# TODO: remove or implement
# :clone => "vrouter.clone",
:rename => "vrouter.rename"
:rename => "vrouter.rename",
:attachnic => "vrouter.attachnic",
:detachnic => "vrouter.detachnic",
}
# Creates a VirtualRouter description with just its identifier
@ -80,6 +81,26 @@ module OpenNebula
super(VIRTUAL_ROUTER_METHODS[:allocate], description)
end
# Creates VM instances from a VM Template. New VMs will be associated
# to this Virtual Router, and its Virtual Networks
#
# @para n_vms [Integer] Number of VMs to instantiate
# @para template_id [Integer] VM Template id to instantiate
# @param name [String] Name for the VM instances. If it is an empty
# string OpenNebula will set a default name
# @param hold [true,false] false to create the VM in pending state,
# true to create it on hold
# @param template [String] User provided Template to merge with the
# one being instantiated
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def instantiate(n_vms, template_id, name="", hold=false, template="")
return call(VIRTUAL_ROUTER_METHODS[:instantiate], @pe_id,
n_vms.to_i, template_id.to_i, name, hold, template)
end
# Deletes the VirtualRouter
def delete()
super(VIRTUAL_ROUTER_METHODS[:delete])
@ -125,21 +146,7 @@ module OpenNebula
super(VIRTUAL_ROUTER_METHODS[:chmod], owner_u, owner_m, owner_a, group_u,
group_m, group_a, other_u, other_m, other_a)
end
=begin
# Clones this VirtualRouter into a new one
#
# @param [String] name for the new VirtualRouter.
#
# @return [Integer, OpenNebula::Error] The new VirtualRouter ID in case
# of success, Error otherwise
def clone(name)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VIRTUAL_ROUTER_METHODS[:clone], @pe_id, name)
return rc
end
=end
# Renames this VirtualRouter
#
# @param name [String] New name for the VirtualRouter.
@ -150,6 +157,24 @@ module OpenNebula
return call(VIRTUAL_ROUTER_METHODS[:rename], @pe_id, name)
end
# Attaches a NIC to this VirtualRouter, and each one of its VMs
#
# @param nic_template [String] Template containing a NIC element
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def nic_attach(nic_template)
return call(VIRTUAL_ROUTER_METHODS[:attachnic], @pe_id, nic_template)
end
# Detaches a NIC from this VirtualRouter, and each one of its VMs
#
# @param nic_id [Integer] Id of the NIC to be detached
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def nic_detach(nic_id)
return call(VIRTUAL_ROUTER_METHODS[:detachnic], @pe_id, nic_id)
end
#######################################################################
# Helpers to get VirtualRouter information
#######################################################################

View File

@ -31,7 +31,7 @@ require 'nokogiri'
module OneDBFsck
VERSION = "4.11.80"
LOCAL_VERSION = "4.13.85"
LOCAL_VERSION = "4.90.0"
def check_db_version()
db_version = read_db_version()
@ -59,9 +59,10 @@ EOT
IMAGE_STATES=%w{INIT READY USED DISABLED LOCKED ERROR CLONE DELETE USED_PERS}
VM_BIN = 0x0000001000000000
NET_BIN = 0x0000004000000000
HOLD = 0xFFFFFFFF
VM_BIN = 0x0000001000000000
NET_BIN = 0x0000004000000000
VROUTER_BIN = 0x0004000000000000
HOLD = 0xFFFFFFFF
def fsck
@ -825,7 +826,7 @@ EOT
if ar_id_e.nil?
if !counters[:vnet][net_id][:no_ar_leases][mac_s_to_i(mac)].nil?
log_error("VNet has more than one VM with the same MAC address (#{mac}). "<<
log_error("VNet #{net_id} has more than one lease with the same MAC address (#{mac}). "<<
"FSCK can't handle this, and consistency is not guaranteed", false)
end
@ -836,7 +837,8 @@ EOT
:ip6_ula => nic.at_xpath("IP6_ULA").nil? ? nil : nic.at_xpath("IP6_ULA").text,
:mac => mac,
:vm => row[:oid],
:vnet => nil
:vnet => nil,
:vrouter => nil
}
else
ar_id = ar_id_e.text.to_i
@ -852,7 +854,8 @@ EOT
:ip6_ula => nic.at_xpath("IP6_ULA").nil? ? nil : nic.at_xpath("IP6_ULA").text,
:mac => mac,
:vm => row[:oid],
:vnet => nil
:vnet => nil,
:vrouter => nil
}
end
end
@ -969,6 +972,87 @@ EOT
log_time()
########################################################################
# Virtual Routers
#
########################################################################
vrouters_fix = {}
# Aggregate information of the RUNNING vms
@db.fetch("SELECT oid,body FROM vrouter_pool") do |row|
vrouter_doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
# VNets used by this Virtual Router
vrouter_doc.root.xpath("TEMPLATE/NIC").each do |nic|
net_id = nil
nic.xpath("NETWORK_ID").each do |nid|
net_id = nid.text.to_i
end
floating = false
nic.xpath("FLOATING_IP").each do |floating_e|
floating = (floating_e.text.upcase == "YES")
end
if !net_id.nil? && floating
if counters[:vnet][net_id].nil?
log_error("VRouter #{row[:oid]} is using VNet #{net_id}, "<<
"but it does not exist", false)
else
mac = nic.at_xpath("MAC").nil? ? nil : nic.at_xpath("MAC").text
ar_id_e = nic.at_xpath('AR_ID')
if ar_id_e.nil?
if !counters[:vnet][net_id][:no_ar_leases][mac_s_to_i(mac)].nil?
log_error("VNet #{net_id} has more than one lease with the same MAC address (#{mac}). "<<
"FSCK can't handle this, and consistency is not guaranteed", false)
end
counters[:vnet][net_id][:no_ar_leases][mac_s_to_i(mac)] = {
:ip => nic.at_xpath("IP").nil? ? nil : nic.at_xpath("IP").text,
:ip6_global => nic.at_xpath("IP6_GLOBAL").nil? ? nil : nic.at_xpath("IP6_GLOBAL").text,
:ip6_link => nic.at_xpath("IP6_LINK").nil? ? nil : nic.at_xpath("IP6_LINK").text,
:ip6_ula => nic.at_xpath("IP6_ULA").nil? ? nil : nic.at_xpath("IP6_ULA").text,
:mac => mac,
:vm => nil,
:vnet => nil,
:vrouter => row[:oid],
}
else
ar_id = ar_id_e.text.to_i
if counters[:vnet][net_id][:ar_leases][ar_id].nil?
log_error("VRouter #{row[:oid]} is using VNet #{net_id}, AR #{ar_id}, "<<
"but the AR does not exist", false)
else
counters[:vnet][net_id][:ar_leases][ar_id][mac_s_to_i(mac)] = {
:ip => nic.at_xpath("IP").nil? ? nil : nic.at_xpath("IP").text,
:ip6_global => nic.at_xpath("IP6_GLOBAL").nil? ? nil : nic.at_xpath("IP6_GLOBAL").text,
:ip6_link => nic.at_xpath("IP6_LINK").nil? ? nil : nic.at_xpath("IP6_LINK").text,
:ip6_ula => nic.at_xpath("IP6_ULA").nil? ? nil : nic.at_xpath("IP6_ULA").text,
:mac => mac,
:vm => nil,
:vnet => nil,
:vrouter => row[:oid],
}
end
end
end
end
end
end
@db.transaction do
vrouters_fix.each do |id, body|
@db[:vrouter_pool].where(:oid => id).update(:body => body)
end
end
log_time()
########################################################################
# Hosts
#
@ -1278,7 +1362,8 @@ EOT
:ip6_ula => nil,
:mac => nil,
:vm => nil,
:vnet => row[:oid]
:vnet => row[:oid],
:vrouter => nil
}
#MAC
@ -1389,7 +1474,8 @@ EOT
:ip6_ula => nil,
:mac => nil,
:vm => nil,
:vnet => nil
:vnet => nil,
:vrouter => nil
}
# MAC
@ -1432,9 +1518,12 @@ EOT
if (binary_magic & VM_BIN != 0)
lease[:vm] = lease_oid
lease_obj = "VM"
else # binary_magic & NET_BIN != 0
elsif (binary_magic & NET_BIN != 0)
lease[:vnet] = lease_oid
lease_obj = "VNet"
else #(binary_magic & VROUTER_BIN != 0)
lease[:vrouter] = lease_oid
lease_obj = "VRouter"
end
counter_lease = counter_ar[mac]
@ -1457,8 +1546,9 @@ EOT
if counter_lease != lease
# Things that can be fixed
if (counter_lease[:vm] != lease[:vm] ||
counter_lease[:vnet] != lease[:vnet])
if (counter_lease[:vm] != lease[:vm] ||
counter_lease[:vnet] != lease[:vnet] ||
counter_lease[:vrouter] != lease[:vrouter])
new_lease_obj = ""
new_lease_oid = 0
@ -1470,12 +1560,18 @@ EOT
new_binary_magic = (VM_BIN |
(new_lease_oid & 0xFFFFFFFF))
else
elsif !counter_lease[:vnet].nil?
new_lease_obj = "VNet"
new_lease_oid = counter_lease[:vnet].to_i
new_binary_magic = (NET_BIN |
(new_lease_oid & 0xFFFFFFFF))
else #if !counter_lease[:vrouter].nil?
new_lease_obj = "VRouter"
new_lease_oid = counter_lease[:vrouter].to_i
new_binary_magic = (VROUTER_BIN |
(new_lease_oid & 0xFFFFFFFF))
end
if (lease[:vm] == HOLD)
@ -1527,12 +1623,18 @@ EOT
new_binary_magic = (VM_BIN |
(new_lease_oid & 0xFFFFFFFF))
else
elsif !counter_lease[:vnet].nil?
new_lease_obj = "VNet"
new_lease_oid = counter_lease[:vnet].to_i
new_binary_magic = (NET_BIN |
(new_lease_oid & 0xFFFFFFFF))
else #if !counter_lease[:vrouter].nil?
new_lease_obj = "VRouter"
new_lease_oid = counter_lease[:vrouter].to_i
new_binary_magic = (VROUTER_BIN |
(new_lease_oid & 0xFFFFFFFF))
end
log_error("VNet #{oid} AR #{ar_id} does not have a lease "<<
@ -1799,6 +1901,31 @@ EOT
end
@db.fetch("SELECT body FROM vrouter_pool WHERE #{where_filter}") do |vrouter_row|
vrouter_doc = Nokogiri::XML(vrouter_row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
# VNet quotas
vrouter_doc.root.xpath("TEMPLATE/NIC").each { |nic|
net_id = nil
nic.xpath("NETWORK_ID").each do |nid|
net_id = nid.text
end
floating = false
nic.xpath("FLOATING_IP").each do |floating_e|
floating = (floating_e.text.upcase == "YES")
end
if !net_id.nil? && floating
vnet_usage[net_id] = 0 if vnet_usage[net_id].nil?
vnet_usage[net_id] += 1
end
}
end
# VM quotas
vm_elem = nil

View File

@ -0,0 +1,89 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'opennebula'
include OpenNebula
module Migrator
def db_version
"4.90.0"
end
def one_version
"OpenNebula 4.90.0"
end
def up
init_log_time()
# 4215
@db.run "CREATE TABLE vrouter_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER);"
@db.transaction do
@db.fetch("SELECT oid,body FROM group_pool") do |row|
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
doc.root.xpath("ADMINS/ID").each do |uid|
user = Acl::USERS["UID"] | uid.text.to_i
resource = 354936097341440 | Acl::USERS["GID"] | row[:oid]
@db[:acl].where({
:user=>user, # #<uid>
:resource=>resource, # VM+NET+IMAGE+TEMPLATE+DOCUMENT+SECGROUP/@<gid>
:rights=>3, # USE+MANAGE
:zone=>17179869184 # *
}).update(
# VM+NET+IMAGE+TEMPLATE+DOCUMENT+SECGROUP+VROUTER/@101
:resource => (1480836004184064 | Acl::USERS["GID"] | row[:oid]))
end
end
end
log_time()
@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.transaction do
@db.fetch("SELECT * FROM old_network_pool") do |row|
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
doc.root.add_child(doc.create_element("VROUTERS"))
@db[:network_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
: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 => row[:pid])
end
end
@db.run "DROP TABLE old_network_pool;"
log_time()
return true
end
end

View File

@ -19,56 +19,59 @@
#include "PoolObjectAuth.h"
string Request::format_str;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* RequestLog Methods */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Request::execute(
xmlrpc_c::paramList const& _paramList,
xmlrpc_c::value * const _retval)
string Request::object_name(PoolObjectSQL::ObjectType ob)
{
RequestAttributes att;
att.retval = _retval;
att.session = xmlrpc_c::value_string (_paramList.getString(0));
att.req_id = (reinterpret_cast<uintptr_t>(this) * rand()) % 10000;
Nebula& nd = Nebula::instance();
UserPool* upool = nd.get_upool();
bool authenticated = upool->authenticate(att.session,
att.password,
att.uid,
att.gid,
att.uname,
att.gname,
att.group_ids,
att.umask);
log_method_invoked(att, _paramList);
if ( authenticated == false )
switch (ob)
{
failure_response(AUTHENTICATION, authenticate_error(), att);
}
else
{
request_execute(_paramList, att);
}
log_result(att);
case PoolObjectSQL::VM:
return "virtual machine";
case PoolObjectSQL::HOST:
return "host";
case PoolObjectSQL::NET:
return "virtual network";
case PoolObjectSQL::IMAGE:
return "image";
case PoolObjectSQL::USER:
return "user";
case PoolObjectSQL::TEMPLATE:
return "virtual machine template";
case PoolObjectSQL::GROUP:
return "group";
case PoolObjectSQL::ACL:
return "ACL";
case PoolObjectSQL::DATASTORE:
return "datastore";
case PoolObjectSQL::CLUSTER:
return "cluster";
case PoolObjectSQL::DOCUMENT:
return "document";
case PoolObjectSQL::ZONE:
return "zone";
case PoolObjectSQL::SECGROUP:
return "security group";
case PoolObjectSQL::VDC:
return "VDC";
case PoolObjectSQL::VROUTER:
return "virtual router";
default:
return "-";
}
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Request::log_method_invoked(
const RequestAttributes& att,
const xmlrpc_c::paramList& paramList)
void Request::log_method_invoked(const RequestAttributes& att,
const xmlrpc_c::paramList& paramList, const string& format_str,
const std::string& method_name, const std::set<int>& hidden_params)
{
ostringstream oss;
std::ostringstream oss;
for (unsigned int j = 0 ;j < format_str.length() - 1; j++ )
{
@ -141,16 +144,15 @@ void Request::log_method_invoked(
}
}
NebulaLog::log("ReM",Log::DEBUG, oss);
NebulaLog::log("ReM", Log::DEBUG, oss);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Request::log_result(
const RequestAttributes& att)
void Request::log_result(const RequestAttributes& att, const string& method_name)
{
ostringstream oss;
std::ostringstream oss;
oss << "Req:" << att.req_id << " UID:";
@ -177,23 +179,21 @@ void Request::log_result(
log_xmlrpc_value(vvalue[i], oss);
}
NebulaLog::log("ReM",Log::DEBUG, oss);
NebulaLog::log("ReM", Log::DEBUG, oss);
}
else
{
oss << "FAILURE "
<< static_cast<string>(xmlrpc_c::value_string(vvalue[1]));
NebulaLog::log("ReM",Log::ERROR, oss);
NebulaLog::log("ReM", Log::ERROR, oss);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Request::log_xmlrpc_value(
const xmlrpc_c::value& v,
ostringstream& oss)
void Request::log_xmlrpc_value(const xmlrpc_c::value& v, std::ostringstream& oss)
{
size_t st_limit = 20;
size_t st_newline;
@ -245,6 +245,53 @@ void Request::log_xmlrpc_value(
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Request Methods */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string Request::format_str;
/* -------------------------------------------------------------------------- */
void Request::execute(
xmlrpc_c::paramList const& _paramList,
xmlrpc_c::value * const _retval)
{
RequestAttributes att;
att.retval = _retval;
att.session = xmlrpc_c::value_string (_paramList.getString(0));
att.req_id = (reinterpret_cast<uintptr_t>(this) * rand()) % 10000;
Nebula& nd = Nebula::instance();
UserPool* upool = nd.get_upool();
bool authenticated = upool->authenticate(att.session,
att.password,
att.uid,
att.gid,
att.uname,
att.gname,
att.group_ids,
att.umask);
log_method_invoked(att, _paramList, format_str, method_name, hidden_params);
if ( authenticated == false )
{
failure_response(AUTHENTICATION, att);
}
else
{
request_execute(_paramList, att);
}
log_result(att, method_name);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -261,9 +308,8 @@ bool Request::basic_authorization(int oid,
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return false;
}
@ -293,9 +339,8 @@ bool Request::basic_authorization(int oid,
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return false;
}
@ -449,15 +494,11 @@ bool Request::quota_authorization(Template * tmpl,
Quotas::QuotaType qtype,
RequestAttributes& att)
{
string error_str;
bool auth = quota_authorization(tmpl, qtype, att, error_str);
bool auth = quota_authorization(tmpl, qtype, att, att.resp_msg);
if ( auth == false )
{
failure_response(AUTHORIZATION,
request_error(error_str, ""),
att);
failure_response(AUTHORIZATION, att);
}
return auth;
@ -538,6 +579,78 @@ void Request::failure_response(ErrorCode ec, const string& str_val,
*(att.retval) = arrayresult;
}
/* -------------------------------------------------------------------------- */
void Request::failure_response(ErrorCode ec, RequestAttributes& att)
{
std::ostringstream oss;
std::string obname;
if ( att.resp_obj == PoolObjectSQL::NONE )
{
obname = object_name(auth_object);
}
else
{
obname = object_name(att.resp_obj);
}
oss << "[" << method_name << "]";
switch(ec)
{
case SUCCESS:
return;
case AUTHORIZATION:
oss << " User [" << att.uid << "] ";
if (att.resp_msg.empty())
{
oss << "not authorized to perform action on " << obname << ".";
}
else
{
oss << ": " << att.resp_msg << ".";
}
break;
case AUTHENTICATION:
oss << " User couldn't be authenticated, aborting call.";
break;
case ACTION:
case XML_RPC_API:
case INTERNAL:
oss << att.resp_msg;
break;
case NO_EXISTS:
oss << " Error getting " << obname;
if ( att.resp_id != -1 )
{
oss << " [" << att.resp_id << "].";
}
else
{
oss << " Pool.";
}
break;
case ALLOCATE:
oss << "Error allocating a new " << obname << ".";
if (!att.resp_msg.empty())
{
oss << " " << att.resp_msg;
}
break;
}
failure_response(ec, oss.str(), att);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -708,43 +821,6 @@ string Request::request_error (const string &err_desc, const string &err_detail)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string Request::allocate_error(PoolObjectSQL::ObjectType obj,
const string& error)
{
ostringstream oss;
oss << "[" << method_name << "]" << " Error allocating a new "
<< object_name(obj) << ".";
if (!error.empty())
{
oss << " " << error;
}
return oss.str();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string Request::allocate_error (const string& error)
{
ostringstream oss;
oss << "[" << method_name << "]" << " Error allocating a new "
<< object_name(auth_object) << ".";
if (!error.empty())
{
oss << " " << error;
}
return oss.str();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Request::get_info(
PoolSQL * pool,
int id,
@ -760,7 +836,9 @@ int Request::get_info(
{
if (throw_error)
{
failure_response(NO_EXISTS, get_error(object_name(type), id), att);
att.resp_obj = type;
att.resp_id = id;
failure_response(NO_EXISTS, att);
}
return -1;

View File

@ -41,6 +41,7 @@
#include "RequestManagerVdc.h"
#include "RequestManagerDatastore.h"
#include "RequestManagerMarketPlaceApp.h"
#include "RequestManagerVirtualRouter.h"
#include "RequestManagerSystem.h"
#include "RequestManagerProxy.h"
@ -469,6 +470,11 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr secg_rename(new SecurityGroupRename());
xmlrpc_c::methodPtr vrouter_rename(new VirtualRouterRename());
// Virtual Router Methods
xmlrpc_c::methodPtr vrouter_instantiate(new VirtualRouterInstantiate());
xmlrpc_c::methodPtr vrouter_attachnic(new VirtualRouterAttachNic());
xmlrpc_c::methodPtr vrouter_detachnic(new VirtualRouterDetachNic());
/* VM related methods */
RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy);
RequestManagerRegistry.addMethod("one.vm.action", vm_action);
@ -901,6 +907,9 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vrouter.chown", vrouter_chown);
RequestManagerRegistry.addMethod("one.vrouter.chmod", vrouter_chmod);
RequestManagerRegistry.addMethod("one.vrouter.rename", vrouter_rename);
RequestManagerRegistry.addMethod("one.vrouter.instantiate",vrouter_instantiate);
RequestManagerRegistry.addMethod("one.vrouter.attachnic", vrouter_attachnic);
RequestManagerRegistry.addMethod("one.vrouter.detachnic", vrouter_detachnic);
RequestManagerRegistry.addMethod("one.vrouterpool.info",vrouter_pool_info);

View File

@ -18,8 +18,8 @@
using namespace std;
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AclAddRule::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
@ -61,18 +61,16 @@ void AclAddRule::request_execute(xmlrpc_c::paramList const& paramList,
zone = AclRule::INDIVIDUAL_ID | Nebula::instance().get_zone_id();
}
string error_msg;
if ( basic_authorization(-1, att) == false )
{
return;
}
int rc = aclm->add_rule(user, resource, rights, zone, error_msg);
int rc = aclm->add_rule(user, resource, rights, zone, att.resp_msg);
if ( rc < 0 )
{
failure_response(INTERNAL, request_error(error_msg, ""), att);
failure_response(INTERNAL, att);
return;
}
@ -81,8 +79,8 @@ void AclAddRule::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AclDelRule::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
@ -95,11 +93,11 @@ void AclDelRule::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
int rc = aclm->del_rule(oid, error_msg);
int rc = aclm->del_rule(oid, att.resp_msg);
if ( rc < 0 )
{
failure_response(INTERNAL, request_error(error_msg, ""), att);
failure_response(INTERNAL, att);
return;
}
@ -108,8 +106,8 @@ void AclDelRule::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AclInfo::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
@ -126,7 +124,8 @@ void AclInfo::request_execute(xmlrpc_c::paramList const& paramList,
if ( rc != 0 )
{
failure_response(INTERNAL, request_error("Internal Error",""), att);
att.resp_msg = "Internal Database error";
failure_response(INTERNAL, att);
return;
}
@ -135,4 +134,3 @@ void AclInfo::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
/* ------------------------------------------------------------------------- */

View File

@ -52,9 +52,8 @@ bool RequestManagerAllocate::allocate_authorization(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return false;
}
@ -87,13 +86,8 @@ bool VirtualMachineAllocate::allocate_authorization(
{
if (ttmpl->check(aname))
{
ostringstream oss;
oss << "VM Template includes a restricted attribute " << aname;
failure_response(AUTHORIZATION,
authorization_error(oss.str(), att),
att);
att.resp_msg = "VM Template includes a restricted attribute "+aname;
failure_response(AUTHORIZATION, att);
return false;
}
@ -107,9 +101,8 @@ bool VirtualMachineAllocate::allocate_authorization(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return false;
}
@ -136,7 +129,6 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params,
{
Template * tmpl = 0;
string error_str;
int rc, id;
Cluster * cluster = 0;
@ -150,11 +142,11 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params,
tmpl = get_object_template();
rc = tmpl->parse_str_or_xml(str_tmpl, error_str);
rc = tmpl->parse_str_or_xml(str_tmpl, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL, allocate_error(error_str), att);
failure_response(INTERNAL, att);
delete tmpl;
return;
@ -185,11 +177,11 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params,
return;
}
rc = pool_allocate(params, tmpl, id, error_str,att,cluster_id,cluster_name);
rc = pool_allocate(params, tmpl, id, att, cluster_id, cluster_name);
if ( rc < 0 )
{
failure_response(INTERNAL, allocate_error(error_str), att);
failure_response(INTERNAL, att);
return;
}
@ -201,14 +193,13 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params,
if ( cluster == 0 )
{
failure_response(
NO_EXISTS,
get_error(object_name(PoolObjectSQL::CLUSTER), cluster_id),
att);
att.resp_obj = PoolObjectSQL::CLUSTER;
att.resp_id = cluster_id;
failure_response(NO_EXISTS, att);
return;
}
rc = add_to_cluster(cluster, id, ds_type, error_str);
rc = add_to_cluster(cluster, id, ds_type, att.resp_msg);
if ( rc < 0 )
{
@ -225,7 +216,7 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params,
obj->unlock();
}
failure_response(INTERNAL, allocate_error(error_str), att);
failure_response(INTERNAL, att);
return;
}
@ -244,7 +235,6 @@ int VirtualMachineAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
bool on_hold = false;
@ -260,7 +250,7 @@ int VirtualMachineAllocate::pool_allocate(
Template tmpl_back(*tmpl);
int rc = vmpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
ttmpl, &id, error_str, on_hold);
ttmpl, &id, att.resp_msg, on_hold);
if ( rc < 0 )
{
@ -278,7 +268,6 @@ int VirtualNetworkAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att,
int cluster_id,
const string& cluster_name)
@ -287,7 +276,7 @@ int VirtualNetworkAllocate::pool_allocate(
VirtualNetworkTemplate * vtmpl=static_cast<VirtualNetworkTemplate *>(tmpl);
return vpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,-1,
vtmpl, &id, cluster_id, cluster_name, error_str);
vtmpl, &id, cluster_id, cluster_name, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -296,7 +285,6 @@ int VirtualNetworkAllocate::pool_allocate(
void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
RequestAttributes& att)
{
string error_str;
string size_str;
long long size_mb;
@ -344,11 +332,11 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
tmpl = new ImageTemplate;
rc = tmpl->parse_str_or_xml(str_tmpl, error_str);
rc = tmpl->parse_str_or_xml(str_tmpl, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL, allocate_error(error_str), att);
failure_response(INTERNAL, att);
delete tmpl;
return;
@ -358,9 +346,9 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
if ((ds = dspool->get(ds_id,true)) == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
att);
att.resp_id = ds_id;
att.resp_obj = PoolObjectSQL::DATASTORE;
failure_response(NO_EXISTS, att);
delete tmpl;
return;
@ -370,15 +358,12 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
if ( ds_type == Datastore::SYSTEM_DS )
{
ostringstream oss;
ds->unlock();
oss << "New images cannot be allocated in a system datastore.";
failure_response(INTERNAL, allocate_error(oss.str()), att);
att.resp_msg = "New images cannot be allocated in a system datastore.";
failure_response(ALLOCATE, att);
delete tmpl;
return;
}
@ -398,14 +383,13 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
{
// This image comes from a MarketPlaceApp. Get the Market info and
// the size.
app = apppool->get(app_id, true);
if ( app == 0 )
{
failure_response(INTERNAL,
"Cannot find appliance referenced by FROM_APP.",
att);
att.resp_msg = "Cannot determine image SIZE: " + size_str;
failure_response(INTERNAL, att);
delete tmpl;
return;
}
@ -421,8 +405,9 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
if ( market == 0 )
{
failure_response(INTERNAL, "Could not get the appliance's market.",
att);
att.resp_msg = "Could not get the appliance's market.";
failure_response(INTERNAL, att);
delete tmpl;
return;
}
@ -437,10 +422,9 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
if ( rc == -1 )
{
failure_response(INTERNAL,
request_error("Cannot determine Image SIZE",
size_str),
att);
att.resp_msg = "Cannot parse image SIZE: " + size_str;
failure_response(INTERNAL, att);
delete tmpl;
return;
}
@ -461,7 +445,8 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
if (ds_check && (size_mb > avail))
{
failure_response(ACTION, "Not enough space in datastore", att);
att.resp_msg = "Not enough space in datastore";
failure_response(ACTION, att);
delete tmpl;
return;
@ -487,13 +472,8 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
{
if (tmpl->check(aname))
{
ostringstream oss;
oss << "Template includes a restricted attribute " << aname;
failure_response(AUTHORIZATION,
authorization_error(oss.str(), att),
att);
att.resp_msg = "Template includes a restricted attribute "+aname;
failure_response(AUTHORIZATION, att);
delete tmpl;
return;
@ -509,9 +489,8 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
delete tmpl;
return;
@ -540,12 +519,12 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params,
extra_data,
-1,
&id,
error_str);
att.resp_msg);
if ( rc < 0 )
{
quota_rollback(&img_usage, Quotas::DATASTORE, att);
failure_response(INTERNAL, allocate_error(error_str), att);
failure_response(ALLOCATE, att);
return;
}
@ -570,7 +549,6 @@ int TemplateAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
VMTemplatePool * tpool = static_cast<VMTemplatePool *>(pool);
@ -578,7 +556,7 @@ int TemplateAllocate::pool_allocate(
VirtualMachineTemplate * ttmpl=static_cast<VirtualMachineTemplate *>(tmpl);
return tpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
ttmpl, &id, error_str);
ttmpl, &id, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -603,14 +581,9 @@ bool TemplateAllocate::allocate_authorization(
// ------------ Check template for restricted attributes -------------------
if (ttmpl->check(aname))
{
ostringstream oss;
oss << "VM Template includes a restricted attribute " << aname;
failure_response(AUTHORIZATION,
authorization_error(oss.str(), att),
att);
att.resp_msg = "VM Template includes a restricted attribute " + aname;
failure_response(AUTHORIZATION, att);
return false;
}
@ -624,7 +597,6 @@ int HostAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att,
int cluster_id,
const string& cluster_name)
@ -637,8 +609,7 @@ int HostAllocate::pool_allocate(
HostPool * hpool = static_cast<HostPool *>(pool);
return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad,
cluster_id, cluster_name, error_str);
cluster_id, cluster_name, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -648,7 +619,6 @@ int UserAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
string uname = xmlrpc_c::value_string(paramList.getString(1));
@ -671,7 +641,7 @@ int UserAllocate::pool_allocate(
driver = UserPool::CORE_AUTH;
}
return upool->allocate(&id,ugid,uname,ugname,passwd,driver,true,error_str);
return upool->allocate(&id,ugid,uname,ugname,passwd,driver,true,att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -681,7 +651,6 @@ int GroupAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
int rc;
@ -690,7 +659,7 @@ int GroupAllocate::pool_allocate(
GroupPool * gpool = static_cast<GroupPool *>(pool);
rc = gpool->allocate(gname, &id, error_str);
rc = gpool->allocate(gname, &id, att.resp_msg);
if (rc == -1)
{
@ -701,7 +670,7 @@ int GroupAllocate::pool_allocate(
if (vdc != 0)
{
rc = vdc->add_group(id, error_str);
rc = vdc->add_group(id, att.resp_msg);
vdcpool->update(vdc);
@ -718,7 +687,6 @@ int DatastoreAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att,
int cluster_id,
const string& cluster_name)
@ -727,7 +695,7 @@ int DatastoreAllocate::pool_allocate(
DatastoreTemplate * ds_tmpl = static_cast<DatastoreTemplate *>(tmpl);
return dspool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
ds_tmpl, &id, cluster_id, cluster_name, error_str);
ds_tmpl, &id, cluster_id, cluster_name, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -737,14 +705,13 @@ int ClusterAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
string name = xmlrpc_c::value_string(paramList.getString(1));
ClusterPool * clpool = static_cast<ClusterPool *>(pool);
return clpool->allocate(name, &id, error_str);
return clpool->allocate(name, &id, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -754,7 +721,6 @@ int DocumentAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
int type = xmlrpc_c::value_int(paramList.getInt(2));
@ -762,7 +728,7 @@ int DocumentAllocate::pool_allocate(
DocumentPool * docpool = static_cast<DocumentPool *>(pool);
return docpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
type, tmpl, &id, error_str);
type, tmpl, &id, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -773,9 +739,8 @@ void ZoneAllocate::request_execute(xmlrpc_c::paramList const& params,
{
if(!Nebula::instance().is_federation_master())
{
failure_response(INTERNAL, allocate_error(
"New Zones can only be created if OpenNebula "
"is configured as a Federation Master."), att);
att.resp_msg = "New zones can only be created at federation master";
failure_response(ALLOCATE, att);
return;
}
@ -789,14 +754,13 @@ int ZoneAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
string name = xmlrpc_c::value_string(paramList.getString(1));
ZonePool * zonepool = static_cast<ZonePool *>(pool);
return zonepool->allocate(tmpl, &id, error_str);
return zonepool->allocate(tmpl, &id, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -806,13 +770,12 @@ int SecurityGroupAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
SecurityGroupPool * sgpool = static_cast<SecurityGroupPool *>(pool);
return sgpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
tmpl, &id, error_str);
tmpl, &id, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -822,14 +785,13 @@ int VdcAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
string name = xmlrpc_c::value_string(paramList.getString(1));
VdcPool * vdcpool = static_cast<VdcPool *>(pool);
return vdcpool->allocate(tmpl, &id, error_str);
return vdcpool->allocate(tmpl, &id, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
@ -839,13 +801,52 @@ int VirtualRouterAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
string& error_str,
RequestAttributes& att)
{
VirtualRouterPool * vrpool = static_cast<VirtualRouterPool *>(pool);
return vrpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
tmpl, &id, error_str);
tmpl, &id, att.resp_msg);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool VirtualRouterAllocate::allocate_authorization(
Template * tmpl,
RequestAttributes& att,
PoolObjectAuth * cluster_perms)
{
if ( att.uid == 0 )
{
return true;
}
AuthRequest ar(att.uid, att.group_ids);
string tmpl_str;
// ------------------ Authorize create operation ------------------------
ar.add_create_auth(att.uid, att.gid, auth_object, tmpl->to_xml(tmpl_str));
VirtualRouter::set_auth_request(att.uid, ar, tmpl);
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return false;
}
// -------------------------- Check Quotas ----------------------------
if (quota_authorization(tmpl, Quotas::VIRTUALROUTER, att, att.resp_msg) == false)
{
return AUTHORIZATION;
}
return true;
}
/* -------------------------------------------------------------------------- */

View File

@ -40,7 +40,6 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
int other_a = xmlrpc_c::value_int(paramList.getInt(10));
PoolObjectSQL * object;
string error_str;
if ( att.uid != 0 && att.gid != 0)
{
@ -51,9 +50,8 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
@ -100,10 +98,8 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if ( !enable_other )
{
failure_response(AUTHORIZATION,
"Management of 'other' permissions is disabled in oned.conf",
att);
att.resp_msg = "'other' permissions is disabled in oned.conf";
failure_response(AUTHORIZATION, att);
return;
}
}
@ -114,9 +110,8 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
@ -128,20 +123,17 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
int rc = object->set_permissions(owner_u, owner_m, owner_a, group_u,
group_m, group_a, other_u, other_m, other_a, error_str);
group_m, group_a, other_u, other_m, other_a, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL,
request_error("Error updating permissions",error_str),
att);
failure_response(INTERNAL, att);
object->unlock();
return;

View File

@ -37,15 +37,12 @@ PoolObjectSQL * RequestManagerChown::get_and_quota(
PoolObjectSQL * object;
Quotas::QuotaType qtype;
string error_str;
object = pool->get(oid,true);
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object), oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return 0;
}
@ -70,7 +67,6 @@ PoolObjectSQL * RequestManagerChown::get_and_quota(
unsigned int total = vn->get_size();
ostringstream oss;
string tmp_error;
int parent = vn->get_parent();
@ -86,7 +82,7 @@ PoolObjectSQL * RequestManagerChown::get_and_quota(
oss << " NIC = [ NETWORK_ID = " << parent << " ]" << endl;
}
tmpl->parse_str_or_xml(oss.str(), error_str);
tmpl->parse_str_or_xml(oss.str(), att.resp_msg);
qtype = Quotas::NETWORK;
}
@ -120,11 +116,9 @@ PoolObjectSQL * RequestManagerChown::get_and_quota(
RequestAttributes att_new(new_uid, new_gid, att);
RequestAttributes att_old(old_uid, old_gid, att);
if ( quota_authorization(tmpl, qtype, att_new, error_str) == false )
if ( quota_authorization(tmpl, qtype, att_new, att.resp_msg) == false )
{
failure_response(AUTHORIZATION,
request_error(error_str, ""),
att);
failure_response(AUTHORIZATION, att);
delete tmpl;
return 0;
@ -138,11 +132,10 @@ PoolObjectSQL * RequestManagerChown::get_and_quota(
{
quota_rollback(tmpl, qtype, att_new);
quota_authorization(tmpl, qtype, att_old, error_str);
quota_authorization(tmpl, qtype, att_old, att.resp_msg);
failure_response(NO_EXISTS,
get_error(object_name(auth_object), oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
}
delete tmpl;
@ -164,10 +157,8 @@ int RequestManagerChown::check_name_unique(int oid, int noid, RequestAttributes&
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object), oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return -1;
}
@ -182,12 +173,12 @@ int RequestManagerChown::check_name_unique(int oid, int noid, RequestAttributes&
obj_oid = object->get_oid();
object->unlock();
oss << PoolObjectSQL::type_to_str(PoolObjectSQL::USER)
<< " [" << noid << "] already owns "
<< PoolObjectSQL::type_to_str(auth_object) << " ["
<< obj_oid << "] with NAME " << name;
oss << object_name(PoolObjectSQL::USER) << " ["<<noid<<"] already owns "
<< object_name(auth_object) << " ["<<obj_oid<<"] with NAME " << name;
failure_response(INTERNAL, request_error(oss.str(), ""), att);
att.resp_msg = oss.str();
failure_response(INTERNAL, att);
return -1;
}
@ -268,9 +259,8 @@ void RequestManagerChown::request_execute(xmlrpc_c::paramList const& paramList,
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
@ -300,9 +290,8 @@ void RequestManagerChown::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object), oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
}
}
@ -363,7 +352,8 @@ void UserChown::request_execute(xmlrpc_c::paramList const& paramList,
if ( ngid < 0 )
{
failure_response(XML_RPC_API,request_error("Wrong group ID",""), att);
att.resp_msg = "Wrong group ID";
failure_response(XML_RPC_API, att);
return;
}
@ -385,14 +375,16 @@ void UserChown::request_execute(xmlrpc_c::paramList const& paramList,
{
ostringstream oss;
oss << PoolObjectSQL::type_to_str(PoolObjectSQL::USER)
<< " [" << UserPool::ONEADMIN_ID << "] " << UserPool::oneadmin_name
oss << object_name(PoolObjectSQL::USER) << " ["
<< UserPool::ONEADMIN_ID << "] " << UserPool::oneadmin_name
<< " cannot be moved outside of the "
<< PoolObjectSQL::type_to_str(PoolObjectSQL::GROUP)
<< object_name(PoolObjectSQL::GROUP)
<< " [" << GroupPool::ONEADMIN_ID << "] "
<< GroupPool::ONEADMIN_NAME;
failure_response(INTERNAL, request_error(oss.str(), ""), att);
att.resp_msg = oss.str();
failure_response(INTERNAL, att);
return;
}
@ -405,9 +397,8 @@ void UserChown::request_execute(xmlrpc_c::paramList const& paramList,
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
@ -419,9 +410,10 @@ void UserChown::request_execute(xmlrpc_c::paramList const& paramList,
if ( user == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::USER),oid),
att);
att.resp_obj = PoolObjectSQL::USER;
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
@ -456,9 +448,11 @@ void UserChown::request_execute(xmlrpc_c::paramList const& paramList,
if( group == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::GROUP),ngid),
att);//TODO Rollback
//TODO Rollback
att.resp_obj = PoolObjectSQL::GROUP;
att.resp_id = ngid;
failure_response(NO_EXISTS, att);
return;
}

View File

@ -35,16 +35,12 @@ void RequestManagerClone::request_execute(
Template * tmpl;
PoolObjectSQL * source_obj;
string error_str;
source_obj = pool->get(source_id, true);
if ( source_obj == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object), source_id),
att);
att.resp_id = source_id;
failure_response(NO_EXISTS, att);
return;
}
@ -71,20 +67,19 @@ void RequestManagerClone::request_execute(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
delete tmpl;
return;
}
}
rc = pool_allocate(source_id, tmpl, new_id, error_str, att);
rc = pool_allocate(source_id, tmpl, new_id, att);
if ( rc < 0 )
{
failure_response(INTERNAL, allocate_error(error_str), att);
failure_response(ALLOCATE, att);
return;
}

View File

@ -38,7 +38,6 @@ void RequestManagerCluster::add_generic(
Clusterable * cluster_obj = 0;
PoolObjectSQL * object = 0;
PoolObjectAuth c_perms;
PoolObjectAuth obj_perms;
@ -82,9 +81,8 @@ void RequestManagerCluster::add_generic(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
@ -95,10 +93,9 @@ void RequestManagerCluster::add_generic(
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(type), object_id),
att);
att.resp_obj = type;
att.resp_id = object_id;
failure_response(NO_EXISTS, att);
return;
}
@ -127,9 +124,9 @@ void RequestManagerCluster::add_generic(
if ( cluster == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id),
att);
att.resp_obj = PoolObjectSQL::CLUSTER;
att.resp_id = cluster_id;
failure_response(NO_EXISTS, att);
// Rollback
get(object_id, true, &object, &cluster_obj);
@ -146,13 +143,11 @@ void RequestManagerCluster::add_generic(
return;
}
if ( add_object(cluster, object_id, ds_type, err_msg) < 0 )
if ( add_object(cluster, object_id, ds_type, att.resp_msg) < 0 )
{
cluster->unlock();
failure_response(INTERNAL,
request_error("Cannot add object to cluster", err_msg),
att);
failure_response(INTERNAL, att);
// Rollback
get(object_id, true, &object, &cluster_obj);
@ -189,14 +184,11 @@ void RequestManagerCluster::add_generic(
return;
}
if ( del_object(cluster, object_id, err_msg) < 0 )
if ( del_object(cluster, object_id, att.resp_msg) < 0 )
{
cluster->unlock();
failure_response(INTERNAL,
request_error("Cannot remove object from cluster", err_msg),
att);
failure_response(INTERNAL, att);
return;
}

View File

@ -29,7 +29,6 @@ void DatastoreEnable::request_execute(xmlrpc_c::paramList const& paramList,
int rc;
Datastore * ds;
string err_msg;
if ( basic_authorization(id, att) == false )
{
@ -40,18 +39,16 @@ void DatastoreEnable::request_execute(xmlrpc_c::paramList const& paramList,
if ( ds == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
rc = ds->enable(enable_flag, err_msg);
rc = ds->enable(enable_flag, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL,request_error(err_msg,""), att);
failure_response(INTERNAL, att);
ds->unlock();
return;

View File

@ -37,9 +37,8 @@ bool RequestManagerDelete::delete_authorization(
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return false;
}
@ -53,9 +52,8 @@ bool RequestManagerDelete::delete_authorization(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return false;
}
@ -82,8 +80,8 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
failure_response(NO_EXISTS, get_error(object_name(auth_object), oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
@ -91,9 +89,8 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList,
if ( rc != 0 )
{
failure_response(ACTION,
request_error("Cannot delete "+object_name(auth_object),error_msg),
att);
att.resp_msg = "Cannot delete " + object_name(auth_object) + ". " + error_msg;
failure_response(ACTION, att);
return;
}

View File

@ -26,16 +26,14 @@ void GroupSetQuota::
string quota_str = xmlrpc_c::value_string(paramList.getString(2));
Group * group;
string error_str;
Template quota_tmpl;
int rc;
if ( id == GroupPool::ONEADMIN_ID )
{
failure_response(ACTION,
request_error("Cannot set quotas for oneadmin group",""),
att);
att.resp_msg = "Cannot set quotas for oneadmin group";
failure_response(ACTION, att);
return;
}
@ -44,11 +42,11 @@ void GroupSetQuota::
return;
}
rc = quota_tmpl.parse_str_or_xml(quota_str, error_str);
rc = quota_tmpl.parse_str_or_xml(quota_str, att.resp_msg);
if ( rc != 0 )
{
failure_response(ACTION, request_error(error_str,""), att);
failure_response(ACTION, att);
return;
}
@ -56,14 +54,12 @@ void GroupSetQuota::
if ( group == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
group->quota.set(&quota_tmpl, error_str);
group->quota.set(&quota_tmpl, att.resp_msg);
static_cast<GroupPool *>(pool)->update_quotas(group);
@ -71,7 +67,7 @@ void GroupSetQuota::
if ( rc != 0 )
{
failure_response(ACTION, request_error(error_str,""), att);
failure_response(ACTION, att);
}
else
{
@ -117,9 +113,9 @@ void GroupEditAdmin::request_execute(
if ( rc == -1 )
{
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::USER),
user_id), att);
att.resp_obj = PoolObjectSQL::USER;
att.resp_id = user_id;
failure_response(NO_EXISTS, att);
return;
}
@ -133,9 +129,8 @@ void GroupEditAdmin::request_execute(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
@ -145,14 +140,12 @@ void GroupEditAdmin::request_execute(
if ( group == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),group_id),
att);
att.resp_id = group_id;
failure_response(NO_EXISTS, att);
return;
}
rc = edit_admin(group, user_id, error_str);
rc = edit_admin(group, user_id, att.resp_msg);
if (rc == 0)
{
@ -163,9 +156,8 @@ void GroupEditAdmin::request_execute(
if (rc != 0)
{
failure_response(INTERNAL,
request_error("Cannot edit group", error_str),
att);
att.resp_msg = "Cannot edit group. " + att.resp_msg;
failure_response(INTERNAL, att);
return;
}

View File

@ -30,8 +30,6 @@ void HostEnable::request_execute(xmlrpc_c::paramList const& paramList,
HostPool * hpool = static_cast<HostPool *>(pool);
string error_str;
if ( basic_authorization(id, att) == false )
{
return;
@ -41,9 +39,8 @@ void HostEnable::request_execute(xmlrpc_c::paramList const& paramList,
if ( host == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
@ -85,7 +82,8 @@ void HostMonitoring::request_execute(
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
att.resp_msg = "Internal error";
failure_response(INTERNAL, att);
return;
}

View File

@ -28,8 +28,6 @@ void ImageEnable::request_execute(xmlrpc_c::paramList const& paramList,
bool enable_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
int rc;
string err_msg;
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
@ -38,20 +36,20 @@ void ImageEnable::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
rc = imagem->enable_image(id,enable_flag, err_msg);
rc = imagem->enable_image(id,enable_flag, att.resp_msg);
if( rc < 0 )
{
if (enable_flag == true)
{
err_msg = "Could not enable image: " + err_msg;
att.resp_msg = "Could not enable image: " + att.resp_msg;
}
else
{
err_msg = "Could not disable image: " + err_msg;
att.resp_msg = "Could not disable image: " + att.resp_msg;
}
failure_response(INTERNAL, request_error(err_msg,""), att);
failure_response(INTERNAL, att);
return;
}
@ -69,7 +67,6 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
int rc;
Image * image;
string err_msg;
if ( basic_authorization(id, att) == false )
{
@ -80,9 +77,8 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
if ( image == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
@ -97,27 +93,26 @@ void ImagePersistent::request_execute(xmlrpc_c::paramList const& paramList,
case Image::KERNEL:
case Image::RAMDISK:
case Image::CONTEXT:
failure_response(ACTION,
request_error("KERNEL, RAMDISK and CONTEXT files must be "
"non-persistent",""), att);
att.resp_msg = "KERNEL, RAMDISK and CONTEXT must be non-persistent";
failure_response(ACTION, att);
image->unlock();
return;
}
rc = image->persistent(persistent_flag, err_msg);
rc = image->persistent(persistent_flag, att.resp_msg);
if ( rc != 0 )
{
if (persistent_flag == true)
{
err_msg = "Could not make image persistent: " + err_msg;
att.resp_msg = "Could not make image persistent: " + att.resp_msg;
}
else
{
err_msg = "Could not make image non-persistent: " + err_msg;
att.resp_msg = "Could not make image non-persistent: " + att.resp_msg;
}
failure_response(INTERNAL,request_error(err_msg,""), att);
failure_response(INTERNAL, att);
image->unlock();
return;
@ -143,7 +138,6 @@ void ImageChangeType::request_execute(xmlrpc_c::paramList const& paramList,
Image::ImageType itype;
Image * image;
string err_msg;
if ( basic_authorization(id, att) == false )
{
@ -154,10 +148,8 @@ void ImageChangeType::request_execute(xmlrpc_c::paramList const& paramList,
if ( image == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
@ -168,14 +160,12 @@ void ImageChangeType::request_execute(xmlrpc_c::paramList const& paramList,
case Image::OS:
case Image::DATABLOCK:
case Image::CDROM:
if ((itype != Image::OS) &&
(itype != Image::DATABLOCK)&&
(itype != Image::CDROM) )
if ((itype != Image::OS) && (itype != Image::DATABLOCK)&&
(itype != Image::CDROM))
{
failure_response(ACTION,
request_error("Cannot change image type to an incompatible"
" type for the current datastore.",""),
att);
att.resp_msg = "Cannot change image type to an incompatible type"
" for the current datastore.";
failure_response(ACTION, att);
image->unlock();
return;
@ -189,10 +179,9 @@ void ImageChangeType::request_execute(xmlrpc_c::paramList const& paramList,
(itype != Image::RAMDISK)&&
(itype != Image::CONTEXT) )
{
failure_response(ACTION,
request_error("Cannot change image type to an incompatible"
" type for the current datastore.",""),
att);
att.resp_msg = "Cannot change image type to an incompatible type"
" for the current datastore.";
failure_response(ACTION, att);
image->unlock();
return;
@ -200,11 +189,11 @@ void ImageChangeType::request_execute(xmlrpc_c::paramList const& paramList,
break;
}
rc = image->set_type(type, err_msg);
rc = image->set_type(type, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL,request_error(err_msg,""), att);
failure_response(INTERNAL, att);
image->unlock();
return;
@ -229,7 +218,7 @@ void ImageClone::request_execute(
long long avail, size;
int rc, new_id, ds_id_orig, ds_id = -1;
string error_str, ds_name, ds_data, ds_mad;
string ds_name, ds_data, ds_mad;
bool ds_check;
Image::DiskType disk_type;
@ -256,10 +245,8 @@ void ImageClone::request_execute(
if ( img == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object), clone_id),
att);
att.resp_id = clone_id;
failure_response(NO_EXISTS, att);
return;
}
@ -273,9 +260,8 @@ void ImageClone::request_execute(
case Image::KERNEL:
case Image::RAMDISK:
case Image::CONTEXT:
failure_response(ACTION,
allocate_error("KERNEL, RAMDISK and CONTEXT files cannot be "
"cloned."), att);
att.resp_msg = "KERNEL, RAMDISK and CONTEXT cannot be cloned.";
failure_response(ACTION, att);
img->unlock();
return;
}
@ -284,8 +270,8 @@ void ImageClone::request_execute(
if (snaps.size () > 0)
{
failure_response(ACTION,
request_error("Cannot clone images with snapshots",""), att);
att.resp_msg = "Cannot clone images with snapshots";
failure_response(ACTION, att);
img->unlock();
return;
}
@ -311,9 +297,9 @@ void ImageClone::request_execute(
if ( ds == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
att);
att.resp_obj = PoolObjectSQL::DATASTORE;
att.resp_id = ds_id;
failure_response(NO_EXISTS, att);
delete tmpl;
return;
@ -321,8 +307,8 @@ void ImageClone::request_execute(
if ( ds->get_type() != Datastore::IMAGE_DS )
{
failure_response(ACTION,
request_error("Clone only supported for IMAGE_DS Datastores",""),att);
att.resp_msg = "Clone only supported for IMAGE_DS Datastores";
failure_response(ACTION, att);
ds->unlock();
@ -348,8 +334,9 @@ void ImageClone::request_execute(
if (ds == 0)
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE),ds_id_orig),att);
att.resp_obj = PoolObjectSQL::DATASTORE;
att.resp_id = ds_id_orig;
failure_response(NO_EXISTS, att);
delete tmpl;
return;
@ -357,8 +344,8 @@ void ImageClone::request_execute(
if (ds->get_type() != Datastore::IMAGE_DS)
{
failure_response(ACTION, request_error(
"Clone only supported for IMAGE_DS Datastores",""), att);
att.resp_msg = "Clone only supported for IMAGE_DS Datastores";
failure_response(ACTION, att);
ds->unlock();
@ -368,8 +355,8 @@ void ImageClone::request_execute(
if (ds->get_ds_mad() != ds_mad)
{
failure_response(ACTION, request_error(
"Clone only supported to same DS_MAD Datastores",""), att);
att.resp_msg = "Clone only supported to same DS_MAD Datastores";
failure_response(ACTION, att);
ds->unlock();
@ -389,8 +376,8 @@ void ImageClone::request_execute(
if (ds_check && (size > avail))
{
failure_response(ACTION,
request_error("Not enough space in datastore",""), att);
att.resp_msg = "Not enough space in datastore";
failure_response(ACTION, att);
delete tmpl;
return;
@ -416,9 +403,8 @@ void ImageClone::request_execute(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
delete tmpl;
return;
@ -447,12 +433,12 @@ void ImageClone::request_execute(
"",
clone_id,
&new_id,
error_str);
att.resp_msg);
if ( rc < 0 )
{
quota_rollback(&img_usage, Quotas::DATASTORE, att);
failure_response(INTERNAL, allocate_error(error_str), att);
failure_response(ALLOCATE, att);
return;
}
@ -487,12 +473,11 @@ void ImageSnapshotDelete::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
string err_msg;
int rc = imagem->delete_snapshot(id, snap_id, err_msg);
int rc = imagem->delete_snapshot(id, snap_id, att.resp_msg);
if ( rc < 0 )
{
failure_response(ACTION, request_error(err_msg, ""), att);
failure_response(ACTION, att);
return;
}
@ -516,12 +501,11 @@ void ImageSnapshotRevert::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
string err_msg;
int rc = imagem->revert_snapshot(id, snap_id, err_msg);
int rc = imagem->revert_snapshot(id, snap_id, att.resp_msg);
if ( rc < 0 )
{
failure_response(ACTION, request_error(err_msg, ""), att);
failure_response(ACTION, att);
return;
}
@ -545,12 +529,11 @@ void ImageSnapshotFlatten::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
string err_msg;
int rc = imagem->flatten_snapshot(id, snap_id, err_msg);
int rc = imagem->flatten_snapshot(id, snap_id, att.resp_msg);
if ( rc < 0 )
{
failure_response(ACTION, request_error(err_msg, ""), att);
failure_response(ACTION, att);
return;
}

View File

@ -50,9 +50,8 @@ void RequestManagerInfo::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
@ -90,10 +89,8 @@ void TemplateInfo::request_execute(xmlrpc_c::paramList const& paramList,
if ( vm_tmpl == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
@ -119,9 +116,8 @@ void TemplateInfo::request_execute(xmlrpc_c::paramList const& paramList,
{
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
delete extended_tmpl;
return;
@ -132,9 +128,8 @@ void TemplateInfo::request_execute(xmlrpc_c::paramList const& paramList,
if ( vm_tmpl == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
delete extended_tmpl;
return;
@ -166,12 +161,15 @@ void VirtualNetworkInfo::to_xml(RequestAttributes& att, PoolObjectSQL * object,
{
vector<int> vms;
vector<int> vnets;
vector<int> vrs;
string where_vnets;
string where_vms;
string where_vrs;
bool all_reservations;
bool all_vms;
bool all_vrs;
PoolObjectAuth perms;
@ -185,6 +183,7 @@ void VirtualNetworkInfo::to_xml(RequestAttributes& att, PoolObjectSQL * object,
{
all_reservations = true;
all_vms = true;
all_vrs = true;
}
else
{
@ -193,6 +192,9 @@ void VirtualNetworkInfo::to_xml(RequestAttributes& att, PoolObjectSQL * object,
all_vms = RequestManagerPoolInfoFilter::use_filter(att,
PoolObjectSQL::VM, false, false, false, "", where_vms);
all_vrs = RequestManagerPoolInfoFilter::use_filter(att,
PoolObjectSQL::VROUTER, false, false, false, "", where_vrs);
}
if ( all_reservations == true )
@ -213,5 +215,14 @@ void VirtualNetworkInfo::to_xml(RequestAttributes& att, PoolObjectSQL * object,
Nebula::instance().get_vmpool()->search(vms, where_vms);
}
static_cast<VirtualNetwork*>(object)->to_xml_extended(str, vms, vnets);
if ( all_vrs == true )
{
vrs.push_back(-1);
}
else
{
Nebula::instance().get_vrouterpool()->search(vrs, where_vrs);
}
static_cast<VirtualNetwork*>(object)->to_xml_extended(str, vms, vnets, vrs);
};

View File

@ -40,9 +40,8 @@ void RequestManagerLock::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
@ -78,9 +77,8 @@ void RequestManagerUnlock::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}

View File

@ -98,10 +98,8 @@ void VirtualMachinePoolInfo::request_execute(
if (( state < VirtualMachinePoolInfo::ALL_VM ) ||
( state > VirtualMachine::UNDEPLOYED ))
{
failure_response(XML_RPC_API,
request_error("Incorrect filter_flag, state",""),
att);
att.resp_msg = "Incorrect filter_flag, state";
failure_response(XML_RPC_API, att);
return;
}
@ -139,9 +137,8 @@ void VirtualMachinePoolAccounting::request_execute(
if ( filter_flag < MINE )
{
failure_response(XML_RPC_API,
request_error("Incorrect filter_flag",""),
att);
att.resp_msg = "Incorrect filter_flag";
failure_response(XML_RPC_API, att);
return;
}
@ -153,7 +150,8 @@ void VirtualMachinePoolAccounting::request_execute(
time_end);
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
att.resp_msg = "Internal error";
failure_response(INTERNAL, att);
return;
}
@ -181,9 +179,8 @@ void VirtualMachinePoolShowback::request_execute(
if ( filter_flag < MINE )
{
failure_response(XML_RPC_API,
request_error("Incorrect filter_flag",""),
att);
att.resp_msg = "Incorrect filter_flag";
failure_response(XML_RPC_API, att);
return;
}
@ -197,7 +194,8 @@ void VirtualMachinePoolShowback::request_execute(
end_year);
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
att.resp_msg = "Internal error";
failure_response(INTERNAL, att);
return;
}
@ -221,9 +219,8 @@ void VirtualMachinePoolMonitoring::request_execute(
if ( filter_flag < MINE )
{
failure_response(XML_RPC_API,
request_error("Incorrect filter_flag",""),
att);
att.resp_msg = "Incorrect filter_flag";
failure_response(XML_RPC_API, att);
return;
}
@ -233,7 +230,8 @@ void VirtualMachinePoolMonitoring::request_execute(
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
att.resp_msg = "Internal error";
failure_response(INTERNAL, att);
return;
}
@ -269,7 +267,8 @@ void HostPoolMonitoring::request_execute(
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
att.resp_msg = "Internal error";
failure_response(INTERNAL, att);
return;
}
@ -440,9 +439,8 @@ void RequestManagerPoolInfoFilter::dump(
if ( filter_flag < MINE )
{
failure_response(XML_RPC_API,
request_error("Incorrect filter_flag",""),
att);
att.resp_msg = "Incorrect filter_flag";
failure_response(XML_RPC_API, att);
return;
}
@ -468,7 +466,8 @@ void RequestManagerPoolInfoFilter::dump(
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
att.resp_msg = "Internal error";
failure_response(INTERNAL, att);
return;
}
@ -489,9 +488,8 @@ void VirtualNetworkPoolInfo::request_execute(
if ( filter_flag < MINE )
{
failure_response(XML_RPC_API,
request_error("Incorrect filter_flag",""),
att);
att.resp_msg = "Incorrect filter_flag";
failure_response(XML_RPC_API, att);
return;
}
@ -533,7 +531,8 @@ void VirtualNetworkPoolInfo::request_execute(
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
att.resp_msg = "Internal error";
failure_response(INTERNAL, att);
return;
}

View File

@ -61,7 +61,8 @@ void RequestManagerProxy::request_execute(xmlrpc_c::paramList const& _paramList,
}
catch(exception const& e)
{
failure_response(INTERNAL, request_error("Could not connect to the federation master oned", ""), att);
att.resp_msg = "Could not connect to the federation master oned";
failure_response(INTERNAL, att);
}
}

View File

@ -31,15 +31,14 @@ void RequestManagerRename::request_execute(xmlrpc_c::paramList const& paramList,
int rc;
string old_name;
string error_str;
PoolObjectAuth operms;
PoolObjectSQL * object;
if (test_and_set_rename(oid) == false)
{
failure_response(INTERNAL,
request_error("Object is being renamed", ""), att);
att.resp_msg = "Object is being renamed";
failure_response(INTERNAL, att);
return;
}
@ -70,9 +69,8 @@ void RequestManagerRename::request_execute(xmlrpc_c::paramList const& paramList,
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
clear_rename(oid);
return;
}
@ -89,13 +87,13 @@ void RequestManagerRename::request_execute(xmlrpc_c::paramList const& paramList,
object->unlock();
oss << PoolObjectSQL::type_to_str(auth_object)
<< " cannot be renamed to " << new_name
<< " because it collides with "
<< PoolObjectSQL::type_to_str(auth_object) << " "
oss << object_name(auth_object) << " cannot be renamed to " << new_name
<< " because it collides with " << object_name(auth_object) << " "
<< id;
failure_response(ACTION, request_error(oss.str(), ""), att);
att.resp_msg = oss.str();
failure_response(ACTION, att);
clear_rename(oid);
return;
@ -107,19 +105,18 @@ void RequestManagerRename::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object), oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
clear_rename(oid);
return;
}
if ( object->set_name(new_name, error_str) != 0 )
if ( object->set_name(new_name, att.resp_msg) != 0 )
{
object->unlock();
failure_response(ACTION, request_error(error_str, ""), att);
failure_response(ACTION, att);
clear_rename(oid);
return;

View File

@ -43,9 +43,9 @@ void SystemConfig::request_execute(xmlrpc_c::paramList const& paramList,
{
if ( att.gid != GroupPool::ONEADMIN_ID )
{
failure_response(AUTHORIZATION,
"The oned configuration can only be retrieved by users in the oneadmin group",
att);
att.resp_msg = "The oned configuration can only be retrieved by users "
"in the oneadmin group";
failure_response(AUTHORIZATION, att);
return;
}
@ -94,25 +94,25 @@ void QuotaUpdate::request_execute(xmlrpc_c::paramList const& paramList,
if ( att.gid != GroupPool::ONEADMIN_ID )
{
failure_response(AUTHORIZATION,
"The default quotas can only be updated by users in the oneadmin group",
att);
att.resp_msg = "The default quotas can only be updated by users in the"
" oneadmin group";
failure_response(AUTHORIZATION, att);
return;
}
rc = quota_tmpl.parse_str_or_xml(quota_str, error_str);
rc = quota_tmpl.parse_str_or_xml(quota_str, att.resp_msg);
if ( rc != 0 )
{
failure_response(ACTION, request_error(error_str,""), att);
failure_response(ACTION, att);
return;
}
rc = set_default_quota(&quota_tmpl, error_str);
rc = set_default_quota(&quota_tmpl, att.resp_msg);
if ( rc != 0 )
{
failure_response(ACTION, request_error(error_str,""), att);
failure_response(ACTION, att);
return;
}

View File

@ -64,7 +64,6 @@ void RequestManagerUpdateTemplate::request_execute(
RequestAttributes& att)
{
int rc;
string error_str;
int oid = xmlrpc_c::value_int(paramList.getInt(1));
string tmpl = xmlrpc_c::value_string(paramList.getString(2));
@ -85,10 +84,8 @@ void RequestManagerUpdateTemplate::request_execute(
if ( update_type < 0 || update_type > 1 )
{
failure_response(XML_RPC_API,
request_error("Wrong update type",error_str),
att);
att.resp_msg = "Wrong update type";
failure_response(XML_RPC_API, att);
return;
}
@ -97,27 +94,24 @@ void RequestManagerUpdateTemplate::request_execute(
if ( object == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),oid),
att);
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
if (update_type == 0)
{
rc = replace_template(object, tmpl, att, error_str);
rc = replace_template(object, tmpl, att, att.resp_msg);
}
else //if (update_type == 1)
{
rc = append_template(object, tmpl, att, error_str);
rc = append_template(object, tmpl, att, att.resp_msg);
}
if ( rc != 0 )
{
failure_response(INTERNAL,
request_error("Cannot update template",error_str),
att);
att.resp_msg = "Cannot update template. " + att.resp_msg;
failure_response(INTERNAL, att);
object->unlock();
return;

View File

@ -35,16 +35,14 @@ void RequestManagerUser::
if ( user == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
if ( user_action(id,paramList,error_str) < 0 )
if ( user_action(id, paramList, att.resp_msg) < 0 )
{
failure_response(ACTION, request_error(error_str,""), att);
failure_response(ACTION, att);
return;
}
@ -214,17 +212,15 @@ void UserEditGroup::
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
}
if ( secondary_group_action(user_id, group_id, paramList, error_str) < 0 )
if ( secondary_group_action(user_id, group_id, paramList, att.resp_msg) < 0 )
{
failure_response(ACTION, request_error(error_str,""), att);
failure_response(ACTION, att);
return;
}
@ -375,10 +371,7 @@ void UserLogin::request_execute(xmlrpc_c::paramList const& paramList,
if ( user == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),-1),
att);
failure_response(NO_EXISTS, att);
return;
}
@ -393,10 +386,8 @@ void UserLogin::request_execute(xmlrpc_c::paramList const& paramList,
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
}
@ -405,10 +396,7 @@ void UserLogin::request_execute(xmlrpc_c::paramList const& paramList,
if ( user == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),-1),
att);
failure_response(NO_EXISTS, att);
return;
}
@ -424,11 +412,10 @@ void UserLogin::request_execute(xmlrpc_c::paramList const& paramList,
}
else
{
failure_response(XML_RPC_API,
request_error("Wrong valid period for token",""), att);
att.resp_msg = "Wrong valid period for token";
failure_response(XML_RPC_API, att);
user->unlock();
return;
}

View File

@ -29,33 +29,6 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
bool on_hold = false; //Optional XML-RPC argument
string str_uattrs; //Optional XML-RPC argument
int rc;
int vid;
ostringstream sid;
PoolObjectAuth perms;
PoolObjectAuth vr_perms;
Nebula& nd = Nebula::instance();
VirtualMachinePool* vmpool = nd.get_vmpool();
VMTemplatePool * tpool = static_cast<VMTemplatePool *>(pool);
VirtualRouterPool* vrpool = nd.get_vrouterpool();
VirtualRouter * vr;
VirtualMachineTemplate * tmpl;
VirtualMachineTemplate * extended_tmpl = 0;
VirtualMachineTemplate uattrs;
VMTemplate * rtmpl;
string error_str;
string aname;
bool has_vrouter_id;
int vrid;
string tmpl_name;
if ( paramList.size() > 3 )
{
on_hold = xmlrpc_c::value_boolean(paramList.getBoolean(3));
@ -63,19 +36,58 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
str_uattrs = xmlrpc_c::value_string(paramList.getString(4));
}
// TODO: if Template has VROUTER = YES, do not allow to instantiate here
int vid;
ErrorCode ec;
ec = instantiate(id, name, on_hold, str_uattrs, 0, vid, att);
if ( ec == SUCCESS )
{
success_response(vid, att);
}
else
{
failure_response(ec, att);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Request::ErrorCode VMTemplateInstantiate::instantiate(int id, string name,
bool on_hold, string str_uattrs, Template* extra_attrs, int& vid,
RequestAttributes& att)
{
int rc;
ostringstream sid;
PoolObjectAuth perms;
Nebula& nd = Nebula::instance();
VirtualMachinePool* vmpool = nd.get_vmpool();
VMTemplatePool * tpool = nd.get_tpool();
VirtualMachineTemplate * tmpl;
VirtualMachineTemplate * extended_tmpl = 0;
VirtualMachineTemplate uattrs;
VMTemplate * rtmpl;
string aname;
string tmpl_name;
/* ---------------------------------------------------------------------- */
/* Get, check and clone the template */
/* ---------------------------------------------------------------------- */
rtmpl = tpool->get(id,true);
if ( rtmpl == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
return;
att.resp_id = id;
return NO_EXISTS;
}
tmpl_name = rtmpl->get_name();
@ -88,39 +100,42 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
// Parse & merge user attributes (check if the request user is not oneadmin)
if (!str_uattrs.empty())
{
rc = uattrs.parse_str_or_xml(str_uattrs, error_str);
rc = uattrs.parse_str_or_xml(str_uattrs, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL, error_str, att);
delete tmpl;
return;
return INTERNAL;
}
if (att.uid!=UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
{
if (uattrs.check(aname))
{
ostringstream oss;
oss << "User Template includes a restricted attribute "<< aname;
failure_response(AUTHORIZATION,
authorization_error(oss.str(), att),
att);
att.resp_msg ="User Template includes a restricted attribute " + aname;
delete tmpl;
return;
return AUTHORIZATION;
}
}
rc = tmpl->merge(&uattrs, error_str);
rc = tmpl->merge(&uattrs, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL, error_str, att);
delete tmpl;
return;
return INTERNAL;
}
}
if (extra_attrs != 0)
{
rc = tmpl->merge(extra_attrs, att.resp_msg);
if ( rc != 0 )
{
delete tmpl;
return INTERNAL;
}
}
@ -141,48 +156,13 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
tmpl->set(new SingleAttribute("NAME",name));
}
/* ---------------------------------------------------------------------- */
/* If it is a Virtual Router, get the NICs */
/* ---------------------------------------------------------------------- */
has_vrouter_id = tmpl->get("VROUTER_ID", vrid);
if ( has_vrouter_id )
{
vr = vrpool->get(vrid, true);
if (vr == 0)
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::VROUTER),vrid),
att);
delete tmpl;
return;
}
vr->get_permissions(vr_perms);
tmpl->erase("NIC");
rc = tmpl->merge(vr->get_nics(), error_str);
vr->unlock();
if ( rc != 0 )
{
failure_response(INTERNAL, error_str, att);
delete tmpl;
return;
}
}
//--------------------------------------------------------------------------
if ( att.uid != 0 )
{
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(auth_op, perms); //USE TEMPLATE
ar.add_auth(AuthRequest::USE, perms); //USE TEMPLATE
if (!str_uattrs.empty())
{
@ -191,47 +171,37 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
tmpl->to_xml(tmpl_str);
// CREATE TEMPLATE
ar.add_create_auth(att.uid, att.gid, auth_object, tmpl_str);
ar.add_create_auth(att.uid, att.gid, PoolObjectSQL::TEMPLATE, tmpl_str);
}
VirtualMachine::set_auth_request(att.uid, ar, tmpl);
if (has_vrouter_id)
{
ar.add_auth(AuthRequest::MANAGE, vr_perms); // MANAGE VROUTER
}
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
delete tmpl;
return;
return AUTHORIZATION;
}
extended_tmpl = new VirtualMachineTemplate(*tmpl);
VirtualMachine::disk_extended_info(att.uid, extended_tmpl);
if ( quota_authorization(extended_tmpl, Quotas::VIRTUALMACHINE, att) == false )
if (quota_authorization(extended_tmpl, Quotas::VIRTUALMACHINE, att,
att.resp_msg) == false)
{
delete tmpl;
delete extended_tmpl;
return;
return AUTHORIZATION;
}
}
rc = vmpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
tmpl, &vid, error_str, on_hold);
tmpl, &vid, att.resp_msg, on_hold);
if ( rc < 0 )
{
failure_response(INTERNAL,
allocate_error(PoolObjectSQL::VM,error_str),
att);
if (extended_tmpl != 0)
{
quota_rollback(extended_tmpl, Quotas::VIRTUALMACHINE, att);
@ -239,26 +209,12 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
delete extended_tmpl;
return;
return ALLOCATE;
}
delete extended_tmpl;
if ( has_vrouter_id )
{
vr = vrpool->get(vrid, true);
if (vr != 0)
{
vr->add_vmid(vid);
vrpool->update(vr);
vr->unlock();
}
}
success_response(vid, att);
return SUCCESS;
}
/* -------------------------------------------------------------------------- */

View File

@ -30,7 +30,6 @@ void VdcEditGroup::request_execute(
string vdc_name;
string group_name;
string error_str;
Vdc* vdc;
@ -53,9 +52,9 @@ void VdcEditGroup::request_execute(
if ( rc == -1 && check_obj_exist )
{
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::GROUP),
group_id), att);
att.resp_obj = PoolObjectSQL::GROUP;
att.resp_id = group_id;
failure_response(NO_EXISTS, att);
return;
}
@ -68,10 +67,8 @@ void VdcEditGroup::request_execute(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
}
@ -80,14 +77,12 @@ void VdcEditGroup::request_execute(
if ( vdc == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),vdc_id),
att);
att.resp_id = vdc_id;
failure_response(NO_EXISTS, att);
return;
}
rc = edit_group(vdc, group_id, error_str);
rc = edit_group(vdc, group_id, att.resp_msg);
if (rc == 0)
{
@ -98,10 +93,7 @@ void VdcEditGroup::request_execute(
if (rc != 0)
{
failure_response(INTERNAL,
request_error("Cannot edit VDC", error_str),
att);
failure_response(INTERNAL, att);
return;
}
@ -144,7 +136,6 @@ void VdcEditResource::request_execute(
string vdc_name;
string zone_name;
string res_name;
string error_str;
Vdc* vdc;
@ -156,8 +147,7 @@ void VdcEditResource::request_execute(
// Authorize the action
// -------------------------------------------------------------------------
rc = get_info(pool, vdc_id, PoolObjectSQL::VDC,
att, vdc_perms, vdc_name, true);
rc = get_info(pool, vdc_id, PoolObjectSQL::VDC, att, vdc_perms, vdc_name, true);
if ( rc == -1 )
{
@ -165,32 +155,30 @@ void VdcEditResource::request_execute(
}
rc = get_info(zonepool, zone_id, PoolObjectSQL::ZONE, att, zone_perms,
zone_name, false);
zone_name, false);
zone_exists = (rc == 0);
if ( rc == -1 && check_obj_exist )
{
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::ZONE),
zone_id), att);
att.resp_obj = PoolObjectSQL::ZONE;
att.resp_id = zone_id;
failure_response(NO_EXISTS, att);
return;
}
// TODO: resource must exist in target zone, this code only checks locally
if (res_id != Vdc::ALL_RESOURCES && zone_id == local_zone_id)
{
rc = get_info(respool, res_id, res_obj_type, att,
res_perms, res_name, false);
rc = get_info(respool, res_id, res_obj_type, att, res_perms, res_name, false);
res_exists = (rc == 0);
if ( rc == -1 && check_obj_exist )
{
failure_response(NO_EXISTS, get_error(object_name(res_obj_type),
res_id), att);
att.resp_obj = res_obj_type;
att.resp_id = res_id;
failure_response(NO_EXISTS, att);
return;
}
}
@ -213,10 +201,8 @@ void VdcEditResource::request_execute(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
}
@ -225,14 +211,12 @@ void VdcEditResource::request_execute(
if ( vdc == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),vdc_id),
att);
att.resp_id = vdc_id;
failure_response(NO_EXISTS, att);
return;
}
rc = edit_resource(vdc, zone_id, res_id, error_str);
rc = edit_resource(vdc, zone_id, res_id, att.resp_msg);
if (rc == 0)
{
@ -243,10 +227,7 @@ void VdcEditResource::request_execute(
if (rc != 0)
{
failure_response(INTERNAL,
request_error("Error updating the VDC", error_str),
att);
failure_response(INTERNAL, att);
return;
}

File diff suppressed because it is too large Load Diff

View File

@ -19,14 +19,6 @@
using namespace std;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string RequestManagerVirtualNetwork::leases_error (const string& error)
{
return request_error("Error modifying network leases", error);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
@ -40,19 +32,18 @@ void RequestManagerVirtualNetwork::
VirtualNetworkTemplate tmpl;
VirtualNetwork * vn;
string error_str;
int rc;
int rc;
if ( basic_authorization(id, att) == false )
{
return;
}
rc = tmpl.parse_str_or_xml(str_tmpl, error_str);
rc = tmpl.parse_str_or_xml(str_tmpl, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL, leases_error(error_str), att);
failure_response(INTERNAL, att);
return;
}
@ -60,17 +51,16 @@ void RequestManagerVirtualNetwork::
if ( vn == 0 )
{
failure_response(NO_EXISTS, get_error(object_name(auth_object),id),att);
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
rc = leases_action(vn, &tmpl, att, error_str);
rc = leases_action(vn, &tmpl, att, att.resp_msg);
if ( rc < 0 )
{
failure_response(INTERNAL,
request_error("Error modifying network leases",error_str),
att);
failure_response(INTERNAL, att);
vn->unlock();
return;
@ -95,12 +85,9 @@ void VirtualNetworkRmAddressRange::
VirtualNetwork * vn;
string error_str;
// -------------------------------------------------------------------------
// Authorize the operation VNET:MANAGE
// -------------------------------------------------------------------------
if (basic_authorization(id, att) == false)
{
return;
@ -109,12 +96,12 @@ void VirtualNetworkRmAddressRange::
// -------------------------------------------------------------------------
// Get VNET and data for reservations
// -------------------------------------------------------------------------
vn = static_cast<VirtualNetwork *>(pool->get(id,true));
if ( vn == 0 )
{
failure_response(NO_EXISTS, get_error(object_name(auth_object),id),att);
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
@ -131,11 +118,9 @@ void VirtualNetworkRmAddressRange::
vn->get_template_attribute("MAC" , mac , ar_id);
if ( vn->rm_ar(ar_id, error_str) < 0 )
if ( vn->rm_ar(ar_id, att.resp_msg) < 0 )
{
failure_response(INTERNAL,
request_error("Error removing address range",error_str),
att);
failure_response(INTERNAL, att);
vn->unlock();
@ -173,7 +158,7 @@ void VirtualNetworkRmAddressRange::
oss << " NIC = [ NETWORK_ID = " << parent << " ]" << endl;
}
tmpl.parse_str_or_xml(oss.str(), error_str);
tmpl.parse_str_or_xml(oss.str(), att.resp_msg);
Quotas::quota_del(Quotas::NETWORK, uid, gid, &tmpl);
}
@ -198,21 +183,19 @@ void VirtualNetworkReserve::request_execute(
VirtualNetwork * vn = 0;
VirtualNetwork * rvn = 0;
string error_str;
int rc;
int cluster_id;
int rc;
int cluster_id;
PoolObjectAuth reserv_perms;
// -------------------------------------------------------------------------
// Process the Reservation Template
// -------------------------------------------------------------------------
rc = tmpl.parse_str_or_xml(str_tmpl, error_str);
rc = tmpl.parse_str_or_xml(str_tmpl, att.resp_msg);
if ( rc != 0 )
{
failure_response(ACTION,
request_error("Error in reservation request", error_str), att);
failure_response(ACTION, att);
return;
}
@ -222,8 +205,8 @@ void VirtualNetworkReserve::request_execute(
if ( !tmpl.get("SIZE", size) || size <= 0 )
{
failure_response(ACTION, request_error("Error in reservation request",
"Reservation SIZE must be a greater than 0"), att);
att.resp_msg = "Reservation SIZE must be a greater than 0";
failure_response(ACTION, att);
return;
}
@ -238,15 +221,15 @@ void VirtualNetworkReserve::request_execute(
if (rid < 0)
{
failure_response(ACTION, request_error("Error in reservation request",
"NETWORK_ID must be equal or greater than 0"), att);
att.resp_msg = "NETWORK_ID must be equal or greater than 0";
failure_response(ACTION, att);
return;
}
if (rid == id)
{
failure_response(ACTION, request_error("Error in reservation request",
"Cannot add a reservation from the same network"), att);
att.resp_msg = "Cannot add a reservation from the same network";
failure_response(ACTION, att);
return;
}
@ -254,9 +237,8 @@ void VirtualNetworkReserve::request_execute(
if (rvn == 0)
{
failure_response(NO_EXISTS, get_error(object_name(auth_object),rid),
att);
att.resp_id = rid;
failure_response(NO_EXISTS, att);
return;
}
@ -264,8 +246,8 @@ void VirtualNetworkReserve::request_execute(
if (parent == -1)
{
failure_response(ACTION, request_error("Error in reservation request",
"Cannot add reservations to a non-reservation VNET"), att);
att.resp_msg = "Cannot add reservations to a non-reservation VNET";
failure_response(ACTION, att);
rvn->unlock();
@ -279,8 +261,8 @@ void VirtualNetworkReserve::request_execute(
oss << "New reservations for virtual network " << rid
<< " have to be from network " << parent;
failure_response(ACTION, request_error("Error in reservation request",
oss.str()), att);
att.resp_msg = oss.str();
failure_response(ACTION, att);
rvn->unlock();
@ -300,8 +282,8 @@ void VirtualNetworkReserve::request_execute(
if (name.empty() && !on_exisiting)
{
failure_response(ACTION, request_error("Error in reservation request",
"NAME for reservation has to be set"), att);
att.resp_msg = "NAME for reservation has to be set";
failure_response(ACTION, att);
return;
}
@ -312,8 +294,8 @@ void VirtualNetworkReserve::request_execute(
if ( with_ar_id && (ar_id < 0))
{
failure_response(ACTION, request_error("Error in reservation request",
"AR_ID must be equal or greater than 0"), att);
att.resp_msg = "AR_ID must be equal or greater than 0";
failure_response(ACTION, att);
return;
}
@ -325,8 +307,8 @@ void VirtualNetworkReserve::request_execute(
if (!with_ar_id && (!ip.empty()||!mac.empty()))
{
failure_response(ACTION, request_error("Error in reservation request",
"AR_ID must be specified for IP/MAC based reservations"), att);
att.resp_msg = "AR_ID must be specified for IP/MAC based reservations";
failure_response(ACTION, att);
return;
}
@ -337,14 +319,15 @@ void VirtualNetworkReserve::request_execute(
if ( vn == 0 )
{
failure_response(NO_EXISTS, get_error(object_name(auth_object),id),att);
att.resp_msg = id;
failure_response(NO_EXISTS, att);
return;
}
if (vn->get_parent() != -1)
{
failure_response(ACTION, request_error("Error in reservation request",
"Cannot reserve addresses from a reserved VNET"), att);
att.resp_msg = "Cannot reserve addresses from a reserved VNET";
failure_response(ACTION, att);
vn->unlock();
@ -365,8 +348,8 @@ void VirtualNetworkReserve::request_execute(
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION, authorization_error(ar.message, att),
att);
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
vn->unlock();
@ -385,12 +368,11 @@ void VirtualNetworkReserve::request_execute(
cluster_id = vn->get_cluster_id();
rc = vnpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
id, vtmpl, &rid, cluster_id, vn->get_cluster_name(), error_str);
id, vtmpl, &rid, cluster_id, vn->get_cluster_name(), att.resp_msg);
if (rc < 0)
{
failure_response(INTERNAL,
request_error("Cannot create a reservation VNET",error_str),att);
failure_response(INTERNAL, att);
vn->unlock();
@ -402,9 +384,8 @@ void VirtualNetworkReserve::request_execute(
if (rvn == 0)
{
failure_response(NO_EXISTS, get_error(object_name(auth_object),rid),
att);
att.resp_id = rid;
failure_response(NO_EXISTS, att);
vn->unlock();
return;
@ -423,7 +404,7 @@ void VirtualNetworkReserve::request_execute(
qtmpl_s << "NIC = [ NETWORK_ID = " << id << "]" << endl;
}
qtmpl.parse_str_or_xml(qtmpl_s.str(), error_str);
qtmpl.parse_str_or_xml(qtmpl_s.str(), att.resp_msg);
if (quota_authorization(&qtmpl, Quotas::NETWORK, reservation_att) == false)
{
@ -441,31 +422,31 @@ void VirtualNetworkReserve::request_execute(
{
if (!ip.empty())
{
rc = vn->reserve_addr_by_ip(rvn, size, ar_id, ip, error_str);
rc = vn->reserve_addr_by_ip(rvn, size, ar_id, ip, att.resp_msg);
}
else if (!mac.empty())
{
rc = vn->reserve_addr_by_mac(rvn, size, ar_id, mac, error_str);
rc = vn->reserve_addr_by_mac(rvn, size, ar_id, mac, att.resp_msg);
}
else
{
rc = vn->reserve_addr(rvn, size, ar_id, error_str);
rc = vn->reserve_addr(rvn, size, ar_id, att.resp_msg);
}
}
else
{
rc = vn->reserve_addr(rvn, size, error_str);
rc = vn->reserve_addr(rvn, size, att.resp_msg);
}
if (rc != 0 )
{
quota_rollback(&qtmpl, Quotas::NETWORK, reservation_att);
failure_response(ACTION, request_error(error_str,""), att);
failure_response(ACTION, att);
if (!on_exisiting)
{
pool->drop(rvn, error_str);
pool->drop(rvn, att.resp_msg);
}
rvn->unlock();
@ -495,7 +476,7 @@ void VirtualNetworkReserve::request_execute(
if ( cluster != 0 )
{
cluster->add_vnet(rid, error_str);
cluster->add_vnet(rid, att.resp_msg);
clpool->update(cluster);

View File

@ -0,0 +1,370 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManagerVirtualRouter.h"
#include "RequestManagerVMTemplate.h"
#include "RequestManagerVirtualMachine.h"
#include "PoolObjectAuth.h"
#include "Nebula.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualRouterInstantiate::request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
{
int vrid = xmlrpc_c::value_int(paramList.getInt(1));
int n_vms = xmlrpc_c::value_int(paramList.getInt(2));
int tmpl_id = xmlrpc_c::value_int(paramList.getInt(3));
string name = xmlrpc_c::value_string(paramList.getString(4));
bool on_hold = xmlrpc_c::value_boolean(paramList.getBoolean(5));
string str_uattrs = xmlrpc_c::value_string(paramList.getString(6));
Nebula& nd = Nebula::instance();
VirtualRouterPool* vrpool = nd.get_vrouterpool();
VirtualRouter * vr;
DispatchManager* dm = nd.get_dm();
PoolObjectAuth vr_perms;
Template* extra_attrs;
bool has_vmids;
string error;
string vr_name, tmp_name;
ostringstream oss;
vector<int> vms;
vector<int>::iterator vmid;
int vid;
/* ---------------------------------------------------------------------- */
/* Get the Virtual Router NICs */
/* ---------------------------------------------------------------------- */
vr = vrpool->get(vrid, true);
if (vr == 0)
{
att.resp_id = vrid;
failure_response(NO_EXISTS, att);
return;
}
vr->get_permissions(vr_perms);
extra_attrs = vr->get_vm_template();
has_vmids = vr->has_vmids();
vr_name = vr->get_name();
vr->unlock();
if ( att.uid != 0 )
{
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(AuthRequest::MANAGE, vr_perms); // MANAGE VROUTER
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
}
if (has_vmids)
{
att.resp_msg = "Virtual Router already has VMs. Cannot instantiate new ones";
failure_response(ACTION, att);
return;
}
if (name.empty())
{
name = "vr-" + vr_name + "-%i";
}
for (int i=0; i<n_vms; oss.str(""), i++)
{
oss << i;
tmp_name = one_util::gsub(name, "%i", oss.str());
ErrorCode ec = VMTemplateInstantiate::instantiate(tmpl_id, tmp_name,
true, str_uattrs, extra_attrs, vid, att);
if (ec != SUCCESS)
{
failure_response(ec, att);
for (vmid = vms.begin(); vmid != vms.end(); vmid++)
{
dm->finalize(*vmid, att.resp_msg);
}
return;
}
vms.push_back(vid);
}
vr = vrpool->get(vrid, true);
if (vr != 0)
{
for (vmid = vms.begin(); vmid != vms.end(); vmid++)
{
vr->add_vmid(*vmid);
}
vrpool->update(vr);
vr->unlock();
}
// VMs are created on hold to wait for all of them to be created
// successfully, to avoid the rollback dm->finalize call on prolog
if (!on_hold)
{
for (vmid = vms.begin(); vmid != vms.end(); vmid++)
{
dm->release(*vmid, att.resp_msg);
}
}
success_response(vrid, att);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualRouterAttachNic::request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
{
VirtualRouterPool* vrpool = static_cast<VirtualRouterPool*>(pool);
VirtualRouter * vr;
VectorAttribute* nic;
VirtualMachineTemplate tmpl;
PoolObjectAuth vr_perms;
int rc;
int vrid = xmlrpc_c::value_int(paramList.getInt(1));
string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
// -------------------------------------------------------------------------
// Parse NIC template
// -------------------------------------------------------------------------
rc = tmpl.parse_str_or_xml(str_tmpl, att.resp_msg);
if ( rc != 0 )
{
failure_response(INTERNAL, att);
return;
}
// -------------------------------------------------------------------------
// Authorize the operation & check quotas
// -------------------------------------------------------------------------
vr = vrpool->get(vrid, true);
if (vr == 0)
{
att.resp_id = vrid;
failure_response(NO_EXISTS, att);
return;
}
vr->get_permissions(vr_perms);
vr->unlock();
if ( att.uid != 0 )
{
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(AuthRequest::MANAGE, vr_perms); // MANAGE VROUTER
VirtualRouter::set_auth_request(att.uid, ar, &tmpl); // USE VNET
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
}
RequestAttributes att_quota(vr_perms.uid, vr_perms.gid, att);
if ( quota_authorization(&tmpl, Quotas::VIRTUALROUTER, att_quota) == false )
{
return;
}
// -------------------------------------------------------------------------
// Attach NIC to the Virtual Router
// -------------------------------------------------------------------------
vr = vrpool->get(vrid, true);
if (vr == 0)
{
quota_rollback(&tmpl, Quotas::VIRTUALROUTER, att_quota);
att.resp_id = vrid;
failure_response(NO_EXISTS, att);
return;
}
nic = vr->attach_nic(&tmpl, att.resp_msg);
set<int> vms = vr->get_vms();
vrpool->update(vr);
vr->unlock();
if (nic == 0)
{
quota_rollback(&tmpl, Quotas::VIRTUALROUTER, att_quota);
failure_response(ACTION, att);
return;
}
// -------------------------------------------------------------------------
// Attach NIC to each VM
// -------------------------------------------------------------------------
for (set<int>::iterator vmid = vms.begin(); vmid != vms.end(); vmid++)
{
VirtualMachineTemplate tmpl;
tmpl.set(nic->clone());
ErrorCode ec = VirtualMachineAttachNic::attach(*vmid, tmpl, att);
if (ec != SUCCESS) //TODO: manage individual attach error, do rollback?
{
failure_response(ACTION, att);
delete nic;
return;
}
}
delete nic;
success_response(vrid, att);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualRouterDetachNic::request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
{
VirtualRouterPool* vrpool = static_cast<VirtualRouterPool*>(pool);
VirtualRouter * vr;
PoolObjectAuth vr_perms;
int rc;
int vrid = xmlrpc_c::value_int(paramList.getInt(1));
int nic_id = xmlrpc_c::value_int(paramList.getInt(2));
// -------------------------------------------------------------------------
// Authorize the operation
// -------------------------------------------------------------------------
vr = vrpool->get(vrid, true);
if (vr == 0)
{
att.resp_id = vrid;
failure_response(NO_EXISTS, att);
return;
}
vr->get_permissions(vr_perms);
vr->unlock();
if ( att.uid != 0 )
{
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(AuthRequest::MANAGE, vr_perms); // MANAGE VROUTER
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
}
}
// -------------------------------------------------------------------------
// Detach the NIC from the Virtual Router
// -------------------------------------------------------------------------
vr = vrpool->get(vrid, true);
if (vr == 0)
{
att.resp_id = vrid;
failure_response(NO_EXISTS, att);
return;
}
rc = vr->detach_nic(nic_id);
set<int> vms = vr->get_vms();
vrpool->update(vr);
vr->unlock();
if (rc != 0)
{
ostringstream oss;
oss << "NIC with NIC_ID " << nic_id << " does not exist.";
att.resp_msg = oss.str();
failure_response(Request::ACTION, att);
return;
}
// -------------------------------------------------------------------------
// Detach NIC from each VM
// -------------------------------------------------------------------------
for (set<int>::iterator vmid = vms.begin(); vmid != vms.end(); vmid++)
{
ErrorCode ec = VirtualMachineDetachNic::detach(*vmid, nic_id, att);
if (ec != SUCCESS) //TODO: manage individual attach error, do rollback?
{
failure_response(Request::ACTION, att);
return;
}
}
success_response(vrid, att);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -48,6 +48,7 @@ source_files=[
'RequestManagerDatastore.cc',
'RequestManagerLock.cc',
'RequestManagerMarketPlaceApp.cc'
'RequestManagerVirtualRouter.cc',
]
# Build library

View File

@ -451,8 +451,9 @@ tabs:
VirtualRouter.chown: true
VirtualRouter.chgrp: true
VirtualRouter.chmod: true
VirtualRouter.clone_dialog: true
VirtualRouter.delete: true
VirtualRouter.attachnic: true
VirtualRouter.detachnic: true
marketplace-tab:
panel_tabs:
marketplace_info_tab: true

View File

@ -445,8 +445,9 @@ tabs:
VirtualRouter.chown: true
VirtualRouter.chgrp: true
VirtualRouter.chmod: true
VirtualRouter.clone_dialog: true
VirtualRouter.delete: true
VirtualRouter.attachnic: true
VirtualRouter.detachnic: true
marketplace-tab:
panel_tabs:
marketplace_info_tab: true

View File

@ -446,8 +446,9 @@ tabs:
VirtualRouter.chown: true
VirtualRouter.chgrp: true
VirtualRouter.chmod: true
VirtualRouter.clone_dialog: true
VirtualRouter.delete: true
VirtualRouter.attachnic: true
VirtualRouter.detachnic: true
marketplace-tab:
panel_tabs:
marketplace_info_tab: true

View File

@ -44,11 +44,13 @@ module OpenNebulaJSON
end
rc = case action_hash['perform']
when "instantiate" then self.instantiate(action_hash['params'])
when "update" then self.update(action_hash['params'])
when "chown" then self.chown(action_hash['params'])
when "chmod" then self.chmod_json(action_hash['params'])
when "clone" then self.clone(action_hash['params'])
when "rename" then self.rename(action_hash['params'])
when "attachnic" then self.nic_attach(action_hash['params'])
when "detachnic" then self.nic_detach(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
@ -56,6 +58,26 @@ module OpenNebulaJSON
end
end
def instantiate(params=Hash.new)
if params['template']
select_capacity = self['TEMPLATE/SUNSTONE_CAPACITY_SELECT']
if (select_capacity && select_capacity.upcase == "NO")
params['template'].delete("CPU")
params['template'].delete("MEMORY")
end
select_network = self['TEMPLATE/SUNSTONE_NETWORK_SELECT']
if (select_network && select_network.upcase == "NO")
params['template'].delete("NIC")
end
template = template_to_str(params['template'])
super(params['n_vms'], params['template_id'], params['vm_name'], params['hold'], template)
else
super(params['n_vms'], params['template_id'], params['vm_name'], params['hold'])
end
end
def update(params=Hash.new)
super(params['template_raw'])
end
@ -80,12 +102,18 @@ module OpenNebulaJSON
end
end
def clone(params=Hash.new)
super(params['name'])
end
def rename(params=Hash.new)
super(params['name'])
end
def nic_attach(params=Hash.new)
template_json = params['nic_template']
template = template_to_str(template_json)
super(template)
end
def nic_detach(params=Hash.new)
super(params['nic_id'].to_i)
end
end
end

View File

@ -25,6 +25,10 @@ define(function(require) {
"create" : function(params) {
OpenNebulaAction.create(params, RESOURCE);
},
"instantiate" : function(params) {
var action_obj = params.data.extra_param ? params.data.extra_param : {};
OpenNebulaAction.simple_action(params, RESOURCE, "instantiate", action_obj);
},
"del" : function(params) {
OpenNebulaAction.del(params, RESOURCE);
},
@ -48,15 +52,18 @@ define(function(require) {
var action_obj = {"template_raw" : params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj);
},
"clone" : function(params) {
var name = params.data.extra_param ? params.data.extra_param : "";
var action_obj = {"name" : name};
OpenNebulaAction.simple_action(params, RESOURCE, "clone", action_obj);
},
"rename" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj);
},
"attachnic" : function(params) {
var action_obj = {"nic_template": params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "attachnic", action_obj);
},
"detachnic" : function(params) {
var action_obj = {"nic_id": params.data.extra_param};
OpenNebulaAction.simple_action(params, RESOURCE, "detachnic", action_obj);
},
"getName": function(id){
return OpenNebulaAction.getName(id, RESOURCE);
}

View File

@ -261,6 +261,15 @@ define(function(require) {
'SL_PRIMARYIPADDRESS'
];
var NIC_IP_ATTRS = [
"IP",
"IP6_GLOBAL",
"IP6_ULA",
"VROUTER_IP",
"VROUTER_IP6_GLOBAL",
"VROUTER_IP6_ULA"
];
var EXTERNAL_NETWORK_ATTRIBUTES = [
'GUEST_IP',
'GUEST_IP_ADDRESSES',
@ -662,17 +671,11 @@ define(function(require) {
}
$.each(nic, function(index, value) {
if (value.IP) {
ips.push(value.IP);
}
if (value.IP6_GLOBAL) {
ips.push(value.IP6_GLOBAL);
}
if (value.IP6_ULA) {
ips.push(value.IP6_ULA);
}
$.each(NIC_IP_ATTRS, function(j, attr){
if (value[attr]) {
ips.push(value[attr]);
}
});
});
}
}

View File

@ -171,6 +171,7 @@ define(function(require) {
});
$("#group_res_net", context).prop("checked", false);
$("#group_res_vr", context).prop("checked", false);
$(context).off("change", ".admin_view_input");
$(context).on("change", ".admin_view_input", function(){

View File

@ -144,6 +144,7 @@
<th>{{tr "VMs"}}</th>
<th>{{tr "VNets"}}</th>
<th>{{tr "Security Groups"}}</th>
<th>{{tr "Virtual Routers"}}</th>
<th>{{tr "Images"}}</th>
<th>{{tr "Templates"}}</th>
<th>{{tr "Documents"}}<span class="tip">{{tr "Documents are a special tool used for general purposes, mainly by OneFlow. If you want to enable users of this group to use service composition via OneFlow, let it checked."}}</span></th>
@ -153,6 +154,7 @@
<td><input type="checkbox" id="group_res_vm" name="group_res_vm" class="resource_cb" value="VM"></input></td>
<td><input type="checkbox" id="group_res_net" name="group_res_net" class="resource_cb" value="NET"></input></td>
<td><input type="checkbox" id="group_res_sg" name="group_res_sg" class="resource_cb" value="SECGROUP"></input></td>
<td><input type="checkbox" id="group_res_vr" name="group_res_vr" class="resource_cb" value="VROUTER"></input></td>
<td><input type="checkbox" id="group_res_image" name="group_res_image" class="resource_cb" value="IMAGE"></input></td>
<td><input type="checkbox" id="group_res_template" name="group_res_template" class="resource_cb" value="TEMPLATE"></input></td>
<td><input type="checkbox" id="group_res_document" name="group_res_document" class="resource_cb" value="DOCUMENT"></input></td>

View File

@ -1543,13 +1543,12 @@ define(function(require) {
if (network_attrs.length > 0) {
NicsSection.generate_provision_network_accordion(
$(".provision_network_selector", context), true);
$(".provision_network_selector", context), {hide_add_button:true});
$.each(network_attrs, function(index, vnet_attr){
NicsSection.generate_provision_network_table(
$(".provision_nic_accordion", context),
null,
vnet_attr);
{vnet_attr: vnet_attr});
});
}

View File

@ -25,6 +25,8 @@ define(function(require) {
var PermissionsTable = require('utils/panel/permissions-table');
var TemplateTable = require('utils/panel/template-table');
var OpenNebulaVM = require('opennebula/vm');
var Sunstone = require('sunstone');
var Config = require('sunstone-config');
/*
TEMPLATES
@ -73,7 +75,7 @@ define(function(require) {
var lcmStateStr = OpenNebulaVM.lcmStateStr(this.element.LCM_STATE);
var hostname = OpenNebulaVM.hostnameStr(this.element);
var deployId = (typeof(this.element.DEPLOY_ID) == "object" ? "-" : this.element.DEPLOY_ID);
var deployId = (typeof(this.element.DEPLOY_ID) == "object" ? "--" : this.element.DEPLOY_ID);
var resched = (parseInt(this.element.RESCHED) ? Locale.tr("yes") : Locale.tr("no"))
var templateTableHTML = TemplateTable.html(this.element.USER_TEMPLATE, RESOURCE, Locale.tr("Attributes"));
@ -110,6 +112,15 @@ define(function(require) {
RenameTr.setup(TAB_ID, RESOURCE, this.element.ID, context);
PermissionsTable.setup(TAB_ID, RESOURCE, this.element, context);
$("a.vrid", context).on("click", function(){
// TODO: this should be checked internally in showElement,
// but it won't work because of bug #4198
if (Config.isTabEnabled("vrouters-tab")){
Sunstone.showElement("vrouters-tab", "VirtualRouter.show", $(this).text());
}
});
// Get rid of the unwanted (for show) SCHED_* keys
var that = this;
var strippedTemplate = {};

View File

@ -58,6 +58,17 @@
<td class="value_td">{{resched}}</td>
<td></td>
</tr>
<tr>
<td class="key_td">{{tr "Virtual Router ID"}}</td>
<td class="value_td">
{{#if element.TEMPLATE.VROUTER_ID}}
<a class="vrid">{{element.TEMPLATE.VROUTER_ID}}</a>
{{else}}
--
{{/if}}
</td>
<td></td>
</tr>
</tr>
</tbody>
</table>

View File

@ -262,13 +262,27 @@ define(function(require) {
});
}
function ipTr(attr){
var v = "--";
if (nic[attr] != undefined){
v = nic[attr];
if (nic["VROUTER_"+attr] != undefined){
v += ("<br/>" + nic["VROUTER_"+attr] + Locale.tr(" (VRouter)"));
}
}
return v;
}
nic_dt_data.push({
NIC_ID : nic.NIC_ID,
NETWORK : nic.NETWORK,
IP : (nic.IP ? nic.IP : "--"),
IP : ipTr("IP"),
MAC : nic.MAC,
IP6_ULA : (nic.IP6_ULA ? nic.IP6_ULA : "--"),
IP6_GLOBAL : (nic.IP6_GLOBAL ? nic.IP6_GLOBAL : "--"),
IP6_ULA : ipTr("IP6_ULA"),
IP6_GLOBAL : ipTr("IP6_GLOBAL"),
ACTIONS : actions,
SECURITY_GROUP_RULES : secgroups
});
@ -287,10 +301,10 @@ define(function(require) {
},
{"data": "NIC_ID", "defaultContent": ""},
{"data": "NETWORK", "defaultContent": ""},
{"data": "IP", "defaultContent": ""},
{"data": "IP", "defaultContent": "", "class": "nowrap"},
{"data": "MAC", "defaultContent": ""},
{"data": "IP6_ULA", "defaultContent": ""},
{"data": "IP6_GLOBAL", "defaultContent": ""},
{"data": "IP6_ULA", "defaultContent": "", "class": "nowrap"},
{"data": "IP6_GLOBAL", "defaultContent": "", "class": "nowrap"},
{"data": "ACTIONS", "defaultContent": "", "orderable": false},
{"defaultContent": "", "orderable": false}
],

View File

@ -22,17 +22,16 @@ define(function(require) {
var OpenNebula = require('opennebula');
var VNetUtils = require('tabs/vnets-tab/utils/common');
var Vis = require('vis');
var TemplateDashboard = require('hbs!./vnets-topology-tab/html');
var VNETS_TAB_ID = require('tabs/vnets-tab/tabId');
var VNETS_CREATE_FORM_PANEL_ID = require('tabs/vnets-tab/form-panels/create/formPanelId');
var _network;
var _vnetList;
var _vrList;
var _indexedVRs;
var _vrouterVMs;
var _vnetLevel;
var _buttons = {
"NetworkTopology.refresh" : {
@ -40,10 +39,22 @@ define(function(require) {
layout: "refresh",
alwaysActive: true
},
"NetworkTopology.toggleVMs" : {
"NetworkTopology.fit" : {
type: "action",
layout: "main",
text: Locale.tr("Toggle VMs"),
text: '<i class="fa fa-arrows-alt"/>',
alwaysActive: true
},
"NetworkTopology.collapseVMs" : {
type: "action",
layout: "main",
text: Locale.tr("Collapse VMs"),
alwaysActive: true
},
"NetworkTopology.openVMs" : {
type: "action",
layout: "main",
text: Locale.tr("Open VMs"),
alwaysActive: true
}
};
@ -53,9 +64,17 @@ define(function(require) {
type: "custom",
call: _refresh
},
"NetworkTopology.toggleVMs" : {
"NetworkTopology.fit" : {
type: "custom",
call: _toggleVMs
call: _fit
},
"NetworkTopology.collapseVMs" : {
type: "custom",
call: _collapseVMs
},
"NetworkTopology.openVMs" : {
type: "custom",
call: _openVMs
}
};
@ -84,47 +103,55 @@ define(function(require) {
function _refresh() {
OpenNebula.Network.list({
timeout: true,
success: function (request, item_list) {
OpenNebula.VirtualRouter.list({
error: Notifier.onError,
success: function(request, item_list) {
_vrList = item_list;
// TODO: naive way to request all the individual networks info. It might
// be better to use promises, or a Network.list with an 'extended' option
OpenNebula.Network.list({
timeout: true,
success: function (request, item_list) {
var vnetList = [];
// TODO: naive way to request all the individual networks info. It might
// be better to use promises, or a Network.list with an 'extended' option
var i = 0;
var vnetList = [];
function _getVNet(index){
var vnetId = item_list[index].VNET.ID;
var i = 0;
OpenNebula.Network.show({
data : {
id: vnetId
},
timeout:true,
success: function(request,info){
vnetList.push(info);
function _getVNet(index){
var vnetId = item_list[index].VNET.ID;
i += 1;
if (i == item_list.length){
_doTopology(vnetList);
} else {
_getVNet(i);
}
},
error: Notifier.onError
});
}
OpenNebula.Network.show({
data : {
id: vnetId
},
timeout:true,
success: function(request,info){
vnetList.push(info);
_getVNet(i);
},
error: Notifier.onError
i += 1;
if (i == item_list.length){
_vnetList = vnetList;
_doTopology();
} else {
_getVNet(i);
}
},
error: Notifier.onError
});
}
_getVNet(i);
},
error: Notifier.onError
});
}
});
}
function _doTopology(vnetList){
_vnetList = vnetList;
function _doTopology(){
_vnetLevel = {};
var nodes = [];
var edges = [];
@ -132,27 +159,59 @@ define(function(require) {
// Aux object to keep track of duplicated nodes (vms/vr attached to 2 vnets)
var nodeIndex = {};
$.each(vnetList, function(i,element){
var level = 0;
_indexedVRs = {};
_vrouterVMs = {};
$.each(_vrList, function(i, element){
var vr = element.VROUTER;
_indexedVRs[vr.ID] = vr;
var vms = [];
if (vr.VMS.ID != undefined){
vms = vr.VMS.ID;
if (!$.isArray(vms)){
vms = [vms];
}
}
$.each(vms, function(n, vm){
_vrouterVMs[vm] = {
vmid: vm,
vrid: vr.ID,
leases: {}
};
});
});
$.each(_vnetList, function(i,element){
var vnet = element.VNET;
var vnetId = vnet.ID;
// VNet node
// ----------------
var vnetNodeId = "vnet"+vnetId;
var group = "vnet";
if (vnet.PARENT_NETWORK_ID.length > 0){
group = "reservation";
edges.push({from: "vnet"+vnet.PARENT_NETWORK_ID, to: vnetNodeId});
vnetId = vnet.PARENT_NETWORK_ID;
}
nodes.push({
id: vnetNodeId,
label: "VNet "+vnet.NAME,
group: group});
var vnetNodeId = "vnet"+vnetId;
if (!nodeIndex[vnetNodeId]){
level += 2;
_vnetLevel[vnetId] = level;
nodeIndex[vnetNodeId] = true;
nodes.push({
id: vnetNodeId,
level: level,
label: " VNet "+vnet.NAME + " ", // Spaces for padding, no other reason
group: "vnet"});
}
// VRouter nodes
// ----------------
@ -174,6 +233,8 @@ define(function(require) {
nodeIndex[nodeId] = true;
nodes.push({
id: nodeId,
level: level+1,
title: '',
label: "VR "+vr,
group: "vr"});
}
@ -184,8 +245,6 @@ define(function(require) {
// VM nodes
// ----------------
var vms = [];
var arList = VNetUtils.getARList(vnet);
for (var i=0; i<arList.length; i++){
@ -204,12 +263,38 @@ define(function(require) {
var lease = leases[j];
if (lease.VM != undefined) { //used by a VM
var nodeId = "vm"+lease.VM;
var edgeLabel = undefined;
if (lease.IP != undefined){
edgeLabel = lease.IP;
} else if (lease.IP6_GLOBAL != undefined){
edgeLabel = lease.IP6_GLOBAL;
} else if (lease.IP6_ULA != undefined){
edgeLabel = lease.IP6_ULA;
} else if (lease.IP6_LINK != undefined){
edgeLabel = lease.IP6_LINK;
}
// Skip VRouter VMs
var vrouterVMobj = _vrouterVMs[lease.VM];
if (vrouterVMobj != undefined){
if (vrouterVMobj.leases[vnetId] == undefined){
vrouterVMobj.leases[vnetId] = [];
}
vrouterVMobj.leases[vnetId].push(edgeLabel);
continue;
}
if (!nodeIndex[nodeId]){
nodeIndex[nodeId] = true;
nodes.push({
id: nodeId,
level: level+1,
label: "VM "+lease.VM,
group: "vm",
vnet: vnetId});
@ -219,19 +304,8 @@ define(function(require) {
// So it doesn't matter if we don't store the rest of VNet IDs
}
var label = undefined;
edges.push({from: vnetNodeId, to: nodeId, label: edgeLabel});
if (lease.IP != undefined){
label = lease.IP;
} else if (lease.IP6_GLOBAL != undefined){
label = lease.IP6_GLOBAL;
} else if (lease.IP6_ULA != undefined){
label = lease.IP6_ULA;
} else if (lease.IP6_LINK != undefined){
label = lease.IP6_LINK;
}
edges.push({from: vnetNodeId, to: nodeId, label: label});
} else if (lease.VROUTER != undefined){
var nodeId = "vr"+lease.VROUTER;
@ -239,6 +313,7 @@ define(function(require) {
nodeIndex[nodeId] = true;
nodes.push({
id: nodeId,
level: level+1,
label: "VR "+vr,
group: "vr"});
}
@ -268,6 +343,17 @@ define(function(require) {
}
});
// Fill VR nodes tooltips
$.each(nodes, function(i, node){
var parts = node.id.split("vr");
if (parts.length == 1){
return true;
}
node.title = _tableVR(parts[1]);
});
// create a network
var container = document.getElementById('visgraph');
@ -281,23 +367,74 @@ define(function(require) {
groups: {
vnet: {
shape: 'box',
color: '#cfcfcf'
},
reservation: {
shape: 'box',
color: '#cfcfcf'
value: 2,
scaling: {
label: {
enabled: true,
max: 40
},
max: 30
},
color: {
border: "#007a9c",
background: "#0098c3",
hover: "#007a9c",
highlight: "#007a9c"
},
font: {
color: "#fff"
}
},
vr: {
shape: 'circle',
color: '#999'
borderWidth: 2,
color: {
border: "#43AC6A",
background: "#fff",
hover: {
border: "#43AC6A",
background: "#f7f7f7"
},
highlight: {
border: "#43AC6A",
background: "#f7f7f7"
}
}
},
vm: {
shape: 'circle',
color: '#cfcfcf'
borderWidth: 2,
color: {
border: "#007a9c",
background: "#fff",
hover: {
border: "#007a9c",
background: "#f7f7f7"
},
highlight: {
border: "#007a9c",
background: "#f7f7f7"
}
}
},
vmCluster: {
shape: 'circle',
color: '#cfcfcf'
borderWidth: 2,
shapeProperties: {
borderDashes: [5,5]
},
color: {
border: "#007a9c",
background: "#f7f7f7",
hover: {
border: "#007a9c",
background: "#c6c6c6"
},
highlight: {
border: "#007a9c",
background: "#f7f7f7"
}
}
}
},
@ -305,7 +442,8 @@ define(function(require) {
font: {
align: 'middle'
},
color: '#cfcfcf'
color: '#cfcfcf',
length: 300
},
interaction: {
@ -358,13 +496,73 @@ define(function(require) {
});
}
function _toggleVMs(){
function _tableVR(vrid){
var vr = _indexedVRs[vrid];
var vms = [];
if (vr.VMS.ID != undefined){
vms = vr.VMS.ID;
if (!$.isArray(vms)){
vms = [vms];
}
}
var headers = undefined;
var trs = [];
$.each(vms, function(i, vmid){
var vm = _vrouterVMs[vmid];
if (vm == undefined){
return true; // continue
}
if (headers == undefined){
headers =
"<thead>"+
"<th>"+Locale.tr("VM")+"</th>";
$.each(vm.leases, function(vnetId,ip){
headers += "<th>"+Locale.tr("VNet")+" " +vnetId+"</th>";
});
headers += "</thead>";
}
var tr = "<tr><td>"+vmid+"</td>";
$.each(vm.leases, function(vnetId,ips){
tr += "<td>" + ips.join("</br>") + "</td>";
});
tr += "</tr>";
trs.push(tr);
});
var html =
"<table class='dataTable'>"+
headers+
"<tbody>"+
trs.join("")+
"</tbody>"+
"</table>";
return html;
}
function _collapseVMs(){
// Clusters all VMs for each vnet, except those attached to more than one vnet
$.each(_vnetList, function(i,element){
var vnet = element.VNET;
var vnetId = vnet.ID;
if (vnet.PARENT_NETWORK_ID.length > 0){
vnetId = vnet.PARENT_NETWORK_ID;
}
var clusterOptionsByData = {
joinCondition:function(childOptions) {
return (childOptions.group == "vm" &&
@ -373,6 +571,7 @@ define(function(require) {
},
clusterNodeProperties: {
id:"vmCluster"+vnetId,
level: _vnetLevel[vnetId]+1,
label: "VMs",
group: "vmCluster"
},
@ -383,6 +582,27 @@ define(function(require) {
_network.cluster(clusterOptionsByData);
});
_network.stabilize();
}
function _openVMs(){
// Opens all VMs Clusters
$.each(_vnetList, function(i,element){
var vnet = element.VNET;
var clusterId = "vmCluster"+vnet.ID;
try{
_network.openCluster(clusterId);
}catch(err){
}
});
_network.stabilize();
}
function _fit(){
_network.fit();
}
});

View File

@ -14,4 +14,4 @@
{{! limitations under the License. }}
{{! -------------------------------------------------------------------------- }}
<div id="visgraph" style="width: 100%;height: 600px;"></div>
<div id="visgraph" style="width: 100%; min-height: 400px; height: 75vh;"></div>

View File

@ -24,7 +24,7 @@ define(function(require) {
var DATATABLE_ID = "dataTableVirtualRouters";
var _dialogs = [
require('./vrouters-tab/dialogs/clone')
require('./vrouters-tab/dialogs/attach-nic')
];
var _panels = [

View File

@ -26,7 +26,6 @@ define(function(require) {
var XML_ROOT = "VROUTER";
var TAB_ID = require('./tabId');
var CREATE_DIALOG_ID = require('./form-panels/create/formPanelId');
var CLONE_DIALOG_ID = require('./dialogs/clone/dialogId');
var _commonActions = new CommonActions(OpenNebulaResource, RESOURCE, TAB_ID, XML_ROOT);
@ -41,29 +40,12 @@ define(function(require) {
"VirtualRouter.chgrp": _commonActions.multipleAction('chgrp'),
"VirtualRouter.chmod": _commonActions.singleAction('chmod'),
"VirtualRouter.rename": _commonActions.singleAction('rename'),
"VirtualRouter.attachnic": _commonActions.singleAction('attachnic'),
"VirtualRouter.detachnic": _commonActions.singleAction('detachnic'),
"VirtualRouter.update" : _commonActions.update(),
"VirtualRouter.update_template" : _commonActions.updateTemplate(),
"VirtualRouter.update_dialog" : _commonActions.checkAndShowUpdate(),
"VirtualRouter.show_to_update" : _commonActions.showUpdate(CREATE_DIALOG_ID),
"VirtualRouter.clone_dialog" : {
type: "custom",
call: function(){
Sunstone.getDialog(CLONE_DIALOG_ID).show();
}
},
"VirtualRouter.clone" : {
type: "single",
call: OpenNebulaResource.clone,
callback: function(request, response) {
Sunstone.getDialog(CLONE_DIALOG_ID).hide();
Sunstone.getDialog(CLONE_DIALOG_ID).reset();
Sunstone.runAction('VirtualRouter.refresh');
},
error: Notifier.onError,
notify: true
}
};
return _actions;

View File

@ -41,11 +41,6 @@ define(function(require) {
select: "Group",
tip: Locale.tr("Select the new group")+":"
},
"VirtualRouter.clone_dialog" : {
type: "action",
layout: "main",
text: Locale.tr("Clone")
},
"VirtualRouter.delete" : {
type: "confirm",
layout: "del",

View File

@ -20,18 +20,18 @@ define(function(require) {
*/
var BaseDialog = require('utils/dialogs/dialog');
var TemplateHTML = require('hbs!./clone/html');
var TemplateHTML = require('hbs!./attach-nic/html');
var Sunstone = require('sunstone');
var Notifier = require('utils/notifier');
var Locale = require('utils/locale');
var OpenNebulaVirtualRouter = require('opennebula/virtualrouter');
var NicsSection = require('utils/nics-section');
var WizardFields = require('utils/wizard-fields');
/*
CONSTANTS
*/
var DIALOG_ID = require('./clone/dialogId');
var TAB_ID = require('../tabId');
var DIALOG_ID = require('./attach-nic/dialogId');
var TAB_ID = require('../tabId')
/*
CONSTRUCTOR
@ -49,6 +49,7 @@ define(function(require) {
Dialog.prototype.html = _html;
Dialog.prototype.onShow = _onShow;
Dialog.prototype.setup = _setup;
Dialog.prototype.setElement = _setElement;
return Dialog;
@ -65,26 +66,23 @@ define(function(require) {
function _setup(context) {
var that = this;
context.foundation('abide', 'reflow');
context.off('invalid.fndtn.abide', '#' + DIALOG_ID + 'Form');
context.off('valid.fndtn.abide', '#' + DIALOG_ID + 'Form');
NicsSection.insert({},
$(".nicsContext", context),
{floatingIP: true, management: true,
hide_add_button:true,
click_add_button:true
});
context.on('invalid.fndtn.abide', '#' + DIALOG_ID + 'Form', function(e) {
Notifier.notifyError(Locale.tr("One or more required fields are missing or malformed."));
}).on('valid.fndtn.abide', '#' + DIALOG_ID + 'Form', function(e) {
var name = $('input', this).val();
var sel_elems = Sunstone.getDataTable(TAB_ID).elements();
$('#' + DIALOG_ID + 'Form', context).submit(function() {
var templateJSON = NicsSection.retrieve($(".nicsContext", context));
var obj = {
"NIC": templateJSON
};
if (sel_elems.length > 1){
for (var i=0; i< sel_elems.length; i++)
//use name as prefix if several items selected
Sunstone.runAction('VirtualRouter.clone',
sel_elems[i],
name + OpenNebulaVirtualRouter.getName(sel_elems[i]));
} else {
Sunstone.runAction('VirtualRouter.clone',sel_elems[0],name);
}
Sunstone.runAction('VirtualRouter.attachnic', that.element.ID, obj);
Sunstone.getDialog(DIALOG_ID).hide();
Sunstone.getDialog(DIALOG_ID).reset();
return false;
});
@ -92,22 +90,11 @@ define(function(require) {
}
function _onShow(context) {
var sel_elems = Sunstone.getDataTable(TAB_ID).elements();
//show different text depending on how many elements are selected
if (sel_elems.length > 1) {
$('.clone_one', context).hide();
$('.clone_several', context).show();
$('input',context).val('Copy of ');
} else {
$('.clone_one', context).show();
$('.clone_several', context).hide();
$('input',context).val('Copy of ' + OpenNebulaVirtualRouter.getName(sel_elems[0]));
}
$("input[name='name']",context).focus();
$("#vr_id", context).val(this.element.ID);
return false;
}
function _setElement(element) {
this.element = element;
}
});

View File

@ -14,6 +14,6 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
define(function(require){
return 'cloneVirtualRouterDialog';
define(function(require) {
return 'attachNICVirtualRouterDialog';
});

View File

@ -14,32 +14,33 @@
{{! limitations under the License. }}
{{! -------------------------------------------------------------------------- }}
<div id="{{dialogId}}" class="reveal-modal" role="dialog" data-reveal >
<div id="{{dialogId}}" class="reveal-modal large" role="dialog" data-reveal >
<div class="row">
<h3 class="subheader">{{tr "Clone Virtual Router"}}</h3>
<div class="large-12 columns">
<h3 class="subheader" id="">{{tr "Attach new nic"}}</h3>
</div>
</div>
<form data-abide="ajax" id="{{dialogId}}Form">
<div class="row">
<div class="large-12 columns">
<div class="clone_one"></div>
<div class="clone_several">
{{tr "Several virtual routers are selected, please choose a prefix to name the new copies"}}
<div class="reveal-body">
<form id="{{dialogId}}Form" action="">
<div class="row">
<div class="large-6 columns">
<label for="vr_id">{{tr "Virtual Router ID"}}</label>
<input style="border-style: inset; background-color: lightgrey" type="text" name="vr_id" id="vr_id" disabled/>
</div>
</div>
<div class="row">
<div class="large-12 columns nicsContext">
<div class="provision_network_selector">
</div>
<br>
</div>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<label class="clone_one">{{tr "Name"}}</label>
<label class="clone_several">{{tr "Prefix"}}</label>
<input required type="text" name="name"></input>
<div class="reveal-footer">
<div class="form_buttons">
<button class="button radius right success" id="attach_nic_button" type="submit" value="VirtualRouter.attachdisk">{{tr "Attach"}}</button>
</div>
</div>
</div>
<div class="form_buttons row">
<button type="submit" class="button radius right">
{{tr "Clone"}}
</button>
</div>
<a class="close-reveal-modal">&#215;</a>
</form>
<a class="close-reveal-modal">&#215;</a>
</form>
</div>
</div>

View File

@ -98,7 +98,9 @@ define(function(require) {
function _setup(context) {
var that = this;
NicsSection.insert({}, $(".nicsContext", context));
NicsSection.insert({},
$(".nicsContext", context),
{floatingIP: true, management: true});
this.templatesTable.initialize();
@ -129,7 +131,7 @@ define(function(require) {
$('#vm_name', context).val("vr-"+$(this).val()+"-%i");
});
Tips.setup();
Tips.setup(context);
return false;
}
@ -139,17 +141,9 @@ define(function(require) {
var nics = NicsSection.retrieve($(".nicsContext", context));
if (nics.length > 0) {
// TODO: Instead of a global checkbox, each vnet should have
// its own checkbox to choose floating IP or not
$.each(nics, function(){
this["FLOATING_IP"] = virtual_router_json["FLOATING_IP"];
});
virtual_router_json.NIC = nics;
}
delete virtual_router_json["FLOATING_IP"];
var tmplId = this.templatesTable.retrieveResourceTableSelect();
if (this.action == "create") {
@ -171,41 +165,36 @@ define(function(require) {
timeout: true,
success: function (request, response) {
// TODO: close form panel only on instantiate success
Sunstone.resetFormPanel(TAB_ID, FORM_PANEL_ID);
Sunstone.hideFormPanel(TAB_ID);
var extra_msg = "";
if (n_times > 1) {
extra_msg = n_times + " times";
}
Notifier.notifySubmit("Template.instantiate", tmplId, extra_msg);
var tmpl = WizardFields.retrieve($(".template_user_inputs", context));
var extra_info = {
'hold': hold
'n_vms': n_times,
'template_id': tmplId,
'vm_name': vm_name,
'hold': hold,
'template': tmpl
};
var tmpl = WizardFields.retrieve($(".template_user_inputs", context));
tmpl["VROUTER_ID"] = response.VROUTER.ID;
OpenNebulaVirtualRouter.instantiate({
data:{
id: response.VROUTER.ID,
extra_param: extra_info
},
timeout: true,
success: function(request, response){
OpenNebulaAction.clear_cache("VM");
extra_info['template'] = tmpl;
Sunstone.resetFormPanel(TAB_ID, FORM_PANEL_ID);
Sunstone.hideFormPanel(TAB_ID);
},
error: function(request, response) {
Sunstone.hideFormPanelLoading(TAB_ID);
for (var i = 0; i < n_times; i++) {
extra_info['vm_name'] = vm_name.replace(/%i/gi, i);
OpenNebulaTemplate.instantiate({
data:{
id: tmplId,
extra_param: extra_info
},
timeout: true,
success: function(request, response){
OpenNebulaAction.clear_cache("VM");
},
error: Notifier.onError
});
}
Notifier.notifyError(Locale.tr(
"Failed to create VMs. Virtual Router may need to be deleted manually."));
Notifier.onError(request, response);
}
});
},
error: function(request, response) {
Sunstone.hideFormPanelLoading(TAB_ID);

View File

@ -20,7 +20,7 @@
<div class="row">
<div class="medium-6 columns">
<label for="name" >
{{tr "Name"}}:
{{tr "Name"}}
</label>
<input type="text" wizard_field="NAME" required name="name" id="name"/>
</div>
@ -36,13 +36,18 @@
</div>
<div class="row">
<div class="medium-6 columns">
<label for="floating_ip">
<input type="checkbox" wizard_field="FLOATING_IP" value="YES" name="floating_ip" id="floating_ip" />
{{tr "Floating IPs"}}
<span class="tip">
{{tr "If checked, each Virtual Machine will have a floating IP added to its network interface."}}
</span>
<label for="keepalived_id" >
{{tr "Keepalived ID"}}
<span class="tip">{{tr "Optional. Sets keepalived configuration parameter 'virtual_router_id'"}}</span>
</label>
<input type="text" wizard_field="KEEPALIVED_ID" name="keepalived_id" id="keepalived_id"/>
</div>
<div class="medium-6 columns">
<label for="keepalived_password" >
{{tr "Keepalived password"}}
<span class="tip">{{tr "Optional. Sets keepalived configuration parameter 'authentication/auth_pass'"}}</span>
</label>
<input type="text" wizard_field="KEEPALIVED_PASSWORD" name="keepalived_password" id="keepalived_password"/>
</div>
</div>
</div>

View File

@ -21,11 +21,11 @@ define(function(require) {
var TemplateInfo = require('hbs!./info/html');
var Locale = require('utils/locale');
var Config = require('sunstone-config');
var Sunstone = require('sunstone');
var PermissionsTable = require('utils/panel/permissions-table');
var RenameTr = require('utils/panel/rename-tr');
var OpenNebulaVirtualRouter = require('opennebula/virtualrouter');
var Sunstone = require('sunstone');
var Config = require('sunstone-config');
/*
TEMPLATES
@ -42,6 +42,9 @@ define(function(require) {
var RESOURCE = "VirtualRouter";
var XML_ROOT = "VROUTER";
var ATTACH_NIC_DIALOG_ID = require('../dialogs/attach-nic/dialogId');
var CONFIRM_DIALOG_ID = require('utils/dialogs/generic-confirm/dialogId');
/*
CONSTRUCTOR
*/
@ -96,18 +99,44 @@ define(function(require) {
}
function _setup(context) {
$("a.vmid", context).on("click", function(){
// TODO: this should be checked internally in showElement,
// but it won't work because of bug #4198
if (Config.isTabEnabled("vms-tab")){
Sunstone.showElement("vms-tab", "VM.show", $(this).text());
}
});
var that = this;
RenameTr.setup(TAB_ID, RESOURCE, this.element.ID, context);
PermissionsTable.setup(TAB_ID, RESOURCE, this.element, context);
if (Config.isTabActionEnabled(TAB_ID, "VirtualRouter.attachnic")) {
context.off('click', '.attach_nic');
context.on('click', '.attach_nic', function() {
var dialog = Sunstone.getDialog(ATTACH_NIC_DIALOG_ID);
dialog.setElement(that.element);
dialog.show();
return false;
});
}
if (Config.isTabActionEnabled(TAB_ID, "VirtualRouter.detachnic")) {
context.off('click', '.detachnic');
context.on('click', '.detachnic', function() {
var nic_id = $(".nic_id", $(this).parents('tr')).attr('nic_id');
Sunstone.getDialog(CONFIRM_DIALOG_ID).setParams({
//header :
body : Locale.tr("This will detach the nic inmediately"),
//question :
submit : function(){
Sunstone.runAction('VirtualRouter.detachnic', that.element.ID, nic_id);
return false;
}
});
Sunstone.getDialog(CONFIRM_DIALOG_ID).reset();
Sunstone.getDialog(CONFIRM_DIALOG_ID).show();
return false;
});
}
// TODO: simplify interface?
var strippedTemplate = $.extend({}, this.element.TEMPLATE);
delete strippedTemplate["NIC"];

View File

@ -36,23 +36,42 @@
</div>
</div>
<div class="row">
<div class="large-9 columns">
<div class="large-12 columns">
<table class="dataTable">
<thead>
<tr>
<th>{{tr "ID"}}</th>
<th>{{tr "Network"}}</th>
<th>{{tr "Floating IP"}}</th>
<th>{{tr "Floating IPv6 ULA"}}</th>
<th>{{tr "Floating IPv6 Global"}}</th>
<th>{{tr "Management Interface"}}</th>
<th>{{tr "Actions"}}</th>
<th>
{{#isTabActionEnabled "vrouters-tab" "VirtualRouter.attachnic"}}
<button class="attach_nic button tiny success right radius" >
{{tr "Attach nic"}}
</button>
{{/isTabActionEnabled}}
</th>
</tr>
</thead>
<tbody>
{{#each nics}}
<tr>
<td class="nic_id" nic_id="{{NIC_ID}}">{{NIC_ID}}</td>
<td>{{NETWORK}}</td>
<td>{{valOrDefault IP "--"}}</td>
<td>{{valOrDefault IP6_ULA "--"}}</td>
<td>{{valOrDefault IP6_GLOBAL "--"}}</td>
<td>{{valOrDefault VROUTER_MANAGEMENT "--"}}</td>
<td>
{{#isTabActionEnabled "vrouters-tab" "VirtualRouter.detachnic"}}
<a href="VirtualRouter.detachnic" class="detachnic" ><i class="fa fa-times"/>
{{tr "Detach"}}
</a>
{{/isTabActionEnabled}}
</td>
</tr>
{{/each}}
</tbody>

View File

@ -16,6 +16,7 @@
define(function(require) {
var Locale = require('utils/locale');
var Tips = require('utils/tips');
var Notifier = require('utils/notifier');
var OpenNebula = require('opennebula');
@ -29,7 +30,23 @@ define(function(require) {
'generate_provision_network_table': _generate_provision_network_table
}
function _insert(template_json, context) {
/**
* Inserts the section into the context container
* @param {Object} template_json VM Template
* @param {object} context JQuery selector
* @param {object} options Options
* - hide_add_button {bool}
* - click_add_button {bool}
* - floatingIP {bool}: true to show the
* floating IP checkbox
* - management {bool}: true to show the
* management checkbox
*/
function _insert(template_json, context, options) {
if (options == undefined){
options = {};
}
try {
if (template_json.VMTEMPLATE.TEMPLATE.SUNSTONE_NETWORK_SELECT != "NO") {
var template_nic = template_json.VMTEMPLATE.TEMPLATE.NIC
@ -40,17 +57,20 @@ define(function(require) {
nics = [template_nic]
_generate_provision_network_accordion(
$(".provision_network_selector", context));
$(".provision_network_selector", context), options);
$.each(nics, function(index, nic) {
var opt = $.extend({}, options);
opt.nic = nic;
_generate_provision_network_table(
$(".provision_nic_accordion", context),
nic);
opt);
})
}
} catch(err) {
_generate_provision_network_accordion(
$(".provision_network_selector", context));
$(".provision_network_selector", context), options);
}
}
@ -69,6 +89,20 @@ define(function(require) {
}
if (nic) {
if ($("input.floating_ip", $(this)).prop("checked")){
nic["FLOATING_IP"] = "YES";
var ip4 = $("input.manual_ip4", $(this)).val();
if (ip4 != ""){
nic["IP"] = ip4;
}
}
if ($("input.management", $(this)).prop("checked")){
nic["VROUTER_MANAGEMENT"] = "YES";
}
nics.push(nic);
}
});
@ -76,14 +110,28 @@ define(function(require) {
return nics
}
function _generate_provision_network_table(context, nic, vnet_attr) {
/**
* @param {object} context JQuery selector
* @param {object} options Options
* - nic {object}
* - vnet_attr {object}
* - floatingIP {bool}: true to show the
* floating IP checkbox
* - management {bool}: true to show the
* management checkbox
*/
function _generate_provision_network_table(context, options) {
context.off();
var nic_span;
if (nic) {
nic_span = '<span class="selected_network" template_nic=\'' + JSON.stringify(nic) + '\'>' +
if (options == undefined){
options = {};
}
if (options.nic) {
nic_span = '<span class="selected_network" template_nic=\'' + JSON.stringify(options.nic) + '\'>' +
'<span style="color: #999; font-size: 14px">' + Locale.tr("INTERFACE") + "</span>&emsp;&emsp;" +
'<span style="color: #777;">' + (nic.NETWORK || nic.NETWORK_ID) + "</span>" +
'<span style="color: #777;">' + (options.nic.NETWORK || options.nic.NETWORK_ID) + "</span>" +
'</span>' +
'<span class="has-tip right provision_remove_nic" style="cursor: pointer;">' +
'<i class="fa fa-times"/>' +
@ -91,9 +139,9 @@ define(function(require) {
'<span class="has-tip right" style="cursor: pointer; margin-right:10px">' +
'<i class="fa fa-pencil"/>' +
'</span>';
} else if (vnet_attr) {
nic_span = '<span style="color: #777; font-size: 16px">' + vnet_attr.description + "</span><br>" +
'<span class="selected_network only-not-active" attr_name=\'' + vnet_attr.name + '\' style="color: #777;">' +
} else if (options.vnet_attr) {
nic_span = '<span style="color: #777; font-size: 16px">' + options.vnet_attr.description + "</span><br>" +
'<span class="selected_network only-not-active" attr_name=\'' + options.vnet_attr.name + '\' style="color: #777;">' +
'<span style="color: #999; font-size: 14px">' + Locale.tr("INTERFACE") + "</span>&emsp;&emsp;" +
'<span class="button radius small">' + Locale.tr("Select a Network") + "</span>" +
'</span>' +
@ -212,14 +260,60 @@ define(function(require) {
})
dd_context.on("click", ".provision-pricing-table.more-than-one" , function() {
$(".selected_network", dd_context).html(
'<span style="color: #999; font-size: 14px">' + Locale.tr("INTERFACE") + "</span>&emsp;&emsp;" +
'<span style="color: #777;">' + $(this).attr("opennebula_name") + "</span>");
var html =
'<span style="color: #999; font-size: 14px">' + Locale.tr("INTERFACE") + "</span>&emsp;&emsp;" +
'<span style="color: #777;">' + $(this).attr("opennebula_name") + "</span>";
if (options.floatingIP){
html +=
'<div class="row noclick">' +
'<div class="small-12 columns">' +
'<label class="inline" style="color: #777; font-size: 16px">' +
'<input type="checkbox" class="floating_ip" />' +
Locale.tr("Floating IP") + " " +
'<span class="tip">' +
Locale.tr("If checked, each Virtual Machine will have a floating IP added to its network interface.") +
'</span>' +
'</label>' +
'</div>' +
'</div>' +
'<div class="row noclick">' +
'<div class="small-5 columns">' +
'<label class="right inline" style="color: #777; font-size: 16px">' +
Locale.tr("Force IPv4:") + " " +
'<span class="tip">' +
Locale.tr("Optionally, you can force the IP assigned to the floating IP.") +
'</span>' +
'</label>' +
'</div>' +
'<div class="small-7 columns">' +
'<input type="text" class="manual_ip4" />' +
'</div>' +
'</div>';
}
if (options.management){
html +=
'<div class="noclick">' +
'<label style="color: #777; font-size: 16px">' +
'<input type="checkbox" class="management" />' +
Locale.tr("Management Interface") + " " +
'<span class="tip">' +
Locale.tr("If checked, this network interface will be a Virtual Router management interface. Traffic will not be forwarded.") +
'</span>' +
'</label>' +
'</div>';
}
$(".selected_network", dd_context).html(html);
$(".selected_network", dd_context).attr("opennebula_id", $(this).attr("opennebula_id"))
$(".selected_network", dd_context).removeAttr("template_nic")
Tips.setup($(".selected_network", dd_context));
$('a', dd_context).first().trigger("click");
$("input.floating_ip", dd_context).change();
})
dd_context.on("click", ".provision_remove_nic" , function() {
@ -227,14 +321,32 @@ define(function(require) {
return false;
});
if (!nic && !vnet_attr) {
dd_context.on("click", ".noclick" , function(event) {
event.stopPropagation();
});
dd_context.on("change", "input.floating_ip" , function() {
$(".manual_ip4", dd_context).prop("disabled", !$(this).is(":checked"));
});
if (!options.nic && !options.vnet_attr) {
$('a', dd_context).trigger("click");
}
update_provision_networks_datatable(provision_networks_datatable);
}
function _generate_provision_network_accordion(context, hide_add_button) {
/**
* @param {object} context JQuery selector
* @param {object} options Options
* - hide_add_button {bool}
* - click_add_button {bool}
* - floatingIP {bool}: true to show the
* floating IP checkbox
* - management {bool}: true to show the
* management checkbox
*/
function _generate_provision_network_accordion(context, options) {
context.off();
context.html(
'<br>' +
@ -254,7 +366,7 @@ define(function(require) {
'<dl class="accordion provision_nic_accordion" data-accordion="provision_accordion_' + provision_nic_accordion_id + '">' +
'</dl>' +
'<br>' +
'<a class="button radius secondary provision_add_network_interface" style="width:inherit; padding: 1rem; color: #555; ' + (hide_add_button ? 'display:none;' : '') + '">' +
'<a class="button radius secondary provision_add_network_interface" style="width:inherit; padding: 1rem; color: #555; ' + (options.hide_add_button ? 'display:none;' : '') + '">' +
Locale.tr("Add another Network Interface") +
'</a>' +
'</div>' +
@ -264,8 +376,12 @@ define(function(require) {
provision_nic_accordion_id += 1;
$(".provision_add_network_interface", context).on("click", function() {
_generate_provision_network_table($(".accordion", context));
})
_generate_provision_network_table($(".accordion", context), options);
});
if (options.click_add_button == true){
$(".provision_add_network_interface", context).click();
}
$(document).foundation();
}

View File

@ -23,7 +23,7 @@
"almond": "0.3.1",
"datatables": "1.10.7",
"foundation": "5.5.2",
"vis": "4.10.0"
"vis": "4.12.0"
},
"version": "4.14",
"authors": [

View File

@ -1,5 +1,6 @@
@import "../bower_components/fontawesome/css/font-awesome.min.css";
@import "../bower_components/jgrowl/jquery.jgrowl.min.css";
@import "../bower_components/vis/dist/vis.min.css";
@import "settings";
@import "foundation";
@ -1325,4 +1326,14 @@ hr {
.custom_tags td {
vertical-align: top;
}
}
// Overwrite vis.js tooltip css
div.vis-network-tooltip {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
font-stretch: condensed;
background-color: #ffffff;
}

View File

@ -389,6 +389,87 @@ int Template::get(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool Template::get(
const string& name,
VectorAttribute*& vatt)
{
vector<Attribute *> array_attr;
int num;
num = get(name, array_attr);
if ( num < 1 )
{
vatt = 0;
return false;
}
vatt = dynamic_cast<VectorAttribute *>(array_attr[0]);
return ( vatt != 0 );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Template::get(
const string& name,
vector<const VectorAttribute*>& values) const
{
multimap<string, Attribute *>::const_iterator i;
pair<multimap<string, Attribute *>::const_iterator,
multimap<string, Attribute *>::const_iterator> index;
const VectorAttribute * vatt;
index = attributes.equal_range(name);
for ( i = index.first ; i != index.second ; i++ )
{
vatt = dynamic_cast<const VectorAttribute * >(i->second);
if ( vatt == 0 )
{
continue;
}
values.push_back(vatt);
}
return values.size();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Template::get(
const string& name,
vector<VectorAttribute*>& values)
{
multimap<string, Attribute *>::iterator i;
pair<multimap<string, Attribute *>::iterator,
multimap<string, Attribute *>::iterator> index;
VectorAttribute * vatt;
index = attributes.equal_range(name);
for ( i = index.first ; i != index.second ; i++ )
{
vatt = dynamic_cast<VectorAttribute * >(i->second);
if ( vatt == 0 )
{
continue;
}
values.push_back(vatt);
}
return values.size();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Template::get(
const string& name,
string& value) const

View File

@ -607,6 +607,48 @@ static string prolog_os_transfer_commands(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int TransferManager::prolog_context_command(
VirtualMachine * vm,
const string& token_password,
string& vm_tm_mad,
ostream& xfr)
{
string files;
int context_result;
int disk_id;
context_result = vm->generate_context(files, disk_id, token_password);
if ( context_result == -1 )
{
return -1;
}
if ( context_result )
{
//CONTEXT tm_mad files hostname:remote_system_dir/disk.i vmid dsid(=0)
xfr << "CONTEXT "
<< vm_tm_mad << " "
<< vm->get_context_file() << " ";
if (!files.empty())
{
xfr << files << " ";
}
xfr << vm->get_hostname() << ":"
<< vm->get_remote_system_dir() << "/disk." << disk_id << " "
<< vm->get_oid() << " "
<< vm->get_ds_id()
<< endl;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::prolog_action(int vid)
{
ofstream xfr;
@ -628,9 +670,6 @@ void TransferManager::prolog_action(int vid)
vector<const Attribute *> attrs;
int num;
int disk_id;
int context_result;
string token_password;
@ -771,32 +810,16 @@ void TransferManager::prolog_action(int vid)
// Generate context file
// -------------------------------------------------------------------------
context_result = vm->generate_context(files, disk_id, token_password);
rc = prolog_context_command( vm,
token_password,
vm_tm_mad,
xfr);
if ( context_result == -1 )
if ( rc == -1 )
{
goto error_context;
}
if ( context_result )
{
//CONTEXT tm_mad files hostname:remote_system_dir/disk.i vmid dsid(=0)
xfr << "CONTEXT "
<< vm_tm_mad << " "
<< vm->get_context_file() << " ";
if (!files.empty())
{
xfr << files << " ";
}
xfr << vm->get_hostname() << ":"
<< vm->get_remote_system_dir() << "/disk." << disk_id << " "
<< vm->get_oid() << " "
<< vm->get_ds_id()
<< endl;
}
xfr.close();
tm_md->transfer(vid,xfr_name);
@ -986,9 +1009,11 @@ void TransferManager::prolog_resume_action(int vid)
const VectorAttribute * disk;
string tm_mad;
string vm_tm_mad;
string token_password;
int ds_id;
int disk_id;
int rc;
vector<const Attribute *> attrs;
int num;
@ -1008,6 +1033,24 @@ void TransferManager::prolog_resume_action(int vid)
return;
}
int uid = vm->get_created_by_uid();
vm->unlock();
User * user = Nebula::instance().get_upool()->get(uid, true);
if (user != 0)
{
user->get_template_attribute("TOKEN_PASSWORD", token_password);
user->unlock();
}
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
@ -1080,6 +1123,20 @@ void TransferManager::prolog_resume_action(int vid)
<< vm->get_oid() << " "
<< vm->get_ds_id() << endl;
// -------------------------------------------------------------------------
// Generate context file
// -------------------------------------------------------------------------
rc = prolog_context_command( vm,
token_password,
vm_tm_mad,
xfr);
if ( rc == -1 )
{
goto error_context;
}
xfr.close();
tm_md->transfer(vid,xfr_name);
@ -1102,6 +1159,12 @@ error_file:
os << "prolog_resume, could not open file: " << xfr_name;
goto error_common;
error_context:
os << "prolog_resume, could not write context file for VM " << vid;
xfr.close();
goto error_common;
error_common:
(nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid);
vm->log("TM", Log::ERROR, os);

View File

@ -27,13 +27,15 @@ const int QuotaNetwork::NUM_NET_METRICS = 1;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool QuotaNetwork::check(Template * tmpl, Quotas& default_quotas, string& error)
bool QuotaNetwork::check(PoolObjectSQL::ObjectType otype, Template * tmpl,
Quotas& default_quotas, string& error)
{
vector<Attribute*> nics;
VectorAttribute * nic;
string net_id;
int num;
bool uses_lease;
map<string, float> net_request;
@ -52,7 +54,14 @@ bool QuotaNetwork::check(Template * tmpl, Quotas& default_quotas, string& error)
net_id = nic->vector_value("NETWORK_ID");
if ( !net_id.empty() )
uses_lease = true;
if ( otype == PoolObjectSQL::VROUTER )
{
nic->vector_value("FLOATING_IP", uses_lease);
}
if ( !net_id.empty() && uses_lease )
{
if ( !check_quota(net_id, net_request, default_quotas, error) )
{
@ -67,7 +76,7 @@ bool QuotaNetwork::check(Template * tmpl, Quotas& default_quotas, string& error)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void QuotaNetwork::del(Template * tmpl)
void QuotaNetwork::del(PoolObjectSQL::ObjectType otype, Template * tmpl)
{
vector<Attribute*> nics;
@ -75,6 +84,7 @@ void QuotaNetwork::del(Template * tmpl)
string net_id;
int num;
bool uses_lease;
map<string, float> net_request;
@ -93,7 +103,17 @@ void QuotaNetwork::del(Template * tmpl)
net_id = nic->vector_value("NETWORK_ID");
del_quota(net_id, net_request);
uses_lease = true;
if ( otype == PoolObjectSQL::VROUTER )
{
nic->vector_value("FLOATING_IP", uses_lease);
}
if (uses_lease)
{
del_quota(net_id, net_request);
}
}
}

View File

@ -150,7 +150,7 @@ void Quotas::quota_del(QuotaType type, Template *tmpl)
break;
case NETWORK:
network_quota.del(tmpl);
network_quota.del(PoolObjectSQL::VM, tmpl);
break;
case IMAGE:
@ -162,10 +162,14 @@ void Quotas::quota_del(QuotaType type, Template *tmpl)
break;
case VIRTUALMACHINE:
network_quota.del(tmpl);
network_quota.del(PoolObjectSQL::VM, tmpl);
vm_quota.del(tmpl);
image_quota.del(tmpl);
break;
case VIRTUALROUTER:
network_quota.del(PoolObjectSQL::VROUTER, tmpl);
break;
}
}
@ -183,7 +187,7 @@ bool Quotas::quota_check(QuotaType type,
return datastore_quota.check(tmpl, default_quotas, error_str);
case NETWORK:
return network_quota.check(tmpl, default_quotas, error_str);
return network_quota.check(PoolObjectSQL::VM, tmpl, default_quotas, error_str);
case IMAGE:
return image_quota.check(tmpl, default_quotas, error_str);
@ -192,25 +196,30 @@ bool Quotas::quota_check(QuotaType type,
return vm_quota.check(tmpl, default_quotas, error_str);
case VIRTUALMACHINE:
if ( network_quota.check(tmpl, default_quotas, error_str) == false )
if ( network_quota.check(PoolObjectSQL::VM,
tmpl, default_quotas, error_str) == false )
{
return false;
}
if ( vm_quota.check(tmpl, default_quotas, error_str) == false )
{
network_quota.del(tmpl);
network_quota.del(PoolObjectSQL::VM, tmpl);
return false;
}
if ( image_quota.check(tmpl, default_quotas, error_str) == false )
{
network_quota.del(tmpl);
network_quota.del(PoolObjectSQL::VM, tmpl);
vm_quota.del(tmpl);
return false;
}
return true;
case VIRTUALROUTER:
return network_quota.check(PoolObjectSQL::VROUTER,
tmpl, default_quotas, error_str);
}
return false;
@ -231,6 +240,7 @@ bool Quotas::quota_update(QuotaType type,
case NETWORK:
case IMAGE:
case VIRTUALMACHINE:
case VIRTUALROUTER:
error_str = "Cannot update quota. Not implemented";
return false;

View File

@ -144,15 +144,24 @@ const char * VirtualMachine::NETWORK_CONTEXT[][2] = {
{"GATEWAY", "GATEWAY"},
{"DNS", "DNS"},
{"SEARCH_DOMAIN", "SEARCH_DOMAIN"},
{"MTU", "GUEST_MTU"}};
const int VirtualMachine::NUM_NETWORK_CONTEXT = 8;
{"MTU", "GUEST_MTU"},
{"VROUTER_IP", "VROUTER_IP"},
{"VROUTER_MANAGEMENT", "VROUTER_MANAGEMENT"}};
const int VirtualMachine::NUM_NETWORK_CONTEXT = 10;
const char* VirtualMachine::NETWORK6_CONTEXT[][2] = {
{"IP6", "IP6_GLOBAL"},
{"GATEWAY6", "GATEWAY6"},
{"CONTEXT_FORCE_IPV4", "CONTEXT_FORCE_IPV4"}};
{"CONTEXT_FORCE_IPV4", "CONTEXT_FORCE_IPV4"},
{"VROUTER_IP6", "VROUTER_IP6_GLOBAL"}};
const int VirtualMachine::NUM_NETWORK6_CONTEXT = 3;
const int VirtualMachine::NUM_NETWORK6_CONTEXT = 4;
const char* VirtualMachine::VROUTER_ATTRIBUTES[] = {
"VROUTER_ID",
"VROUTER_KEEPALIVED_ID",
"VROUTER_KEEPALIVED_PASSWORD"};
const int VirtualMachine::NUM_VROUTER_ATTRIBUTES = 3;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -842,14 +851,17 @@ int VirtualMachine::parse_vrouter(string& error_str)
{
string st;
user_obj_template->get("VROUTER_ID", st);
if (!st.empty())
for (int i = 0; i < NUM_VROUTER_ATTRIBUTES; i++)
{
obj_template->replace("VROUTER_ID", st);
}
user_obj_template->get(VROUTER_ATTRIBUTES[i], st);
user_obj_template->erase("VROUTER_ID");
if (!st.empty())
{
obj_template->replace(VROUTER_ATTRIBUTES[i], st);
}
user_obj_template->erase(VROUTER_ATTRIBUTES[i]);
}
return 0;
}
@ -892,6 +904,23 @@ static void parse_context_network(const char* vars[][2], int num_vars,
/* -------------------------------------------------------------------------- */
static void clear_context_network(const char* vars[][2], int num_vars,
VectorAttribute * context, int nic_id)
{
ostringstream att_name;
for (int i=0; i < num_vars; i++)
{
att_name.str("");
att_name << "ETH" << nic_id << "_" << vars[i][0];
context->remove(att_name.str());
}
}
/* -------------------------------------------------------------------------- */
int VirtualMachine::parse_context(string& error_str)
{
int rc, num;
@ -904,6 +933,7 @@ int VirtualMachine::parse_context(string& error_str)
string parsed;
string files_ds;
string files_ds_parsed;
string st;
ostringstream oss_parsed;
@ -1095,6 +1125,20 @@ int VirtualMachine::parse_context(string& error_str)
add_template_attribute("CREATED_BY", uid);
}
// -------------------------------------------------------------------------
// Virtual Router attributes
// -------------------------------------------------------------------------
for (int i = 0; i < NUM_VROUTER_ATTRIBUTES; i++)
{
obj_template->get(VROUTER_ATTRIBUTES[i], st);
if (!st.empty())
{
context_parsed->replace(VROUTER_ATTRIBUTES[i], st);
}
}
return rc;
error_cleanup:
@ -1109,6 +1153,51 @@ error_cleanup:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::reparse_context()
{
int rc;
VectorAttribute * context;
VectorAttribute * context_parsed;
string * str;
string parsed;
string error_str;
obj_template->get("CONTEXT", context);
// -------------------------------------------------------------------------
// Parse CONTEXT variables & free vector attributes
// -------------------------------------------------------------------------
str = context->marshall();
if (str == 0)
{
return -1;
}
rc = parse_template_attribute(*str, parsed, error_str);
delete str;
if (rc != 0)
{
return -1;
}
context_parsed = new VectorAttribute("CONTEXT");
context_parsed->unmarshall(parsed);
obj_template->erase("CONTEXT");
obj_template->set(context_parsed);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::parse_pci(string& error_str)
{
VectorAttribute * pci;
@ -2592,7 +2681,8 @@ int VirtualMachine::set_up_attach_nic(
set<int> nic_sgs;
int rc = vnpool->nic_attribute(new_nic, max_nic_id+1, uid, vm_id, error_str);
int rc = vnpool->nic_attribute(PoolObjectSQL::VM,
new_nic, max_nic_id+1, uid, vm_id, error_str);
if ( rc == -1 ) //-2 is not using a pre-defined network
{
@ -2614,7 +2704,7 @@ int VirtualMachine::set_up_attach_nic(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::clear_attach_nic()
VectorAttribute* VirtualMachine::get_attach_nic()
{
int num_nics;
vector<Attribute *> nics;
@ -2633,34 +2723,7 @@ void VirtualMachine::clear_attach_nic()
if ( nic->vector_value("ATTACH") == "YES" )
{
nic->remove("ATTACH");
return;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * VirtualMachine::delete_attach_nic()
{
vector<Attribute *> nics;
VectorAttribute * nic;
int num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
if ( nic->vector_value("ATTACH") == "YES" )
{
return static_cast<VectorAttribute * >(obj_template->remove(nic));
return nic;
}
}
@ -2670,10 +2733,116 @@ VectorAttribute * VirtualMachine::delete_attach_nic()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::attach_nic_success()
{
VectorAttribute * nic = get_attach_nic();
if (nic != 0)
{
nic->remove("ATTACH");
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * VirtualMachine::attach_nic_failure()
{
VectorAttribute * nic;
VectorAttribute * context = 0;
int nic_id;
nic = get_attach_nic();
if (nic == 0)
{
return 0;
}
obj_template->remove(nic);
obj_template->get("CONTEXT", context);
if (context != 0)
{
nic->vector_value("NIC_ID", nic_id);
clear_context_network(NETWORK_CONTEXT, NUM_NETWORK_CONTEXT, context, nic_id);
clear_context_network(NETWORK6_CONTEXT, NUM_NETWORK6_CONTEXT, context, nic_id);
}
return nic;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::detach_nic_failure()
{
VectorAttribute * nic;
VectorAttribute * context = 0;
bool net_context;
nic = get_attach_nic();
if (nic == 0)
{
return;
}
nic->remove("ATTACH");
obj_template->get("CONTEXT", context);
if (context == 0)
{
return;
}
context->vector_value("NETWORK", net_context);
if (net_context)
{
parse_context_network(NETWORK_CONTEXT, NUM_NETWORK_CONTEXT,
context, nic);
if (!nic->vector_value("IP6_GLOBAL").empty())
{
parse_context_network(NETWORK6_CONTEXT, NUM_NETWORK6_CONTEXT,
context, nic);
}
reparse_context();
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * VirtualMachine::detach_nic_success()
{
VectorAttribute * nic = get_attach_nic();
if (nic == 0)
{
return 0;
}
obj_template->remove(nic);
return nic;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::set_attach_nic(
VectorAttribute * new_nic,
vector<VectorAttribute*> &rules)
{
VectorAttribute * context = 0;
bool net_context;
vector<VectorAttribute*>::iterator it;
new_nic->replace("ATTACH", "YES");
@ -2684,22 +2853,48 @@ void VirtualMachine::set_attach_nic(
{
obj_template->set(*it);
}
obj_template->get("CONTEXT", context);
if (context == 0)
{
return;
}
context->vector_value("NETWORK", net_context);
if (net_context)
{
parse_context_network(NETWORK_CONTEXT, NUM_NETWORK_CONTEXT,
context, new_nic);
if (!new_nic->vector_value("IP6_GLOBAL").empty())
{
parse_context_network(NETWORK6_CONTEXT, NUM_NETWORK6_CONTEXT,
context, new_nic);
}
reparse_context();
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::set_attach_nic(int nic_id)
int VirtualMachine::set_detach_nic(int nic_id)
{
int num_nics;
int n_id;
vector<Attribute *> nics;
VectorAttribute * nic;
VectorAttribute * context = 0;
bool found = false;
num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
for(int i=0; !found && i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
@ -2713,11 +2908,27 @@ int VirtualMachine::set_attach_nic(int nic_id)
if ( n_id == nic_id )
{
nic->replace("ATTACH", "YES");
return 0;
found = true;
}
}
return -1;
if (!found)
{
return -1;
}
obj_template->get("CONTEXT", context);
if (context != 0)
{
clear_context_network(NETWORK_CONTEXT, NUM_NETWORK_CONTEXT,
context, nic_id);
clear_context_network(NETWORK6_CONTEXT, NUM_NETWORK6_CONTEXT,
context, nic_id);
}
return 0;
}
/* -------------------------------------------------------------------------- */
@ -2992,7 +3203,7 @@ int VirtualMachine::get_network_leases(string& estr)
merge_nic_defaults(nic);
rc = vnpool->nic_attribute(nic, i, uid, oid, estr);
rc = vnpool->nic_attribute(PoolObjectSQL::VM, nic, i, uid, oid, estr);
if (rc == -1)
{
@ -3261,8 +3472,27 @@ bool VirtualMachine::is_vrouter()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool VirtualMachine::is_vrouter_action_supported(History::VMAction action)
{
return (action == History::MIGRATE_ACTION ||
action == History::LIVE_MIGRATE_ACTION ||
action == History::HOLD_ACTION ||
action == History::RELEASE_ACTION ||
action == History::RESUME_ACTION ||
action == History::BOOT_ACTION ||
action == History::REBOOT_ACTION ||
action == History::REBOOT_HARD_ACTION ||
action == History::RESCHED_ACTION ||
action == History::UNRESCHED_ACTION ||
action == History::DISK_SNAPSHOT_CREATE_ACTION ||
action == History::DISK_SNAPSHOT_DELETE_ACTION);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::generate_context(string &files, int &disk_id,
string& token_password)
const string& token_password)
{
ofstream file;
string files_ds;
@ -3397,6 +3627,22 @@ int VirtualMachine::generate_context(string &files, int &disk_id,
return 1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::get_created_by_uid() const
{
int created_by_uid;
if (obj_template->get("CREATED_BY", created_by_uid))
{
return created_by_uid;
}
return get_uid();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -3433,6 +3679,65 @@ const VectorAttribute* VirtualMachine::get_disk(int disk_id) const
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const VectorAttribute* VirtualMachine::get_context_disk() const
{
vector<const Attribute *> array_context;
const VectorAttribute * context;
int num;
num = obj_template->get("CONTEXT", array_context);
if ( num != 1 )
{
return 0;
}
context = dynamic_cast<const VectorAttribute *>(array_context[0]);
if ( context == 0 )
{
return 0;
}
return context;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const VectorAttribute* VirtualMachine::get_nic(int nic_id) const
{
int num_nics;
int tnic_id;
vector<const Attribute *> nics;
const VectorAttribute * nic;
num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<const VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
nic->vector_value("NIC_ID", tnic_id);
if ( tnic_id == nic_id )
{
return nic;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::set_saveas_disk(int disk_id, int snap_id, int &iid,
long long &size, string& err_str)
{
@ -3686,7 +3991,7 @@ void VirtualMachine::set_auth_request(int uid,
continue;
}
vnpool->authorize_nic(vector,uid,&ar);
vnpool->authorize_nic(PoolObjectSQL::VM, vector, uid, &ar);
get_security_groups(vector, sgroups);

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