diff options
author | Lars Wirzenius <liw@liw.fi> | 2018-04-08 13:15:51 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2018-04-08 13:15:51 +0300 |
commit | 124939fc94bb08a02207750fd017209f6e8edb46 (patch) | |
tree | 3c23d23812ebc16e30b78341ce830a50e9e61593 | |
parent | b9171928c024fde56789846233a539ccd0ffee48 (diff) | |
parent | 186cf88fa34b54d6f2cd82d8eab8160be015ba5f (diff) | |
download | ick2-124939fc94bb08a02207750fd017209f6e8edb46.tar.gz |
Merge: improve icktool
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ick2/client.py | 17 | ||||
-rwxr-xr-x | icktool | 108 | ||||
-rwxr-xr-x | worker_manager | 37 |
4 files changed, 158 insertions, 7 deletions
@@ -20,6 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. Version 0.35+git, not yet released ---------------------------------- +* `icktool` is again mostly functional. Deleting resources (projects, + pipelines, etc) hasn't been implemented yet. Neither has handling + blobs. These will be added later, when some one needs them. Version 0.35, released 2018-04-07 ---------------------------------- diff --git a/ick2/client.py b/ick2/client.py index ec2a113..533b8cd 100644 --- a/ick2/client.py +++ b/ick2/client.py @@ -214,6 +214,23 @@ class ControllerClient: url = self.url(path) return self._api.post(url, body=obj) + def trigger(self, project_name, pipeline_name): # pragma: no cover + path = '/projects/{}/pipelines/{}/+trigger'.format( + project_name, pipeline_name) + url = self.url(path) + return self._api.get_blob(url) + + def get_build_status( + self, project_name, pipeline_name): # pragma: no cover + path = '/projects/{}/pipelines/{}'.format(project_name, pipeline_name) + url = self.url(path) + return self._api.get_dict(url) + + def get_log(self, build_id): # pragma: no cover + path = '/logs/{}'.format(build_id) + url = self.url(path) + return self._api.get_blob(url) + class AuthClient: @@ -125,6 +125,16 @@ class Icktool(cliapp.Application): version = api.get_version() self._prettyson(version) + def cmd_trigger(self, args): + project_name = args[0] + pipeline_name = args[1] + + token = self._new_token() + api = self._new_api() + api.set_token(token) + result = api.trigger(project_name, pipeline_name) + self._prettyson(result) + def cmd_make_it_so(self, argv): obj = self._read_object() @@ -156,6 +166,76 @@ class Icktool(cliapp.Application): objs = api.show('/' + kind) self._prettyson(objs) + def cmd_status(self, args): + token = self._new_token() + api = self._new_api() + api.set_token(token) + + rows = [] + projects = api.show('/projects')['projects'] + projects = sorted(projects, key=lambda p: p.get('project')) + + builds = api.show('/builds')['builds'] + + for project in projects: + pipeline_names = sorted(project['pipelines']) + for pipeline_name in pipeline_names: + build = self._get_latest_build( + project['project'], pipeline_name, builds) + + if build is None: + build = { + 'build_id': 'never', + 'log': 'none', + 'status': 'n/a', + } + + status = api.get_build_status( + project['project'], pipeline_name) + + row = { + 'project': project['project'], + 'pipeline': pipeline_name, + 'build_id': build['build_id'], + 'status': status['status'], + 'build_status': build['status'], + 'log': build['log'], + } + rows.append(row) + self._pretty_table( + rows, ['project', 'pipeline', 'status', 'build_status', 'log']) + + def _get_latest_build(self, project_name, pipeline_name, builds): + wanted = [ + b for b in builds + if b['project'] == project_name and b['pipeline'] == pipeline_name + ] + if wanted: + return wanted[-1] + return None + + def cmd_show_latest_log(self, args): + token = self._new_token() + api = self._new_api() + api.set_token(token) + + project_name = args[0] + builds = api.show('/builds')['builds'] + project_builds = [b for b in builds if b['project'] == project_name] + if project_builds: + b = project_builds[-1] + log = api.get_log(b['build_id']) + self.output.write(log.decode('UTF-8')) + + def cmd_show_log(self, args): + token = self._new_token() + api = self._new_api() + api.set_token(token) + + build_id = args[0] + log = api.get_log(build_id) + self.output.write(log.decode('UTF-8')) + def _new_api(self): api = ick2.ControllerClient() api.set_verify_tls(self.settings['verify-tls']) @@ -192,6 +272,34 @@ class Icktool(cliapp.Application): json.dump(obj, self.output, indent=4, sort_keys=True) self.output.write('\n') + def _pretty_table(self, rows, columns): + headings = { + column: column + for column in columns + } + + widths = { + column: 0 + for column in columns + } + + for row in [headings] + rows: + for column in columns: + widths[column] = max(widths[column], len(str(row[column]))) + + underlines = { + column: '-' * widths[column] + for column in columns + } + + for row in [headings, underlines] + rows: + self.output.write( + '{}\n'.format(self._pretty_row(widths, row, columns))) + + def _pretty_row(self, widths, row, columns): + parts = ['%*s' % (widths[c], row[c]) for c in columns] + return ' | '.join(parts) + class Command: diff --git a/worker_manager b/worker_manager index 6fd556c..1590109 100755 --- a/worker_manager +++ b/worker_manager @@ -35,14 +35,20 @@ class WorkerManager(cliapp.Application): def add_settings(self): self.settings.string( - ['controller'], - 'base URL for the controller', - metavar='URL', + ['client-id'], + 'use ID as the client id when authenticatin to IDP', + metavar='ID', + ) + + self.settings.string( + ['client-secret-cmd'], + 'run CMD to gget the client secret when authentication to IDP', + metavar='CMD', ) self.settings.string( - ['name'], - 'name of this worker', + ['controller'], + 'base URL for the controller', metavar='URL', ) @@ -82,16 +88,20 @@ class WorkerManager(cliapp.Application): raise def main_program(self, args): - self.settings.require('name') + self.settings.require('client-id') + self.settings.require('client-secret-cmd') self.settings.require('controller') - name = self.settings['name'] + name = self.settings['client-id'] url = self.settings['controller'] workspace = self.settings['workspace'] systree = self.settings['systree'] + secret = self.get_client_secret() + api = ControllerAPI(name, url) api.set_verify_tls(self.settings['verify-tls']) + api.set_client_creds(name, secret) worker = Worker(name, api, workspace, systree) logging.info('Worker manager %s starts, controller is %s', name, url) @@ -108,6 +118,12 @@ class WorkerManager(cliapp.Application): secs = self.settings['sleep'] time.sleep(secs) + def get_client_secret(self): + cmd = self.settings['client-secret-cmd'] + output = cliapp.runcmd(['sh', '-c', cmd]) + lines = output.splitlines() + return lines[0].strip() + class ControllerAPI: @@ -126,13 +142,20 @@ class ControllerAPI: self._cc.set_controller_url(url) self._ac = None self._blobs = None + self._client_id = None + self._client_secret = None def set_verify_tls(self, verify): self._cc.set_verify_tls(verify) + def set_client_creds(self, client_id, client_secret): + self._client_id = client_id + self._client_secret = client_secret + def get_token(self): if self._ac is None: self._ac = self._cc.get_auth_client() + self._ac.set_client_creds(self._client_id, self._client_secret) return self._ac.get_token(self._scopes) def register(self): |