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