maps

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MaxEncodedMatchSizePerRule  = 4096
	MaxEncodedMatchSizePerRoute = 12 * 1024
)

Encoded size guards: HAProxy truncates map values above ~16KB, so oversized rules must be rejected at admission instead of silently degrading.

Variables

This section is empty.

Functions

func BuildPlainRouteValue added in v1.0.3

func BuildPlainRouteValue(desired map[string]*WeightedValue) string

BuildPlainRouteValue returns names as a plain comma-separated string (no weights, no JSON). Used for listener maps where the value must be a literal string, not a weighted backend list. It uses ValueName rather than the map key so composite keys cannot leak. The Gateway API tie-break orders cross-route candidates by oldest route first, then "{namespace}/{name}", so equal timestamps fall back to the name order.

func BuildRouteValue added in v0.9.0

func BuildRouteValue(desired map[string]*WeightedValue) string

BuildRouteValue renders the map-file value for the given desired state.

Legacy entries (no conditions anywhere) keep the historical format: a bare backend name, or the weighted-random JSON.

Entries with at least one conditional candidate use the conditional format, parsed by lua select_route / find_route:

~1;<conds>>target;<conds>>target;...

Candidates are ordered by the Gateway API precedence rules after path (already the map key): method, header count, query count, then rule order — so the first passing candidate is the spec-correct one. An unconditional candidate sorts last and acts as fallback. Duplicate signatures from later rules are dropped (spec: first matching rule wins ties).

Types

type CollectedBackendIntents added in v0.9.0

type CollectedBackendIntents struct {
	CreatedAt  time.Time
	Weight     *int32
	Conditions *MatchConditions
	// Carried from the intents so DesiredValue keeps the real backend name and
	// the candidate ranking fields, even when the map key is a composite of
	// conditions, rule index and backend name.
	ValueName string
	RuleIdx   int
	PresentOperations
}

func (CollectedBackendIntents) String added in v0.9.0

func (cbi CollectedBackendIntents) String() string

type EntryKey added in v0.9.0

type EntryKey struct {
	Hostname string
	Path     string
}

func (EntryKey) String added in v0.9.0

func (ek EntryKey) String() string

type EntryValue added in v0.9.0

type EntryValue struct {
	// IntentsByBackendByResouceOrigin map[ResourceOrigin]*IntentValue
	// in the following lines:
	// value can be:
	// - a backend name with a weight (for path-based maps) or just a backend name (for sni-based maps) that we want to create/update/delete in the runtime map file (desired state)
	// - a listener name
	// - a listener + route name
	IntentsByBackendByResouceOrigin map[ResourceOrigin]map[string]*IntentValue // resource origin -> value name -> value + weight
	CurrentValue                    map[string]*WeightedValue                  // value name -> value + weight
	DiffValue                       map[string]*IntentValue                    // value name -> value + weight + operation (useful for sockets orders)
	DesiredValue                    map[string]*WeightedValue                  // value name -> value + weight
}

EntryValue represents all the information necessary to compute the desired state for a given key in the map file

func (EntryValue) CopyDesiredValue added in v0.9.0

func (ev EntryValue) CopyDesiredValue() map[string]*WeightedValue

func (*EntryValue) PrettyString added in v0.9.0

func (ev *EntryValue) PrettyString(indent string) string

type IntentValue added in v0.9.0

type IntentValue struct {
	Operation
	WeightedValue
}

func (IntentValue) Copy added in v0.9.0

func (i IntentValue) Copy() *IntentValue

func (IntentValue) String added in v0.9.0

func (i IntentValue) String() string

type MapFileState added in v0.9.0

type MapFileState struct {
	// The contents of the map file.
	// Could be in the format: hostname+path ou sni-> backend
	Entries           map[EntryKey]*EntryValue
	EntriesByResource map[ResourceOrigin]map[EntryKey]struct{}

	// FileName          string
	// RelativeFileName  string
	Path futils.FilePath
	// PlainValues disables the JSON weighted format: values are written as plain
	// comma-separated names (no weights, no JSON wrapper). Use this for maps that
	// are looked up directly by HAProxy (listener_exact_match, listener_wildcard_match,
	// listener_route_exact_match, listener_route_wildcard_match).
	PlainValues bool
	// contains filtered or unexported fields
}

