mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
chore: Fix save_config.py script with kubernetes + Update save_config Database function to return changed_plugins if no error happened
This commit is contained in:
parent
6f53e83c65
commit
6947b19b9a
4 changed files with 85 additions and 47 deletions
|
|
@ -140,6 +140,15 @@ class Config(ConfigCaller):
|
|||
if err:
|
||||
self.__logger.error(f"Failed to update instances: {err}")
|
||||
|
||||
# save config to database
|
||||
changed_plugins = []
|
||||
if "config" in changes:
|
||||
err = self._db.save_config(self.__config, "autoconf", changed=False)
|
||||
if isinstance(err, str):
|
||||
success = False
|
||||
self.__logger.error(f"Can't save config in database: {err}, config may not work as expected")
|
||||
changed_plugins = err
|
||||
|
||||
# save custom configs to database
|
||||
if "custom_configs" in changes:
|
||||
err = self._db.save_custom_configs(custom_configs, "autoconf", changed=False)
|
||||
|
|
@ -147,16 +156,9 @@ class Config(ConfigCaller):
|
|||
success = False
|
||||
self.__logger.error(f"Can't save autoconf custom configs in database: {err}, custom configs may not work as expected")
|
||||
|
||||
# save config to database
|
||||
if "config" in changes:
|
||||
err = self._db.save_config(self.__config, "autoconf")
|
||||
if err:
|
||||
success = False
|
||||
self.__logger.error(f"Can't save config in database: {err}, config may not work as expected")
|
||||
else:
|
||||
# update changes in db
|
||||
ret = self._db.checked_changes(changes, value=True)
|
||||
if ret:
|
||||
self.__logger.error(f"An error occurred when setting the changes to checked in the database : {ret}")
|
||||
# update changes in db
|
||||
ret = self._db.checked_changes(changes, plugins_changes=changed_plugins, value=True)
|
||||
if ret:
|
||||
self.__logger.error(f"An error occurred when setting the changes to checked in the database : {ret}")
|
||||
|
||||
return success
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from os.path import join
|
|||
from pathlib import Path
|
||||
from re import compile as re_compile
|
||||
from sys import argv, path as sys_path
|
||||
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
||||
from typing import Any, Dict, List, Literal, Optional, Set, Tuple, Union
|
||||
from time import sleep
|
||||
from uuid import uuid4
|
||||
from zipfile import ZIP_DEFLATED, ZipFile
|
||||
|
|
@ -512,9 +512,12 @@ class Database:
|
|||
except BaseException as e:
|
||||
return str(e)
|
||||
|
||||
def checked_changes(self, changes: Optional[List[str]] = None, value: Optional[bool] = False) -> str:
|
||||
def checked_changes(
|
||||
self, changes: Optional[List[str]] = None, plugins_changes: Optional[Union[Set[str], List[str], Tuple[str]]] = None, value: Optional[bool] = False
|
||||
) -> str:
|
||||
"""Set changed bit for config, custom configs, instances and plugins"""
|
||||
changes = changes or ["config", "custom_configs", "external_plugins", "pro_plugins", "instances"]
|
||||
plugins_changes = plugins_changes or set()
|
||||
with self.__db_session() as session:
|
||||
if self.readonly:
|
||||
return "The database is read-only, the changes will not be saved"
|
||||
|
|
@ -536,25 +539,10 @@ class Database:
|
|||
metadata.pro_plugins_changed = value
|
||||
if "instances" in changes:
|
||||
metadata.instances_changed = value
|
||||
session.commit()
|
||||
except BaseException as e:
|
||||
return str(e)
|
||||
|
||||
return ""
|
||||
if plugins_changes:
|
||||
session.query(Plugins).filter(Plugins.id.in_(plugins_changes)).update({Plugins.config_changed: value})
|
||||
|
||||
def checked_plugins_changes(self, plugins: Optional[List[str]] = None, value: Optional[bool] = False) -> str:
|
||||
"""Set changed bit for plugins"""
|
||||
with self.__db_session() as session:
|
||||
if self.readonly:
|
||||
return "The database is read-only, the changes will not be saved"
|
||||
|
||||
plugins = plugins or []
|
||||
|
||||
try:
|
||||
query = session.query(Plugins)
|
||||
if plugins:
|
||||
query = query.filter(Plugins.id.in_(plugins))
|
||||
query.update({Plugins.config_changed: value})
|
||||
session.commit()
|
||||
except BaseException as e:
|
||||
return str(e)
|
||||
|
|
@ -1130,7 +1118,7 @@ class Database:
|
|||
|
||||
return True, ""
|
||||
|
||||
def save_config(self, config: Dict[str, Any], method: str, changed: Optional[bool] = True) -> str:
|
||||
def save_config(self, config: Dict[str, Any], method: str, changed: Optional[bool] = True) -> Union[str, Set[str]]:
|
||||
"""Save the config in the database"""
|
||||
to_put = []
|
||||
with self.__db_session() as session:
|
||||
|
|
@ -1331,6 +1319,9 @@ class Database:
|
|||
continue
|
||||
query.update({Global_values.value: value})
|
||||
|
||||
if changed_services:
|
||||
changed_plugins = set(plugin.id for plugin in session.query(Plugins).with_entities(Plugins.id).all())
|
||||
|
||||
if changed:
|
||||
with suppress(ProgrammingError, OperationalError):
|
||||
metadata = session.query(Metadata).get(1)
|
||||
|
|
@ -1338,9 +1329,7 @@ class Database:
|
|||
if not metadata.first_config_saved:
|
||||
metadata.first_config_saved = True
|
||||
|
||||
if changed_services:
|
||||
session.query(Plugins).update({Plugins.config_changed: True})
|
||||
elif changed_plugins:
|
||||
if changed_plugins:
|
||||
session.query(Plugins).filter(Plugins.id.in_(changed_plugins)).update({Plugins.config_changed: True})
|
||||
|
||||
try:
|
||||
|
|
@ -1349,7 +1338,7 @@ class Database:
|
|||
except BaseException as e:
|
||||
return str(e)
|
||||
|
||||
return ""
|
||||
return changed_plugins
|
||||
|
||||
def save_custom_configs(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in ((
|
|||
sys_path.append(deps_path)
|
||||
|
||||
from docker import DockerClient
|
||||
from kubernetes import client as kube_client
|
||||
from kubernetes import config as kube_config
|
||||
|
||||
from common_utils import get_integration # type: ignore
|
||||
from logger import setup_logger # type: ignore
|
||||
|
|
@ -142,6 +144,8 @@ if __name__ == "__main__":
|
|||
logger.error(f"Missing RX rights on directory : {path}")
|
||||
sys_exit(1)
|
||||
|
||||
tmp_config = {}
|
||||
|
||||
if args.variables:
|
||||
variables_path = Path(args.variables)
|
||||
logger.info(f"Variables : {variables_path}")
|
||||
|
|
@ -178,7 +182,6 @@ if __name__ == "__main__":
|
|||
|
||||
api_http_port = None
|
||||
api_server_name = None
|
||||
tmp_config = {}
|
||||
custom_confs = []
|
||||
apis = []
|
||||
|
||||
|
|
@ -216,6 +219,49 @@ if __name__ == "__main__":
|
|||
host=api_server_name or getenv("API_SERVER_NAME", "bwapi"),
|
||||
)
|
||||
)
|
||||
else:
|
||||
kube_config.load_incluster_config()
|
||||
kubernetes_client = kube_client.CoreV1Api()
|
||||
|
||||
api_http_port = None
|
||||
api_server_name = None
|
||||
custom_confs = []
|
||||
apis = []
|
||||
|
||||
for pod in kubernetes_client.list_pod_for_all_namespaces(watch=False).items:
|
||||
if pod.metadata.annotations is not None and "bunkerweb.io/INSTANCE" in pod.metadata.annotations:
|
||||
for env in pod.env:
|
||||
if custom_confs_rx.match(env.name):
|
||||
custom_conf = custom_confs_rx.search(env.name).groups()
|
||||
custom_confs.append(
|
||||
{
|
||||
"value": f"# CREATED BY ENV\n{env.value}",
|
||||
"exploded": (
|
||||
custom_conf[0],
|
||||
custom_conf[1],
|
||||
custom_conf[2].replace(".conf", ""),
|
||||
),
|
||||
}
|
||||
)
|
||||
logger.info(
|
||||
f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}"
|
||||
)
|
||||
else:
|
||||
tmp_config[env.name] = env.value
|
||||
|
||||
if not db and env.name == "DATABASE_URI":
|
||||
db = Database(logger, sqlalchemy_string=env.value)
|
||||
elif env.name == "API_HTTP_PORT":
|
||||
api_http_port = env.value
|
||||
elif env.name == "API_SERVER_NAME":
|
||||
api_server_name = env.value
|
||||
|
||||
apis.append(
|
||||
API(
|
||||
f"http://{pod.status.pod_ip or pod.metadata.name}:{api_http_port or getenv('API_HTTP_PORT', '5000')}",
|
||||
host=api_server_name or getenv("API_SERVER_NAME", "bwapi"),
|
||||
)
|
||||
)
|
||||
|
||||
if not db:
|
||||
db = Database(logger)
|
||||
|
|
@ -278,11 +324,13 @@ if __name__ == "__main__":
|
|||
sys_exit(0)
|
||||
|
||||
changes = []
|
||||
changed_plugins = set()
|
||||
err = db.save_config(config_files, args.method, changed=False)
|
||||
|
||||
if err:
|
||||
if isinstance(err, str):
|
||||
logger.warning(f"Couldn't save config to database : {err}, config may not work as expected")
|
||||
else:
|
||||
changed_plugins = err
|
||||
changes.append("config")
|
||||
logger.info("Config successfully saved to database")
|
||||
|
||||
|
|
@ -327,7 +375,7 @@ if __name__ == "__main__":
|
|||
|
||||
if not args.no_check_changes:
|
||||
# update changes in db
|
||||
ret = db.checked_changes(changes, value=True)
|
||||
ret = db.checked_changes(changes, plugins_changes=changed_plugins, value=True)
|
||||
if ret:
|
||||
logger.error(f"An error occurred when setting the changes to checked in the database : {ret}")
|
||||
except SystemExit as e:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from flask import flash
|
|||
from json import loads as json_loads
|
||||
from pathlib import Path
|
||||
from re import error as RegexError, search as re_search
|
||||
from typing import List, Literal, Optional, Tuple
|
||||
from typing import List, Literal, Optional, Set, Tuple, Union
|
||||
|
||||
|
||||
class Config:
|
||||
|
|
@ -15,7 +15,9 @@ class Config:
|
|||
self.__settings = json_loads(Path(sep, "usr", "share", "bunkerweb", "settings.json").read_text(encoding="utf-8"))
|
||||
self.__db = db
|
||||
|
||||
def __gen_conf(self, global_conf: dict, services_conf: list[dict], *, check_changes: bool = True, changed_service: Optional[str] = None) -> None:
|
||||
def __gen_conf(
|
||||
self, global_conf: dict, services_conf: list[dict], *, check_changes: bool = True, changed_service: Optional[str] = None
|
||||
) -> Union[str, Set[str]]:
|
||||
"""Generates the nginx configuration file from the given configuration
|
||||
|
||||
Parameters
|
||||
|
|
@ -136,9 +138,6 @@ class Config:
|
|||
|
||||
return error
|
||||
|
||||
def reload_config(self) -> Optional[str]:
|
||||
return self.__gen_conf(self.get_config(methods=False), self.get_services(methods=False))
|
||||
|
||||
def new_service(self, variables: dict, is_draft: bool = False) -> Tuple[str, int]:
|
||||
"""Creates a new service from the given variables
|
||||
|
||||
|
|
@ -165,7 +164,7 @@ class Config:
|
|||
|
||||
services.append(variables | {"IS_DRAFT": "yes" if is_draft else "no"})
|
||||
ret = self.__gen_conf(self.get_config(methods=False), services, check_changes=not is_draft)
|
||||
if ret:
|
||||
if isinstance(ret, str):
|
||||
return ret, 1
|
||||
return f"Configuration for {variables['SERVER_NAME'].split(' ')[0]} has been generated.", 0
|
||||
|
||||
|
|
@ -205,7 +204,7 @@ class Config:
|
|||
config.pop(k)
|
||||
|
||||
ret = self.__gen_conf(config, services, check_changes=check_changes, changed_service=server_name_splitted[0])
|
||||
if ret:
|
||||
if isinstance(ret, str):
|
||||
return ret, 1
|
||||
return f"Configuration for {old_server_name_splitted[0]} has been edited.", 0
|
||||
|
||||
|
|
@ -223,7 +222,7 @@ class Config:
|
|||
the confirmation message
|
||||
"""
|
||||
ret = self.__gen_conf(self.get_config(methods=False) | variables, self.get_services(methods=False))
|
||||
if ret:
|
||||
if isinstance(ret, str):
|
||||
return ret, 1
|
||||
return "The global configuration has been edited.", 0
|
||||
|
||||
|
|
@ -273,6 +272,6 @@ class Config:
|
|||
service.pop(k)
|
||||
|
||||
ret = self.__gen_conf(new_env, new_services, check_changes=check_changes)
|
||||
if ret:
|
||||
if isinstance(ret, str):
|
||||
return ret, 1
|
||||
return f"Configuration for {service_name} has been deleted.", 0
|
||||
|
|
|
|||
Loading…
Reference in a new issue