diff --git a/README.md b/README.md index 6e5f34f..28bc541 100644 --- a/README.md +++ b/README.md @@ -36,25 +36,32 @@ This can be useful if, for example, all your domains also have an alternate doma ``` ❯ proteuscmd -usage: proteuscmd [-h] [--view {all,intern,extern}] {get,set,delete} domain [target] +Usage: python -m proteuscmd [OPTIONS] COMMAND [ARGS]... + +Options: + --help Show this message and exit. + +Commands: + dns Get information about or update DNS entries. + ip Register IP addresses. ``` Get information about a DNS record: ``` -❯ proteuscmd get lktest.uni-osnabrueck.de +❯ proteuscmd dns get lktest.uni-osnabrueck.de ``` Set an alias record: ``` -❯ proteuscmd set lktest.uni-osnabrueck.de vm123.rz.uni-osnabrueck.de +❯ proteuscmd dns set lktest.uni-osnabrueck.de vm123.rz.uni-osnabrueck.de ``` Set a host record: ``` -❯ proteuscmd set lktest.uni-osnabrueck.de 131.12.65.123 +❯ proteuscmd dns set lktest.uni-osnabrueck.de 131.12.65.123 ``` Delete a record: ``` -❯ proteuscmd delete lktest.uni-osnabrueck.de +❯ proteuscmd dns delete lktest.uni-osnabrueck.de ``` diff --git a/proteuscmd/__main__.py b/proteuscmd/__main__.py index 3ca408d..78db6b6 100644 --- a/proteuscmd/__main__.py +++ b/proteuscmd/__main__.py @@ -1,43 +1,83 @@ -import argparse +import click +import json +from functools import wraps from proteuscmd.config import proteus_from_config -__config = None +__views = click.Choice(('intern', 'extern', 'all'), case_sensitive=False) -def main(): - parser = argparse.ArgumentParser(description='Proteus DNS command line') - parser.add_argument('--view', - choices=('all', 'intern', 'extern'), - default='all', - help='View to operate on') - parser.add_argument('operation', - choices=('get', 'set', 'delete'), - help='Operation to perform on domain') - parser.add_argument('domain', - help='Domain to operate on') - parser.add_argument('target', - nargs='?', - help='Target of the DNS record') +def with_proteus(f): + '''Provide a Proteus client as first parameter of the wraped function. + Print the result if one exists. + ''' + @wraps(f) + def decorated(*args, **kwargs): + with proteus_from_config() as proteus: + data = f(proteus, *args, **kwargs) + if data: + print(json.dumps(data, indent=2)) + return decorated - args = parser.parse_args() - if args.operation == 'set' and not args.target: - parser.error("set requires a target.") +@click.group() +def cli(): + pass - # Interaction with Proteus - with proteus_from_config() as proteus: - views = proteus.get_requested_views(args.view) - for name, view in views: - print(name) - if args.operation == 'get': - print('\n'.join(proteus.get_record(view, args.domain))) - elif args.operation == 'set': - print(proteus.set_record(view, args.domain, args.target)) - elif args.operation == 'delete': - print(proteus.delete_record(view, args.domain)) +@cli.group() +def dns(): + '''Get information about or update DNS entries. + ''' + pass + + +@cli.group() +def ip(): + '''Register IP addresses. + Not implemented yet. + ''' + pass + + +@dns.command() +@click.option('--view', default='all', type=__views) +@click.argument('domain') +@with_proteus +def get(proteus, view, domain): + '''Get information about a DNS entry. + ''' + views = proteus.get_requested_views(view) + return {name: proteus.get_record(view, domain) for name, view in views} + + +@dns.command() +@click.option('--view', default='all', type=__views) +@click.argument('domain') +@click.argument('target') +@with_proteus +def set(proteus, view, domain, target): + '''Set DNS entry in Proteus + ''' + views = proteus.get_requested_views(view) + result = {} + for name, view in views: + proteus.set_record(view, domain, target) + result[name] = proteus.get_record(view, domain) + return result + + +@dns.command() +@click.option('--view', default='all', type=__views) +@click.argument('domain') +@with_proteus +def delete(proteus, view, domain): + '''Delete DNS record in Proteus + ''' + views = proteus.get_requested_views(view) + for name, view in views: + proteus.delete_record(view, domain) if __name__ == '__main__': - main() + cli() diff --git a/proteuscmd/api.py b/proteuscmd/api.py index 70bf247..6edfdfe 100644 --- a/proteuscmd/api.py +++ b/proteuscmd/api.py @@ -171,8 +171,9 @@ def get_record(self, view, domain): + self.get_entities_by_name(host, parent, 'AliasRecord') for record in data: properties = record['properties'].split('|') - return [prop for prop in filter(bool, properties)] - return [] + properties = [prop.split('=', 1) for prop in properties if prop] + return {prop[0]: prop[1] for prop in properties} + return {} def set_record(self, view, domain, target): diff --git a/requirements.txt b/requirements.txt index f229360..b070841 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ requests +Click