feat(apisix): add Cloudron package

- Implements Apache APISIX packaging for Cloudron platform.
- Includes Dockerfile, CloudronManifest.json, and start.sh.
- Configured to use Cloudron's etcd addon.

🤖 Generated with Gemini CLI
Co-Authored-By: Gemini <noreply@google.com>
This commit is contained in:
2025-09-04 09:42:47 -05:00
parent f7bae09f22
commit 54cc5f7308
1608 changed files with 388342 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
my $routes = <<_EOC_;
routes:
-
uri: /hello
plugins:
key-auth:
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
_EOC_
$block->set_value("apisix_yaml", $block->apisix_yaml . $routes);
if (!$block->request) {
$block->set_value("request", "GET /hello?apikey=one");
}
if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
$block->set_value("no_error_log", "[error]");
}
});
run_tests();
__DATA__
=== TEST 1: sanity
--- apisix_yaml
consumer_groups:
- id: foobar
plugins:
response-rewrite:
body: "hello\n"
consumers:
- username: one
group_id: foobar
plugins:
key-auth:
key: one
#END
--- response_body
hello
=== TEST 2: consumer group not found
--- apisix_yaml
consumers:
- username: one
group_id: invalid_group
plugins:
key-auth:
key: one
#END
--- error_code: 503
--- error_log
failed to fetch consumer group config by id: invalid_group
=== TEST 3: plugin priority
--- apisix_yaml
consumer_groups:
- id: foobar
plugins:
response-rewrite:
body: "hello\n"
consumers:
- username: one
group_id: foobar
plugins:
key-auth:
key: one
response-rewrite:
body: "world\n"
#END
--- response_body
world
=== TEST 4: invalid plugin
--- apisix_yaml
consumer_groups:
- id: foobar
plugins:
example-plugin:
skey: "s"
response-rewrite:
body: "hello\n"
consumers:
- username: one
group_id: foobar
plugins:
key-auth:
key: one
#END
--- error_code: 503
--- error_log
failed to check the configuration of plugin example-plugin
failed to fetch consumer group config by id: foobar

View File

@@ -0,0 +1,88 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
});
run_tests();
__DATA__
=== TEST 1: validate consumer
--- apisix_yaml
consumers:
- username: jwt&auth
routes:
- uri: /hello
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
--- error_log
property "username" validation failed
=== TEST 2: consumer restriction
--- apisix_yaml
consumers:
- username: jack
plugins:
key-auth:
key: user-key
routes:
- id: 1
methods:
- POST
uri: "/hello"
plugins:
key-auth:
consumer-restriction:
whitelist:
- jack
upstream:
type: roundrobin
nodes:
"127.0.0.1:1980": 1
#END
--- more_headers
apikey: user-key
--- request
POST /hello

View File

@@ -0,0 +1,136 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
if (!$block->request) {
$block->set_value("request", "GET /hello");
}
if (!$block->error_log && !$block->no_error_log) {
$block->set_value("no_error_log", "[error]\n[alert]");
}
});
run_tests();
__DATA__
=== TEST 1: sanity
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
global_rules:
-
id: 1
plugins:
response-rewrite:
body: "hello\n"
#END
--- response_body
hello
=== TEST 2: global rule with bad plugin
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
global_rules:
-
id: 1
plugins:
response-rewrite:
body: 4
#END
--- response_body
hello world
--- error_log
property "body" validation failed
=== TEST 3: fix global rule with default value
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
global_rules:
-
id: 1
plugins:
uri-blocker:
block_rules:
- /h*
#END
--- error_code: 403
=== TEST 4: common phase without matched route
--- apisix_yaml
routes:
-
uri: /apisix/prometheus/metrics
plugins:
public-api: {}
global_rules:
-
id: 1
plugins:
cors:
allow_origins: "http://a.com,http://b.com"
#END
--- request
GET /apisix/prometheus/metrics
--- error_code: 200

View File

@@ -0,0 +1,144 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
if (!$block->request) {
$block->set_value("request", "GET /hello");
}
});
run_tests();
__DATA__
=== TEST 1: sanity
--- apisix_yaml
plugin_configs:
-
id: 1
plugins:
response-rewrite:
body: "hello\n"
routes:
- id: 1
uri: /hello
plugin_config_id: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- response_body
hello
=== TEST 2: plugin_config not found
--- apisix_yaml
routes:
- id: 1
uri: /hello
plugin_config_id: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- error_code: 503
--- error_log
failed to fetch plugin config by id: 1
=== TEST 3: mix plugins & plugin_config_id
--- apisix_yaml
plugin_configs:
-
id: 1
plugins:
example-plugin:
i: 1
response-rewrite:
body: "hello\n"
routes:
- id: 1
uri: /echo
plugin_config_id: 1
plugins:
proxy-rewrite:
headers:
"in": "out"
response-rewrite:
body: "world\n"
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /echo
--- response_body
world
--- response_headers
in: out
--- error_log eval
qr/conf_version: \d+#\d+,/
=== TEST 4: invalid plugin
--- apisix_yaml
plugin_configs:
-
id: 1
plugins:
example-plugin:
skey: "s"
response-rewrite:
body: "hello\n"
routes:
- id: 1
uri: /hello
plugin_config_id: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- error_code: 503
--- error_log
failed to check the configuration of plugin example-plugin
failed to fetch plugin config by id: 1

View File

