mirror of
https://gitlab.sectorq.eu/jaydee/portainer.git
synced 2025-12-14 10:44:52 +01:00
build
This commit is contained in:
92
port.py
92
port.py
@@ -2,15 +2,15 @@ import os
|
||||
import requests
|
||||
import json
|
||||
import uuid
|
||||
import argparse
|
||||
import shutil
|
||||
import time
|
||||
import logging
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from tabulate import tabulate
|
||||
from git import Repo # pip install gitpython
|
||||
import base64
|
||||
|
||||
|
||||
class Portainer:
|
||||
"""
|
||||
Simple wrapper around the module-level Portainer helper functions.
|
||||
@@ -28,22 +28,83 @@ class Portainer:
|
||||
self.stack_ids = []
|
||||
self.endpoint_name = None
|
||||
self.endpoint_id = None
|
||||
#self.git_url = "https://gitlab.sectorq.eu/home/docker-compose.git"
|
||||
# self.git_url = "https://gitlab.sectorq.eu/home/docker-compose.git"
|
||||
self.git_url = "git@gitlab.sectorq.eu:home/docker-compose.git"
|
||||
self.repo_dir = "/tmp/docker-compose"
|
||||
self.basic_stacks = ["pihole","nginx", "mosquitto", "webhub", "authentik","bitwarden","mailu3","home-assistant","homepage"]
|
||||
self.nas_stacks = self.basic_stacks + ["gitlab", "bookstack","dockermon","gitea","grafana","immich","jupyter","kestra","mealie"]
|
||||
self.m_server_stacks = self.basic_stacks + ['immich', 'zabbix-server', 'gitea', 'unifibrowser', 'mediacenter', 'watchtower', 'wazuh', 'octoprint', 'motioneye', 'kestra', 'bookstack', 'wud', 'uptime-kuma', 'registry', 'regsync', 'dockermon', 'grafana', 'nextcloud', 'semaphore', 'node-red', 'test', 'jupyter', 'paperless', 'mealie', 'n8n', 'ollama', 'rancher']
|
||||
self.rpi5_stacks = self.basic_stacks + ["gitlab","bookstack","gitea"]
|
||||
self.rack_stacks = self.basic_stacks + ["gitlab", "bookstack","dockermon","gitea","grafana","immich","jupyter","kestra","mealie"]
|
||||
self.basic_stacks = [
|
||||
"pihole",
|
||||
"nginx",
|
||||
"mosquitto",
|
||||
"webhub",
|
||||
"authentik",
|
||||
"bitwarden",
|
||||
"mailu3",
|
||||
"home-assistant",
|
||||
"homepage"
|
||||
]
|
||||
self.nas_stacks = self.basic_stacks + [
|
||||
"gitlab",
|
||||
"bookstack",
|
||||
"dockermon",
|
||||
"gitea",
|
||||
"grafana",
|
||||
"immich",
|
||||
"jupyter",
|
||||
"kestra",
|
||||
"mealie"
|
||||
]
|
||||
self.m_server_stacks = self.basic_stacks + [
|
||||
'immich',
|
||||
'zabbix-server',
|
||||
'gitea',
|
||||
'unifibrowser',
|
||||
'mediacenter',
|
||||
'watchtower',
|
||||
'wazuh',
|
||||
'octoprint',
|
||||
'motioneye',
|
||||
'kestra',
|
||||
'bookstack',
|
||||
'wud',
|
||||
'uptime-kuma',
|
||||
'registry',
|
||||
'regsync',
|
||||
'dockermon',
|
||||
'grafana',
|
||||
'nextcloud',
|
||||
'semaphore',
|
||||
'node-red',
|
||||
'test',
|
||||
'jupyter',
|
||||
'paperless',
|
||||
'mealie',
|
||||
'n8n',
|
||||
'ollama',
|
||||
'rancher'
|
||||
]
|
||||
self.rpi5_stacks = self.basic_stacks + [
|
||||
"gitlab",
|
||||
"bookstack",
|
||||
"gitea"
|
||||
]
|
||||
self.rack_stacks = self.basic_stacks + [
|
||||
"gitlab",
|
||||
"bookstack",
|
||||
"dockermon",
|
||||
"gitea",
|
||||
"grafana",
|
||||
"immich",
|
||||
"jupyter",
|
||||
"kestra",
|
||||
"mealie"
|
||||
]
|
||||
self.log_mode = False
|
||||
self.hw_mode = False
|
||||
self.all_data = {"containers":{},"stacks":{},"endpoints":{}}
|
||||
self.all_data = {"containers": {}, "stacks": {}, "endpoints": {}}
|
||||
self.get_endpoints()
|
||||
self.get_stacks()
|
||||
self.get_containers()
|
||||
|
||||
|
||||
def is_number(self, s):
|
||||
"""Check if the input string is a number."""
|
||||
try:
|
||||
@@ -62,8 +123,8 @@ class Portainer:
|
||||
def api_post(self, path, json="", timeout=120):
|
||||
url = f"{self.base_url.rstrip('/')}{path}"
|
||||
headers = {"X-API-Key": f"{self.token}"}
|
||||
#print(url)
|
||||
#print(json)
|
||||
# print(url)
|
||||
# print(json)
|
||||
resp = requests.post(url, headers=headers, json=json, timeout=timeout)
|
||||
return resp.text
|
||||
|
||||
@@ -361,18 +422,15 @@ class Portainer:
|
||||
self.endpoint_id = self.get_endpoint_id(endpoint)
|
||||
if os.path.exists(self.repo_dir):
|
||||
shutil.rmtree(self.repo_dir)
|
||||
print(f"Folder '{self.repo_dir}' has been removed.")
|
||||
else:
|
||||
print(f"Folder '{self.repo_dir}' does not exist.")
|
||||
Repo.clone_from(self.git_url, self.repo_dir)
|
||||
if mode == "git":
|
||||
print("Creating new stack from git repo...")
|
||||
path = f"/stacks/create/{p}/repository"
|
||||
|
||||
if self.endpoint_id is not None:
|
||||
path += f"?endpointId={self.endpoint_id}"
|
||||
|
||||
print(path)
|
||||
|
||||
if stack == "all":
|
||||
if self.endpoint_name == "rack":
|
||||
|
||||
77
portainer.py
77
portainer.py
@@ -24,8 +24,8 @@ defaults = {
|
||||
|
||||
|
||||
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("--base", "-b", default=os.getenv("PORTAINER_URL", \
|
||||
"https://portainer.example.com"),help="Base URL for Portainer (ENV: PORTAINER_URL)")
|
||||
parser.add_argument("--site", "-t", type=str, default=None, help="Site")
|
||||
parser.add_argument("--endpoint-id", "-e", type=str, default=None, help="Endpoint ID to limit stack operations")
|
||||
parser.add_argument("--refresh-environment", "-R", action="store_true", help="List endpoints")
|
||||
@@ -114,7 +114,24 @@ def get_portainer_token(base_url, username=None, password=None, timeout=10):
|
||||
if not token:
|
||||
raise ValueError(f"No token found in response: {data}")
|
||||
return token
|
||||
def prompt_missing_args(args, defaults, fields):
|
||||
"""
|
||||
fields = [("arg_name", "Prompt text")]
|
||||
"""
|
||||
for field, text in fields:
|
||||
value = getattr(args, field)
|
||||
default = defaults.get(field)
|
||||
|
||||
if value is None:
|
||||
if default is not None:
|
||||
prompt = f"{text} (default={default}) : "
|
||||
value = input(prompt) or default
|
||||
else:
|
||||
value = input(f"{text}: ")
|
||||
|
||||
setattr(args, field, value)
|
||||
|
||||
return args
|
||||
if __name__ == "__main__":
|
||||
# Example usage: set PORTAINER_USER and PORTAINER_PASS in env, or pass literals below.
|
||||
#token = get_portainer_token(base,"admin","l4c1j4yd33Du5lo") # or get_portainer_token(base, "admin", "secret")
|
||||
@@ -149,24 +166,24 @@ if __name__ == "__main__":
|
||||
sys.exit()
|
||||
|
||||
if args.action == "delete_stack":
|
||||
if args.endpoint_id == None:
|
||||
args.endpoint_id = input("Endpoint ID is required for deleting stacks : ")
|
||||
if args.stack == None:
|
||||
args.stack = input("Stack name or ID is required for deleting stacks : ")
|
||||
args = prompt_missing_args(args, defaults, [
|
||||
("site", "Site"),
|
||||
("endpoint_id", "Endpoint ID"),
|
||||
("stack", "Stack name or ID")
|
||||
])
|
||||
por.delete_stack(args.endpoint_id, args.stack,)
|
||||
sys.exit()
|
||||
|
||||
if args.action == "create_stack":
|
||||
if args.endpoint_id == None:
|
||||
args.endpoint_id = input(f"Endpoint ID (default={defaults["endpoint_id"]}) : ") or defaults["endpoint_id"]
|
||||
if args.stack == None:
|
||||
args.stack = input(f"Stack name or ID : ")
|
||||
if args.stack_mode == None:
|
||||
args.stack_mode = input(f"Stack mode (swarm or compose) (default={defaults["stack_mode"]}) : ") or defaults["stack_mode"]
|
||||
if args.deploy_mode == None:
|
||||
args.deploy_mode = input(f"Deploy mode (git or upload) (default={defaults["deploy_mode"]}) : ") or defaults["deploy_mode"]
|
||||
if args.site == None:
|
||||
args.site = input(f"Site (default={defaults["site"]}) : ") or defaults["site"]
|
||||
args = prompt_missing_args(args, defaults, [
|
||||
("site", "Site"),
|
||||
("endpoint_id", "Endpoint ID"),
|
||||
("stack", "Stack name or ID"),
|
||||
("stack_mode", "Stack mode (swarm or compose)"),
|
||||
("deploy_mode", "Deploy mode (git or upload)")
|
||||
])
|
||||
|
||||
|
||||
por.create_stack(args.endpoint_id,args.stack, args.deploy_mode, args.autostart, args.stack_mode)
|
||||
sys.exit()
|
||||
|
||||
@@ -183,7 +200,7 @@ if __name__ == "__main__":
|
||||
args.endpoint_id = input("Endpoint ID is required for starting stacks : ")
|
||||
if args.stack == None:
|
||||
args.stack = input("Stack name or ID is required for starting stacks : ")
|
||||
por.start_stack(args.stack,args.endpoint_id)
|
||||
por.start_stack(args.stack, args.endpoint_id)
|
||||
sys.exit()
|
||||
|
||||
if args.action == "list_stacks":
|
||||
@@ -202,17 +219,17 @@ if __name__ == "__main__":
|
||||
por.update_stack(args.endpoint_id,args.stack,autostart)
|
||||
sys.exit()
|
||||
if args.action == "print_all_data":
|
||||
print(json.dumps(por.all_data,indent=2))
|
||||
print(json.dumps(por.all_data, indent=2))
|
||||
sys.exit()
|
||||
if args.action == "update_status":
|
||||
por.update_status(args.endpoint_id,args.stack)
|
||||
por.update_status(args.endpoint_id, args.stack)
|
||||
sys.exit()
|
||||
|
||||
if args.action == "list_endpoints":
|
||||
eps = por.get_endpoints()
|
||||
data = []
|
||||
for i in eps["by_id"]:
|
||||
data.append([i,eps["by_id"][i]])
|
||||
data.append([i, eps["by_id"][i]])
|
||||
headers = ["EndpointId", "Name"]
|
||||
print(tabulate(data, headers=headers, tablefmt="github"))
|
||||
|
||||
@@ -226,37 +243,35 @@ if __name__ == "__main__":
|
||||
cont = []
|
||||
for c in por.all_data["containers"][args.endpoint_id]:
|
||||
if args.stack == c or args.stack == "all":
|
||||
cont+=por.all_data["containers"][args.endpoint_id][c]
|
||||
por.stop_containers(args.endpoint_id,cont)
|
||||
cont += por.all_data["containers"][args.endpoint_id][c]
|
||||
por.stop_containers(args.endpoint_id, cont)
|
||||
sys.exit()
|
||||
|
||||
if args.action == "start_containers":
|
||||
print("Starting containers")
|
||||
cont = []
|
||||
#input(json.dumps(por.all_data,indent=2))
|
||||
# input(json.dumps(por.all_data, indent=2))
|
||||
for c in por.all_data["containers"][args.endpoint_id]:
|
||||
if args.stack == c or args.stack == "all":
|
||||
cont+=por.all_data["containers"][args.endpoint_id][c]
|
||||
por.start_containers(args.endpoint_id,cont)
|
||||
cont += por.all_data["containers"][args.endpoint_id][c]
|
||||
por.start_containers(args.endpoint_id, cont)
|
||||
sys.exit()
|
||||
if args.action == "start_containers":
|
||||
print("Starting containers")
|
||||
cont = []
|
||||
#input(json.dumps(por.all_data,indent=2))
|
||||
# input(json.dumps(por.all_data,indent=2))
|
||||
for c in por.all_data["containers"][args.endpoint_id]:
|
||||
if args.stack == c or args.stack == "all":
|
||||
cont+=por.all_data["containers"][args.endpoint_id][c]
|
||||
por.start_containers(args.endpoint_id,cont)
|
||||
cont += por.all_data["containers"][args.endpoint_id][c]
|
||||
por.start_containers(args.endpoint_id, cont)
|
||||
sys.exit()
|
||||
if args.action == "refresh_environment":
|
||||
cont = por.refresh()
|
||||
sys.exit()
|
||||
|
||||
if args.action == "refresh_status":
|
||||
if args.stack== "all":
|
||||
if args.stack == "all":
|
||||
print("Stopping all stacks...")
|
||||
stcks = por.get_stacks(base, token, endpoint_id=args.endpoint_id)
|
||||
# stcks = get_stack(base, sta, token, endpoint_id=install_endpoint_id)
|
||||
else:
|
||||
por.refresh_status(base, args.stack_id, token)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user