diff options
Diffstat (limited to 'p11p-daemon/src/p11p_config.erl')
-rw-r--r-- | p11p-daemon/src/p11p_config.erl | 188 |
1 files changed, 105 insertions, 83 deletions
diff --git a/p11p-daemon/src/p11p_config.erl b/p11p-daemon/src/p11p_config.erl index 330c490..d24aad6 100644 --- a/p11p-daemon/src/p11p_config.erl +++ b/p11p-daemon/src/p11p_config.erl @@ -4,50 +4,85 @@ -module(p11p_config). -behaviour(gen_server). -%% API +%%% API %%% +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). -export([start_link/0]). -%%-export([config/0]). -export([nameof/1]). -export([tokens/0]). -export([proxyapp_bin_path/0, modules_for_token/1, module_path/1, module_env/1, - token_mode/1]). --export_type([token_mode_t/0]). - -%% Genserver callbacks. --export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). + token_balance/1, token_retries/1, token_timeout/1]). -%% Records and types. +%%% Records and types %%% -record(p11module, { name :: string(), path :: string(), - env :: [{string(), string()}] %FIXME: maches [] too? + env :: [{string(), string()}] }). -type p11module() :: #p11module{}. --type token_mode_t() :: {failover, [timeout]} | {balance, [non_neg_integer()]}. - -record(token, { name :: string(), - mode :: token_mode_t(), + timeout :: non_neg_integer(), + failover :: non_neg_integer(), % How many failover attempts. + balance :: [non_neg_integer()], modules = #{} :: #{string() => p11module()} }). -type token() :: #token{}. -%% Genserver state. -record(state, { proxyapp_bin_path :: string(), tokens :: #{string() => token()} }). -%%%%%%%%%%%%%%%%%%%% -%% API. +%%% Genserver callbacks %%% +init(_Args) -> + case application:get_env(p11p, config_file) of + {ok, ConfigFile} -> + {ok, init_state(ConfigFile)}; + _ -> + {ok, init_state()} + end. + +handle_call(proxyapp_bin_path, _From, S = #state{proxyapp_bin_path = Path}) -> + {reply, Path, S}; +handle_call(tokens, _From, State = #state{tokens = Tokens}) -> + {reply, maps:values(Tokens), State}; +handle_call({modules_for_token, TokName}, _, S = #state{tokens = Tokens}) -> + #{TokName := Token} = Tokens, + {reply, maps:values(Token#token.modules), S}; +handle_call({token_balance, TokName}, _, State = #state{tokens = Tokens}) -> + #{TokName := Token} = Tokens, + {reply, Token#token.balance, State}; +handle_call({token_retries, TokName}, _, State = #state{tokens = Tokens}) -> + #{TokName := Token} = Tokens, + {reply, Token#token.failover, State}; +handle_call({token_timeout, TokName}, _, State = #state{tokens = Tokens}) -> + #{TokName := Token} = Tokens, + {reply, Token#token.timeout, State}; +handle_call(Request, _From, State) -> + lager:warning("Unhandled call: ~p", [Request]), + {reply, unhandled, State}. + +handle_cast(Message, State) -> + lager:warning("Unhandled cast: ~p", [Message]), + {noreply, State}. + +handle_info(Info, State) -> + lager:warning("Unhandled info: ~p", [Info]), + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVersion, State, _Extra) -> + {ok, State}. + + +%%% External functions %%% start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). -%% config() -> -%% gen_server:call(?MODULE, config). - proxyapp_bin_path() -> gen_server:call(?MODULE, proxyapp_bin_path). @@ -55,9 +90,17 @@ proxyapp_bin_path() -> tokens() -> gen_server:call(?MODULE, tokens). --spec token_mode(string()) -> token_mode_t(). -token_mode(TokName) -> - gen_server:call(?MODULE, {token_mode, TokName}). +-spec token_balance(string()) -> [integer()]. +token_balance(TokName) -> + gen_server:call(?MODULE, {token_balance, TokName}). + +-spec token_retries(string()) -> non_neg_integer(). +token_retries(TokName) -> + gen_server:call(?MODULE, {token_retries, TokName}). + +-spec token_timeout(string()) -> non_neg_integer(). +token_timeout(TokName) -> + gen_server:call(?MODULE, {token_timeout, TokName}). -spec modules_for_token(string()) -> [p11module()]. modules_for_token(TokName) -> @@ -78,52 +121,28 @@ nameof(#p11module{name = Name}) -> nameof(List) -> [nameof(E) || E <- List]. -%%%%%%%%%%%%%%%%%%%% -%% Genserver callbacks. -init(_Args) -> - State = init_state(), - {ok, State}. - -%% handle_call(config, _From, State) -> -%% {reply, State, State}; -handle_call(proxyapp_bin_path, _From, #state{proxyapp_bin_path = Path} = State) -> - {reply, Path, State}; -handle_call(tokens, _From, #state{tokens = Tokens} = State) -> - {reply, maps:values(Tokens), State}; -handle_call({modules_for_token, TokName}, _, #state{tokens = Tokens} = S) -> - #{TokName := Token} = Tokens, - {reply, maps:values(Token#token.modules), S}; -handle_call({token_mode, TokName}, _, #state{tokens = Tokens} = State) -> - #{TokName := Token} = Tokens, - {reply, Token#token.mode, State}; -handle_call(Request, _From, State) -> - lager:warning("Unhandled call: ~p", [Request]), - {reply, unhandled, State}. - -handle_cast(Message, State) -> - lager:warning("Unhandled cast: ~p", [Message]), - {noreply, State}. - -handle_info(Info, State) -> - lager:warning("Unhandled info: ~p", [Info]), - {noreply, State}. - -terminate(_Reason, _State) -> - ok. - -code_change(_OldVersion, State, _Extra) -> - {ok, State}. - -%%%%%%%%%%%%%%%%%%%% -%% Private. +%%% Private functions %%% +-define(PROXYAPP_DEFAULT, "/usr/local/libexec/p11-kit/p11-kit-remote"). init_state() -> - #state { - proxyapp_bin_path = - application:get_env(p11p, proxyapp_bin_path, - "/usr/local/libexec/p11-kit/p11-kit-remote"), - tokens = conf_tokens(application:get_env(p11p, groups, [])) - }. + #state{ + proxyapp_bin_path = application:get_env(p11p, + proxyapp_bin_path, + ?PROXYAPP_DEFAULT), + tokens = conf_tokens(application:get_env(p11p, + vtokens, + []))}. +init_state(Filename) -> + {ok, Config} = p11p_config_file:load_config(Filename), + #state{ + proxyapp_bin_path = p11p_config_file:get(Config, + string, + "proxyapp_bin_path", + ?PROXYAPP_DEFAULT), + tokens = conf_tokens(p11p_config_file:get(Config, + section, + "vtokens", + []))}. conf_tokens(L) -> conf_tokens(L, #{}). @@ -135,14 +154,20 @@ conf_tokens([H = {Name, _}|T], Acc) -> -spec new_token({string(), [tuple()]}) -> token(). new_token({Name, Settings}) -> Modules = conf_modules(proplists:get_value(modules, Settings)), - Mode = mode(proplists:get_value(mode, Settings, {failover, [timeout]}), %FIXME: s/[timeout]/[10]/g or some other sane default? - maps:size(Modules)), #token{ name = Name, - mode = Mode, + timeout = proplists:get_value(timeout, Settings, 25000), + failover = proplists:get_value(failover, Settings, maps:size(Modules) - 1), + balance = balance(proplists:get_value(balance, Settings, []), + maps:size(Modules)), modules = Modules }. +balance([], _) -> + []; +balance(List, NModules) -> + List ++ [1 || _ <- lists:seq(1, NModules - length(List))]. + conf_modules(L) -> conf_modules(L, #{}). conf_modules([], Acc) -> @@ -159,30 +184,23 @@ new_module(Name, Path, Env) -> env = Env }. --spec mode(p11p_config:token_mode_t(), non_neg_integer()) -> - p11p_config:token_mode_t(). -mode({balance, Args}, NModules) -> - {balance, Args ++ [1 || _ <- lists:seq(1, NModules - length(Args))]}; -mode(Conf, _) -> - Conf. - -%%%%%%%%%%%%%% -%% Unit tests. +%%% Unit tests %%% -include_lib("eunit/include/eunit.hrl"). - tokens_init_test_() -> {setup, fun() -> conf_tokens( [ {"vtoken0", - [{mode, {balance, [3]}}, + [{balance, [3]}, {modules, [{"bogusmod0_0", "/path/to/bogusmod0_0"}, {"bogusmod0_1", "/path/to/bogusmod0_1"} ]}]}, {"vtoken1", - [{modules, [{"bogusmod1_0", "/path/to/bogusmod1_0"}, + [{timeout, 12000}, + {failover, 3}, + {modules, [{"bogusmod1_0", "/path/to/bogusmod1_0"}, {"bogusmod1_1", "/path/to/bogusmod1_1", [{"MYENV", "myenv"}]} ]}]} ]) end, @@ -191,14 +209,18 @@ tokens_init_test_() -> [?_assertEqual( #{"vtoken0" => {token,"vtoken0", - {balance,[3,1]}, + 25000, + 1, + [3,1], #{"bogusmod0_0" => {p11module,"bogusmod0_0", "/path/to/bogusmod0_0", []}, "bogusmod0_1" => {p11module,"bogusmod0_1", "/path/to/bogusmod0_1", []}}}, "vtoken1" => {token,"vtoken1", - {failover,[timeout]}, + 12000, + 3, + [], #{"bogusmod1_0" => {p11module,"bogusmod1_0", "/path/to/bogusmod1_0", []}, "bogusmod1_1" => |