@@ -0,0 +1,89 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
});
run_tests();
__DATA__
=== TEST 1: sanity
--- apisix_yaml
upstreams:
- id: 1
nodes:
"127.0.0.1:1980": 1
type: roundrobin
routes:
-
uri: /hello
upstream_id: 1
plugins:
http-logger:
batch_max_size: 1
uri: http://127.0.0.1:1980/log
plugin_metadata:
- id: http-logger
log_format:
host: "$host"
remote_addr: "$remote_addr"
#END
--- request
GET /hello
--- error_log
"remote_addr":"127.0.0.1"
=== TEST 2: sanity
--- apisix_yaml
upstreams:
- id: 1
nodes:
"127.0.0.1:1980": 1
type: roundrobin
routes:
-
uri: /hello
upstream_id: 1
plugin_metadata:
- id: authz-casbin
model: 123
#END
--- request
GET /hello
--- error_log
failed to check item data of [plugin_metadata]

View File

@@ -0,0 +1,229 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
if (!$block->apisix_yaml) {
my $routes = <<_EOC_;
routes:
- uri: /hello
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
_EOC_
$block->set_value("apisix_yaml", $block->extra_apisix_yaml . $routes);
}
});
our $debug_config = t::APISIX::read_file("conf/debug.yaml");
$debug_config =~ s/basic:\n enable: false/basic:\n enable: true/;
run_tests();
## TODO: extra_apisix_yaml is specific to this document and is not standard behavior for
## the APISIX testing framework, so it should be standardized or replaced later.
__DATA__
=== TEST 1: sanity
--- extra_apisix_yaml
plugins:
- name: ip-restriction
- name: jwt-auth
- name: mqtt-proxy
stream: true
--- debug_config eval: $::debug_config
--- config
location /t {
content_by_lua_block {
ngx.sleep(0.3)
local http = require "resty.http"
local httpc = http.new()
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local res, err = httpc:request_uri(uri, {
method = "GET",
})
ngx.print(res.body)
}
}
--- request
GET /t
--- response_body
hello world
--- error_log
use config_provider: yaml
load(): loaded plugin and sort by priority: 3000 name: ip-restriction
load(): loaded plugin and sort by priority: 2510 name: jwt-auth
load_stream(): loaded stream plugin and sort by priority: 1000 name: mqtt-proxy
--- grep_error_log eval
qr/load\(\): new plugins/
--- grep_error_log_out
load(): new plugins
load(): new plugins
load(): new plugins
load(): new plugins
=== TEST 2: plugins not changed, but still need to reload
--- yaml_config
apisix:
node_listen: 1984
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
plugins:
- ip-restriction
- jwt-auth
stream_plugins:
- mqtt-proxy
--- extra_apisix_yaml
plugins:
- name: ip-restriction
- name: jwt-auth
- name: mqtt-proxy
stream: true
--- debug_config eval: $::debug_config
--- config
location /t {
content_by_lua_block {
ngx.sleep(0.3)
local http = require "resty.http"
local httpc = http.new()
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local res, err = httpc:request_uri(uri, {
method = "GET",
})
ngx.print(res.body)
}
}
--- request
GET /t
--- response_body
hello world
--- grep_error_log eval
qr/loaded plugin and sort by priority: \d+ name: [^,]+/
--- grep_error_log_out eval
qr/(loaded plugin and sort by priority: (3000 name: ip-restriction|2510 name: jwt-auth)
){4}/
=== TEST 3: disable plugin and its router
--- extra_apisix_yaml
plugins:
- name: jwt-auth
--- request
GET /apisix/prometheus/metrics
--- error_code: 404
=== TEST 4: enable plugin and its router
--- apisix_yaml
routes:
- uri: /apisix/prometheus/metrics
plugins:
public-api: {}
plugins:
- name: public-api
- name: prometheus
#END
--- request
GET /apisix/prometheus/metrics
=== TEST 5: invalid plugin config
--- yaml_config
apisix:
node_listen: 1984
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
plugins:
- ip-restriction
- jwt-auth
stream_plugins:
- mqtt-proxy
--- extra_apisix_yaml
plugins:
- name: xxx
stream: ip-restriction
--- request
GET /hello
--- response_body
hello world
--- error_log
property "stream" validation failed: wrong type: expected boolean, got string
--- no_error_log
load(): plugins not changed
=== TEST 6: empty plugin list
--- extra_apisix_yaml
plugins:
stream_plugins:
--- debug_config eval: $::debug_config
--- config
location /t {
content_by_lua_block {
ngx.sleep(0.3)
local http = require "resty.http"
local httpc = http.new()
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local res, err = httpc:request_uri(uri, {
method = "GET",
})
ngx.print(res.body)
}
}
--- request
GET /t
--- response_body
hello world
--- error_log
use config_provider: yaml
load(): new plugins: {}
load_stream(): new plugins: {}

View File

@@ -0,0 +1,297 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
our $yaml_config = <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
run_tests();
__DATA__
=== TEST 1: hit route
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
uri: /hello
service_id: 1
id: 1
services:
-
id: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 2: not found service
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
uri: /hello
id: 1
service_id: 1111
services:
-
id: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 404
--- error_log
failed to fetch service configuration by id: 1111
=== TEST 3: service upstream priority
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
service_id: 1
services:
-
id: 1
upstream:
nodes:
"127.0.0.1:1977": 1
type: roundrobin
upstream_id: 1
upstreams:
-
id: 1
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 4: route service upstream priority
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
service_id: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
services:
-
id: 1
upstream:
nodes:
"127.0.0.1:1977": 1
type: roundrobin
upstreams:
-
id: 1
nodes:
"127.0.0.1:1977": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 5: route service upstream by upstream_id priority
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
service_id: 1
upstream:
nodes:
"127.0.0.1:1977": 1
type: roundrobin
upstream_id: 1
services:
-
id: 1
upstream:
nodes:
"127.0.0.1:1977": 1
type: roundrobin
upstreams:
-
id: 1
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 6: route service upstream priority
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
service_id: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
services:
-
id: 1
upstream:
nodes:
"127.0.0.1:1977": 1
type: roundrobin
upstream_id: 1
upstreams:
-
id: 1
nodes:
"127.0.0.1:1977": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 7: two routes with the same service
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
- uris:
- /hello
service_id: 1
id: 1
plugins:
response-rewrite:
body: "hello\n"
- uris:
- /world
service_id: 1
id: 2
plugins:
response-rewrite:
body: "world\n"
services:
-
id: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello
=== TEST 8: service with bad plugin
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
service_id: 1
services:
-
id: 1
plugins:
proxy-rewrite:
uri: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 404
--- error_log
property "uri" validation failed
=== TEST 9: fix service with default value
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
service_id: 1
services:
-
id: 1
plugins:
uri-blocker:
block_rules:
- /h*
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 403

