Loading cloudcontrol/server/clients/cli.py +72 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ from cloudcontrol.server.exceptions import (ReservedTagError, BadObjectError, BadRoleError, NotConnectedAccountError, CloneError, RightError) from cloudcontrol.server.election import Elector from cloudcontrol.server.repository import RepositoryOperationError from cloudcontrol.server.handlers import listed, Reporter from cloudcontrol.server.clients import Client, RegisteredCCHandler Loading Loading @@ -588,6 +589,77 @@ class CliHandler(RegisteredCCHandler): return errs.get_dict() @listed def loadscript(self, name): """ Get the content of a script stored ont he server. :param name: name of the script to load """ self.client.check('script') return self.server.scripts.load(name, empty_if_missing=True)[1] @listed def savescript(self, name, content): """ Save a script on the server. :param name: name of the script to save :param content: content of the script to save """ self.client.check('script') return self.server.scripts.save(name, content) @listed def delscript(self, query): """ Delete a script on the server. :param query: the tql query used to select scripts to delete """ objects = self.client.list(query, show=('r', 'name'), method='script') errs = Reporter() for obj in objects: if obj['r'] != 'script': errs.error(obj['id'], 'not a script') else: try: self.server.scripts.delete(obj['name']) except RepositoryOperationError as err: errs.error(obj['id'], 'error: %s' % err) else: errs.success(obj['id'], 'script deleted') return errs.get_dict() @listed def runscript(self, query, script, *args): """ Execute a script on matching nodes. """ # Load the script: sha1_hash, _ = self.server.scripts.load(script) objects = self.client.list(query, show=('r', ), method='script') errs = Reporter() for obj in objects: if obj['r'] not in ('host', 'hv'): errs.error(obj['id'], 'not a host') else: try: node = self.server.get_client(obj['id']) except KeyError: errs.error(obj['id'], 'node not connected') continue try: job_id = node.script_run(sha1_hash, script, self.client.login, *args) except RpcError as err: errs.error(obj['id'], '%s (exc: %s)' % (err.message, err.exception)) else: job_id = '.'.join((obj['id'], job_id)) errs.success(obj['id'], 'ok.', jobs=job_id) return errs.get_dict() @listed def electiontypes(self): return Elector.ALGO_BY_TYPES Loading cloudcontrol/server/clients/host.py +11 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,12 @@ class HostHandler(RegisteredCCHandler): """ Handler binded to an host client. """ def script_get(self, name): """ Get a script by its name. :param name: name of the script to get """ return self.server.scripts.load(name) class HostClient(Client): Loading Loading @@ -55,5 +61,10 @@ class HostClient(Client): self.proxy.forward(tun.label, port, destination) return tun def script_run(self, sha1_hash, script, *args): """ Run a script on the host. """ return self.conn.call('script_run', sha1_hash, script, *args) Client.register_client_class(HostClient) cloudcontrol/server/server.py +8 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ from cloudcontrol.server.exceptions import (AlreadyRegistered, from cloudcontrol.server.clients import Client from cloudcontrol.server.rights import RightManager from cloudcontrol.server.jobs import KillOldCliJob from cloudcontrol.server.repository import Repository from cloudcontrol.server.db import SObject, SRequestor from cloudcontrol.common.tql.db.tag import StaticTag Loading Loading @@ -93,6 +94,13 @@ class CCServer(object): os.path.join(conf_dir, 'ruleset')) self.logger.info('Server started to running') # Script repository: scripts_directory = os.path.join(conf_dir, 'scripts') if not os.path.isdir(scripts_directory): os.mkdir(scripts_directory) self.scripts = Repository(self.logger.getChild('scripts'), self, scripts_directory, role='script') def _update_accounts(self): """ Update the database with accounts. """ Loading Loading
cloudcontrol/server/clients/cli.py +72 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ from cloudcontrol.server.exceptions import (ReservedTagError, BadObjectError, BadRoleError, NotConnectedAccountError, CloneError, RightError) from cloudcontrol.server.election import Elector from cloudcontrol.server.repository import RepositoryOperationError from cloudcontrol.server.handlers import listed, Reporter from cloudcontrol.server.clients import Client, RegisteredCCHandler Loading Loading @@ -588,6 +589,77 @@ class CliHandler(RegisteredCCHandler): return errs.get_dict() @listed def loadscript(self, name): """ Get the content of a script stored ont he server. :param name: name of the script to load """ self.client.check('script') return self.server.scripts.load(name, empty_if_missing=True)[1] @listed def savescript(self, name, content): """ Save a script on the server. :param name: name of the script to save :param content: content of the script to save """ self.client.check('script') return self.server.scripts.save(name, content) @listed def delscript(self, query): """ Delete a script on the server. :param query: the tql query used to select scripts to delete """ objects = self.client.list(query, show=('r', 'name'), method='script') errs = Reporter() for obj in objects: if obj['r'] != 'script': errs.error(obj['id'], 'not a script') else: try: self.server.scripts.delete(obj['name']) except RepositoryOperationError as err: errs.error(obj['id'], 'error: %s' % err) else: errs.success(obj['id'], 'script deleted') return errs.get_dict() @listed def runscript(self, query, script, *args): """ Execute a script on matching nodes. """ # Load the script: sha1_hash, _ = self.server.scripts.load(script) objects = self.client.list(query, show=('r', ), method='script') errs = Reporter() for obj in objects: if obj['r'] not in ('host', 'hv'): errs.error(obj['id'], 'not a host') else: try: node = self.server.get_client(obj['id']) except KeyError: errs.error(obj['id'], 'node not connected') continue try: job_id = node.script_run(sha1_hash, script, self.client.login, *args) except RpcError as err: errs.error(obj['id'], '%s (exc: %s)' % (err.message, err.exception)) else: job_id = '.'.join((obj['id'], job_id)) errs.success(obj['id'], 'ok.', jobs=job_id) return errs.get_dict() @listed def electiontypes(self): return Elector.ALGO_BY_TYPES Loading
cloudcontrol/server/clients/host.py +11 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,12 @@ class HostHandler(RegisteredCCHandler): """ Handler binded to an host client. """ def script_get(self, name): """ Get a script by its name. :param name: name of the script to get """ return self.server.scripts.load(name) class HostClient(Client): Loading Loading @@ -55,5 +61,10 @@ class HostClient(Client): self.proxy.forward(tun.label, port, destination) return tun def script_run(self, sha1_hash, script, *args): """ Run a script on the host. """ return self.conn.call('script_run', sha1_hash, script, *args) Client.register_client_class(HostClient)
cloudcontrol/server/server.py +8 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ from cloudcontrol.server.exceptions import (AlreadyRegistered, from cloudcontrol.server.clients import Client from cloudcontrol.server.rights import RightManager from cloudcontrol.server.jobs import KillOldCliJob from cloudcontrol.server.repository import Repository from cloudcontrol.server.db import SObject, SRequestor from cloudcontrol.common.tql.db.tag import StaticTag Loading Loading @@ -93,6 +94,13 @@ class CCServer(object): os.path.join(conf_dir, 'ruleset')) self.logger.info('Server started to running') # Script repository: scripts_directory = os.path.join(conf_dir, 'scripts') if not os.path.isdir(scripts_directory): os.mkdir(scripts_directory) self.scripts = Repository(self.logger.getChild('scripts'), self, scripts_directory, role='script') def _update_accounts(self): """ Update the database with accounts. """ Loading