Documentation
¶
Overview ¶
Package proxy is part of the Redoubt control plane. See CLAUDE.md for its role.
Index ¶
Constants ¶
const (
// BaseFile is the name of the shared middlewares file inside the provider directory.
BaseFile = "_base.yml"
)
const RateLimitMiddleware = "redoubt-ratelimit"
RateLimitMiddleware is an opt-in middleware apps may attach later.
const SecureHeadersMiddleware = "redoubt-secure-headers"
SecureHeadersMiddleware is the name of the middleware every app router uses.
Variables ¶
var ErrInvalid = errors.New("invalid proxy input")
ErrInvalid is wrapped by every validation failure in this package.
Functions ¶
func RenderBase ¶
func RenderBase() []byte
RenderBase returns the shared middlewares file: the secure-headers middleware every app router references and the opt-in rate limiter.
func RenderRoute ¶
RenderRoute renders the Traefik dynamic configuration (router + service) for r using the certificate resolver named resolver. It fails, producing no output, if any input is invalid or if the rendered bytes would contain Go template delimiters (see routeTemplate).
func ValidateHostname ¶
ValidateHostname enforces a strict RFC 1123 hostname: lowercase ASCII letters, digits and hyphens only; labels of 1–63 characters that neither start nor end with a hyphen; at most 253 characters in total; at least two labels unless allowSingleLabel is set (development hosts such as "localhost"). Wildcards, uppercase (rejected rather than folded), trailing dots, IP literals and every character outside [a-z0-9.-] are rejected.
The value is interpolated into a Traefik rule Host(`…`), so the character set is the security boundary: backticks, quotes, whitespace, parentheses and rule operators cannot appear in an accepted hostname.
func ValidateRoute ¶
ValidateRoute checks every field of r and the resolver name without rendering anything.
func ValidateServiceURL ¶
ValidateServiceURL enforces the shape of a Traefik backend URL generated by the platform: scheme http or https; host is a Docker container/network name or an IPv4 address; an explicit port in 1..65535; and nothing else — no userinfo, path, query, fragment or opaque part. The raw string must already be in canonical "scheme://host:port" form (lowercase scheme, no trailing delimiters, no leading zeros in the port): what is validated is exactly what RenderRoute emits, byte for byte.
Types ¶
type Route ¶
type Route struct {
// App is the application name; it becomes the router and service name "app-<app>".
App string
// Host is the public hostname the app is served on.
Host string
// ServiceURL is the backend, e.g. "http://redoubt-hello-r1:8080" resolved via Docker DNS.
ServiceURL string
}
Route is the complete set of user-influenced data that reaches Traefik for one app. Host is the only value an end user ever supplies; App and ServiceURL are chosen by the platform. Every field is validated before it is rendered (D-009).
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer owns the Traefik file-provider directory. Traefik watches the directory and loads every *.yml file in it; Writer is the only thing that ever writes there (D-009). NewWriter is the only constructor: the zero Writer has no directory and every method on it fails with ErrInvalid.
func NewWriter ¶
NewWriter returns a Writer for dir, creating the directory (mode 0750) if it is missing. dir must be an absolute path (D-012 fixes the provider directory as absolute), so temp files, renames and directory fsyncs never depend on the process working directory.
func (*Writer) ListRoutes ¶
ListRoutes returns the names of every app that currently has a route file, sorted.
func (*Writer) RemoveRoute ¶
RemoveRoute deletes app-<app>.yml. Removing a route that does not exist is not an error.