diff --git a/portainer.py b/portainer.py index 53c2503..5b2f7ce 100644 --- a/portainer.py +++ b/portainer.py @@ -2,7 +2,24 @@ import os import requests import json import uuid -# portainer.py +import argparse +parser = argparse.ArgumentParser(description="Portainer helper - use env vars or pass credentials.") +parser.add_argument("--base", "-b", default=os.getenv("PORTAINER_URL", "https://portainer.example.com"), + help="Base URL for Portainer (ENV: PORTAINER_URL)") +parser.add_argument("--user", "-u", default=os.getenv("PORTAINER_USER"), + help="Portainer username (ENV: PORTAINER_USER)") +parser.add_argument("--password", "-p", default=os.getenv("PORTAINER_PASS"), + help="Portainer password (ENV: PORTAINER_PASS)") +parser.add_argument("--endpoint-id", "-e", type=int, help="Endpoint ID to limit stack operations") +parser.add_argument("--list-endpoints", action="store_true", help="List endpoints") +parser.add_argument("--list-stacks", action="store_true", help="List stacks") +parser.add_argument("--get-stack", metavar="NAME_OR_ID", help="Get stack by name or numeric id") +parser.add_argument("--create-stack", action='store_true') +parser.add_argument("--stack-id", "-s", type=str, help="Stack ID for operations") +parser.add_argument("--token-only", action="store_true", help="Print auth token and exit") +parser.add_argument("--timeout", type=int, default=10, help="Request timeout seconds") +args = parser.parse_args() + def get_portainer_token(base_url, username=None, password=None, timeout=10): """ @@ -81,7 +98,13 @@ def create_stack(base_url, token, endpoint_id=None, data={}, timeout=10): path = "/api/stacks/create/standalone/repository" if endpoint_id is not None: path += f"?endpointId={endpoint_id}" - stacks = api_post(base_url, path, token, data, timeout=timeout) + try: + stacks = api_post(base_url, path, token, data, timeout=timeout) + except Exception as e: + #print(f"Error creating stack: {e}") + if "Conflict for url" in str(e): + print("Stack with this name may already exist.") + return [] if stacks is None: return [] return stacks @@ -104,7 +127,7 @@ if __name__ == "__main__": for stack in stacks: print(f"Stack ID: {stack['Id']}, Name: {stack['Name']}") - stck = get_stack(base, "pihole", token) + stck = get_stack(base, args.stack_id, token) @@ -134,13 +157,13 @@ if __name__ == "__main__": "supportRelativePath": True, "repositoryAuthentication": True, "fromAppTemplate": False, - "registries": [], + "registries": [6], "FromAppTemplate": False, "Namespace": "", "CreatedByUserId": "", "Webhook": "", "filesystemPath": "/tmp", - "RegistryID": 6 + "RegistryID": 4 } except: req = { @@ -160,7 +183,7 @@ if __name__ == "__main__": "supportRelativePath": True, "repositoryAuthentication": True, "fromAppTemplate": False, - "registries": [], + "registries": [6], "FromAppTemplate": False, "Namespace": "", "CreatedByUserId": "", @@ -169,5 +192,7 @@ if __name__ == "__main__": "RegistryID": 6 } print(json.dumps(req, indent=2)) - - create_stack(base, token, 41, data=req) \ No newline at end of file + if args.create_stack: + create_stack(base, token, 41, data=req) + else: + print("Not creating stack, --create-stack not provided.") \ No newline at end of file