Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add vault common components #8412

Merged
merged 9 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
test_dir:
- t/plugin/[a-k]*
- t/plugin/[l-z]*
- t/admin t/cli t/config-center-yaml t/control t/core t/debug t/deployment t/discovery t/error_page t/misc
- t/admin t/cli t/config-center-yaml t/control t/core t/debug t/deployment t/discovery t/error_page t/kms t/misc
- t/node t/pubsub t/router t/script t/stream-node t/utils t/wasm t/xds-library t/xrpc

runs-on: ${{ matrix.platform }}
Expand Down Expand Up @@ -86,6 +86,7 @@ jobs:
- name: Linux launch common services
run: |
make ci-env-up project_compose_ci=ci/pod/docker-compose.common.yml
sudo ./ci/init-common-test-service.sh

- name: Create tarball
if: ${{ startsWith(github.ref, 'refs/heads/release/') }}
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/centos7-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
test_dir:
- t/plugin/[a-k]*
- t/plugin/[l-z]*
- t/admin t/cli t/config-center-yaml t/control t/core t/debug t/deployment t/discovery t/error_page t/misc
- t/admin t/cli t/config-center-yaml t/control t/core t/debug t/deployment t/discovery t/error_page t/kms t/misc
- t/node t/pubsub t/router t/script t/stream-node t/utils t/wasm t/xds-library

steps:
Expand Down Expand Up @@ -72,6 +72,7 @@ jobs:
- name: Linux launch common services
run: |
make ci-env-up project_compose_ci=ci/pod/docker-compose.common.yml
sudo ./ci/init-common-test-service.sh

