#!/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 . 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()