diff options
-rw-r--r-- | NEWS | 5 | ||||
-rwxr-xr-x | icktool | 136 | ||||
-rwxr-xr-x | icktool2 | 210 |
3 files changed, 15 insertions, 336 deletions
@@ -20,6 +20,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. Version 0.40+git, not yet released ---------------------------------- +* `icktool` is now the rewritten version. + +* The controller now allows triggering an entire project, instead of a + pipeline in a project. Additionally, when the project build starts, + all actions from all pipelines are queued for the build. Version 0.40, released 2018-04-16 ------------------------------------ @@ -18,10 +18,13 @@ import configparser import json import logging -import os import sys +import time +import apifw import cliapp +import Crypto.PublicKey.RSA +import requests import yaml import ick2 @@ -83,7 +86,6 @@ class Icktool(cliapp.Application): ['secrets'], 'use URL as the controller base URL', metavar='URL', - default=os.path.expanduser('~/.config/icktool/credentials.conf'), ) self.settings.boolean( @@ -125,16 +127,6 @@ 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() @@ -142,22 +134,15 @@ class Icktool(cliapp.Application): api = self._new_api() api.set_token(token) - self._create_resources( - api, '/projects', 'project', obj.get('projects', [])) - self._create_resources( - api, '/pipelines', 'pipeline', obj.get('pipelines', [])) + self._create_resources(api, '/projects', obj.get('projects', [])) + self._create_resources(api, '/pipelines', obj.get('pipelines', [])) def _read_object(self): return yaml.load(sys.stdin) - def _create_resources(self, api, path, field, objs): + def _create_resources(self, api, path, objs): for obj in objs: - try: - api.create(path, obj) - except ick2.HttpError: - if field in obj: - obj_path = '{}/{}'.format(path, obj[field]) - api.update(obj_path, obj) + api.create(path, obj) def cmd_show(self, args): token = self._new_token() @@ -173,76 +158,6 @@ 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']) @@ -251,9 +166,6 @@ class Icktool(cliapp.Application): def _new_auth(self): url = self.settings['auth-url'] - if not url: - api = self._new_api() - url = api.get_auth_url() client_id, client_secret = self._get_client_creds(url) ac = ick2.AuthClient() @@ -265,8 +177,8 @@ class Icktool(cliapp.Application): if self.settings['token']: return self.settings['token'] ac = self._new_auth() - wanted_scopes = ' '.join(self.settings['scope']) - return ac.get_token(wanted_scopes) + scopes = ' '.join(self.settings['scope']) + return ac.get_token(scopes) def _get_client_creds(self, url): cp = configparser.ConfigParser() @@ -279,34 +191,6 @@ 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/icktool2 b/icktool2 deleted file mode 100755 index 20140ee..0000000 --- a/icktool2 +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/python3 -# Copyright 2017-2018 Lars Wirzenius -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - - -import configparser -import json -import logging -import sys -import time - -import apifw -import cliapp -import Crypto.PublicKey.RSA -import requests -import yaml - -import ick2 - - -def scopes(base): - patterns = [ - 'uapi_{}_get', - 'uapi_{}_post', - 'uapi_{}_id_get', - 'uapi_{}_id_put', - 'uapi_{}_id_delete', - ] - return [x.format(base) for x in patterns] - - -def scopes_for_types(typelist): - result = [] - for type_name in typelist: - result.extend(scopes(type_name)) - return result - - -types = [ - 'projects', - 'pipelines', - 'workers', - 'work', - 'builds', - 'logs', -] - - -class Icktool(cliapp.Application): - - _default_scopes = [ - 'uapi_version_get', - 'uapi_work_post', - 'uapi_projects_id_status_get', - 'uapi_projects_id_status_put', - 'uapi_blobs_id_get', - 'uapi_blobs_id_put', - ] + scopes_for_types(types) - - def add_settings(self): - self.settings.string( - ['controller', 'c'], - 'use URL as the controller base URL', - metavar='URL', - ) - - self.settings.string( - ['auth-url'], - 'use URL as the authentication URL', - metavar='URL', - ) - - self.settings.string( - ['secrets'], - 'use URL as the controller base URL', - metavar='URL', - ) - - self.settings.boolean( - ['verify-tls'], - 'verify API provider TLS certificate ' - '(default is verify, use --no-verify-tls)', - default=True, - ) - - self.settings.string( - ['token'], - 'use TOKEN instead of generating a new one', - metavar='TOKEN', - ) - - self.settings.string_list( - ['scope'], - 'add SCOPE to the list of scope in requested token', - metavar='SCOPE', - default=self._default_scopes, - ) - - def setup(self): - if not self.settings['verify-tls']: - logging.captureWarnings(True) - - def cmd_scopes(self, args): - for scope in self.settings['scope']: - self.output.write('{}\n'.format(scope)) - - def cmd_token(self, args): - token = self._new_token() - self.output.write('{}\n'.format(token)) - - def cmd_version(self, args): - token = self._new_token() - api = self._new_api() - api.set_token(token) - version = api.get_version() - self._prettyson(version) - - def cmd_make_it_so(self, argv): - obj = self._read_object() - - token = self._new_token() - api = self._new_api() - api.set_token(token) - - self._create_resources(api, '/projects', obj.get('projects', [])) - self._create_resources(api, '/pipelines', obj.get('pipelines', [])) - - def _read_object(self): - return yaml.load(sys.stdin) - - def _create_resources(self, api, path, objs): - for obj in objs: - api.create(path, obj) - - def cmd_show(self, args): - token = self._new_token() - api = self._new_api() - api.set_token(token) - if not args: - args = [ - 'projects', - 'pipelines', - ] - - for kind in args: - objs = api.show('/' + kind) - self._prettyson(objs) - - def _new_api(self): - api = ick2.ControllerClient() - api.set_verify_tls(self.settings['verify-tls']) - api.set_controller_url(self.settings['controller']) - return api - - def _new_auth(self): - url = self.settings['auth-url'] - client_id, client_secret = self._get_client_creds(url) - - ac = ick2.AuthClient() - ac.set_auth_url(url) - ac.set_client_creds(client_id, client_secret) - return ac - - def _new_token(self): - if self.settings['token']: - return self.settings['token'] - ac = self._new_auth() - scopes = ' '.join(self.settings['scope']) - return ac.get_token(scopes) - - def _get_client_creds(self, url): - cp = configparser.ConfigParser() - cp.read(self.settings['secrets']) - client_id = cp.get(url, 'client_id') - client_secret = cp.get(url, 'client_secret') - return client_id, client_secret - - def _prettyson(self, obj): - json.dump(obj, self.output, indent=4, sort_keys=True) - self.output.write('\n') - - -class Command: - - def __init__(self, api): - self._api = api - - def execute(self): - raise NotImplementedError() - - -class VersionCommand(Command): - - def execute(self): - self._api.get_version() - - -Icktool(version=ick2.__version__).run() |