update apphub

This commit is contained in:
zhaojing1987 2023-11-29 15:22:58 +08:00
parent ffc02e9c51
commit c8ed948d59
4 changed files with 163 additions and 51 deletions

View File

@ -1,6 +1,6 @@
from typing import List, Optional from typing import List, Optional
from fastapi import APIRouter, Query,Path from fastapi import APIRouter, Query,Path,Request,Depends
from fastapi.params import Body from fastapi.params import Body
from src.schemas.domainNames import DomainNames from src.schemas.domainNames import DomainNames
from src.schemas.errorResponse import ErrorResponse from src.schemas.errorResponse import ErrorResponse
@ -59,22 +59,22 @@ def update_proxys(
): ):
return AppManger().update_proxy_by_app(proxy_id,domain_names.domain_names,endpointId) return AppManger().update_proxy_by_app(proxy_id,domain_names.domain_names,endpointId)
@router.delete( # @router.delete(
"/proxys/app/{app_id}", # "/proxys/app/{app_id}",
summary="Delete Proxys", # summary="Delete Proxys",
description="Delete proxys by app", # description="Delete proxys by app",
status_code=204, # status_code=204,
responses={ # responses={
204: {"description": "Delete Proxys Success"}, # 204: {"description": "Delete Proxys Success"},
400: {"model": ErrorResponse}, # 400: {"model": ErrorResponse},
500: {"model": ErrorResponse}, # 500: {"model": ErrorResponse},
} # }
) # )
def delete_proxys_by_app( # def delete_proxys_by_app(
app_id: str = Path(..., description="App ID to create proxys from"), # app_id: str = Path(..., description="App ID to create proxys from"),
endpointId: int = Query(None, description="Endpoint ID to create proxys from. If not set, create proxys from the local endpoint"), # endpointId: int = Query(None, description="Endpoint ID to create proxys from. If not set, create proxys from the local endpoint"),
): # ):
AppManger().remove_proxy_by_app(app_id,endpointId) # AppManger().remove_proxy_by_app(app_id,endpointId)
@router.delete( @router.delete(
"/proxys/{proxy_id}", "/proxys/{proxy_id}",
@ -88,6 +88,10 @@ def delete_proxys_by_app(
} }
) )
def delete_proxys_by_id( def delete_proxys_by_id(
request: Request,
proxy_id: int = Path(..., description="Proxy ID to delete proxys from") proxy_id: int = Path(..., description="Proxy ID to delete proxys from")
): ):
AppManger().remove_proxy_by_id(proxy_id) client_host = request.headers.get("Host")
# client_host = request.client.host
AppManger().remove_proxy_by_id(proxy_id,client_host)

View File

