mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-10-10 10:48:10 +02:00
fix(csp): resolve all CSP-related issues and extend webserver health checks
- Added _normalize_codes to support lists of valid HTTP status codes - Updated web_health_expectations to handle multiple codes, deduplication, and fallback logic - Extended unit tests with coverage for list/default combinations, invalid values, and alias behavior - Fixed Flowise CSP flags and whitelist entries - Adjusted Flowise, MinIO, and Pretix docker service resource limits - Updated docker-compose templates with explicit service_name - Corrected MinIO status_codes to 301 redirects ✅ All CSP errors fixed See details: https://chatgpt.com/share/68d557ad-fc10-800f-b68b-0411d20ea6eb
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
# roles/sys-ctl-hlth-webserver/filter_plugins/web_health_expectations.py
|
||||
import os
|
||||
import sys
|
||||
from collections.abc import Mapping
|
||||
@@ -94,6 +93,26 @@ def _normalize_selection(group_names):
|
||||
raise ValueError("web_health_expectations: 'group_names' must be provided and non-empty")
|
||||
return sel
|
||||
|
||||
def _normalize_codes(x):
|
||||
"""
|
||||
Accepts:
|
||||
- single code (int or str)
|
||||
- list/tuple/set of codes
|
||||
Returns a de-duplicated list of valid ints (100..599) in original order.
|
||||
"""
|
||||
if x is None:
|
||||
return []
|
||||
if isinstance(x, (list, tuple, set)):
|
||||
out = []
|
||||
seen = set()
|
||||
for v in x:
|
||||
c = _valid_http_code(v)
|
||||
if c is not None and c not in seen:
|
||||
seen.add(c)
|
||||
out.append(c)
|
||||
return out
|
||||
c = _valid_http_code(x)
|
||||
return [c] if c is not None else []
|
||||
|
||||
def web_health_expectations(applications, www_enabled: bool = False, group_names=None, redirect_maps=None):
|
||||
"""Produce a **flat mapping**: domain -> [expected_status_codes].
|
||||
@@ -138,17 +157,15 @@ def web_health_expectations(applications, www_enabled: bool = False, group_names
|
||||
sc_map = {}
|
||||
if isinstance(sc_raw, Mapping):
|
||||
for k, v in sc_raw.items():
|
||||
code = _valid_http_code(v)
|
||||
if code is not None:
|
||||
sc_map[str(k)] = code
|
||||
codes = _normalize_codes(v)
|
||||
if codes:
|
||||
sc_map[str(k)] = codes
|
||||
|
||||
if isinstance(canonical_raw, Mapping) and canonical_raw:
|
||||
for key, domains in canonical_raw.items():
|
||||
domains_list = _to_list(domains, allow_mapping=False)
|
||||
code = _valid_http_code(sc_map.get(key))
|
||||
if code is None:
|
||||
code = _valid_http_code(sc_map.get("default"))
|
||||
expected = [code] if code is not None else list(DEFAULT_OK)
|
||||
codes = sc_map.get(key) or sc_map.get("default")
|
||||
expected = list(codes) if codes else list(DEFAULT_OK)
|
||||
for d in domains_list:
|
||||
if d:
|
||||
expectations[d] = expected
|
||||
@@ -156,8 +173,8 @@ def web_health_expectations(applications, www_enabled: bool = False, group_names
|
||||
for d in _to_list(canonical_raw, allow_mapping=True):
|
||||
if not d:
|
||||
continue
|
||||
code = _valid_http_code(sc_map.get("default"))
|
||||
expectations[d] = [code] if code is not None else list(DEFAULT_OK)
|
||||
codes = sc_map.get("default")
|
||||
expectations[d] = list(codes) if codes else list(DEFAULT_OK)
|
||||
|
||||
for d in aliases:
|
||||
if d:
|
||||
|
@@ -12,38 +12,51 @@ server:
|
||||
- "flow.ai.{{ PRIMARY_DOMAIN }}"
|
||||
aliases: []
|
||||
csp:
|
||||
flags: {}
|
||||
#script-src-elem:
|
||||
# unsafe-inline: true
|
||||
#script-src:
|
||||
# unsafe-inline: true
|
||||
# unsafe-eval: true
|
||||
#style-src:
|
||||
# unsafe-inline: true
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
font-src:
|
||||
- https://fonts.gstatic.com
|
||||
style-src-elem:
|
||||
- https://fonts.googleapis.com
|
||||
connect-src: []
|
||||
script-src-elem:
|
||||
- https://fonts.googleapis.com
|
||||
- https://fonts.gstatic.com
|
||||
- https://r.wdfl.co
|
||||
connect-src: []
|
||||
docker:
|
||||
services:
|
||||
litellm:
|
||||
backup:
|
||||
no_stop_required: true
|
||||
image: ghcr.io/berriai/litellm
|
||||
version: main-v1.77.3.dynamic_rates
|
||||
name: litellm
|
||||
image: ghcr.io/berriai/litellm
|
||||
version: main-v1.77.3.dynamic_rates
|
||||
name: litellm
|
||||
cpus: "1.0"
|
||||
mem_reservation: "0.5g"
|
||||
mem_limit: "1g"
|
||||
pids_limit: 1024
|
||||
qdrant:
|
||||
backup:
|
||||
no_stop_required: true
|
||||
image: qdrant/qdrant
|
||||
version: latest
|
||||
name: qdrant
|
||||
image: qdrant/qdrant
|
||||
version: latest
|
||||
name: qdrant
|
||||
cpus: "2.0"
|
||||
mem_reservation: "2g"
|
||||
mem_limit: "4g"
|
||||
pids_limit: 2048
|
||||
flowise:
|
||||
backup:
|
||||
no_stop_required: true
|
||||
image: flowiseai/flowise
|
||||
version: latest
|
||||
name: flowise
|
||||
no_stop_required: false # As long as SQLite is used
|
||||
image: flowiseai/flowise
|
||||
version: latest
|
||||
name: flowise
|
||||
cpus: "1.0"
|
||||
mem_reservation: "1g"
|
||||
mem_limit: "2g"
|
||||
pids_limit: 1024
|
||||
redis:
|
||||
enabled: false
|
||||
database:
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{% include 'roles/docker-compose/templates/base.yml.j2' %}
|
||||
litellm:
|
||||
{% set service_name = 'litellm' %}
|
||||
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
||||
image: {{ FLOWISE_LITELLM_IMAGE }}:{{ FLOWISE_LITELLM_VERSION }}
|
||||
container_name: {{ FLOWISE_LITELLM_CONTAINER }}
|
||||
@@ -14,6 +15,7 @@
|
||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||
|
||||
qdrant:
|
||||
{% set service_name = 'qdrant' %}
|
||||
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
||||
image: {{ FLOWISE_QDRANT_IMAGE }}:{{ FLOWISE_QDRANT_VERSION }}
|
||||
container_name: {{ FLOWISE_QDRANT_CONTAINER }}
|
||||
@@ -25,6 +27,7 @@
|
||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||
|
||||
flowise:
|
||||
{% set service_name = 'flowise' %}
|
||||
{% include 'roles/docker-container/templates/base.yml.j2' %}
|
||||
image: {{ FLOWISE_IMAGE }}:{{ FLOWISE_VERSION }}
|
||||
container_name: {{ FLOWISE_CONTAINER }}
|
||||
|
@@ -10,7 +10,8 @@ features:
|
||||
ldap: false # OIDC is already activated so LDAP isn't necessary
|
||||
server:
|
||||
status_codes:
|
||||
api: 400
|
||||
api: 301
|
||||
console: 301
|
||||
domains:
|
||||
canonical:
|
||||
console: "console.s3.{{ PRIMARY_DOMAIN }}"
|
||||
@@ -25,10 +26,14 @@ docker:
|
||||
services:
|
||||
minio:
|
||||
backup:
|
||||
no_stop_required: true
|
||||
image: quay.io/minio/minio
|
||||
version: latest
|
||||
name: minio
|
||||
no_stop_required: false
|
||||
image: quay.io/minio/minio
|
||||
version: latest
|
||||
name: minio
|
||||
cpus: "2.0"
|
||||
mem_reservation: "2g"
|
||||
mem_limit: "4g"
|
||||
pids_limit: 2048
|
||||
redis:
|
||||
enabled: false
|
||||
database:
|
||||
|
@@ -11,6 +11,10 @@ docker:
|
||||
name: pretix
|
||||
backup:
|
||||
no_stop_required: true
|
||||
cpus: "2.0"
|
||||
mem_reservation: "1.5g"
|
||||
mem_limit: "2g"
|
||||
pids_limit: 1024
|
||||
volumes:
|
||||
data: "pretix_data"
|
||||
config: "pretix_config"
|
||||
|
Reference in New Issue
Block a user