Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python
#coding=utf8
import inspect
import logging
from sjrpc.utils import RpcHandler, pure
from tql import TqlQuery
def listed(func):
func.__listed__ = True
return func
class CCHandler(RpcHandler):
'''
Base class for handlers of CloudControl server.
:cvar role_name: the name of the role binded to the handler
:type role_name: str or None is not applicable
'''
role_name = None
def __init__(self, server):
self._server = server
def __getitem__(self, name):
logging.debug('Called method %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__
cmd['description'] = inspect.cleandoc(inspect.getdoc(attr))
cmd_list.append(cmd)
return cmd_list
class HypervisorHandler(CCHandler):
'''
Handler binded to 'node' role.
'''
role_name = 'hypervisor'
class ClientHandler(CCHandler):
'''
Handler binded to 'cli' role.
'''
role_name = 'client'
@pure
@listed
def list_vm(self):
'''
List all VMs on nodes.
'''
found_vm = []
async_ids = set()
# Send the asynchronous request to all nodes:
for node in self._server.iterrole('node'):
async_ids.add(node.async_call('list_vm'))
# Wait for the response:
responses = self._server.manager.wait(frozenset(async_ids), timeout=5)
# Process the responses:
for resp in responses:
if resp['error'] is None:
for vm in resp['return']:
found_vm.append(vm)
return tuple(found_vm)
@pure
@listed
def list(self, query):
'''
List all objects registered on this instance.
'''
logging.debug('Executed list function with query %s' % query)
# Contains all the objects to be filted:
objects = []
# The query object:
query = TqlQuery(query)
# Get the hypervisors that match the query:
hypervisors = list(self._server.iterrole('hypervisor'))
if query.has_condition('hv'):
hypervisors = query.filter(hypervisors, tag_name='hv',
key=lambda o,n: o.get_tags([n]).get(n))
logging.debug('Querying %d hypervisors: %s' % (len(hypervisors),
hypervisors))
# Try to get vm for each matched hypervisor:
async_calls = {}
for hy in hypervisors:
async_calls[hy.connection.async_call('list_vm')] = hy
logging.debug('Waiting for the response of hypervisors...')
responses = self._server.manager.wait(frozenset(async_calls), timeout=5)
logging.debug('Responses received.')
# Make the hypervisor object -> tags mapping:
hv_tags = {}
for hy in hypervisors:
tags = hy.get_tags(tags=tuple(query.tags))
hv_tags[hy] = tags
objects.append(tags)
for resp in responses:
if resp['error'] is None:
hy = async_calls[resp['id']]
for vm in resp['return']:
vm_tags = hv_tags[hy].copy()
vm_tags.update(vm)
vm_tags['role'] = 'vm'
objects.append(vm_tags)
# Filter the objects with the query, and return it:
return query.filter(objects)
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.
'''
role = self._server.conf.authentify(login, password)
if role is None:
logging.info('New authentication from %s: failure' % login)
return False
else:
# If authentication is a success, ask tags to the server:
self._server.register(login, role, connection)
connection.set_handler(WelcomeHandler.ROLES.get(role)(self._server))
logging.info('New authentication from %s: success' % login)
return role