#!/usr/bin/python3 # Copyright 2017 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 json import logging import sys import cliapp import urllib3 import requests import ick2 class Icktool(cliapp.Application): _default_scopes = [ 'uapi_version_get', ] def add_settings(self): self.settings.string( ['controller'], 'use URL as the controller base URL', metavar='URL', ) self.settings.boolean( ['verify-tls'], 'verify TLS certifcate signature? default is yes', ) self.settings.string( ['token'], 'use TOKEN instead of generating a new one', metavar='TOKEN', ) self.settings.string( ['token-private-key-cmd'], 'run CMD to print private key for token signing', metavar='CMD', ) self.settings.string_list( ['scope'], 'add SCOPE to the list of scope in generated token', metavar='SCOPE', default=self._default_scopes, ) def setup(self): if not self.settings['verify-tls']: logging.captureWarnings(True) def cmd_token(self, args): token = self._new_token() sys.stdout.write(token) def cmd_version(self, args): api = self._new_api() self._prettyson(api.get('/version')) def _new_token(self): scopes = self.settings['scope'] cmd = self.settings['token-private-key-cmd'] if not cmd: raise cliapp.AppException('no --token-private-cmd specified') gen = TokenGenerator() gen.set_cmd(cmd) gen.set_scopes(scopes) return gen.new_token() def _new_api(self): token = self.settings['token'] or self._new_token() api = API() api.set_token(token) api.set_url(self.settings['controller']) api.set_verify(self.settings['verify-tls']) return api def _prettyson(self, obj): json.dump(obj, sys.stdout, indent=4) sys.stdout.write('\n') class API: def __init__(self): self._url = None self._token = None self._verify = True def set_url(self, url): self._url = url def set_token(self, token): self._token = token def set_verify(self, verify): self._verify = verify def get(self, path): assert self._url is not None assert self._token is not None version_url = '{}/version'.format(self._url) headers = { 'Authorization': 'Bearer {}'.format(self._token), } r = requests.get(version_url, headers=headers, verify=self._verify) return r.json() class TokenGenerator: def __init__(self): self._cmd = None self._scopes = None def set_cmd(self, cmd): self._cmd = cmd def set_scopes(self, scopes): self._scopes = scopes def new_token(self): assert self._cmd is not None assert self._scopes is not None privkey = cliapp.runcmd(['sh', '-c', self._cmd]) token = cliapp.runcmd( ['./create-token', ' '.join(self._scopes)], feed_stdin=privkey) return token.decode('ascii') Icktool(version=ick2.__version__).run()