Skip to content

Commit

Permalink
feat(cli) use new config and dao loaders
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaultcha committed Oct 15, 2015
1 parent 57b9e30 commit d26e179
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 133 deletions.
49 changes: 0 additions & 49 deletions kong/cli/config_validation.lua

This file was deleted.

6 changes: 4 additions & 2 deletions kong/cli/db.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
local Faker = require "kong.tools.faker"
local constants = require "kong.constants"
local cutils = require "kong.cli.utils"
local IO = require "kong.tools.io"
local config = require "kong.tools.config_loader"
local dao = require "kong.tools.dao_loader"
local lapp = require("lapp")

local args = lapp(string.format([[
Expand All @@ -29,7 +30,8 @@ if args.command == "db" then
end

local config_path = cutils.get_kong_config_path(args.config)
local _, dao_factory = IO.load_configuration_and_dao(config_path)
local config = config.load(config_path)
local dao_factory = dao.load(config)

if args.command == "seed" then

Expand Down
6 changes: 4 additions & 2 deletions kong/cli/migrations.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ local constants = require "kong.constants"
local cutils = require "kong.cli.utils"
local utils = require "kong.tools.utils"
local input = require "kong.cli.utils.input"
local IO = require "kong.tools.io"
local config = require "kong.tools.config_loader"
local dao = require "kong.tools.dao_loader"
local lapp = require "lapp"
local args = lapp(string.format([[
Kong datastore migrations.
Expand All @@ -28,7 +29,8 @@ if args.command == "migrations" then
end

local config_path = cutils.get_kong_config_path(args.config)
local configuration, dao_factory = IO.load_configuration_and_dao(config_path)
local configuration = config.load(config_path)
local dao_factory = dao.load(configuration)
local migrations = Migrations(dao_factory)

local kind = args.type
Expand Down
32 changes: 10 additions & 22 deletions kong/cli/utils/signal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ local constants = require "kong.constants"
local syslog = require "kong.tools.syslog"
local socket = require "socket"
local dnsmasq = require "kong.cli.utils.dnsmasq"
local config = require "kong.tools.config_loader"
local dao = require "kong.tools.dao_loader"

-- Cache config path, parsed config and DAO factory
local kong_config_path
local kong_config
local dao_factory
local kong_config_path, kong_config

-- Retrieve the desired Kong config file, parse it and provides a DAO factory
-- Will cache them for future retrieval
Expand All @@ -28,9 +28,9 @@ local function get_kong_config(args_config)
cutils.logger:info("Using configuration: "..kong_config_path)
end
if not kong_config then
kong_config, dao_factory = IO.load_configuration_and_dao(kong_config_path)
kong_config = config.load(kong_config_path)
end
return kong_config, kong_config_path, dao_factory
return kong_config, kong_config_path
end

-- Check if an executable (typically `nginx`) is a distribution of openresty
Expand Down Expand Up @@ -82,33 +82,20 @@ local function prepare_nginx_working_dir(args_config)
if err then
cutils.logger:error_exit(err)
end

-- Create logs files
os.execute("touch "..IO.path:join(kong_config.nginx_working_dir, "logs", "error.log"))
os.execute("touch "..IO.path:join(kong_config.nginx_working_dir, "logs", "access.log"))

-- Create SSL folder if needed
local _, err = IO.path:mkdir(IO.path:join(kong_config.nginx_working_dir, "ssl"))
if err then
cutils.logger:error_exit(err)
end
-- TODO: this is NOT the place to do this.
-- @see https://github.com/Mashape/kong/issues/92 for configuration validation/defaults
-- @see https://github.com/Mashape/kong/issues/217 for a better configuration file

-- Check memory cache
if kong_config.memory_cache_size then
if tonumber(kong_config.memory_cache_size) == nil then
cutils.logger:error_exit("Invalid \"memory_cache_size\" setting")
elseif tonumber(kong_config.memory_cache_size) < 32 then
cutils.logger:error_exit("Invalid \"memory_cache_size\" setting: needs to be at least 32")
end
else
kong_config.memory_cache_size = 128 -- Default value
cutils.logger:warn("Setting \"memory_cache_size\" to default 128MB")
end

ssl.prepare_ssl(kong_config)
local ssl_cert_path, ssl_key_path = ssl.get_ssl_cert_and_key(kong_config)
local trusted_ssl_cert_path = kong_config.databases_available[kong_config.database].properties.ssl_certificate -- DAO ssl cert
local trusted_ssl_cert_path = kong_config.dao_config.properties.ssl_certificate -- DAO ssl cert

-- Check dns_resolver
local dns_resolver
Expand Down Expand Up @@ -180,7 +167,8 @@ end
-- Prepare the database keyspace if needed (run schema migrations)
-- @param args_config Path to the desired configuration (usually from the --config CLI argument)
local function prepare_database(args_config)
local kong_config, _, dao_factory = get_kong_config(args_config)
local kong_config = get_kong_config(args_config)
local dao_factory = dao.load(kong_config)
local migrations = require("kong.tools.migrations")(dao_factory)

local keyspace_exists, err = dao_factory.migrations:keyspace_exists()
Expand Down
8 changes: 4 additions & 4 deletions kong/kong.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
-- |[[ ]]|
-- ==========

local IO = require "kong.tools.io"
local config = require "kong.tools.config_loader"
local dao_loader = require "kong.tools.dao_loader"
local utils = require "kong.tools.utils"
local cache = require "kong.tools.database_cache"
local stringy = require "stringy"
Expand Down Expand Up @@ -62,8 +63,6 @@ local function load_plugin(api_id, consumer_id, plugin_name)

if plugin and not plugin.null and plugin.enabled then
return plugin
else
return nil
end
end

Expand Down Expand Up @@ -136,7 +135,8 @@ end
-- it will be thrown and needs to be catched in init_by_lua.
function _M.init()
-- Loading configuration
configuration, dao = IO.load_configuration_and_dao(os.getenv("KONG_CONF"))
configuration = config.load(os.getenv("KONG_CONF"))
dao = dao_loader.load(configuration)

-- Initializing plugins
plugins = init_plugins()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ return {
["plugins_available"] = {type = "array",
default = {"ssl", "jwt", "acl", "cors", "oauth2", "tcp-log", "udp-log", "file-log",
"http-log", "key-auth", "hmac-auth", "basic-auth", "ip-restriction",
"mashape-analytics", "request_transformer", "response-transformer",
"mashape-analytics", "request-transformer", "response-transformer",
"request-size-limiting", "rate-limiting", "response-ratelimiting"}
},
["nginx_working_dir"] = {type = "string", default = "/user/local/kong"},
Expand Down Expand Up @@ -39,6 +39,6 @@ return {
["ssl_cert_path"] = {type = "string", nullable = true},
["ssl_key_path"] = {type = "string", nullable = true},
["send_anonymous_reports"] = {type = "boolean", default = false},
["memory_cache_size"] = {type = "number", default = 128},
["memory_cache_size"] = {type = "number", default = 128, min = 32},
["nginx"] = {type = "string", nullable = true}
}
105 changes: 105 additions & 0 deletions kong/tools/config_loader.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
local yaml = require "yaml"
local IO = require "kong.tools.io"
local utils = require "kong.tools.utils"
local cutils = require "kong.cli.utils"
local stringy = require "stringy"
local constants = require "kong.constants"
local config_defaults = require "kong.tools.config_defaults"

local function get_type(value, val_type)
if val_type == "array" and utils.is_array(value) then
return "array"
else
return type(value)
end
end

local function validate_config_schema(config, config_schema)
if not config_schema then config_schema = config_defaults end
local errors, property

for config_key, key_infos in pairs(config_schema) do
-- Default value
property = config[config_key] or key_infos.default

-- Recursion on table values
if key_infos.type == "table" then
if property == nil then
property = {}
end

local ok, s_errors = validate_config_schema(property, key_infos.content)
if not ok then
--errors = utils.add_error(errors, config_key, s_errors)
for s_k, s_v in pairs(s_errors) do
errors = utils.add_error(errors, config_key.."."..s_k, s_v)
end
end
end

-- Nullable checking
if property ~= nil and not key_infos.nullable then
local property_type = get_type(property, key_infos.type)
-- Type checking
if property_type ~= key_infos.type then
errors = utils.add_error(errors, config_key, "must be a "..key_infos.type)
end
-- Min checking
if property_type == "number" and key_infos.min ~= nil and property < key_infos.min then
errors = utils.add_error(errors, config_key, "must be greater than "..key_infos.min)
end
end

config[config_key] = property
end

return errors == nil, errors
end

local _M = {}

function _M.validate(config)
local ok, errors = validate_config_schema(config)
if not ok then
return false, errors
end

-- Check selected database
if config.databases_available[config.database] == nil then
return false, {database = config.database.." is not listed in databases_available"}
end

return true
end

function _M.load(config_path)
local config_contents = IO.read_file(config_path)
if not config_contents then
cutils.logger:error_exit("No configuration file at: "..config_path)
end

local config = yaml.load(config_contents)

local ok, errors = _M.validate(config)
if not ok then
for config_key, config_error in pairs(errors) do
cutils.logger:warn(string.format("%s: %s", config_key, config_error))
end
cutils.logger:error_exit("Invalid properties in given configuration file")
end

-- Adding computed properties
config.pid_file = IO.path:join(config.nginx_working_dir, constants.CLI.NGINX_PID)
config.dao_config = config.databases_available[config.database]

-- Load absolute path for the nginx working directory
if not stringy.startswith(config.nginx_working_dir, "/") then
-- It's a relative path, convert it to absolute
local fs = require "luarocks.fs"
config.nginx_working_dir = fs.current_dir().."/"..config.nginx_working_dir
end

return config
end

return _M
8 changes: 8 additions & 0 deletions kong/tools/dao_loader.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
local _M = {}

function _M.load(config)
local DaoFactory = require("kong.dao."..config.database..".factory")
return DaoFactory(config.dao_config.properties, config.plugins_available)
end

return _M
40 changes: 0 additions & 40 deletions kong/tools/io.lua
Original file line number Diff line number Diff line change
Expand Up @@ -102,44 +102,4 @@ function _M.file_size(path)
return size
end

--- Load a yaml configuration file.
-- The return config will get 2 extra fields; `pid_file` of the nginx process
-- and `dao_config` as a shortcut to the dao configuration
-- @param configuration_path path to configuration file to load
-- @return config Loaded configuration table
-- @return dao_factory the accompanying DAO factory
function _M.load_configuration_and_dao(configuration_path)
local configuration_file = _M.read_file(configuration_path)
if not configuration_file then
error("No configuration file at: "..configuration_path)
end

-- Configuration should already be validated by the CLI at this point
local configuration = yaml.load(configuration_file)

local dao_config = configuration.databases_available[configuration.database]
if dao_config == nil then
error('No "'..configuration.database..'" dao defined')
end

-- Adding computed properties to the configuration
configuration.pid_file = path:join(configuration.nginx_working_dir, constants.CLI.NGINX_PID)

-- Alias the DAO configuration we are using for this instance for easy access
configuration.dao_config = dao_config

-- Load absolute path for the nginx working directory
if not stringy.startswith(configuration.nginx_working_dir, "/") then
-- It's a relative path, convert it to absolute
local fs = require "luarocks.fs"
configuration.nginx_working_dir = fs.current_dir().."/"..configuration.nginx_working_dir
end

-- Instantiate the DAO Factory along with the configuration
local DaoFactory = require("kong.dao."..configuration.database..".factory")
local dao_factory = DaoFactory(dao_config.properties, configuration.plugins_available)

return configuration, dao_factory
end

return _M
5 changes: 4 additions & 1 deletion spec/spec_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
-- It supports other environments by passing a configuration file.

local IO = require "kong.tools.io"
local config = require "kong.tools.config_loader"
local dao = require "kong.tools.dao_loader"
local Faker = require "kong.tools.faker"
local Migrations = require "kong.tools.migrations"
local Threads = require "llthreads2.ex"
Expand Down Expand Up @@ -30,7 +32,8 @@ _M.envs = {}
-- When dealing with another configuration file for a few tests, this allows to add
-- a factory/migrations/faker that are environment-specific to this new config.
function _M.add_env(conf_file)
local env_configuration, env_factory = IO.load_configuration_and_dao(conf_file)
local env_configuration = config.load(conf_file)
local env_factory = dao.load(env_configuration)
_M.envs[conf_file] = {
configuration = env_configuration,
dao_factory = env_factory,
Expand Down
Loading

0 comments on commit d26e179

Please sign in to comment.