@kumori.systems/components-apisix 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/kumori.systems/components/apisix/@0.0.1/README.adoc +130 -0
  2. package/kumori.systems/components/apisix/@0.0.1/assets/images/routing_diagram.png +0 -0
  3. package/kumori.systems/components/apisix/@0.0.1/componentref.cue +26 -0
  4. package/kumori.systems/components/apisix/@0.0.1/cue.mod/module.cue +1 -0
  5. package/kumori.systems/components/apisix/@0.0.1/kmodule.cue +30 -0
  6. package/kumori.systems/components/apisix/@0.0.1/manifest.cue +159 -0
  7. package/kumori.systems/components/apisix/@0.0.1/openid-connect.cue +587 -0
  8. package/kumori.systems/components/apisix/@0.0.1/serviceref.cue +26 -0
  9. package/kumori.systems/components/apisix/@0.0.1/settings/apisix_settings.cue +33 -0
  10. package/kumori.systems/components/apisix/@0.0.1/settings/entrypoint.cue +38 -0
  11. package/kumori.systems/components/apisix/@0.0.1/settings/types/connections.cue +131 -0
  12. package/kumori.systems/components/apisix/@0.0.1/settings/types/consumer.cue +6 -0
  13. package/kumori.systems/components/apisix/@0.0.1/settings/types/globalrule.cue +6 -0
  14. package/kumori.systems/components/apisix/@0.0.1/settings/types/healthcheck.cue +39 -0
  15. package/kumori.systems/components/apisix/@0.0.1/settings/types/plugin.cue +20 -0
  16. package/kumori.systems/components/apisix/@0.0.1/settings/types/pluginmetadata.cue +6 -0
  17. package/kumori.systems/components/apisix/@0.0.1/settings/types/route.cue +34 -0
  18. package/kumori.systems/components/apisix/@0.0.1/settings/types/service.cue +6 -0
  19. package/kumori.systems/components/apisix/@0.0.1/settings/types/ssl.cue +11 -0
  20. package/kumori.systems/components/apisix/@0.0.1/settings/types/streamroute.cue +6 -0
  21. package/kumori.systems/components/apisix/@0.0.1/settings/types/upstream.cue +35 -0
  22. package/kumori.systems/components/apisix/@0.0.1/settings/types/utils.cue +11 -0
  23. package/package.json +1 -0
@@ -0,0 +1,587 @@
1
+ package component
2
+
3
+ #openid_connect_lua: ###"""
4
+ --
5
+ -- Licensed to the Apache Software Foundation (ASF) under one or more
6
+ -- contributor license agreements. See the NOTICE file distributed with
7
+ -- this work for additional information regarding copyright ownership.
8
+ -- The ASF licenses this file to You under the Apache License, Version 2.0
9
+ -- (the "License"); you may not use this file except in compliance with
10
+ -- the License. You may obtain a copy of the License at
11
+ --
12
+ -- http://www.apache.org/licenses/LICENSE-2.0
13
+ --
14
+ -- Unless required by applicable law or agreed to in writing, software
15
+ -- distributed under the License is distributed on an "AS IS" BASIS,
16
+ -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ -- See the License for the specific language governing permissions and
18
+ -- limitations under the License.
19
+ --
20
+
21
+ local core = require("apisix.core")
22
+ local ngx_re = require("ngx.re")
23
+ local openidc = require("resty.openidc")
24
+ local random = require("resty.random")
25
+ local string = string
26
+ local ngx = ngx
27
+ local ipairs = ipairs
28
+ local concat = table.concat
29
+
30
+ local ngx_encode_base64 = ngx.encode_base64
31
+
32
+ local plugin_name = "openid-connect"
33
+
34
+
35
+ local schema = {
36
+ type = "object",
37
+ properties = {
38
+ client_id = {type = "string"},
39
+ client_secret = {type = "string"},
40
+ discovery = {type = "string"},
41
+ scope = {
42
+ type = "string",
43
+ default = "openid",
44
+ },
45
+ ssl_verify = {
46
+ type = "boolean",
47
+ default = false,
48
+ },
49
+ timeout = {
50
+ type = "integer",
51
+ minimum = 1,
52
+ default = 3,
53
+ description = "timeout in seconds",
54
+ },
55
+ introspection_endpoint = {
56
+ type = "string"
57
+ },
58
+ introspection_endpoint_auth_method = {
59
+ type = "string",
60
+ default = "client_secret_basic"
61
+ },
62
+ token_endpoint_auth_method = {
63
+ type = "string",
64
+ default = "client_secret_basic"
65
+ },
66
+ bearer_only = {
67
+ type = "boolean",
68
+ default = false,
69
+ },
70
+ session = {
71
+ type = "object",
72
+ properties = {
73
+ secret = {
74
+ type = "string",
75
+ description = "the key used for the encrypt and HMAC calculation",
76
+ minLength = 16,
77
+ },
78
+ },
79
+ required = {"secret"},
80
+ additionalProperties = false,
81
+ },
82
+ realm = {
83
+ type = "string",
84
+ default = "apisix",
85
+ },
86
+ logout_path = {
87
+ type = "string",
88
+ default = "/logout",
89
+ },
90
+ redirect_uri = {
91
+ type = "string",
92
+ description = "auto append '.apisix/redirect' to ngx.var.uri if not configured"
93
+ },
94
+ post_logout_redirect_uri = {
95
+ type = "string",
96
+ description = "the URI will be redirect when request logout_path",
97
+ },
98
+ unauth_action = {
99
+ type = "string",
100
+ default = "auth",
101
+ enum = {"auth", "deny", "pass"},
102
+ description = "The action performed when client is not authorized. Use auth to " ..
103
+ "redirect user to identity provider, deny to respond with 401 Unauthorized, and " ..
104
+ "pass to allow the request regardless."
105
+ },
106
+ public_key = {type = "string"},
107
+ token_signing_alg_values_expected = {type = "string"},
108
+ use_pkce = {
109
+ description = "when set to true the PKEC(Proof Key for Code Exchange) will be used.",
110
+ type = "boolean",
111
+ default = false
112
+ },
113
+ set_access_token_header = {
114
+ description = "Whether the access token should be added as a header to the request " ..
115
+ "for downstream",
116
+ type = "boolean",
117
+ default = true
118
+ },
119
+ access_token_in_authorization_header = {
120
+ description = "Whether the access token should be added in the Authorization " ..
121
+ "header as opposed to the X-Access-Token header.",
122
+ type = "boolean",
123
+ default = false
124
+ },
125
+ set_id_token_header = {
126
+ description = "Whether the ID token should be added in the X-ID-Token header to " ..
127
+ "the request for downstream.",
128
+ type = "boolean",
129
+ default = true
130
+ },
131
+ set_userinfo_header = {
132
+ description = "Whether the user info token should be added in the X-Userinfo " ..
133
+ "header to the request for downstream.",
134
+ type = "boolean",
135
+ default = true
136
+ },
137
+ set_refresh_token_header = {
138
+ description = "Whether the refresh token should be added in the X-Refresh-Token " ..
139
+ "header to the request for downstream.",
140
+ type = "boolean",
141
+ default = false
142
+ },
143
+ proxy_opts = {
144
+ description = "HTTP proxy server be used to access identity server.",
145
+ type = "object",
146
+ properties = {
147
+ http_proxy = {
148
+ type = "string",
149
+ description = "HTTP proxy like: http://proxy-server:80.",
150
+ },
151
+ https_proxy = {
152
+ type = "string",
153
+ description = "HTTPS proxy like: http://proxy-server:80.",
154
+ },
155
+ http_proxy_authorization = {
156
+ type = "string",
157
+ description = "Basic [base64 username:password].",
158
+ },
159
+ https_proxy_authorization = {
160
+ type = "string",
161
+ description = "Basic [base64 username:password].",
162
+ },
163
+ no_proxy = {
164
+ type = "string",
165
+ description = "Comma separated list of hosts that should not be proxied.",
166
+ }
167
+ },
168
+ },
169
+ authorization_params = {
170
+ description = "Extra authorization params to the authorize endpoint",
171
+ type = "object"
172
+ },
173
+ client_rsa_private_key = {
174
+ description = "Client RSA private key used to sign JWT.",
175
+ type = "string"
176
+ },
177
+ client_rsa_private_key_id = {
178
+ description = "Client RSA private key ID used to compute a signed JWT.",
179
+ type = "string"
180
+ },
181
+ client_jwt_assertion_expires_in = {
182
+ description = "Life duration of the signed JWT in seconds.",
183
+ type = "integer",
184
+ default = 60
185
+ },
186
+ renew_access_token_on_expiry = {
187
+ description = "Whether to attempt silently renewing the access token.",
188
+ type = "boolean",
189
+ default = true
190
+ },
191
+ access_token_expires_in = {
192
+ description = "Lifetime of the access token in seconds if expires_in is not present.",
193
+ type = "integer"
194
+ },
195
+ refresh_session_interval = {
196
+ description = "Time interval to refresh user ID token without re-authentication.",
197
+ type = "integer"
198
+ },
199
+ iat_slack = {
200
+ description = "Tolerance of clock skew in seconds with the iat claim in an ID token.",
201
+ type = "integer",
202
+ default = 120
203
+ },
204
+ accept_none_alg = {
205
+ description = "Set to true if the OpenID provider does not sign its ID token.",
206
+ type = "boolean",
207
+ default = false
208
+ },
209
+ accept_unsupported_alg = {
210
+ description = "Ignore ID token signature to accept unsupported signature algorithm.",
211
+ type = "boolean",
212
+ default = true
213
+ },
214
+ access_token_expires_leeway = {
215
+ description = "Expiration leeway in seconds for access token renewal.",
216
+ type = "integer",
217
+ default = 0
218
+ },
219
+ force_reauthorize = {
220
+ description = "Whether to execute the authorization flow when a token has been cached.",
221
+ type = "boolean",
222
+ default = false
223
+ },
224
+ use_nonce = {
225
+ description = "Whether to include nonce parameter in authorization request.",
226
+ type = "boolean",
227
+ default = false
228
+ },
229
+ revoke_tokens_on_logout = {
230
+ description = "Notify authorization server a previous token is no longer needed.",
231
+ type = "boolean",
232
+ default = false
233
+ },
234
+ jwk_expires_in = {
235
+ description = "Expiration time for JWK cache in seconds.",
236
+ type = "integer",
237
+ default = 86400
238
+ },
239
+ jwt_verification_cache_ignore = {
240
+ description = "Whether to ignore cached verification and re-verify.",
241
+ type = "boolean",
242
+ default = false
243
+ },
244
+ cache_segment = {
245
+ description = "Name of a cache segment to differentiate caches.",
246
+ type = "string"
247
+ },
248
+ introspection_interval = {
249
+ description = "TTL of the cached and introspected access token in seconds.",
250
+ type = "integer",
251
+ default = 0
252
+ },
253
+ introspection_expiry_claim = {
254
+ description = "Name of the expiry claim that controls the cached access token TTL.",
255
+ type = "string"
256
+ },
257
+ required_scopes = {
258
+ description = "List of scopes that are required to be granted to the access token",
259
+ type = "array",
260
+ items = {
261
+ type = "string"
262
+ }
263
+ }
264
+ },
265
+ encrypt_fields = {"client_secret"},
266
+ required = {"client_id", "client_secret", "discovery"}
267
+ }
268
+
269
+
270
+ local _M = {
271
+ version = 0.2,
272
+ priority = 2599,
273
+ name = plugin_name,
274
+ schema = schema,
275
+ }
276
+
277
+
278
+ function _M.check_schema(conf)
279
+ if conf.ssl_verify == "no" then
280
+ -- we used to set 'ssl_verify' to "no"
281
+ conf.ssl_verify = false
282
+ end
283
+
284
+ if not conf.bearer_only and not conf.session then
285
+ core.log.warn("when bearer_only = false, " ..
286
+ "you'd better complete the session configuration manually")
287
+ conf.session = {
288
+ -- generate a secret when bearer_only = false and no secret is configured
289
+ secret = ngx_encode_base64(random.bytes(32, true) or random.bytes(32))
290
+ }
291
+ end
292
+
293
+ local ok, err = core.schema.check(schema, conf)
294
+ if not ok then
295
+ return false, err
296
+ end
297
+
298
+ return true
299
+ end
300
+
301
+
302
+ local function get_bearer_access_token(ctx)
303
+ -- Get Authorization header, maybe.
304
+ local auth_header = core.request.header(ctx, "Authorization")
305
+ if not auth_header then
306
+ -- No Authorization header, get X-Access-Token header, maybe.
307
+ local access_token_header = core.request.header(ctx, "X-Access-Token")
308
+ if not access_token_header then
309
+ -- No X-Access-Token header neither.
310
+ return false, nil, nil
311
+ end
312
+
313
+ -- Return extracted header value.
314
+ return true, access_token_header, nil
315
+ end
316
+
317
+ -- Check format of Authorization header.
318
+ local res, err = ngx_re.split(auth_header, " ", nil, nil, 2)
319
+
320
+ if not res then
321
+ -- No result was returned.
322
+ return false, nil, err
323
+ elseif #res < 2 then
324
+ -- Header doesn't split into enough tokens.
325
+ return false, nil, "Invalid Authorization header format."
326
+ end
327
+
328
+ if string.lower(res[1]) == "bearer" then
329
+ -- Return extracted token.
330
+ return true, res[2], nil
331
+ end
332
+
333
+ return false, nil, nil
334
+ end
335
+
336
+
337
+ local function introspect(ctx, conf)
338
+ -- Extract token, maybe.
339
+ local has_token, token, err = get_bearer_access_token(ctx)
340
+
341
+ if err then
342
+ return ngx.HTTP_BAD_REQUEST, err, nil, nil
343
+ end
344
+
345
+ if not has_token then
346
+ -- Could not find token.
347
+
348
+ if conf.bearer_only then
349
+ -- Token strictly required in request.
350
+ ngx.header["WWW-Authenticate"] = 'Bearer realm="' .. conf.realm .. '"'
351
+ return ngx.HTTP_UNAUTHORIZED, "No bearer token found in request.", nil, nil
352
+ else
353
+ -- Return empty result.
354
+ return nil, nil, nil, nil
355
+ end
356
+ end
357
+
358
+ -- If we get here, token was found in request.
359
+
360
+ if conf.public_key or conf.use_jwks then
361
+ -- Validate token against public key or jwks document of the oidc provider.
362
+ -- TODO: In the called method, the openidc module will try to extract
363
+ -- the token by itself again -- from a request header or session cookie.
364
+ -- It is inefficient that we also need to extract it (just from headers)
365
+ -- so we can add it in the configured header. Find a way to use openidc
366
+ -- module's internal methods to extract the token.
367
+ local res, err = openidc.bearer_jwt_verify(conf)
368
+
369
+ if err then
370
+ -- Error while validating or token invalid.
371
+ ngx.header["WWW-Authenticate"] = 'Bearer realm="' .. conf.realm ..
372
+ '", error="invalid_token", error_description="' .. err .. '"'
373
+ return ngx.HTTP_UNAUTHORIZED, err, nil, nil
374
+ end
375
+
376
+ -- Token successfully validated.
377
+ local method = (conf.public_key and "public_key") or (conf.use_jwks and "jwks")
378
+ core.log.debug("token validate successfully by ", method)
379
+ return res, err, token, res
380
+ else
381
+ -- Validate token against introspection endpoint.
382
+ -- TODO: Same as above for public key validation.
383
+ local res, err = openidc.introspect(conf)
384
+
385
+ if err then
386
+ ngx.header["WWW-Authenticate"] = 'Bearer realm="' .. conf.realm ..
387
+ '", error="invalid_token", error_description="' .. err .. '"'
388
+ return ngx.HTTP_UNAUTHORIZED, err, nil, nil
389
+ end
390
+
391
+ -- Token successfully validated and response from the introspection
392
+ -- endpoint contains the userinfo.
393
+ core.log.debug("token validate successfully by introspection")
394
+ return res, err, token, res
395
+ end
396
+ end
397
+
398
+
399
+ local function add_access_token_header(ctx, conf, token)
400
+ if token then
401
+ -- Add Authorization or X-Access-Token header, respectively, if not already set.
402
+ if conf.set_access_token_header then
403
+ if conf.access_token_in_authorization_header then
404
+ if not core.request.header(ctx, "Authorization") then
405
+ -- Add Authorization header.
406
+ core.request.set_header(ctx, "Authorization", "Bearer " .. token)
407
+ end
408
+ else
409
+ if not core.request.header(ctx, "X-Access-Token") then
410
+ -- Add X-Access-Token header.
411
+ core.request.set_header(ctx, "X-Access-Token", token)
412
+ end
413
+ end
414
+ end
415
+ end
416
+ end
417
+
418
+ -- Function to split the scope string into a table
419
+ local function split_scopes_by_space(scope_string)
420
+ local scopes = {}
421
+ for scope in string.gmatch(scope_string, "%S+") do
422
+ scopes[scope] = true
423
+ end
424
+ return scopes
425
+ end
426
+
427
+ -- Function to check if all required scopes are present
428
+ local function required_scopes_present(required_scopes, http_scopes)
429
+ for _, scope in ipairs(required_scopes) do
430
+ if not http_scopes[scope] then
431
+ return false
432
+ end
433
+ end
434
+ return true
435
+ end
436
+
437
+ function _M.rewrite(plugin_conf, ctx)
438
+ local conf = core.table.clone(plugin_conf)
439
+
440
+ -- Previously, we multiply conf.timeout before storing it in etcd.
441
+ -- If the timeout is too large, we should not multiply it again.
442
+ if not (conf.timeout >= 1000 and conf.timeout % 1000 == 0) then
443
+ conf.timeout = conf.timeout * 1000
444
+ end
445
+
446
+ local path = ctx.var.request_uri
447
+
448
+ if not conf.redirect_uri then
449
+ -- NOTE: 'lua-resty-openidc' requires that 'redirect_uri' be
450
+ -- different from 'uri'. So default to append the
451
+ -- '.apisix/redirect' suffix if not configured.
452
+ local suffix = "/.apisix/redirect"
453
+ local uri = ctx.var.uri
454
+ if core.string.has_suffix(uri, suffix) then
455
+ -- This is the redirection response from the OIDC provider.
456
+ conf.redirect_uri = uri
457
+ else
458
+ if string.sub(uri, -1, -1) == "/" then
459
+ conf.redirect_uri = string.sub(uri, 1, -2) .. suffix
460
+ else
461
+ conf.redirect_uri = uri .. suffix
462
+ end
463
+ end
464
+ core.log.debug("auto set redirect_uri: ", conf.redirect_uri)
465
+ end
466
+
467
+ if not conf.ssl_verify then
468
+ -- openidc use "no" to disable ssl verification
469
+ conf.ssl_verify = "no"
470
+ end
471
+
472
+ if path == (conf.logout_path or "/logout") then
473
+ local discovery, discovery_err = openidc.get_discovery_doc(conf)
474
+ if discovery_err then
475
+ core.log.error("OIDC access discovery url failed : ", discovery_err)
476
+ return 503
477
+ end
478
+ if conf.post_logout_redirect_uri and not discovery.end_session_endpoint then
479
+ -- If the end_session_endpoint field does not exist in the OpenID Provider Discovery
480
+ -- Metadata, the redirect_after_logout_uri field is used for redirection.
481
+ conf.redirect_after_logout_uri = conf.post_logout_redirect_uri
482
+ end
483
+ end
484
+
485
+ local response, err, session, _
486
+
487
+ if conf.bearer_only or conf.introspection_endpoint or conf.public_key or conf.use_jwks then
488
+ -- An introspection endpoint or a public key has been configured. Try to
489
+ -- validate the access token from the request, if it is present in a
490
+ -- request header. Otherwise, return a nil response. See below for
491
+ -- handling of the case where the access token is stored in a session cookie.
492
+ local access_token, userinfo
493
+ response, err, access_token, userinfo = introspect(ctx, conf)
494
+
495
+ if err then
496
+ -- Error while validating token or invalid token.
497
+ core.log.error("OIDC introspection failed: ", err)
498
+ return response
499
+ end
500
+
501
+ if response then
502
+ if conf.required_scopes then
503
+ local http_scopes = response.scope and split_scopes_by_space(response.scope) or {}
504
+ local is_authorized = required_scopes_present(conf.required_scopes, http_scopes)
505
+ if not is_authorized then
506
+ core.log.error("OIDC introspection failed: ", "required scopes not present")
507
+ local error_response = {
508
+ error = "required scopes " .. concat(conf.required_scopes, ", ") ..
509
+ " not present"
510
+ }
511
+ return 403, core.json.encode(error_response)
512
+ end
513
+ end
514
+ -- Add configured access token header, maybe.
515
+ add_access_token_header(ctx, conf, access_token)
516
+
517
+ if userinfo and conf.set_userinfo_header then
518
+ -- Set X-Userinfo header to introspection endpoint response.
519
+ core.request.set_header(ctx, "X-Userinfo",
520
+ ngx_encode_base64(core.json.encode(userinfo)))
521
+ end
522
+ end
523
+ end
524
+
525
+ if not response then
526
+ -- Either token validation via introspection endpoint or public key is
527
+ -- not configured, and/or token could not be extracted from the request.
528
+
529
+ local unauth_action = conf.unauth_action
530
+ if unauth_action ~= "auth" then
531
+ unauth_action = "deny"
532
+ end
533
+
534
+ -- Authenticate the request. This will validate the access token if it
535
+ -- is stored in a session cookie, and also renew the token if required.
536
+ -- If no token can be extracted, the response will redirect to the ID
537
+ -- provider's authorization endpoint to initiate the Relying Party flow.
538
+ -- This code path also handles when the ID provider then redirects to
539
+ -- the configured redirect URI after successful authentication.
540
+ response, err, _, session = openidc.authenticate(conf, nil, unauth_action, conf.session)
541
+
542
+ if err then
543
+ if err == "unauthorized request" then
544
+ if conf.unauth_action == "pass" then
545
+ return nil
546
+ end
547
+ return 401
548
+ end
549
+ core.log.error("OIDC authentication failed: ", err)
550
+ return 500
551
+ end
552
+
553
+ if response then
554
+ -- If the openidc module has returned a response, it may contain,
555
+ -- respectively, the access token, the ID token, the refresh token,
556
+ -- and the userinfo.
557
+ -- Add respective headers to the request, if so configured.
558
+
559
+ -- Add configured access token header, maybe.
560
+ add_access_token_header(ctx, conf, response.access_token)
561
+
562
+ -- Add X-ID-Token header, maybe.
563
+ if response.id_token and conf.set_id_token_header then
564
+ local token = core.json.encode(response.id_token)
565
+ core.request.set_header(ctx, "X-ID-Token", ngx.encode_base64(token))
566
+ end
567
+
568
+ -- Add X-Userinfo header, maybe.
569
+ if response.user and conf.set_userinfo_header then
570
+ core.request.set_header(ctx, "X-Userinfo",
571
+ ngx_encode_base64(core.json.encode(response.user)))
572
+ end
573
+
574
+ -- Add X-Refresh-Token header, maybe.
575
+ if session.data.refresh_token and conf.set_refresh_token_header then
576
+ core.request.set_header(ctx, "X-Refresh-Token", session.data.refresh_token)
577
+ end
578
+ end
579
+ end
580
+ if session then
581
+ session:close()
582
+ end
583
+ end
584
+
585
+
586
+ return _M
587
+ """###
@@ -0,0 +1,26 @@
1
+
2
+ // Automatically generated file. Do not edit.
3
+ package service
4
+
5
+ import (
6
+ k "kumori.systems/kumori/@1.1.6:kumori"
7
+ m "...:kmodule"
8
+ )
9
+
10
+
11
+
12
+ #Artifact: k.#Artifact & {
13
+ spec: m.spec
14
+ ref: {
15
+ version: m.version
16
+ if m.prerelease != _|_ {
17
+ prerelease: m.prerelease
18
+ }
19
+ if m.buildmetadata != _|_ {
20
+ buildmetadata: m.buildmetadata
21
+ }
22
+ domain: m.domain
23
+ module: m.module
24
+ kind: "service"
25
+ }
26
+ }
@@ -0,0 +1,33 @@
1
+ package settings
2
+
3
+ import (
4
+ Types ".../settings/types"
5
+ )
6
+
7
+
8
+
9
+ // https://apisix.apache.org/docs/apisix/deployment-modes/#standalone
10
+ #ApisixConfig: {
11
+ deployment: {
12
+ role: string | *"data_plane"
13
+ role_data_plane: config_provider: string | *"yaml"
14
+ }
15
+ apisix: {
16
+ enable_admin: false
17
+ config_center: "yaml"
18
+ }
19
+ }
20
+
21
+ #ApisixStandalone: {
22
+ routes?: Types.#Routes
23
+ services?: Types.#Services
24
+ upstreams?: Types.#Upstreams
25
+ plugins?: Types.#Plugins // List of plugins to load
26
+ plugin_configs?: Types.#PluginConfigs
27
+ ssls?: Types.#Ssls
28
+ stream_routes?: Types.#StreamRoutes
29
+ global_rules?: Types.#GlobalRules
30
+ consumers?: Types.#Consumers
31
+ plugin_metadata?: Types.#PluginsMetadata
32
+ ...
33
+ }
@@ -0,0 +1,38 @@
1
+ package settings
2
+
3
+ #Entrypoint: ##"""
4
+ #!/usr/bin/env sh
5
+
6
+ set -x
7
+
8
+ apt update
9
+ apt-get install -y gettext-base
10
+ apt-get install -y inotify-tools
11
+
12
+ path="/tmp/apisix.yaml"
13
+
14
+ processApisixConfig() {
15
+ envsubst < /tmp/apisix.yaml > /tmp/apisix.yaml.tmp
16
+ echo "#END" >> /tmp/apisix.yaml.tmp
17
+
18
+ mv /tmp/apisix.yaml.tmp /usr/local/apisix/conf/apisix.yaml
19
+ }
20
+
21
+ processApisixConfig
22
+
23
+ # Wait for changes to the Apisix config file.
24
+ # This helps to laverage hot reloading in APISIX
25
+ while true; do
26
+ inotifywait -e modify "$path"
27
+ echo "$path was modified"
28
+ processApisixConfig
29
+ done &
30
+
31
+ set +x
32
+
33
+ if [ "$#" -eq 0 ]; then
34
+ exec apisix start
35
+ else
36
+ exec "$@"
37
+ fi
38
+ """##