Add admin subcommands

This commit is contained in:
Tim Van Baak 2021-06-15 16:18:19 -07:00
parent 64973c4873
commit 32a0948deb
3 changed files with 61 additions and 120 deletions

View File

@ -2,6 +2,8 @@ from argparse import ArgumentParser
import logging import logging
import logging.config import logging.config
import amanuensis.cli.admin
LOGGING_CONFIG = { LOGGING_CONFIG = {
"version": 1, "version": 1,
@ -84,6 +86,7 @@ def main():
# Add commands from cli submodules # Add commands from cli submodules
subparsers = parser.add_subparsers(metavar="COMMAND") subparsers = parser.add_subparsers(metavar="COMMAND")
add_subcommand(subparsers, amanuensis.cli.admin)
# Parse args and execute the desired action # Parse args and execute the desired action
args = parser.parse_args() args = parser.parse_args()

58
amanuensis/cli/admin.py Normal file
View File

@ -0,0 +1,58 @@
import collections
import json
import logging
import os
from amanuensis.db import DbContext
from .helpers import add_argument
COMMAND_NAME = "admin"
COMMAND_HELP = "Interact with Amanuensis."
LOG = logging.getLogger(__name__)
@add_argument("path", metavar="DB_PATH", help="Path to where the database should be created")
@add_argument("--force", "-f", action="store_true", help="Overwrite existing database")
@add_argument("--verbose", "-v", action="store_true", help="Enable db echo")
def command_init_db(args) -> int:
"""
Initialize the Amanuensis database.
"""
# Check if force is required
if not args.force and os.path.exists(args.path):
args.parser.error(f"{args.path} already exists and --force was not specified")
# Initialize the database
db_uri = f"sqlite:///{os.path.abspath(args.path)}"
LOG.info(f"Creating database at {db_uri}")
db = DbContext(db_uri, debug=args.verbose)
db.create_all()
LOG.info("Done")
return 0
@add_argument("path", metavar="CONFIG_PATH", help="Path to the config file")
def command_secret_key(args) -> int:
"""
Generate a Flask secret key.
The Flask server will not run unless a secret key has
been generated.
"""
# Load the json config
with open(args.path, mode="r", encoding="utf8") as f:
config = json.load(f, object_pairs_hook=collections.OrderedDict)
# Set the secret key to a new random string
config["SECRET_KEY"] = os.urandom(32).hex()
# Write the config back out
with open(args.path, mode="w", encoding="utf8") as f:
json.dump(config, f, indent=2)
LOG.info("Regenerated Flask secret key")
return 0

View File

@ -1,120 +0,0 @@
import logging
import os
from amanuensis.config import RootConfigDirectoryContext
from .helpers import (
add_argument,
no_argument,
alias,
config_get,
config_set,
CONFIG_GET_ROOT_VALUE)
logger = logging.getLogger(__name__)
@alias('i')
@add_argument("--refresh",
action="store_true",
help="Refresh an existing config directory")
def command_init(args):
"""
Initialize a config directory at --config-dir
A clean config directory will contain a config.json, a
lexicon config directory, and a user config directory.
Refreshing an existing directory will add keys to the global config that
are present in the default configs. Users and lexicons that are missing
from the indexes will be deleted, and stale index entries will be removed.
"""
# Module imports
from amanuensis.config.init import create_config_dir
# Verify arguments
if args.refresh and not os.path.isdir(args.config_dir):
print("Error: couldn't find directory '{}'".format(args.config_dir))
# Internal call
create_config_dir(args.config_dir, args.refresh)
logger.info(f'Initialized config dir at {args.config_dir}')
return 0
@alias('gs')
@no_argument
def command_generate_secret(args):
"""
Generate a Flask secret key
The Flask server will not run unless a secret key has
been generated.
"""
root: RootConfigDirectoryContext = args.root
secret_key: bytes = os.urandom(32)
with root.edit_config() as cfg:
cfg.secret_key = secret_key.hex()
logger.info("Regenerated Flask secret key")
return 0
@alias('r')
@add_argument("-a", "--address", default="127.0.0.1")
@add_argument("-p", "--port", default="5000")
@add_argument("--debug", action="store_true")
def command_run(args):
"""
Run the default Flask server
The default Flask server is not secure, and should
only be used for development.
"""
from amanuensis.server import get_app
root: RootConfigDirectoryContext = args.root
with root.read_config() as cfg:
if cfg.secret_key is None:
logger.error("Can't run server without a secret_key. "
"Run generate-secet first.")
return -1
get_app(root).run(host=args.address, port=args.port, debug=args.debug)
return 0
@alias('n')
@add_argument("--get",
metavar="PATHSPEC",
dest="get",
nargs="?",
const=CONFIG_GET_ROOT_VALUE,
help="Get the value of a config key")
@add_argument("--set",
metavar=("PATHSPEC", "VALUE"),
dest="set",
nargs=2,
help="Set the value of a config key")
def command_config(args):
"""
Interact with the global config
PATHSPEC is a path into the config object formatted as
a dot-separated sequence of keys.
"""
root: RootConfigDirectoryContext = args.root
if args.get and args.set:
logger.error("Specify one of --get and --set")
return -1
if args.get:
with root.read_config() as cfg:
config_get(cfg, args.get)
if args.set:
with root.edit_config() as cfg:
config_set("config", cfg, args.set)
return 0