Support file and directory Traefik dynamic config paths#69
Support file and directory Traefik dynamic config paths#69smoochy wants to merge 2 commits intohhftechnology:pangolinfrom
Conversation
|
@smoochy is attempting to deploy a commit to the HHF Technologies' projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
There was a problem hiding this comment.
Code Review
This pull request introduces support for directory-based Traefik dynamic configurations, allowing the TRAEFIK_DYNAMIC_CONFIG environment variable to point to either a single YAML file or a directory of configuration fragments. When a directory is used, CrowdSec Manager manages its own overlay file named crowdsec-manager.yml to avoid modifying user-defined files. The changes include a significant refactor of the backend handlers to use a new traefikconfig package for unified configuration access, updates to documentation and Docker Compose examples, and a fix in the web UI to normalize bouncer data shapes. Feedback is provided regarding the hardcoded path mapping in the configuration resolution logic, which may be brittle for custom volume mounts.
| func containerPathToHostPath(cfg *config.Config, containerPath string) (string, error) { | ||
| switch { | ||
| case containerPath == "/etc/traefik": | ||
| return filepath.Join(cfg.ConfigDir, "traefik"), nil | ||
| case strings.HasPrefix(containerPath, "/etc/traefik/"): | ||
| return filepath.Join(cfg.ConfigDir, "traefik", filepath.FromSlash(strings.TrimPrefix(containerPath, "/etc/traefik/"))), nil | ||
| case containerPath == "/rules": | ||
| return filepath.Join(cfg.ConfigDir, "traefik", "rules"), nil | ||
| case strings.HasPrefix(containerPath, "/rules/"): | ||
| return filepath.Join(cfg.ConfigDir, "traefik", "rules", filepath.FromSlash(strings.TrimPrefix(containerPath, "/rules/"))), nil | ||
| default: | ||
| return "", fmt.Errorf("unsupported Traefik container path: %s", containerPath) | ||
| } | ||
| } |
There was a problem hiding this comment.
The containerPathToHostPath function relies on hardcoded path prefixes to map container paths to host paths. This assumes a specific volume mount structure as defined in the project's default docker-compose.yml files.
This implementation can be brittle. If a user customizes their volume mounts (e.g., mapping a different host directory to /etc/traefik in the container), this function will fail to find the correct host path, leading to errors when trying to read from or write to the host filesystem.
A more robust solution would be to dynamically determine the host path by inspecting the container's mount points using the Docker API. This would make the application more resilient to different user configurations.
|
@smoochy this is a huge refactor. Can you dm me on discord for this. |
Summary
Allow
TRAEFIK_DYNAMIC_CONFIGto point to either a single Traefik dynamic config file or a directory of dynamic config fragments.Problem
Several code paths still assumed that the Traefik dynamic config was always a single file. The most visible breakage was in
internal/api/handlers/captcha_setup.go, where the code built a hard-codeddynamic_config.ymlpath instead of using the configured target.That fails for Traefik setups that load a directory such as
/etc/traefik/rules, because CrowdSec Manager then tries to read or write the wrong target. It also risks writing to a shared base file when the correct behavior is to maintain a dedicated CrowdSec-managed overlay.Solution
internal/traefikconfig/traefik_dynamic_config.goto resolve file vs directory mode, map managed paths, and read combined fragment content.internal/api/handlers/captcha_setup.goandinternal/api/handlers/captcha_config.goto write to the resolved managed file. In directory mode this iscrowdsec-manager.yml.internal/api/handlers/whitelist.goandinternal/api/handlers/whitelist_ops.goso CrowdSec Manager only writes to its managed overlay instead of touching shared files likebase.yml.internal/api/handlers/captcha_detect.go,internal/api/handlers/services.go,internal/api/handlers/health_diagnostics.go, andinternal/api/handlers/services_config.goto support both a single file and a directory of YAML fragments.internal/configvalidator/validator.goto snapshot the resolved managed dynamic-config file instead of treating a directory as a plain file.internal/traefikconfig/traefik_dynamic_config_test.go,internal/config/traefik_dynamic_config_test.go, andinternal/api/handlers/captcha_setup_test.go.Testing
go test ./...Misc
This PR also includes the fixes from #67
AI Transparency
This change was prepared with AI assistance.