[mod] revise args and conf

This commit is contained in:
Christian Fraß 2024-05-31 11:24:53 +02:00
parent 8dcc0a761d
commit e8bf8073ca
3 changed files with 332 additions and 148 deletions

View file

@ -1,5 +1,80 @@
_conf_data = { _conf_data = None
def conf_schema(
):
return {
"type": "object",
"properties": {
"url": { "url": {
"type": "object",
"properties": {
},
"additionalProperties": {
"type": "object",
"properties": {
"scheme": {
"type": "string",
},
"host": {
"type": "string",
},
"port": {
"type": "number",
},
"path": {
"type": "string",
},
},
"additionalProperties": False,
"required": [
"host",
]
},
"required": [
]
},
"environment": {
"type": "string",
},
"account": {
"type": "object",
"properties": {
"username": {
"type": "string",
},
"password": {
"type": "string",
},
},
"additionalProperties": False,
"required": [
]
}
},
"additionalProperties": False,
"required": [
],
}
def conf_load(
path : str
):
global _conf_data
if (not _os.path.exists(path)):
pass
else:
conf_data_raw = _json.loads(file_read(path))
for pair in conf_data_raw.get("url", {}).items():
if ("host" in pair[1]):
pass
else:
raise ValueError("flawed conf: missing mandatory value 'host' for url entry '%s'" % pair[0])
_conf_data = {
"url": convey(
(
{
"test": { "test": {
"scheme": "https", "scheme": "https",
"host": "api.ote.domrobot.com", "host": "api.ote.domrobot.com",
@ -12,27 +87,34 @@ _conf_data = {
"port": 443, "port": 443,
"path": "jsonrpc/" "path": "jsonrpc/"
} }
},
"environment": "production",
"account": {
"username": None,
"password": None
} }
} |
conf_data_raw.get("url", {})
),
def conf_load( [
path : str lambda x: x.items(),
): lambda pairs: map(
global _conf_data lambda pair: (
if (not _os.path.exists(path)): pair[0],
pass {
else: "scheme": pair[1].get("scheme", "https"),
handle = open(path, "r") "host": pair[1]["host"],
content = handle.read() "port": pair[1].get("port", 443),
handle.close() "path": pair[1].get("path", "jsonrpc/"),
data = _json.loads(content) }
_conf_data = merge(_conf_data, data) ),
pairs
),
dict,
]
),
"environment": conf_data_raw.get("environment", "production"),
"account": {
"username": conf_data_raw.get("account", {}).get("username", None),
"password": conf_data_raw.get("account", {}).get("password", None),
}
}
print(_json.dumps(_conf_data, indent = "\t"))
def conf_get( def conf_get(
@ -41,12 +123,3 @@ def conf_get(
global _conf_data global _conf_data
return path_read(_conf_data, path.split(".")) return path_read(_conf_data, path.split("."))
def conf_set(
path : str,
value
):
global _conf_data
path_write(_conf_data, path.split("."), value)

View file

@ -1,3 +1,29 @@
def convey(x, fs):
y = x
for f in fs:
y = f(y)
return y
def string_coin(
template : str,
arguments : dict
):
result = template
for (key, value, ) in arguments.items():
result = result.replace("{{%s}}" % key, value)
return result
def file_read(
path : str
):
handle = open(path, "r")
content = handle.read()
handle.close()
return content
def log( def log(
messsage : str messsage : str
): ):
@ -16,30 +42,6 @@ def path_read(
return position return position
def path_write(
thing,
steps : List[str],
value
):
steps_first = steps[:-1]
step_last = steps[-1]
position = thing
for step in steps_first:
if (not (step in position)):
position[step] = {}
position = position[step]
position[step_last] = value
def merge(
core,
mantle
):
result = core.copy()
result.update(mantle)
return result
def http_call( def http_call(
request : dict, request : dict,
) -> dict: ) -> dict:

View file

@ -1,12 +1,13 @@
def main(
def args(
): ):
## args
argumentparser = _argparse.ArgumentParser( argumentparser = _argparse.ArgumentParser(
description = "INWX CLI Frontend" description = "INWX CLI Frontend"
) )
argumentparser.add_argument( argumentparser.add_argument(
"-c", "-c",
"--conf", "--conf",
type = str,
dest = "conf", dest = "conf",
default = _os.path.join(str(_pathlib.Path.home()), ".inwx-conf.json"), default = _os.path.join(str(_pathlib.Path.home()), ".inwx-conf.json"),
metavar = "<conf>", metavar = "<conf>",
@ -15,14 +16,16 @@ def args(
argumentparser.add_argument( argumentparser.add_argument(
"-e", "-e",
"--environment", "--environment",
type = str,
dest = "environment", dest = "environment",
metavar = "<environment>", metavar = "<environment>",
default = None, default = None,
help = "environment to use; one of the keys in the 'url' filed of the configuration; overwrites the configuration value", help = "environment to use; one of the keys in the 'url' file of the configuration; overwrites the configuration value",
) )
argumentparser.add_argument( argumentparser.add_argument(
"-u", "-u",
"--username", "--username",
type = str,
dest = "username", dest = "username",
metavar = "<username>", metavar = "<username>",
default = None, default = None,
@ -31,24 +34,52 @@ def args(
argumentparser.add_argument( argumentparser.add_argument(
"-p", "-p",
"--password", "--password",
type = str,
dest = "password", dest = "password",
metavar = "<password>", metavar = "<password>",
default = None, default = None,
help = "password; overwrites the configuration value", help = "password; overwrites the configuration value",
) )
'''
argumentparser.add_argument( argumentparser.add_argument(
"-d", "-b",
"--domain", "--domain-base",
dest = "domain", type = str,
dest = "domain_base",
default = None, default = None,
metavar = "<domain>", metavar = "<domain-base>",
help = "the domain to work with" help = "the domain, which holds the records"
)
argumentparser.add_argument(
"-n",
"--domain-path",
type = str,
dest = "domain_path",
default = None,
metavar = "<domain-path>",
help = "the record name/sub domain to work with"
)
argumentparser.add_argument(
"-t",
"--type",
type = str,
dest = "type",
default = None,
metavar = "<type>",
help = "the record type (A, AAAA, TXT, …)"
)
argumentparser.add_argument(
"-v",
"--value",
type = str,
dest = "value",
default = None,
metavar = "<value>",
help = "value for the record"
) )
'''
argumentparser.add_argument( argumentparser.add_argument(
"-x", "-x",
"--challenge-prefix", "--challenge-prefix",
type = str,
dest = "challenge_prefix", dest = "challenge_prefix",
metavar = "<challenge-prefix>", metavar = "<challenge-prefix>",
default = "_acme-challenge", default = "_acme-challenge",
@ -57,83 +88,161 @@ def args(
argumentparser.add_argument( argumentparser.add_argument(
"-w", "-w",
"--delay", "--delay",
dest = "delay",
type = float, type = float,
dest = "delay",
default = 60.0, default = 60.0,
metavar = "<delay>", metavar = "<delay>",
help = "seconds to wait at end of certbot auth hook", help = "seconds to wait at end of certbot auth hook",
) )
argumentparser.add_argument( argumentparser.add_argument(
"action",
type = str, type = str,
choices = ["info", "list", "save", "delete", "certbot-hook"], dest = "action",
choices = [
"conf-schema",
"info",
"list",
"save",
"delete",
"certbot-hook",
],
metavar = "<action>", metavar = "<action>",
help = "action to execute; options: info,list,save,delete,certbot-hook", help = string_coin(
"action to execute; options:\n{{options}}",
{
"options": convey(
[
{"name": "conf-schema", "requirements": []},
{"name": "info", "requirements": []},
{"name": "list", "requirements": ["<domain-base>"]},
{"name": "save", "requirements": ["<domain-base>", "<domain-path>", "<type>", "<value>"]},
{"name": "delete", "requirements": ["<domain-base>", "<domain-path>"]},
{"name": "certbot-hook", "requirements": []},
],
[
lambda x: map(
lambda entry: string_coin(
"{{name}}{{macro_requirements}}",
{
"name": entry["name"],
"macro_requirements": (
""
if (len(entry["requirements"]) <= 0) else
string_coin(
" (requires: {{requirements}})",
{
"requirements": ",".join(entry["requirements"]),
}
) )
argumentparser.add_argument( ),
"parameter", }
nargs = "*", ),
type = str, x
metavar = "<parameters>", ),
help = "action specific parameters", " | ".join,
]
)
}
),
) )
arguments = argumentparser.parse_args() arguments = argumentparser.parse_args()
return arguments
def main(
):
arguments = args()
## conf
conf_load(arguments.conf) conf_load(arguments.conf)
if (not (arguments.environment is None)): conf_set("environment", arguments.environment)
if (not (arguments.username is None)): conf_set("account.username", arguments.username)
if (not (arguments.password is None)): conf_set("account.password", arguments.password)
if (arguments.action == "info"): ## vars
environment = (arguments.environment or conf_get("environment"))
account_username = (arguments.username or conf_get("account.username"))
account_password = (arguments.password or conf_get("account.password"))
## exec
if (arguments.action == "conf-schema"):
print(_json.dumps(conf_schema(), indent = "\t"))
elif (arguments.action == "info"):
if (account_username is None):
raise ValueError("account username required")
else:
if (account_password is None):
raise ValueError("account password required")
else:
result = api_macro_info( result = api_macro_info(
conf_get("environment"), environment,
conf_get("account.username"), account_username,
conf_get("account.password") account_password
) )
print(_json.dumps(result, indent = "\t")) print(_json.dumps(result, indent = "\t"))
elif (arguments.action == "list"): elif (arguments.action == "list"):
domain = arguments.parameter[0] if (account_username is None):
raise ValueError("account username required")
else:
if (account_password is None):
raise ValueError("account password required")
else:
if (arguments.domain_base is None):
raise ValueError("domain base required")
else:
result = api_macro_list( result = api_macro_list(
conf_get("environment"), environment,
conf_get("account.username"), account_username,
conf_get("account.password"), account_password,
domain arguments.domain_base
) )
print(_json.dumps(result, indent = "\t")) print(_json.dumps(result, indent = "\t"))
elif (arguments.action == "save"): elif (arguments.action == "save"):
domain = arguments.parameter[0] if (account_username is None):
name = arguments.parameter[1] raise ValueError("account username required")
type_ = arguments.parameter[2] else:
content = arguments.parameter[3] if (account_password is None):
raise ValueError("account password required")
else:
if (arguments.domain_base is None):
raise ValueError("domain base required")
else:
if (arguments.domain_base is None):
raise ValueError("domain path required")
else:
if (arguments.type is None):
raise ValueError("type required")
else:
if (arguments.value is None):
raise ValueError("value required")
else:
api_macro_save( api_macro_save(
conf_get("environment"), environment,
conf_get("account.username"), account_username,
conf_get("account.password"), account_password,
domain, arguments.domain_base,
name, arguments.domain_path,
type_, arguments.type,
content arguments.value
) )
# print(_json.dumps(result, indent = "\t"))
elif (arguments.action == "delete"): elif (arguments.action == "delete"):
domain = arguments.parameter[0] if (account_username is None):
name = arguments.parameter[1] raise ValueError("account username required")
type_ = (arguments.parameter[2] if (len(arguments.parameter) >= 2) else None) else:
if (account_password is None):
raise ValueError("account password required")
else:
if (arguments.domain_base is None):
raise ValueError("domain base required")
else:
if (arguments.domain_base is None):
raise ValueError("domain path required")
else:
api_macro_delete( api_macro_delete(
conf_get("environment"), environment,
conf_get("account.username"), account_username,
conf_get("account.password"), account_password,
domain, arguments.domain_base,
name, arguments.domain_path,
type_ arguments.type
) )
elif (arguments.action == "certbot-hook"): elif (arguments.action == "certbot-hook"):
if (account_username is None):
raise ValueError("account username required")
else:
if (account_password is None):
raise ValueError("account password required")
else:
domain_full_parts = _os.environ["CERTBOT_DOMAIN"].split(".") domain_full_parts = _os.environ["CERTBOT_DOMAIN"].split(".")
account = ".".join(domain_full_parts[-2:]) account = ".".join(domain_full_parts[-2:])
concern = ".".join(domain_full_parts[:-2]) concern = ".".join(domain_full_parts[:-2])
@ -142,9 +251,9 @@ def main(
type_ = "TXT" type_ = "TXT"
content = _os.environ["CERTBOT_VALIDATION"] content = _os.environ["CERTBOT_VALIDATION"]
api_macro_save( api_macro_save(
conf_get("environment"), environment,
conf_get("account.username"), account_username,
conf_get("account.password"), account_password,
domain, domain,
name, name,
type_, type_,
@ -159,5 +268,5 @@ def main(
try: try:
main() main()
except ValueError as error: except ValueError as error:
_sys.stderr.write(str(error) + "\n") _sys.stderr.write("-- %s\n" % str(error))