xdseval

package
v0.0.0-...-84176c5 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package xdseval evaluates the parts of Envoy configuration the agent's tests reason about, the way the pinned proxy does: which filter chain of a listener a connection selects (filter_chain_matcher, or the legacy filter_chain_match), and what a route table answers one request (virtual host selection, the virtual host's matcher, the first matching route).

It is a model, and models only what the agent generates. Anything it does not model is reported (Unsupported) rather than guessed at, so a test built on it fails instead of passing on a wrong answer.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EvalMatcher

EvalMatcher evaluates a generic matcher the way Envoy's MatchTree does: an exact map hands a key it does not hold, AND a child that does not match, to its on_no_match; a list tries its field matchers in order and moves on when a matched predicate's on_match does not match. It returns the action the match ends in, or nil for no match.

func FilterLevels

func FilterLevels(vhost map[string]*anypb.Any, r *routev3.Route) map[string][]*anypb.Any

FilterLevels returns, per HTTP filter a route's per-filter config names (on the route or its virtual host), the configs the proxy hands that filter: [virtual host's, route's], either nil when that level has none; or nothing for a filter that does not run. A config at the virtual host and the same config on the route are told apart: the levels must be the same, not merely amount to the same.

  • a route-level envoy.config.route.v3.FilterConfig with disabled set disables the filter for the route, whatever its virtual host says, and a virtual-host one does when the route says nothing (RouteEntryImplBase::filterDisabled, source/common/router/config_impl.cc);
  • otherwise each level's config is handed over (getAllPerFilterConfig).

A filter neither level names is taken not to run: every filter aether configures per route sits in the chain disabled by default.

func FirstRoute

func FirstRoute(routes []*routev3.Route, r Request) (*routev3.Route, error)

FirstRoute returns the first of routes that r matches (path and request header matchers), nil for none.

func MatchString

func MatchString(sm *xdsmatcherv3.StringMatcher, v string) (bool, error)

MatchString evaluates an xds StringMatcher.

func MatcherActionNames

func MatcherActionNames(m *xdsmatcherv3.Matcher) []string

MatcherActionNames returns every chain name an action of a listener's filter_chain_matcher selects, sorted and de-duplicated. A name the listener has no chain of closes the connection (Envoy's NoopFilterChainAction), so every one must be on the listener.

func PickVirtualHost

func PickVirtualHost(rc *routev3.RouteConfiguration, host string) *routev3.VirtualHost

PickVirtualHost returns the virtual host of rc that host selects, nil for none (Table.Pick).

func SameAnswer

func SameAnswer(a, b Answer) (same bool, why string, err error)

SameAnswer reports whether a and b give a request the same treatment: the same effective route list, or both no route at all. why says how they differ.

func SameTreatment

func SameTreatment(a, b *routev3.Route) (same bool, why string)

SameTreatment reports whether two routes treat a request alike: the same action (cluster, cluster selection, redirect, direct-response status), the same per-filter config, header mutations and every other route field. The routes' matches are not compared (they are how the request got there), nor a direct response's body (a diagnostic; the x-aether-error header is the contract and is compared). why says how they differ.

func SameTreatmentIn

func SameTreatmentIn(aVhost map[string]*anypb.Any, a *routev3.Route, bVhost map[string]*anypb.Any, b *routev3.Route) (same bool, why string)

SameTreatmentIn is SameTreatment for routes of virtual hosts with the typed_per_filter_config aVhost and bVhost: the filters each route runs and the config of each level they read (FilterLevels) must be the same, level by level, not merely amount to the same; every other route field as SameTreatment.

func SelectChain

func SelectChain(l *listenerv3.Listener, c Conn) (string, error)

SelectChain returns the name of the chain l selects for c: by its filter_chain_matcher when it has one, else by its chains' filter_chain_match. It returns the default chain's name when nothing matches, and "" when there is no default chain (the connection is closed). A matcher action naming a chain the listener does not have also closes the connection, and returns "".

Types

type Answer

type Answer struct {
	Vhost       string
	Routes      []*routev3.Route
	VhostConfig map[string]*anypb.Any
	// NoVhost: no virtual host takes the Host (the proxy answers 404 NR).
	NoVhost bool
	// NoRoutes: the virtual host's matcher ended in no match (404 NR too).
	NoRoutes bool
}

Answer is what a route table does with a request: the virtual host it selected, and the route list that applies (the virtual host's routes, or the RouteList its matcher ended in), with the virtual host's own typed_per_filter_config beside it.

func Resolve

func Resolve(rc *routev3.RouteConfiguration, r Request) (Answer, error)

Resolve selects the virtual host of rc for r the way the proxy does (Table.Pick), and evaluates its matcher.

func (Answer) Effective

func (a Answer) Effective() ([]*routev3.Route, error)

Effective returns the routes of a with the virtual host's typed_per_filter_config in force on each route, as the proxy applies the two levels (extensionfilter.CombineLevels). A route on which they cannot be combined is reported as an error.

type Conn

type Conn struct {
	IP   string
	Port uint32
	// SNI is the TLS server name, "" for none.
	SNI string
	// Transport is "raw_buffer" or "tls".
	Transport string
	// App are the application protocols the inspectors reported.
	App []string
}

Conn is a connection as the capture listener's selection sees it.

type InputFunc

type InputFunc func(input *xdscorev3.TypedExtensionConfig) (string, bool, error)

InputFunc returns the value of one matcher input, and false when the input has no data (Envoy's absl::monostate).

type Outcome

type Outcome struct {
	Status uint32
	Body   string
	Reason string
	// Cluster is the static cluster; ClusterHeader the header that names it
	// (the on-demand route); Weighted lists weighted clusters.
	Cluster       string
	ClusterHeader string
	Weighted      []string
	Redirect      bool
}

Outcome is the end of a request through one route: a direct response (status, body, x-aether-error) or a cluster.

func OutcomeOf

func OutcomeOf(rt *routev3.Route) Outcome

OutcomeOf summarizes a route.

type Request

type Request struct {
	// Host is the :authority.
	Host string
	// Path is the :path; "/" when empty.
	Path string
	// Headers are other request headers, lower-case names.
	Headers map[string]string
	// FilterState is the connection's filter state, as strings. A key that is
	// absent has no data.
	FilterState map[string]string
}

Request is one HTTP request as a route table sees it.

type Table

type Table struct {
	// contains filtered or unexported fields
}

Table is a route table indexed for virtual-host selection.

func NewTable

func NewTable(rc *routev3.RouteConfiguration) *Table

NewTable indexes rc.

func (*Table) Pick

func (t *Table) Pick(host string) *routev3.VirtualHost

Pick returns the virtual host host selects, nil for none: an exact domain, then the longest "*suffix" wildcard, then the longest "prefix*" wildcard, then "*", all compared lower-cased; a wildcard needs at least one character in place of its "*".

func (*Table) Resolve

func (t *Table) Resolve(r Request) (Answer, error)

Resolve is the package-level Resolve on an indexed table.

type Unsupported

type Unsupported struct{ What string }

Unsupported is the error of a construct the model does not cover.

func (Unsupported) Error