t/kubernetes/discovery/kubernetes.t (85 lines of code) (raw):
#
# 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('warn');
no_root_location();
no_shuffle();
workers(4);
our $token_file = "/tmp/var/run/secrets/kubernetes.io/serviceaccount/token";
our $token_value = eval {`cat $token_file 2>/dev/null`};
add_block_preprocessor(sub {
my ($block) = @_;
my $apisix_yaml = $block->apisix_yaml // <<_EOC_;
routes: []
#END
_EOC_
$block->set_value("apisix_yaml", $apisix_yaml);
my $main_config = $block->main_config // <<_EOC_;
env MyPort=6443;
env KUBERNETES_SERVICE_HOST=127.0.0.1;
env KUBERNETES_SERVICE_PORT=6443;
env KUBERNETES_CLIENT_TOKEN=$::token_value;
env KUBERNETES_CLIENT_TOKEN_FILE=$::token_file;
_EOC_
$block->set_value("main_config", $main_config);
my $config = $block->config // <<_EOC_;
location /compare {
content_by_lua_block {
local http = require("resty.http")
local core = require("apisix.core")
local local_conf = require("apisix.core.config_local").local_conf()
local function deep_compare(tbl1, tbl2)
if tbl1 == tbl2 then
return true
elseif type(tbl1) == "table" and type(tbl2) == "table" then
for key1, value1 in pairs(tbl1) do
local value2 = tbl2[key1]
if value2 == nil then
-- avoid the type call for missing keys in tbl2 by directly comparing with nil
return false
elseif value1 ~= value2 then
if type(value1) == "table" and type(value2) == "table" then
if not deep_compare(value1, value2) then
return false
end
else
return false
end
end
end
for key2, _ in pairs(tbl2) do
if tbl1[key2] == nil then
return false
end
end
return true
end
return false
end
ngx.req.read_body()
local request_body = ngx.req.get_body_data()
local expect = core.json.decode(request_body)
local current = local_conf.discovery.kubernetes
if deep_compare(expect,current) then
ngx.say("true")
else
ngx.say("false, current is ",core.json.encode(current,true))
end
}
}
location /update_token {
content_by_lua_block {
local token_file = "$::token_file"
local file = io.open(token_file, "w")
file:write("invalid_token_value")
file:close()
ngx.sleep(3)
file = io.open(token_file, "w")
local token_value = [[$::token_value]]
file:write(token_value)
file:close()
}
}
_EOC_
$block->set_value("config", $config);
});
run_tests();
__DATA__
=== TEST 1: default value with minimal configuration
--- yaml_config
apisix:
node_listen: 1984
config_center: yaml
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
kubernetes:
client:
token: ${KUBERNETES_CLIENT_TOKEN}
--- request
GET /compare
{
"service": {
"schema": "https",
"host": "${KUBERNETES_SERVICE_HOST}",
"port": "${KUBERNETES_SERVICE_PORT}"
},
"client": {
"token": "${KUBERNETES_CLIENT_TOKEN}"
},
"watch_endpoint_slices": false,
"shared_size": "1m",
"default_weight": 50
}
--- more_headers
Content-type: application/json
--- response_body
true
=== TEST 2: default value with minimal service and client configuration
--- yaml_config
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
kubernetes:
service: {}
client:
token: ${KUBERNETES_CLIENT_TOKEN}
--- request
GET /compare
{
"service": {
"schema": "https",
"host": "${KUBERNETES_SERVICE_HOST}",
"port": "${KUBERNETES_SERVICE_PORT}"
},
"client": {
"token": "${KUBERNETES_CLIENT_TOKEN}"
},
"watch_endpoint_slices": false,
"shared_size": "1m",
"default_weight": 50
}
--- more_headers
Content-type: application/json
--- response_body
true
=== TEST 3: mixing set custom and default values
--- yaml_config
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
kubernetes:
service:
host: "sample.com"
shared_size: "2m"
client:
token: ${KUBERNETES_CLIENT_TOKEN}
--- request
GET /compare
{
"service": {
"schema": "https",
"host": "sample.com",
"port": "${KUBERNETES_SERVICE_PORT}"
},
"client": {
"token": "${KUBERNETES_CLIENT_TOKEN}"
},
"watch_endpoint_slices": false,
"shared_size": "2m",
"default_weight": 50
}
--- more_headers
Content-type: application/json
--- response_body
true
=== TEST 4: mixing set custom and default values
--- yaml_config
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
kubernetes:
client:
token: ${KUBERNETES_CLIENT_TOKEN}
default_weight: 33
--- request
GET /compare
{
"service": {
"schema": "https",
"host": "${KUBERNETES_SERVICE_HOST}",
"port": "${KUBERNETES_SERVICE_PORT}"
},
"client": {
"token": "${KUBERNETES_CLIENT_TOKEN}"
},
"watch_endpoint_slices": false,
"shared_size": "1m",
"default_weight": 33
}
--- more_headers
Content-type: application/json
--- response_body
true
=== TEST 5: multi cluster mode configuration
--- http_config
lua_shared_dict kubernetes-debug 1m;
lua_shared_dict kubernetes-release 1m;
--- yaml_config
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
kubernetes:
- id: "debug"
service:
host: "1.cluster.com"
port: "6445"
client:
token: ${KUBERNETES_CLIENT_TOKEN}
- id: "release"
service:
schema: "http"
host: "2.cluster.com"
port: "${MyPort}"
client:
token: ${KUBERNETES_CLIENT_TOKEN}
default_weight: 33
shared_size: "2m"
--- request
GET /compare
[
{
"id": "debug",
"service": {
"schema": "https",
"host": "1.cluster.com",
"port": "6445"
},
"client": {
"token": "${KUBERNETES_CLIENT_TOKEN}"
},
"watch_endpoint_slices": false,
"default_weight": 50,
"shared_size": "1m"
},
{
"id": "release",
"service": {
"schema": "http",
"host": "2.cluster.com",
"port": "${MyPort}"
},
"client": {
"token": "${KUBERNETES_CLIENT_TOKEN}"
},
"watch_endpoint_slices": false,
"default_weight": 33,
"shared_size": "2m"
}
]
--- more_headers
Content-type: application/json
--- response_body
true
=== TEST 6: set watch_endpoint_slices true and use kubernetes endpointslices api
--- yaml_config
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
kubernetes:
client:
token: ${KUBERNETES_CLIENT_TOKEN}
default_weight: 33
watch_endpoint_slices: true
--- request
GET /compare
{
"service": {
"schema": "https",
"host": "${KUBERNETES_SERVICE_HOST}",
"port": "${KUBERNETES_SERVICE_PORT}"
},
"client": {
"token": "${KUBERNETES_CLIENT_TOKEN}"
},
"watch_endpoint_slices": true,
"shared_size": "1m",
"default_weight": 33
}
--- more_headers
Content-type: application/json
--- response_body
true
=== TEST 7: auto read token file before get token value
--- yaml_config
apisix:
node_listen: 1984
config_center: yaml
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
kubernetes:
client:
token_file: "${KUBERNETES_CLIENT_TOKEN_FILE}"
--- request
GET /update_token
--- log_level: debug
--- grep_error_log eval
qr/re-read the token value/
--- grep_error_log_out
re-read the token value
re-read the token value
=== TEST 8: default value with minimal configuration and large shared_size
--- yaml_config
apisix:
node_listen: 1984
config_center: yaml
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
kubernetes:
client:
token: ${KUBERNETES_CLIENT_TOKEN}
shared_size: "1000m"
--- request
GET /compare
{
"service": {
"schema": "https",
"host": "${KUBERNETES_SERVICE_HOST}",
"port": "${KUBERNETES_SERVICE_PORT}"
},
"client": {
"token": "${KUBERNETES_CLIENT_TOKEN}"
},
"watch_endpoint_slices": false,
"shared_size": "1000m",
"default_weight": 50
}
--- more_headers
Content-type: application/json
--- response_body
true