Skip to content

Commit

Permalink
Switch from argparse to click
Browse files Browse the repository at this point in the history
This patch switches from argparse to click for handling command line
arguments in preparation to introducing multiple command line argument
groups.

This patch does not change the functionality. The CLI still only handles
DNS modifications. But this is now in its own group and we can easily
add another one, for example, to handle IP address registration.
  • Loading branch information
lkiesow committed Sep 27, 2023
1 parent 78208c9 commit 58ba518
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 38 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
102 changes: 71 additions & 31 deletions proteuscmd/__main__.py
Original file line number Diff line number Diff line change
@@ -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()
5 changes: 3 additions & 2 deletions proteuscmd/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
requests
Click

0 comments on commit 58ba518

Please sign in to comment.