summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Ahltorp <map@kth.se>2017-01-27 02:02:39 +0100
committerMagnus Ahltorp <map@kth.se>2017-01-27 02:03:24 +0100
commitd4793aea4dfbf1862bf6ca8eb5cf4279a41b36a4 (patch)
tree0814d4181a2cc946f3ada50f3e9c2b2b43eba7b8
parent7b114604595b2e3bb0816ffb01548b02c43cdea5 (diff)
Separate erlang config file for reloadable parameters
-rw-r--r--src/http_auth.erl4
-rw-r--r--src/plop.erl4
-rw-r--r--src/plop_app.erl1
-rw-r--r--src/plop_sup.erl3
-rw-r--r--src/plopconfig.erl57
-rw-r--r--src/plopcontrol.erl44
-rw-r--r--src/sign.erl4
7 files changed, 110 insertions, 7 deletions
diff --git a/src/http_auth.erl b/src/http_auth.erl
index 16d7dfa..3bd18b1 100644
--- a/src/http_auth.erl
+++ b/src/http_auth.erl
@@ -20,7 +20,7 @@ read_key_table() ->
lists:foreach(
fun ({KeyName, Der}) ->
true = ets:insert(?KEY_TABLE, {KeyName, sign:pem_entry_decode({'SubjectPublicKeyInfo', Der, []})})
- end, application:get_env(plop, apikeys, [])),
+ end, plopconfig:get_env(apikeys, [])),
case application:get_env(plop, own_key, none) of
{_OwnKeyName, OwnKeyFile} ->
OwnKey = sign:read_keyfile_ec(OwnKeyFile),
@@ -72,7 +72,7 @@ check_acl(Method, KeyName, Path) ->
_ ->
allowed_clients
end,
- ACL = application:get_env(plop, EnvVarName, []),
+ ACL = plopconfig:get_env(EnvVarName, []),
lager:debug("ACL: ~p", [ACL]),
case lists:keyfind(Path, 1, ACL) of
{_, noauth} ->
diff --git a/src/plop.erl b/src/plop.erl
index 4ad0b98..fcc964b 100644
--- a/src/plop.erl
+++ b/src/plop.erl
@@ -210,10 +210,10 @@ testing_get_pubkey() ->
sign:get_pubkey().
storage_nodes() ->
- application:get_env(plop, storage_nodes, []).
+ plopconfig:get_env(storage_nodes, []).
storage_nodes_quorum() ->
- {ok, Value} = application:get_env(plop, storage_nodes_quorum),
+ {ok, Value} = plopconfig:get_env(storage_nodes_quorum),
Value.
send_http_request(TreeLeafHash, URL, Headers, RequestBody) ->
diff --git a/src/plop_app.erl b/src/plop_app.erl
index 12f52ee..c51e6e4 100644
--- a/src/plop_app.erl
+++ b/src/plop_app.erl
@@ -7,6 +7,7 @@
start(normal, Args) ->
hackney:start(),
+ plopconfig:init_table(),
http_auth:init_key_table(),
plop:initsize(),
perm:init_module(),
diff --git a/src/plop_sup.erl b/src/plop_sup.erl
index 55d6e9a..6bac20e 100644
--- a/src/plop_sup.erl
+++ b/src/plop_sup.erl
@@ -48,7 +48,8 @@ init([]) ->
]),
Children = [permanent_worker(the_db, {db, start_link, []}, [db]),
permanent_worker(the_storagedb, {storagedb, start_link, []}),
- permanent_worker(fsync, {fsyncport, start_link, []})],
+ permanent_worker(fsync, {fsyncport, start_link, []}),
+ permanent_worker(plopcontrol, {plopcontrol, start_link, []})],
OptionalChildren = lists:map(fun (ServiceName) ->
case ServiceName of
ht ->
diff --git a/src/plopconfig.erl b/src/plopconfig.erl
new file mode 100644
index 0000000..00b29df
--- /dev/null
+++ b/src/plopconfig.erl
@@ -0,0 +1,57 @@
+%%% Copyright (c) 2017, NORDUnet A/S.
+%%% See LICENSE for licensing information.
+
+-module(plopconfig).
+-export([get_env/1, get_env/2, init_table/0, load_config/0]).
+
+-define(PLOPCONFIG_TABLE, plopconfig).
+
+init_table() ->
+ case ets:info(?PLOPCONFIG_TABLE) of
+ undefined ->
+ ok;
+ _ ->
+ ets:delete(?PLOPCONFIG_TABLE)
+ end,
+ ets:new(?PLOPCONFIG_TABLE, [set, public, named_table]),
+ load_config().
+
+keys() ->
+ KeyList = lists:map(fun ({Key, _Value}) -> Key end,
+ ets:tab2list(?PLOPCONFIG_TABLE)),
+ sets:from_list(KeyList).
+
+load_config() ->
+ {ok, Filename} = application:get_env(plop, plopconfig),
+ {ok, File} = file:consult(Filename),
+ OldKeys = keys(),
+ lists:foreach(
+ fun ({Key, Value}) ->
+ true = ets:insert(?PLOPCONFIG_TABLE, {Key, Value})
+ end, hd(File)),
+ NewKeys = keys(),
+ RemovedKeys = sets:subtract(OldKeys, NewKeys),
+ lists:foreach(fun (Key) ->
+ ets:delete(?PLOPCONFIG_TABLE, Key)
+ end, sets:to_list(RemovedKeys)),
+ lager:info("loaded config: new keys ~p old keys ~p removed keys ~p",
+ [sets:to_list(NewKeys),
+ sets:to_list(OldKeys),
+ sets:to_list(RemovedKeys)]),
+ ok.
+
+get_env(Key, DefaultValue) ->
+ case get_env(Key) of
+ {ok, Value} ->
+ Value;
+ _ ->
+ DefaultValue
+ end.
+
+get_env(Key) ->
+ case ets:lookup(?PLOPCONFIG_TABLE, Key) of
+ [{_, Value}] ->
+ {ok, Value};
+ [] ->
+ undefined
+ end.
diff --git a/src/plopcontrol.erl b/src/plopcontrol.erl
new file mode 100644
index 0000000..de7faba
--- /dev/null
+++ b/src/plopcontrol.erl
@@ -0,0 +1,44 @@
+%%% Copyright (c) 2017, NORDUnet A/S.
+%%% See LICENSE for licensing information.
+
+-module(plopcontrol).
+-export([start_link/0, server_start/2]).
+
+start_link() ->
+ case gen_tcp:listen(application:get_env(plop, plopcontrolport, 0), [binary, {packet, line},
+ {active, false},
+ {ip, {127, 0, 0, 1}}]) of
+ {ok, ListenSocket} ->
+ proc_lib:start_link(?MODULE,server_start,[self(), ListenSocket]);
+ {error,Reason} ->
+ {error,Reason}
+ end.
+
+server_start(Parent, ListenSocket) ->
+ proc_lib:init_ack(Parent, {ok, self()}),
+ {ok, Port} = inet:port(ListenSocket),
+ {ok, PlopcontrolFile} = application:get_env(plop, plopcontrol),
+ atomic:replacefile(PlopcontrolFile, integer_to_list(Port)),
+ acceptloop(ListenSocket).
+
+acceptloop(ListenSocket) ->
+ {ok, Socket} = gen_tcp:accept(ListenSocket),
+ commandloop(Socket),
+ acceptloop(ListenSocket).
+
+commandloop(Socket) ->
+ case gen_tcp:recv(Socket, 0) of
+ {ok, Packet} ->
+ Answer = command(Packet),
+ gen_tcp:send(Socket, Answer),
+ commandloop(Socket);
+ {error, _Reason} ->
+ ok
+ end.
+
+command(<<"reload\n">>) ->
+ plopconfig:load_config(),
+ "reload completed\n";
+
+command(_) ->
+ "unknown command\n".
diff --git a/src/sign.erl b/src/sign.erl
index 99b83e6..6e0e0bd 100644
--- a/src/sign.erl
+++ b/src/sign.erl
@@ -151,7 +151,7 @@ remote_sign_request([URL|RestURLs], Request) ->
sign_sct(Data = <<_Version:8,
?CERTIFICATE_TIMESTAMP:8,
_/binary>>) ->
- case application:get_env(plop, signing_nodes) of
+ case plopconfig:get_env(signing_nodes) of
{ok, URLBases} ->
Request = {[{plop_version, 1},
{data, base64:encode(Data)}
@@ -164,7 +164,7 @@ sign_sct(Data = <<_Version:8,
sign_sth(Data = <<_Version:8,
?TREE_HASH:8,
_/binary>>) ->
- case application:get_env(plop, signing_nodes) of
+ case plopconfig:get_env(signing_nodes) of
{ok, URLBases} ->
Request = {[{plop_version, 1},
{data, base64:encode(Data)}