mirror of
https://gitlab.sectorq.eu/jaydee/portainer.git
synced 2026-01-29 04:49:44 +01:00
Compare commits
26 Commits
d7f202e2b8
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| d215dd2615 | |||
| 0cbbb443f2 | |||
| 91702d8f4a | |||
| 4884ba41c4 | |||
| ec47d331d7 | |||
| cc6dc31409 | |||
| 609da77e77 | |||
| 17daad941e | |||
| cd32ad1d3e | |||
| 45a0b0030c | |||
| 5d0b488b87 | |||
| 5df457bdcb | |||
| 8f207f2fad | |||
| c0682d478d | |||
| db1710e065 | |||
| 7bac5e84c8 | |||
| 3a0117c2a5 | |||
| 8b916572cb | |||
| 498b88c7ee | |||
| 497a1f7947 | |||
| 928e4daae6 | |||
| 926248fda7 | |||
| ab9e93effe | |||
| fdbf41a819 | |||
| 958f050691 | |||
| 1dde729887 |
118
port.py
118
port.py
@@ -161,6 +161,7 @@ class Portainer:
|
|||||||
data=payload,
|
data=payload,
|
||||||
headers={"X-Gotify-Key": "ASn_fIAd5OVjm8c"}
|
headers={"X-Gotify-Key": "ASn_fIAd5OVjm8c"}
|
||||||
)
|
)
|
||||||
|
logger.debug(response.text)
|
||||||
# print("Status:", response.status_code)
|
# print("Status:", response.status_code)
|
||||||
# print("Response:", response.text)
|
# print("Response:", response.text)
|
||||||
pass
|
pass
|
||||||
@@ -335,7 +336,6 @@ class Portainer:
|
|||||||
return endpoint
|
return endpoint
|
||||||
|
|
||||||
def refresh_in_containers(self):
|
def refresh_in_containers(self):
|
||||||
print("Refreshing containers")
|
|
||||||
'''Get a list of containers for a specific endpoint and stack.'''
|
'''Get a list of containers for a specific endpoint and stack.'''
|
||||||
# print(json.dumps(self.all_data,indent=2))
|
# print(json.dumps(self.all_data,indent=2))
|
||||||
# print(endpoint)
|
# print(endpoint)
|
||||||
@@ -474,38 +474,62 @@ class Portainer:
|
|||||||
with ThreadPoolExecutor(max_workers=10) as exe:
|
with ThreadPoolExecutor(max_workers=10) as exe:
|
||||||
exe.map(stop, containers)
|
exe.map(stop, containers)
|
||||||
|
|
||||||
def update_stack(self, endpoint, stack, autostart, timeout=130):
|
def update_stack(self, args):
|
||||||
'''Update one stack or all stacks on an endpoint.'''
|
'''Update one stack or all stacks on an endpoint.'''
|
||||||
stcs = []
|
#print("Updating stacks")
|
||||||
if stack == "all":
|
stacks = self.get_stacks(endpoint_id=args.endpoint_id)
|
||||||
for s in self.all_data["webhooks"][endpoint]:
|
stacks_tuples = []
|
||||||
stcs.append([s, self.all_data["webhooks"][endpoint][s]])
|
|
||||||
else:
|
for s in stacks:
|
||||||
|
#print(s)
|
||||||
try:
|
try:
|
||||||
stcs.append([stack, self.all_data["webhooks"][endpoint][stack]])
|
stacks_tuples.append((s['AutoUpdate']['Webhook'],s['Name']))
|
||||||
except Exception as e:
|
# print(s['Name'], " : ", s['AutoUpdate']['Webhook'])
|
||||||
print(f"Error: Stack {stack} not found on endpoint {endpoint}: {e}")
|
except:
|
||||||
|
stacks_tuples.append((s['Webhook'],s['Name']))
|
||||||
|
# print(s['Name'], " : ", s['Webhook'])
|
||||||
|
stacks_dict = dict(stacks_tuples)
|
||||||
|
print(stacks_dict)
|
||||||
|
#input(stacks_tuples)
|
||||||
|
# stacks_tuples = [(s['AutoUpdate']['Webhook'], s['Name']) for s in stacks if "Webhook" in s['AutoUpdate'] ]
|
||||||
|
|
||||||
|
|
||||||
# input(stcs)
|
|
||||||
def update(c):
|
def update(c):
|
||||||
print(f" > Updating {c[0]} on {endpoint}")
|
print(f" > Updating {c[1]} ")
|
||||||
ans = self._api_post_no_body(f"/stacks/webhooks/{c[1]}")
|
ans = self._api_post_no_body(f"/stacks/webhooks/{c[0]}")
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"Update response for stack {c[0]} on endpoint {endpoint}: {ans}"
|
f"Update response for stack {c[0]} on endpoint {ans}"
|
||||||
)
|
)
|
||||||
|
# input(stacks_tuples)
|
||||||
|
if args.debug:
|
||||||
|
input(args)
|
||||||
|
stacks_tuples = sorted(stacks_tuples, key=lambda x: x[1])
|
||||||
|
stack_dict = dict(stacks_tuples)
|
||||||
|
# input(service_tuples)
|
||||||
|
if self.args.service_id is None:
|
||||||
|
#services = [(s["Id"], s["Name"]) for s in self.get_stacks(endpoint_id)]
|
||||||
|
stacks_tuples.insert(0, ("__ALL__", "[Select ALL]"))
|
||||||
|
stack_ids = checkboxlist_dialog(
|
||||||
|
title="Select one stack to update",
|
||||||
|
text="Choose a service:",
|
||||||
|
values=stacks_tuples
|
||||||
|
).run()
|
||||||
|
stcs = []
|
||||||
|
input(stack_ids)
|
||||||
|
|
||||||
def stop():
|
if args.stack == "all":
|
||||||
cont = []
|
for s in stack_dict:
|
||||||
for c in self.all_data["containers"][endpoint]:
|
stcs.append([s, stack_dict[s]])
|
||||||
if stack == c or stack == "all":
|
else:
|
||||||
cont += self.all_data["containers"][endpoint][c]
|
for s in stack_dict:
|
||||||
self.stop_containers(endpoint, cont)
|
if s in stack_ids:
|
||||||
|
stcs.append([s, stack_dict[s]])
|
||||||
|
|
||||||
|
print(stcs)
|
||||||
with ThreadPoolExecutor(max_workers=10) as exe:
|
with ThreadPoolExecutor(max_workers=10) as exe:
|
||||||
exe.map(update, stcs)
|
list(exe.map(update, stcs))
|
||||||
|
|
||||||
if not autostart:
|
input('UPDATED')
|
||||||
|
if not args.autostart:
|
||||||
time.sleep(120)
|
time.sleep(120)
|
||||||
cont = []
|
cont = []
|
||||||
for c in self.all_data["containers"][endpoint]:
|
for c in self.all_data["containers"][endpoint]:
|
||||||
@@ -749,7 +773,7 @@ class Portainer:
|
|||||||
if not autostart:
|
if not autostart:
|
||||||
# self.get_stacks()
|
# self.get_stacks()
|
||||||
# self.stop_stack(stack,self.endpoint_id)
|
# self.stop_stack(stack,self.endpoint_id)
|
||||||
conts = self.get_containers(self.endpoint_name, stack)
|
conts = self.get_containers()
|
||||||
# print(conts)
|
# print(conts)
|
||||||
self.stop_containers(self.endpoint_name, conts)
|
self.stop_containers(self.endpoint_name, conts)
|
||||||
|
|
||||||
@@ -817,7 +841,7 @@ class Portainer:
|
|||||||
data = []
|
data = []
|
||||||
stack_names = []
|
stack_names = []
|
||||||
for stack in stacks:
|
for stack in stacks:
|
||||||
print(stack)
|
# print(stack)
|
||||||
if endpoint is not None:
|
if endpoint is not None:
|
||||||
if not stack["EndpointId"] in self.endpoints["by_id"]:
|
if not stack["EndpointId"] in self.endpoints["by_id"]:
|
||||||
continue
|
continue
|
||||||
@@ -838,6 +862,7 @@ class Portainer:
|
|||||||
logger.debug(
|
logger.debug(
|
||||||
"KeyError getting endpoint name for stack %s : %s", stack["Name"], e
|
"KeyError getting endpoint name for stack %s : %s", stack["Name"], e
|
||||||
)
|
)
|
||||||
|
count += 1
|
||||||
|
|
||||||
data = sorted(data, key=lambda x: x[1])
|
data = sorted(data, key=lambda x: x[1])
|
||||||
headers = ["StackID", "Name", "Endpoint"]
|
headers = ["StackID", "Name", "Endpoint"]
|
||||||
@@ -862,15 +887,21 @@ class Portainer:
|
|||||||
values=service_tuples
|
values=service_tuples
|
||||||
).run()
|
).run()
|
||||||
elif self.args.service_id == "all":
|
elif self.args.service_id == "all":
|
||||||
service_ids = [s[0] for s in service_tuples if s[0] != "__ALL__" and s[0] != "__ONLY_CHECK__"]
|
service_ids = [s[0] for s in service_tuples if s[0] != "__ALL__" ]
|
||||||
else:
|
else:
|
||||||
service_ids = [self.args.service_id]
|
service_ids = [self.args.service_id]
|
||||||
if "__ONLY_CHECK__" in service_ids or self.args.update is False:
|
|
||||||
pull = False
|
if self.args.update is False:
|
||||||
print("Checking for updates only...")
|
if "__ONLY_CHECK__" in service_ids:
|
||||||
|
service_ids.remove("__ONLY_CHECK__")
|
||||||
|
pull = False
|
||||||
|
print("Checking for updates only...")
|
||||||
|
else:
|
||||||
|
pull = True
|
||||||
|
print("Checking for updates and pulling updates...")
|
||||||
else:
|
else:
|
||||||
print("Checking for updates and pulling updates...")
|
|
||||||
pull = True
|
pull = True
|
||||||
|
print("Checking for updates and pulling updates...")
|
||||||
if "__ALL__" in service_ids:
|
if "__ALL__" in service_ids:
|
||||||
service_ids = [s[0] for s in service_tuples if s[0] != "__ALL__" and s[0] != "__ONLY_CHECK__"]
|
service_ids = [s[0] for s in service_tuples if s[0] != "__ALL__" and s[0] != "__ONLY_CHECK__"]
|
||||||
|
|
||||||
@@ -899,7 +930,7 @@ class Portainer:
|
|||||||
print("?")
|
print("?")
|
||||||
elif resp['Status'] == "outdated":
|
elif resp['Status'] == "outdated":
|
||||||
if pull:
|
if pull:
|
||||||
|
print("Recreate")
|
||||||
self.recreate_container(service_id, pull)
|
self.recreate_container(service_id, pull)
|
||||||
#print(f"Service {service_dict[service_id]:<{longest}} : updated")
|
#print(f"Service {service_dict[service_id]:<{longest}} : updated")
|
||||||
self.gotify_message(f"Service {service_dict[service_id]} updated")
|
self.gotify_message(f"Service {service_dict[service_id]} updated")
|
||||||
@@ -939,21 +970,30 @@ class Portainer:
|
|||||||
text="Choose a service:",
|
text="Choose a service:",
|
||||||
values=service_tuples
|
values=service_tuples
|
||||||
).run()
|
).run()
|
||||||
|
if "__ONLY_CHECK__" in service_ids:
|
||||||
|
self.args.update = False
|
||||||
|
else:
|
||||||
|
self.args.update = True
|
||||||
|
if "__ALL__" in service_ids:
|
||||||
|
service_ids = [s[0] for s in service_tuples if s[0] != "__ALL__" and s[0] != "__ONLY_CHECK__"]
|
||||||
|
|
||||||
elif self.args.service_id == "all":
|
elif self.args.service_id == "all":
|
||||||
service_ids = [s[0] for s in service_tuples if s[0] != "__ALL__" and s[0] != "__ONLY_CHECK__"]
|
service_ids = [s[0] for s in service_tuples if s[0] != "__ALL__" and s[0] != "__ONLY_CHECK__"]
|
||||||
else:
|
else:
|
||||||
service_ids = [self.args.service_id]
|
service_ids = [self.args.service_id]
|
||||||
if "__ONLY_CHECK__" in service_ids or self.args.update is False:
|
|
||||||
|
if self.args.update:
|
||||||
|
pull = True
|
||||||
|
print("Checking for updates and pulling updates...")
|
||||||
|
else:
|
||||||
pull = False
|
pull = False
|
||||||
print("Checking for updates only...")
|
print("Checking for updates only...")
|
||||||
else:
|
|
||||||
print("Checking for updates and pulling updates...")
|
|
||||||
pull = True
|
|
||||||
if "__ALL__" in service_ids:
|
|
||||||
service_ids = [s[0] for s in service_tuples if s[0] != "__ALL__" and s[0] != "__ONLY_CHECK__"]
|
|
||||||
|
|
||||||
longest = 0
|
longest = 0
|
||||||
for a in service_dict.items():
|
for a in service_dict.items():
|
||||||
|
if a[0] == "__ONLY_CHECK__":
|
||||||
|
continue
|
||||||
# print(a[1])
|
# print(a[1])
|
||||||
if len(a[1]) > longest:
|
if len(a[1]) > longest:
|
||||||
longest = len(a[1])
|
longest = len(a[1])
|
||||||
@@ -1054,7 +1094,7 @@ class Portainer:
|
|||||||
def recreate_container(self,service_id, pull=False):
|
def recreate_container(self,service_id, pull=False):
|
||||||
"""Restart a service on an endpoint."""
|
"""Restart a service on an endpoint."""
|
||||||
path = f"/docker/{self.endpoint_id}/containers/{service_id}/recreate"
|
path = f"/docker/{self.endpoint_id}/containers/{service_id}/recreate"
|
||||||
#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=20)
|
||||||
@@ -1069,7 +1109,7 @@ class Portainer:
|
|||||||
params={"serviceID": service_id, "pullImage": pool}
|
params={"serviceID": service_id, "pullImage": pool}
|
||||||
try:
|
try:
|
||||||
resp = self._api_put(path, json=params, timeout=20)
|
resp = self._api_put(path, json=params, timeout=20)
|
||||||
print(resp)
|
# print(resp)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print(f"Error restarting service: {e}")
|
print(f"Error restarting service: {e}")
|
||||||
return []
|
return []
|
||||||
|
|||||||
27
portainer.py
27
portainer.py
@@ -39,7 +39,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.14"
|
VERSION = "0.1.16"
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
"endpoint_id": "vm01",
|
"endpoint_id": "vm01",
|
||||||
@@ -163,7 +163,7 @@ update_configs(cur_config)
|
|||||||
if args.debug:
|
if args.debug:
|
||||||
input(cur_config)
|
input(cur_config)
|
||||||
|
|
||||||
_LOG_LEVEL = "INFO"
|
_LOG_LEVEL = "DEBUG"
|
||||||
LOG_FILE = "/tmp/portainer.log"
|
LOG_FILE = "/tmp/portainer.log"
|
||||||
if _LOG_LEVEL == "DEBUG":
|
if _LOG_LEVEL == "DEBUG":
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@@ -475,8 +475,8 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
if args.action == "create_stack":
|
if args.action == "create_stack":
|
||||||
por.action = "create_stack"
|
por.action = "create_stack"
|
||||||
print(cur_config)
|
#print(cur_config)
|
||||||
print(args)
|
#print(args)
|
||||||
args = prompt_missing_args(
|
args = prompt_missing_args(
|
||||||
args,
|
args,
|
||||||
cur_config,
|
cur_config,
|
||||||
@@ -538,9 +538,6 @@ if __name__ == "__main__":
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
if args.action == "update_service":
|
if args.action == "update_service":
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
args = prompt_missing_args(
|
args = prompt_missing_args(
|
||||||
args,
|
args,
|
||||||
cur_config,
|
cur_config,
|
||||||
@@ -576,7 +573,7 @@ if __name__ == "__main__":
|
|||||||
("endpoint_id", "Endpoint ID"),
|
("endpoint_id", "Endpoint ID"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
por.print_stacks(args.endpoint_id)
|
por.print_stacks(args)
|
||||||
# print(json.dumps(por.all_data, indent=2))
|
# print(json.dumps(por.all_data, indent=2))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
@@ -585,11 +582,19 @@ if __name__ == "__main__":
|
|||||||
print(por.get_containers())
|
print(por.get_containers())
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
if args.action == "update_stack":
|
if args.action == "update_stack":
|
||||||
print("Updating stacks")
|
args = prompt_missing_args(
|
||||||
por.update_stack(args.endpoint_id, args.stack, args.autostart)
|
args,
|
||||||
|
cur_config,
|
||||||
|
[
|
||||||
|
("site", "Site"),
|
||||||
|
("endpoint_id", "Endpoint ID")
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
por.update_stack(args)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
if args.action == "print_all_data":
|
if args.action == "print_all_data":
|
||||||
print(json.dumps(por.all_data, indent=2))
|
print(json.dumps(por.all_data, indent=2))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|||||||
Reference in New Issue
Block a user