func NewMapFileState added in v0.9.0

func NewMapFileState(mapBaseDir, mapFileName string, logger *slog.Logger) *MapFileState

NewMapFileState creates a new instance of MapFileState with the given filename and logger. It returns a pointer to the new instance.

func (*MapFileState) ApplyDesiredBackends added in v0.9.0

func (m *MapFileState) ApplyDesiredBackends(
	entryKey EntryKey,
	resourceOrigin ResourceOrigin,
	desired map[string]*WeightedValue,
)

ApplyDesiredBackends applies the desired backends for an entry and resource origin to the map file state. It handles four cases: 1. Get/Create EntryValue 2. Get the intents for all backends from this resource origin 3. DELETE : present before, absent now 4. CREATE / UPDATE / NOOP

func (*MapFileState) ApplyRoute added in v0.9.0

func (m *MapFileState) ApplyRoute(
	ro ResourceOrigin,
	newEntries map[EntryKey]map[string]*WeightedValue,
)

ApplyRoute applies a set of new entries to the MapFileState and updates the EntriesByResource accordingly. It handles three cases: 1. Apply / update for all new entries 2. Handle removed entries (previous but not in new) 3. Update EntriesByResource

func (*MapFileState) BuildValue added in v1.0.3

func (m *MapFileState) BuildValue(desired map[string]*WeightedValue) string

BuildValue returns the map-file value string for the given desired state, choosing between the plain and JSON-weighted formats based on m.PlainValues.

func (*MapFileState) PrettyString added in v0.9.0

func (m *MapFileState) PrettyString() string

func (*MapFileState) ProcessMapFiles added in v0.9.0

func (m *MapFileState) ProcessMapFiles()

ProcessMapFiles processes the map file and updates the desired values based on the intent operations stored in the map file state. It iterates over each entry/intent for the filename and collects the operations for each backend name. It then fills the desired values with the current values and updates the diff values with the desired operations. Finally, it prints the map file state after processing.

func (*MapFileState) RemoveEntriesFrom added in v1.1.0

func (m *MapFileState) RemoveEntriesFrom(ro ResourceOrigin)

RemoveEntriesFrom drops every entry this origin wrote and forgets it, which is what a listener or a route that left a map file owes. It is ApplyRoute with nothing to apply, spelled for the intent rather than for the mechanism.

func (*MapFileState) RemoveEntriesFromRoute added in v1.1.0

func (m *MapFileState) RemoveEntriesFromRoute(kind string, routeKey types.NamespacedName) int

RemoveEntriesFromRoute drops every entry written by an origin belonging to a route, whatever listeners it was attached to when it wrote them, and reports how many origins it dropped.

This is what a route that has left a map owes, and it is the only way to express it without knowing which listeners the route had. A caller that re-derived them -- from the route's spec, or from the attachments its checks recorded -- would depend on state that may no longer exist by the time the entries have to go: a route created and deleted without an intervening update has never had its attachments filled, so that route would leave its entries behind forever.

NewRouteOrigin prefixes the name with the kind and ends it with the route name. The namespace, kind and final path segment together identify the owning route; listener origins and another kind's homonyms are left alone.

func (*MapFileState) Reset added in v0.9.0

func (m *MapFileState) Reset()

Reset resets the MapFileState to its initial state. It deletes all the entries with their corresponding functions and resources. It also resets the DesiredValue and diffValue of each entry to their initial state. It is intended to be used after a map file has been processed and its contents have been applied to the runtime maps.

func (*MapFileState) WriteOnDiskIfChanged added in v0.9.0

func (m *MapFileState) WriteOnDiskIfChanged() error

WriteOnDiskIfChanged writes the MapFileState to disk if there are any differences between the desired state and the current state. It iterates over the entries in the map file state and checks if there are any differences between the desired state and the current state. If there are differences, it writes the desired state to disk in the format "key value\n"

