Documentation
¶
Overview ¶
Package api implements the REST management API for the fos1 router/firewall. It exposes a single resource family, FilterPolicy, over HTTPS with mTLS client-cert authentication. The server is backed by a controller-runtime client so it shares a cached view of the cluster with other in-process controllers when run side-by-side.
Scope: Sprint 30 Ticket 41 shipped list/get (read-only v0). Sprint 31 Ticket 48 adds Create (POST), Replace (PUT), Patch (JSON Merge Patch / Strategic Merge Patch), and Delete verbs. Watch / streaming endpoints and additional resource families (NAT, routing, DPI, zones) remain explicit non-goals. See docs/design/api-server.md for the full architecture and the list of explicit deferrals.
Index ¶
Constants ¶
const DefaultListenAddress = ":8443"
DefaultListenAddress is the mTLS listen socket used when the caller does not override ServerConfig.Address. 8443 is the convention for internal HTTPS management endpoints in this repository.
const DefaultReadTimeout = 15 * time.Second
DefaultReadTimeout bounds request reads to protect the server from slow- loris-style misuse. Management clients are expected to be fast and machine-generated so a short timeout is appropriate.
const DefaultWriteTimeout = 30 * time.Second
DefaultWriteTimeout bounds response writes for the same reason.
Variables ¶
This section is empty.
Functions ¶
func ValidateFilterPolicy ¶
func ValidateFilterPolicy(fp *policy.FilterPolicy) field.ErrorList
ValidateFilterPolicy returns a field.ErrorList describing every problem in fp's Spec (and its metadata when it carries write-path requirements). An empty list means the object is acceptable. The function is shared by the REST API handlers and any future admission webhook — keep it pure (no Kubernetes client calls, no environmental lookups).
The validator is intentionally conservative: it rejects inputs that are unambiguously malformed, but tolerates author choices the translator handles at runtime (for example unknown selector types are downgraded to a no-match, which is not a failure mode worth a 422).
Types ¶
type Authorizer ¶
type Authorizer interface {
// Authorize returns nil if the subject is permitted, or an error with a
// human-readable message explaining the denial otherwise. The error is
// surfaced as the 403 body; callers must not include sensitive data.
Authorize(subjectCN string) error
}
Authorizer decides whether a client presented by the TLS handshake is permitted to call the API. It is kept as an interface so tests can inject a deterministic decision without going through the TLS stack.
type FilterPolicyHandler ¶
type FilterPolicyHandler struct {
// Client is used to read and mutate FilterPolicy objects. All write
// verbs go through this interface so tests can drive them with a fake
// client.
Client client.Client
}
FilterPolicyHandler serves the /v1/filter-policies routes. It reads and writes via a controller-runtime client.Client which may be cached (shared with a controller-runtime manager) or direct. Sprint 30 Ticket 41 shipped List/Get; Sprint 31 Ticket 48 adds the full CRUD surface — Create, Replace (PUT), Patch (JSON Merge Patch / Strategic Merge Patch), and Delete — behind the same mTLS + allowlist middleware.
type Readiness ¶
type Readiness interface {
// Ready returns nil if the component is ready to serve traffic, and a
// non-nil error describing why it is not otherwise.
Ready(ctx context.Context) error
}
Readiness is an interface exposed by components that can report whether they are ready to serve traffic. The readyz handler consults the informer cache via this interface.
type Server ¶
type Server struct {
// Client is a read-capable Kubernetes client. The handlers only use
// List/Get so the implementation may be a cached controller-runtime
// client or a direct one; the choice is a concern of the caller.
Client client.Client
// Config is the validated configuration used to construct the server.
Config ServerConfig
// Readiness, if set, is consulted by readyz_handler. If nil the
// /readyz endpoint reports ready immediately.
Readiness Readiness
// Authorizer extracts client identity from the TLS connection and
// consults the allowlist. It is pluggable so tests can inject a fake.
Authorizer Authorizer
}
Server is the read-only REST management API. It is built around the controller-runtime client.Client interface so tests can drive it with a fake client and production can share the cached manager client.
func NewServer ¶
func NewServer(c client.Client, cfg ServerConfig) (*Server, error)
NewServer constructs a Server from a controller-runtime client and a ServerConfig. It validates that required cert/key/CA paths are set but does not yet touch the filesystem — Run is responsible for loading files and building tls.Config. Returning construction errors early lets the caller fail fast before any Kubernetes informer cache is started.
type ServerConfig ¶
type ServerConfig struct {
// Address is the TCP listen address (host:port). If empty,
// DefaultListenAddress is used.
Address string
// CertDir is the directory holding tls.crt / tls.key / ca.crt as
// written by cert-manager. When set it takes precedence over the
// per-file ServerCertFile/ServerKeyFile/ClientCAFile fields and the
// server picks up rotation via certificates.WatchAndReload. This is
// the Sprint 31 / Ticket 49 path; the per-file fields remain for
// backward-compatibility with overlays that point at custom paths.
CertDir string
// ServerCertFile is the path to the PEM-encoded server certificate.
// cert-manager typically mounts it as tls.crt inside a Secret.
// Ignored when CertDir is set.
ServerCertFile string
// ServerKeyFile is the path to the PEM-encoded server private key.
// cert-manager typically mounts it as tls.key inside a Secret.
// Ignored when CertDir is set.
ServerKeyFile string
// ClientCAFile is the path to the PEM-encoded CA bundle used to verify
// client certificates. The bundle identifies the trust anchor for
// accepted callers; every client presenting a cert chain rooted in this
// bundle is authenticated at the TLS layer. Authorization still requires
// the subject to appear in Allowlist. Ignored when CertDir is set —
// in that case ca.crt under CertDir is used as the client CA bundle.
ClientCAFile string
// Allowlist is the set of client-cert Subject Common Names authorized to
// call the API. A caller whose cert chains to ClientCAFile but whose CN
// is not in this set receives a 403.
Allowlist []string
// ReadTimeout bounds request reads. Zero means DefaultReadTimeout.
ReadTimeout time.Duration
// WriteTimeout bounds response writes. Zero means DefaultWriteTimeout.
WriteTimeout time.Duration
}
ServerConfig captures the inputs to build and run the API server.
type StaticAllowlist ¶
type StaticAllowlist struct {
// contains filtered or unexported fields
}
StaticAllowlist is an Authorizer backed by a fixed set of client-cert Subject Common Names. The allowlist is intended to be populated from a ConfigMap or command-line argument at bootstrap; live reloading is out of scope for v0.
func NewStaticAllowlist ¶
func NewStaticAllowlist(cns []string) *StaticAllowlist
NewStaticAllowlist constructs a StaticAllowlist from a slice of Common Names. Nil or empty input produces an empty allowlist — every caller will then receive 403 until the allowlist is populated.
func (*StaticAllowlist) Authorize ¶
func (a *StaticAllowlist) Authorize(cn string) error
Authorize implements Authorizer. It returns nil if cn is allowlisted.
func (*StaticAllowlist) Set ¶
func (a *StaticAllowlist) Set(cns []string)
Set replaces the current allowlist contents atomically. It is intended for test injection; production callers do not mutate the allowlist after construction in v0.