// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package api import ( "encoding/json" "time" "github.com/hashicorp/go-multierror" ) type ServiceRouterConfigEntry struct { Kind string Name string Partition string `json:",omitempty"` Namespace string `json:",omitempty"` Routes []ServiceRoute `json:",omitempty"` Meta map[string]string `json:",omitempty"` CreateIndex uint64 ModifyIndex uint64 } func (e *ServiceRouterConfigEntry) GetKind() string { return e.Kind } func (e *ServiceRouterConfigEntry) GetName() string { return e.Name } func (e *ServiceRouterConfigEntry) GetPartition() string { return e.Partition } func (e *ServiceRouterConfigEntry) GetNamespace() string { return e.Namespace } func (e *ServiceRouterConfigEntry) GetMeta() map[string]string { return e.Meta } func (e *ServiceRouterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } func (e *ServiceRouterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } type ServiceRoute struct { Match *ServiceRouteMatch `json:",omitempty"` Destination *ServiceRouteDestination `json:",omitempty"` } type ServiceRouteMatch struct { HTTP *ServiceRouteHTTPMatch `json:",omitempty"` } type ServiceRouteHTTPMatch struct { PathExact string `json:",omitempty" alias:"path_exact"` PathPrefix string `json:",omitempty" alias:"path_prefix"` PathRegex string `json:",omitempty" alias:"path_regex"` Header []ServiceRouteHTTPMatchHeader `json:",omitempty"` QueryParam []ServiceRouteHTTPMatchQueryParam `json:",omitempty" alias:"query_param"` Methods []string `json:",omitempty"` } type ServiceRouteHTTPMatchHeader struct { Name string Present bool `json:",omitempty"` Exact string `json:",omitempty"` Prefix string `json:",omitempty"` Suffix string `json:",omitempty"` Regex string `json:",omitempty"` Invert bool `json:",omitempty"` } type ServiceRouteHTTPMatchQueryParam struct { Name string Present bool `json:",omitempty"` Exact string `json:",omitempty"` Regex string `json:",omitempty"` } type ServiceRouteDestination struct { Service string `json:",omitempty"` ServiceSubset string `json:",omitempty" alias:"service_subset"` Namespace string `json:",omitempty"` Partition string `json:",omitempty"` PrefixRewrite string `json:",omitempty" alias:"prefix_rewrite"` RequestTimeout time.Duration `json:",omitempty" alias:"request_timeout"` IdleTimeout time.Duration `json:",omitempty" alias:"idle_timeout"` NumRetries uint32 `json:",omitempty" alias:"num_retries"` RetryOnConnectFailure bool `json:",omitempty" alias:"retry_on_connect_failure"` RetryOnStatusCodes []uint32 `json:",omitempty" alias:"retry_on_status_codes"` RetryOn []string `json:",omitempty" alias:"retry_on"` RequestHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"request_headers"` ResponseHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"response_headers"` } func (e *ServiceRouteDestination) MarshalJSON() ([]byte, error) { type Alias ServiceRouteDestination exported := &struct { RequestTimeout string `json:",omitempty"` IdleTimeout string `json:",omitempty"` *Alias }{ RequestTimeout: e.RequestTimeout.String(), IdleTimeout: e.IdleTimeout.String(), Alias: (*Alias)(e), } if e.RequestTimeout == 0 { exported.RequestTimeout = "" } if e.IdleTimeout == 0 { exported.IdleTimeout = "" } return json.Marshal(exported) } func (e *ServiceRouteDestination) UnmarshalJSON(data []byte) error { type Alias ServiceRouteDestination aux := &struct { RequestTimeout string IdleTimeout string *Alias }{ Alias: (*Alias)(e), } if err := json.Unmarshal(data, &aux); err != nil { return err } var err error if aux.RequestTimeout != "" { if e.RequestTimeout, err = time.ParseDuration(aux.RequestTimeout); err != nil { return err } } if aux.IdleTimeout != "" { if e.IdleTimeout, err = time.ParseDuration(aux.IdleTimeout); err != nil { return err } } return nil } type ServiceSplitterConfigEntry struct { Kind string Name string Partition string `json:",omitempty"` Namespace string `json:",omitempty"` Splits []ServiceSplit `json:",omitempty"` Meta map[string]string `json:",omitempty"` CreateIndex uint64 ModifyIndex uint64 } func (e *ServiceSplitterConfigEntry) GetKind() string { return e.Kind } func (e *ServiceSplitterConfigEntry) GetName() string { return e.Name } func (e *ServiceSplitterConfigEntry) GetPartition() string { return e.Partition } func (e *ServiceSplitterConfigEntry) GetNamespace() string { return e.Namespace } func (e *ServiceSplitterConfigEntry) GetMeta() map[string]string { return e.Meta } func (e *ServiceSplitterConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } func (e *ServiceSplitterConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } type ServiceSplit struct { Weight float32 Service string `json:",omitempty"` ServiceSubset string `json:",omitempty" alias:"service_subset"` Namespace string `json:",omitempty"` Partition string `json:",omitempty"` RequestHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"request_headers"` ResponseHeaders *HTTPHeaderModifiers `json:",omitempty" alias:"response_headers"` } type ServiceResolverConfigEntry struct { Kind string Name string Partition string `json:",omitempty"` Namespace string `json:",omitempty"` DefaultSubset string `json:",omitempty" alias:"default_subset"` Subsets map[string]ServiceResolverSubset `json:",omitempty"` Redirect *ServiceResolverRedirect `json:",omitempty"` Failover map[string]ServiceResolverFailover `json:",omitempty"` ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"` RequestTimeout time.Duration `json:",omitempty" alias:"request_timeout"` // PrioritizeByLocality controls whether the locality of services within the // local partition will be used to prioritize connectivity. PrioritizeByLocality *ServiceResolverPrioritizeByLocality `json:",omitempty" alias:"prioritize_by_locality"` // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. LoadBalancer *LoadBalancer `json:",omitempty" alias:"load_balancer"` Meta map[string]string `json:",omitempty"` CreateIndex uint64 ModifyIndex uint64 } func (e *ServiceResolverConfigEntry) MarshalJSON() ([]byte, error) { type Alias ServiceResolverConfigEntry exported := &struct { ConnectTimeout string `json:",omitempty"` RequestTimeout string `json:",omitempty"` *Alias }{ ConnectTimeout: e.ConnectTimeout.String(), RequestTimeout: e.RequestTimeout.String(), Alias: (*Alias)(e), } if e.ConnectTimeout == 0 { exported.ConnectTimeout = "" } if e.RequestTimeout == 0 { exported.RequestTimeout = "" } return json.Marshal(exported) } func (e *ServiceResolverConfigEntry) UnmarshalJSON(data []byte) error { type Alias ServiceResolverConfigEntry aux := &struct { ConnectTimeout string RequestTimeout string *Alias }{ Alias: (*Alias)(e), } var err error if err = json.Unmarshal(data, &aux); err != nil { return err } var merr *multierror.Error if aux.ConnectTimeout != "" { if e.ConnectTimeout, err = time.ParseDuration(aux.ConnectTimeout); err != nil { merr = multierror.Append(merr, err) } } if aux.RequestTimeout != "" { if e.RequestTimeout, err = time.ParseDuration(aux.RequestTimeout); err != nil { merr = multierror.Append(merr, err) } } return merr.ErrorOrNil() } func (e *ServiceResolverConfigEntry) GetKind() string { return e.Kind } func (e *ServiceResolverConfigEntry) GetName() string { return e.Name } func (e *ServiceResolverConfigEntry) GetPartition() string { return e.Partition } func (e *ServiceResolverConfigEntry) GetNamespace() string { return e.Namespace } func (e *ServiceResolverConfigEntry) GetMeta() map[string]string { return e.Meta } func (e *ServiceResolverConfigEntry) GetCreateIndex() uint64 { return e.CreateIndex } func (e *ServiceResolverConfigEntry) GetModifyIndex() uint64 { return e.ModifyIndex } type ServiceResolverSubset struct { Filter string `json:",omitempty"` OnlyPassing bool `json:",omitempty" alias:"only_passing"` } type ServiceResolverRedirect struct { Service string `json:",omitempty"` ServiceSubset string `json:",omitempty" alias:"service_subset"` Namespace string `json:",omitempty"` Partition string `json:",omitempty"` Datacenter string `json:",omitempty"` Peer string `json:",omitempty"` SamenessGroup string `json:",omitempty" alias:"sameness_group"` } type ServiceResolverFailover struct { Service string `json:",omitempty"` ServiceSubset string `json:",omitempty" alias:"service_subset"` // Referencing other partitions is not supported. Namespace string `json:",omitempty"` Datacenters []string `json:",omitempty"` Targets []ServiceResolverFailoverTarget `json:",omitempty"` Policy *ServiceResolverFailoverPolicy `json:",omitempty"` SamenessGroup string `json:",omitempty" alias:"sameness_group"` } type ServiceResolverFailoverTarget struct { Service string `json:",omitempty"` ServiceSubset string `json:",omitempty" alias:"service_subset"` Partition string `json:",omitempty"` Namespace string `json:",omitempty"` Datacenter string `json:",omitempty"` Peer string `json:",omitempty"` } type ServiceResolverFailoverPolicy struct { // Mode specifies the type of failover that will be performed. Valid values are // "sequential", "" (equivalent to "sequential") and "order-by-locality". Mode string `json:",omitempty"` Regions []string `json:",omitempty"` } type ServiceResolverPrioritizeByLocality struct { // Mode specifies the type of prioritization that will be performed // when selecting nodes in the local partition. // Valid values are: "" (default "none"), "none", and "failover". Mode string `json:",omitempty"` } // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. type LoadBalancer struct { // Policy is the load balancing policy used to select a host Policy string `json:",omitempty"` // RingHashConfig contains configuration for the "ring_hash" policy type RingHashConfig *RingHashConfig `json:",omitempty" alias:"ring_hash_config"` // LeastRequestConfig contains configuration for the "least_request" policy type LeastRequestConfig *LeastRequestConfig `json:",omitempty" alias:"least_request_config"` // HashPolicies is a list of hash policies to use for hashing load balancing algorithms. // Hash policies are evaluated individually and combined such that identical lists // result in the same hash. // If no hash policies are present, or none are successfully evaluated, // then a random backend host will be selected. HashPolicies []HashPolicy `json:",omitempty" alias:"hash_policies"` } // RingHashConfig contains configuration for the "ring_hash" policy type type RingHashConfig struct { // MinimumRingSize determines the minimum number of entries in the hash ring MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"` // MaximumRingSize determines the maximum number of entries in the hash ring MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"` } // LeastRequestConfig contains configuration for the "least_request" policy type type LeastRequestConfig struct { // ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests. ChoiceCount uint32 `json:",omitempty" alias:"choice_count"` } // HashPolicy defines which attributes will be hashed by hash-based LB algorithms type HashPolicy struct { // Field is the attribute type to hash on. // Must be one of "header","cookie", or "query_parameter". // Cannot be specified along with SourceIP. Field string `json:",omitempty"` // FieldValue is the value to hash. // ie. header name, cookie name, URL query parameter name // Cannot be specified along with SourceIP. FieldValue string `json:",omitempty" alias:"field_value"` // CookieConfig contains configuration for the "cookie" hash policy type. CookieConfig *CookieConfig `json:",omitempty" alias:"cookie_config"` // SourceIP determines whether the hash should be of the source IP rather than of a field and field value. // Cannot be specified along with Field or FieldValue. SourceIP bool `json:",omitempty" alias:"source_ip"` // Terminal will short circuit the computation of the hash when multiple hash policies are present. // If a hash is computed when a Terminal policy is evaluated, // then that hash will be used and subsequent hash policies will be ignored. Terminal bool `json:",omitempty"` } // CookieConfig contains configuration for the "cookie" hash policy type. // This is specified to have Envoy generate a cookie for a client on its first request. type CookieConfig struct { // Generates a session cookie with no expiration. Session bool `json:",omitempty"` // TTL for generated cookies. Cannot be specified for session cookies. TTL time.Duration `json:",omitempty"` // The path to set for the cookie Path string `json:",omitempty"` } // HTTPHeaderModifiers is a set of rules for HTTP header modification that // should be performed by proxies as the request passes through them. It can // operate on either request or response headers depending on the context in // which it is used. type HTTPHeaderModifiers struct { // Add is a set of name -> value pairs that should be appended to the request // or response (i.e. allowing duplicates if the same header already exists). Add map[string]string `json:",omitempty"` // Set is a set of name -> value pairs that should be added to the request or // response, overwriting any existing header values of the same name. Set map[string]string `json:",omitempty"` // Remove is the set of header names that should be stripped from the request // or response. Remove []string `json:",omitempty"` }