From 1d1912fdf7c7c4ec11559531a803ddb61216f239 Mon Sep 17 00:00:00 2001 From: Gitea Admin Date: Wed, 22 Feb 2023 18:57:12 +0100 Subject: [PATCH] 'server-test' toevoegen --- server-test | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 server-test diff --git a/server-test b/server-test new file mode 100644 index 0000000..2a8c66f --- /dev/null +++ b/server-test @@ -0,0 +1,213 @@ +from email.quoprimime import body_check +from http.client import HTTPException +# from turtle import title +from typing import Union, Optional +from fastapi import FastAPI, Response, status, HTTPException, Request +from fastapi.params import Body +from fastapi.responses import HTMLResponse, PlainTextResponse +from pydantic import BaseModel +from random import randrange +import os +import subprocess +# from podman import PodmanClient +import json +import yaml +import docker +from fastapi.templating import Jinja2Templates +import socket +import random +import string + +dragontool = FastAPI() + +#uri = "unix:///run/podman/podman.sock" +#uri = "http+unix://%2frun%2fpodman.sock/v4.0.0/libpod/version" +#podmanapi = PodmanClient(base_url=uri) + +podmanapi = docker.DockerClient(base_url='unix://run/user/1000/podman/podman.sock') + +yaml_file = open("containers.yaml", 'r') +yaml_content = yaml.load(yaml_file,Loader=yaml.FullLoader) + +templates = Jinja2Templates(directory="templates") + +class Environment(BaseModel): + username: str + uid: Optional[str] = None + +def Random_alphanumeric_string(length): + return ''.join(random.choices(string.ascii_letters + string.digits,k=length)) + +def Filter(string, substr): + return [str for str in string if + any(sub in str for sub in substr)] + +def Unique_list(input_list): + output_list = [] + for word in input_list: + if word not in output_list: + output_list.append(word) + return output_list + +@dragontool.get("/") +async def root(): + return {"message": "Welcome to Dragontool API!"} + +@dragontool.post("/api/v1/environments", status_code=status.HTTP_201_CREATED) +async def create_environments(env: Environment): + env_dict = env.dict() + env_dict['username'] = env_dict['username'].replace("-", "_") + if env_dict['uid'] is None: + container_uid = Random_alphanumeric_string(8) + else: + container_uid = env_dict['uid'] + try: + network = podmanapi.networks.create(name=env_dict['username']+'-'+container_uid) + except docker.errors.APIError: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Server returns an error") + if env_dict['username'] == "gitlab": + container_timeout = "86400" + else: + container_timeout = "432000" + for container in yaml_content['containers']: + cmd = subprocess.run(["podman","run","-dt","--rm","-P","--privileged","--memory",container['memory'],"--cpus",container['cpus'],"--timeout",container_timeout,"--name",container['name']+'-'+env_dict['username']+'-'+container_uid,"--network",env_dict['username']+'-'+container_uid,"--network-alias",container['name'],container['image']+':1.0'],stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text=True) +# try: +# container = podmanapi.containers.run(image=container['image']+":1.0",name=container['name']+'-'+env_dict['username']+'-'+container_uid,privileged=True,detach=True,publish_all_ports=True, remove=True,network=env_dict['username']+'-'+container_uid) +# except docker.errors.ContainerError: +# raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Environment {env_dict['username']+'-'+env_dict['uid']} already in use!") +# except docker.errors.ImageNotFound: +# raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Image on server does not exist!") +# except docker.errors.APIError: +# raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Server returns an error") + json_response = json.dumps({'Username': env_dict['username'],'uid': container_uid,'Creation': 'successfull'}, indent=4, default=str) + return Response(content=json_response,media_type='application/json') + + +@dragontool.post("/api/v1/environments/inventory", status_code=status.HTTP_201_CREATED, response_class=HTMLResponse) +async def get_inventory(request: Request, env: Environment): + env_dict = env.dict() + env_dict['username'] = env_dict['username'].replace("-", "_") + env_dict['uid'] = env_dict['uid'].replace("-", "_") + container_list = [] + for yaml_container in yaml_content['containers']: + try: + container = podmanapi.containers.get(yaml_container['name']+'-'+env_dict['username']+'-'+env_dict['uid']) + except docker.errors.NotFound: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Environment {env_dict['username']+'-'+env_dict['uid']} not found!") + except docker.errors.APIError: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Server returns an error") + for priv_port,pub_port in container.ports.items(): + if priv_port == '2222/tcp': + for host_port in pub_port: + containers_0 = {} + containers_0['container_alias'] = yaml_container['name'] + containers_0['container_name'] = container.name.strip('/') + containers_0['container_pub_ssh_port'] = host_port['HostPort'] + containers_0['container_batch'] = yaml_container['batch'] + container_list.append(containers_0) + response = templates.TemplateResponse("hosts-template-v2.ini", {"request": request, "container_list": container_list, "host_ip": socket.gethostbyname(socket.gethostname()) }) + return response + +@dragontool.post("/api/v1/environments/ports", status_code=status.HTTP_201_CREATED, response_class=HTMLResponse) +async def get_ports(request: Request, env: Environment): + env_dict = env.dict() + env_dict['username'] = env_dict['username'].replace("-", "_") + env_dict['uid'] = env_dict['uid'].replace("-", "_") + container_list = [] + for yaml_container in yaml_content['containers']: + try: + container = podmanapi.containers.get(yaml_container['name']+'-'+env_dict['username']+'-'+env_dict['uid']) + except docker.errors.NotFound: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Environment {env_dict['username']+'-'+env_dict['uid']} not found!") + except docker.errors.APIError: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Server returns an error") + for priv_port,pub_port in container.ports.items(): + #print(priv_port,pub_port) + if priv_port == '2222/tcp': + for host_port in pub_port: + containers_0 = {} + containers_0['container_alias'] = yaml_container['name'] + containers_0['container_name'] = container.name.strip('/') + containers_0['container_pub_ssh_port'] = host_port['HostPort'] + containers_0['host_ip'] = socket.gethostbyname(socket.gethostname()) + container_list.append(containers_0) + if priv_port == '3890/tcp': + for host_port in pub_port: + containers_0 = {} + containers_0['container_alias'] = yaml_container['name'] + containers_0['container_name'] = container.name.strip('/') + containers_0['container_pub_ldap_port'] = host_port['HostPort'] + containers_0['host_ip'] = socket.gethostbyname(socket.gethostname()) + container_list.append(containers_0) + + json_response = json.dumps(container_list, indent=4, default=str) + return Response(content=json_response,media_type='application/json') + + +@dragontool.delete("/api/v1/environments", status_code=status.HTTP_204_NO_CONTENT) +async def delete_environments(env: Environment): + """ Delete environments of username + uid given """ + env_dict = env.dict() + env_dict['username'] = env_dict['username'].replace("-", "_") + env_dict['uid'] = env_dict['uid'].replace("-", "_") + for container in yaml_content['containers']: + try: + container = podmanapi.containers.get(container['name']+'-'+env_dict['username']+'-'+env_dict['uid']) + try: + container.remove(v=True,force=True) + except docker.errors.APIError: + pass + except docker.errors.NotFound: + pass + except docker.errors.APIError: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Server returns an error") + try: + network = podmanapi.networks.prune() + except docker.errors.APIError: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Server returns an error") + try: + container = podmanapi.containers.prune() + except docker.errors.APIError: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Server returns an error") + try: + image = podmanapi.images.prune() + except docker.errors.APIError: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Server returns an error") + return Response(status_code=status.HTTP_204_NO_CONTENT) + + +@dragontool.post("/api/v1/environments/list") +async def list_environments(env: Environment): + """ Restrieve environments belonging to username that is given """ + env_dict = env.dict() + env_dict['username'] = env_dict['username'].replace("-", "_") + #env_dict['uid'] = env_dict['uid'].replace("-", "_") + containers = podmanapi.containers.list(all=True) + container_list = [] + for container in containers: + container_list.append(container.name) + #print(container.status) + substr = [env_dict['username']] + filtered_containers = (Filter(container_list, substr)) + container_list = [] + for container in yaml_content['containers']: + container_list.append(container['name']) + filtered_containers_list = [] + for filtered_container in filtered_containers: + filtered_container = filtered_container.split("-", 2) + filtered_containers_list.extend(filtered_container) + for cont in container_list: + while cont in filtered_containers_list: + filtered_containers_list.remove(cont) + filtered_containers_list.remove(env_dict['username']) + conts_0 = Unique_list(filtered_containers_list) + + container_list = [] + for cont_0 in conts_0: + containers_0 = {} + containers_0['uid'] = cont_0 + container_list.append(containers_0) + json_response = json.dumps(container_list, indent=4, default=str) + return Response(content=json_response,media_type='application/json') + +