Documentation
¶
Index ¶
- Constants
- func BuildPlainRouteValue(desired map[string]*WeightedValue) string
- func BuildRouteValue(desired map[string]*WeightedValue) string
- type CollectedBackendIntents
- type EntryKey
- type EntryValue
- type IntentValue
- type MapFileState
- func (m *MapFileState) ApplyDesiredBackends(entryKey EntryKey, resourceOrigin ResourceOrigin, ...)
- func (m *MapFileState) ApplyRoute(ro ResourceOrigin, newEntries map[EntryKey]map[string]*WeightedValue)
- func (m *MapFileState) BuildValue(desired map[string]*WeightedValue) string
- func (m *MapFileState) PrettyString() string
- func (m *MapFileState) ProcessMapFiles()
- func (m *MapFileState) RemoveEntriesFrom(ro ResourceOrigin)
- func (m *MapFileState) RemoveEntriesFromRoute(kind string, routeKey types.NamespacedName) int
- func (m *MapFileState) Reset()
- func (m *MapFileState) WriteOnDiskIfChanged() error
- type MatchCond
- type MatchCondType
- type MatchConditions
- type Operation
- type PresentOperations
- type ResourceOrigin
- type WeightedValue
Constants ¶
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 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 PresentOperations ¶ added in v0.9.0
Collect all intentions for each backend Each order has a precedence order Create & Update > Delete
type ResourceOrigin ¶ added in v0.9.0
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