mirror of
https://gitlab.sectorq.eu/jaydee/portainer.git
synced 2026-01-29 04:49:44 +01:00
Compare commits
27 Commits
807437c47e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ba22f79b9 | |||
| ddeb67750f | |||
| 12ff88f8e8 | |||
| 9d27e804a5 | |||
| 1f0a19b7b1 | |||
| 5adfbbcf3d | |||
| 0dda82be87 | |||
| 1a54c1e341 | |||
| 8d4bd382ee | |||
|
|
96068d4fb3 | ||
|
|
de37276ab6 | ||
| 2dc800f7f9 | |||
| ae387a794c | |||
| a3518ec0bb | |||
|
|
3e86a75502 | ||
|
|
11cd76215a | ||
| 4bbe283211 | |||
| fc3fe7b837 | |||
| 3152014ca3 | |||
| e411c81224 | |||
| 8ae696a96a | |||
| abd989a0db | |||
| bb8ef3bdb8 | |||
| 99aa451620 | |||
| fd1fcf90a4 | |||
| 135447d7aa | |||
| 164252534e |
24
main.py
24
main.py
@@ -26,7 +26,8 @@ from prompt_toolkit.shortcuts import checkboxlist_dialog
|
|||||||
from prompt_toolkit.shortcuts import radiolist_dialog
|
from prompt_toolkit.shortcuts import radiolist_dialog
|
||||||
|
|
||||||
|
|
||||||
VAULT_ADDR = os.environ.get("VAULT_ADDR", "http://192.168.77.101:8200")
|
# VAULT_ADDR = os.environ.get("VAULT_ADDR", "http://192.168.77.101:8200")
|
||||||
|
VAULT_ADDR = os.environ.get("VAULT_ADDR", "https://vault.sectorq.eu")
|
||||||
try:
|
try:
|
||||||
VAULT_TOKEN = os.environ.get("VAULT_TOKEN")
|
VAULT_TOKEN = os.environ.get("VAULT_TOKEN")
|
||||||
if VAULT_TOKEN is None:
|
if VAULT_TOKEN is None:
|
||||||
@@ -43,7 +44,7 @@ else:
|
|||||||
raise Exception("Failed to authenticate with Vault")
|
raise Exception("Failed to authenticate with Vault")
|
||||||
# Specify the mount point of your KV engine
|
# Specify the mount point of your KV engine
|
||||||
|
|
||||||
VERSION = "0.1.53"
|
VERSION = "0.1.55"
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
"endpoint_id": "vm01",
|
"endpoint_id": "vm01",
|
||||||
@@ -248,11 +249,11 @@ def prompt_missing_args(args_in, defaults_in, fields, action=None,stacks=None):
|
|||||||
if args.action == "create_stack":
|
if args.action == "create_stack":
|
||||||
# input(json.dumps(stacks, indent=2))
|
# input(json.dumps(stacks, indent=2))
|
||||||
commands = [
|
commands = [
|
||||||
'authentik', 'bitwarden', 'bookstack', 'dockermon', 'fail2ban', 'gitea', 'gitlab', 'grafana',
|
'authentik', 'bitwarden', 'bookstack', 'dockermon', 'duplicati', 'fail2ban', 'gitea', 'gitlab', 'grafana', 'grocy',
|
||||||
'hashicorp', 'home-assistant', 'homepage', 'immich', 'influxdb', 'jupyter', 'kestra', 'mailu3',
|
'hashicorp', 'home-assistant', 'homebox','homepage', 'immich', 'influxdb', 'jupyter', 'kestra', 'kopia', 'mailu3',
|
||||||
'mealie', 'mediacenter', 'mosquitto', 'motioneye', 'n8n', 'nebula', 'nextcloud', 'nginx',
|
'mealie', 'mediacenter', 'mosquitto', 'motioneye', 'n8n', 'nebula', 'nextcloud', 'nginx',
|
||||||
'node-red', 'octoprint', 'ollama', 'onlyoffice', 'paperless-ngx', 'pihole', 'portainer-ce', 'rancher', 'registry',
|
'node-red', 'octoprint', 'ollama', 'onlyoffice', 'paperless-ngx', 'pihole', 'portainer-ce', 'rancher', 'registry',
|
||||||
'regsync', 'semaphore', 'unifibrowser', 'uptime-kuma', 'watchtower', 'wazuh', 'webhub', 'wordpress',
|
'regsync', 'searxng','semaphore', 'unifibrowser', 'uptime-kuma', 'watchtower', 'wazuh', 'webhub', 'wordpress',
|
||||||
'wud', 'zabbix-server']
|
'wud', 'zabbix-server']
|
||||||
try:
|
try:
|
||||||
print(por.all_data['stacks'][defaults_in[f"PORTAINER_ENDPOINT_ID".upper()]]['by_name'].keys())
|
print(por.all_data['stacks'][defaults_in[f"PORTAINER_ENDPOINT_ID".upper()]]['by_name'].keys())
|
||||||
@@ -409,18 +410,13 @@ if __name__ == "__main__":
|
|||||||
]
|
]
|
||||||
|
|
||||||
selected_action = radiolist_dialog(
|
selected_action = radiolist_dialog(
|
||||||
title="Select one service",
|
title=f"Select one service - version: {VERSION}",
|
||||||
text="Choose a service:",
|
text="Choose a service:",
|
||||||
values=actions
|
values=actions
|
||||||
).run()
|
).run()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print("Selected:", selected_action)
|
print("Selected:", selected_action)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# print("Possible actions: \n")
|
# print("Possible actions: \n")
|
||||||
# i = 1
|
# i = 1
|
||||||
# for a in actions:
|
# for a in actions:
|
||||||
@@ -682,8 +678,4 @@ if __name__ == "__main__":
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
if args.action == "refresh_status":
|
if args.action == "refresh_status":
|
||||||
if args.stack == "all":
|
por.refresh_status(args)
|
||||||
print("Stopping all stacks...")
|
|
||||||
stcks = por.get_stacks(endpoint_id=args.endpoint_id)
|
|
||||||
else:
|
|
||||||
por.refresh_status(args.stack_id)
|
|
||||||
@@ -141,6 +141,13 @@ class PortainerApi:
|
|||||||
self.get_endpoints()
|
self.get_endpoints()
|
||||||
self.get_stacks()
|
self.get_stacks()
|
||||||
|
|
||||||
|
def refresh_status(self, args):
|
||||||
|
for s in self.all_data['stacks']['m-s']['by_id']:
|
||||||
|
path = f'/stacks/{s}/images_status?refresh=true'
|
||||||
|
|
||||||
|
print(path)
|
||||||
|
res = self._api_get(path, timeout=args.timeout)
|
||||||
|
|
||||||
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."""
|
||||||
try:
|
try:
|
||||||
@@ -159,7 +166,7 @@ class PortainerApi:
|
|||||||
response = requests.post(
|
response = requests.post(
|
||||||
"https://gotify.sectorq.eu/message",
|
"https://gotify.sectorq.eu/message",
|
||||||
data=payload,
|
data=payload,
|
||||||
headers={"X-Gotify-Key": "ASn_fIAd5OVjm8c"}
|
headers={"X-Gotify-Key": "A1krRuo8GIW-fpY"}
|
||||||
)
|
)
|
||||||
logger.debug(response.text)
|
logger.debug(response.text)
|
||||||
# print("Status:", response.status_code)
|
# print("Status:", response.status_code)
|
||||||
@@ -343,7 +350,6 @@ class PortainerApi:
|
|||||||
# print(stack)
|
# print(stack)
|
||||||
cont = []
|
cont = []
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
eps = [ep for ep in self.all_data['endpoints']['by_id'].keys()]
|
eps = [ep for ep in self.all_data['endpoints']['by_id'].keys()]
|
||||||
#input(eps)
|
#input(eps)
|
||||||
for endpoint in eps:
|
for endpoint in eps:
|
||||||
@@ -362,11 +368,15 @@ class PortainerApi:
|
|||||||
print(f"failed to get containers from {path}: {e}")
|
print(f"failed to get containers from {path}: {e}")
|
||||||
continue
|
continue
|
||||||
contr = []
|
contr = []
|
||||||
|
# print(f"Containers: {containers}")
|
||||||
try:
|
try:
|
||||||
for c in containers:
|
for c in containers:
|
||||||
#input(c)
|
# print(c)
|
||||||
|
try:
|
||||||
cont.append([c["Names"][0].replace("/", ""),c["Id"], c['Image']])
|
cont.append([c["Names"][0].replace("/", ""),c["Id"], c['Image']])
|
||||||
contr.append([c["Names"][0].replace("/", ""), c["Id"], c['Image']])
|
contr.append([c["Names"][0].replace("/", ""), c["Id"], c['Image']])
|
||||||
|
except:
|
||||||
|
print("Unable to parse container info")
|
||||||
if self.all_data["endpoints"]["by_id"][endpoint] in data:
|
if self.all_data["endpoints"]["by_id"][endpoint] in data:
|
||||||
data[self.all_data["endpoints"]["by_id"][endpoint]] = contr
|
data[self.all_data["endpoints"]["by_id"][endpoint]] = contr
|
||||||
data[endpoint] = contr
|
data[endpoint] = contr
|
||||||
@@ -489,7 +499,7 @@ class PortainerApi:
|
|||||||
stacks_tuples.append((s['Webhook'],s['Name']))
|
stacks_tuples.append((s['Webhook'],s['Name']))
|
||||||
# print(s['Name'], " : ", s['Webhook'])
|
# print(s['Name'], " : ", s['Webhook'])
|
||||||
stacks_dict = dict(stacks_tuples)
|
stacks_dict = dict(stacks_tuples)
|
||||||
print(stacks_dict)
|
# print(stacks_dict)
|
||||||
#input(stacks_tuples)
|
#input(stacks_tuples)
|
||||||
# stacks_tuples = [(s['AutoUpdate']['Webhook'], s['Name']) for s in stacks if "Webhook" in s['AutoUpdate'] ]
|
# stacks_tuples = [(s['AutoUpdate']['Webhook'], s['Name']) for s in stacks if "Webhook" in s['AutoUpdate'] ]
|
||||||
|
|
||||||
@@ -514,7 +524,7 @@ class PortainerApi:
|
|||||||
values=stacks_tuples
|
values=stacks_tuples
|
||||||
).run()
|
).run()
|
||||||
stcs = []
|
stcs = []
|
||||||
input(stack_ids)
|
#input(stack_ids)
|
||||||
|
|
||||||
if args.stack == "all":
|
if args.stack == "all":
|
||||||
for s in stack_dict:
|
for s in stack_dict:
|
||||||
@@ -524,11 +534,11 @@ class PortainerApi:
|
|||||||
if s in stack_ids:
|
if s in stack_ids:
|
||||||
stcs.append([s, stack_dict[s]])
|
stcs.append([s, stack_dict[s]])
|
||||||
|
|
||||||
print(stcs)
|
# print(stcs)
|
||||||
with ThreadPoolExecutor(max_workers=10) as exe:
|
with ThreadPoolExecutor(max_workers=10) as exe:
|
||||||
list(exe.map(update, stcs))
|
list(exe.map(update, stcs))
|
||||||
|
|
||||||
input('UPDATED')
|
#input('UPDATED')
|
||||||
if not args.autostart:
|
if not args.autostart:
|
||||||
time.sleep(120)
|
time.sleep(120)
|
||||||
cont = []
|
cont = []
|
||||||
@@ -868,7 +878,6 @@ class PortainerApi:
|
|||||||
headers = ["StackID", "Name", "Endpoint"]
|
headers = ["StackID", "Name", "Endpoint"]
|
||||||
print(tabulate.tabulate(data, headers=headers, tablefmt="github"))
|
print(tabulate.tabulate(data, headers=headers, tablefmt="github"))
|
||||||
print(f"Total stacks: {count}")
|
print(f"Total stacks: {count}")
|
||||||
input("Continue...")
|
|
||||||
# print(sorted(stack_names))
|
# print(sorted(stack_names))
|
||||||
|
|
||||||
def update_containers(self):
|
def update_containers(self):
|
||||||
@@ -963,7 +972,14 @@ class PortainerApi:
|
|||||||
|
|
||||||
def update_service(self):
|
def update_service(self):
|
||||||
all_services = self.get_services(self.get_endpoint_id())
|
all_services = self.get_services(self.get_endpoint_id())
|
||||||
#input(all_services)
|
if self.args.debug:
|
||||||
|
print(all_services)
|
||||||
|
if all_services == 503:
|
||||||
|
print("No services found on this endpoint.")
|
||||||
|
return False
|
||||||
|
if len(all_services) == 0:
|
||||||
|
print("No services found on this endpoint.")
|
||||||
|
return False
|
||||||
service_tuples = [(s['ID'], s['Spec']['Name']) for s in all_services]
|
service_tuples = [(s['ID'], s['Spec']['Name']) for s in all_services]
|
||||||
service_tuples = sorted(service_tuples, key=lambda x: x[1])
|
service_tuples = sorted(service_tuples, key=lambda x: x[1])
|
||||||
service_dict = dict(service_tuples)
|
service_dict = dict(service_tuples)
|
||||||
@@ -1031,6 +1047,7 @@ class PortainerApi:
|
|||||||
print(err)
|
print(err)
|
||||||
else:
|
else:
|
||||||
print(ok)
|
print(ok)
|
||||||
|
self.gotify_message(f"Service update process finished")
|
||||||
print("\033[?25h", end="")
|
print("\033[?25h", end="")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -1104,7 +1121,7 @@ class PortainerApi:
|
|||||||
# print(path)
|
# print(path)
|
||||||
params={"pullImage": pull}
|
params={"pullImage": pull}
|
||||||
try:
|
try:
|
||||||
resp = self._api_post(path, json=params, timeout=20)
|
resp = self._api_post(path, json=params, timeout=120)
|
||||||
#print(resp)
|
#print(resp)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print(f"Error restarting service: {e}")
|
print(f"Error restarting service: {e}")
|
||||||
|
|||||||
@@ -6,3 +6,5 @@ flake8
|
|||||||
pylint
|
pylint
|
||||||
black
|
black
|
||||||
docker
|
docker
|
||||||
|
hvac
|
||||||
|
prompt_toolkit
|
||||||
Reference in New Issue
Block a user