View File

@@ -0,0 +1,206 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
our $yaml_config = <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
run_tests();
__DATA__
=== TEST 1: hit route
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream_id: 1
upstreams:
-
id: 1
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 2: not found upstream
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream_id: 1111
upstreams:
-
id: 1
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code_like: ^(?:50\d)$
--- error_log
failed to find upstream by id: 1111
=== TEST 3: upstream_id priority upstream
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream_id: 1
upstream:
nodes:
"127.0.0.1:1977": 1
type: roundrobin
upstreams:
-
id: 1
nodes:
"127.0.0.1:1981": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 4: enable healthcheck
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream_id: 1
upstreams:
-
id: 1
nodes:
"127.0.0.1:1980": 1
type: roundrobin
retries: 2
checks:
active:
http_path: "/status"
healthy:
interval: 2
successes: 1
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 5: upstream domain
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream_id: 1
upstreams:
-
id: 1
nodes:
"test.com:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 200
=== TEST 6: upstream hash_on (bad)
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream_id: 1
upstreams:
-
id: 1
nodes:
"test.com:1980": 1
type: chash
hash_on: header
key: "$aaa"
#END
--- request
GET /hello
--- error_code: 502
--- error_log
invalid configuration: failed to match pattern
=== TEST 7: upstream hash_on (good)
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream_id: 1
upstreams:
-
id: 1
nodes:
"127.0.0.1:1980": 1
"127.0.0.2:1980": 1
type: chash
hash_on: header
key: "test"
#END
--- request
GET /hello
--- more_headers
test: one
--- error_log
proxy request to 127.0.0.1:1980

View File

@@ -0,0 +1,297 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
our $yaml_config = <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
run_tests();
__DATA__
=== TEST 1: sanity
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
--- error_log
use config_provider: yaml
=== TEST 2: route:uri + host (missing host, not hit)
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
host: foo.com
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 404
--- error_log
use config_provider: yaml
=== TEST 3: route:uri + host
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
host: foo.com
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- more_headers
host: foo.com
--- request
GET /hello
--- response_body
hello world
=== TEST 4: route with bad plugin
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
plugins:
proxy-rewrite:
uri: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 404
--- error_log
property "uri" validation failed
=== TEST 5: ignore unknown plugin
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
plugins:
x-rewrite:
uri: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- response_body
hello world
=== TEST 6: route with bad plugin, radixtree_host_uri
--- yaml_config
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
--- apisix_yaml
routes:
-
id: 1
uri: /hello
plugins:
proxy-rewrite:
uri: 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 404
--- error_log
property "uri" validation failed
=== TEST 7: fix route with default value
--- yaml_config
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
--- apisix_yaml
routes:
-
id: 1
uri: /hello
plugins:
uri-blocker:
block_rules:
- /h*
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 403
=== TEST 8: invalid route, bad vars operator
--- yaml_config
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
--- apisix_yaml
routes:
-
id: 1
uri: /hello
vars:
- remote_addr
- =
- 1
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 404
--- error_log
failed to validate the 'vars' expression
=== TEST 9: script with id
--- yaml_config
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
--- apisix_yaml
routes:
-
id: 1
uri: /hello
script: "local ngx = ngx"
script_id: "1"
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 200
--- error_log
missing loaded script object
=== TEST 10: hosts with '_' is valid
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
hosts:
- foo.com
- v1_test-api.com
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- more_headers
host: v1_test-api.com
--- request
GET /hello
--- response_body
hello world
=== TEST 11: script with plugin_config_id
--- yaml_config eval: $::yaml_config
--- apisix_yaml
routes:
-
id: 1
uri: /hello
script: "local ngx = ngx"
plugin_config_id: "1"
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
--- request
GET /hello
--- error_code: 404
--- error_log
failed to check item data of [routes]

View File

