2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| *.csv | ||||
| *.toml | ||||
| .vscode/ | ||||
|  | ||||
| thunder-tests/ | ||||
| # Byte-compiled / optimized / DLL files | ||||
| __pycache__/ | ||||
| *.py[cod] | ||||
|   | ||||
							
								
								
									
										26
									
								
								cclient.py
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								cclient.py
									
									
									
									
									
								
							| @@ -1,25 +1,21 @@ | ||||
| def c_auth(req_obj, host, port, username, password): | ||||
|     url = f'https://{host}:{port}/api/auth' | ||||
|     c_auth_response = req_obj.post(url, json={"Username":username,"Password":password}, verify=False) | ||||
|     return c_auth_response.json()["jwt"] | ||||
|  | ||||
| def c_get_containers(req_obj, host, port, jwt, endpoint): | ||||
| def c_get_containers(req_obj, host, port, access_token, endpoint): | ||||
|     url = f'https://{host}:{port}/api/endpoints/{endpoint}/docker/containers/json?all=true' | ||||
|     c_get_containers_response = req_obj.get(url, headers={"Authorization": f"Bearer {jwt}"},verify=False) | ||||
|     c_get_containers_response = req_obj.get(url, headers={"X-API-Key": access_token},verify=False) | ||||
|     return c_get_containers_response.json() | ||||
|  | ||||
| #filters={"name": ["restic","qbittorrent"],"status": ["paused","dead","created","exited","removing","restarting","created"]} | ||||
| def c_get_filtered_containers(req_obj, host, port, jwt, endpoint, containers, statuses): | ||||
|     url = f'https://{host}:{port}/api/endpoints/{endpoint}/docker/containers/json?filters={"name": {containers},"status": {statuses}}' | ||||
|     c_get_containers_response = req_obj.get(url, headers={"Authorization": f"Bearer {jwt}"},verify=False) | ||||
| def c_get_filtered_containers(req_obj, j_obj, host, port, access_token, endpoint, containers, statuses): | ||||
|     filter_string = j_obj.dumps({"name":containers,"status":statuses}) | ||||
|     # url = 'https://192.168.4.11:9443/api/endpoints/1/docker/containers/json?filters={"name": ["restic","qbittorrent"],"status": ["paused","dead","created","exited","removing","restarting","created"]}' | ||||
|     url = f'https://{host}:{port}/api/endpoints/{endpoint}/docker/containers/json?filters={filter_string}' | ||||
|     c_get_containers_response = req_obj.get(url, headers={"X-API-Key": access_token}, verify=False) | ||||
|     return c_get_containers_response.json() | ||||
|  | ||||
| def c_start_container(req_obj, host, port, jwt, endpoint, cid): | ||||
| def c_start_container(req_obj, host, port, access_token, endpoint, cid): | ||||
|     url = f'https://{host}:{port}/api/endpoints/{endpoint}/docker/containers/{cid}/start' | ||||
|     c_start_container_response = req_obj.post(url, headers={"Authorization": f"Bearer {jwt}"},verify=False) | ||||
|     c_start_container_response = req_obj.post(url, headers={"X-API-Key": access_token},verify=False) | ||||
|     return c_start_container_response.status_code | ||||
|  | ||||
| def c_stop_container(req_obj, host, port, jwt, endpoint, cid): | ||||
| def c_stop_container(req_obj, host, port, access_token, endpoint, cid): | ||||
|     url = f'https://{host}:{port}/api/endpoints/{endpoint}/docker/containers/{cid}/stop' | ||||
|     c_start_container_response = req_obj.post(url, headers={"Authorization": f"Bearer {jwt}"},verify=False) | ||||
|     c_start_container_response = req_obj.post(url, headers={"X-API-Key": access_token},verify=False) | ||||
|     return c_start_container_response.status_code | ||||
							
								
								
									
										36
									
								
								cprocess.py
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								cprocess.py
									
									
									
									
									
								
							| @@ -1,32 +1,8 @@ | ||||
| # TODO add file for containers that need to be started | ||||
|  | ||||
| def build_cont_list(obj, hypercare_containers): | ||||
|     cont_list = [] | ||||
|     for i, c in enumerate(obj): | ||||
|         if c["State"].lower() != "running": | ||||
|             continue | ||||
|         if c["Names"][0].lstrip("/") in hypercare_containers: | ||||
|             cont_list.append(c) | ||||
|     return cont_list | ||||
|  | ||||
| def build_full_cont_list(obj, hypercare_containers): | ||||
|     cont_full_list = [] | ||||
|     for i, c in enumerate(obj): | ||||
|         if c["Names"][0].lstrip("/") in hypercare_containers: | ||||
|             cont_full_list.append(c) | ||||
|     return cont_full_list | ||||
|  | ||||
| def process_cont_list(full_cont_list, start_cont_fn, req_obj, host, port, jwt, endpoint): | ||||
| def process_cont_list(full_cont_list, start_cont_fn, req_obj, host, port, access_token, endpoint): | ||||
|     if full_cont_list: | ||||
|         #print(full_cont_list) | ||||
|         started = [] | ||||
|         for container in full_cont_list: | ||||
|             start_cont_fn(req_obj, host, port, jwt, endpoint, container["Id"]) | ||||
|             return container["Names"][0].lstrip("/") | ||||
|  | ||||
| def process_cont_status(obj): | ||||
|     if not obj: | ||||
|         return -1 # Can't find the containter | ||||
|     for c in enumerate(obj): | ||||
|         if 'running' in c[1]["State"].lower(): | ||||
|             return 0 | ||||
|         if c[1]["State"] != 'running': | ||||
|             return 1 | ||||
|             start_cont_fn(req_obj, host, port, access_token, endpoint, container["Id"]) | ||||
|             started.append(container["Names"][0].lstrip("/")) | ||||
|         return started | ||||
							
								
								
									
										21
									
								
								crane.py
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								crane.py
									
									
									
									
									
								
							| @@ -1,4 +1,5 @@ | ||||
