Add admin subcommands
This commit is contained in:
parent
64973c4873
commit
32a0948deb
|
@ -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()
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
Loading…
Reference in New Issue