-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsample.config.yaml
More file actions
279 lines (236 loc) · 10.4 KB
/
Copy pathsample.config.yaml
File metadata and controls
279 lines (236 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# Aastro - example configuration showcasing every available option.
#
# This file is meant as a reference, not a copy-paste production config.
# Most blocks are optional; uncomment and adjust what you actually need.
#
# Required top-level sections: schema, gateway.server, gateway.admin, gateway.routing.
# Everything else has sensible defaults.
schema: v1
debug: false # verbose logging across router, scatter, and upstream components
gateway:
# ── Service identity ─────────────────────────────────────────────────────
# Appears as service.name in OpenTelemetry resource attributes.
service:
name: aastro
# ── Data port ────────────────────────────────────────────────────────────
# Serves API traffic. Optionally protected by TLS or mTLS.
server:
port: 7805
timeout: 20s # read + write timeout per request
header_timeout: 5s # Slowloris defence - caps header read time
# TLS / mTLS on the data port.
# Remove the tls block entirely for plain HTTP.
tls:
enabled: true
cert_file: /etc/aastro/server.crt
key_file: /etc/aastro/server.key
min_version: "1.2" # 1.2 or 1.3 - older versions are not selectable
client_auth: require # none | optional | require
client_ca_file: /etc/aastro/client-ca.crt # required unless client_auth=none
# ── Admin port ───────────────────────────────────────────────────────────
# Health probes, metrics, pprof. Bound to localhost by default.
# Never TLS-terminated - kubelet probes and Prometheus scrape over plain HTTP
# even when the data port enforces mTLS.
admin:
port: 9090
bind_addr: 127.0.0.1 # set to 0.0.0.0 only if Prometheus runs outside the pod
timeout: 5m # generous to accommodate long pprof captures
header_timeout: 5s
enable_pprof: true # exposes /debug/pprof/ on the admin port
# ── Observability ────────────────────────────────────────────────────────
# Push-based instrumentation. Metrics in prometheus mode also exposes
# /metrics on the admin port; OTLP mode is purely push.
observability:
metrics:
enabled: true
exporter: prometheus # prometheus | otlp
# OTLP config is used only when exporter=otlp:
otlp:
endpoint: otel-collector:4318
insecure: true
interval: 10s
tracing:
enabled: true
exporter: otlp
sampling_ratio: 1.0 # 0.0–1.0 (1.0 = sample every trace)
otlp:
endpoint: otel-collector:4318
insecure: true
interval: 10s
# ── Routing ──────────────────────────────────────────────────────────────
routing:
# CIDR ranges whose X-Forwarded-* headers are appended to rather than overwritten.
# Leave empty if Aastro is your outermost edge.
trusted_proxies:
- 127.0.0.1/32
- 10.0.0.0/8
# Per-IP rate limiter. The IP is the one extracted via trusted-proxy resolution.
rate_limiter:
enabled: true
config:
limit: 100
window: 1s
# ── Flow examples ──────────────────────────────────────────────────────
# A flow defines: how a request is matched, which upstreams it scatters to,
# how their responses are aggregated, and which plugins/middlewares run.
flows:
# ── Example 1: merge aggregation across two upstreams ────────────────
# Combines responses from `users` and `orders` services into a single
# JSON object. Returns 206 Partial Content if one fails and best_effort
# is enabled.
- path: /api/v1/customers/{customer_id}
method: GET
aggregation:
strategy: merge # merge | array | namespace
best_effort: true # return partial data on upstream failures
on_conflict:
policy: prefer # overwrite | first | error | prefer
prefer_upstream: users # this upstream wins on key collision
# Cross-cutting middlewares wrap the entire flow handler.
# First in the list = outermost wrapper.
middlewares:
- name: recoverer
source: builtin
- name: logger
source: builtin
- name: auth
source: builtin
config:
alg: HS256
issuer: https://auth.example.com
audience: api
hmac_secret: "base64secret"
# Plugins run at specific lifecycle phases (request / response).
plugins:
- name: snakeify
source: builtin
- name: tenant_resolver
source: file
path: /etc/aastro/plugins/
config:
header: X-Tenant-Id
upstreams:
- name: users
hosts:
- https://users-1.internal
- https://users-2.internal
path: /v1/users/{customer_id}
method: GET
timeout: 3s
forward_headers: [ "Authorization", "X-Tenant-Id", "X-Request-Id" ]
forward_queries: [ "expand", "fields" ]
forward_params: [ "customer_id" ]
transport:
max_idle_conns: 100
max_idle_conns_per_host: 50
idle_conn_timeout: 90s
# Outbound mTLS to the upstream.
# Omit the tls block entirely for plain HTTPS - Go uses system roots.
tls:
enabled: true
cert_file: /etc/aastro/clients/users.crt
key_file: /etc/aastro/clients/users.key
ca_file: /etc/aastro/internal-ca.crt
server_name: users.internal # SNI / hostname verification
min_version: "1.2"
policy:
require_body: true
max_response_body_size: 1048576 # 1 MiB
header_blacklist:
- X-Internal-Token
retry:
max_retries: 3
retry_on_statuses: [ 500, 502, 503, 504 ]
backoff_delay: 200ms
circuit_breaker:
enabled: true
max_failures: 5
reset_timeout: 10s
load_balancing:
mode: least_conns # round_robin | least_conns
- name: orders
hosts: https://orders.internal # single host - string is fine
path: /v1/customers/{customer_id}/orders
timeout: 2s
forward_params: [ "customer_id" ]
# No upstream tls block → public-ish HTTPS via system root CAs
policy:
retry:
max_retries: 2
retry_on_statuses: [ 503 ]
backoff_delay: 100ms
# ── Example 2: namespace aggregation ─────────────────────────────────
# Each upstream's response lives under a key named after the upstream:
# {"profile": {...}, "preferences": {...}}
- path: /api/v1/me
method: GET
aggregation:
strategy: namespace
best_effort: false # any upstream failure fails the whole request
middlewares:
- name: auth
source: builtin
config:
alg: HS256
hmac_secret: "base64secret"
upstreams:
- name: profile
hosts: https://profile.internal
path: /v1/profile
forward_headers: [ "Authorization" ]
- name: preferences
hosts: https://prefs.internal
path: /v1/prefs
forward_headers: [ "Authorization" ]
# ── Example 3: array aggregation, POST with body ─────────────────────
# Each upstream response becomes an element of a JSON array.
# POST/PUT/PATCH bodies are forwarded; other methods discard the body.
- path: /api/v1/search
method: POST
aggregation:
strategy: array
best_effort: true
upstreams:
- name: catalog
hosts: https://catalog.internal
path: /v1/search
method: POST
timeout: 5s
forward_headers: [ "Content-Type", "Authorization", "X-*" ]
- name: docs
hosts: https://docs.internal
path: /v2/query
method: POST
timeout: 5s
forward_headers: [ "Content-Type", "Authorization" ]
# ── Example 4: streaming (SSE / chunked) ──────────────────────────────
# Bypasses aggregation entirely. Body streams chunk-by-chunk to the
# client. Requires exactly one upstream. Response-phase plugins do not
# run (body is already streaming by the time they'd execute).
- path: /api/v1/events/{user_id}
method: GET
streaming: true
# Request-phase plugins still run before the upstream call.
plugins:
- name: tenant_resolver
source: file
path: /etc/aastro/plugins/
config:
header: X-Tenant-Id
upstreams:
- name: events
hosts: https://events.internal
path: /v1/users/{user_id}/events
timeout: 60s # long-lived; remember server.timeout caps this
forward_headers: [ "Authorization", "Accept", "Last-Event-Id" ]
forward_params: [ "user_id" ]
# ── Example 5: bare minimum ──────────────────────────────────────────
# Single upstream, simplest possible flow.
- path: /api/v1/health-check
method: GET
aggregation:
strategy: array
upstreams:
- name: noop
hosts: https://example.com
path: /