diff options
| author | 2024-11-20 01:17:40 -0500 | |
|---|---|---|
| committer | 2024-11-20 01:17:40 -0500 | |
| commit | 3e3ebe586385a83b10c8f1d0b9ba9b67c8b56d2f (patch) | |
| tree | 5682f748fc9867166043734aad44e1734d16abeb /pkb_client/cli | |
| parent | fa197fe27b8a03bbf4504476f842956ece2c76c9 (diff) | |
New upstream version 2.0.0.upstream/2.0.0
Diffstat (limited to 'pkb_client/cli')
| -rw-r--r-- | pkb_client/cli/__init__.py | 3 | ||||
| -rw-r--r-- | pkb_client/cli/cli.py | 347 |
2 files changed, 350 insertions, 0 deletions
diff --git a/pkb_client/cli/__init__.py b/pkb_client/cli/__init__.py new file mode 100644 index 0000000..ed32c05 --- /dev/null +++ b/pkb_client/cli/__init__.py @@ -0,0 +1,3 @@ +from .cli import main + +__all__ = ["main"] diff --git a/pkb_client/cli/cli.py b/pkb_client/cli/cli.py new file mode 100644 index 0000000..4bf53cd --- /dev/null +++ b/pkb_client/cli/cli.py @@ -0,0 +1,347 @@ +import argparse +import dataclasses +import json +import os +import textwrap +from datetime import datetime + +from pkb_client.client import PKBClient, API_ENDPOINT +from pkb_client.client.dns import DNSRecordType, DNSRestoreMode +from pkb_client.client.forwarding import URLForwardingType + + +class CustomJSONEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, datetime): + return o.isoformat() + if dataclasses.is_dataclass(o): + return dataclasses.asdict(o) + return super().default(o) + + +def main(): + parser = argparse.ArgumentParser( + description="Python client for the Porkbun API", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=textwrap.dedent(""" + License: + MIT - Copyright (c) Marvin Heptner + """), + ) + + parser.add_argument( + "-k", + "--key", + help='The API key used for Porkbun API calls (usually starts with "pk").', + ) + parser.add_argument( + "-s", + "--secret", + help='The API secret used for Porkbun API calls (usually starts with "sk").', + ) + parser.add_argument("--debug", help="Enable debug mode.", action="store_true") + parser.add_argument( + "--endpoint", help="The API endpoint to use.", default=API_ENDPOINT + ) + + subparsers = parser.add_subparsers(help="Supported API methods") + + parser_ping = subparsers.add_parser("ping", help="Ping the API Endpoint") + parser_ping.set_defaults(func=PKBClient.ping) + + parser_dns_create = subparsers.add_parser( + "create-dns-record", help="Create a new DNS record." + ) + parser_dns_create.set_defaults(func=PKBClient.create_dns_record) + parser_dns_create.add_argument( + "domain", help="The domain for which the new DNS record should be created." + ) + parser_dns_create.add_argument( + "record_type", + help="The type of the new DNS record.", + choices=list(DNSRecordType), + ) + parser_dns_create.add_argument("content", help="The content of the new DNS record.") + parser_dns_create.add_argument( + "--name", + help="The subdomain for which the new DNS record should be created." + "The * can be used for a wildcard DNS record." + "If not used, then a DNS record for the root domain will be created", + required=False, + ) + parser_dns_create.add_argument( + "--ttl", type=int, help="The ttl of the new DNS record.", required=False + ) + parser_dns_create.add_argument( + "--prio", type=int, help="The priority of the new DNS record.", required=False + ) + + parser_dns_edit = subparsers.add_parser( + "update-dns-record", help="Edit an existing DNS record." + ) + parser_dns_edit.set_defaults(func=PKBClient.update_dns_record) + parser_dns_edit.add_argument( + "domain", help="The domain for which the DNS record should be edited." + ) + parser_dns_edit.add_argument( + "record_id", help="The id of the DNS record which should be edited." + ) + parser_dns_edit.add_argument( + "record_type", + help="The new type of the DNS record.", + choices=list(DNSRecordType), + ) + parser_dns_edit.add_argument("content", help="The new content of the DNS record.") + parser_dns_edit.add_argument( + "--name", + help="The new value of the subdomain for which the DNS record should apply. " + "The * can be used for a wildcard DNS record. If not set, the record will " + "be set for the root domain.", + required=False, + ) + parser_dns_edit.add_argument( + "--ttl", type=int, help="The new ttl of the DNS record.", required=False + ) + parser_dns_edit.add_argument( + "--prio", type=int, help="The new priority of the DNS record.", required=False + ) + + parser_dns_delete = subparsers.add_parser( + "delete-dns-records", help="Delete an existing DNS record." + ) + parser_dns_delete.set_defaults(func=PKBClient.delete_dns_record) + parser_dns_delete.add_argument( + "domain", help="The domain for which the DNS record should be deleted." + ) + parser_dns_delete.add_argument( + "record_id", help="The id of the DNS record which should be deleted." + ) + + parser_dns_receive = subparsers.add_parser( + "get-dns-records", help="Get all DNS records." + ) + parser_dns_receive.set_defaults(func=PKBClient.get_dns_records) + parser_dns_receive.add_argument( + "domain", help="The domain for which the DNS record should be retrieved." + ) + + parser_dns_export = subparsers.add_parser( + "export-dns-records", help="Save all DNS records to a local json file." + ) + parser_dns_export.set_defaults(func=PKBClient.export_dns_records) + parser_dns_export.add_argument( + "domain", + help="The domain for which the DNS record should be retrieved and saved.", + ) + parser_dns_export.add_argument( + "filepath", help="The filepath where to save the exported DNS records." + ) + + parser_dns_export_bind = subparsers.add_parser( + "export-bind-dns-records", help="Save all DNS records to a local BIND file." + ) + parser_dns_export_bind.set_defaults(func=PKBClient.export_bind_dns_records) + parser_dns_export_bind.add_argument( + "domain", + help="The domain for which the DNS record should be retrieved and saved.", + ) + parser_dns_export_bind.add_argument( + "filepath", help="The filepath where to save the exported DNS records." + ) + + parser_dns_import = subparsers.add_parser( + "import-dns-records", + help="Restore all DNS records from a local json file.", + formatter_class=argparse.RawTextHelpFormatter, + ) + parser_dns_import.set_defaults(func=PKBClient.import_dns_records) + parser_dns_import.add_argument( + "domain", help="The domain for which the DNS record should be restored." + ) + parser_dns_import.add_argument( + "filepath", help="The filepath from which the DNS records are to be restored." + ) + parser_dns_import.add_argument( + "restore_mode", + help="""The restore mode (DNS records are identified by the record type, name and prio if supported): + clear: remove all existing DNS records and restore all DNS records from the provided file + replace: replace only existing DNS records with the DNS records from the provided file, but do not create any new DNS records + keep: keep the existing DNS records and only create new ones for all DNS records from the specified file if they do not exist + """, + type=DNSRestoreMode.from_string, + choices=list(DNSRestoreMode), + ) + + parser_dns_import_bind = subparsers.add_parser( + "import-bind-dns-records", + help="Restore all DNS records from a local BIND file.", + formatter_class=argparse.RawTextHelpFormatter, + ) + parser_dns_import_bind.set_defaults(func=PKBClient.import_bind_dns_records) + parser_dns_import_bind.add_argument( + "filepath", help="The filepath from which the DNS records are to be restored." + ) + parser_dns_import_bind.add_argument( + "restore_mode", + help="""The restore mode (DNS records are identified by the record id): + clear: remove all existing DNS records and restore all DNS records from the provided file + """, + type=DNSRestoreMode.from_string, + choices=[DNSRestoreMode.clear], + ) + + parser_domain_pricing = subparsers.add_parser( + "get-domain-pricing", help="Get the pricing for Porkbun domains." + ) + parser_domain_pricing.set_defaults(func=PKBClient.get_domain_pricing) + + parser_ssl_retrieve = subparsers.add_parser( + "get-ssl-bundle", help="Retrieve an SSL bundle for given domain." + ) + parser_ssl_retrieve.set_defaults(func=PKBClient.get_ssl_bundle) + parser_ssl_retrieve.add_argument( + "domain", help="The domain for which the SSL bundle should be retrieve." + ) + + parser_update_dns_server = subparsers.add_parser( + "update-dns-servers", help="Update the DNS servers for a domain." + ) + parser_update_dns_server.set_defaults(func=PKBClient.update_dns_servers) + parser_update_dns_server.add_argument( + "domain", help="The domain for which the DNS servers should be set." + ) + parser_update_dns_server.add_argument( + "dns_servers", nargs="+", help="The DNS servers to be set." + ) + + parser_get_dns_server = subparsers.add_parser( + "get-dns-servers", help="Retrieve the DNS servers for a domain." + ) + parser_get_dns_server.set_defaults(func=PKBClient.get_dns_servers) + parser_get_dns_server.add_argument( + "domain", help="The domain for which the DNS servers should be retrieved." + ) + + parser_list_domains = subparsers.add_parser( + "get-domains", help="List all domains in this account in chunks of 1000." + ) + parser_list_domains.set_defaults(func=PKBClient.get_domains) + parser_list_domains.add_argument( + "--start", + type=int, + help="The start index of the list.", + default=0, + required=False, + ) + + parser_get_url_forward = subparsers.add_parser( + "get-url-forwards", help="Retrieve all URL forwards." + ) + parser_get_url_forward.set_defaults(func=PKBClient.get_url_forwards) + parser_get_url_forward.add_argument( + "domain", help="The domain for which the URL forwards should be retrieved." + ) + + parser_add_url_forward = subparsers.add_parser( + "create-url-forward", help="Create a new URL forward." + ) + parser_add_url_forward.set_defaults(func=PKBClient.create_url_forward) + parser_add_url_forward.add_argument( + "domain", help="The domain for which the new URL forward should be created." + ) + parser_add_url_forward.add_argument( + "location", + help="The location to which the url forwarding should redirect.", + ) + parser_add_url_forward.add_argument( + "type", help="The type of the url forwarding.", choices=list(URLForwardingType) + ) + parser_add_url_forward.add_argument( + "--subdomain", + help="The subdomain for which the url forwarding should be added.", + required=False, + default="", + ) + parser_add_url_forward.add_argument( + "--include-path", + help="Whether the path should be included in the url forwarding.", + action="store_true", + default=False, + ) + parser_add_url_forward.add_argument( + "--wildcard", + help="Whether the url forwarding should be also applied to subdomains.", + action="store_true", + default=False, + ) + + parser_delete_url_forward = subparsers.add_parser( + "delete-url-forward", help="Delete an existing URL forward." + ) + parser_delete_url_forward.set_defaults(func=PKBClient.delete_url_forward) + parser_delete_url_forward.add_argument( + "domain", help="The domain for which the URL forward should be deleted." + ) + parser_delete_url_forward.add_argument( + "id", help="The id of the URL forward which should be deleted." + ) + + args = vars(parser.parse_args()) + + debug = args.pop("debug", False) + + func = args.pop("func", None) + if not func: + raise argparse.ArgumentError( + None, "No method specified. Please provide a method and try again." + ) + + endpoint = args.pop("endpoint") + api_key = args.pop("key") + api_secret = args.pop("secret") + + # call the api methods which do not require authentication + if func == PKBClient.get_domain_pricing: + pkb_client = PKBClient(api_endpoint=endpoint, debug=debug) + ret = func(pkb_client, **args) + + print(json.dumps(ret, cls=CustomJSONEncoder, indent=4)) + exit(0) + + if api_key is None: + # try to get the api key from the environment variable or fallback to user input + api_key = os.environ.get("PKB_API_KEY", "") + if len(api_key.strip()) == 0: + while True: + api_key = input( + 'Please enter your API key you got from Porkbun (usually starts with "pk"): ' + ) + if len(api_key.strip()) == 0: + print("The api key can not be empty.") + else: + break + + if api_secret is None: + # try to get the api secret from the environment variable or fallback to user input + api_secret = os.environ.get("PKB_API_SECRET", "") + if len(api_secret.strip()) == 0: + while True: + api_secret = input( + 'Please enter your API key secret you got from Porkbun (usually starts with "sk"): ' + ) + if len(api_secret.strip()) == 0: + print("The api key secret can not be empty.") + else: + break + + pkb_client = PKBClient( + api_key=api_key, secret_api_key=api_secret, api_endpoint=endpoint, debug=debug + ) + + ret = func(pkb_client, **args) + + print(json.dumps(ret, cls=CustomJSONEncoder, indent=4)) + + +if __name__ == "__main__": + main() |
