Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 110 lines (95 sloc) 4.085 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2011 Basho Technologies, Inc. All Rights Reserved.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License. You may obtain
%% a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations
%% under the License.
%%
%% -------------------------------------------------------------------

-module(admin_cluster).
-export([routes/0,
         init/1,
         content_types_provided/2,
         to_json/2,
         is_authorized/2,
         service_available/2
        ]).

%% riak_control and webmachine dependencies
-include_lib("riak_control/include/riak_control.hrl").
-include_lib("webmachine/include/webmachine.hrl").

%% mappings to the various content types supported for this resource
-define(CONTENT_TYPES,[{"application/json",to_json}]).

%% defines the webmachine routes this module handles
routes () ->
    [{admin_routes:cluster_route(["list"]),?MODULE,list},
     {admin_routes:cluster_route(["join",node]),?MODULE,join},
     {admin_routes:cluster_route(["down",node]),?MODULE,down}].

%% entry-point for the resource from webmachine
init (Action) ->
    {ok,Action}.

%% redirect to SSL port if using HTTP
service_available (RD,C) ->
    riak_control_security:scheme_is_available(RD,C).

%% validate username and password
is_authorized (RD,C) ->
    riak_control_security:enforce_auth(RD,C).

%% return the list of available content types for webmachine
content_types_provided (Req,C) ->
    {?CONTENT_TYPES,Req,C}.

%% all actions return the same format
cluster_action_result (Error={error,_},Req,C) ->
    {{error,mochijson2:encode({struct,[Error]})},Req,C};
cluster_action_result (Error={badrpc,_},Req,C) ->
    {{error,mochijson2:encode({struct,[Error]})},Req,C};
cluster_action_result (_,Req,C) ->
    {mochijson2:encode({struct,[{result,ok}]}),Req,C}.

%% get a list of all the nodes in the ring and their status
to_json (Req,C=list) ->
    {ok,_V,Nodes}=riak_control_session:get_nodes(),
    Status=[{struct,[{"name",Node#member_info.node},
                     {"status",Node#member_info.status},
                     {"reachable",Node#member_info.reachable},
                     {"ring_pct",Node#member_info.ring_pct},
                     {"pending_pct",Node#member_info.pending_pct},
                     {"mem_total",Node#member_info.mem_total},
                     {"mem_used",Node#member_info.mem_used},
                     {"mem_erlang",Node#member_info.mem_erlang},
                     {"me",Node#member_info.node == node()}
                    ]}
            || Node=#member_info{} <- Nodes],
    {mochijson2:encode(Status),Req,C};

%% join this node to the cluster of another ring
to_json (Req,C=join) ->
    {ok,Ring}=riak_core_ring_manager:get_my_ring(),
    NodeStr=dict:fetch(node,wrq:path_info(Req)),
    Node=list_to_atom(NodeStr),

    %% if we're a member of a single-node cluster (us) then we're
    %% going to join the other node's ring, otherwise we'll make
    %% the target node join our ring.
    case riak_core_ring:all_members(Ring) of
        [_Me] ->
            %% we're a single-node cluster, join the other guy...
            Result=riak_core:join(Node),
            cluster_action_result(Result,Req,C);
        _ ->
            %% we have a cluster, make them join us
            Result=rpc:call(Node,riak_core,join,[node()]),
            cluster_action_result(Result,Req,C)
    end;

%% mark a node in the cluster as down
to_json (Req,C=down) ->
    NodeStr=dict:fetch(node,wrq:path_info(Req)),
    Node=list_to_existing_atom(NodeStr),
    Result=riak_core:down(Node),
    cluster_action_result(Result,Req,C).

Something went wrong with that request. Please try again.