aproxy/config.lua

121 lines
4.0 KiB
Lua

local env_config_path = os.getenv('APROXY_CONFIG_PATH')
local DEFAULT_CONFIG_PATH = ".;/etc/aproxy"
local config_path = env_config_path or DEFAULT_CONFIG_PATH
local function findConfigFile()
for _, config_directory in ipairs(string.split(config_path, ";")) do
local possible_config_path = config_directory .. "/" .. "conf.lua"
local fd, res = io.open(possible_config_path, "rb")
if fd then
local data = fd:read("*a")
fd:close()
return data
else
log('config not found at ' .. possible_config_path .. ':' .. tostring(res))
end
end
return nil
end
local function insertError(errors, key, message)
errors[key] = errors[key] or {}
table.insert(errors[key], message)
return errors
end
local function fakeTableSchema(value_schema)
return setmetatable({ __list = true }, {
__index = function ()
return value_schema
end
})
end
local SPECIAL_KEYS = {__list = true}
local function validateSchema(schema, input, errors_in)
local errors = errors_in or {}
if schema.__list then
-- generate full schema for lists that are same size as input
for k, _ in pairs(input) do schema[k] = schema.__schema_value end
end
for key, field_schema in pairs(schema) do
if not SPECIAL_KEYS[key] then
assert(field_schema, 'schema not provided')
local input_value = input[key]
local input_type = type(input_value)
local wanted_type = field_schema.type
local actual_wanted_type = wanted_type
if wanted_type == 'list' then
actual_wanted_type = 'table'
end
if input_type == actual_wanted_type then
if wanted_type == 'table' then
-- recursive schema validation for generic tables
errors[key] = errors[key] or {}
validateSchema(field_schema.schema, input_value, errors[key])
if next(errors[key]) == nil then
errors[key] = nil
end
elseif wanted_type == 'list' then
-- for lists (which only have schemas for values), interpret
-- it differently
errors[key] = errors[key] or {}
validateSchema(fakeTableSchema(field_schema.schema), input_value, errors[key])
if next(errors[key]) == nil then
errors[key] = nil
end
end
else
insertError(
errors, key,
string.format('wanted %s but got %s', tostring(wanted_type), tostring(input_type))
)
end
end
end
return errors
end
local function validateConfigFile(config_object)
local all_schema_errors = {}
for module_name, module_config in pairs(config_object.wantedScripts) do
local module_manifest = require('scripts.' .. module_name)
local config_schema = module_manifest.config
local schema_errors = validateSchema(config_schema, module_config)
if schema_errors then
all_schema_errors[module_name] = schema_errors
end
end
return all_schema_errors
end
local function loadConfigFile(options_in)
local options = options_in or {}
local config_file_data = assert(findConfigFile(), 'no config file found, config path: ' .. config_path)
local config_file_function = assert(loadstring(config_file_data))
local config_object = config_file_function()
if options.validate then
local schema_errors = validateConfigFile(config_object)
local total_count = table.pprint(schema_errors, {call=function() end})
if total_count > 0 then
log('CONFIG ERROR')
table.pprint(schema_errors, {call=log})
end
end
return config_object
end
return {
loadConfigFile=loadConfigFile,
validateSchema=validateSchema,
}