This commit is contained in:
2025-12-04 20:06:22 +01:00
parent cce4c5eb9b
commit f8b0acdfcc
2 changed files with 42 additions and 22 deletions

32
port.py
View File

@@ -23,9 +23,10 @@ class Portainer:
to perform API operations. to perform API operations.
""" """
def __init__(self, base_url, token, timeout=10): def __init__(self, site, timeout=10):
self.base_url = base_url.rstrip("/") self.base_url = None
self.token = token self.token = None
self._debug = False
self.timeout = timeout self.timeout = timeout
self.git_url = "git@gitlab.sectorq.eu:home/docker-compose.git" self.git_url = "git@gitlab.sectorq.eu:home/docker-compose.git"
self.stack_name = None self.stack_name = None
@@ -103,9 +104,22 @@ class Portainer:
self.log_mode = False self.log_mode = False
self.hw_mode = False self.hw_mode = False
self.all_data = {"containers": {}, "stacks": {}, "endpoints": {}} self.all_data = {"containers": {}, "stacks": {}, "endpoints": {}}
self.get_site(site)
self.get_endpoints() self.get_endpoints()
self.get_stacks() self.get_stacks()
self.get_containers() self.get_containers()
def get_site(self, site):
if site == "portainer":
self.base_url = os.getenv("PORTAINER_URL", "https://portainer.sectorq.eu/api")
self.token = "ptr_GCNUoFcTOaXm7k8ZxPdQGmrFIamxZPTydbserYofMHc="
elif site == "port":
self.base_url = os.getenv("PORTAINER_URL", "https://port.sectorq.eu/api")
self.token = "ptr_/5RkMCT/j3BTaL32vMSDtXFi76yOXRKVFOrUtzMsl5Y="
else:
self.base_url = os.getenv("PORTAINER_URL", "https://portainer.sectorq.eu/api")
self.token = "ptr_GCNUoFcTOaXm7k8ZxPdQGmrFIamxZPTydbserYofMHc="
def _is_number(self, s): def _is_number(self, s):
"""Check if the input string is a number.""" """Check if the input string is a number."""
@@ -445,9 +459,9 @@ class Portainer:
stack=None, stack=None,
mode="git", mode="git",
autostart=False, autostart=False,
swarm=False, stack_mode='swarm',
): ):
if swarm: if stack_mode == 'swarm':
swarm_id = self.get_swarm_id(endpoint) swarm_id = self.get_swarm_id(endpoint)
p = "swarm" p = "swarm"
env_path = f"{self.repo_dir}/__swarm/{stack}/.env" env_path = f"{self.repo_dir}/__swarm/{stack}/.env"
@@ -463,6 +477,7 @@ class Portainer:
Repo.clone_from(self.git_url, self.repo_dir) Repo.clone_from(self.git_url, self.repo_dir)
if mode == "git": if mode == "git":
path = f"/stacks/create/{p}/repository" path = f"/stacks/create/{p}/repository"
print(p)
if self.endpoint_id is not None: if self.endpoint_id is not None:
path += f"?endpointId={self.endpoint_id}" path += f"?endpointId={self.endpoint_id}"
@@ -556,7 +571,7 @@ class Portainer:
"method": "repository", "method": "repository",
"swarmID": None, "swarmID": None,
} }
if swarm: if stack_mode == 'swarm':
req["type"] = "swarm" req["type"] = "swarm"
req["swarmID"] = swarm_id req["swarmID"] = swarm_id
req["composeFile"] = f"__swarm/{stack}/{stack}-swarm.yml" req["composeFile"] = f"__swarm/{stack}/{stack}-swarm.yml"
@@ -749,8 +764,11 @@ class Portainer:
def _resolve_endpoint(self, endpoint_id): def _resolve_endpoint(self, endpoint_id):
self.get_endpoints() self.get_endpoints()
if self._debug:
print(endpoint_id)
print(self.endpoints)
if self._is_number(endpoint_id): if self._is_number(endpoint_id):
self.endpoint_id = int(endpoint_id) self.endpoint_id = int(endpoint_id)
self.endpoint_name = self.endpoints["by_id"][self.endpoint_id] self.endpoint_name = self.endpoints["by_id"][self.endpoint_id]

