1package api
2
3import (
4	"encoding/json"
5	"time"
6)
7
8type ServiceRouterConfigEntry struct {
9	Kind      string
10	Name      string
11	Namespace string `json:",omitempty"`
12
13	Routes []ServiceRoute `json:",omitempty"`
14
15	Meta        map[string]string `json:",omitempty"`
16	CreateIndex uint64
17	ModifyIndex uint64
18}
19
20func (e *ServiceRouterConfigEntry) GetKind() string            { return e.Kind }
21func (e *ServiceRouterConfigEntry) GetName() string            { return e.Name }
22func (e *ServiceRouterConfigEntry) GetNamespace() string       { return e.Namespace }
23func (e *ServiceRouterConfigEntry) GetMeta() map[string]string { return e.Meta }
24func (e *ServiceRouterConfigEntry) GetCreateIndex() uint64     { return e.CreateIndex }
25func (e *ServiceRouterConfigEntry) GetModifyIndex() uint64     { return e.ModifyIndex }
26
27type ServiceRoute struct {
28	Match       *ServiceRouteMatch       `json:",omitempty"`
29	Destination *ServiceRouteDestination `json:",omitempty"`
30}
31
32type ServiceRouteMatch struct {
33	HTTP *ServiceRouteHTTPMatch `json:",omitempty"`
34}
35
36type ServiceRouteHTTPMatch struct {
37	PathExact  string `json:",omitempty" alias:"path_exact"`
38	PathPrefix string `json:",omitempty" alias:"path_prefix"`
39	PathRegex  string `json:",omitempty" alias:"path_regex"`
40
41	Header     []ServiceRouteHTTPMatchHeader     `json:",omitempty"`
42	QueryParam []ServiceRouteHTTPMatchQueryParam `json:",omitempty" alias:"query_param"`
43	Methods    []string                          `json:",omitempty"`
44}
45
46type ServiceRouteHTTPMatchHeader struct {
47	Name    string
48	Present bool   `json:",omitempty"`
49	Exact   string `json:",omitempty"`
50	Prefix  string `json:",omitempty"`
51	Suffix  string `json:",omitempty"`
52	Regex   string `json:",omitempty"`
53	Invert  bool   `json:",omitempty"`
54}
55
56type ServiceRouteHTTPMatchQueryParam struct {
57	Name    string
58	Present bool   `json:",omitempty"`
59	Exact   string `json:",omitempty"`
60	Regex   string `json:",omitempty"`
61}
62
63type ServiceRouteDestination struct {
64	Service               string        `json:",omitempty"`
65	ServiceSubset         string        `json:",omitempty" alias:"service_subset"`
66	Namespace             string        `json:",omitempty"`
67	PrefixRewrite         string        `json:",omitempty" alias:"prefix_rewrite"`
68	RequestTimeout        time.Duration `json:",omitempty" alias:"request_timeout"`
69	NumRetries            uint32        `json:",omitempty" alias:"num_retries"`
70	RetryOnConnectFailure bool          `json:",omitempty" alias:"retry_on_connect_failure"`
71	RetryOnStatusCodes    []uint32      `json:",omitempty" alias:"retry_on_status_codes"`
72}
73
74func (e *ServiceRouteDestination) MarshalJSON() ([]byte, error) {
75	type Alias ServiceRouteDestination
76	exported := &struct {
77		RequestTimeout string `json:",omitempty"`
78		*Alias
79	}{
80		RequestTimeout: e.RequestTimeout.String(),
81		Alias:          (*Alias)(e),
82	}
83	if e.RequestTimeout == 0 {
84		exported.RequestTimeout = ""
85	}
86
87	return json.Marshal(exported)
88}
89
90func (e *ServiceRouteDestination) UnmarshalJSON(data []byte) error {
91	type Alias ServiceRouteDestination
92	aux := &struct {
93		RequestTimeout string
94		*Alias
95	}{
96		Alias: (*Alias)(e),
97	}
98	if err := json.Unmarshal(data, &aux); err != nil {
99		return err
100	}
101	var err error
102	if aux.RequestTimeout != "" {
103		if e.RequestTimeout, err = time.ParseDuration(aux.RequestTimeout); err != nil {
104			return err
105		}
106	}
107	return nil
108}
109
110type ServiceSplitterConfigEntry struct {
111	Kind      string
112	Name      string
113	Namespace string `json:",omitempty"`
114
115	Splits []ServiceSplit `json:",omitempty"`
116
117	Meta        map[string]string `json:",omitempty"`
118	CreateIndex uint64
119	ModifyIndex uint64
120}
121
122func (e *ServiceSplitterConfigEntry) GetKind() string            { return e.Kind }
123func (e *ServiceSplitterConfigEntry) GetName() string            { return e.Name }
124func (e *ServiceSplitterConfigEntry) GetNamespace() string       { return e.Namespace }
125func (e *ServiceSplitterConfigEntry) GetMeta() map[string]string { return e.Meta }
126func (e *ServiceSplitterConfigEntry) GetCreateIndex() uint64     { return e.CreateIndex }
127func (e *ServiceSplitterConfigEntry) GetModifyIndex() uint64     { return e.ModifyIndex }
128
129type ServiceSplit struct {
130	Weight        float32
131	Service       string `json:",omitempty"`
132	ServiceSubset string `json:",omitempty" alias:"service_subset"`
133	Namespace     string `json:",omitempty"`
134}
135
136type ServiceResolverConfigEntry struct {
137	Kind      string
138	Name      string
139	Namespace string `json:",omitempty"`
140
141	DefaultSubset  string                             `json:",omitempty" alias:"default_subset"`
142	Subsets        map[string]ServiceResolverSubset   `json:",omitempty"`
143	Redirect       *ServiceResolverRedirect           `json:",omitempty"`
144	Failover       map[string]ServiceResolverFailover `json:",omitempty"`
145	ConnectTimeout time.Duration                      `json:",omitempty" alias:"connect_timeout"`
146
147	// LoadBalancer determines the load balancing policy and configuration for services
148	// issuing requests to this upstream service.
149	LoadBalancer *LoadBalancer `json:",omitempty" alias:"load_balancer"`
150
151	Meta        map[string]string `json:",omitempty"`
152	CreateIndex uint64
153	ModifyIndex uint64
154}
155
156func (e *ServiceResolverConfigEntry) MarshalJSON() ([]byte, error) {
157	type Alias ServiceResolverConfigEntry
158	exported := &struct {
159		ConnectTimeout string `json:",omitempty"`
160		*Alias
161	}{
162		ConnectTimeout: e.ConnectTimeout.String(),
163		Alias:          (*Alias)(e),
164	}
165	if e.ConnectTimeout == 0 {
166		exported.ConnectTimeout = ""
167	}
168
169	return json.Marshal(exported)
170}
171
172func (e *ServiceResolverConfigEntry) UnmarshalJSON(data []byte) error {
173	type Alias ServiceResolverConfigEntry
174	aux := &struct {
175		ConnectTimeout string
176		*Alias
177	}{
178		Alias: (*Alias)(e),
179	}
180	if err := json.Unmarshal(data, &aux); err != nil {
181		return err
182	}
183	var err error
184	if aux.ConnectTimeout != "" {
185		if e.ConnectTimeout, err = time.ParseDuration(aux.ConnectTimeout); err != nil {
186			return err
187		}
188	}
189	return nil
190}
191
192func (e *ServiceResolverConfigEntry) GetKind() string            { return e.Kind }
193func (e *ServiceResolverConfigEntry) GetName() string            { return e.Name }
194func (e *ServiceResolverConfigEntry) GetNamespace() string       { return e.Namespace }
195func (e *ServiceResolverConfigEntry) GetMeta() map[string]string { return e.Meta }
196func (e *ServiceResolverConfigEntry) GetCreateIndex() uint64     { return e.CreateIndex }
197func (e *ServiceResolverConfigEntry) GetModifyIndex() uint64     { return e.ModifyIndex }
198
199type ServiceResolverSubset struct {
200	Filter      string `json:",omitempty"`
201	OnlyPassing bool   `json:",omitempty" alias:"only_passing"`
202}
203
204type ServiceResolverRedirect struct {
205	Service       string `json:",omitempty"`
206	ServiceSubset string `json:",omitempty" alias:"service_subset"`
207	Namespace     string `json:",omitempty"`
208	Datacenter    string `json:",omitempty"`
209}
210
211type ServiceResolverFailover struct {
212	Service       string   `json:",omitempty"`
213	ServiceSubset string   `json:",omitempty" alias:"service_subset"`
214	Namespace     string   `json:",omitempty"`
215	Datacenters   []string `json:",omitempty"`
216}
217
218// LoadBalancer determines the load balancing policy and configuration for services
219// issuing requests to this upstream service.
220type LoadBalancer struct {
221	// Policy is the load balancing policy used to select a host
222	Policy string `json:",omitempty"`
223
224	// RingHashConfig contains configuration for the "ring_hash" policy type
225	RingHashConfig *RingHashConfig `json:",omitempty" alias:"ring_hash_config"`
226
227	// LeastRequestConfig contains configuration for the "least_request" policy type
228	LeastRequestConfig *LeastRequestConfig `json:",omitempty" alias:"least_request_config"`
229
230	// HashPolicies is a list of hash policies to use for hashing load balancing algorithms.
231	// Hash policies are evaluated individually and combined such that identical lists
232	// result in the same hash.
233	// If no hash policies are present, or none are successfully evaluated,
234	// then a random backend host will be selected.
235	HashPolicies []HashPolicy `json:",omitempty" alias:"hash_policies"`
236}
237
238// RingHashConfig contains configuration for the "ring_hash" policy type
239type RingHashConfig struct {
240	// MinimumRingSize determines the minimum number of entries in the hash ring
241	MinimumRingSize uint64 `json:",omitempty" alias:"minimum_ring_size"`
242
243	// MaximumRingSize determines the maximum number of entries in the hash ring
244	MaximumRingSize uint64 `json:",omitempty" alias:"maximum_ring_size"`
245}
246
247// LeastRequestConfig contains configuration for the "least_request" policy type
248type LeastRequestConfig struct {
249	// ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests.
250	ChoiceCount uint32 `json:",omitempty" alias:"choice_count"`
251}
252
253// HashPolicy defines which attributes will be hashed by hash-based LB algorithms
254type HashPolicy struct {
255	// Field is the attribute type to hash on.
256	// Must be one of "header","cookie", or "query_parameter".
257	// Cannot be specified along with SourceIP.
258	Field string `json:",omitempty"`
259
260	// FieldValue is the value to hash.
261	// ie. header name, cookie name, URL query parameter name
262	// Cannot be specified along with SourceIP.
263	FieldValue string `json:",omitempty" alias:"field_value"`
264
265	// CookieConfig contains configuration for the "cookie" hash policy type.
266	CookieConfig *CookieConfig `json:",omitempty" alias:"cookie_config"`
267
268	// SourceIP determines whether the hash should be of the source IP rather than of a field and field value.
269	// Cannot be specified along with Field or FieldValue.
270	SourceIP bool `json:",omitempty" alias:"source_ip"`
271
272	// Terminal will short circuit the computation of the hash when multiple hash policies are present.
273	// If a hash is computed when a Terminal policy is evaluated,
274	// then that hash will be used and subsequent hash policies will be ignored.
275	Terminal bool `json:",omitempty"`
276}
277
278// CookieConfig contains configuration for the "cookie" hash policy type.
279// This is specified to have Envoy generate a cookie for a client on its first request.
280type CookieConfig struct {
281	// Generates a session cookie with no expiration.
282	Session bool `json:",omitempty"`
283
284	// TTL for generated cookies. Cannot be specified for session cookies.
285	TTL time.Duration `json:",omitempty"`
286
287	// The path to set for the cookie
288	Path string `json:",omitempty"`
289}
290