-- -- 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 env = core.env local schema = { type = "object", properties = { uri = core.schema.uri_def, prefix = { type = "string", }, token = { type = "string", }, namespace = { type = "string", }, }, required = {"uri", "prefix", "token"}, } local _M = { schema = schema } 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 token, _ = env.fetch_by_uri(conf.token) if not token then token = conf.token end local headers = { ["X-Vault-Token"] = token } if conf.namespace then -- The namespace rule is referenced in -- https://developer.hashicorp.com/vault/docs/enterprise/namespaces#vault-api-and-namespaces headers["X-Vault-Namespace"] = conf.namespace end local res, err = httpc:request_uri(req_addr, { method = method, headers = headers, 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