type MatchCond added in v1.1.0

type MatchCond struct {
	Name  string
	Type  MatchCondType
	Value string
}

MatchCond is one header or query-param predicate. All conds of a match are ANDed.

type MatchCondType added in v1.1.0

type MatchCondType string

MatchCondType selects how a header or query-param value is compared.

const (
	// MatchCondExact compares the full field value.
	MatchCondExact MatchCondType = "e"
	// MatchCondRegexp searches the value with a regex, unanchored.
	MatchCondRegexp MatchCondType = "r"
)

type MatchConditions added in v1.1.0

type MatchConditions struct {
	Method  string
	Headers []MatchCond // lowercased names: HTTP header names are case-insensitive
	Query   []MatchCond // verbatim names: query param names are case-sensitive
}

MatchConditions holds the non-path predicates of one HTTPRouteMatch. A nil or empty value means the candidate is unconditional.

func NormalizeHTTPRouteMatch added in v1.1.0

func NormalizeHTTPRouteMatch(match gatewayv1.HTTPRouteMatch) (MatchConditions, error)

NormalizeHTTPRouteMatch extracts and validates the non-path predicates of a Gateway API HTTPRouteMatch. Header names are lowercased and later duplicates of a name (case-insensitively) are dropped, keeping only the first occurrence as the spec requires. RegularExpression values must compile in the Go RE2 dialect, the documented supported subset of the PCRE2 engine HAProxy uses at runtime.

func (*MatchConditions) Counts added in v1.1.0

func (mc *MatchConditions) Counts() (hasMethod bool, nHeaders, nQuery int)

Counts feeds precedence ordering: method first, then header count, then query count, as required by the Gateway API match precedence rules.

func (*MatchConditions) Encode added in v1.1.0

func (mc *MatchConditions) Encode() string

Encode renders the canonical condition string. It doubles as dedup signature inside map values and as part of the weighted-value map key. Empty when unconditional.

func (*MatchConditions) IsEmpty added in v1.1.0

func (mc *MatchConditions) IsEmpty() bool

type Operation added in v0.9.0

type Operation string
const (
	Create Operation = "create"
	Update Operation = "update"
	Delete Operation = "delete"
	Empty  Operation = ""
)

type PresentOperations added in v0.9.0

type PresentOperations struct {
	Create bool
	Update bool
	Delete bool
	Empty  bool
}

Collect all intentions for each backend Each order has a precedence order Create & Update > Delete

type ResourceOrigin added in v0.9.0

type ResourceOrigin struct {
	Namespace string
	Name      string
}

func NewRouteOrigin added in v1.1.0

func NewRouteOrigin(kind, listenerKey string, routeKey types.NamespacedName) ResourceOrigin

NewRouteOrigin identifies one route's contribution through one listener. Kind is part of the internal provenance, not the HAProxy map key or value: homonymous HTTPRoutes and TLSRoutes must never share a cleanup identity.

func (ResourceOrigin) String added in v0.9.0

func (ro ResourceOrigin) String() string

type WeightedValue added in v1.0.3

type WeightedValue struct {
	// CreatedAt orders comma-joined listener-route values: the spec breaks
	// cross-route ties by oldest route first, then ns/name. Zero for maps
	// that never hold several routes per value.
	CreatedAt time.Time
	Weight    *int32
	// Conditions, when non-empty, restrict this candidate to requests
	// satisfying them. Two rules of the same route can share one map entry,
	// so the key of the enclosing map carries the encoded conditions and the
	// rule index to keep their candidates apart; ValueName stays the real
	// backend name.
	Conditions *MatchConditions
	ValueName  string
	// RuleIdx ranks candidates from the same route: more conditions first,
	// then lower rule index (spec: first matching rule wins ties).
	RuleIdx int
}

func (WeightedValue) Copy added in v1.0.3

func (wb WeightedValue) Copy() *WeightedValue

func (WeightedValue) String added in v1.0.3

func (wb WeightedValue) String() string

Jump to

Keyboard shortcuts

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