mirror of
https://gitlab.sectorq.eu/jaydee/portainer.git
synced 2025-12-14 10:44:52 +01:00
build
This commit is contained in:
78
port.py
78
port.py
@@ -12,7 +12,10 @@ import base64
|
|||||||
import tabulate
|
import tabulate
|
||||||
from git import Repo
|
from git import Repo
|
||||||
import requests
|
import requests
|
||||||
|
from prompt_toolkit import prompt
|
||||||
|
from prompt_toolkit.completion import WordCompleter
|
||||||
|
from prompt_toolkit.shortcuts import checkboxlist_dialog
|
||||||
|
from prompt_toolkit.shortcuts import radiolist_dialog
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -156,6 +159,14 @@ class Portainer:
|
|||||||
resp = requests.post(url, headers=headers, json=json, timeout=timeout)
|
resp = requests.post(url, headers=headers, json=json, timeout=timeout)
|
||||||
return resp.text
|
return resp.text
|
||||||
|
|
||||||
|
def _api_put(self, path, json="", timeout=120):
|
||||||
|
url = f"{self.base_url.rstrip('/')}{path}"
|
||||||
|
headers = {"X-API-Key": f"{self.token}"}
|
||||||
|
# print(url)
|
||||||
|
# print(json)
|
||||||
|
resp = requests.put(url, headers=headers, json=json, timeout=timeout)
|
||||||
|
return resp.text
|
||||||
|
|
||||||
def _api_post_file(self, path, endpoint_id, name, envs, file, timeout=120):
|
def _api_post_file(self, path, endpoint_id, name, envs, file, timeout=120):
|
||||||
# input("API POST2 called. Press Enter to continue.")
|
# input("API POST2 called. Press Enter to continue.")
|
||||||
"""Example authenticated GET request to Portainer API."""
|
"""Example authenticated GET request to Portainer API."""
|
||||||
@@ -261,6 +272,13 @@ class Portainer:
|
|||||||
# input(json.dumps(self.stacks_all,indent=2))
|
# input(json.dumps(self.stacks_all,indent=2))
|
||||||
return stcks
|
return stcks
|
||||||
|
|
||||||
|
def get_services(self, endpoint, stack, timeout=30):
|
||||||
|
'''Get a list of services for a specific stack on an endpoint.'''
|
||||||
|
path = f"/endpoints/{self.all_data['endpoints']['by_name'][endpoint]}/docker/services"
|
||||||
|
#path += f'?filters={{"label": ["com.docker.compose.project={stack}"]}}'
|
||||||
|
services = self._api_get(path, timeout=timeout)
|
||||||
|
return services
|
||||||
|
|
||||||
def update_status(self, endpoint, stack):
|
def update_status(self, endpoint, stack):
|
||||||
'''Get the update status of a specific stack on an endpoint.'''
|
'''Get the update status of a specific stack on an endpoint.'''
|
||||||
path = f"/stacks/{self.all_data['stacks'][endpoint]['by_name'][stack]}/images_status?refresh=true"
|
path = f"/stacks/{self.all_data['stacks'][endpoint]['by_name'][stack]}/images_status?refresh=true"
|
||||||
@@ -480,15 +498,13 @@ class Portainer:
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
def create_stack(
|
def create_stack(
|
||||||
self,
|
self,
|
||||||
endpoint,
|
endpoint,
|
||||||
stacks=None,
|
stacks=None,
|
||||||
mode="git",
|
mode="git",
|
||||||
autostart=False,
|
autostart=False,
|
||||||
stack_mode="swarm",
|
stack_mode="swarm",
|
||||||
):
|
):
|
||||||
|
|
||||||
|
|
||||||
for stack in stacks:
|
for stack in stacks:
|
||||||
if stack_mode == "swarm":
|
if stack_mode == "swarm":
|
||||||
swarm_id = self.get_swarm_id(endpoint)
|
swarm_id = self.get_swarm_id(endpoint)
|
||||||
@@ -705,6 +721,7 @@ class Portainer:
|
|||||||
}
|
}
|
||||||
self._api_post_file(path, self.endpoint_id, stack, envs, file)
|
self._api_post_file(path, self.endpoint_id, stack, envs, file)
|
||||||
|
|
||||||
|
|
||||||
def print_stacks(self, endpoint="all"):
|
def print_stacks(self, endpoint="all"):
|
||||||
"""Print a table of stacks, optionally filtered by endpoint."""
|
"""Print a table of stacks, optionally filtered by endpoint."""
|
||||||
stacks = self.get_stacks()
|
stacks = self.get_stacks()
|
||||||
@@ -739,6 +756,47 @@ class Portainer:
|
|||||||
print(f"Total stacks: {count}")
|
print(f"Total stacks: {count}")
|
||||||
# print(sorted(stack_names))
|
# print(sorted(stack_names))
|
||||||
|
|
||||||
|
def restart_service(self, endpoint_id, service_id):
|
||||||
|
stacks = [(s["Id"], s["Name"]) for s in self.get_stacks(endpoint_id)]
|
||||||
|
stack_id = radiolist_dialog(
|
||||||
|
title="Select one service",
|
||||||
|
text="Choose a service:",
|
||||||
|
values=stacks
|
||||||
|
).run()
|
||||||
|
service_dict = dict(stacks)
|
||||||
|
services = self.get_services(self.endpoint_name, stack_id)
|
||||||
|
svc_name = service_dict.get(stack_id)
|
||||||
|
stack_svcs = []
|
||||||
|
svc_menu = []
|
||||||
|
for s in services:
|
||||||
|
try:
|
||||||
|
if svc_name in s['Spec']['Name']:
|
||||||
|
stack_svcs.append([s['Version']['Index'], s['Spec']['Name']])
|
||||||
|
svc_menu.append([s['ID'], s['Spec']['Name']])
|
||||||
|
except KeyError as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
|
||||||
|
service_id = radiolist_dialog(
|
||||||
|
title="Select one service",
|
||||||
|
text="Choose a service:",
|
||||||
|
values=svc_menu
|
||||||
|
).run()
|
||||||
|
|
||||||
|
|
||||||
|
"""Restart a service on an endpoint."""
|
||||||
|
path = f"/endpoints/{self.endpoint_id}/forceupdateservice"
|
||||||
|
params={"serviceID": service_id, "pullImage": False}
|
||||||
|
try:
|
||||||
|
resp = self._api_put(path, json=params, timeout=20)
|
||||||
|
print(resp)
|
||||||
|
except ValueError as e:
|
||||||
|
print(f"Error restarting service: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
print(f"Service {service_id} : restarted")
|
||||||
|
return True
|
||||||
|
|
||||||
def start_stack(self, stack=None, endpoint_id=None):
|
def start_stack(self, stack=None, endpoint_id=None):
|
||||||
"""Start one stack or all stacks on an endpoint."""
|
"""Start one stack or all stacks on an endpoint."""
|
||||||
if endpoint_id is not None:
|
if endpoint_id is not None:
|
||||||
|
|||||||
16
portainer.py
16
portainer.py
@@ -392,6 +392,7 @@ if __name__ == "__main__":
|
|||||||
("delete_stack","delete_stack"),
|
("delete_stack","delete_stack"),
|
||||||
("stop_stack","stop_stack"),
|
("stop_stack","stop_stack"),
|
||||||
("start_stack","start_stack"),
|
("start_stack","start_stack"),
|
||||||
|
("restart_service","restart_service"),
|
||||||
("list_stacks","list_stacks"),
|
("list_stacks","list_stacks"),
|
||||||
("update_stack","update_stack"),
|
("update_stack","update_stack"),
|
||||||
("secrets","secrets"),
|
("secrets","secrets"),
|
||||||
@@ -526,6 +527,18 @@ if __name__ == "__main__":
|
|||||||
por.start_stack(args.stack, args.endpoint_id)
|
por.start_stack(args.stack, args.endpoint_id)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
if args.action == "restart_service":
|
||||||
|
args = prompt_missing_args(
|
||||||
|
args,
|
||||||
|
cur_config,
|
||||||
|
[
|
||||||
|
("site", "Site"),
|
||||||
|
("endpoint_id", "Endpoint ID")
|
||||||
|
],
|
||||||
|
)
|
||||||
|
por.restart_service(args.endpoint_id, "lala")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
if args.action == "list_stacks":
|
if args.action == "list_stacks":
|
||||||
args = prompt_missing_args(
|
args = prompt_missing_args(
|
||||||
args,
|
args,
|
||||||
@@ -544,6 +557,9 @@ if __name__ == "__main__":
|
|||||||
por.get_containers(args.endpoint_id, args.stack)
|
por.get_containers(args.endpoint_id, args.stack)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if args.action == "update_stack":
|
if args.action == "update_stack":
|
||||||
print("Updating stacks")
|
print("Updating stacks")
|
||||||
por.update_stack(args.endpoint_id, args.stack, args.autostart)
|
por.update_stack(args.endpoint_id, args.stack, args.autostart)
|
||||||
|
|||||||
Reference in New Issue
Block a user