@ -1,3 +1,4 @@
import base64
import json import json
import os import os
import shutil import shutil
@ -333,7 +334,7 @@ class AppManger:
endpointId = portainerManager.get_local_endpoint_id() endpointId = portainerManager.get_local_endpoint_id()
# generate app_id # generate app_id
app_id = app_id + "_" + PasswordGenerator.generate_weak_password(6) app_id = app_id + "_" + PasswordGenerator.generate_random_string(5)
# add app to appInstalling # add app to appInstalling
app_uuid = start_app_installation(app_id, app_name) app_uuid = start_app_installation(app_id, app_name)
@ -389,7 +390,7 @@ class AppManger:
envHelper.set_value("W9_ID", app_id) envHelper.set_value("W9_ID", app_id)
envHelper.set_value("W9_DIST", "community") envHelper.set_value("W9_DIST", "community")
envHelper.set_value("W9_VERSION", app_version) envHelper.set_value("W9_VERSION", app_version)
envHelper.set_value("POWER_PASSWORD", PasswordGenerator.generate_strong_password()) envHelper.set_value("W9_POWER_PASSWORD", PasswordGenerator.generate_strong_password())
# Get "W9_URL" from env file (validate the app is web app) # Get "W9_URL" from env file (validate the app is web app)
is_web_app = envHelper.get_value("W9_URL") is_web_app = envHelper.get_value("W9_URL")
@ -921,6 +922,30 @@ class AppManger:
forward_port = https_port forward_port = https_port
# Create proxy # Create proxy
if forward_port: if forward_port:
w9_url = stack_env.get("W9_URL",None)
w9_url_replace = stack_env.get("W9_URL_REPLACE",None)
if w9_url and w9_url_replace:
# Get the all proxys by app_id
all_domain_names = proxyManager.get_proxy_host_by_app(app_id)
# if all_domain_names is empty,create proxy
if not all_domain_names:
# update the env file
self._update_gitea_env_file(app_id,w9_url,domain_names[0])
# redeploy app
self.redeploy_app(app_id,False)
else:
combined_domain_names = []
for item in all_domain_names:
combined_domain_names.extend(item['domain_names'])
combined_domain_names.extend(domain_names)
if w9_url not in combined_domain_names:
# update the env file
self._update_gitea_env_file(app_id,w9_url,domain_names[0])
# redeploy app
self.redeploy_app(app_id,False)
# Get the forward scheme form env file: http or https # Get the forward scheme form env file: http or https
proxy_host = proxyManager.create_proxy_by_app(domain_names,app_id,forward_port,forward_scheme=forward_scheme) proxy_host = proxyManager.create_proxy_by_app(domain_names,app_id,forward_port,forward_scheme=forward_scheme)
if proxy_host: if proxy_host:
@ -974,7 +999,7 @@ class AppManger:
proxyManager.remove_proxy_host_by_app(app_id) proxyManager.remove_proxy_host_by_app(app_id)
logger.access(f"Successfully removed all domains for app: [{app_id}]") logger.access(f"Successfully removed all domains for app: [{app_id}]")
def remove_proxy_by_id(self,proxy_id:int): def remove_proxy_by_id(self,proxy_id:int,client_host:str):
""" """
Remove proxy by proxy_id Remove proxy by proxy_id
@ -982,29 +1007,59 @@ class AppManger:
proxy_id (int): The proxy id. proxy_id (int): The proxy id.
""" """
# Check the proxy id is exists # Check the proxy id is exists
host = ProxyManager().get_proxy_host_by_id(proxy_id) try:
proxyManager = ProxyManager()
host = proxyManager.get_proxy_host_by_id(proxy_id)
if host is None: if host is None:
raise CustomException( raise CustomException(
status_code=400, status_code=400,
message="Invalid Request", message="Invalid Request",
details=f"Proxy ID:{proxy_id} Not Found" details=f"Proxy ID:{proxy_id} Not Found"
) )
# # Get the app_id by proxy_id # Get the app_id by proxy_id
# app_id = host.get("forward_host",None) app_id = host.get("forward_host",None)
# if app_id: if app_id:
# # Get the app_info by app_id # Get the app_info by app_id
# app_info = self.get_app_by_id(app_id) app_info = self.get_app_by_id(app_id)
# if app_info: if app_info:
# # Get the w9_url and w9_url_replace # Get the w9_url and w9_url_replace
# w9_url = app_info.get("w9_url",None) w9_url_replace = next((element.get("w9_url_replace") for element in app_info.domain_names if element.get("id") == proxy_id), None)
# w9_url_replace = app_info.get("w9_url_replace",None) w9_url = next((element.get("w9_url") for element in app_info.domain_names if element.get("id") == proxy_id), None)
# if w9_url_replace: # validate w9_url_replace is true
# domain_names = host.get("domain_names",None) if w9_url_replace:
domain_names = host.get("domain_names",None)
if domain_names:
# Get the all proxys by app_id
app_proxys = self.get_proxys_by_app(app_id)
# if w9_url is in domain_names
if w9_url in domain_names:
new_w9_url = None
if len(app_proxys) == 1 and app_proxys[0].get("id") == proxy_id:
new_w9_url = client_host
elif len(app_proxys) > 1:
# Get the first proxy_host
proxy_host = next((proxy for proxy in app_proxys if proxy.get("id") != proxy_id), None)
if proxy_host:
# Get the domain_names
domain_names = proxy_host.get("domain_names",None)
if domain_names:
# Get the first domain_name
new_w9_url = domain_names[0]
# update the env file
self._update_gitea_env_file(app_id,w9_url,new_w9_url)
# redeploy app
self.redeploy_app(app_id,False)
# Remove proxy # Remove proxy
ProxyManager().remove_proxy_host_by_id(proxy_id) proxyManager.remove_proxy_host_by_id(proxy_id)
logger.access(f"Successfully removed domains:{host['domain_names']} for app: [{host['forward_host']}]") logger.access(f"Successfully removed domains:{host['domain_names']} for app: [{app_id}]")
except CustomException as e:
raise e
except Exception as e:
logger.error(f"Remove proxy error:{e}")
raise CustomException()
def update_proxy_by_app(self,proxy_id:str,domain_names:list[str],endpointId:int = None): def update_proxy_by_app(self,proxy_id:str,domain_names:list[str],endpointId:int = None):
""" """
@ -1033,7 +1088,26 @@ class AppManger:
details=f"Proxy ID:{proxy_id} Not Found" details=f"Proxy ID:{proxy_id} Not Found"
) )
# check_domain_names(domain_names) # Get the app_id by proxy_id
app_id = host.get("forward_host",None)
old_domain_names = host.get("domain_names",None)
logger.access(f"old_domain_names:{old_domain_names}")
if app_id:
# Get the app_info by app_id
app_info = self.get_app_by_id(app_id)
if app_info:
# Get the w9_url and w9_url_replace
w9_url_replace = next((element.get("w9_url_replace") for element in app_info.domain_names if element.get("id") == proxy_id), None)
w9_url = next((element.get("w9_url") for element in app_info.domain_names if element.get("id") == proxy_id), None)
# validate w9_url_replace is true
if w9_url_replace and w9_url:
if w9_url in old_domain_names:
if w9_url not in domain_names:
# update the env file
self._update_gitea_env_file(app_id,w9_url,domain_names[0])
# redeploy app
self.redeploy_app(app_id,False)
# Update proxy # Update proxy
result = proxyManager.update_proxy_by_app(proxy_id,domain_names) result = proxyManager.update_proxy_by_app(proxy_id,domain_names)
@ -1064,4 +1138,37 @@ class AppManger:
logger.error(f"Init local repo and push to remote repo error:{e}") logger.error(f"Init local repo and push to remote repo error:{e}")
raise CustomException() raise CustomException()
def _update_gitea_env_file(self,app_id:str,key:str,value:str):
"""
Update the env file w9_url
Args:
app_id (str): The app id.
domain_name (str): The domain name.
"""
try:
giteaManager = GiteaManager()
# Get the env file from git repo
git_env_file = giteaManager.get_file_content_from_repo(app_id,".env")
# Get the env file sha
git_env_file_sha = git_env_file.get("sha",None)
# Get the env file content
git_env_file_content = git_env_file.get("content",None)
if git_env_file_sha and git_env_file_content:
# Get the env file content
env_file_content = base64.b64decode(git_env_file_content).decode("utf-8")
# Modify the env file content
env_file_content = env_file_content.replace(key,value)
# base64 encode for env_file_content
env_file_content = base64.b64encode(env_file_content.encode("utf-8")).decode("utf-8")
# Update the env file to git repo
giteaManager.update_file_in_repo(app_id,".env",env_file_content,git_env_file_sha)
logger.access(f"Update the git repo env file for app: [{app_id}]")
else:
logger.error(f"Get the git repo env file error")
raise CustomException()
except CustomException as e:
raise e
except Exception as e:
logger.error(f"Update the git repo env file error:{e}")
raise CustomException()

View File

@ -116,7 +116,7 @@ class GiteaManager:
sha (str): File sha sha (str): File sha
""" """
response = self.gitea.update_file_content_in_repo(repo_name, file_path, content, sha) response = self.gitea.update_file_content_in_repo(repo_name, file_path, content, sha)
if response.status_code != 201: if response.status_code != 200:
logger.error(f"Update file:{file_path} content in repo:{repo_name} error:{response.status_code}:{response.text}") logger.error(f"Update file:{file_path} content in repo:{repo_name} error:{response.status_code}:{response.text}")
raise CustomException() raise CustomException()

View File

@ -33,8 +33,9 @@ class PasswordGenerator:
return password return password
@staticmethod @staticmethod
def generate_weak_password(length:int=8): def generate_random_string(length:int=8):
""" """
Generate a weak password. Generate a weak password.
@ -44,5 +45,5 @@ class PasswordGenerator:
Returns: Returns:
str: A weak password. str: A weak password.
""" """
return ''.join(random.choice(string.ascii_lowercase) for _ in range(length)) characters = string.ascii_lowercase + string.digits
return ''.join(random.choice(characters) for _ in range(length))