Loading cloudcontrol/server/ccserver.py +12 −45 Original line number Diff line number Diff line Loading @@ -140,60 +140,27 @@ class CCServer(object): logging.warning(logmsg + 'bad role in account config (%s)', conn.getpeername(), login) raise BadRoleError('%r is not a legal role' % role) create_object = False # If authentication is a success, try to register the client: if role == 'bootstrap': # Set a bootstrap id for the object: login = '%s.%s' % (login, conn.get_fd()) # Real role of the node will be host: role = 'host' create_object = True # Try to register the client: for _ in xrange(5): try: self.register(login, role, conn, create_object) except AlreadyRegistered: if role == 'cli': try: self.kill(login) except NotConnectedAccountError: pass else: break else: logging.warning(logmsg + 'already connected (%s)', conn.getpeername(), login) raise AuthenticationError('Already connected') client = self.register(login, role, conn) return client.role logging.info('Authentication success from %s with login %s', conn.getpeername(), login) return role def register(self, login, role, connection, create_object=False): def register(self, login, role, connection): ''' Register a new connected account on the server. :param login: login of the account :param connection: connection to register :param tags: tags to add for the client :param create_object: create the object on objectdb ''' # Create the object on objectdb if required: if create_object: tql_object = SObject(login) tql_object.register(StaticTag('r', role)) self.db.register(tql_object) client = Client.from_role(role, login, self, connection) if client.login in self._clients: if client.KILL_ALREADY_CONNECTED: self.kill(client.login) else: tql_object = self.db.get(login) assert tql_object is not None # Register the client: if login in self._clients: raise AlreadyRegistered('A client is already connected with this account.') else: client = Client.from_role(role, login, self, connection, tql_object) self._clients[login] = client client.attach() self._clients[client.login] = client return client def unregister(self, client): """ Unregister a client. Loading cloudcontrol/server/clients/__init__.py +31 −11 Original line number Diff line number Diff line Loading @@ -88,29 +88,28 @@ class Client(object): ROLE = None RPC_HANDLER = RegisteredCCHandler KILL_ALREADY_CONNECTED = False roles = {} def __init__(self, login, server, connection, tql_object): def __init__(self, login, server, connection): self._login = login self._server = server self._connection = connection self._tql_object = tql_object self._handler = self.RPC_HANDLER(self) self._proxy = ConnectionProxy(self._connection.rpc) self._last_action = datetime.now() self._connection_date = datetime.now() # Set the role's handler for the client: self._connection.rpc.set_handler(self._handler) self._tql_object = None # Remote tags registered: self._remote_tags = set() # Register the server defined client tags: self._tql_object.register(CallbackTag('con', lambda: self.uptime, ttl=0)) self._tql_object.register(CallbackTag('idle', lambda: self.idle, ttl=0)) self._tql_object.register(CallbackTag('ip', lambda: self.ip)) def _get_tql_object(self): """ Get the TQL object of the client from the cc-server tql database. """ return self._server.db.get(self.login) @classmethod def register_client_class(cls, class_): Loading @@ -119,8 +118,8 @@ class Client(object): cls.roles[class_.ROLE] = class_ @classmethod def from_role(cls, role, login, server, connection, tql_object): return cls.roles[role](login, server, connection, tql_object) def from_role(cls, role, login, server, connection): return cls.roles[role](login, server, connection) # # Properties Loading @@ -144,6 +143,12 @@ class Client(object): """ return self._login @property def role(self): """ Return the role of this client. """ return self.ROLE @property def server(self): """ Return the cc-server binded to this client. Loading Loading @@ -182,6 +187,21 @@ class Client(object): peer = self.conn.getpeername() return ':'.join(peer.split(':')[:-1]) def attach(self): """ Attach the client to the server. """ # Set the role's handler for the client: self.conn.rpc.set_handler(self._handler) # Register the client in tql database: self._tql_object = self._get_tql_object() # Register the server defined client tags: self._tql_object.register(CallbackTag('con', lambda: self.uptime, ttl=0)) self._tql_object.register(CallbackTag('idle', lambda: self.idle, ttl=0)) self._tql_object.register(CallbackTag('ip', lambda: self.ip)) def get_tags(self, tags): # DEPRECATED """ Get tags on the remote node. Loading cloudcontrol/server/clients/bootstrap.py +24 −1 Original line number Diff line number Diff line from cloudcontrol.server.clients import Client from cloudcontrol.server.clients.host import HostClient from cloudcontrol.server.db import SObject from cloudcontrol.common.tql.db.tag import StaticTag class BootstrapClient(Client): class BootstrapClient(HostClient): """ A bootstrap client connected to the cc-server. """ ROLE = 'bootstrap' def _get_tql_object(self): tql_object = SObject(self.login) tql_object.register(StaticTag('r', self.role)) self._server.db.register(tql_object) return tql_object @property def login(self): return '%s.%s' % (self._login, self.conn.get_fd()) @property def role(self): return 'host' def shutdown(self): super(BootstrapClient, self).shutdown() # Also, remote the object from the db: self._server.db.unregister(self.login) Client.register_client_class(BootstrapClient) cloudcontrol/server/clients/cli.py +1 −0 Original line number Diff line number Diff line Loading @@ -764,6 +764,7 @@ class CliClient(Client): ROLE = 'cli' RPC_HANDLER = CliHandler KILL_ALREADY_CONNECTED = True def __init__(self, *args, **kwargs): super(CliClient, self).__init__(*args, **kwargs) Loading Loading
cloudcontrol/server/ccserver.py +12 −45 Original line number Diff line number Diff line Loading @@ -140,60 +140,27 @@ class CCServer(object): logging.warning(logmsg + 'bad role in account config (%s)', conn.getpeername(), login) raise BadRoleError('%r is not a legal role' % role) create_object = False # If authentication is a success, try to register the client: if role == 'bootstrap': # Set a bootstrap id for the object: login = '%s.%s' % (login, conn.get_fd()) # Real role of the node will be host: role = 'host' create_object = True # Try to register the client: for _ in xrange(5): try: self.register(login, role, conn, create_object) except AlreadyRegistered: if role == 'cli': try: self.kill(login) except NotConnectedAccountError: pass else: break else: logging.warning(logmsg + 'already connected (%s)', conn.getpeername(), login) raise AuthenticationError('Already connected') client = self.register(login, role, conn) return client.role logging.info('Authentication success from %s with login %s', conn.getpeername(), login) return role def register(self, login, role, connection, create_object=False): def register(self, login, role, connection): ''' Register a new connected account on the server. :param login: login of the account :param connection: connection to register :param tags: tags to add for the client :param create_object: create the object on objectdb ''' # Create the object on objectdb if required: if create_object: tql_object = SObject(login) tql_object.register(StaticTag('r', role)) self.db.register(tql_object) client = Client.from_role(role, login, self, connection) if client.login in self._clients: if client.KILL_ALREADY_CONNECTED: self.kill(client.login) else: tql_object = self.db.get(login) assert tql_object is not None # Register the client: if login in self._clients: raise AlreadyRegistered('A client is already connected with this account.') else: client = Client.from_role(role, login, self, connection, tql_object) self._clients[login] = client client.attach() self._clients[client.login] = client return client def unregister(self, client): """ Unregister a client. Loading
cloudcontrol/server/clients/__init__.py +31 −11 Original line number Diff line number Diff line Loading @@ -88,29 +88,28 @@ class Client(object): ROLE = None RPC_HANDLER = RegisteredCCHandler KILL_ALREADY_CONNECTED = False roles = {} def __init__(self, login, server, connection, tql_object): def __init__(self, login, server, connection): self._login = login self._server = server self._connection = connection self._tql_object = tql_object self._handler = self.RPC_HANDLER(self) self._proxy = ConnectionProxy(self._connection.rpc) self._last_action = datetime.now() self._connection_date = datetime.now() # Set the role's handler for the client: self._connection.rpc.set_handler(self._handler) self._tql_object = None # Remote tags registered: self._remote_tags = set() # Register the server defined client tags: self._tql_object.register(CallbackTag('con', lambda: self.uptime, ttl=0)) self._tql_object.register(CallbackTag('idle', lambda: self.idle, ttl=0)) self._tql_object.register(CallbackTag('ip', lambda: self.ip)) def _get_tql_object(self): """ Get the TQL object of the client from the cc-server tql database. """ return self._server.db.get(self.login) @classmethod def register_client_class(cls, class_): Loading @@ -119,8 +118,8 @@ class Client(object): cls.roles[class_.ROLE] = class_ @classmethod def from_role(cls, role, login, server, connection, tql_object): return cls.roles[role](login, server, connection, tql_object) def from_role(cls, role, login, server, connection): return cls.roles[role](login, server, connection) # # Properties Loading @@ -144,6 +143,12 @@ class Client(object): """ return self._login @property def role(self): """ Return the role of this client. """ return self.ROLE @property def server(self): """ Return the cc-server binded to this client. Loading Loading @@ -182,6 +187,21 @@ class Client(object): peer = self.conn.getpeername() return ':'.join(peer.split(':')[:-1]) def attach(self): """ Attach the client to the server. """ # Set the role's handler for the client: self.conn.rpc.set_handler(self._handler) # Register the client in tql database: self._tql_object = self._get_tql_object() # Register the server defined client tags: self._tql_object.register(CallbackTag('con', lambda: self.uptime, ttl=0)) self._tql_object.register(CallbackTag('idle', lambda: self.idle, ttl=0)) self._tql_object.register(CallbackTag('ip', lambda: self.ip)) def get_tags(self, tags): # DEPRECATED """ Get tags on the remote node. Loading
cloudcontrol/server/clients/bootstrap.py +24 −1 Original line number Diff line number Diff line from cloudcontrol.server.clients import Client from cloudcontrol.server.clients.host import HostClient from cloudcontrol.server.db import SObject from cloudcontrol.common.tql.db.tag import StaticTag class BootstrapClient(Client): class BootstrapClient(HostClient): """ A bootstrap client connected to the cc-server. """ ROLE = 'bootstrap' def _get_tql_object(self): tql_object = SObject(self.login) tql_object.register(StaticTag('r', self.role)) self._server.db.register(tql_object) return tql_object @property def login(self): return '%s.%s' % (self._login, self.conn.get_fd()) @property def role(self): return 'host' def shutdown(self): super(BootstrapClient, self).shutdown() # Also, remote the object from the db: self._server.db.unregister(self.login) Client.register_client_class(BootstrapClient)
cloudcontrol/server/clients/cli.py +1 −0 Original line number Diff line number Diff line Loading @@ -764,6 +764,7 @@ class CliClient(Client): ROLE = 'cli' RPC_HANDLER = CliHandler KILL_ALREADY_CONNECTED = True def __init__(self, *args, **kwargs): super(CliClient, self).__init__(*args, **kwargs) Loading