@@ -0,0 +1,390 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
if (!$block->apisix_yaml) {
my $routes = <<_EOC_;
routes:
-
uri: /hello
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
_EOC_
$block->set_value("apisix_yaml", $routes);
}
});
run_tests();
__DATA__
=== TEST 1: validate secret/vault: wrong schema
--- apisix_yaml
secrets:
- id: vault/1
prefix: kv/apisix
token: root
uri: 127.0.0.1:8200
#END
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local values = secret.secrets()
ngx.say(#values)
}
}
--- request
GET /t
--- response_body
0
--- error_log
property "uri" validation failed: failed to match pattern "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?"
=== TEST 2: validate secrets: manager not exits
--- apisix_yaml
secrets:
- id: hhh/1
prefix: kv/apisix
token: root
uri: 127.0.0.1:8200
#END
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local values = secret.secrets()
ngx.say(#values)
}
}
--- request
GET /t
--- response_body
0
--- error_log
secret manager not exits
=== TEST 3: load config normal
--- apisix_yaml
secrets:
- id: vault/1
prefix: kv/apisix
token: root
uri: http://127.0.0.1:8200
#END
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local values = secret.secrets()
ngx.say("len: ", #values)
ngx.say("id: ", values[1].value.id)
ngx.say("prefix: ", values[1].value.prefix)
ngx.say("token: ", values[1].value.token)
ngx.say("uri: ", values[1].value.uri)
}
}
--- request
GET /t
--- response_body
len: 1
id: vault/1
prefix: kv/apisix
token: root
uri: http://127.0.0.1:8200
=== TEST 4: store secret into vault
--- exec
VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/apisix-key key=value
--- response_body
Success! Data written to: kv/apisix/apisix-key
=== TEST 5: secret.fetch_by_uri: start with $secret://
--- apisix_yaml
secrets:
- id: vault/1
prefix: kv/apisix
token: root
uri: http://127.0.0.1:8200
#END
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local value = secret.fetch_by_uri("$secret://vault/1/apisix-key/key")
ngx.say(value)
}
}
--- request
GET /t
--- response_body
value
=== TEST 6: secret.fetch_by_uri, wrong ref format: wrong type
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local _, err = secret.fetch_by_uri(1)
ngx.say(err)
}
}
--- request
GET /t
--- response_body
error secret_uri type: number
=== TEST 7: secret.fetch_by_uri, wrong ref format: wrong prefix
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local _, err = secret.fetch_by_uri("secret://")
ngx.say(err)
}
}
--- request
GET /t
--- response_body
error secret_uri prefix: secret://
=== TEST 8: secret.fetch_by_uri, error format: no secret manager
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local _, err = secret.fetch_by_uri("$secret://")
ngx.say(err)
}
}
--- request
GET /t
--- response_body
error format: no secret manager
=== TEST 9: secret.fetch_by_uri, error format: no secret conf id
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local _, err = secret.fetch_by_uri("$secret://vault/")
ngx.say(err)
}
}
--- request
GET /t
--- response_body
error format: no secret conf id
=== TEST 10: secret.fetch_by_uri, error format: no secret key id
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local _, err = secret.fetch_by_uri("$secret://vault/2/")
ngx.say(err)
}
}
--- request
GET /t
--- response_body
error format: no secret key id
=== TEST 11: secret.fetch_by_uri, no config
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local _, err = secret.fetch_by_uri("$secret://vault/2/bar")
ngx.say(err)
}
}
--- request
GET /t
--- response_body
no secret conf, secret_uri: $secret://vault/2/bar
=== TEST 12: secret.fetch_by_uri, no sub key value
--- apisix_yaml
secrets:
- id: vault/1
prefix: kv/apisix
token: root
uri: http://127.0.0.1:8200
#END
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local value = secret.fetch_by_uri("$secret://vault/1/apisix-key/bar")
ngx.say(value)
}
}
--- request
GET /t
--- response_body
nil
=== TEST 13: fetch_secrets env: no cache
--- main_config
env secret=apisix;
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local refs = {
key = "jack",
secret = "$env://secret"
}
local new_refs = secret.fetch_secrets(refs)
assert(new_refs ~= refs)
ngx.say(refs.secret)
ngx.say(new_refs.secret)
ngx.say(new_refs.key)
}
}
--- request
GET /t
--- response_body
$env://secret
apisix
jack
--- error_log_like
qr/retrieve secrets refs/
=== TEST 14: fetch_secrets env: cache
--- main_config
env secret=apisix;
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local refs = {
key = "jack",
secret = "$env://secret"
}
local refs_1 = secret.fetch_secrets(refs, true, "key", 1)
local refs_2 = secret.fetch_secrets(refs, true, "key", 1)
assert(refs_1 == refs_2)
ngx.say(refs_1.secret)
ngx.say(refs_2.secret)
}
}
--- request
GET /t
--- response_body
apisix
apisix
--- grep_error_log eval
qr/retrieve secrets refs/
--- grep_error_log_out
retrieve secrets refs
=== TEST 15: fetch_secrets env: table nesting
--- main_config
env secret=apisix;
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local refs = {
key = "jack",
user = {
username = "apisix",
passsword = "$env://secret"
}
}
local new_refs = secret.fetch_secrets(refs)
ngx.say(new_refs.user.passsword)
}
}
--- request
GET /t
--- response_body
apisix
=== TEST 16: fetch_secrets: wrong refs type
--- main_config
env secret=apisix;
--- config
location /t {
content_by_lua_block {
local secret = require("apisix.secret")
local refs = "wrong"
local new_refs = secret.fetch_secrets(refs)
ngx.say(new_refs)
}
}
--- request
GET /t
--- response_body
nil

View File

