2024-05-31 11:24:53 +02:00
|
|
|
def main(
|
2020-05-04 22:06:03 +02:00
|
|
|
):
|
2024-05-31 11:24:53 +02:00
|
|
|
## args
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser = _argparse.ArgumentParser(
|
2020-05-04 22:06:03 +02:00
|
|
|
description = "INWX CLI Frontend"
|
|
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2023-05-29 12:03:38 +02:00
|
|
|
"-c",
|
|
|
|
|
"--conf",
|
2024-05-31 11:24:53 +02:00
|
|
|
type = str,
|
2020-05-04 22:06:03 +02:00
|
|
|
dest = "conf",
|
2023-05-29 12:03:38 +02:00
|
|
|
default = _os.path.join(str(_pathlib.Path.home()), ".inwx-conf.json"),
|
|
|
|
|
metavar = "<conf>",
|
|
|
|
|
help = "path to configuration file",
|
2020-05-04 22:06:03 +02:00
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2023-05-29 12:03:38 +02:00
|
|
|
"-e",
|
|
|
|
|
"--environment",
|
2024-05-31 11:24:53 +02:00
|
|
|
type = str,
|
2020-05-04 22:06:03 +02:00
|
|
|
dest = "environment",
|
2023-05-29 12:03:38 +02:00
|
|
|
metavar = "<environment>",
|
|
|
|
|
default = None,
|
2024-05-31 14:06:58 +02:00
|
|
|
help = "environment to use; one of the keys in the 'url' node of the configuration; overwrites the configuration value",
|
2020-05-04 22:06:03 +02:00
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2023-05-29 12:03:38 +02:00
|
|
|
"-u",
|
|
|
|
|
"--username",
|
2024-05-31 11:24:53 +02:00
|
|
|
type = str,
|
2020-05-04 22:06:03 +02:00
|
|
|
dest = "username",
|
2023-05-29 12:03:38 +02:00
|
|
|
metavar = "<username>",
|
|
|
|
|
default = None,
|
|
|
|
|
help = "username; overwrites the configuration value",
|
2020-05-04 22:06:03 +02:00
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2023-05-29 12:03:38 +02:00
|
|
|
"-p",
|
|
|
|
|
"--password",
|
2024-05-31 11:24:53 +02:00
|
|
|
type = str,
|
2020-05-04 22:06:03 +02:00
|
|
|
dest = "password",
|
2023-05-29 12:03:38 +02:00
|
|
|
metavar = "<password>",
|
|
|
|
|
default = None,
|
|
|
|
|
help = "password; overwrites the configuration value",
|
2020-05-04 22:06:03 +02:00
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
|
|
|
|
"-d",
|
|
|
|
|
"--domain",
|
2024-05-31 11:24:53 +02:00
|
|
|
type = str,
|
2024-05-31 14:06:58 +02:00
|
|
|
dest = "domain",
|
2024-05-31 11:24:53 +02:00
|
|
|
default = None,
|
2024-05-31 14:06:58 +02:00
|
|
|
metavar = "<domain>",
|
|
|
|
|
help = "the domain to work with"
|
2024-05-31 11:24:53 +02:00
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2024-05-31 11:24:53 +02:00
|
|
|
"-t",
|
|
|
|
|
"--type",
|
|
|
|
|
type = str,
|
|
|
|
|
dest = "type",
|
|
|
|
|
default = None,
|
|
|
|
|
metavar = "<type>",
|
|
|
|
|
help = "the record type (A, AAAA, TXT, …)"
|
|
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2024-05-31 11:24:53 +02:00
|
|
|
"-v",
|
|
|
|
|
"--value",
|
|
|
|
|
type = str,
|
|
|
|
|
dest = "value",
|
2023-05-29 12:03:38 +02:00
|
|
|
default = None,
|
2024-05-31 11:24:53 +02:00
|
|
|
metavar = "<value>",
|
|
|
|
|
help = "value for the record"
|
2020-05-04 22:06:03 +02:00
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2023-05-29 12:03:38 +02:00
|
|
|
"-x",
|
|
|
|
|
"--challenge-prefix",
|
2024-05-31 11:24:53 +02:00
|
|
|
type = str,
|
2023-05-29 12:03:38 +02:00
|
|
|
dest = "challenge_prefix",
|
|
|
|
|
metavar = "<challenge-prefix>",
|
|
|
|
|
default = "_acme-challenge",
|
|
|
|
|
help = "which subdomain to use for ACME challanges",
|
|
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2023-05-29 12:03:38 +02:00
|
|
|
"-w",
|
|
|
|
|
"--delay",
|
2023-05-29 11:39:33 +02:00
|
|
|
type = float,
|
2024-05-31 11:24:53 +02:00
|
|
|
dest = "delay",
|
2023-05-29 11:39:33 +02:00
|
|
|
default = 60.0,
|
2023-05-29 12:03:38 +02:00
|
|
|
metavar = "<delay>",
|
2023-05-29 11:39:33 +02:00
|
|
|
help = "seconds to wait at end of certbot auth hook",
|
|
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
argument_parser.add_argument(
|
2023-05-29 12:03:38 +02:00
|
|
|
type = str,
|
2024-05-31 11:24:53 +02:00
|
|
|
dest = "action",
|
|
|
|
|
choices = [
|
|
|
|
|
"conf-schema",
|
|
|
|
|
"info",
|
|
|
|
|
"list",
|
|
|
|
|
"save",
|
|
|
|
|
"delete",
|
|
|
|
|
"certbot-hook",
|
|
|
|
|
],
|
2023-05-29 12:03:38 +02:00
|
|
|
metavar = "<action>",
|
2024-05-31 11:24:53 +02:00
|
|
|
help = string_coin(
|
|
|
|
|
"action to execute; options:\n{{options}}",
|
|
|
|
|
{
|
|
|
|
|
"options": convey(
|
|
|
|
|
[
|
|
|
|
|
{"name": "conf-schema", "requirements": []},
|
|
|
|
|
{"name": "info", "requirements": []},
|
2024-05-31 14:06:58 +02:00
|
|
|
{"name": "list", "requirements": ["<domain>"]},
|
|
|
|
|
{"name": "save", "requirements": ["<domain>", "<type>", "<value>"]},
|
|
|
|
|
{"name": "delete", "requirements": ["<domain>"]},
|
2024-05-31 11:24:53 +02:00
|
|
|
{"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"]),
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
x
|
|
|
|
|
),
|
|
|
|
|
" | ".join,
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
),
|
2020-05-04 22:06:03 +02:00
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
args = argument_parser.parse_args()
|
2020-05-04 22:06:03 +02:00
|
|
|
|
2024-05-31 11:24:53 +02:00
|
|
|
## conf
|
2024-05-31 14:06:58 +02:00
|
|
|
conf_load(args.conf)
|
2020-05-04 22:06:03 +02:00
|
|
|
|
2024-05-31 11:24:53 +02:00
|
|
|
## vars
|
2024-05-31 14:06:58 +02:00
|
|
|
environment = (args.environment or conf_get("environment"))
|
|
|
|
|
account_username = (args.username or conf_get("account.username"))
|
|
|
|
|
account_password = (args.password or conf_get("account.password"))
|
|
|
|
|
domain_parts = (None if (args.domain is None) else args.domain.split("."))
|
|
|
|
|
domain_base = (None if (domain_parts is None) else ".".join(domain_parts[-2:]))
|
|
|
|
|
domain_path = (None if ((domain_parts is None) or (len(domain_parts[:-2]) <= 0)) else ".".join(domain_parts[:-2]))
|
2024-05-31 11:24:53 +02:00
|
|
|
|
|
|
|
|
## exec
|
2024-05-31 14:06:58 +02:00
|
|
|
if (args.action == "conf-schema"):
|
2024-05-31 11:24:53 +02:00
|
|
|
print(_json.dumps(conf_schema(), indent = "\t"))
|
2024-05-31 14:06:58 +02:00
|
|
|
elif (args.action == "info"):
|
2024-05-31 11:24:53 +02:00
|
|
|
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(
|
|
|
|
|
environment,
|
|
|
|
|
account_username,
|
|
|
|
|
account_password
|
|
|
|
|
)
|
|
|
|
|
print(_json.dumps(result, indent = "\t"))
|
2024-05-31 14:06:58 +02:00
|
|
|
elif (args.action == "list"):
|
2024-05-31 11:24:53 +02:00
|
|
|
if (account_username is None):
|
|
|
|
|
raise ValueError("account username required")
|
|
|
|
|
else:
|
|
|
|
|
if (account_password is None):
|
|
|
|
|
raise ValueError("account password required")
|
|
|
|
|
else:
|
2024-06-01 12:43:23 +02:00
|
|
|
if (args.domain is None):
|
|
|
|
|
raise ValueError("domain required")
|
2024-05-31 11:24:53 +02:00
|
|
|
else:
|
|
|
|
|
result = api_macro_list(
|
|
|
|
|
environment,
|
|
|
|
|
account_username,
|
|
|
|
|
account_password,
|
2024-05-31 14:06:58 +02:00
|
|
|
domain_base
|
2024-05-31 11:24:53 +02:00
|
|
|
)
|
|
|
|
|
print(_json.dumps(result, indent = "\t"))
|
2024-05-31 14:06:58 +02:00
|
|
|
elif (args.action == "save"):
|
2024-05-31 11:24:53 +02:00
|
|
|
if (account_username is None):
|
|
|
|
|
raise ValueError("account username required")
|
|
|
|
|
else:
|
|
|
|
|
if (account_password is None):
|
|
|
|
|
raise ValueError("account password required")
|
|
|
|
|
else:
|
2024-05-31 14:06:58 +02:00
|
|
|
if (args.domain is None):
|
|
|
|
|
raise ValueError("domain required")
|
2024-05-31 11:24:53 +02:00
|
|
|
else:
|
2024-05-31 14:06:58 +02:00
|
|
|
if (args.type is None):
|
|
|
|
|
raise ValueError("type required")
|
2024-05-31 11:24:53 +02:00
|
|
|
else:
|
2024-05-31 14:06:58 +02:00
|
|
|
if (args.value is None):
|
|
|
|
|
raise ValueError("value required")
|
2024-05-31 11:24:53 +02:00
|
|
|
else:
|
2024-05-31 14:06:58 +02:00
|
|
|
api_macro_save(
|
|
|
|
|
environment,
|
|
|
|
|
account_username,
|
|
|
|
|
account_password,
|
|
|
|
|
domain_base,
|
|
|
|
|
domain_path,
|
|
|
|
|
args.type,
|
|
|
|
|
args.value
|
2024-05-31 11:24:53 +02:00
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
elif (args.action == "delete"):
|
2024-05-31 11:24:53 +02:00
|
|
|
if (account_username is None):
|
|
|
|
|
raise ValueError("account username required")
|
|
|
|
|
else:
|
|
|
|
|
if (account_password is None):
|
|
|
|
|
raise ValueError("account password required")
|
|
|
|
|
else:
|
2024-05-31 14:06:58 +02:00
|
|
|
if (args.domain is None):
|
|
|
|
|
raise ValueError("domain required")
|
2024-05-31 11:24:53 +02:00
|
|
|
else:
|
2024-05-31 14:06:58 +02:00
|
|
|
api_macro_delete(
|
|
|
|
|
environment,
|
|
|
|
|
account_username,
|
|
|
|
|
account_password,
|
|
|
|
|
domain_base,
|
|
|
|
|
domain_path,
|
|
|
|
|
args.type
|
|
|
|
|
)
|
|
|
|
|
elif (args.action == "certbot-hook"):
|
2024-05-31 11:24:53 +02:00
|
|
|
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(".")
|
2024-05-31 14:06:58 +02:00
|
|
|
domain_base = ".".join(domain_full_parts[-2:])
|
|
|
|
|
domain_path_stripped = ".".join(domain_full_parts[:-2])
|
|
|
|
|
domain_path = (args.challenge_prefix + "." + domain_path_stripped)
|
2024-05-31 11:24:53 +02:00
|
|
|
type_ = "TXT"
|
|
|
|
|
content = _os.environ["CERTBOT_VALIDATION"]
|
|
|
|
|
api_macro_save(
|
|
|
|
|
environment,
|
|
|
|
|
account_username,
|
|
|
|
|
account_password,
|
2024-05-31 14:06:58 +02:00
|
|
|
domain_base,
|
|
|
|
|
domain_path,
|
2024-05-31 11:24:53 +02:00
|
|
|
type_,
|
|
|
|
|
content
|
|
|
|
|
)
|
2024-05-31 14:06:58 +02:00
|
|
|
_time.sleep(args.delay)
|
2024-05-31 11:24:53 +02:00
|
|
|
# print(_json.dumps(result, indent = "\t"))
|
2020-05-04 22:06:03 +02:00
|
|
|
else:
|
2024-05-31 14:06:58 +02:00
|
|
|
log("unhandled action '%s'" % (args.action, ))
|
2020-05-04 22:06:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
main()
|
|
|
|
|
except ValueError as error:
|
2024-05-31 11:24:53 +02:00
|
|
|
_sys.stderr.write("-- %s\n" % str(error))
|
2020-05-04 22:06:03 +02:00
|
|
|
|