- name: Build rpm package
if: ${{ startsWith(github.ref, 'refs/heads/release/') }}
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@ install: runtime
$(ENV_INSTALL) -d $(ENV_INST_LUADIR)/apisix/pubsub
$(ENV_INSTALL) apisix/pubsub/*.lua $(ENV_INST_LUADIR)/apisix/pubsub/

$(ENV_INSTALL) -d $(ENV_INST_LUADIR)/apisix/kms
$(ENV_INSTALL) apisix/kms/*.lua $(ENV_INST_LUADIR)/apisix/kms/

$(ENV_INSTALL) -d $(ENV_INST_LUADIR)/apisix/plugins/zipkin
$(ENV_INSTALL) apisix/plugins/zipkin/*.lua $(ENV_INST_LUADIR)/apisix/plugins/zipkin/

Expand Down
91 changes: 91 additions & 0 deletions apisix/kms/vault.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
--
-- 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.
--

--- Vault Tools.
-- Vault is an identity-based secrets and encryption management system.

local core = require("apisix.core")
local http = require("resty.http")

local norm_path = require("pl.path").normpath

local sub = core.string.sub
local rfind_char = core.string.rfind_char

local _M = {}


local function make_request_to_vault(conf, method, key, data)
local httpc = http.new()
-- config timeout or default to 5000 ms
httpc:set_timeout((conf.timeout or 5)*1000)

local req_addr = conf.uri .. norm_path("/v1/"
.. conf.prefix .. "/" .. key)

local res, err = httpc:request_uri(req_addr, {
method = method,
headers = {
["X-Vault-Token"] = conf.token
},
body = core.json.encode(data or {}, true)
})

if not res then
return nil, err
end

return res.body
end

-- key is the vault kv engine path
local function get(conf, key)
core.log.info("fetching data from vault for key: ", key)

local idx = rfind_char(key, '/')
if not idx then
return nil, "error key format, key: " .. key
end

local main_key = sub(key, 1, idx - 1)
if main_key == "" then
return nil, "can't find main key, key: " .. key
end
local sub_key = sub(key, idx + 1)
if sub_key == "" then
return nil, "can't find sub key, key: " .. key
end

core.log.info("main: ", main_key, " sub: ", sub_key)

local res, err = make_request_to_vault(conf, "GET", main_key)
if not res then
return nil, "failed to retrtive data from vault kv engine: " .. err
end

local ret = core.json.decode(res)
if not ret or not ret.data then
return nil, "failed to decode result, res: " .. res
end

return ret.data[sub_key]
end

_M.get = get


return _M
21 changes: 21 additions & 0 deletions ci/init-common-test-service.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
#
# 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.
#

# prepare vault kv engine
sleep 3s
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why sleep 3s here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure that the vault service has been started normally, this is just an experience value, it does work.

docker exec -i vault sh -c "VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault secrets enable -path=kv -version=1 kv"
3 changes: 0 additions & 3 deletions ci/init-plugin-test-service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ docker exec -i rmqnamesrv /home/rocketmq/rocketmq-4.6.0/bin/mqadmin updateTopic
docker exec -i rmqnamesrv /home/rocketmq/rocketmq-4.6.0/bin/mqadmin updateTopic -n rocketmq_namesrv:9876 -t test3 -c DefaultCluster
docker exec -i rmqnamesrv /home/rocketmq/rocketmq-4.6.0/bin/mqadmin updateTopic -n rocketmq_namesrv:9876 -t test4 -c DefaultCluster

# prepare vault kv engine
docker exec -i vault sh -c "VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault secrets enable -path=kv -version=1 kv"

# wait for keycloak ready
bash -c 'while true; do curl -s localhost:8080 &>/dev/null; ret=$?; [[ $ret -eq 0 ]] && break; sleep 3; done'
docker cp ci/kcadm_configure_cas.sh apisix_keycloak_new:/tmp/
Expand Down
15 changes: 15 additions & 0 deletions ci/pod/docker-compose.common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,18 @@ services:
- "5004:6382"
- "5005:6383"
- "5006:6384"


## HashiCorp Vault
vault:
image: vault:1.9.0
container_name: vault
restart: unless-stopped
ports:
- "8200:8200"
cap_add:
- IPC_LOCK
environment:
VAULT_DEV_ROOT_TOKEN_ID: root
VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200
command: [ "vault", "server", "-dev" ]
17 changes: 0 additions & 17 deletions ci/pod/docker-compose.plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,22 +130,6 @@ services:
networks:
skywalk_net:

## HashiCorp Vault
vault:
image: vault:1.9.0
container_name: vault
restart: unless-stopped
ports:
- "8200:8200"
cap_add:
- IPC_LOCK
environment:
VAULT_DEV_ROOT_TOKEN_ID: root
VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200
command: [ "vault", "server", "-dev" ]
networks:
vault_net:


## OpenLDAP
openldap:
Expand Down Expand Up @@ -284,5 +268,4 @@ networks:
kafka_net:
skywalk_net:
rocketmq_net:
vault_net:
opa_net:
158 changes: 158 additions & 0 deletions t/kms/vault.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#
# 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);
no_long_string();
no_root_location();
log_level("info");

run_tests;

__DATA__

=== TEST 1: check key: error format
--- config
location /t {
content_by_lua_block {
local vault = require("apisix.kms.vault")
local conf = {
prefix = "/kv/prefix",
token = "root",
uri = "http://127.0.0.1:2800"
}
local data, err = vault.get(conf, "apisix")
if err then
return ngx.say(err)
end

ngx.say("done")
}
}
--- request
GET /t
--- response_body
error key format, key: apisix



=== TEST 2: check key: no main key
--- config
location /t {
content_by_lua_block {
local vault = require("apisix.kms.vault")
local conf = {
prefix = "/kv/prefix",
token = "root",
uri = "http://127.0.0.1:2800"
}
local data, err = vault.get(conf, "/apisix")
if err then
return ngx.say(err)
end

ngx.say("done")
}
}
--- request
GET /t
--- response_body
can't find main key, key: /apisix



=== TEST 3: check key: no sub key
--- config
location /t {
content_by_lua_block {
local vault = require("apisix.kms.vault")
local conf = {
prefix = "/kv/prefix",
token = "root",
uri = "http://127.0.0.1:2800"
}
local data, err = vault.get(conf, "apisix/")
if err then
return ngx.say(err)
end

ngx.say("done")
}
}
--- request
GET /t
--- response_body
can't find sub key, key: apisix/



=== TEST 4: error vault uri
--- config
location /t {
content_by_lua_block {
local vault = require("apisix.kms.vault")
local conf = {
prefix = "/kv/prefix",
token = "root",
uri = "http://127.0.0.2:2800"
}
local data, err = vault.get(conf, "/apisix/sub")
if err then
return ngx.say(err)
end

ngx.say("done")
}
}
--- request
GET /t
--- response_body
failed to retrtive data from vault kv engine: connection refused
--- timeout: 6



=== TEST 5: store secret into vault
--- exec
VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/apisix-key/jack key=value
--- response_body
Success! Data written to: kv/apisix/apisix-key/jack



=== TEST 6: get value from vault
--- config
location /t {
content_by_lua_block {
local vault = require("apisix.kms.vault")
local conf = {
prefix = "kv/apisix",
token = "root",
uri = "http://127.0.0.1:8200"
}
local value, err = vault.get(conf, "/apisix-key/jack/key")
if err then
return ngx.say(err)
end

ngx.say("value")
}
}
--- request
GET /t
--- response_body
value