@@ -0,0 +1,315 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('debug');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
my $routes = <<_EOC_;
routes:
-
uri: /hello
upstream:
nodes:
"127.0.0.1:1980": 1
type: roundrobin
#END
_EOC_
$block->set_value("apisix_yaml", $block->apisix_yaml . $routes);
if (!$block->request) {
$block->set_value("request", "GET /t");
}
if (!$block->no_error_log && !$block->error_log) {
$block->set_value("no_error_log", "[error]\n[alert]");
}
if ($block->sslhandshake) {
my $sslhandshake = $block->sslhandshake;
$block->set_value("config", <<_EOC_)
listen unix:\$TEST_NGINX_HTML_DIR/nginx.sock ssl;
location /t {
content_by_lua_block {
-- sync
ngx.sleep(0.2)
do
local sock = ngx.socket.tcp()
sock:settimeout(2000)
local ok, err = sock:connect("unix:\$TEST_NGINX_HTML_DIR/nginx.sock")
if not ok then
ngx.say("failed to connect: ", err)
return
end
$sslhandshake
local req = "GET /hello HTTP/1.0\\r\\nHost: test.com\\r\\nConnection: close\\r\\n\\r\\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send http request: ", err)
return
end
local line, err = sock:receive()
if not line then
ngx.say("failed to receive: ", err)
return
end
ngx.say("received: ", line)
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
end -- do
-- collectgarbage()
}
}
_EOC_
}
});
run_tests();
__DATA__
=== TEST 1: sanity
--- apisix_yaml
ssls:
-
cert: |
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIJAI3Meu/gJVTLMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV
BAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwISGFuZ3pob3UxDTAL
BgNVBAoMBHRlc3QxDTALBgNVBAsMBHRlc3QxGzAZBgNVBAMMEmV0Y2QuY2x1c3Rl
ci5sb2NhbDAeFw0yMDEwMjgwMzMzMDJaFw0yMTEwMjgwMzMzMDJaMG4xCzAJBgNV
BAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwISGFuZ3pob3UxDTAL
BgNVBAoMBHRlc3QxDTALBgNVBAsMBHRlc3QxGzAZBgNVBAMMEmV0Y2QuY2x1c3Rl
ci5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ/qwxCR7g5S
s9+VleopkLi5pAszEkHYOBpwF/hDeRdxU0I0e1zZTdTlwwPy2vf8m3kwoq6fmNCt
tdUUXh5Wvgi/2OA8HBBzaQFQL1Av9qWwyES5cx6p0ZBwIrcXQIsl1XfNSUpQNTSS
D44TGduXUIdeshukPvMvLWLezynf2/WlgVh/haWtDG99r/Gj3uBdjl0m/xGvKvIv
NFy6EdgG9fkwcIalutjrUnGl9moGjwKYu4eXW2Zt5el0d1AHXUsqK4voe0p+U2Nz
quDmvxteXWdlsz8o5kQT6a4DUtWhpPIfNj9oZfPRs3LhBFQ74N70kVxMOCdec1lU
bnFzLIMGlz0CAwEAAaNQME4wHQYDVR0OBBYEFFHeljijrr+SPxlH5fjHRPcC7bv2
MB8GA1UdIwQYMBaAFFHeljijrr+SPxlH5fjHRPcC7bv2MAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggEBAG6NNTK7sl9nJxeewVuogCdMtkcdnx9onGtCOeiQ
qvh5Xwn9akZtoLMVEdceU0ihO4wILlcom3OqHs9WOd6VbgW5a19Thh2toxKidHz5
rAaBMyZsQbFb6+vFshZwoCtOLZI/eIZfUUMFqMXlEPrKru1nSddNdai2+zi5rEnM
HCot43+3XYuqkvWlOjoi9cP+C4epFYrxpykVbcrtbd7TK+wZNiK3xtDPnVzjdNWL
geAEl9xrrk0ss4nO/EreTQgS46gVU+tLC+b23m2dU7dcKZ7RDoiA9bdVc4a2IsaS
2MvLL4NZ2nUh8hAEHiLtGMAV3C6xNbEyM07hEpDW6vk6tqk=
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCf6sMQke4OUrPf
lZXqKZC4uaQLMxJB2DgacBf4Q3kXcVNCNHtc2U3U5cMD8tr3/Jt5MKKun5jQrbXV
FF4eVr4Iv9jgPBwQc2kBUC9QL/alsMhEuXMeqdGQcCK3F0CLJdV3zUlKUDU0kg+O
Exnbl1CHXrIbpD7zLy1i3s8p39v1pYFYf4WlrQxvfa/xo97gXY5dJv8RryryLzRc
uhHYBvX5MHCGpbrY61JxpfZqBo8CmLuHl1tmbeXpdHdQB11LKiuL6HtKflNjc6rg
5r8bXl1nZbM/KOZEE+muA1LVoaTyHzY/aGXz0bNy4QRUO+De9JFcTDgnXnNZVG5x
cyyDBpc9AgMBAAECggEAatcEtehZPJaCeClPPF/Cwbe9YoIfe4BCk186lHI3z7K1
5nB7zt+bwVY0AUpagv3wvXoB5lrYVOsJpa9y5iAb3GqYMc/XDCKfD/KLea5hwfcn
BctEn0LjsPVKLDrLs2t2gBDWG2EU+udunwQh7XTdp2Nb6V3FdOGbGAg2LgrSwP1g
0r4z14F70oWGYyTQ5N8UGuyryVrzQH525OYl38Yt7R6zJ/44FVi/2TvdfHM5ss39
SXWi00Q30fzaBEf4AdHVwVCRKctwSbrIOyM53kiScFDmBGRblCWOxXbiFV+d3bjX
gf2zxs7QYZrFOzOO7kLtHGua4itEB02497v+1oKDwQKBgQDOBvCVGRe2WpItOLnj
SF8iz7Sm+jJGQz0D9FhWyGPvrN7IXGrsXavA1kKRz22dsU8xdKk0yciOB13Wb5y6
yLsr/fPBjAhPb4h543VHFjpAQcxpsH51DE0b2oYOWMmz+rXGB5Jy8EkP7Q4njIsc
2wLod1dps8OT8zFx1jX3Us6iUQKBgQDGtKkfsvWi3HkwjFTR+/Y0oMz7bSruE5Z8
g0VOHPkSr4XiYgLpQxjbNjq8fwsa/jTt1B57+By4xLpZYD0BTFuf5po+igSZhH8s
QS5XnUnbM7d6Xr/da7ZkhSmUbEaMeHONSIVpYNgtRo4bB9Mh0l1HWdoevw/w5Ryt
L/OQiPhfLQKBgQCh1iG1fPh7bbnVe/HI71iL58xoPbCwMLEFIjMiOFcINirqCG6V
LR91Ytj34JCihl1G4/TmWnsH1hGIGDRtJLCiZeHL70u32kzCMkI1jOhFAWqoutMa
7obDkmwraONIVW/kFp6bWtSJhhTQTD4adI9cPCKWDXdcCHSWj0Xk+U8HgQKBgBng
t1HYhaLzIZlP/U/nh3XtJyTrX7bnuCZ5FhKJNWrYjxAfgY+NXHRYCKg5x2F5j70V
be7pLhxmCnrPTMKZhik56AaTBOxVVBaYWoewhUjV4GRAaK5Wc8d9jB+3RizPFwVk
V3OU2DJ1SNZ+W2HBOsKrEfwFF/dgby6i2w6MuAP1AoGBAIxvxUygeT/6P0fHN22P
zAHFI4v2925wYdb7H//D8DIADyBwv18N6YH8uH7L+USZN7e4p2k8MGGyvTXeC6aX
IeVtU6fH57Ddn59VPbF20m8RCSkmBvSdcbyBmqlZSBE+fKwCliKl6u/GH0BNAWKz
r8yiEiskqRmy7P7MY9hDmEbG
-----END PRIVATE KEY-----
snis:
- "t.com"
- "test.com"
--- sslhandshake
local sess, err = sock:sslhandshake(nil, "test.com", false)
if not sess then
ngx.say("failed to do SSL handshake: ", err)
return
end
--- response_body
received: HTTP/1.1 200 OK
close: 1 nil
--- error_log
server name: "test.com"
=== TEST 2: single sni
--- apisix_yaml
ssls:
-
cert: |
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIJAI3Meu/gJVTLMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV
BAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwISGFuZ3pob3UxDTAL
BgNVBAoMBHRlc3QxDTALBgNVBAsMBHRlc3QxGzAZBgNVBAMMEmV0Y2QuY2x1c3Rl
ci5sb2NhbDAeFw0yMDEwMjgwMzMzMDJaFw0yMTEwMjgwMzMzMDJaMG4xCzAJBgNV
BAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwISGFuZ3pob3UxDTAL
BgNVBAoMBHRlc3QxDTALBgNVBAsMBHRlc3QxGzAZBgNVBAMMEmV0Y2QuY2x1c3Rl
ci5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ/qwxCR7g5S
s9+VleopkLi5pAszEkHYOBpwF/hDeRdxU0I0e1zZTdTlwwPy2vf8m3kwoq6fmNCt
tdUUXh5Wvgi/2OA8HBBzaQFQL1Av9qWwyES5cx6p0ZBwIrcXQIsl1XfNSUpQNTSS
D44TGduXUIdeshukPvMvLWLezynf2/WlgVh/haWtDG99r/Gj3uBdjl0m/xGvKvIv
NFy6EdgG9fkwcIalutjrUnGl9moGjwKYu4eXW2Zt5el0d1AHXUsqK4voe0p+U2Nz
quDmvxteXWdlsz8o5kQT6a4DUtWhpPIfNj9oZfPRs3LhBFQ74N70kVxMOCdec1lU
bnFzLIMGlz0CAwEAAaNQME4wHQYDVR0OBBYEFFHeljijrr+SPxlH5fjHRPcC7bv2
MB8GA1UdIwQYMBaAFFHeljijrr+SPxlH5fjHRPcC7bv2MAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggEBAG6NNTK7sl9nJxeewVuogCdMtkcdnx9onGtCOeiQ
qvh5Xwn9akZtoLMVEdceU0ihO4wILlcom3OqHs9WOd6VbgW5a19Thh2toxKidHz5
rAaBMyZsQbFb6+vFshZwoCtOLZI/eIZfUUMFqMXlEPrKru1nSddNdai2+zi5rEnM
HCot43+3XYuqkvWlOjoi9cP+C4epFYrxpykVbcrtbd7TK+wZNiK3xtDPnVzjdNWL
geAEl9xrrk0ss4nO/EreTQgS46gVU+tLC+b23m2dU7dcKZ7RDoiA9bdVc4a2IsaS
2MvLL4NZ2nUh8hAEHiLtGMAV3C6xNbEyM07hEpDW6vk6tqk=
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCf6sMQke4OUrPf
lZXqKZC4uaQLMxJB2DgacBf4Q3kXcVNCNHtc2U3U5cMD8tr3/Jt5MKKun5jQrbXV
FF4eVr4Iv9jgPBwQc2kBUC9QL/alsMhEuXMeqdGQcCK3F0CLJdV3zUlKUDU0kg+O
Exnbl1CHXrIbpD7zLy1i3s8p39v1pYFYf4WlrQxvfa/xo97gXY5dJv8RryryLzRc
uhHYBvX5MHCGpbrY61JxpfZqBo8CmLuHl1tmbeXpdHdQB11LKiuL6HtKflNjc6rg
5r8bXl1nZbM/KOZEE+muA1LVoaTyHzY/aGXz0bNy4QRUO+De9JFcTDgnXnNZVG5x
cyyDBpc9AgMBAAECggEAatcEtehZPJaCeClPPF/Cwbe9YoIfe4BCk186lHI3z7K1
5nB7zt+bwVY0AUpagv3wvXoB5lrYVOsJpa9y5iAb3GqYMc/XDCKfD/KLea5hwfcn
BctEn0LjsPVKLDrLs2t2gBDWG2EU+udunwQh7XTdp2Nb6V3FdOGbGAg2LgrSwP1g
0r4z14F70oWGYyTQ5N8UGuyryVrzQH525OYl38Yt7R6zJ/44FVi/2TvdfHM5ss39
SXWi00Q30fzaBEf4AdHVwVCRKctwSbrIOyM53kiScFDmBGRblCWOxXbiFV+d3bjX
gf2zxs7QYZrFOzOO7kLtHGua4itEB02497v+1oKDwQKBgQDOBvCVGRe2WpItOLnj
SF8iz7Sm+jJGQz0D9FhWyGPvrN7IXGrsXavA1kKRz22dsU8xdKk0yciOB13Wb5y6
yLsr/fPBjAhPb4h543VHFjpAQcxpsH51DE0b2oYOWMmz+rXGB5Jy8EkP7Q4njIsc
2wLod1dps8OT8zFx1jX3Us6iUQKBgQDGtKkfsvWi3HkwjFTR+/Y0oMz7bSruE5Z8
g0VOHPkSr4XiYgLpQxjbNjq8fwsa/jTt1B57+By4xLpZYD0BTFuf5po+igSZhH8s
QS5XnUnbM7d6Xr/da7ZkhSmUbEaMeHONSIVpYNgtRo4bB9Mh0l1HWdoevw/w5Ryt
L/OQiPhfLQKBgQCh1iG1fPh7bbnVe/HI71iL58xoPbCwMLEFIjMiOFcINirqCG6V
LR91Ytj34JCihl1G4/TmWnsH1hGIGDRtJLCiZeHL70u32kzCMkI1jOhFAWqoutMa
7obDkmwraONIVW/kFp6bWtSJhhTQTD4adI9cPCKWDXdcCHSWj0Xk+U8HgQKBgBng
t1HYhaLzIZlP/U/nh3XtJyTrX7bnuCZ5FhKJNWrYjxAfgY+NXHRYCKg5x2F5j70V
be7pLhxmCnrPTMKZhik56AaTBOxVVBaYWoewhUjV4GRAaK5Wc8d9jB+3RizPFwVk
V3OU2DJ1SNZ+W2HBOsKrEfwFF/dgby6i2w6MuAP1AoGBAIxvxUygeT/6P0fHN22P
zAHFI4v2925wYdb7H//D8DIADyBwv18N6YH8uH7L+USZN7e4p2k8MGGyvTXeC6aX
IeVtU6fH57Ddn59VPbF20m8RCSkmBvSdcbyBmqlZSBE+fKwCliKl6u/GH0BNAWKz
r8yiEiskqRmy7P7MY9hDmEbG
-----END PRIVATE KEY-----
sni: "test.com"
--- sslhandshake
local sess, err = sock:sslhandshake(nil, "test.com", false)
if not sess then
ngx.say("failed to do SSL handshake: ", err)
return
end
--- response_body
received: HTTP/1.1 200 OK
close: 1 nil
--- error_log
server name: "test.com"
=== TEST 3: bad cert
--- apisix_yaml
ssls:
-
cert: |
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIJAI3Meu/gJVTLMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV
BAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwISGFuZ3pob3UxDTAL
BgNVBAoMBHRlc3QxDTALBgNVBAsMBHRlc3QxGzAZBgNVBAMMEmV0Y2QuY2x1c3Rl
ci5sb2NhbDAeFw0yMDEwMjgwMzMzMDJaFw0yMTEwMjgwMzMzMDJaMG4xCzAJBgNV
BAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwISGFuZ3pob3UxDTAL
BgNVBAoMBHRlc3QxDTALBgNVBAsMBHRlc3QxGzAZBgNVBAMMEmV0Y2QuY2x1c3Rl
ci5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ/qwxCR7g5S
s9+VleopkLi5pAszEkHYOBpwF/hDeRdxU0I0e1zZTdTlwwPy2vf8m3kwoq6fmNCt
tdUUXh5Wvgi/2OA8HBBzaQFQL1Av9qWwyES5cx6p0ZBwIrcXQIsl1XfNSUpQNTSS
D44TGduXUIdeshukPvMvLWLezynf2/WlgVh/haWtDG99r/Gj3uBdjl0m/xGvKvIv
quDmvxteXWdlsz8o5kQT6a4DUtWhpPIfNj9oZfPRs3LhBFQ74N70kVxMOCdec1lU
bnFzLIMGlz0CAwEAAaNQME4wHQYDVR0OBBYEFFHeljijrr+SPxlH5fjHRPcC7bv2
MB8GA1UdIwQYMBaAFFHeljijrr+SPxlH5fjHRPcC7bv2MAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggEBAG6NNTK7sl9nJxeewVuogCdMtkcdnx9onGtCOeiQ
qvh5Xwn9akZtoLMVEdceU0ihO4wILlcom3OqHs9WOd6VbgW5a19Thh2toxKidHz5
rAaBMyZsQbFb6+vFshZwoCtOLZI/eIZfUUMFqMXlEPrKru1nSddNdai2+zi5rEnM
HCot43+3XYuqkvWlOjoi9cP+C4epFYrxpykVbcrtbd7TK+wZNiK3xtDPnVzjdNWL
geAEl9xrrk0ss4nO/EreTQgS46gVU+tLC+b23m2dU7dcKZ7RDoiA9bdVc4a2IsaS
2MvLL4NZ2nUh8hAEHiLtGMAV3C6xNbEyM07hEpDW6vk6tqk=
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCf6sMQke4OUrPf
lZXqKZC4uaQLMxJB2DgacBf4Q3kXcVNCNHtc2U3U5cMD8tr3/Jt5MKKun5jQrbXV
FF4eVr4Iv9jgPBwQc2kBUC9QL/alsMhEuXMeqdGQcCK3F0CLJdV3zUlKUDU0kg+O
Exnbl1CHXrIbpD7zLy1i3s8p39v1pYFYf4WlrQxvfa/xo97gXY5dJv8RryryLzRc
uhHYBvX5MHCGpbrY61JxpfZqBo8CmLuHl1tmbeXpdHdQB11LKiuL6HtKflNjc6rg
5r8bXl1nZbM/KOZEE+muA1LVoaTyHzY/aGXz0bNy4QRUO+De9JFcTDgnXnNZVG5x
cyyDBpc9AgMBAAECggEAatcEtehZPJaCeClPPF/Cwbe9YoIfe4BCk186lHI3z7K1
5nB7zt+bwVY0AUpagv3wvXoB5lrYVOsJpa9y5iAb3GqYMc/XDCKfD/KLea5hwfcn
BctEn0LjsPVKLDrLs2t2gBDWG2EU+udunwQh7XTdp2Nb6V3FdOGbGAg2LgrSwP1g
0r4z14F70oWGYyTQ5N8UGuyryVrzQH525OYl38Yt7R6zJ/44FVi/2TvdfHM5ss39
SXWi00Q30fzaBEf4AdHVwVCRKctwSbrIOyM53kiScFDmBGRblCWOxXbiFV+d3bjX
gf2zxs7QYZrFOzOO7kLtHGua4itEB02497v+1oKDwQKBgQDOBvCVGRe2WpItOLnj
SF8iz7Sm+jJGQz0D9FhWyGPvrN7IXGrsXavA1kKRz22dsU8xdKk0yciOB13Wb5y6
yLsr/fPBjAhPb4h543VHFjpAQcxpsH51DE0b2oYOWMmz+rXGB5Jy8EkP7Q4njIsc
2wLod1dps8OT8zFx1jX3Us6iUQKBgQDGtKkfsvWi3HkwjFTR+/Y0oMz7bSruE5Z8
g0VOHPkSr4XiYgLpQxjbNjq8fwsa/jTt1B57+By4xLpZYD0BTFuf5po+igSZhH8s
QS5XnUnbM7d6Xr/da7ZkhSmUbEaMeHONSIVpYNgtRo4bB9Mh0l1HWdoevw/w5Ryt
L/OQiPhfLQKBgQCh1iG1fPh7bbnVe/HI71iL58xoPbCwMLEFIjMiOFcINirqCG6V
LR91Ytj34JCihl1G4/TmWnsH1hGIGDRtJLCiZeHL70u32kzCMkI1jOhFAWqoutMa
7obDkmwraONIVW/kFp6bWtSJhhTQTD4adI9cPCKWDXdcCHSWj0Xk+U8HgQKBgBng
t1HYhaLzIZlP/U/nh3XtJyTrX7bnuCZ5FhKJNWrYjxAfgY+NXHRYCKg5x2F5j70V
be7pLhxmCnrPTMKZhik56AaTBOxVVBaYWoewhUjV4GRAaK5Wc8d9jB+3RizPFwVk
V3OU2DJ1SNZ+W2HBOsKrEfwFF/dgby6i2w6MuAP1AoGBAIxvxUygeT/6P0fHN22P
zAHFI4v2925wYdb7H//D8DIADyBwv18N6YH8uH7L+USZN7e4p2k8MGGyvTXeC6aX
IeVtU6fH57Ddn59VPbF20m8RCSkmBvSdcbyBmqlZSBE+fKwCliKl6u/GH0BNAWKz
r8yiEiskqRmy7P7MY9hDmEbG
-----END PRIVATE KEY-----
snis:
- "t.com"
- "test.com"
--- error_log
failed to parse cert
--- error_code: 404

