Newer
Older
#!/usr/bin/env python
#coding=utf8
import inspect
import logging
from sjrpc.utils import RpcHandler, pure
from conf import CCConf
from exceptions import AlreadyRegistered, AuthenticationError
def listed(func):
func.__listed__ = True
return func
class CCHandler(RpcHandler):
'''
Base class for handlers of CloudControl server.
'''
def __init__(self, server):
self._server = server
def __getitem__(self, name):
if name.startswith('_'):
# Filter the private members access:
raise KeyError('Remote name %s is private.' % repr(name))
else:
logging.debug('Called %s.%s' % (self.__class__.__name__, name))
return super(CCHandler, self).__getitem__(name)
@pure
def list_commands(self):
cmd_list = []
for attr in dir(self):
attr = getattr(self, attr, None)
if getattr(attr, '__listed__', False):
cmd = {}
cmd['name'] = attr.__name__
doc = inspect.getdoc(attr)
if doc:
cmd['description'] = inspect.cleandoc(doc)
class OnlineCCHandler(CCHandler):
def on_disconnect(self, connection):
self._server.unregister(connection)
class HypervisorHandler(OnlineCCHandler):
class ClientHandler(OnlineCCHandler):
@pure
@listed
def list(self, query):
'''
List all objects registered on this instance.
'''
logging.debug('Executed list function with query %s' % query)
return self._server.list(query)
Antoine Millet
committed
def _vm_action(self, query, method, *args, **kwargs):
vms = self._server.list(query + '$vm$role')
hypervisors = list(self._server.iter_connected_role('hypervisor'))
Antoine Millet
committed
for hv in hypervisors:
vm_to_start = []
for vm in vms:
if vm['role'] != 'vm':
pass
elif vm['id'].split('.')[0] == hv.login:
vm_to_start.append(vm['vm'])
Antoine Millet
committed
if vm_to_start:
hv.connection.call(method, vm_to_start, *args, **kwargs)
@pure
@listed
def start(self, query):
self._vm_action(query, 'start_vm')
@pure
@listed
def stop(self, query, force=False):
self._vm_action(query, 'stop_vm', force)
Antoine Millet
committed
@pure
@listed
def destroy(self, query):
self.stop(query, force=True)
Antoine Millet
committed
@pure
@listed
Antoine Millet
committed
self._vm_action(query, 'suspend_vm')
@pure
@listed
def resume(self, query):
self._vm_action(query, 'resume_vm')
def passwd(self, login, password, method='ssha'):
'''
Define a new password for specified user.
'''
self._server.conf.set_password(login, password, method)
@pure
@listed
'''
Create a new account with specified login.
'''
self._server.conf.create_account(login, role, password)
@pure
@listed
def addtag(self, login, tag_name, tag_value):
'''
Add a tag to the account with specified login.
'''
self._server.conf.add_tag(login, tag_name, tag_value)
@pure
@listed
def deltag(self, login, tag):
'''
Remove a tag of the account with specified login.
'''
self._server.conf.remove_tag(login, tag)
@pure
@listed
def tags(self, login):
'''
Return all static tags attached to the specified login.
'''
return self._server.conf.show(login)['tags']
@pure
@listed
'''
Delete the account with specified login.
'''
self._server.conf.remove_account(login)
@pure
def proxy_client(self, login, command, *args, **kwargs):
client = self._server.get_connection(login)
return client.connection.call(command, *args, **kwargs)
class WelcomeHandler(CCHandler):
'''
Default handler used on client connections of the server.
:cvar ROLES: role name/handler mapping
'''
ROLES = {
'client': ClientHandler,
'hypervisor': HypervisorHandler,
}
@listed
def authentify(self, connection, login, password):
'''
Authenticate the client.
'''
try:
role = self._server.conf.authentify(login, password)
except CCConf.UnknownAccount:
raise AuthenticationError('Authentication failure (Unknown login)')
if role is None:
logging.info('New authentication from %s: failure' % login)
raise AuthenticationError('Authentication failure')
# If authentication is a success, try to register the client:
try:
self._server.register(login, role, connection)
except AlreadyRegistered:
raise AuthenticationError('Authentication failure '
'(already connected)')
connection.set_handler(WelcomeHandler.ROLES.get(role)(self._server))
logging.info('New authentication from %s: success' % login)
return role