Merge branch 'dev' into staging

This commit is contained in:
florian 2024-04-07 09:53:35 +02:00
commit fa171fbdfb
No known key found for this signature in database
GPG key ID: 93EE47CC3D061500
8 changed files with 101 additions and 49 deletions

View file

@ -12,6 +12,7 @@ from contextlib import suppress
from os import getenv
def print_md_table(settings) -> MarkdownTableWriter:
writer = MarkdownTableWriter(
headers=["Setting", "Default", "Context", "Multiple", "Description"],
@ -101,9 +102,8 @@ for pro in glob(f"v{version}/*/plugin.json"):
with open(pro, "r") as f:
with suppress(Exception):
pro_plugin = loads(f.read())
if len(pro_plugin["settings"]) > 0:
core_settings[pro_plugin["name"]] = pro_plugin
core_settings[pro_plugin["name"]]["is_pro"] = True
core_settings[pro_plugin["name"]] = pro_plugin
core_settings[pro_plugin["name"]]["is_pro"] = True
# Print plugins and their settings
for data in dict(sorted(core_settings.items())).values():
@ -113,7 +113,8 @@ for data in dict(sorted(core_settings.items())).values():
print(f"## {data['name']}{pro_crown}\n", file=doc)
print(f"{stream_support(data['stream'])}\n", file=doc)
print(f"{data['description']}\n", file=doc)
print(print_md_table(data["settings"]), file=doc)
if data["settings"]:
print(print_md_table(data["settings"]), file=doc)
# Remove zip file
Path(f"v{version}.zip").unlink()

View file

@ -99,6 +99,25 @@ Backup your data to a custom location. Ensure the safety and availability of you
|`BACKUP_SCHEDULE` |`daily` |global |no |The frequency of the backup |
|`BACKUP_ROTATION` |`7` |global |no |The number of backups to keep |
## Backup S3 <img src='../assets/img/pro-icon.svg' alt='crow pro icon' height='24px' width='24px' style='transform : translateY(3px);'> (PRO)
STREAM support :white_check_mark:
Automatically backup your data to an S3 bucket
| Setting |Default|Context|Multiple| Description |
|-----------------------------|-------|-------|--------|--------------------------------------------|
|`USE_BACKUP_S3` |`no` |global |no |Enable or disable the S3 backup feature |
|`BACKUP_S3_SCHEDULE` |`daily`|global |no |The frequency of the backup |
|`BACKUP_S3_ROTATION` |`7` |global |no |The number of backups to keep |
|`BACKUP_S3_ENDPOINT` | |global |no |The S3 endpoint |
|`BACKUP_S3_BUCKET` | |global |no |The S3 bucket |
|`BACKUP_S3_REGION` | |global |no |The S3 region |
|`BACKUP_S3_ACCESS_KEY_ID` | |global |no |The S3 access key ID |
|`BACKUP_S3_ACCESS_KEY_SECRET`| |global |no |The S3 access key secret |
|`BACKUP_S3_COMP_LEVEL` |`6` |global |no |The compression level of the backup zip file|
## Bad behavior
STREAM support :white_check_mark:
@ -355,6 +374,7 @@ Automatic creation, renewal and configuration of Let's Encrypt certificates usin
|`USE_LETS_ENCRYPT_DNS_WILDCARD` |`yes` |multisite|no |Create wildcard certificates for all domains using DNS challenges. |
|`LETS_ENCRYPT_DNS_PROPAGATION` |`default`|multisite|no |The time to wait for DNS propagation in seconds. |
|`LETS_ENCRYPT_DNS_CREDENTIAL_ITEM`| |multisite|yes |Configuration item that will be added to the credentials.ini file for the DNS provider.|
|`LETS_ENCRYPT_DNS_CLEAR_OLD_CERTS`|`no` |global |no |Clear old certificates when renewing. |
## Limit
@ -384,6 +404,13 @@ Metrics collection and retrieve.
|`METRICS_MEMORY_SIZE` |`16m` |global |no |Size of the internal storage for metrics. |
|`METRICS_MAX_BLOCKED_REQUESTS`|`100` |global |no |Maximum number of blocked requests to store (per worker).|
## Migration <img src='../assets/img/pro-icon.svg' alt='crow pro icon' height='24px' width='24px' style='transform : translateY(3px);'> (PRO)
STREAM support :white_check_mark:
Migration of BunkerWeb configuration between instances made easy via the web UI
## Miscellaneous
STREAM support :warning:
@ -656,4 +683,3 @@ Allow access based on internal and external IP/network/rDNS/ASN whitelists.
|`WHITELIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to whitelist. |
|`WHITELIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to whitelist. |
|`WHITELIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to whitelist. |

View file

@ -66,6 +66,7 @@ RUN apk add --no-cache bash && \
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
LABEL version "1.5.7"
LABEL url "https://www.bunkerweb.io"
LABEL bunkerweb.type "autoconf"
VOLUME /data

View file

@ -73,6 +73,8 @@ RUN apk add --no-cache openssl pcre bash python3 yajl geoip libxml2 libgd curl &
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
LABEL version "1.5.7"
LABEL url "https://www.bunkerweb.io"
LABEL bunkerweb.type "bunkerweb"
LABEL bunkerweb.INSTANCE "bunkerweb"
EXPOSE 8080/tcp 8443/tcp

View file

@ -74,6 +74,7 @@ COPY --chown=root:scheduler --chmod=770 src/bw/misc/country.mmdb /var/tmp/bunker
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
LABEL version "1.5.7"
LABEL url "https://www.bunkerweb.io"
LABEL bunkerweb.type "scheduler"
VOLUME /data

View file

@ -578,59 +578,68 @@ if __name__ == "__main__":
# infinite schedule for the jobs
logger.info("Executing job scheduler ...")
errors = 0
while RUN and not NEED_RELOAD:
SCHEDULER.run_pending()
sleep(1)
current_time = datetime.now()
while DB_LOCK_FILE.is_file() and DB_LOCK_FILE.stat().st_ctime + 30 > current_time.timestamp():
logger.debug("Database is locked, waiting for it to be unlocked (timeout: 30s) ...")
try:
SCHEDULER.run_pending()
sleep(1)
current_time = datetime.now()
DB_LOCK_FILE.unlink(missing_ok=True)
while DB_LOCK_FILE.is_file() and DB_LOCK_FILE.stat().st_ctime + 30 > current_time.timestamp():
logger.debug("Database is locked, waiting for it to be unlocked (timeout: 30s) ...")
sleep(1)
changes = db.check_changes()
DB_LOCK_FILE.unlink(missing_ok=True)
if isinstance(changes, str):
logger.error(f"An error occurred when checking for changes in the database : {changes}")
stop(1)
changes = db.check_changes()
# check if the plugins have changed since last time
if changes["pro_plugins_changed"]:
logger.info("Pro plugins changed, generating ...")
PRO_PLUGINS_NEED_GENERATION = True
CONFIG_NEED_GENERATION = True
RUN_JOBS_ONCE = True
NEED_RELOAD = True
if isinstance(changes, str):
logger.error(f"An error occurred when checking for changes in the database : {changes}")
stop(1)
if changes["external_plugins_changed"]:
logger.info("External plugins changed, generating ...")
PLUGINS_NEED_GENERATION = True
CONFIG_NEED_GENERATION = True
RUN_JOBS_ONCE = True
NEED_RELOAD = True
# check if the plugins have changed since last time
if changes["pro_plugins_changed"]:
logger.info("Pro plugins changed, generating ...")
PRO_PLUGINS_NEED_GENERATION = True
CONFIG_NEED_GENERATION = True
RUN_JOBS_ONCE = True
NEED_RELOAD = True
# check if the custom configs have changed since last time
if changes["custom_configs_changed"]:
logger.info("Custom configs changed, generating ...")
CONFIGS_NEED_GENERATION = True
CONFIG_NEED_GENERATION = True
NEED_RELOAD = True
if changes["external_plugins_changed"]:
logger.info("External plugins changed, generating ...")
PLUGINS_NEED_GENERATION = True
CONFIG_NEED_GENERATION = True
RUN_JOBS_ONCE = True
NEED_RELOAD = True
# check if the config have changed since last time
if changes["config_changed"]:
logger.info("Config changed, generating ...")
CONFIG_NEED_GENERATION = True
RUN_JOBS_ONCE = True
NEED_RELOAD = True
# check if the custom configs have changed since last time
if changes["custom_configs_changed"]:
logger.info("Custom configs changed, generating ...")
CONFIGS_NEED_GENERATION = True
CONFIG_NEED_GENERATION = True
NEED_RELOAD = True
# check if the instances have changed since last time
if changes["instances_changed"]:
logger.info("Instances changed, generating ...")
INSTANCES_NEED_GENERATION = True
CONFIGS_NEED_GENERATION = True
CONFIG_NEED_GENERATION = True
NEED_RELOAD = True
# check if the config have changed since last time
if changes["config_changed"]:
logger.info("Config changed, generating ...")
CONFIG_NEED_GENERATION = True
RUN_JOBS_ONCE = True
NEED_RELOAD = True
# check if the instances have changed since last time
if changes["instances_changed"]:
logger.info("Instances changed, generating ...")
INSTANCES_NEED_GENERATION = True
CONFIGS_NEED_GENERATION = True
CONFIG_NEED_GENERATION = True
NEED_RELOAD = True
except BaseException:
logger.debug(format_exc())
if errors > 5:
logger.error(f"An error occurred when executing the scheduler : {format_exc()}")
stop(1)
errors += 1
sleep(5)
if NEED_RELOAD:
CHANGES.clear()

View file

@ -44,7 +44,7 @@ COPY --from=builder --chown=0:101 /usr/share/bunkerweb /usr/share/bunkerweb
WORKDIR /usr/share/bunkerweb
# Add ui user, install runtime dependencies, create data folders and set permissions
RUN apk add --no-cache bash libmagic && \
RUN apk add --no-cache bash libmagic mariadb-client postgresql-client sqlite && \
addgroup -g 101 ui && \
adduser -h /var/cache/nginx -g ui -s /bin/sh -G ui -D -H -u 101 ui && \
echo "Docker" > INTEGRATION && \
@ -66,6 +66,7 @@ RUN apk add --no-cache bash libmagic && \
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
LABEL version "1.5.7"
LABEL url "https://www.bunkerweb.io"
LABEL bunkerweb.type "ui"
VOLUME /data

View file

@ -340,6 +340,9 @@ def run_action(plugin: str, function_name: str = ""):
if message or not isinstance(res, dict) and not res:
return {"status": "ko", "code": 500, "message": message or "The plugin did not return a valid response"}
if isinstance(res, Response):
return res
return {"status": "ok", "code": 200, "data": res}
@ -1625,11 +1628,19 @@ def custom_plugin(plugin: str):
)
action_result = run_action(plugin)
if isinstance(action_result, Response):
app.logger.info(f"Plugin {plugin} action executed successfully")
return action_result
# case error
if action_result["status"] == "ko":
return error_message(action_result["message"]), action_result["code"]
app.logger.info(f"Plugin {plugin} action executed successfully")
if request.content_type == "application/x-www-form-urlencoded":
return redirect(f"{url_for('plugins')}/{plugin}", code=303)
return jsonify({"message": "ok", "data": action_result["data"]}), 200