View File

@@ -175,12 +175,6 @@ logging.info("script started")
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
if args.site == "portainer":
base = os.getenv("PORTAINER_URL", "https://portainer.sectorq.eu/api")
PORTAINER_API_KEY = "ptr_GCNUoFcTOaXm7k8ZxPdQGmrFIamxZPTydbserYofMHc="
else:
base = os.getenv("PORTAINER_URL", "https://port.sectorq.eu/api")
PORTAINER_API_KEY = "ptr_/5RkMCT/j3BTaL32vMSDtXFi76yOXRKVFOrUtzMsl5Y="
def wl(msg): def wl(msg):
@@ -192,8 +186,8 @@ def prompt_missing_args(args_in, defaults_in, fields):
""" """
fields = [("arg_name", "Prompt text")] fields = [("arg_name", "Prompt text")]
""" """
def input_with_default(prompt, default): def input_with_default(prompt, default, longest):
full_prompt = f" >> {prompt:40}" full_prompt = f" >> {prompt:{longest}}"
sys.stdout.write(full_prompt) sys.stdout.write(full_prompt)
sys.stdout.flush() sys.stdout.flush()
checkmark = "\033[92m\u2714\033[0m" checkmark = "\033[92m\u2714\033[0m"
@@ -225,25 +219,32 @@ def prompt_missing_args(args_in, defaults_in, fields):
# rewrite final line cleanly # rewrite final line cleanly
sys.stdout.write(f"\r{full_prompt}{user_input:10} {checkmark}\n") sys.stdout.write(f"\r{full_prompt}{user_input:10} {checkmark}\n")
sys.stdout.flush() sys.stdout.flush()
return user_input return user_input
longest = 0
for field, text in fields:
a = text + " (default= " + cur_config["PORTAINER_" + field.upper()] + ")"
if len(a) > longest:
longest = len(a)
for field, text in fields: for field, text in fields:
value_in = getattr(args_in, field) value_in = getattr(args_in, field)
default = defaults_in.get(f"PORTAINER_{field}".upper()) default = defaults_in.get(f"PORTAINER_{field}".upper())
cur_site = defaults_in.get("PORTAINER_SITE".upper())
if value_in is None: if value_in is None:
if default is not None: if default is not None:
prompt = f"{text} (default={default}) : " prompt = f"{text} (default={default}) : "
# value_in = input(prompt) or default # value_in = input(prompt) or default
value_in = input_with_default(prompt, default) value_in = input_with_default(prompt, default, longest+2)
defaults_in[f"PORTAINER_{field}".upper()] = value_in defaults_in[f"PORTAINER_{field}".upper()] = value_in
else: else:
#value_in = input(f"{text}: ") #value_in = input(f"{text}: ")
value_in = input_with_default(text, default) value_in = input_with_default(text, default, longest+2)
defaults_in[f"PORTAINER_{field}".upper()] = value_in defaults_in[f"PORTAINER_{field}".upper()] = value_in
setattr(args, field, value_in) setattr(args, field, value_in)
os.environ[field] = value_in os.environ[field] = value_in
if field == "site" and value_in != cur_site:
por.get_site(value_in)
with open("/myapps/portainer.conf", "w") as f: with open("/myapps/portainer.conf", "w") as f:
for k in defaults_in.keys(): for k in defaults_in.keys():
f.write(f"{k}={defaults_in[k]}\n") f.write(f"{k}={defaults_in[k]}\n")
@@ -288,8 +289,9 @@ if __name__ == "__main__":
args.action = actions[int(ans) - 1] args.action = actions[int(ans) - 1]
os.system("cls" if os.name == "nt" else "clear") os.system("cls" if os.name == "nt" else "clear")
# Example: list endpoints # Example: list endpoints
por = Portainer(base, PORTAINER_API_KEY, timeout=args.timeout) por = Portainer(defaults['site'], timeout=args.timeout)
if args.debug:
por._debug = True
if args.action == "secrets": if args.action == "secrets":
if args.endpoint_id is None: if args.endpoint_id is None:
args.endpoint_id = input("Endpoint ID is required for creating secrets : ") args.endpoint_id = input("Endpoint ID is required for creating secrets : ")