Shell completion

main
Micke Nordin 2 years ago
parent 9791c72a6e
commit 149dc17019
Signed by: micke
GPG Key ID: 0DA0A7A5708FE257

@ -6,10 +6,11 @@ https://gitlab.nic.cz/knot/knot-dns-rest
## Usage
```
usage: knotctl [-h] [--json | --no-json] {add,config,delete,list,update} ...
usage: knotctl [-h] [--json | --no-json]
{add,complete,config,delete,list,update} ...
positional arguments:
{add,config,delete,list,update}
{add,complete,config,delete,list,update}
options:
-h, --help show this help message and exit
@ -27,6 +28,31 @@ options:
-t TTL, --ttl TTL
-z ZONE, --zone ZONE
```
### COMPLETE
```
usage: knotctl complete [-h] [-s SHELL]
options:
-h, --help show this help message and exit
-s SHELL, --shell SHELL
```
For bash: add this to .bashrc
```
eval "$(knotctl complete)"
```
For fish, run:
```
knotctl complete --shell fish > ~/.config/fish/completions/knotctl.fish
```
For tcsh: add this to .cshrc
```
eval "$(knotctl complete --shell tcsh)"
```
For zsh: add this to .zshrc
```
eval "$(autoload -U bashcompinit; bashcompinit; scripts/knotctl complete)"
```
### CONFIG
```
usage: knotctl config [-h] [-b BASEURL] [-p PASSWORD] [-u USERNAME]

@ -3,8 +3,8 @@
import argparse
import getpass
import json
import os
import sys
import urllib.parse
from collections.abc import Sequence
from os import environ, mkdir
from os.path import isdir, isfile, join
@ -16,6 +16,7 @@ import yaml
from requests.models import HTTPBasicAuth
# Helper functions
def error(description: str, error: str) -> Sequence[dict]:
response = []
reply = {}
@ -32,16 +33,6 @@ def get_config(config_filename: str):
return yaml.safe_load(fh.read())
def output(response: Sequence[dict], jsonout: bool = False):
try:
if jsonout:
print(json.dumps(response))
else:
print(nested_out(response))
except BrokenPipeError:
pass
def nested_out(input, tabs="") -> str:
string = ""
if isinstance(input, str) or isinstance(input, int):
@ -56,13 +47,33 @@ def nested_out(input, tabs="") -> str:
return string
# Define the parser for each command
def output(response: Sequence[dict], jsonout: bool = False):
try:
if jsonout:
print(json.dumps(response))
else:
print(nested_out(response))
except BrokenPipeError:
pass
# Define the runner for each command
def run_add(url: str, jsonout: bool, headers: dict):
print(url)
response = requests.put(url, headers=headers)
output(response.json(), jsonout)
def run_complete(shell: Union[None, str]):
if not shell or shell in ["bash", "zsh"]:
os.system("register-python-argcomplete knotctl")
elif shell == "fish":
os.system("register-python-argcomplete --shell fish knotctl")
elif shell == "tcsh":
os.system("register-python-argcomplete --shell tcsh knotctl",
shell=True)
def run_config(
config_filename: str,
baseurl: Union[None, str] = None,
@ -150,32 +161,8 @@ def setup_url(
return url
# Entry point to program
def main() -> int:
config_basepath = join(environ["HOME"], ".knot")
config_filename = join(config_basepath, "config")
if not isdir(config_basepath):
mkdir(config_basepath)
if not isfile(config_filename):
print("You need to configure knotctl before proceeding")
run_config(config_filename)
configcmd = get_config(config_filename)
baseurl = configcmd["baseurl"]
username = configcmd["username"]
password = configcmd["password"]
# Authenticate
basic = HTTPBasicAuth(username, password)
response = requests.get(baseurl + "/user/login", auth=basic)
try:
token = response.json()["token"]
except KeyError:
output(response.json())
return 1
headers = {"Authorization": "Bearer {}".format(token)}
# Grab user input
parser = argparse.ArgumentParser()
parser.add_argument("--json", action=argparse.BooleanOptionalAction)
@ -187,6 +174,9 @@ def main() -> int:
addcmd.add_argument("-t", "--ttl", required=True)
addcmd.add_argument("-z", "--zone", required=True)
completecmd = subparsers.add_parser("complete")
completecmd.add_argument("-s", "--shell")
configcmd = subparsers.add_parser("config")
configcmd.add_argument("-b", "--baseurl")
configcmd.add_argument("-p", "--password")
@ -213,6 +203,36 @@ def main() -> int:
argcomplete.autocomplete(parser)
args = parser.parse_args()
if args.command == "complete":
run_complete(args.shell)
return 0
# Make sure we have config
config_basepath = join(environ["HOME"], ".knot")
config_filename = join(config_basepath, "config")
if not isdir(config_basepath):
mkdir(config_basepath)
if not isfile(config_filename):
if args.command != "config":
print("You need to configure knotctl before proceeding")
run_config(config_filename)
config = get_config(config_filename)
baseurl = config["baseurl"]
username = config["username"]
password = config["password"]
# Authenticate
basic = HTTPBasicAuth(username, password)
response = requests.get(baseurl + "/user/login", auth=basic)
try:
token = response.json()["token"]
except KeyError:
output(response.json())
return 1
headers = {"Authorization": "Bearer {}".format(token)}
# Route based on command
ttl = None

Loading…
Cancel
Save