View File

@@ -0,0 +1,127 @@
#
# 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.
#
use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
my $yaml_config = $block->yaml_config // <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
_EOC_
$block->set_value("yaml_config", $yaml_config);
$block->set_value("stream_enable", 1);
if (!$block->stream_request) {
$block->set_value("stream_request", "mmm");
}
if (!$block->error_log && !$block->no_error_log) {
$block->set_value("no_error_log", "[error]\n[alert]");
}
});
run_tests();
__DATA__
=== TEST 1: sanity
--- apisix_yaml
stream_routes:
- server_addr: 127.0.0.1
server_port: 1985
id: 1
upstream:
nodes:
"127.0.0.1:1995": 1
type: roundrobin
#END
--- stream_response
hello world
=== TEST 2: rule with bad plugin
--- apisix_yaml
stream_routes:
- server_addr: 127.0.0.1
server_port: 1985
id: 1
plugins:
mqtt-proxy:
uri: 1
upstream:
nodes:
"127.0.0.1:1995": 1
type: roundrobin
#END
--- error_log eval
qr/property "\w+" is required/
=== TEST 3: ignore unknown plugin
--- apisix_yaml
stream_routes:
- server_addr: 127.0.0.1
server_port: 1985
id: 1
plugins:
x-rewrite:
uri: 1
upstream:
nodes:
"127.0.0.1:1995": 1
type: roundrobin
#END
--- stream_response
hello world
=== TEST 4: sanity with plugin
--- apisix_yaml
stream_routes:
- server_addr: 127.0.0.1
server_port: 1985
id: 1
upstream_id: 1
plugins:
mqtt-proxy:
protocol_name: "MQTT"
protocol_level: 4
upstreams:
- nodes:
"127.0.0.1:1995": 1
type: roundrobin
id: 1
#END
--- stream_request eval
"\x10\x0f\x00\x04\x4d\x51\x54\x54\x04\x02\x00\x3c\x00\x03\x66\x6f\x6f"
--- stream_response
hello world