This commit is contained in:
Théophile Diot 2023-02-14 14:22:47 +01:00
commit fdd0da35d5
No known key found for this signature in database
GPG Key ID: E752C80DB72BB014
53 changed files with 4116 additions and 894 deletions

View File

@ -755,17 +755,20 @@ Repositories of Linux packages for BunkerWeb are available on [PackageCloud](htt
sudo dnf install -y nginx-1.20.2
```
```shell
curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | sudo bash && \
sudo dnf check-update && \
sudo dnf install -y bunkerweb-1.4.4
```
And finally install BunkerWeb 1.4.4 :
```shell
curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh | \
sed 's/yum install -y pygpgme --disablerepo='\''bunkerity_bunkerweb'\''/yum install -y python-gnupg/g' | \
sed 's/pypgpme_check=`rpm -qa | grep -qw pygpgme`/python-gnupg_check=`rpm -qa | grep -qw python-gnupg`/g' | sudo bash && \
sudo dnf makecache && \
sudo dnf install -y bunkerweb-1.4.4
```
To prevent upgrading NGINX and/or BunkerWeb packages when executing `dnf upgrade`, you can use the following command :
```shell
sudo dnf versionlock add nginx && \
sudo dnf versionlock add bunkerweb
```
```shell
sudo dnf versionlock add nginx && \
sudo dnf versionlock add bunkerweb
```
=== "CentOS Stream"

View File

@ -1,5 +1,5 @@
mkdocs==1.4.2
mkdocs-material==9.0.2
mkdocs-material==9.0.10
pytablewriter==0.64.2
mike==1.1.2
jinja2<3.1.0

View File

@ -1 +1 @@
1.4.4
1.5.0

View File

@ -75,7 +75,7 @@ RUN apk add --no-cache pcre bash python3 && \
chmod 660 /usr/share/bunkerweb/INTEGRATION
# Fix CVEs
RUN apk add "openssl>=1.1.1q-r0" "git>=2.32.3-r0"
RUN apk add "openssl>=1.1.1q-r0" "curl>=7.83.1-r5" "git>=2.36.4-r0" "libcurl>=7.83.1-r5"
VOLUME /data /etc/nginx

View File

@ -161,6 +161,12 @@ api.do_api_call = function(self)
if status ~= ngx.HTTP_OK then
ret = false
end
if (#resp["msg"] == 0) then
resp["msg"] = ""
elseif (type(resp["msg"]) == "table") then
resp["data"] = resp["msg"]
resp["msg"] = resp["status"]
end
return ret, resp["msg"], status, cjson.encode(resp)
end
end

View File

@ -7,6 +7,26 @@ from ApiCaller import ApiCaller
from API import API
def format_remaining_time(seconds):
days, seconds = divmod(seconds, 86400)
hours, seconds = divmod(seconds, 3600)
minutes, seconds = divmod(seconds, 60)
time_parts = []
if days > 0:
time_parts.append(f"{int(days)} day{'' if days == 1 else 's'}")
if hours > 0:
time_parts.append(f"{int(hours)} hour{'' if hours == 1 else 's'}")
if minutes > 0:
time_parts.append(f"{int(minutes)} minute{'' if minutes == 1 else 's'}")
if seconds > 0:
time_parts.append(f"{seconds:.2f} second{'' if seconds == 1 else 's'}")
if len(time_parts) > 1:
time_parts[-1] = f"and {time_parts[-1]}"
return " ".join(time_parts)
class CLI(ApiCaller):
def __init__(self):
self.__variables = dotenv_values("/etc/nginx/variables.env")
@ -126,9 +146,13 @@ class CLI(ApiCaller):
def bans(self):
ret, resp = self._send_to_apis("GET", "/bans", response=True)
if ret:
bans = resp["bans"]
bans = resp.get("data", [])
if len(bans) == 0:
return True, "No ban found"
cli_str = "List of bans :\n"
for ban in bans:
cli_str += f"- {ban['ip']} for {ban['exp']}s : {ban['reason']}\n"
cli_str += f"- {ban['ip']} for {format_remaining_time(ban['exp'])} : {ban.get('reason', 'no reason given')}\n"
return True, cli_str
return False, "error"

View File

@ -38,7 +38,7 @@
"id": "antibot-session-secret",
"label": "Antibot Session secret",
"regex": "^(random|\\w+)$",
"type": "text"
"type": "password"
},
"ANTIBOT_SESSION_NAME": {
"context": "global",
@ -74,7 +74,7 @@
"id": "antibot-recaptcha-secret",
"label": "reCAPTCHA secret",
"regex": "^[\\w-]*$",
"type": "text"
"type": "password"
},
"ANTIBOT_HCAPTCHA_SITEKEY": {
"context": "multisite",
@ -92,7 +92,7 @@
"id": "antibot-hcaptcha-secret",
"label": "hCaptcha secret",
"regex": "^(0x[a-zA-Z0-9]+)?$",
"type": "text"
"type": "password"
}
}
}

View File

@ -39,7 +39,7 @@
"id": "auth-basic-password",
"label": "Password",
"regex": "^.+",
"type": "text"
"type": "password"
},
"AUTH_BASIC_TEXT": {
"context": "multisite",

View File

@ -1,5 +1,6 @@
import requests, traceback
from os import getenv
from os.path import exists
def request(method, url, _id=None):
@ -50,13 +51,16 @@ def get_version():
def get_integration():
try:
if getenv("KUBERNETES_MODE") == "yes":
return "kubernetes"
if getenv("AUTOCONF_MODE") == "yes":
return "autoconf"
if getenv("SWARM_MODE") == "yes":
return "swarm"
with open("/etc/os-release", "r") as f:
if f.read().contains("Alpine"):
return "docker"
elif getenv("KUBERNETES_MODE") == "yes":
return "kubernetes"
elif exists("/usr/share/bunkerweb/INTEGRATION"):
with open("/usr/share/bunkerweb/INTEGRATION", "r") as f:
return f.read().strip().lower()
return "linux"
except:
return "unknown"

View File

@ -12,36 +12,37 @@ location = {{ page }} {
{% endfor %}
{% endif %}
{% set default_errors = ["400", "401", "403", "404", "405", "413", "429", "500", "501", "502", "503", "504"] %}
{% for default_error in default_errors %}
{% if not default_error + "=" in ERRORS +%}
{% if default_error == "405" +%}
error_page 405 =200 @405;
{% else +%}
error_page {{ default_error }} @{{ default_error }};
{% endif +%}
location @{{ default_error }} {
auth_basic off;
internal;
modsecurity off;
default_type 'text/html';
content_by_lua_block {
local logger = require "logger"
local errors = require "errors.errors"
local html, err
if ngx.status == 200 then
html, err = errors.error_html(tostring(405))
else
html, err = errors.error_html(tostring(ngx.status))
end
if not html then
logger.log(ngx.ERR, "ERRORS", "Error while computing HTML error template for {{ default_error }} : " .. err)
else
ngx.say(html)
end
{% if INTERCEPTED_ERROR_CODES != "" %}
{% for intercepted_error_code in INTERCEPTED_ERROR_CODES.split(" ") %}
{% if not intercepted_error_code + "=" in ERRORS +%}
{% if intercepted_error_code == "405" +%}
error_page 405 =200 @405;
{% else +%}
error_page {{ intercepted_error_code }} @{{ intercepted_error_code }};
{% endif +%}
location @{{ intercepted_error_code }} {
auth_basic off;
internal;
modsecurity off;
default_type 'text/html';
content_by_lua_block {
local logger = require "logger"
local errors = require "errors.errors"
local html, err
if ngx.status == 200 then
html, err = errors.error_html(tostring(405))
else
html, err = errors.error_html(tostring(ngx.status))
end
if not html then
logger.log(ngx.ERR, "ERRORS", "Error while computing HTML error template for {{ intercepted_error_code }} : " .. err)
else
ngx.say(html)
end
}
}
}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}

View File

@ -13,6 +13,15 @@
"label": "Errors",
"regex": "^(?! )( ?([1-5]\\d{2})(?!.*\\2(?![^=]))=(/[\\w\\].~:/?#[@!$&'()*+,;=-]*)(?!.*\\3(?!.)))*$",
"type": "text"
},
"INTERCEPTED_ERROR_CODES": {
"context": "multisite",
"default": "400 401 403 404 405 413 429 500 501 502 503 504",
"help": "List of HTTP error code intercepted by Bunkerweb",
"id": "intercepted-error-codes",
"label": "Intercepted error codes",
"regex": "^.*$",
"type": "text"
}
}
}

View File

@ -1,14 +1,14 @@
#!/usr/bin/python3
from io import BytesIO
from os import getenv, listdir, makedirs, chmod, stat, _exit
from os.path import isfile, dirname
from os import getenv, listdir, makedirs, chmod, stat, _exit, walk
from os.path import join, isfile, dirname
from stat import S_IEXEC
from sys import exit as sys_exit, path as sys_path
from uuid import uuid4
from glob import glob
from json import load, loads
from shutil import copytree, rmtree
from shutil import chown, copytree, rmtree
from traceback import format_exc
from zipfile import ZipFile
@ -97,6 +97,7 @@ try:
continue
external_plugins = []
external_plugins_ids = []
for plugin in listdir("/etc/bunkerweb/plugins"):
with open(
f"/etc/bunkerweb/plugins/{plugin}/plugin.json",
@ -105,6 +106,18 @@ try:
plugin_file = load(f)
external_plugins.append(plugin_file)
external_plugins_ids.append(plugin_file["id"])
db_plugins = db.get_plugins()
for plugin in db_plugins:
if plugin["external"] is True and plugin["id"] not in external_plugins_ids:
external_plugins.append(plugin)
# Fix permissions for the certificates
for root, dirs, files in walk("/data/plugins", topdown=False):
for name in files + dirs:
chown(join(root, name), "root", 101)
chmod(join(root, name), 0o770)
if external_plugins:
err = db.update_external_plugins(external_plugins)

View File

@ -5,12 +5,11 @@ from hashlib import sha256
from logging import (
Logger,
)
import oracledb
from os import _exit, getenv, listdir, makedirs
from os.path import dirname, exists
from pymysql import install_as_MySQLdb
from re import compile as re_compile
from sys import modules, path as sys_path
from sys import path as sys_path
from typing import Any, Dict, List, Optional, Tuple
from sqlalchemy import create_engine, inspect
from sqlalchemy.exc import (
@ -45,9 +44,6 @@ if "/usr/share/bunkerweb/utils" not in sys_path:
from jobs import file_hash
oracledb.version = "8.3.0"
modules["cx_Oracle"] = oracledb
install_as_MySQLdb()
@ -71,22 +67,33 @@ class Database:
sqlalchemy_string = f"{splitted[0]}:{':'.join(splitted[1].split(':')[1:])}"
self.database_uri = sqlalchemy_string
error = False
try:
self.__sql_engine = create_engine(
sqlalchemy_string,
encoding="utf-8",
future=True,
)
except ArgumentError:
self.__logger.error(f"Invalid database URI: {sqlalchemy_string}")
error = True
except SQLAlchemyError:
self.__logger.error(
f"Error when trying to create the engine: {format_exc()}"
)
error = True
finally:
if error:
_exit(1)
try:
assert self.__sql_engine is not None
except AssertionError:
self.__logger.error("The database engine is not initialized")
_exit(1)
not_connected = True
retries = 5
retries = 15
while not_connected:
try:
@ -98,12 +105,12 @@ class Database:
f"Can't connect to database : {format_exc()}",
)
_exit(1)
else:
self.__logger.warning(
"Can't connect to database, retrying in 5 seconds ...",
)
retries -= 1
sleep(5)
self.__logger.warning(
"Can't connect to database, retrying in 5 seconds ...",
)
retries -= 1
sleep(5)
except SQLAlchemyError:
self.__logger.error(
f"Error when trying to connect to the database: {format_exc()}"
@ -130,8 +137,13 @@ class Database:
@contextmanager
def __db_session(self):
session = self.__sql_session()
try:
assert self.__sql_session is not None
except AssertionError:
self.__logger.error("The database session is not initialized")
_exit(1)
session = self.__sql_session()
session.expire_on_commit = False
try:
@ -218,7 +230,7 @@ class Database:
return ""
def init_tables(self, default_settings: List[Dict[str, str]]) -> Tuple[bool, str]:
def init_tables(self, default_settings: List[dict]) -> Tuple[bool, str]:
"""Initialize the database tables and return the result"""
inspector = inspect(self.__sql_engine)
if len(Base.metadata.tables.keys()) <= len(inspector.get_table_names()):
@ -721,7 +733,7 @@ class Database:
for key, value in deepcopy(config).items():
original_key = key
if self.suffix_rx.search(key):
key = key[: -len(str(suffix)) - 1]
key = key[: -len(str(key.split("_")[-1])) - 1]
if key not in multisite:
continue
@ -844,7 +856,7 @@ class Database:
file_name: str,
data: bytes,
*,
checksum: str = None,
checksum: Optional[str] = None,
) -> str:
"""Update the plugin cache in the database"""
with self.__db_session() as session:
@ -1111,10 +1123,14 @@ class Database:
Jobs.name == job["name"]
).update(updates)
if exists(f"/usr/share/bunkerweb/core/{plugin['id']}/ui"):
if {"template.html", "actions.py"}.issubset(
listdir(f"/usr/share/bunkerweb/core/{plugin['id']}/ui")
):
path_ui = (
f"/var/tmp/bunkerweb/ui/{plugin['id']}/ui"
if exists(f"/var/tmp/bunkerweb/ui/{plugin['id']}/ui")
else f"/etc/bunkerweb/plugins/{plugin['id']}/ui"
)
if exists(path_ui):
if {"template.html", "actions.py"}.issubset(listdir(path_ui)):
db_plugin_page = (
session.query(Plugin_pages)
.with_entities(
@ -1127,12 +1143,12 @@ class Database:
if db_plugin_page is None:
with open(
f"/usr/share/bunkerweb/core/{plugin['id']}/ui/template.html",
f"{path_ui}/template.html",
"r",
) as file:
template = file.read().encode("utf-8")
with open(
f"/usr/share/bunkerweb/core/{plugin['id']}/ui/actions.py",
f"{path_ui}/actions.py",
"r",
) as file:
actions = file.read().encode("utf-8")
@ -1149,18 +1165,16 @@ class Database:
else: # TODO test this
updates = {}
template_checksum = file_hash(
f"/usr/share/bunkerweb/core/{plugin['id']}/ui/template.html"
)
actions_checksum = file_hash(
f"/usr/share/bunkerweb/core/{plugin['id']}/ui/actions.py"
f"{path_ui}/template.html"
)
actions_checksum = file_hash(f"{path_ui}/actions.py")
if (
template_checksum
!= db_plugin_page.template_checksum
):
with open(
f"/usr/share/bunkerweb/core/{plugin['id']}/ui/template.html",
f"{path_ui}/template.html",
"r",
) as file:
updates.update(
@ -1174,7 +1188,7 @@ class Database:
if actions_checksum != db_plugin_page.actions_checksum:
with open(
f"/usr/share/bunkerweb/core/{plugin['id']}/ui/actions.py",
f"{path_ui}/actions.py",
"r",
) as file:
updates.update(
@ -1258,6 +1272,79 @@ class Database:
return ""
def get_plugins(self) -> List[Dict[str, Any]]:
"""Get plugins."""
plugins = []
with self.__db_session() as session:
for plugin in (
session.query(Plugins)
.with_entities(
Plugins.id,
Plugins.order,
Plugins.name,
Plugins.description,
Plugins.version,
Plugins.external,
)
.order_by(Plugins.order)
.all()
):
page = (
session.query(Plugin_pages)
.with_entities(Plugin_pages.id)
.filter_by(plugin_id=plugin.id)
.first()
)
data = {
"id": plugin.id,
"order": plugin.order,
"name": plugin.name,
"description": plugin.description,
"version": plugin.version,
"external": plugin.external,
"page": page is not None,
"settings": {},
}
for setting in (
session.query(Settings)
.with_entities(
Settings.id,
Settings.context,
Settings.default,
Settings.help,
Settings.name,
Settings.label,
Settings.regex,
Settings.type,
Settings.multiple,
)
.filter_by(plugin_id=plugin.id)
.all()
):
data["settings"][setting.id] = {
"context": setting.context,
"default": setting.default,
"help": setting.help,
"id": setting.name,
"label": setting.label,
"regex": setting.regex,
"type": setting.type,
} | ({"multiple": setting.multiple} if setting.multiple else {})
if setting.type == "select":
data["settings"][setting.id]["select"] = [
select.value
for select in session.query(Selects)
.with_entities(Selects.value)
.filter_by(setting_id=setting.id)
.all()
]
plugins.append(data)
return plugins
def get_plugins_errors(self) -> int:
"""Get plugins errors."""
with self.__db_session() as session:
@ -1317,6 +1404,27 @@ class Database:
.first()
)
def get_jobs_cache_files(self) -> List[Dict[str, Any]]:
"""Get jobs cache files."""
with self.__db_session() as session:
return [
{
"job_name": cache.job_name,
"service_id": cache.service_id,
"file_name": cache.file_name,
"data": "Download file to view content",
}
for cache in (
session.query(Jobs_cache)
.with_entities(
Jobs_cache.job_name,
Jobs_cache.service_id,
Jobs_cache.file_name,
)
.all()
)
]
def add_instance(self, hostname: str, port: int, server_name: str) -> str:
"""Add instance."""
with self.__db_session() as session:
@ -1381,3 +1489,33 @@ class Database:
.all()
)
]
def get_plugin_actions(self, plugin: str) -> Optional[Any]:
"""get actions file for the plugin"""
with self.__db_session() as session:
page = (
session.query(Plugin_pages)
.with_entities(Plugin_pages.actions_file)
.filter_by(plugin_id=plugin)
.first()
)
if page is None:
return None
return page.actions_file
def get_plugin_template(self, plugin: str) -> Optional[Any]:
"""get template file for the plugin"""
with self.__db_session() as session:
page = (
session.query(Plugin_pages)
.with_entities(Plugin_pages.template_file)
.filter_by(plugin_id=plugin)
.first()
)
if page is None:
return None
return page.template_file

View File

@ -15,7 +15,9 @@ from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy.schema import UniqueConstraint
CONTEXTS_ENUM = Enum("global", "multisite", name="contexts_enum")
SETTINGS_TYPES_ENUM = Enum("text", "check", "select", name="settings_types_enum")
SETTINGS_TYPES_ENUM = Enum(
"password", "text", "check", "select", name="settings_types_enum"
)
METHODS_ENUM = Enum("ui", "scheduler", "autoconf", "manual", name="methods_enum")
SCHEDULES_ENUM = Enum("once", "minute", "hour", "day", "week", name="schedules_enum")
CUSTOM_CONFIGS_TYPES_ENUM = Enum(
@ -61,12 +63,10 @@ class Plugins(Base):
external = Column(Boolean, default=False, nullable=False)
settings = relationship(
"Settings", back_populates="plugin", cascade="all, delete, delete-orphan"
"Settings", back_populates="plugin", cascade="all, delete-orphan"
)
jobs = relationship(
"Jobs", back_populates="plugin", cascade="all, delete, delete-orphan"
)
pages = relationship("Plugin_pages", back_populates="plugin", cascade="all, delete")
jobs = relationship("Jobs", back_populates="plugin", cascade="all, delete-orphan")
pages = relationship("Plugin_pages", back_populates="plugin", cascade="all")
class Settings(Base):
@ -81,7 +81,7 @@ class Settings(Base):
name = Column(String(256), primary_key=True)
plugin_id = Column(
String(64),
ForeignKey("plugins.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("plugins.id", onupdate="cascade", ondelete="cascade"),
nullable=False,
)
context = Column(CONTEXTS_ENUM, nullable=False)
@ -92,12 +92,12 @@ class Settings(Base):
type = Column(SETTINGS_TYPES_ENUM, nullable=False)
multiple = Column(String(128), nullable=True)
selects = relationship("Selects", back_populates="setting", cascade="all, delete")
selects = relationship("Selects", back_populates="setting", cascade="all")
services = relationship(
"Services_settings", back_populates="setting", cascade="all, delete"
"Services_settings", back_populates="setting", cascade="all"
)
global_value = relationship(
"Global_values", back_populates="setting", cascade="all, delete"
"Global_values", back_populates="setting", cascade="all"
)
plugin = relationship("Plugins", back_populates="settings")
@ -107,7 +107,7 @@ class Global_values(Base):
setting_id = Column(
String(256),
ForeignKey("settings.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("settings.id", onupdate="cascade", ondelete="cascade"),
primary_key=True,
)
value = Column(String(4096), nullable=False)
@ -124,14 +124,12 @@ class Services(Base):
method = Column(METHODS_ENUM, nullable=False)
settings = relationship(
"Services_settings", back_populates="service", cascade="all, delete"
"Services_settings", back_populates="service", cascade="all"
)
custom_configs = relationship(
"Custom_configs", back_populates="service", cascade="all, delete"
)
jobs_cache = relationship(
"Jobs_cache", back_populates="service", cascade="all, delete"
"Custom_configs", back_populates="service", cascade="all"
)
jobs_cache = relationship("Jobs_cache", back_populates="service", cascade="all")
class Services_settings(Base):
@ -139,12 +137,12 @@ class Services_settings(Base):
service_id = Column(
String(64),
ForeignKey("services.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("services.id", onupdate="cascade", ondelete="cascade"),
primary_key=True,
)
setting_id = Column(
String(256),
ForeignKey("settings.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("settings.id", onupdate="cascade", ondelete="cascade"),
primary_key=True,
)
value = Column(String(4096), nullable=False)
@ -162,7 +160,7 @@ class Jobs(Base):
name = Column(String(128), primary_key=True)
plugin_id = Column(
String(64),
ForeignKey("plugins.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("plugins.id", onupdate="cascade", ondelete="cascade"),
)
file_name = Column(String(256), nullable=False)
every = Column(SCHEDULES_ENUM, nullable=False)
@ -171,7 +169,7 @@ class Jobs(Base):
last_run = Column(DateTime, nullable=True)
plugin = relationship("Plugins", back_populates="jobs")
cache = relationship("Jobs_cache", back_populates="job", cascade="all, delete")
cache = relationship("Jobs_cache", back_populates="job", cascade="all")
class Plugin_pages(Base):
@ -184,7 +182,7 @@ class Plugin_pages(Base):
)
plugin_id = Column(
String(64),
ForeignKey("plugins.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("plugins.id", onupdate="cascade", ondelete="cascade"),
nullable=False,
)
template_file = Column(LargeBinary(length=(2**32) - 1), nullable=False)
@ -206,12 +204,12 @@ class Jobs_cache(Base):
)
job_name = Column(
String(128),
ForeignKey("jobs.name", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("jobs.name", onupdate="cascade", ondelete="cascade"),
nullable=False,
)
service_id = Column(
String(64),
ForeignKey("services.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("services.id", onupdate="cascade", ondelete="cascade"),
nullable=True,
)
file_name = Column(
@ -237,7 +235,7 @@ class Custom_configs(Base):
)
service_id = Column(
String(64),
ForeignKey("services.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("services.id", onupdate="cascade", ondelete="cascade"),
nullable=True,
)
type = Column(CUSTOM_CONFIGS_TYPES_ENUM, nullable=False)
@ -254,7 +252,7 @@ class Selects(Base):
setting_id = Column(
String(256),
ForeignKey("settings.id", onupdate="CASCADE", ondelete="CASCADE"),
ForeignKey("settings.id", onupdate="cascade", ondelete="cascade"),
primary_key=True,
)
value = Column(String(256), primary_key=True)

View File

@ -1,4 +1,3 @@
sqlalchemy==1.4.46
sqlalchemy==2.0.1
psycopg2-binary==2.9.5
PyMySQL==1.0.2
oracledb==1.2.1

View File

@ -4,189 +4,68 @@
#
# pip-compile --allow-unsafe --generate-hashes --resolver=backtracking
#
cffi==1.15.1 \
--hash=sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5 \
--hash=sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef \
--hash=sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104 \
--hash=sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426 \
--hash=sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405 \
--hash=sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375 \
--hash=sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a \
--hash=sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e \
--hash=sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc \
--hash=sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf \
--hash=sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185 \
--hash=sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497 \
--hash=sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3 \
--hash=sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35 \
--hash=sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c \
--hash=sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83 \
--hash=sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21 \
--hash=sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca \
--hash=sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984 \
--hash=sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac \
--hash=sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd \
--hash=sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee \
--hash=sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a \
--hash=sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2 \
--hash=sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192 \
--hash=sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7 \
--hash=sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585 \
--hash=sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f \
--hash=sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e \
--hash=sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27 \
--hash=sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b \
--hash=sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e \
--hash=sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e \
--hash=sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d \
--hash=sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c \
--hash=sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415 \
--hash=sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82 \
--hash=sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02 \
--hash=sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314 \
--hash=sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325 \
--hash=sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c \
--hash=sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3 \
--hash=sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914 \
--hash=sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045 \
--hash=sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d \
--hash=sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9 \
--hash=sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5 \
--hash=sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2 \
--hash=sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c \
--hash=sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3 \
--hash=sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2 \
--hash=sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8 \
--hash=sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d \
--hash=sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d \
--hash=sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9 \
--hash=sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162 \
--hash=sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76 \
--hash=sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4 \
--hash=sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e \
--hash=sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9 \
--hash=sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6 \
--hash=sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b \
--hash=sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01 \
--hash=sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0
# via cryptography
cryptography==39.0.0 \
--hash=sha256:1a6915075c6d3a5e1215eab5d99bcec0da26036ff2102a1038401d6ef5bef25b \
--hash=sha256:1ee1fd0de9851ff32dbbb9362a4d833b579b4a6cc96883e8e6d2ff2a6bc7104f \
--hash=sha256:407cec680e811b4fc829de966f88a7c62a596faa250fc1a4b520a0355b9bc190 \
--hash=sha256:50386acb40fbabbceeb2986332f0287f50f29ccf1497bae31cf5c3e7b4f4b34f \
--hash=sha256:6f97109336df5c178ee7c9c711b264c502b905c2d2a29ace99ed761533a3460f \
--hash=sha256:754978da4d0457e7ca176f58c57b1f9de6556591c19b25b8bcce3c77d314f5eb \
--hash=sha256:76c24dd4fd196a80f9f2f5405a778a8ca132f16b10af113474005635fe7e066c \
--hash=sha256:7dacfdeee048814563eaaec7c4743c8aea529fe3dd53127313a792f0dadc1773 \
--hash=sha256:80ee674c08aaef194bc4627b7f2956e5ba7ef29c3cc3ca488cf15854838a8f72 \
--hash=sha256:844ad4d7c3850081dffba91cdd91950038ee4ac525c575509a42d3fc806b83c8 \
--hash=sha256:875aea1039d78557c7c6b4db2fe0e9d2413439f4676310a5f269dd342ca7a717 \
--hash=sha256:887cbc1ea60786e534b00ba8b04d1095f4272d380ebd5f7a7eb4cc274710fad9 \
--hash=sha256:ad04f413436b0781f20c52a661660f1e23bcd89a0e9bb1d6d20822d048cf2856 \
--hash=sha256:bae6c7f4a36a25291b619ad064a30a07110a805d08dc89984f4f441f6c1f3f96 \
--hash=sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288 \
--hash=sha256:e0a05aee6a82d944f9b4edd6a001178787d1546ec7c6223ee9a848a7ade92e39 \
--hash=sha256:e324de6972b151f99dc078defe8fb1b0a82c6498e37bff335f5bc6b1e3ab5a1e \
--hash=sha256:e5d71c5d5bd5b5c3eebcf7c5c2bb332d62ec68921a8c593bea8c394911a005ce \
--hash=sha256:f3ed2d864a2fa1666e749fe52fb8e23d8e06b8012e8bd8147c73797c506e86f1 \
--hash=sha256:f671c1bb0d6088e94d61d80c606d65baacc0d374e67bf895148883461cd848de \
--hash=sha256:f6c0db08d81ead9576c4d94bbb27aed8d7a430fa27890f39084c2d0e2ec6b0df \
--hash=sha256:f964c7dcf7802d133e8dbd1565914fa0194f9d683d82411989889ecd701e8adf \
--hash=sha256:fec8b932f51ae245121c4671b4bbc030880f363354b2f0e0bd1366017d891458
# via oracledb
greenlet==2.0.1 \
--hash=sha256:0109af1138afbfb8ae647e31a2b1ab030f58b21dd8528c27beaeb0093b7938a9 \
--hash=sha256:0459d94f73265744fee4c2d5ec44c6f34aa8a31017e6e9de770f7bcf29710be9 \
--hash=sha256:04957dc96669be041e0c260964cfef4c77287f07c40452e61abe19d647505581 \
--hash=sha256:0722c9be0797f544a3ed212569ca3fe3d9d1a1b13942d10dd6f0e8601e484d26 \
--hash=sha256:097e3dae69321e9100202fc62977f687454cd0ea147d0fd5a766e57450c569fd \
--hash=sha256:0b493db84d124805865adc587532ebad30efa68f79ad68f11b336e0a51ec86c2 \
--hash=sha256:13ba6e8e326e2116c954074c994da14954982ba2795aebb881c07ac5d093a58a \
--hash=sha256:13ebf93c343dd8bd010cd98e617cb4c1c1f352a0cf2524c82d3814154116aa82 \
--hash=sha256:1407fe45246632d0ffb7a3f4a520ba4e6051fc2cbd61ba1f806900c27f47706a \
--hash=sha256:1bf633a50cc93ed17e494015897361010fc08700d92676c87931d3ea464123ce \
--hash=sha256:2d0bac0385d2b43a7bd1d651621a4e0f1380abc63d6fb1012213a401cbd5bf8f \
--hash=sha256:3001d00eba6bbf084ae60ec7f4bb8ed375748f53aeaefaf2a37d9f0370558524 \
--hash=sha256:356e4519d4dfa766d50ecc498544b44c0249b6de66426041d7f8b751de4d6b48 \
--hash=sha256:38255a3f1e8942573b067510f9611fc9e38196077b0c8eb7a8c795e105f9ce77 \
--hash=sha256:3d75b8d013086b08e801fbbb896f7d5c9e6ccd44f13a9241d2bf7c0df9eda928 \
--hash=sha256:41b825d65f31e394b523c84db84f9383a2f7eefc13d987f308f4663794d2687e \
--hash=sha256:42e602564460da0e8ee67cb6d7236363ee5e131aa15943b6670e44e5c2ed0f67 \
--hash=sha256:4aeaebcd91d9fee9aa768c1b39cb12214b30bf36d2b7370505a9f2165fedd8d9 \
--hash=sha256:4c8b1c43e75c42a6cafcc71defa9e01ead39ae80bd733a2608b297412beede68 \
--hash=sha256:4d37990425b4687ade27810e3b1a1c37825d242ebc275066cfee8cb6b8829ccd \
--hash=sha256:4f09b0010e55bec3239278f642a8a506b91034f03a4fb28289a7d448a67f1515 \
--hash=sha256:505138d4fa69462447a562a7c2ef723c6025ba12ac04478bc1ce2fcc279a2db5 \
--hash=sha256:5067920de254f1a2dee8d3d9d7e4e03718e8fd2d2d9db962c8c9fa781ae82a39 \
--hash=sha256:56961cfca7da2fdd178f95ca407fa330c64f33289e1804b592a77d5593d9bd94 \
--hash=sha256:5a8e05057fab2a365c81abc696cb753da7549d20266e8511eb6c9d9f72fe3e92 \
--hash=sha256:659f167f419a4609bc0516fb18ea69ed39dbb25594934bd2dd4d0401660e8a1e \
--hash=sha256:662e8f7cad915ba75d8017b3e601afc01ef20deeeabf281bd00369de196d7726 \
--hash=sha256:6f61d71bbc9b4a3de768371b210d906726535d6ca43506737682caa754b956cd \
--hash=sha256:72b00a8e7c25dcea5946692a2485b1a0c0661ed93ecfedfa9b6687bd89a24ef5 \
--hash=sha256:811e1d37d60b47cb8126e0a929b58c046251f28117cb16fcd371eed61f66b764 \
--hash=sha256:81b0ea3715bf6a848d6f7149d25bf018fd24554a4be01fcbbe3fdc78e890b955 \
--hash=sha256:88c8d517e78acdf7df8a2134a3c4b964415b575d2840a2746ddb1cc6175f8608 \
--hash=sha256:8dca09dedf1bd8684767bc736cc20c97c29bc0c04c413e3276e0962cd7aeb148 \
--hash=sha256:974a39bdb8c90a85982cdb78a103a32e0b1be986d411303064b28a80611f6e51 \
--hash=sha256:9e112e03d37987d7b90c1e98ba5e1b59e1645226d78d73282f45b326f7bddcb9 \
--hash=sha256:9e9744c657d896c7b580455e739899e492a4a452e2dd4d2b3e459f6b244a638d \
--hash=sha256:9ed358312e63bf683b9ef22c8e442ef6c5c02973f0c2a939ec1d7b50c974015c \
--hash=sha256:9f2c221eecb7ead00b8e3ddb913c67f75cba078fd1d326053225a3f59d850d72 \
--hash=sha256:a20d33124935d27b80e6fdacbd34205732660e0a1d35d8b10b3328179a2b51a1 \
--hash=sha256:a4c0757db9bd08470ff8277791795e70d0bf035a011a528ee9a5ce9454b6cba2 \
--hash=sha256:afe07421c969e259e9403c3bb658968702bc3b78ec0b6fde3ae1e73440529c23 \
--hash=sha256:b1992ba9d4780d9af9726bbcef6a1db12d9ab1ccc35e5773685a24b7fb2758eb \
--hash=sha256:b23d2a46d53210b498e5b701a1913697671988f4bf8e10f935433f6e7c332fb6 \
--hash=sha256:b5e83e4de81dcc9425598d9469a624826a0b1211380ac444c7c791d4a2137c19 \
--hash=sha256:be35822f35f99dcc48152c9839d0171a06186f2d71ef76dc57fa556cc9bf6b45 \
--hash=sha256:be9e0fb2ada7e5124f5282d6381903183ecc73ea019568d6d63d33f25b2a9000 \
--hash=sha256:c140e7eb5ce47249668056edf3b7e9900c6a2e22fb0eaf0513f18a1b2c14e1da \
--hash=sha256:c6a08799e9e88052221adca55741bf106ec7ea0710bca635c208b751f0d5b617 \
--hash=sha256:cb242fc2cda5a307a7698c93173d3627a2a90d00507bccf5bc228851e8304963 \
--hash=sha256:cce1e90dd302f45716a7715517c6aa0468af0bf38e814ad4eab58e88fc09f7f7 \
--hash=sha256:cd4ccc364cf75d1422e66e247e52a93da6a9b73cefa8cad696f3cbbb75af179d \
--hash=sha256:d21681f09e297a5adaa73060737e3aa1279a13ecdcfcc6ef66c292cb25125b2d \
--hash=sha256:d38ffd0e81ba8ef347d2be0772e899c289b59ff150ebbbbe05dc61b1246eb4e0 \
--hash=sha256:d566b82e92ff2e09dd6342df7e0eb4ff6275a3f08db284888dcd98134dbd4243 \
--hash=sha256:d5b0ff9878333823226d270417f24f4d06f235cb3e54d1103b71ea537a6a86ce \
--hash=sha256:d6ee1aa7ab36475035eb48c01efae87d37936a8173fc4d7b10bb02c2d75dd8f6 \
--hash=sha256:db38f80540083ea33bdab614a9d28bcec4b54daa5aff1668d7827a9fc769ae0a \
--hash=sha256:ea688d11707d30e212e0110a1aac7f7f3f542a259235d396f88be68b649e47d1 \
--hash=sha256:f6327b6907b4cb72f650a5b7b1be23a2aab395017aa6f1adb13069d66360eb3f \
--hash=sha256:fb412b7db83fe56847df9c47b6fe3f13911b06339c2aa02dcc09dce8bbf582cd
greenlet==2.0.2 \
--hash=sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a \
--hash=sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a \
--hash=sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43 \
--hash=sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33 \
--hash=sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8 \
--hash=sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088 \
--hash=sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca \
--hash=sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343 \
--hash=sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645 \
--hash=sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db \
--hash=sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df \
--hash=sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3 \
--hash=sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86 \
--hash=sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2 \
--hash=sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a \
--hash=sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf \
--hash=sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7 \
--hash=sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394 \
--hash=sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40 \
--hash=sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3 \
--hash=sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6 \
--hash=sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74 \
--hash=sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0 \
--hash=sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3 \
--hash=sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91 \
--hash=sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5 \
--hash=sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9 \
--hash=sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8 \
--hash=sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b \
--hash=sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6 \
--hash=sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb \
--hash=sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73 \
--hash=sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b \
--hash=sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df \
--hash=sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9 \
--hash=sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f \
--hash=sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0 \
--hash=sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857 \
--hash=sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a \
--hash=sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249 \
--hash=sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30 \
--hash=sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292 \
--hash=sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b \
--hash=sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d \
--hash=sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b \
--hash=sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c \
--hash=sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca \
--hash=sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7 \
--hash=sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75 \
--hash=sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae \
--hash=sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b \
--hash=sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470 \
--hash=sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564 \
--hash=sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9 \
--hash=sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099 \
--hash=sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0 \
--hash=sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5 \
--hash=sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19 \
--hash=sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1 \
--hash=sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526
# via sqlalchemy
oracledb==1.2.1 \
--hash=sha256:075c33684986db2d94d301b67649b64522536e064fd105ba7849cca0ffb882b9 \
--hash=sha256:13e5450eb9e9a8b9807ba9bd80405cff444a357c147d672130f52fc7c97abb9b \
--hash=sha256:1d98a9ec2abd41417524e051fa7589c8d645f65461f22ae41881a9d9ca5ab77e \
--hash=sha256:261d02e9aa42899d20c1be028987cace6f5e05c7b6250a0f5d85239529e98fd8 \
--hash=sha256:26d0c412dd8b8967b4c22e9014f414c6107d03506d454b478076fa67ee536ac2 \
--hash=sha256:2d5ff9930790f610a42c86bba63ebd4cc3c6a6c2a14c33ca6b1adb8a5bb6a7ec \
--hash=sha256:2db753160682bef565fd32776cd153564dfc6176317a079bde424e183f81fa03 \
--hash=sha256:3288b70c2a882e9400da5d4eac5974d2aebacc2caa7ae8cc65b16b17e8914481 \
--hash=sha256:36119ba78e70481c1f7e106c1c11d69ddebf05347c5fa1f018ae570c76eddfdf \
--hash=sha256:5751006cdfd8d642bdad7fba7e7c1cbb911e9fa5537715af572c01068c150f51 \
--hash=sha256:58b8a6b7352bf4642b996139ed60d78e0b4f811d14e8ae6a4c04e5aaade19f83 \
--hash=sha256:7518d4aca4725672758ddd7f9fac815e3da8bc95893d003ddda07a46fbc731f7 \
--hash=sha256:755fbdb535dc6bef25fa991d9d9ddef627511e67324b5add680719b3352f7025 \
--hash=sha256:80b50934b2dba435ecb60c430ae429d018a76f397888175f221b671cb4a97acd \
--hash=sha256:840a9d83b91d6fcb1654636765a56a201bc94195adc739636d121739f868b4a8 \
--hash=sha256:8a87ce3277d37c4e05b12b98aed5ed7fb98020ca82198d09afa77e56f018837f \
--hash=sha256:96b5c0e421d16e4fb83b27dfb7096c162205883c076b21373a7b0b4bbf427095 \
--hash=sha256:acf4647c67536a7ccf69cd1f7aafd7738ce6f1d0d7060ac9dbccf9504ebca283 \
--hash=sha256:b28006e7fa6fedc65c6a6410ea4244d32e00e97e0eb78307f665db6387c7f055 \
--hash=sha256:b83f764b6f98df36324c48b07b69fd2d779f2baa6d21e1fe511960483f99fcaf \
--hash=sha256:b85ff3e649099b4bd71dd4b53c1a3b4adf08aa5bb6c765b3d55017818cb1ab27 \
--hash=sha256:bed7f2606106aa6b29e5273977fddb520f11942fb68233d6ae2ca1c9a1de3473 \
--hash=sha256:c71e342710d22e421e63094b99191263e09a75bd0ed2ec0bd6d152095dc7f4f2 \
--hash=sha256:cf03443c32b93a9ed8ce3260cec2d1601ced2e67f0913ccd108bbcbac5ccdff4 \
--hash=sha256:f2a6dc58806f5a190057173f8349e8600c8fbff71c6d0b6bf3c7171b3b4e53f2 \
--hash=sha256:f63e8c134c54c74f8b356939f0b7d3431158ebcfaf9199ecec6a6f4fb98e3ff1 \
--hash=sha256:fb91181294597a1bb56ee273b177d6359e208a63fe0ab61e75ce1368cf02cc9f \
--hash=sha256:ff113727383365ce5b37239376e3704ac2d183dac6449a61cb13f4089aa725b8
# via -r requirements.in
psycopg2-binary==2.9.5 \
--hash=sha256:00475004e5ed3e3bf5e056d66e5dcdf41a0dc62efcd57997acd9135c40a08a50 \
--hash=sha256:01ad49d68dd8c5362e4bfb4158f2896dc6e0c02e87b8a3770fc003459f1a4425 \
@ -260,54 +139,54 @@ psycopg2-binary==2.9.5 \
--hash=sha256:e72c91bda9880f097c8aa3601a2c0de6c708763ba8128006151f496ca9065935 \
--hash=sha256:f95b8aca2703d6a30249f83f4fe6a9abf2e627aa892a5caaab2267d56be7ab69
# via -r requirements.in
pycparser==2.21 \
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
# via cffi
pymysql==1.0.2 \
--hash=sha256:41fc3a0c5013d5f039639442321185532e3e2c8924687abe6537de157d403641 \
--hash=sha256:816927a350f38d56072aeca5dfb10221fe1dc653745853d30a216637f5d7ad36
# via -r requirements.in
sqlalchemy==1.4.46 \
--hash=sha256:07e48cbcdda6b8bc7a59d6728bd3f5f574ffe03f2c9fb384239f3789c2d95c2e \
--hash=sha256:18cafdb27834fa03569d29f571df7115812a0e59fd6a3a03ccb0d33678ec8420 \
--hash=sha256:1b1e5e96e2789d89f023d080bee432e2fef64d95857969e70d3cadec80bd26f0 \
--hash=sha256:315676344e3558f1f80d02535f410e80ea4e8fddba31ec78fe390eff5fb8f466 \
--hash=sha256:31de1e2c45e67a5ec1ecca6ec26aefc299dd5151e355eb5199cd9516b57340be \
--hash=sha256:3d94682732d1a0def5672471ba42a29ff5e21bb0aae0afa00bb10796fc1e28dd \
--hash=sha256:3ec187acf85984263299a3f15c34a6c0671f83565d86d10f43ace49881a82718 \
--hash=sha256:4847f4b1d822754e35707db913396a29d874ee77b9c3c3ef3f04d5a9a6209618 \
--hash=sha256:4d112b0f3c1bc5ff70554a97344625ef621c1bfe02a73c5d97cac91f8cd7a41e \
--hash=sha256:51e1ba2884c6a2b8e19109dc08c71c49530006c1084156ecadfaadf5f9b8b053 \
--hash=sha256:535377e9b10aff5a045e3d9ada8a62d02058b422c0504ebdcf07930599890eb0 \
--hash=sha256:5dbf17ac9a61e7a3f1c7ca47237aac93cabd7f08ad92ac5b96d6f8dea4287fc1 \
--hash=sha256:5f752676fc126edc1c4af0ec2e4d2adca48ddfae5de46bb40adbd3f903eb2120 \
--hash=sha256:64cb0ad8a190bc22d2112001cfecdec45baffdf41871de777239da6a28ed74b6 \
--hash=sha256:6913b8247d8a292ef8315162a51931e2b40ce91681f1b6f18f697045200c4a30 \
--hash=sha256:69fac0a7054d86b997af12dc23f581cf0b25fb1c7d1fed43257dee3af32d3d6d \
--hash=sha256:7001f16a9a8e06488c3c7154827c48455d1c1507d7228d43e781afbc8ceccf6d \
--hash=sha256:7b81b1030c42b003fc10ddd17825571603117f848814a344d305262d370e7c34 \
--hash=sha256:7f8267682eb41a0584cf66d8a697fef64b53281d01c93a503e1344197f2e01fe \
--hash=sha256:887865924c3d6e9a473dc82b70977395301533b3030d0f020c38fd9eba5419f2 \
--hash=sha256:9167d4227b56591a4cc5524f1b79ccd7ea994f36e4c648ab42ca995d28ebbb96 \
--hash=sha256:939f9a018d2ad04036746e15d119c0428b1e557470361aa798e6e7d7f5875be0 \
--hash=sha256:955162ad1a931fe416eded6bb144ba891ccbf9b2e49dc7ded39274dd9c5affc5 \
--hash=sha256:984ee13543a346324319a1fb72b698e521506f6f22dc37d7752a329e9cd00a32 \
--hash=sha256:9883f5fae4fd8e3f875adc2add69f8b945625811689a6c65866a35ee9c0aea23 \
--hash=sha256:a1ad90c97029cc3ab4ffd57443a20fac21d2ec3c89532b084b073b3feb5abff3 \
--hash=sha256:a3714e5b33226131ac0da60d18995a102a17dddd42368b7bdd206737297823ad \
--hash=sha256:ae067ab639fa499f67ded52f5bc8e084f045d10b5ac7bb928ae4ca2b6c0429a5 \
--hash=sha256:b33ffbdbbf5446cf36cd4cc530c9d9905d3c2fe56ed09e25c22c850cdb9fac92 \
--hash=sha256:b6e4cb5c63f705c9d546a054c60d326cbde7421421e2d2565ce3e2eee4e1a01f \
--hash=sha256:b7f4b6aa6e87991ec7ce0e769689a977776db6704947e562102431474799a857 \
--hash=sha256:c04144a24103135ea0315d459431ac196fe96f55d3213bfd6d39d0247775c854 \
--hash=sha256:c522e496f9b9b70296a7675272ec21937ccfc15da664b74b9f58d98a641ce1b6 \
--hash=sha256:c5a99282848b6cae0056b85da17392a26b2d39178394fc25700bcf967e06e97a \
--hash=sha256:c7a46639ba058d320c9f53a81db38119a74b8a7a1884df44d09fbe807d028aaf \
--hash=sha256:d4b1cc7835b39835c75cf7c20c926b42e97d074147c902a9ebb7cf2c840dc4e2 \
--hash=sha256:d4d164df3d83d204c69f840da30b292ac7dc54285096c6171245b8d7807185aa \
--hash=sha256:d61e9ecc849d8d44d7f80894ecff4abe347136e9d926560b818f6243409f3c86 \
--hash=sha256:d68e1762997bfebf9e5cf2a9fd0bcf9ca2fdd8136ce7b24bbd3bbfa4328f3e4a \
--hash=sha256:e3c1808008124850115a3f7e793a975cfa5c8a26ceeeb9ff9cbb4485cac556df \
--hash=sha256:f8cb80fe8d14307e4124f6fad64dfd87ab749c9d275f82b8b4ec84c84ecebdbe
sqlalchemy==2.0.1 \
--hash=sha256:01704ec4a6877b74608264992a87979a27a8927cefd14ccdc0d478acacc1ed85 \
--hash=sha256:0186b970fd4561def531b582a86819d8f8af65c8b1a78cf015ee47e526f4cfb6 \
--hash=sha256:05b81afdc25d1ce43cb59647c9992559dc7487b1670ccab0426fc8b8f859e933 \
--hash=sha256:08c9169692722df8a2ef6c6ff1055e11563c990e9c74df9af62139a0c6397b8c \
--hash=sha256:0fcc9b2f5b334fdaf278459dfc0fb86d3a0317ae8ce813a7a3ef8639b44b6e4a \
--hash=sha256:101df3fa8f207ade1124d7729f6c9eab28a2560baa31b3e131e76a599d884b33 \
--hash=sha256:1f504779e6e68d0cb7043825958125abd7742c7c73ce9c6b652d20c6b5f17022 \
--hash=sha256:20b9e36f0219285c580dc5e98cadb59b751e259f3829460bc58d45e7a770dd36 \
--hash=sha256:31d019c60f4817b24c484d3110c7754cd2b8f7070057eddef5822994bf16da5a \
--hash=sha256:34a4e134eac68354cce40b35ccdbc91ff67ce0c791ea4aa81e021f2ee14bfefb \
--hash=sha256:3846d36c1ca113a7fa078abb5e69a8c3d1c7642baf12267dcd9a0d660cf1bdeb \
--hash=sha256:3997238968fa495fac4b17fa18b36616c41a6e6759f323dfb3f83cbcf1d3b1bb \
--hash=sha256:476bd377f430b1871f058332696ef61c42dfa8ad242ebb8bcf212c3d4127ea8a \
--hash=sha256:54b24a20cca275ada37ba40aa87dd257fda6e7da7f448d3282b6124d940f64d5 \
--hash=sha256:5bc451ee18776dcb6b2ac8c154db0536f75a2535f5da055179734f5e7f2e7b72 \
--hash=sha256:619784c399f5c4240b002e4dba30cfba15696274614da77846b69b2c9a74066b \
--hash=sha256:655e93fabd11bf53e6af44cee152b608d49ece4b4d9cc29328dd476faaa47c0c \
--hash=sha256:664a21613d7eff895de9ef731632575cfca773ddbac9b7f7adad288ab971bcbd \
--hash=sha256:664ec164bc01ab66dfd19062ca7982a9ea12274596e17732908eb78621adc147 \
--hash=sha256:67c35b33a0828b4f5ac6e76a1b6a54b27d693599c93ea7a4c8e53ff52796378f \
--hash=sha256:6dd8405bd1ffcbf11fda0e6b172e7e90044610de16325295efe92367551f666d \
--hash=sha256:70d38432d75f6c95973f9713b30881e40a4e8d8ccfe8bbeb55466d8c737acc79 \
--hash=sha256:7b07b83789997cf83ce9a5e7156a2b9a6cb54a4137add8ad95eff32f6746279b \
--hash=sha256:7e23205506a437476dce8193357ce47254cce7c94018b1b4856476ad2e74f1ae \
--hash=sha256:8770318683c8e08976633cec2c9711eb4279553ecbad1ca97f82c5b9174e0e76 \
--hash=sha256:8f9085bedb9e2f2bf714cfd86be6deaa7050f998843a3a0e595ec3eb0d25c743 \
--hash=sha256:9efb27e899cf7d43cf42c0852ef772a8b568c39dc7b55768a5a80c67bb64dfc2 \
--hash=sha256:a5e1826a1ebbbbc26285a0304d7cafff4ec63cdae83fde89d5f2ec67f4444a44 \
--hash=sha256:a97c4b5527ea563867ccbee031af93932d9699c6c73f1ea70adcbc935c80379e \
--hash=sha256:aeb49e1436d6558d31c006b385a5071e802be6db257ce36940e66cefce92aa72 \
--hash=sha256:c34c6b7975cb9e4848d4366d54a634bbced7b491a36029642c7e738a44b595a3 \
--hash=sha256:c681d0f59c8ed12fd3f68d08d423354b1cc501220ddabc7a20b9ca8ed52b8f70 \
--hash=sha256:ca2ce5f3125cb6e043c90dd901446b74878f35eb6660e0e58d7ef02832f7d332 \
--hash=sha256:d1588f6ba25dbb2d6eb1531e56f419e02cdc9ec06d9f082195877c5148f6f6ab \
--hash=sha256:db3e4db26c1a771d7b23a1031eaf351cfcaaa96d463ae900bb56c6a6f0585fbf \
--hash=sha256:e49e9aefffe9c598a6ccf8d2dbb4556f4d93d0ae346b9d199b3712d24af0ce75 \
--hash=sha256:e60bec8fdd753212aa8cec012bbb3060e9c2227496fa935ca8918744a34c864d \
--hash=sha256:eeec87ebe90018bc871b84b03e4bff5dbdc722e28b8f5a6e9a94486eb0cb4902 \
--hash=sha256:eff376cc201363634b5b60a828b3998b088a71e16f7a43da26fc0e2201e25a05 \
--hash=sha256:f44c37e03cb941dd0db371a9f391cfb586c9966f436bf18b5492ee26f5ac6a5b \
--hash=sha256:f707729cc35dbd1d672b11037f5464b8a42c1e89772d7fc60648da215fa72fc6
# via -r requirements.in
typing-extensions==4.4.0 \
--hash=sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa \
--hash=sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e
# via sqlalchemy

View File

@ -14,9 +14,11 @@ class Configurator:
self,
settings: str,
core: Union[str, dict],
plugins: str,
plugins: Union[str, dict],
variables: Union[str, dict],
logger: Logger,
*,
plugins_settings: list = None,
):
self.__logger = logger
self.__settings = self.__load_settings(settings)
@ -26,8 +28,12 @@ class Configurator:
else:
self.__core = core
self.__plugins_settings = []
self.__plugins = self.__load_plugins(plugins, "plugins")
self.__plugins_settings = plugins_settings or []
if isinstance(plugins, str):
self.__plugins = self.__load_plugins(plugins, "plugins")
else:
self.__plugins = plugins
if isinstance(variables, str):
self.__variables = self.__load_variables(variables)

View File

@ -1,5 +1,5 @@
docker==6.0.1
kubernetes==25.3.0
jinja2==3.1.2
python-dotenv==0.21.0
requests==2.28.1
python-dotenv==0.21.1
requests==2.28.2

View File

@ -4,9 +4,9 @@
#
# pip-compile --allow-unsafe --generate-hashes --resolver=backtracking
#
cachetools==5.2.0 \
--hash=sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757 \
--hash=sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db
cachetools==5.3.0 \
--hash=sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14 \
--hash=sha256:429e1a1e845c008ea6c85aa35d4b98b65d6a9763eeef3e37e92728a12d1de9d4
# via google-auth
certifi==2022.12.7 \
--hash=sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3 \
@ -14,17 +14,103 @@ certifi==2022.12.7 \
# via
# kubernetes
# requests
charset-normalizer==2.1.1 \
--hash=sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845 \
--hash=sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f
charset-normalizer==3.0.1 \
--hash=sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b \
--hash=sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42 \
--hash=sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d \
--hash=sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b \
--hash=sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a \
--hash=sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59 \
--hash=sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154 \
--hash=sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1 \
--hash=sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c \
--hash=sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a \
--hash=sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d \
--hash=sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6 \
--hash=sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b \
--hash=sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b \
--hash=sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783 \
--hash=sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5 \
--hash=sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918 \
--hash=sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555 \
--hash=sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639 \
--hash=sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786 \
--hash=sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e \
--hash=sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed \
--hash=sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820 \
--hash=sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8 \
--hash=sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3 \
--hash=sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541 \
--hash=sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14 \
--hash=sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be \
--hash=sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e \
--hash=sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76 \
--hash=sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b \
--hash=sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c \
--hash=sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b \
--hash=sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3 \
--hash=sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc \
--hash=sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6 \
--hash=sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59 \
--hash=sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4 \
--hash=sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d \
--hash=sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d \
--hash=sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3 \
--hash=sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a \
--hash=sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea \
--hash=sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6 \
--hash=sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e \
--hash=sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603 \
--hash=sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24 \
--hash=sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a \
--hash=sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58 \
--hash=sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678 \
--hash=sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a \
--hash=sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c \
--hash=sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6 \
--hash=sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18 \
--hash=sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174 \
--hash=sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317 \
--hash=sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f \
--hash=sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc \
--hash=sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837 \
--hash=sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41 \
--hash=sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c \
--hash=sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579 \
--hash=sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753 \
--hash=sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8 \
--hash=sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291 \
--hash=sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087 \
--hash=sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866 \
--hash=sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3 \
--hash=sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d \
--hash=sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1 \
--hash=sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca \
--hash=sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e \
--hash=sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db \
--hash=sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72 \
--hash=sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d \
--hash=sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc \
--hash=sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539 \
--hash=sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d \
--hash=sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af \
--hash=sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b \
--hash=sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602 \
--hash=sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f \
--hash=sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478 \
--hash=sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c \
--hash=sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e \
--hash=sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479 \
--hash=sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7 \
--hash=sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8
# via requests
docker==6.0.1 \
--hash=sha256:896c4282e5c7af5c45e8b683b0b0c33932974fe6e50fc6906a0a83616ab3da97 \
--hash=sha256:dbcb3bd2fa80dca0788ed908218bf43972772009b881ed1e20dfc29a65e49782
# via -r requirements.in
google-auth==2.15.0 \
--hash=sha256:6897b93556d8d807ad70701bb89f000183aea366ca7ed94680828b37437a4994 \
--hash=sha256:72f12a6cfc968d754d7bdab369c5c5c16032106e52d32c6dfd8484e4c01a6d1f
google-auth==2.16.0 \
--hash=sha256:5045648c821fb72384cdc0e82cc326df195f113a33049d9b62b74589243d2acc \
--hash=sha256:ed7057a101af1146f0554a769930ac9de506aeca4fd5af6543ebe791851a9fbd
# via kubernetes
idna==3.4 \
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
@ -38,55 +124,65 @@ kubernetes==25.3.0 \
--hash=sha256:213befbb4e5aed95f94950c7eed0c2322fc5a2f8f40932e58d28fdd42d90836c \
--hash=sha256:eb42333dad0bb5caf4e66460c6a4a1a36f0f057a040f35018f6c05a699baed86
# via -r requirements.in
markupsafe==2.1.1 \
--hash=sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003 \
--hash=sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88 \
--hash=sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5 \
--hash=sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7 \
--hash=sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a \
--hash=sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603 \
--hash=sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1 \
--hash=sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135 \
--hash=sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247 \
--hash=sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6 \
--hash=sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601 \
--hash=sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77 \
--hash=sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02 \
--hash=sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e \
--hash=sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63 \
--hash=sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f \
--hash=sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980 \
--hash=sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b \
--hash=sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812 \
--hash=sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff \
--hash=sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96 \
--hash=sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1 \
--hash=sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925 \
--hash=sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a \
--hash=sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6 \
--hash=sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e \
--hash=sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f \
--hash=sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4 \
--hash=sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f \
--hash=sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3 \
--hash=sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c \
--hash=sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a \
--hash=sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417 \
--hash=sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a \
--hash=sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a \
--hash=sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37 \
--hash=sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452 \
--hash=sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933 \
--hash=sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a \
--hash=sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7
markupsafe==2.1.2 \
--hash=sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed \
--hash=sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc \
--hash=sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2 \
--hash=sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460 \
--hash=sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7 \
--hash=sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0 \
--hash=sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1 \
--hash=sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa \
--hash=sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03 \
--hash=sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323 \
--hash=sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65 \
--hash=sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013 \
--hash=sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036 \
--hash=sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f \
--hash=sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4 \
--hash=sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419 \
--hash=sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2 \
--hash=sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619 \
--hash=sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a \
--hash=sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a \
--hash=sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd \
--hash=sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7 \
--hash=sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666 \
--hash=sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65 \
--hash=sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859 \
--hash=sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625 \
--hash=sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff \
--hash=sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156 \
--hash=sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd \
--hash=sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba \
--hash=sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f \
--hash=sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1 \
--hash=sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094 \
--hash=sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a \
--hash=sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513 \
--hash=sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed \
--hash=sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d \
--hash=sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3 \
--hash=sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147 \
--hash=sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c \
--hash=sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603 \
--hash=sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601 \
--hash=sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a \
--hash=sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1 \
--hash=sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d \
--hash=sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3 \
--hash=sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54 \
--hash=sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2 \
--hash=sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6 \
--hash=sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58
# via jinja2
oauthlib==3.2.2 \
--hash=sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca \
--hash=sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918
# via requests-oauthlib
packaging==22.0 \
--hash=sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3 \
--hash=sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3
packaging==23.0 \
--hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 \
--hash=sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97
# via docker
pyasn1==0.4.8 \
--hash=sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d \
@ -102,9 +198,9 @@ python-dateutil==2.8.2 \
--hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
--hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
# via kubernetes
python-dotenv==0.21.0 \
--hash=sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5 \
--hash=sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045
python-dotenv==0.21.1 \
--hash=sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49 \
--hash=sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a
# via -r requirements.in
pyyaml==6.0 \
--hash=sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf \
@ -148,9 +244,9 @@ pyyaml==6.0 \
--hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \
--hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5
# via kubernetes
requests==2.28.1 \
--hash=sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983 \
--hash=sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349
requests==2.28.2 \
--hash=sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa \
--hash=sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf
# via
# -r requirements.in
# docker
@ -164,10 +260,6 @@ rsa==4.9 \
--hash=sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7 \
--hash=sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21
# via google-auth
setuptools==65.6.3 \
--hash=sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54 \
--hash=sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75
# via kubernetes
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
@ -175,16 +267,22 @@ six==1.16.0 \
# google-auth
# kubernetes
# python-dateutil
urllib3==1.26.13 \
--hash=sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc \
--hash=sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8
urllib3==1.26.14 \
--hash=sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72 \
--hash=sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1
# via
# docker
# kubernetes
# requests
websocket-client==1.4.2 \
--hash=sha256:d6b06432f184438d99ac1f456eaf22fe1ade524c3dd16e661142dc54e9cba574 \
--hash=sha256:d6e8f90ca8e2dd4e8027c4561adeb9456b54044312dba655e7cae652ceb9ae59
websocket-client==1.5.0 \
--hash=sha256:561ca949e5bbb5d33409a37235db55c279235c78ee407802f1d2314fff8a8536 \
--hash=sha256:fb5d81b95d350f3a54838ebcb4c68a5353bbd1412ae8f068b1e5280faeb13074
# via
# docker
# kubernetes
# The following packages are considered to be unsafe in a requirements file:
setuptools==67.1.0 \
--hash=sha256:a7687c12b444eaac951ea87a9627c4f904ac757e7abdc5aac32833234af90378 \
--hash=sha256:e261cdf010c11a41cb5cb5f1bf3338a7433832029f559a6a7614bd42a967c300
# via kubernetes

View File

@ -23,7 +23,6 @@ sys_path.extend(
)
from docker import DockerClient
from kubernetes import client as kube_client
from logger import setup_logger
from Database import Database
@ -31,7 +30,7 @@ from Configurator import Configurator
from API import API
custom_confs_rx = re_compile(
r"^([0-9a-z\.\-]*)_?CUSTOM_CONF_(HTTP|DEFAULT_SERVER_HTTP|SERVER_HTTP|MODSEC|MODSEC_CRS)_(.+)$"
r"^([0-9a-z\.-]*)_?CUSTOM_CONF_(HTTP|DEFAULT_SERVER_HTTP|SERVER_HTTP|MODSEC_CRS|MODSEC)_(.+)$"
)
@ -145,6 +144,18 @@ if __name__ == "__main__":
db = None
apis = []
plugins = args.plugins
plugins_settings = None
if not exists("/usr/sbin/nginx") and args.method == "ui":
db = Database(logger)
plugins = {}
plugins_settings = []
for plugin in db.get_plugins():
del plugin["page"]
del plugin["external"]
plugins_settings.append(plugin)
plugins.update(plugin["settings"])
# Check existences and permissions
logger.info("Checking arguments ...")
files = [args.settings] + ([args.variables] if args.variables else [])
@ -200,7 +211,12 @@ if __name__ == "__main__":
# Compute the config
logger.info("Computing config ...")
config = Configurator(
args.settings, core_settings, args.plugins, args.variables, logger
args.settings,
core_settings,
plugins,
args.variables,
logger,
plugins_settings=plugins_settings,
)
config_files = config.get_config()
custom_confs = [
@ -288,7 +304,12 @@ if __name__ == "__main__":
if config_files is None:
logger.info("Computing config ...")
config = Configurator(
args.settings, core_settings, args.plugins, tmp_config, logger
args.settings,
core_settings,
plugins,
tmp_config,
logger,
plugins_settings=plugins_settings,
)
config_files = config.get_config()

View File

@ -125,6 +125,8 @@ class ApiCaller:
)
if response:
if isinstance(resp, dict):
return ret, resp
return ret, resp.json()
return ret

View File

@ -1,3 +1,4 @@
from datetime import datetime
from logging import (
CRITICAL,
DEBUG,
@ -5,7 +6,6 @@ from logging import (
INFO,
WARNING,
Logger,
_levelToName,
_nameToLevel,
addLevelName,
basicConfig,
@ -13,13 +13,12 @@ from logging import (
setLoggerClass,
)
from os import getenv
from threading import Lock
from typing import Optional, Union
class BWLogger(Logger):
def __init__(self, name, level=INFO):
self.name = name
self.db_lock = Lock()
return super(BWLogger, self).__init__(name, level)
def _log(
@ -32,6 +31,10 @@ class BWLogger(Logger):
stack_info=False,
stacklevel=1,
):
if self.name == "UI":
with open("/var/log/nginx/ui.log", "a") as f:
f.write(f"[{datetime.now().replace(microsecond=0)}] {msg}\n")
return super(BWLogger, self)._log(
level, msg, args, exc_info, extra, stack_info, stacklevel
)
@ -73,10 +76,15 @@ addLevelName(INFO, " ")
addLevelName(WARNING, "⚠️ ")
def setup_logger(title: str, level=INFO) -> Logger:
def setup_logger(title: str, level: Optional[Union[str, int]] = None) -> Logger:
"""Set up local logger"""
title = title.upper()
logger = getLogger(title)
logger.setLevel(_nameToLevel.get(level, _levelToName.get(level, INFO)))
level = level or default_level
if isinstance(level, str):
logger.setLevel(_nameToLevel.get(level.upper(), default_level))
else:
logger.setLevel(level)
return logger

View File

@ -22,7 +22,7 @@ RUN mkdir -p /usr/share/bunkerweb/deps && \
# Nginx
COPY src/linux/nginx.repo /etc/yum.repos.d/nginx.repo
RUN dnf install yum-utils -y && \
RUN dnf install yum-utils redhat-lsb-core -y && \
dnf install nginx-1.22.1 -y
# Compile and install dependencies

View File

@ -1,4 +1,4 @@
FROM fedora:36
FROM fedora:37
ENV OS=fedora
ENV NGINX_VERSION 1.22.1

View File

@ -1,10 +1,16 @@
FROM redhat/ubi8:8.6
FROM redhat/ubi8:8.7
ENV OS=rhel
ENV NGINX_VERSION 1.22.1
# RHEL subscription
RUN subscription-manager register --username=username --password=password --auto-attach
# Copy centos repo
COPY src/linux/centos.repo /etc/yum.repos.d/centos.repo
# Copy RPM-GPG-KEY-CentOS-Official
COPY src/linux/RPM-GPG-KEY-centosofficial /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
# Import RPM-GPG-KEY-CentOS-Official
RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
# Install fpm
RUN dnf install -y ruby ruby-devel make gcc redhat-rpm-config rpm-build wget && \
@ -16,7 +22,9 @@ RUN dnf install -y ruby ruby-devel make gcc redhat-rpm-config rpm-build wget &&
# Nginx
COPY src/linux/nginx.repo /etc/yum.repos.d/nginx.repo
RUN dnf install yum-utils -y && \
dnf install nginx-1.22.1 -y
wget https://nginx.org/packages/rhel/8/x86_64/RPMS/nginx-1.22.1-1.el8.ngx.x86_64.rpm && \
dnf install nginx-1.22.1-1.el8.ngx.x86_64.rpm -y && \
rm -rf nginx-1.22.1-1.el8.ngx.x86_64.rpm
# Copy dependencies sources folder
COPY src/deps /tmp/bunkerweb/deps
@ -30,7 +38,7 @@ RUN mkdir -p /usr/share/bunkerweb/deps && \
rm -rf /tmp/req
# Compile and install dependencies
RUN dnf install -y wget python39-pip brotli brotli-devel gperftools-devel perl libxslt-devel libxml2 libxslt bash gd gd-devel gcc-c++ kernel-devel curl znc-modtcl libmpc-devel gmp-devel gawk mpfr-devel libtool pcre-devel automake autoconf readline-devel gcc make openssl-devel git zlib-devel libxml2-devel pkgconf libcurl-devel geoip-devel lmdb-libs && \
RUN dnf install -y readline-devel python39-pip brotli brotli-devel gperftools-devel perl libxslt-devel libxml2 libxslt bash gd gd-devel gcc-c++ curl znc-modtcl gawk libtool pcre-devel automake autoconf gcc make openssl-devel git zlib-devel libxml2-devel pkgconf libcurl-devel geoip-devel --skip-broken && \
pip3.9 install --no-cache-dir --upgrade pip && \
pip3.9 install wheel && \
#mkdir -p /usr/share/bunkerweb/deps && \

View File

@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
mQINBFzMWxkBEADHrskpBgN9OphmhRkc7P/YrsAGSvvl7kfu+e9KAaU6f5MeAVyn
rIoM43syyGkgFyWgjZM8/rur7EMPY2yt+2q/1ZfLVCRn9856JqTIq0XRpDUe4nKQ
8BlA7wDVZoSDxUZkSuTIyExbDf0cpw89Tcf62Mxmi8jh74vRlPy1PgjWL5494b3X
5fxDidH4bqPZyxTBqPrUFuo+EfUVEqiGF94Ppq6ZUvrBGOVo1V1+Ifm9CGEK597c
aevcGc1RFlgxIgN84UpuDjPR9/zSndwJ7XsXYvZ6HXcKGagRKsfYDWGPkA5cOL/e
f+yObOnC43yPUvpggQ4KaNJ6+SMTZOKikM8yciyBwLqwrjo8FlJgkv8Vfag/2UR7
JINbyqHHoLUhQ2m6HXSwK4YjtwidF9EUkaBZWrrskYR3IRZLXlWqeOi/+ezYOW0m
vufrkcvsh+TKlVVnuwmEPjJ8mwUSpsLdfPJo1DHsd8FS03SCKPaXFdD7ePfEjiYk
nHpQaKE01aWVSLUiygn7F7rYemGqV9Vt7tBw5pz0vqSC72a5E3zFzIIuHx6aANry
Gat3aqU3qtBXOrA/dPkX9cWE+UR5wo/A2UdKJZLlGhM2WRJ3ltmGT48V9CeS6N9Y
m4CKdzvg7EWjlTlFrd/8WJ2KoqOE9leDPeXRPncubJfJ6LLIHyG09h9kKQARAQAB
tDpDZW50T1MgKENlbnRPUyBPZmZpY2lhbCBTaWduaW5nIEtleSkgPHNlY3VyaXR5
QGNlbnRvcy5vcmc+iQI3BBMBAgAhBQJczFsZAhsDBgsJCAcDAgYVCAIJCgsDFgIB
Ah4BAheAAAoJEAW1VbOEg8ZdjOsP/2ygSxH9jqffOU9SKyJDlraL2gIutqZ3B8pl
Gy/Qnb9QD1EJVb4ZxOEhcY2W9VJfIpnf3yBuAto7zvKe/G1nxH4Bt6WTJQCkUjcs
N3qPWsx1VslsAEz7bXGiHym6Ay4xF28bQ9XYIokIQXd0T2rD3/lNGxNtORZ2bKjD
vOzYzvh2idUIY1DgGWJ11gtHFIA9CvHcW+SMPEhkcKZJAO51ayFBqTSSpiorVwTq
a0cB+cgmCQOI4/MY+kIvzoexfG7xhkUqe0wxmph9RQQxlTbNQDCdaxSgwbF2T+gw
byaDvkS4xtR6Soj7BKjKAmcnf5fn4C5Or0KLUqMzBtDMbfQQihn62iZJN6ZZ/4dg
q4HTqyVpyuzMXsFpJ9L/FqH2DJ4exGGpBv00ba/Zauy7GsqOc5PnNBsYaHCply0X
407DRx51t9YwYI/ttValuehq9+gRJpOTTKp6AjZn/a5Yt3h6jDgpNfM/EyLFIY9z
V6CXqQQ/8JRvaik/JsGCf+eeLZOw4koIjZGEAg04iuyNTjhx0e/QHEVcYAqNLhXG
rCTTbCn3NSUO9qxEXC+K/1m1kaXoCGA0UWlVGZ1JSifbbMx0yxq/brpEZPUYm+32
o8XfbocBWljFUJ+6aljTvZ3LQLKTSPW7TFO+GXycAOmCGhlXh2tlc6iTc41PACqy
yy+mHmSv
=kkH7
-----END PGP PUBLIC KEY BLOCK-----

6
src/linux/centos.repo Normal file
View File

@ -0,0 +1,6 @@
[centos8-base]
name = CentOS 8 Base OS
baseurl = http://mirror.centos.org/centos/8-stream/BaseOS/x86_64/os/
gpgcheck = 1
enabled = 1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

View File

@ -7,6 +7,7 @@
--description "BunkerWeb %VERSION% for CentOS Stream 8"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"
--before-install /usr/share/bunkerweb/scripts/beforeInstall.sh
--after-install /usr/share/bunkerweb/scripts/postinstall.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemove.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemoveRPM.sh
/usr/share/bunkerweb/=/usr/share/bunkerweb/ /usr/bin/bwcli=/usr/bin/bwcli /etc/bunkerweb/=/etc/bunkerweb /var/tmp/bunkerweb/=/var/tmp/bunkerweb /var/cache/bunkerweb/=/var/cache/bunkerweb /lib/systemd/system/bunkerweb.service=/lib/systemd/system/bunkerweb.service /lib/systemd/system/bunkerweb-ui.service=/lib/systemd/system/bunkerweb-ui.service /var/lib/bunkerweb=/var/lib/bunkerweb /etc/letsencrypt=/etc/letsencrypt

View File

@ -7,6 +7,7 @@
--description "BunkerWeb %VERSION% for Debian 11"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"
--before-install /usr/share/bunkerweb/scripts/beforeInstall.sh
--after-install /usr/share/bunkerweb/scripts/postinstall.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemove.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemoveDEB.sh
/usr/share/bunkerweb/=/usr/share/bunkerweb/ /usr/bin/bwcli=/usr/bin/bwcli /etc/bunkerweb/=/etc/bunkerweb /var/tmp/bunkerweb/=/var/tmp/bunkerweb /var/cache/bunkerweb/=/var/cache/bunkerweb /lib/systemd/system/bunkerweb.service=/lib/systemd/system/bunkerweb.service /lib/systemd/system/bunkerweb-ui.service=/lib/systemd/system/bunkerweb-ui.service /var/lib/bunkerweb=/var/lib/bunkerweb /etc/letsencrypt=/etc/letsencrypt

View File

@ -3,10 +3,11 @@
--license agpl3
--version %VERSION%
--architecture x86_64
--depends bash --depends python3 --depends 'nginx = 1:1.22.1-2.fc36' --depends libcurl-devel --depends libxml2 --depends lmdb-libs --depends geoip-devel --depends gd --depends sudo --depends procps --depends lsof
--depends bash --depends python3 --depends 'nginx = 1:1.22.1-1.fc37' --depends libcurl-devel --depends libxml2 --depends lmdb-libs --depends geoip-devel --depends gd --depends sudo --depends procps --depends lsof
--description "BunkerWeb %VERSION% for Fedora 36"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"
--before-install /usr/share/bunkerweb/scripts/beforeInstall.sh
--after-install /usr/share/bunkerweb/scripts/postinstall.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemove.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemoveRPM.sh
/usr/share/bunkerweb/=/usr/share/bunkerweb/ /usr/bin/bwcli=/usr/bin/bwcli /etc/bunkerweb/=/etc/bunkerweb /var/tmp/bunkerweb/=/var/tmp/bunkerweb /var/cache/bunkerweb/=/var/cache/bunkerweb /lib/systemd/system/bunkerweb.service=/lib/systemd/system/bunkerweb.service /lib/systemd/system/bunkerweb-ui.service=/lib/systemd/system/bunkerweb-ui.service /var/lib/bunkerweb=/var/lib/bunkerweb /etc/letsencrypt=/etc/letsencrypt

View File

@ -3,10 +3,11 @@
--license agpl3
--version %VERSION%
--architecture x86_64
--depends bash --depends epel-release --depends python39 --depends 'nginx = 1:1.22.1-1.el8.ngx' --depends libcurl-devel --depends libxml2 --depends lmdb-libs --depends GeoIP-devel --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof
--depends bash --depends python39 --depends 'nginx = 1:1.22.1-1.el8.ngx' --depends libcurl-devel --depends libxml2 --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof
--description "BunkerWeb %VERSION% for Rhel 8"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"
--before-install /usr/share/bunkerweb/scripts/beforeInstall.sh
--after-install /usr/share/bunkerweb/scripts/postinstall.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemove.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemoveRPM.sh
/usr/share/bunkerweb/=/usr/share/bunkerweb/ /usr/bin/bwcli=/usr/bin/bwcli /etc/bunkerweb/=/etc/bunkerweb /var/tmp/bunkerweb/=/var/tmp/bunkerweb /var/cache/bunkerweb/=/var/cache/bunkerweb /lib/systemd/system/bunkerweb.service=/lib/systemd/system/bunkerweb.service /lib/systemd/system/bunkerweb-ui.service=/lib/systemd/system/bunkerweb-ui.service /var/lib/bunkerweb=/var/lib/bunkerweb /etc/letsencrypt=/etc/letsencrypt

View File

@ -6,7 +6,8 @@
--description "BunkerWeb %VERSION% for Ubuntu 22.04"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"
--before-install /usr/share/bunkerweb/scripts/beforeInstall.sh
--after-install /usr/share/bunkerweb/scripts/postinstall.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemove.sh
--after-remove /usr/share/bunkerweb/scripts/afterRemoveDEB.sh
--deb-no-default-config-files
/usr/share/bunkerweb/=/usr/share/bunkerweb/ /usr/bin/bwcli=/usr/bin/bwcli /etc/bunkerweb/=/etc/bunkerweb /var/tmp/bunkerweb/=/var/tmp/bunkerweb /var/cache/bunkerweb/=/var/cache/bunkerweb /lib/systemd/system/bunkerweb.service=/lib/systemd/system/bunkerweb.service /lib/systemd/system/bunkerweb-ui.service=/lib/systemd/system/bunkerweb-ui.service /var/lib/bunkerweb=/var/lib/bunkerweb /etc/letsencrypt=/etc/letsencrypt

View File

@ -25,17 +25,14 @@ function remove_systemd_service {
service=$1
service_file="/lib/systemd/system/$service.service"
echo "checking service $service with $service_file file "
if test -f "$service_file"; then
if [ -f "$service_file" ]; then
echo " Remove $service service"
do_and_check_cmd systemctl stop $service
do_and_check_cmd systemctl disable $service
do_and_check_cmd rm -f "$service_file"
reload_systemd
else
echo "❌ Error: $service file not found"
do_and_check_cmd systemctl stop $service
do_and_check_cmd systemctl disable $service
reload_systemd
echo "$service_file not found"
fi
}
@ -105,7 +102,7 @@ fi
# Detect OS
OS=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
if ! [[ "$OS" =~ (debian|ubuntu|centos|fedora) ]]; then
if ! [[ "$OS" =~ (debian|ubuntu) ]]; then
echo "❌ Unsupported Operating System"
exit 1
fi
@ -119,5 +116,14 @@ elif [ "$1" = "purge" ]; then
purge
else
echo "Package is being upgraded"
# Check the version of the package and if it's inferior to 1.5.0, we need to copy the variables.env file
VERSION=$(dpkg-query -W -f='${Version}' bunkerweb)
if [ "$VERSION" <= "1.5.0" ]; then
echo " Copyenv variables to /var/tmp/bunkerweb/*.env"
do_and_check_cmd cp -f /opt/bunkerweb/variables.env /var/tmp/variables.env
do_and_check_cmd cp -f /opt/bunkerweb/ui.env /var/tmp/ui.env
fi
cp -f /etc/bunkerweb/variables.env /var/tmp/variables.env
cp -f /etc/bunkerweb/ui.env /var/tmp/ui.env
exit 0
fi

View File

@ -0,0 +1,136 @@
#!/bin/bash
# Function to run a command and check its return code
function do_and_check_cmd() {
output=$("$@" 2>&1)
ret="$?"
if [ $ret -ne 0 ] ; then
echo "❌ Error from command : $*"
echo "$output"
exit $ret
else
echo "✔️ Success: $*"
echo "$output"
fi
return 0
}
function reload_systemd() {
do_and_check_cmd systemctl daemon-reload
do_and_check_cmd systemctl reset-failed
}
# remove a systemd service
function remove_systemd_service {
service=$1
service_file="/lib/systemd/system/$service.service"
echo "checking service $service with $service_file file "
if [ -f "$service_file" ]; then
echo " Remove $service service"
do_and_check_cmd systemctl stop $service
do_and_check_cmd systemctl disable $service
do_and_check_cmd rm -f "$service_file"
reload_systemd
else
echo "$service_file not found"
fi
}
function remove {
echo "Package is being uninstalled"
# Stop nginx
if systemctl is-active nginx; then
echo " Stop nginx service"
do_and_check_cmd systemctl stop nginx
fi
remove_systemd_service "bunkerweb"
remove_systemd_service "bunkerweb-ui"
# Remove /usr/share/bunkerweb
if test -e "/usr/share/bunkerweb"; then
echo " Remove /usr/share/bunkerweb"
do_and_check_cmd rm -rf /usr/share/bunkerweb
fi
# Remove /etc/bunkerweb
if test -e "/var/tmp/bunkerweb"; then
echo " Remove /var/tmp/bunkerweb"
do_and_check_cmd rm -rf /var/tmp/bunkerweb
fi
# Remove /var/lib/bunkerweb
if test -e "/var/cache/bunkerweb"; then
echo " Remove /var/cache/bunkerweb"
do_and_check_cmd rm -rf /var/cache/bunkerweb
fi
# Remove /usr/bin/bwcli
if test -f "/usr/bin/bwcli"; then
echo " Remove /usr/bin/bwcli"
do_and_check_cmd rm -f /usr/bin/bwcli
fi
echo " BunkerWeb successfully uninstalled"
}
function purge() {
echo "Package is being purged"
remove
# Remove /var/lib/bunkerweb
if test -e "/var/lib/bunkerweb"; then
echo " Remove /var/lib/bunkerweb"
do_and_check_cmd rm -rf /var/lib/bunkerweb
fi
# Remove /var/tmp/bunkerweb/variables.env
if test -d "/etc/bunkerweb"; then
echo " Remove /etc/bunkerweb"
do_and_check_cmd rm -rf /etc/bunkerweb
fi
echo " BunkerWeb successfully purged"
}
# Check if we are root
if [ $(id -u) -ne 0 ] ; then
echo "❌ Run me as root"
exit 1
fi
if [ -f /etc/redhat-release ]; then
OS="redhat"
else
OS=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
fi
if ! [[ "$OS" =~ (centos|fedora|redhat) ]]; then
echo "❌ Unsupported Operating System"
exit 1
fi
# Check if the package is being upgraded or uninstalled
if [ "$1" = "0" ]; then
# Call the remove function
remove
purge
elif [ "$1" = "1" ]; then
echo "Package is being upgraded"
# Check the version of the package and if it's inferior to 1.5.0, we need to copy the variables.env file
VERSION=$(rpm -q --queryformat '%{VERSION}' bunkerweb)
if [ "$VERSION" <= "1.5.0" ]; then
echo " Copy /etc/bunkerweb/variables.env to /var/tmp/bunkerweb/variables.env"
do_and_check_cmd cp -f /opt/bunkerweb/variables.env /var/tmp/variables.env
do_and_check_cmd cp -f /opt/bunkerweb/ui.env /var/tmp/ui.env
fi
cp -f /etc/bunkerweb/variables.env /var/tmp/variables.env
cp -f /etc/bunkerweb/ui.env /var/tmp/ui.env
cp -f /var/lib/bunkerweb/db.sqlite3 /var/tmp/db.sqlite3
exit 0
fi
else
echo "Error"
exit 0
fi

View File

@ -0,0 +1,44 @@
#!/bin/bash
# Function to run a command and check its return code
function do_and_check_cmd() {
output=$("$@" 2>&1)
ret="$?"
if [ $ret -ne 0 ] ; then
echo "❌ Error from command : $*"
echo "$output"
exit $ret
else
echo "✔️ Success: $*"
echo "$output"
fi
return 0
}
# Check the os running
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$NAME
if [[ "$OS" == "Ubuntu" || "$OS" == "Debian" ]]; then
# Get the version of the package
VERSION=$(dpkg-query -W -f='${Version}' bunkerweb)
if dpkg --compare-versions "$VERSION" lt "1.5.0" && [ -f /var/tmp/variables.env ] && [ -f /var/tmp/ui.env ]; then
echo " Copy /var/tmp/variables.env to /etc/bunkerweb/variables.env"
do_and_check_cmd cp -f /var/tmp/variables.env /etc/bunkerweb/variables.env
echo " Copy /var/tmp/ui.env to /etc/bunkerweb/ui.env"
do_and_check_cmd cp -f /var/tmp/ui.env /etc/bunkerweb/ui.env
fi
elif [[ "$OS" == "CentOS Linux" || "$OS" == "Fedora" ]]; then
# Get the version of the package
VERSION=$(rpm -q --queryformat '%{VERSION}' bunkerweb)
if [ "$(printf '%s\n' "$VERSION" "$(echo '1.5.0' | tr -d ' ')" | sort -V | head -n 1)" = "$VERSION" ] && [ -f /var/tmp/variables.env ] && [ -f /var/tmp/ui.env ]; then
echo " Copy /var/tmp/variables.env to /etc/bunkerweb/variables.env"
do_and_check_cmd cp -f /var/tmp/variables.env /etc/bunkerweb/variables.env
echo " Copy /var/tmp/ui.env to /etc/bunkerweb/ui.env"
do_and_check_cmd cp -f /var/tmp/ui.env /etc/bunkerweb/ui.env
fi
fi
else
echo "❌ Error: /etc/os-release not found"
exit 1
fi

View File

@ -6,7 +6,7 @@ export PYTHONPATH=/usr/share/bunkerweb/deps/python
# Create the ui.env file if it doesn't exist
if [ ! -f /etc/bunkerweb/ui.env ]; then
echo "ADMIN_USERNAME=admin" > /etc/bunkerweb/ui.env
echo "ADMIN_PASSWORD=changeme" >> /etc/bunkerweb/ui.env
echo "ADMIN_PASSWORD=PasswordChanged" >> /etc/bunkerweb/ui.env
echo "ABSOLUTE_URI=" >> /etc/bunkerweb/ui.env
fi
@ -16,25 +16,18 @@ start() {
if [ ! -f /var/tmp/bunkerweb/ui.pid ]; then
touch /var/tmp/bunkerweb/ui.pid
fi
# Check if there is a process listening on port 7000
if lsof -i :7000; then
echo "Killing existing process on port 7000"
lsof -i :7000 | awk '{if(NR>1) print $2}' | xargs kill -9
fi
python3 -m gunicorn --bind=127.0.0.1:7000 --chdir /usr/share/bunkerweb/ui/ --workers=1 --threads=2 main:app &
echo $! > /var/tmp/bunkerweb/ui.pid
source /etc/bunkerweb/ui.env
export $(cat /etc/bunkerweb/ui.env)
python3 -m gunicorn --bind=127.0.0.1:7000 --chdir /usr/share/bunkerweb/ui/ --workers=1 --threads=2 main:app &
echo $! > /var/tmp/bunkerweb/ui.pid
}
# Function to stop the UI
stop() {
echo "Stopping UI service..."
if [ -f "/var/tmp/bunkerweb/ui.pid" ]; then
kill -SIGINT $(cat /var/tmp/bunkerweb/ui.pid)
rm -f /var/tmp/bunkerweb/ui.pid
echo "UI service stopped."
pid=$(cat /var/tmp/bunkerweb/ui.pid)
kill -s TERM $pid
else
echo "UI service is not running or the pid file doesn't exist."
fi

View File

@ -1,21 +1,80 @@
#!/bin/bash
#Start the nginx service
echo "Starting nginx service..."
systemctl start nginx
# Function to run a command and check its return code
function do_and_check_cmd() {
output=$("$@" 2>&1)
ret="$?"
if [ $ret -ne 0 ] ; then
echo "❌ Error from command : $*"
echo "$output"
exit $ret
else
echo "✔️ Success: $*"
echo "$output"
fi
return 0
}
#Start the nginx service if it is not already running
if ! systemctl is-active nginx; then
echo "Starting nginx service..."
do_and_check_cmd systemctl start nginx
fi
#Give all the permissions to the nginx user
echo "Setting ownership for all necessary directories to nginx user and group..."
chown -R nginx:nginx /usr/share/bunkerweb /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb
do_and_check_cmd chown -R nginx:nginx /usr/share/bunkerweb /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb
#Start bunkerweb service as nginx user and enable it to start on boot
echo "Enabling and starting bunkerweb service..."
systemctl enable bunkerweb
systemctl start bunkerweb
do_and_check_cmd systemctl enable bunkerweb
do_and_check_cmd systemctl start bunkerweb
#Start and enable bunkerweb-ui service
echo "Enabling and starting bunkerweb-ui service..."
systemctl enable bunkerweb-ui
systemctl start bunkerweb-ui
do_and_check_cmd systemctl enable bunkerweb-ui
do_and_check_cmd systemctl start bunkerweb-ui
# Copy old line from environment file to new one
# Check if old environment file exists
if [ -f /var/tmp/variables.env ]; then
echo "Old environment file found!"
echo "Copying old line from environment file to new one..."
while read line; do
echo "$line" >> /etc/bunkerweb/variables.env
done < /var/tmp/variables.env
# Remove old environment files
echo "Removing old environment files..."
do_and_check_cmd rm -f /var/tmp/variables.env
else
echo "Old environment file not found!"
exit 0
fi
# Copy old line from ui environment file to new one
# Check if old environment file exists
if [ -f /var/tmp/ui.env ]; then
echo "Old ui environment file found!"
echo "Copying old line from ui environment file to new one..."
while read line; do
echo "$line" >> /etc/bunkerweb/ui.env
done < /var/tmp/ui.env
# Remove old environment files
echo "Removing old environment files..."
do_and_check_cmd rm -f /var/tmp/ui.env
else
echo "Old ui environment file not found!"
exit 0
fi
# Check if old db.sqlite3 file exists
if [ -f /var/tmp/bunkerweb/db.sqlite3 ]; then
echo "Old db.sqlite3 file found!"
do_and_check_cmd cp /var/tmp/bunkerweb/db.sqlite3 /var/lib/bunkerweb/db.sqlite3
do_and_check_cmd rm -f /var/lib/bunkerweb/db.sqlite3
else
echo "Old db.sqlite3 file not found!"
exit 0
fi
echo "All services started and enabled successfully!"

View File

@ -26,19 +26,21 @@ function start() {
echo $nginx_pid > /var/tmp/bunkerweb/nginx.pid
# Check if scheduler pid file exist and remove it if so
if [ -f /var/tmp/bunkerweb/scheduler.pid ] ; then
rm -f /var/tmp/bunkerweb/scheduler.pid
fi
# if [ -f /var/tmp/bunkerweb/scheduler.pid ] ; then
# rm -f /var/tmp/bunkerweb/scheduler.pid
# fi
# Setup and check /data folder
/usr/share/bunkerweb/helpers/data.sh "ENTRYPOINT"
# Init database
if [ ! -f /etc/bunkerweb/variables.env ]; then
echo -e "IS_LOADING=yes\nSERVER_NAME=\nAPI_HTTP_PORT=${API_HTTP_PORT:-7000}\nAPI_SERVER_NAME=${API_SERVER_NAME:-bwapi}\nAPI_WHITELIST_IP=${API_WHITELIST_IP:-127.0.0.0/8}" > /etc/bunkerweb/variables.env
/usr/share/bunkerweb/gen/save_config.py --variables /etc/bunkerweb/variables.env --init
if [ "$?" -ne 0 ] ; then
log "ENTRYPOINT" "❌" "Scheduler generator failed"
exit 1
fi
fi
# Execute jobs

View File

@ -1,3 +1,3 @@
schedule==1.1.0
certbot==2.1.0
certbot==2.2.0
maxminddb==2.2.0

View File

@ -4,13 +4,13 @@
#
# pip-compile --allow-unsafe --generate-hashes --resolver=backtracking
#
acme==2.1.0 \
--hash=sha256:04cd54d46ee6611b540f79dc550a86c6de39c6c9648b856e952dcf3817ce99dd \
--hash=sha256:6a1b786154dfa3248cab36e0db7a78187986677857af2bac04f53bc79b642b8c
acme==2.2.0 \
--hash=sha256:0a0432c8fdf3b7ff2098bf97d8f2d86f746208a1dc2bd5871dfdc413d6b167b5 \
--hash=sha256:699f4efc2a012c70eff4dbfaf7ef6798b44ef7677d8b3776bd1f0058288b2219
# via certbot
certbot==2.1.0 \
--hash=sha256:0f7b7bf81bca57be9441dc90d42a589f844f7abc758ee4220ea1e3c6ccb3a4bf \
--hash=sha256:1f4409739f8454956963b4c78fc1c959db2bef85ea6fc6f08951d7275ec2595d
certbot==2.2.0 \
--hash=sha256:6bbefdbf937f3e58d0d127d98b3ede5c616bfa34af664d432a82c0d5b55004ab \
--hash=sha256:6d11bda7167d219ecba94e33907c65bfc0b2a3a3d783c525341a7b16d93ea6e9
# via -r requirements.in
certifi==2022.12.7 \
--hash=sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3 \
@ -82,16 +82,103 @@ cffi==1.15.1 \
--hash=sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01 \
--hash=sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0
# via cryptography
charset-normalizer==2.1.1 \
--hash=sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845 \
--hash=sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f
charset-normalizer==3.0.1 \
--hash=sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b \
--hash=sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42 \
--hash=sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d \
--hash=sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b \
--hash=sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a \
--hash=sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59 \
--hash=sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154 \
--hash=sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1 \
--hash=sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c \
--hash=sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a \
--hash=sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d \
--hash=sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6 \
--hash=sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b \
--hash=sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b \
--hash=sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783 \
--hash=sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5 \
--hash=sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918 \
--hash=sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555 \
--hash=sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639 \
--hash=sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786 \
--hash=sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e \
--hash=sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed \
--hash=sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820 \
--hash=sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8 \
--hash=sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3 \
--hash=sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541 \
--hash=sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14 \
--hash=sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be \
--hash=sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e \
--hash=sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76 \
--hash=sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b \
--hash=sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c \
--hash=sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b \
--hash=sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3 \
--hash=sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc \
--hash=sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6 \
--hash=sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59 \
--hash=sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4 \
--hash=sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d \
--hash=sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d \
--hash=sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3 \
--hash=sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a \
--hash=sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea \
--hash=sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6 \
--hash=sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e \
--hash=sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603 \
--hash=sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24 \
--hash=sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a \
--hash=sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58 \
--hash=sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678 \
--hash=sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a \
--hash=sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c \
--hash=sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6 \
--hash=sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18 \
--hash=sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174 \
--hash=sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317 \
--hash=sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f \
--hash=sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc \
--hash=sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837 \
--hash=sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41 \
--hash=sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c \
--hash=sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579 \
--hash=sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753 \
--hash=sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8 \
--hash=sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291 \
--hash=sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087 \
--hash=sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866 \
--hash=sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3 \
--hash=sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d \
--hash=sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1 \
--hash=sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca \
--hash=sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e \
--hash=sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db \
--hash=sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72 \
--hash=sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d \
--hash=sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc \
--hash=sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539 \
--hash=sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d \
--hash=sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af \
--hash=sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b \
--hash=sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602 \
--hash=sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f \
--hash=sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478 \
--hash=sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c \
--hash=sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e \
--hash=sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479 \
--hash=sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7 \
--hash=sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8
# via requests
configargparse==1.5.3 \
--hash=sha256:18f6535a2db9f6e02bd5626cc7455eac3e96b9ab3d969d366f9aafd5c5c00fe7 \
--hash=sha256:1b0b3cbf664ab59dada57123c81eff3d9737e0d11d8cf79e3d6eb10823f1739f
# via certbot
configobj==5.0.6 \
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902
configobj==5.0.8 \
--hash=sha256:6f704434a07dc4f4dc7c9a745172c1cad449feb548febd9f7fe362629c627a97 \
--hash=sha256:a7a8c6ab7daade85c3f329931a807c8aee750a2494363934f8ea84d8a54c87ea
# via certbot
cryptography==39.0.0 \
--hash=sha256:1a6915075c6d3a5e1215eab5d99bcec0da26036ff2102a1038401d6ef5bef25b \
@ -159,33 +246,35 @@ pyrfc3339==1.1 \
# via
# acme
# certbot
pytz==2022.7 \
--hash=sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a \
--hash=sha256:93007def75ae22f7cd991c84e02d434876818661f8df9ad5df9e950ff4e52cfd
pytz==2022.7.1 \
--hash=sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0 \
--hash=sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a
# via
# acme
# certbot
# pyrfc3339
requests==2.28.1 \
--hash=sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983 \
--hash=sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349
requests==2.28.2 \
--hash=sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa \
--hash=sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf
# via acme
schedule==1.1.0 \
--hash=sha256:617adce8b4bf38c360b781297d59918fbebfb2878f1671d189f4f4af5d0567a4 \
--hash=sha256:e6ca13585e62c810e13a08682e0a6a8ad245372e376ba2b8679294f377dfc8e4
# via -r requirements.in
setuptools==65.6.3 \
--hash=sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54 \
--hash=sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75
# via
# acme
# certbot
# josepy
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
# via configobj
urllib3==1.26.13 \
--hash=sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc \
--hash=sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8
urllib3==1.26.14 \
--hash=sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72 \
--hash=sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1
# via requests
# The following packages are considered to be unsafe in a requirements file:
setuptools==67.1.0 \
--hash=sha256:a7687c12b444eaac951ea87a9627c4f904ac757e7abdc5aac32833234af90378 \
--hash=sha256:e261cdf010c11a41cb5cb5f1bf3338a7433832029f559a6a7614bd42a967c300
# via
# acme
# certbot
# josepy

View File

@ -29,7 +29,7 @@ COPY src/ui /usr/share/bunkerweb/ui
COPY src/VERSION /usr/share/bunkerweb/VERSION
# Add ui user
RUN apk add --no-cache bash file && \
RUN apk add --no-cache bash && \
addgroup -g 101 ui && \
adduser -h /var/cache/nginx -g ui -s /bin/sh -G ui -D -H -u 101 ui && \
echo "Docker" > /usr/share/bunkerweb/INTEGRATION && \
@ -37,14 +37,15 @@ RUN apk add --no-cache bash file && \
mkdir -p /etc/bunkerweb && \
mkdir -p /data/cache && ln -s /data/cache /var/cache/bunkerweb && \
mkdir -p /data/lib && ln -s /data/lib /var/lib/bunkerweb && \
mkdir -p /var/log/nginx/ && touch /var/log/nginx/ui.log && \
for dir in $(echo "configs plugins") ; do mkdir -p "/data/${dir}" && ln -s "/data/${dir}" "/etc/bunkerweb/${dir}" ; done && \
for dir in $(echo "configs/http configs/stream configs/server-http configs/server-stream configs/default-server-http configs/default-server-stream configs/modsec configs/modsec-crs") ; do mkdir "/data/${dir}" ; done && \
chown -R root:ui /data && \
chmod -R 770 /data && \
chown -R root:ui /usr/share/bunkerweb /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb && \
chown -R root:ui /usr/share/bunkerweb /var/cache/bunkerweb /var/lib/bunkerweb /etc/bunkerweb /var/tmp/bunkerweb /var/log/nginx && \
for dir in $(echo "/usr/share/bunkerweb /etc/bunkerweb") ; do find ${dir} -type f -exec chmod 0740 {} \; ; done && \
for dir in $(echo "/usr/share/bunkerweb /etc/bunkerweb") ; do find ${dir} -type d -exec chmod 0750 {} \; ; done && \
chmod 770 /var/cache/bunkerweb /var/lib/bunkerweb /var/tmp/bunkerweb && \
chmod 770 /var/cache/bunkerweb /var/lib/bunkerweb /var/tmp/bunkerweb /var/log/nginx/ui.log && \
chmod 750 /usr/share/bunkerweb/gen/*.py /usr/share/bunkerweb/deps/python/bin/* && \
chmod 660 /usr/share/bunkerweb/INTEGRATION
@ -60,4 +61,4 @@ WORKDIR /usr/share/bunkerweb/ui
USER ui:ui
ENV PYTHONPATH /usr/share/bunkerweb/deps/python
CMD ["python3", "-m", "gunicorn", "--bind=0.0.0.0:7000", "--workers=1", "--threads=2", "--user", "ui", "--group", "ui", "main:app"]
CMD ["python3", "-m", "gunicorn", "--graceful-timeout=0", "--bind=0.0.0.0:7000", "--workers=1", "--threads=2", "--user", "ui", "--group", "ui", "main:app"]

View File

@ -1,7 +1,10 @@
from contextlib import suppress
from importlib.machinery import SourceFileLoader
from io import BytesIO
from pathlib import Path
from signal import SIGINT, signal, SIGTERM
from subprocess import PIPE, Popen, call
from tempfile import NamedTemporaryFile
from bs4 import BeautifulSoup
from copy import deepcopy
from datetime import datetime, timedelta, timezone
@ -33,7 +36,7 @@ from os.path import exists, isdir, isfile, join
from re import match as re_match
from requests import get
from shutil import rmtree, copytree, chown
from sys import path as sys_path, exit as sys_exit, modules as sys_modules
from sys import path as sys_path, modules as sys_modules
from tarfile import CompressionError, HeaderError, ReadError, TarError, open as tar_open
from threading import Thread
from time import time
@ -63,24 +66,40 @@ from utils import (
from logger import setup_logger
from Database import Database
if not exists("/var/log/nginx/ui.log"):
Path("/var/log/nginx").mkdir(parents=True, exist_ok=True)
Path("/var/log/nginx/ui.log").touch()
logger = setup_logger("UI", getenv("LOG_LEVEL", "INFO"))
def stop(status):
remove("/var/tmp/bunkerweb/ui.pid")
def stop_gunicorn():
p = Popen(["pgrep", "-f", "gunicorn"], stdout=PIPE)
out, _ = p.communicate()
pid = out.strip().decode().split("\n")[0]
call(["kill", "-SIGTERM", pid])
def stop(status, stop=True):
if exists("/var/tmp/bunkerweb/ui.pid"):
remove("/var/tmp/bunkerweb/ui.pid")
if stop is True:
stop_gunicorn()
_exit(status)
def handle_stop(signum, frame):
logger.info("Catched stop operation")
logger.info("Stopping web ui ...")
stop(0)
stop(0, False)
signal(SIGINT, handle_stop)
signal(SIGTERM, handle_stop)
Path("/var/tmp/bunkerweb/ui.pid").write_text(str(getpid()))
# Flask app
app = Flask(
__name__,
@ -95,28 +114,25 @@ vars = get_variables()
if "ABSOLUTE_URI" not in vars:
logger.error("ABSOLUTE_URI is not set")
sys_exit(1)
stop(1)
elif "ADMIN_USERNAME" not in vars:
logger.error("ADMIN_USERNAME is not set")
sys_exit(1)
stop(1)
elif "ADMIN_PASSWORD" not in vars:
logger.error("ADMIN_PASSWORD is not set")
sys_exit(1)
stop(1)
if not vars["FLASK_ENV"] == "development" and vars["ADMIN_PASSWORD"] == "changeme":
if not vars.get("FLASK_DEBUG", False) and vars["ADMIN_PASSWORD"] == "changeme":
logger.error("Please change the default admin password.")
sys_exit(1)
stop(1)
if not vars["ABSOLUTE_URI"].endswith("/"):
vars["ABSOLUTE_URI"] += "/"
if not vars["FLASK_ENV"] == "development" and vars["ABSOLUTE_URI"].endswith(
"/changeme/"
):
if not vars.get("FLASK_DEBUG", False) and vars["ABSOLUTE_URI"].endswith("/changeme/"):
logger.error("Please change the default URL.")
sys_exit(1)
stop(1)
Path("/var/tmp/bunkerweb/ui.pid").write_text(str(getpid()))
login_manager = LoginManager()
login_manager.init_app(app)
@ -180,7 +196,7 @@ try:
)
except FileNotFoundError as e:
logger.error(repr(e), e.filename)
sys_exit(1)
stop(1)
# Declare functions for jinja2
app.jinja_env.globals.update(check_settings=check_settings)
@ -189,6 +205,8 @@ app.jinja_env.globals.update(check_settings=check_settings)
def manage_bunkerweb(method: str, operation: str = "reloads", *args):
# Do the operation
if method == "services":
error = False
if operation == "new":
operation, error = app.config["CONFIG"].new_service(args[0])
elif operation == "edit":
@ -414,7 +432,7 @@ def services():
del variables["OLD_SERVER_NAME"]
# Edit check fields and remove already existing ones
config = app.config["CONFIG"].get_config(methods=False)
config = app.config["CONFIG"].get_config(methods=True)
for variable, value in deepcopy(variables).items():
variable_splitted = variable.split("_")
if "SCHEMA" in variable_splitted:
@ -428,13 +446,16 @@ def services():
elif value == "off":
value = "no"
config_setting = config.get(
f"{variables['SERVER_NAME'].split(' ')[0]}_{variable}", None
)
if variable in variables and (
request.form["operation"] == "edit"
and variable != "SERVER_NAME"
and value
== config.get(
f"{variables['SERVER_NAME'].split(' ')[0]}_{variable}", None
)
and config_setting is not None
and config_setting["method"] == "default"
and value == config_setting["value"]
or not value.strip()
):
del variables[variable]
@ -659,14 +680,12 @@ def configs():
return redirect(url_for("loading", next=url_for("configs")))
db_configs = db.get_custom_configs()
return render_template(
"configs.html",
folders=[
path_to_dict(
"/etc/bunkerweb/configs",
db_configs=db_configs,
integration=integration,
db_data=db.get_custom_configs(),
services=app.config["CONFIG"]
.get_config(methods=False)["SERVER_NAME"]
.split(" "),
@ -688,25 +707,40 @@ def plugins():
variables = deepcopy(request.form.to_dict())
del variables["csrf_token"]
if variables["external"] == "false":
if variables["external"] != "True":
flash(f"Can't delete internal plugin {variables['name']}", "error")
return redirect(url_for("loading", next=url_for("plugins"))), 500
variables["path"] = f"/etc/bunkerweb/plugins/{variables['name']}"
if not exists("/usr/sbin/nginx"):
plugins = app.config["CONFIG"].get_plugins()
for plugin in deepcopy(plugins):
if plugin["external"] is False or plugin["id"] == variables["name"]:
del plugins[plugins.index(plugin)]
operation = app.config["CONFIGFILES"].check_path(
variables["path"], "/etc/bunkerweb/plugins/"
)
err = db.update_external_plugins(plugins)
if err:
flash(
f"Couldn't update external plugins to database: {err}",
"error",
)
else:
variables["path"] = f"/etc/bunkerweb/plugins/{variables['name']}"
if operation:
flash(operation, "error")
return redirect(url_for("loading", next=url_for("plugins"))), 500
operation = app.config["CONFIGFILES"].check_path(
variables["path"], "/etc/bunkerweb/plugins/"
)
operation, error = app.config["CONFIGFILES"].delete_path(variables["path"])
if operation:
flash(operation, "error")
return redirect(url_for("loading", next=url_for("plugins"))), 500
if error:
flash(operation, "error")
return redirect(url_for("loading", next=url_for("plugins")))
operation, error = app.config["CONFIGFILES"].delete_path(
variables["path"]
)
if error:
flash(operation, "error")
return redirect(url_for("loading", next=url_for("plugins")))
else:
if not exists("/var/tmp/bunkerweb/ui") or not listdir(
"/var/tmp/bunkerweb/ui"
@ -758,13 +792,33 @@ def plugins():
)
raise Exception
if exists(f"/etc/bunkerweb/plugins/{folder_name}"):
raise FileExistsError
if not exists("/usr/sbin/nginx"):
plugins = app.config["CONFIG"].get_plugins()
for plugin in deepcopy(plugins):
if plugin["id"] == folder_name:
raise FileExistsError
elif plugin["external"] is False:
del plugins[plugins.index(plugin)]
copytree(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}",
f"/etc/bunkerweb/plugins/{folder_name}",
)
plugins.append(plugin_file)
err = db.update_external_plugins(plugins)
if err:
error = 1
flash(
f"Couldn't update external plugins to database: {err}",
"error",
)
raise Exception
else:
if exists(
f"/etc/bunkerweb/plugins/{folder_name}"
):
raise FileExistsError
copytree(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}",
f"/etc/bunkerweb/plugins/{folder_name}",
)
except KeyError:
zip_file.extractall(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}"
@ -812,13 +866,33 @@ def plugins():
)
raise Exception
if exists(f"/etc/bunkerweb/plugins/{folder_name}"):
raise FileExistsError
if not exists("/usr/sbin/nginx"):
plugins = app.config["CONFIG"].get_plugins()
for plugin in deepcopy(plugins):
if plugin["id"] == folder_name:
raise FileExistsError
elif plugin["external"] is False:
del plugins[plugins.index(plugin)]
copytree(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}/{dirs[0]}",
f"/etc/bunkerweb/plugins/{folder_name}",
)
plugins.append(plugin_file)
err = db.update_external_plugins(plugins)
if err:
error = 1
flash(
f"Couldn't update external plugins to database: {err}",
"error",
)
raise Exception
else:
if exists(
f"/etc/bunkerweb/plugins/{folder_name}"
):
raise FileExistsError
copytree(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}/{dirs[0]}",
f"/etc/bunkerweb/plugins/{folder_name}",
)
except BadZipFile:
errors += 1
error = 1
@ -861,13 +935,33 @@ def plugins():
)
raise Exception
if exists(f"/etc/bunkerweb/plugins/{folder_name}"):
raise FileExistsError
if not exists("/usr/sbin/nginx"):
plugins = app.config["CONFIG"].get_plugins()
for plugin in deepcopy(plugins):
if plugin["id"] == folder_name:
raise FileExistsError
elif plugin["external"] is False:
del plugins[plugins.index(plugin)]
copytree(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}",
f"/etc/bunkerweb/plugins/{folder_name}",
)
plugins.append(plugin_file)
err = db.update_external_plugins(plugins)
if err:
error = 1
flash(
f"Couldn't update external plugins to database: {err}",
"error",
)
raise Exception
else:
if exists(
f"/etc/bunkerweb/plugins/{folder_name}"
):
raise FileExistsError
copytree(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}",
f"/etc/bunkerweb/plugins/{folder_name}",
)
except KeyError:
tar_file.extractall(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}",
@ -915,13 +1009,33 @@ def plugins():
)
raise Exception
if exists(f"/etc/bunkerweb/plugins/{folder_name}"):
raise FileExistsError
if not exists("/usr/sbin/nginx"):
plugins = app.config["CONFIG"].get_plugins()
for plugin in deepcopy(plugins):
if plugin["id"] == folder_name:
raise FileExistsError
elif plugin["external"] is False:
del plugins[plugins.index(plugin)]
copytree(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}/{dirs[0]}",
f"/etc/bunkerweb/plugins/{folder_name}",
)
plugins.append(plugin_file)
err = db.update_external_plugins(plugins)
if err:
error = 1
flash(
f"Couldn't update external plugins to database: {err}",
"error",
)
raise Exception
else:
if exists(
f"/etc/bunkerweb/plugins/{folder_name}"
):
raise FileExistsError
copytree(
f"/var/tmp/bunkerweb/ui/{temp_folder_name}/{dirs[0]}",
f"/etc/bunkerweb/plugins/{folder_name}",
)
except ReadError:
errors += 1
error = 1
@ -993,14 +1107,12 @@ def plugins():
# Fix permissions for plugins folders
for root, dirs, files in walk("/etc/bunkerweb/plugins", topdown=False):
for name in files + dirs:
chown(join(root, name), 101, 101)
chown(join(root, name), "root", 101)
chmod(join(root, name), 0o770)
if operation:
flash(operation)
app.config["CONFIG"].reload_plugins()
# Reload instances
app.config["RELOADING"] = True
Thread(
@ -1023,19 +1135,28 @@ def plugins():
if request.args.get("plugin_id", False):
plugin_id = request.args.get("plugin_id")
page_path = ""
template = None
if exists(f"/etc/bunkerweb/plugins/{plugin_id}/ui/template.html"):
page_path = f"/etc/bunkerweb/plugins/{plugin_id}/ui/template.html"
elif exists(f"/usr/share/bunkerweb/core/{plugin_id}/ui/template.html"):
page_path = f"/usr/share/bunkerweb/core/{plugin_id}/ui/template.html"
if not exists("/usr/sbin/nginx"):
page = db.get_plugin_template(plugin_id)
if page is not None:
template = Template(page.decode("utf-8"))
else:
flash(f"Plugin {plugin_id} not found", "error")
page_path = ""
if page_path:
with open(page_path, "r") as f:
template = Template(f.read())
if exists(f"/etc/bunkerweb/plugins/{plugin_id}/ui/template.html"):
page_path = f"/etc/bunkerweb/plugins/{plugin_id}/ui/template.html"
elif exists(f"/usr/share/bunkerweb/core/{plugin_id}/ui/template.html"):
page_path = f"/usr/share/bunkerweb/core/{plugin_id}/ui/template.html"
else:
flash(f"Plugin {plugin_id} not found", "error")
if page_path:
with open(page_path, "r") as f:
template = Template(f.read())
if template is not None:
return template.render(
csrf_token=generate_csrf,
url_for=url_for,
@ -1047,7 +1168,6 @@ def plugins():
),
)
app.config["CONFIG"].reload_plugins()
plugins = app.config["CONFIG"].get_plugins()
plugins_internal = 0
plugins_external = 0
@ -1096,33 +1216,66 @@ def custom_plugin(plugin):
)
return redirect(url_for("loading", next=url_for("plugins", plugin_id=plugin)))
if not exists(f"/etc/bunkerweb/plugins/{plugin}/ui/actions.py") and not exists(
f"/usr/share/bunkerweb/core/{plugin}/ui/actions.py"
):
flash(
f"The <i>actions.py</i> file for the plugin <b>{plugin}</b> does not exist",
"error",
)
return redirect(url_for("loading", next=url_for("plugins", plugin_id=plugin)))
if not exists("/usr/sbin/nginx"):
module = db.get_plugin_actions(plugin)
# Add the custom plugin to sys.path
sys_path.append(
(
"/etc/bunkerweb/plugins"
if exists(f"/etc/bunkerweb/plugins/{plugin}/ui/actions.py")
else "/usr/share/bunkerweb/core"
if module is None:
flash(
f"The <i>actions.py</i> file for the plugin <b>{plugin}</b> does not exist",
"error",
)
return redirect(
url_for("loading", next=url_for("plugins", plugin_id=plugin))
)
try:
# Try to import the custom plugin
with NamedTemporaryFile(mode="wb", suffix=".py", delete=True) as temp:
temp.write(module)
temp.flush()
temp.seek(0)
loader = SourceFileLoader("actions", temp.name)
actions = loader.load_module()
except:
flash(
f"An error occurred while importing the plugin <b>{plugin}</b>:<br/>{format_exc()}",
"error",
)
return redirect(
url_for("loading", next=url_for("plugins", plugin_id=plugin))
)
else:
if not exists(f"/etc/bunkerweb/plugins/{plugin}/ui/actions.py") and not exists(
f"/usr/share/bunkerweb/core/{plugin}/ui/actions.py"
):
flash(
f"The <i>actions.py</i> file for the plugin <b>{plugin}</b> does not exist",
"error",
)
return redirect(
url_for("loading", next=url_for("plugins", plugin_id=plugin))
)
# Add the custom plugin to sys.path
sys_path.append(
(
"/etc/bunkerweb/plugins"
if exists(f"/etc/bunkerweb/plugins/{plugin}/ui/actions.py")
else "/usr/share/bunkerweb/core"
)
+ f"/{plugin}/ui/"
)
+ f"/{plugin}/ui/"
)
try:
# Try to import the custom plugin
import actions
except:
flash(
f"An error occurred while importing the plugin <b>{plugin}</b>:<br/>{format_exc()}",
"error",
)
return redirect(url_for("loading", next=url_for("plugins", plugin_id=plugin)))
try:
# Try to import the custom plugin
import actions
except:
flash(
f"An error occurred while importing the plugin <b>{plugin}</b>:<br/>{format_exc()}",
"error",
)
return redirect(
url_for("loading", next=url_for("plugins", plugin_id=plugin))
)
error = False
res = None
@ -1145,10 +1298,11 @@ def custom_plugin(plugin):
)
error = True
finally:
# Remove the custom plugin from the shared library
sys_path.pop()
sys_modules.pop("actions")
del actions
if exists("/usr/sbin/nginx"):
# Remove the custom plugin from the shared library
sys_path.pop()
sys_modules.pop("actions")
del actions
if (
request.method != "POST"
@ -1171,7 +1325,16 @@ def custom_plugin(plugin):
def cache():
return render_template(
"cache.html",
folders=[path_to_dict("/var/cache/bunkerweb", is_cache=True)],
folders=[
path_to_dict(
"/var/cache/bunkerweb",
is_cache=True,
db_data=db.get_jobs_cache_files(),
services=app.config["CONFIG"]
.get_config(methods=False)["SERVER_NAME"]
.split(" "),
)
],
dark_mode=app.config["DARK_MODE"],
)

View File

@ -1,9 +1,7 @@
Flask==2.2.2
Flask_Cors==3.0.10
Flask_Login==0.6.2
Flask_WTF==1.0.1
beautifulsoup4==4.11.1
Flask_WTF==1.1.1
beautifulsoup4==4.11.2
python_dateutil==2.8.2
python-magic==0.4.27
bcrypt==4.0.1
gunicorn==20.1.0

View File

@ -27,9 +27,9 @@ bcrypt==4.0.1 \
--hash=sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e \
--hash=sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3
# via -r requirements.in
beautifulsoup4==4.11.1 \
--hash=sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30 \
--hash=sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693
beautifulsoup4==4.11.2 \
--hash=sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39 \
--hash=sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106
# via -r requirements.in
click==8.1.3 \
--hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \
@ -51,9 +51,9 @@ flask-login==0.6.2 \
--hash=sha256:1ef79843f5eddd0f143c2cd994c1b05ac83c0401dc6234c143495af9a939613f \
--hash=sha256:c0a7baa9fdc448cdd3dd6f0939df72eec5177b2f7abe6cb82fc934d29caac9c3
# via -r requirements.in
flask-wtf==1.0.1 \
--hash=sha256:34fe5c6fee0f69b50e30f81a3b7ea16aa1492a771fe9ad0974d164610c09a6c9 \
--hash=sha256:9d733658c80be551ce7d5bc13c7a7ac0d80df509be1e23827c847d9520f4359a
flask-wtf==1.1.1 \
--hash=sha256:41c4244e9ae626d63bed42ae4785b90667b885b1535d5a4095e1f63060d12aa9 \
--hash=sha256:7887d6f1ebb3e17bf648647422f0944c9a469d0fcf63e3b66fb9a83037e38b2c
# via -r requirements.in
gunicorn==20.1.0 \
--hash=sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e \
@ -73,47 +73,57 @@ jinja2==3.1.2 \
--hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \
--hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61
# via flask
markupsafe==2.1.1 \
--hash=sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003 \
--hash=sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88 \
--hash=sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5 \
--hash=sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7 \
--hash=sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a \
--hash=sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603 \
--hash=sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1 \
--hash=sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135 \
--hash=sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247 \
--hash=sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6 \
--hash=sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601 \
--hash=sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77 \
--hash=sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02 \
--hash=sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e \
--hash=sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63 \
--hash=sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f \
--hash=sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980 \
--hash=sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b \
--hash=sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812 \
--hash=sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff \
--hash=sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96 \
--hash=sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1 \
--hash=sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925 \
--hash=sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a \
--hash=sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6 \
--hash=sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e \
--hash=sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f \
--hash=sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4 \
--hash=sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f \
--hash=sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3 \
--hash=sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c \
--hash=sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a \
--hash=sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417 \
--hash=sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a \
--hash=sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a \
--hash=sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37 \
--hash=sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452 \
--hash=sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933 \
--hash=sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a \
--hash=sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7
markupsafe==2.1.2 \
--hash=sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed \
--hash=sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc \
--hash=sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2 \
--hash=sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460 \
--hash=sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7 \
--hash=sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0 \
--hash=sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1 \
--hash=sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa \
--hash=sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03 \
--hash=sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323 \
--hash=sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65 \
--hash=sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013 \
--hash=sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036 \
--hash=sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f \
--hash=sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4 \
--hash=sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419 \
--hash=sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2 \
--hash=sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619 \
--hash=sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a \
--hash=sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a \
--hash=sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd \
--hash=sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7 \
--hash=sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666 \
--hash=sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65 \
--hash=sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859 \
--hash=sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625 \
--hash=sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff \
--hash=sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156 \
--hash=sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd \
--hash=sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba \
--hash=sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f \
--hash=sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1 \
--hash=sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094 \
--hash=sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a \
--hash=sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513 \
--hash=sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed \
--hash=sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d \
--hash=sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3 \
--hash=sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147 \
--hash=sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c \
--hash=sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603 \
--hash=sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601 \
--hash=sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a \
--hash=sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1 \
--hash=sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d \
--hash=sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3 \
--hash=sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54 \
--hash=sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2 \
--hash=sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6 \
--hash=sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58
# via
# jinja2
# werkzeug
@ -126,10 +136,6 @@ python-magic==0.4.27 \
--hash=sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b \
--hash=sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3
# via -r requirements.in
setuptools==65.6.3 \
--hash=sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54 \
--hash=sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75
# via gunicorn
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
@ -150,7 +156,13 @@ wtforms==3.0.1 \
--hash=sha256:6b351bbb12dd58af57ffef05bc78425d08d1914e0fd68ee14143b7ade023c5bc \
--hash=sha256:837f2f0e0ca79481b92884962b914eba4e72b7a2daaf1f939c890ed0124b834b
# via flask-wtf
zipp==3.11.0 \
--hash=sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa \
--hash=sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766
zipp==3.12.0 \
--hash=sha256:73efd63936398aac78fd92b6f4865190119d6c91b531532e798977ea8dd402eb \
--hash=sha256:9eb0a4c5feab9b08871db0d672745b53450d7f26992fd1e4653aa43345e97b86
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
setuptools==67.1.0 \
--hash=sha256:a7687c12b444eaac951ea87a9627c4f904ac757e7abdc5aac32833234af90378 \
--hash=sha256:e261cdf010c11a41cb5cb5f1bf3338a7433832029f559a6a7614bd42a967c300
# via gunicorn

View File

@ -35,54 +35,6 @@ class Config:
sleep(3)
env = self.__db.get_config()
self.reload_plugins()
def reload_plugins(self) -> None:
self.__plugins = []
external_plugins = []
for foldername in list(iglob("/etc/bunkerweb/plugins/*")) + list(
iglob("/usr/share/bunkerweb/core/*")
):
content = listdir(foldername)
if "plugin.json" not in content:
continue
with open(f"{foldername}/plugin.json", "r") as f:
plugin = json_load(f)
plugin.update(
{
"page": False,
"external": foldername.startswith("/etc/bunkerweb/plugins"),
}
)
if plugin["external"] is True:
external_plugin = deepcopy(plugin)
del external_plugin["external"]
del external_plugin["page"]
external_plugins.append(external_plugin)
if "ui" in content:
if "template.html" in listdir(f"{foldername}/ui"):
plugin["page"] = True
self.__plugins.append(plugin)
self.__plugins.sort(key=lambda plugin: plugin.get("name"))
self.__plugins_settings = {
**{k: v for x in self.__plugins for k, v in x["settings"].items()},
**self.__settings,
}
if external_plugins:
err = self.__db.update_external_plugins(external_plugins)
if err:
self.__logger.error(
f"Couldn't update external plugins to database: {err}",
)
def __env_to_dict(self, filename: str) -> dict:
"""Converts the content of an env file into a dict
@ -139,17 +91,17 @@ class Config:
conf = deepcopy(global_conf)
servers = []
plugins_settings = self.get_plugins_settings()
for service in services_conf:
server_name = service["SERVER_NAME"].split(" ")[0]
for k in service.keys():
key_without_server_name = k.replace(f"{server_name}_", "")
if (
self.__plugins_settings[key_without_server_name]["context"]
!= "global"
if key_without_server_name in self.__plugins_settings
plugins_settings[key_without_server_name]["context"] != "global"
if key_without_server_name in plugins_settings
else True
):
if not k.startswith(server_name) or k in self.__plugins_settings:
if not k.startswith(server_name) or k in plugins_settings:
conf[f"{server_name}_{k}"] = service[k]
else:
conf[k] = service[k]
@ -178,10 +130,44 @@ class Config:
remove(env_file)
def get_plugins_settings(self) -> dict:
return self.__plugins_settings
return {
**{k: v for x in self.get_plugins() for k, v in x["settings"].items()},
**self.__settings,
}
def get_plugins(self) -> List[dict]:
return self.__plugins
if not exists("/usr/sbin/nginx"):
plugins = self.__db.get_plugins()
plugins.sort(key=lambda x: x["name"])
return plugins
plugins = []
for foldername in list(iglob("/etc/bunkerweb/plugins/*")) + list(
iglob("/usr/share/bunkerweb/core/*")
):
content = listdir(foldername)
if "plugin.json" not in content:
continue
with open(f"{foldername}/plugin.json", "r") as f:
plugin = json_load(f)
plugin.update(
{
"page": False,
"external": foldername.startswith("/etc/bunkerweb/plugins"),
}
)
if "ui" in content:
if "template.html" in listdir(f"{foldername}/ui"):
plugin["page"] = True
plugins.append(plugin)
plugins.sort(key=lambda x: x["name"])
return plugins
def get_settings(self) -> dict:
return self.__settings
@ -212,6 +198,7 @@ class Config:
"""
if exists("/usr/sbin/nginx"):
services = []
plugins_settings = self.get_plugins_settings()
for filename in iglob("/etc/nginx/**/variables.env"):
service = filename.split("/")[3]
env = {
@ -219,8 +206,7 @@ class Config:
{"value": v, "method": "ui"} if methods is True else v
)
for k, v in self.__env_to_dict(filename).items()
if k.startswith(f"{service}_")
or k in self.__plugins_settings.keys()
if k.startswith(f"{service}_") or k in plugins_settings.keys()
}
services.append(env)
@ -242,11 +228,12 @@ class Config:
Return the error code
"""
error = 0
plugins_settings = self.get_plugins_settings()
for k, v in variables.items():
check = False
if k in self.__plugins_settings:
if _global ^ (self.__plugins_settings[k]["context"] == "global"):
if k in plugins_settings:
if _global ^ (plugins_settings[k]["context"] == "global"):
error = 1
flash(f"Variable {k} is not valid.", "error")
continue
@ -255,16 +242,16 @@ class Config:
else:
setting = k[0 : k.rfind("_")]
if (
setting not in self.__plugins_settings
or "multiple" not in self.__plugins_settings[setting]
setting not in plugins_settings
or "multiple" not in plugins_settings[setting]
):
error = 1
flash(f"Variable {k} is not valid.", "error")
continue
if not (
_global ^ (self.__plugins_settings[setting]["context"] == "global")
) and re_search(self.__plugins_settings[setting]["regex"], v):
_global ^ (plugins_settings[setting]["context"] == "global")
) and re_search(plugins_settings[setting]["regex"], v):
check = True
if not check:

View File

@ -164,9 +164,10 @@
<!-- checkbox -->
{% if value["type"] == "check" %}
<div checkbox-handler="{{value['id']}}" class="relative mb-7 md:mb-0">
<input type="hidden" name="{{setting}}" value="no" default-value="no" default-method="default" />
<input id="{{setting}}" name="{{setting}}" default-method="{{global_config[setting]['method']}}" default-value="{{value['default']}}" {% if global_config[setting]['method'] != 'ui' or global_config[setting]['method'] != 'default' %} disabled {% endif %} {% if global_config[setting]['value'] and global_config[setting]['value'] == 'yes' or not global_config[setting]['value'] and value['default'] == 'yes' %} checked {% endif %} id="checkbox-{{value['id']}}"
<input id="{{setting}}" name="{{setting}}"
default-method="{{global_config[setting]['method']}}" default-value="{{value['default']}}"
{% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} disabled {% endif %}
{% if global_config[setting]['value'] and global_config[setting]['value'] == 'yes' or not global_config[setting]['value'] and value['default'] == 'yes' %} checked {% endif %} id="checkbox-{{value['id']}}"
class="relative {% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} pointer-events-none {% else %} cursor-pointer {% endif %} dark:border-slate-600 dark:bg-slate-700 z-10 checked:z-0 w-5 h-5 ease text-base rounded-1.4 checked:bg-primary checked:border-primary dark:checked:bg-primary dark:checked:border-primary duration-250 float-left mt-1 appearance-none border border-gray-300 bg-white bg-contain bg-center bg-no-repeat align-top transition-all disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 disabled:text-gray-700 dark:disabled:text-gray-300"
type="checkbox"
pattern="{{value['regex']|safe}}"

View File

@ -194,7 +194,7 @@
<input id="{{setting}}" name="{{setting}}"
default-method="{{global_config[setting]['method']}}"
default-value="{{global_config[setting]['value']}}" {% if
global_config[setting]['method'] != 'ui' or global_config[setting]['method']
global_config[setting]['method'] != 'ui' and global_config[setting]['method']
!= 'default' %} disabled {% endif %} {% if global_config[setting]['value'] and
global_config[setting]['value'] == 'yes' or not
global_config[setting]['value'] and value['default'] == 'yes' %} checked {%
@ -417,7 +417,7 @@
<input id="{{setting}}_SCHEMA" name="{{setting}}_SCHEMA"
default-method="{{global_config[setting]['method']}}"
default-value="{{global_config[setting]['value']}}" {% if
global_config[setting]['method'] != 'ui' or global_config[setting]['method']
global_config[setting]['method'] != 'ui' and global_config[setting]['method']
!= 'default' %} disabled {% endif %} {% if global_config[setting]['value'] and
global_config[setting]['value'] == 'yes' or not
global_config[setting]['value'] and value['default'] == 'yes' %} checked {%

View File

@ -1,6 +1,4 @@
from datetime import datetime
from typing import List
import magic
import os
@ -20,80 +18,14 @@ def get_variables():
return vars
def log(event):
with open("/var/log/nginx/ui.log", "a") as f:
f.write("[" + str(datetime.now().replace(microsecond=0)) + "] " + event + "\n")
def path_to_dict(
path,
*,
level: int = 0,
is_cache: bool = False,
db_configs: List[dict] = [],
integration: str = "Linux",
db_data: List[dict] = [],
services: List[str] = [],
) -> dict:
if integration == "Linux":
d = {"name": os.path.basename(path)}
if os.path.isdir(path):
d.update(
{
"type": "folder",
"path": path,
"can_create_files": level > 0 and not is_cache,
"can_create_folders": level > 0 and not is_cache,
"can_edit": level > 1 and not is_cache,
"can_delete": False,
"children": [
path_to_dict(
os.path.join(path, x),
level=level + 1,
is_cache=is_cache,
db_configs=db_configs,
)
for x in sorted(os.listdir(path))
],
}
)
if level > 1 and not is_cache and not d["children"]:
d["can_delete"] = True
else:
d.update(
{
"type": "file",
"path": path,
"can_download": True,
}
)
can_edit = False
if level > 1 and not is_cache:
exploded_path = path.split("/")
for conf in db_configs:
if exploded_path[-1].replace(".conf", "") == conf["name"]:
if level > 2 and exploded_path[-2] != conf["service_id"]:
continue
can_edit = True
break
d["can_edit"] = can_edit
magic_file = magic.from_file(path, mime=True)
if (
not is_cache
or magic_file.startswith("text/")
or magic_file.startswith("application/json")
):
with open(path, "rb") as f:
d["content"] = f.read().decode("utf-8")
else:
d["content"] = "Download file to view content"
else:
if not is_cache:
config_types = [
"http",
"stream",
@ -103,6 +35,7 @@ def path_to_dict(
"modsec",
"modsec-crs",
]
d = {
"name": "configs",
"type": "folder",
@ -138,7 +71,7 @@ def path_to_dict(
],
}
for conf in db_configs:
for conf in db_data:
type_lower = conf["type"].replace("_", "-")
file_info = {
"name": f"{conf['name']}.conf",
@ -163,6 +96,47 @@ def path_to_dict(
d["children"][config_types.index(type_lower)]["children"].append(
file_info
)
else:
d = {
"name": "cache",
"type": "folder",
"path": path,
"can_create_files": False,
"can_create_folders": False,
"can_edit": False,
"can_delete": False,
"children": [
{
"name": service,
"type": "folder",
"path": f"{path}/{service}",
"can_create_files": False,
"can_create_folders": False,
"can_edit": False,
"can_delete": False,
"children": [],
}
for service in services
],
}
for conf in db_data:
file_info = {
"name": f"{conf['job_name']}/{conf['file_name']}",
"type": "file",
"path": f"{path}{'/' + conf['service_id'] if conf['service_id'] else ''}/{conf['file_name']}",
"can_edit": False,
"can_delete": False,
"can_download": True,
"content": conf["data"],
}
if conf["service_id"]:
d["children"][
[x["file_name"] for x in d["children"]].index(conf["service_id"])
]["children"].append(file_info)
else:
d["children"].append(file_info)
return d

View File

@ -1,7 +1,5 @@
FROM quay.io/centos/centos:stream8
RUN yum install -y initscripts # for old "service"
ENV container=docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
@ -13,13 +11,11 @@ rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
COPY linux/nginx.repo /etc/yum.repos.d/nginx.repo
RUN dnf -y install sudo
RUN dnf install php-fpm curl yum-utils epel-release -y && \
dnf install nginx-1.20.2 -y
RUN echo -e "[nginx-stable]\nname=nginx stable repo\nbaseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/\ngpgcheck=1\nenabled=1\ngpgkey=https://nginx.org/keys/nginx_signing.key\nmodule_hotfixes=true" > /etc/yum.repos.d/nginx.repo
RUN sudo dnf install nginx-1.20.2 -y && sudo dnf install epel-release -y
COPY ./packages/centos/*.rpm /opt
VOLUME [/sys/fs/cgroup]
VOLUME /run /tmp
CMD /usr/sbin/init
CMD ["/usr/sbin/init"]

View File

@ -1,4 +1,4 @@
FROM fedora:latest
FROM fedora:36
ENV container docker
@ -19,10 +19,14 @@ RUN rm -f /lib/systemd/system/multi-user.target.wants/* \
# Nginx
RUN dnf update -y && \
dnf install -y php-fpm curl gnupg2 ca-certificates redhat-lsb-core python3-pip which && \
dnf install nginx-1.20.2 -y
dnf install -y nginx-1.20.2
COPY ./packages/fedora/*.rpm /opt
RUN curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.rpm.sh \
| sed 's/yum install -y pygpgme --disablerepo='\''bunkerity_bunkerweb'\''/yum install -y python-gnupg/g' \
| sed 's/pypgpme_check=`rpm -qa | grep -qw pygpgme`/python-gnupg_check=`rpm -qa | grep -qw python-gnupg`/g' \
| sudo bash && \
sudo dnf makecache && \
sudo dnf install -y bunkerweb-1.4.5
VOLUME ["/sys/fs/cgroup"]

File diff suppressed because it is too large Load Diff

View File

@ -100,7 +100,6 @@ volumes:
bw-data:
mariadb:
networks:
bw-universe:
name: bw-universe

View File

@ -1,2 +1,2 @@
selenium==4.7.2
requests==2.28.1
selenium==4.8.0
requests==2.28.2