api

package
v0.0.0-...-6aca3c6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2026 License: MIT Imports: 25 Imported by: 0

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

View Source
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.

View Source
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.

View Source
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.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the http.Handler that serves the API. It is exported so tests can drive it without building a TLS listener.

func (*Server) Run

func (s *Server) Run(ctx context.Context) error

Run starts the HTTPS server and blocks until ctx is canceled or a fatal error occurs. It performs graceful shutdown on context cancellation.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL