summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Doane <jay.s.doane@gmail.com>2019-02-12 14:57:37 -0800
committerGitHub <noreply@github.com>2019-02-12 14:57:37 -0800
commite699fe6859eb4fb32eafbd637cda1fc7d5e9043a (patch)
tree90a781dfbbd15c19ca1828637babbd23eb69c4fa
parentb46df8c8d3c96eadb07d540b82fcb992e6da2a82 (diff)
parenta6c1988c5db4993487ea627cc6009e1f5d51d367 (diff)
downloadcouchdb-e699fe6859eb4fb32eafbd637cda1fc7d5e9043a.tar.gz
Merge pull request #1803 from cloudant/configurable-auth-salt
Sync admin passwords at cluster setup finish
-rw-r--r--src/setup/src/setup.erl66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/setup/src/setup.erl b/src/setup/src/setup.erl
index 3ae455f54..9437fbc07 100644
--- a/src/setup/src/setup.erl
+++ b/src/setup/src/setup.erl
@@ -198,9 +198,75 @@ setup_node(NewCredentials, NewBindAddress, NodeCount, Port) ->
finish_cluster(Options) ->
+ ok = wait_connected(),
+ ok = sync_admins(),
Dbs = proplists:get_value(ensure_dbs_exist, Options, cluster_system_dbs()),
finish_cluster_int(Dbs, has_cluster_system_dbs(Dbs)).
+
+wait_connected() ->
+ Nodes = other_nodes(),
+ Result = test_util:wait(fun() ->
+ case disconnected(Nodes) of
+ [] -> ok;
+ _ -> wait
+ end
+ end),
+ case Result of
+ timeout ->
+ Reason = "Cluster setup timed out waiting for nodes to connect",
+ throw({setup_error, Reason});
+ ok ->
+ ok
+ end.
+
+
+other_nodes() ->
+ mem3:nodes() -- [node()].
+
+
+disconnected(Nodes) ->
+ lists:filter(fun(Node) ->
+ case net_adm:ping(Node) of
+ pong -> false;
+ pang -> true
+ end
+ end, Nodes).
+
+
+sync_admins() ->
+ ok = lists:foreach(fun({User, Pass}) ->
+ sync_admin(User, Pass)
+ end, config:get("admins")).
+
+
+sync_admin(User, Pass) ->
+ {Results, Errors} = rpc:multicall(other_nodes(), config, set,
+ ["admins", User, Pass]),
+ case validate_multicall(Results, Errors) of
+ ok ->
+ ok;
+ error ->
+ log:error("~p sync_admin results ~p errors ~p",
+ [?MODULE, Results, Errors]),
+ Reason = "Cluster setup unable to sync admin passwords",
+ throw({setup_error, Reason})
+ end.
+
+
+validate_multicall(Results, Errors) ->
+ AllOk = lists:all(fun
+ (ok) -> true;
+ (_) -> false
+ end, Results),
+ case AllOk andalso Errors == [] of
+ true ->
+ ok;
+ false ->
+ error
+ end.
+
+
finish_cluster_int(_Dbs, true) ->
{error, cluster_finished};
finish_cluster_int(Dbs, false) ->