diff options
author | Lars Wirzenius <liw@liw.fi> | 2018-04-07 15:24:40 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2018-04-07 16:54:03 +0300 |
commit | d52f5cbef49edff9ceb1b5092ed7e60553ce185a (patch) | |
tree | 7623145a540e4cae506ff7c0845b052d8ef5a07f | |
parent | daafee995775a5b79ef7bc23d819c39d30362061 (diff) | |
download | ick2-d52f5cbef49edff9ceb1b5092ed7e60553ce185a.tar.gz |
Add: new icktool2 command
-rw-r--r-- | ick2/client.py | 10 | ||||
-rwxr-xr-x | icktool2 | 210 |
2 files changed, 219 insertions, 1 deletions
diff --git a/ick2/client.py b/ick2/client.py index cda3649..ec2a113 100644 --- a/ick2/client.py +++ b/ick2/client.py @@ -154,7 +154,7 @@ class ControllerClient: return self._api.get_dict(url) def get_artifact_store_url(self): - version = self.version() + version = self.get_version() url = version.get('artifact_store') logging.info('Artifact store URL: %r', url) return url @@ -206,6 +206,14 @@ class ControllerClient: body = json.dumps(work) self._api.post(url, headers=headers, body=body) + def show(self, path): # pragma: no cover + url = self.url(path) + return self._api.get_dict(url) + + def create(self, path, obj): # pragma: no cover + url = self.url(path) + return self._api.post(url, body=obj) + class AuthClient: diff --git a/icktool2 b/icktool2 new file mode 100755 index 0000000..df5ccdd --- /dev/null +++ b/icktool2 @@ -0,0 +1,210 @@ +#!/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_pipelines_id_get', + 'uapi_projects_id_pipelines_id_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() |