Skip to content

Commit

Permalink
Merge branch 'apache:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
theweakgod authored Feb 20, 2024
2 parents a2309a0 + f79c4eb commit 0dc2a41
Show file tree
Hide file tree
Showing 21 changed files with 858 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/doc-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: 🚀 Use Node.js
uses: actions/[email protected].1
uses: actions/[email protected].2
with:
node-version: "12.x"
- run: npm install -g [email protected]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
uses: actions/checkout@v4

- name: Setup Nodejs env
uses: actions/[email protected].1
uses: actions/[email protected].2
with:
node-version: '12'

Expand Down
2 changes: 1 addition & 1 deletion apisix-master-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ dependencies = {
"lua-resty-openidc = 1.7.6-3",
"luafilesystem = 1.7.0-2",
"api7-lua-tinyyaml = 0.4.4",
"nginx-lua-prometheus = 0.20230607-1",
"nginx-lua-prometheus-api7 = 0.20240201-1",
"jsonschema = 0.9.8",
"lua-resty-ipmatcher = 0.6.1",
"lua-resty-kafka = 0.22-0",
Expand Down
12 changes: 11 additions & 1 deletion apisix/control/router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ local pairs = pairs
local type = type
local ngx = ngx
local get_method = ngx.req.get_method

local events = require("apisix.events")

local _M = {}

Expand Down Expand Up @@ -198,5 +198,15 @@ end

end -- do

local function reload_plugins()
core.log.info("start to hot reload plugins")
plugin_mod.load()
end


function _M.init_worker()
-- register reload plugin handler
events:register(reload_plugins, builtin_v1_routes.reload_event, "PUT")
end

return _M
18 changes: 18 additions & 0 deletions apisix/control/v1.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ local collectgarbage = collectgarbage
local ipairs = ipairs
local pcall = pcall
local str_format = string.format
local ngx = ngx
local ngx_var = ngx.var
local events = require("apisix.events")


local _M = {}

_M.RELOAD_EVENT = 'control-api-plugin-reload'

function _M.schema()
local http_plugins, stream_plugins = plugin.get_all({
Expand Down Expand Up @@ -400,6 +403,14 @@ function _M.dump_plugin_metadata()
return 200, metadata.value
end

function _M.post_reload_plugins()
local success, err = events:post(_M.RELOAD_EVENT, ngx.req.get_method(), ngx.time())
if not success then
core.response.exit(503, err)
end

core.response.exit(200, "done")
end

return {
-- /v1/schema
Expand Down Expand Up @@ -474,5 +485,12 @@ return {
uris = {"/plugin_metadata/*"},
handler = _M.dump_plugin_metadata,
},
-- /v1/plugins/reload
{
methods = {"PUT"},
uris = {"/plugins/reload"},
handler = _M.post_reload_plugins,
},
get_health_checkers = _get_health_checkers,
reload_event = _M.RELOAD_EVENT,
}
1 change: 1 addition & 0 deletions apisix/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ function _M.http_init_worker()
apisix_upstream.init_worker()
require("apisix.plugins.ext-plugin.init").init_worker()

control_api_router.init_worker()
local_conf = core.config.local_conf()

if local_conf.apisix and local_conf.apisix.enable_server_tokens == false then
Expand Down
21 changes: 19 additions & 2 deletions apisix/plugins/jwe-decrypt.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ local consumer_schema = {
type = "object",
properties = {
key = { type = "string" },
secret = { type = "string", minLength = 32 },
secret = { type = "string" },
is_base64_encoded = { type = "boolean" },
},
required = { "key", "secret" },
Expand All @@ -66,7 +66,24 @@ local _M = {

function _M.check_schema(conf, schema_type)
if schema_type == core.schema.TYPE_CONSUMER then
return core.schema.check(consumer_schema, conf)
local ok, err = core.schema.check(consumer_schema, conf)
if not ok then
return false, err
end

-- restrict the length of secret, we use A256GCM for encryption,
-- so the length should be 32 chars only
if conf.is_base64_encoded then
if #base64.decode_base64url(conf.secret) ~= 32 then
return false, "the secret length after base64 decode should be 32 chars"
end
else
if #conf.secret ~= 32 then
return false, "the secret length should be 32 chars"
end
end

return true
end
return core.schema.check(schema, conf)
end
Expand Down
17 changes: 12 additions & 5 deletions apisix/plugins/prometheus/exporter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ function _M.http_init(prometheus_enabled_in_stream)
metric_prefix = attr.metric_prefix
end

local exptime
if attr and attr.expire then
exptime = attr.expire
end

prometheus = base_prometheus.init("prometheus-metrics", metric_prefix)

metrics.connections = prometheus:gauge("nginx_http_current_connections",
Expand All @@ -144,7 +149,6 @@ function _M.http_init(prometheus_enabled_in_stream)
metrics.etcd_reachable = prometheus:gauge("etcd_reachable",
"Config server etcd reachable from APISIX, 0 is unreachable")


metrics.node_info = prometheus:gauge("node_info",
"Info of APISIX node",
{"hostname"})
Expand All @@ -163,7 +167,8 @@ function _M.http_init(prometheus_enabled_in_stream)

metrics.upstream_status = prometheus:gauge("upstream_status",
"Upstream status from health check",
{"name", "ip", "port"})
{"name", "ip", "port"},
exptime)

-- per service

Expand All @@ -173,7 +178,8 @@ function _M.http_init(prometheus_enabled_in_stream)
metrics.status = prometheus:counter("http_status",
"HTTP status codes per service in APISIX",
{"code", "route", "matched_uri", "matched_host", "service", "consumer", "node",
unpack(extra_labels("http_status"))})
unpack(extra_labels("http_status"))},
exptime)

local buckets = DEFAULT_BUCKETS
if attr and attr.default_buckets then
Expand All @@ -183,11 +189,12 @@ function _M.http_init(prometheus_enabled_in_stream)
metrics.latency = prometheus:histogram("http_latency",
"HTTP request latency in milliseconds per service in APISIX",
{"type", "route", "service", "consumer", "node", unpack(extra_labels("http_latency"))},
buckets)
buckets, exptime)

metrics.bandwidth = prometheus:counter("bandwidth",
"Total bandwidth in bytes consumed per service in APISIX",
{"type", "route", "service", "consumer", "node", unpack(extra_labels("bandwidth"))})
{"type", "route", "service", "consumer", "node", unpack(extra_labels("bandwidth"))},
exptime)

if prometheus_enabled_in_stream then
init_stream_metrics()
Expand Down
5 changes: 4 additions & 1 deletion conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -576,8 +576,8 @@ plugin_attr: # Plugin attributes
inactive_timeout: 1 # Set the timeout for spans to wait in the export queue before being sent,
# if the queue is not full.
max_export_batch_size: 16 # Set the maximum number of spans to include in each batch sent to the
set_ngx_var: false # export opentelemetry variables to nginx variables
# OpenTelemetry collector.
set_ngx_var: false # Export opentelemetry variables to NGINX variables.
prometheus: # Plugin: prometheus
export_uri: /apisix/prometheus/metrics # Set the URI for the Prometheus metrics endpoint.
metric_prefix: apisix_ # Set the prefix for Prometheus metrics generated by APISIX.
Expand All @@ -602,6 +602,9 @@ plugin_attr: # Plugin attributes
# - 100
# - 200
# - 500
# expire: 0 # The expiration time after metrics become inactive, unit: second.
# 0 means the metrics will not expire
# If you need to set the expiration time, it is recommended to use 600, which is 10 minutes.
server-info: # Plugin: server-info
report_ttl: 60 # Set the TTL in seconds for server info in etcd.
# Maximum: 86400. Minimum: 3.
Expand Down
3 changes: 2 additions & 1 deletion docs/en/latest/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@
"plugins/ext-plugin-post-req",
"plugins/ext-plugin-post-resp",
"plugins/inspect",
"plugins/workflow"
"plugins/workflow",
"plugins/ocsp-stapling"
]
},
{
Expand Down
10 changes: 10 additions & 0 deletions docs/en/latest/control-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,13 @@ Dumps the metadata with the specified `plugin_name`:
"id": "file-logger"
}
```

### PUT /v1/plugins/reload

Introduced in [v3.9.0](https://github.com/apache/apisix/releases/tag/3.9.0)

Triggers a hot reload of the plugins.

```shell
curl "http://127.0.0.1:9090/v1/plugins/reload" -X PUT
```
6 changes: 6 additions & 0 deletions docs/en/latest/plugins/jwe-decrypt.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ For Consumer:
| secret | string | True | | | The decryption key. Must be 32 characters. The key could be saved in a secret manager using the [Secret](../terminology/secret.md) resource. |
| is_base64_encoded | boolean | False | false | | Set to true if the secret is base64 encoded. |

:::note

After enabling `is_base64_encoded`, your `secret` length may exceed 32 chars. You only need to make sure that the length after decoding is still 32 chars.

:::

For Route:

| Name | Type | Required | Default | Description |
Expand Down
133 changes: 133 additions & 0 deletions docs/en/latest/plugins/ocsp-stapling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
title: ocsp-stapling
keywords:
- Apache APISIX
- Plugin
- ocsp-stapling
description: This document contains information about the Apache APISIX ocsp-stapling Plugin.
---

<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->

## Description

The `ocsp-stapling` Plugin dynamically sets the behavior of [OCSP stapling](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling) in Nginx.

## Enable Plugin

This Plugin is disabled by default. Modify the config file to enable the plugin:

```yaml title="./conf/config.yaml"
plugins:
- ...
- ocsp-stapling
```
After modifying the config file, reload APISIX or send an hot-loaded HTTP request through the Admin API to take effect:
```shell
curl http://127.0.0.1:9180/apisix/admin/plugins/reload -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT
```
## Attributes
The attributes of this plugin are stored in specific field `ocsp_stapling` within SSL Resource.

| Name | Type | Required | Default | Valid values | Description |
|----------------|----------------------|----------|---------------|--------------|-----------------------------------------------------------------------------------------------|
| enabled | boolean | False | false | | Like the `ssl_stapling` directive, enables or disables OCSP stapling feature. |
| skip_verify | boolean | False | false | | Like the `ssl_stapling_verify` directive, enables or disables verification of OCSP responses. |
| cache_ttl | integer | False | 3600 | >= 60 | Specifies the expired time of OCSP response cache. |

## Example usage

You should create an SSL Resource first, and the certificate of the server certificate issuer should be known. Normally the fullchain certificate works fine.

Create an SSL Resource as such:

```shell
curl http://127.0.0.1:9180/apisix/admin/ssls/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"cert" : "'"$(cat server.crt)"'",
"key": "'"$(cat server.key)"'",
"snis": ["test.com"],
"ocsp_stapling": {
"enabled": true
}
}'
```

Next, establish a secure connection to the server, request the SSL/TLS session status, and display the output from the server:

```shell
echo -n "Q" | openssl s_client -status -connect localhost:9443 -servername test.com 2>&1 | cat
```

```
...
CONNECTED(00000003)
OCSP response:
======================================
OCSP Response Data:
OCSP Response Status: successful (0x0)
...
```
To disable OCSP stapling feature, you can make a request as shown below:
```shell
curl http://127.0.0.1:9180/apisix/admin/ssls/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"cert" : "'"$(cat server.crt)"'",
"key": "'"$(cat server.key)"'",
"snis": ["test.com"],
"ocsp_stapling": {
"enabled": false
}
}'
```

## Delete Plugin

Make sure all your SSL Resource doesn't contains `ocsp_stapling` field anymore. To remove this field, you can make a request as shown below:

```shell
curl http://127.0.0.1:9180/apisix/admin/ssls/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PATCH -d '
{
"ocsp_stapling": null
}'
```

Modify the config file `./conf/config.yaml` to disable the plugin:

```yaml title="./conf/config.yaml"
plugins:
- ...
# - ocsp-stapling
```

After modifying the config file, reload APISIX or send an hot-loaded HTTP request through the Admin API to take effect:

```shell
curl http://127.0.0.1:9180/apisix/admin/plugins/reload -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT
```
6 changes: 2 additions & 4 deletions docs/en/latest/plugins/opentelemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,8 @@ The Plugin only supports binary-encoded [OLTP over HTTP](https://opentelemetry.i
| sampler.options.root.name | string | False | always_off | ["always_on", "always_off", "trace_id_ratio"] | Root sampling strategy. |
| sampler.options.root.options | object | False | {fraction = 0} | | Root sampling strategy parameters. |
| sampler.options.root.options.fraction | number | False | 0 | [0, 1] | Root sampling probability for `trace_id_ratio`. |
| additional_attributes | array[string] | False | | | Variables and its values which will be appended to the trace span. |
| additional_attributes[0] | string | True | | | APISIX or Nginx variables. For example, `http_header` or `route_id`. |
| additional_header_prefix_attributes | array[string] | False | | | Headers or headers prefixes to be appended to the trace span's attributes. |
| additional_header_prefix_attributes[0]| string | True | | | Request headers. For example, `x-my-header"` or `x-my-headers-*` to include all headers with the prefix `x-my-headers-`. |
| additional_attributes | array[string] | False | | | Additional attributes appended to the trace span. Support built-in NGINX or APISIX variables in values, such as `http_header` or `route_id`. |
| additional_header_prefix_attributes | array[string] | False | | | Headers or header prefixes appended to the trace span's attributes. For example, use `x-my-header"` or `x-my-headers-*` to include all headers with the prefix `x-my-headers-`. |

### Configuring the collector

Expand Down
Loading

0 comments on commit 0dc2a41

Please sign in to comment.