| import pushover | ||||
| import json | ||||
| from cclient import * | ||||
| from clogging import * | ||||
| from cprocess import * | ||||
| @@ -20,12 +21,12 @@ class Crn: | ||||
|         # Create the logging and pushover objects | ||||
|         self.tl = logging | ||||
|         self.po = pushover | ||||
|         self.jn = json | ||||
|         #Load settings from config.toml | ||||
|         #portainer | ||||
|         self.host = self.config["portainer"]["host"] | ||||
|         self.port = self.config["portainer"]["port"] | ||||
|         self.username = self.config["portainer"]["username"] | ||||
|         self.password = self.config["portainer"]["password"] | ||||
|         self.access_token = self.config["portainer"]["access_token"] | ||||
|         self.endpoint = self.config["portainer"]["endpoint"] | ||||
|         self.start_containers = self.config["portainer"]["start_containers"] | ||||
|         #logging | ||||
| @@ -37,7 +38,8 @@ class Crn: | ||||
|         self.po_key = self.config["pushover"]["po_key"] | ||||
|         self.po_token = self.config["pushover"]["po_token"] | ||||
|         #containers | ||||
|         self.observed_containers = self.config["containers"].values() | ||||
|         self.observed_containers = list(self.config["containers"].values()) | ||||
|         self.container_statuses = ["paused","dead","created","exited","removing","restarting","created"] | ||||
|  | ||||
|         cont_log(self) | ||||
|         cont_notify(self) | ||||
| @@ -45,16 +47,13 @@ class Crn: | ||||
|  | ||||
|         #logging in | ||||
|         try: | ||||
|             self.tl.debug('Authenticating.') | ||||
|             self.jwt = c_auth(self.cc, self.host, self.port, self.username, self.password) | ||||
|             self.tl.info('Authenticated successfully.') | ||||
|             self.cont_obj = c_get_containers(self.cc, self.host, self.port, self.jwt, self.endpoint) | ||||
|             # c_get_filtered_containers(req_obj, j_obj, host, port, access_token, endpoint, containers, statuses) | ||||
|             self.cont_obj = c_get_filtered_containers(self.cc, self.jn, self.host, self.port, self.access_token, self.endpoint,self.observed_containers,self.container_statuses) | ||||
|             # print(self.cont_obj) | ||||
|             self.tl.debug('Collected container data.') | ||||
|             self.cont_list = build_full_cont_list(self.cont_obj, self.observed_containers) | ||||
|             self.tl.debug('Building container list.') | ||||
|             self.process_cont_list_response = process_cont_list(self.cont_list, c_start_container, self.cc, self.host, self.port, self.jwt, self.endpoint) | ||||
|             self.process_cont_list_response = process_cont_list(self.cont_obj, c_start_container, self.cc, self.host, self.port, self.access_token, self.endpoint) | ||||
|             if self.process_cont_list_response: | ||||
|                 self.tl.warning(f'Started: [{self.process_cont_list_response}]') | ||||
|                 self.tl.warning(f'Started: {self.process_cont_list_response}') | ||||
|  | ||||
|         except requests.exceptions.RequestException as e: | ||||
|             self.tl.exception(e) | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| import unittest | ||||
| import requests | ||||
| import json | ||||
| from tomllib import load | ||||
| from cclient import c_auth, c_get_containers, c_start_container, c_stop_container, c_get_filtered_containers | ||||
| from cprocess import build_cont_list, process_cont_list, build_full_cont_list, process_cont_status | ||||
| unittest.TestLoader.sortTestMethodsUsing = None | ||||
| from cclient import c_get_filtered_containers, c_start_container, c_stop_container, c_get_filtered_containers | ||||
| from cprocess import process_cont_list | ||||
| # unittest.TestLoader.sortTestMethodsUsing = None | ||||
|  | ||||
| class TestCrane(unittest.TestCase): | ||||
|     def setUp(self): | ||||
| @@ -11,54 +12,34 @@ class TestCrane(unittest.TestCase): | ||||
|             self.config = load(c) | ||||
|         self.host = self.config["portainer"]["host"] | ||||
|         self.port = self.config["portainer"]["port"] | ||||
|         self.username = self.config["portainer"]["username"] | ||||
|         self.password = self.config["portainer"]["password"] | ||||
|         self.access_token = "ptr_ufS1nADXmrU3QSN3bvITLMQ7oOH9yo3ECb/QNwtIYJ4=" | ||||
|         self.endpoint = self.config["portainer"]["endpoint"] | ||||
|         self.cid = 'aa5b217ca6217fd9d268396039da69ea9e4a5aff381b3dceb71edb5a1f4d429d' | ||||
|         self.cid = 'ef8fee86e02b2b82acbddf6f0da1ff023f60bfe52c0b4087cac29c1686ccbac4' | ||||
|         self.req_obj = requests | ||||
|         self.hypercare_containers = ['hello-world'] | ||||
|         #self.status_filters = ["paused","dead","created","exited","removing","restarting","created"] | ||||
|         self.jwt = c_auth(self.req_obj, self.host, self.port, self.username, self.password) | ||||
|         self.cont_obj = c_get_containers(self.req_obj, self.host, self.port, self.jwt, self.endpoint) | ||||
|         #self.cont_obj_f = c_get_filtered_containers(self.req_obj, self.host, self.port, self.jwt, self.endpoint,self.hypercare_containers,self.status_filters) | ||||
|         self.j_obj = json | ||||
|         self.hypercare_containers = ['restic','qbittorrent'] | ||||
|         self.status_filters = ["paused","dead","created","exited","removing","restarting","created"] | ||||
|         self.cont_obj = c_get_filtered_containers(self.req_obj,self.j_obj, self.host, self.port, self.access_token, self.endpoint,self.hypercare_containers,self.status_filters) | ||||
|  | ||||
|     def test_c_auth(self): | ||||
|         self.assertTrue(self.jwt, "No JWT returned by cauth.") | ||||
|  | ||||
|     def test_c_get_containers(self): | ||||
|         self.assertTrue(self.cont_obj, "No cont object returned by c_get_containers.") | ||||
|  | ||||
|     def test_c_get_containers_f(self): | ||||
|         self.assertTrue(self.cont_obj_f, "No cont object returned by c_get_containers.") | ||||
|  | ||||
|     def test_a_is_hypercare_container_status(self): | ||||
|         self.cont_full_list = build_full_cont_list(self.cont_obj, self.hypercare_containers) | ||||
|         self.process_cont_status_response = process_cont_status(self.cont_full_list) | ||||
|         if self.process_cont_status_response == 0: | ||||
|             c_stop_container(self.req_obj, self.host, self.port, self.jwt, self.endpoint, self.cid) | ||||
|          | ||||
|     def test_build_cont_list(self): | ||||
|         self.cont_list = build_cont_list(self.cont_obj, self.hypercare_containers) | ||||
|         self.assertTrue(self.cont_list, "No cont_list returned by build_cont_list. Does the test container exist?") | ||||
|     def test_c_get_filtered_containers(self): | ||||
|         self.assertTrue(self.cont_obj, "No cont object returned by c_get_filtered_containers.") | ||||
|  | ||||
|     def test_c_start_container(self): | ||||
|         self.c_start_container_response = c_start_container(self.req_obj, self.host, self.port, self.jwt, self.endpoint, self.cid) | ||||
|         self.c_start_container_response = c_start_container(self.req_obj, self.host, self.port, self.access_token, self.endpoint, self.cid) | ||||
|         # print(self.c_start_container_response) | ||||
|         self.assertTrue(self.c_start_container_response, "No c_start_container_resonse returned by c_start_container.") | ||||
|         # 204 success 304 already on | ||||
|      | ||||
|     def test_c_process_cont_list(self): | ||||
|         self.assertTrue(process_cont_list(self.cont_obj, c_start_container, self.req_obj, self.host, self.port, self.access_token, self.endpoint)) | ||||
|      | ||||
|     def test_c_stop_container(self): | ||||
|         self.c_stop_container_response = c_stop_container(self.req_obj, self.host, self.port, self.jwt, self.endpoint, self.cid) | ||||
|         self.c_stop_container_response = c_stop_container(self.req_obj, self.host, self.port, self.access_token, self.endpoint, self.cid) | ||||
|         # print(self.c_stop_container_response) | ||||
|         self.assertTrue(self.c_stop_container_response, "No c_start_container_resonse returned by c_start_container.") | ||||
|      | ||||
|     def test_process_cont_list(self): | ||||
|         self.cont_list = build_cont_list(self.cont_obj, self.hypercare_containers) | ||||
|         self.process_cont_list_response = process_cont_list(self.cont_list, c_start_container, self.req_obj, self.host, self.port, self.jwt, self.endpoint) | ||||
|         self.assertTrue(self.process_cont_list_response, "No c_start_container_resonse returned by c_start_container.") | ||||
|      | ||||
|     def test_z_tear_down(self): | ||||
|         c_stop_container(self.req_obj, self.host, self.port, self.jwt, self.endpoint, self.cid) | ||||
|         c_stop_container(self.req_obj, self.host, self.port, self.access_token, self.endpoint, self.cid) | ||||
|          | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|   | ||||
		Reference in New Issue
	
	Block a user