diff options
Diffstat (limited to 'src/simplec_vms.erl')
-rw-r--r-- | src/simplec_vms.erl | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/simplec_vms.erl b/src/simplec_vms.erl new file mode 100644 index 0000000..1d3e076 --- /dev/null +++ b/src/simplec_vms.erl @@ -0,0 +1,191 @@ +%%%------------------------------------------------------------------- +%%% @author Guido <agx@bogon.m.sigxcpu.org> +%%% @copyright (C) 2015, Guido Günther +%%% @doc +%%% +%%% @end +%%% Created : 2 Sep 2015 by Guido <agx@bogon.m.sigxcpu.org> +%%%------------------------------------------------------------------- +-module(simplec_vms). + +-behaviour(gen_server). + +-include("simplec.hrl"). + +%% API +-export([start_link/1]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +-define(SERVER, ?MODULE). +-define(QUERY_INTERVAL, 2000). + +-record(state, {url, verxref, cur}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +%%-------------------------------------------------------------------- +%% @doc +%% Starts the server +%% +%% @spec start_link() -> {ok, Pid} | ignore | {error, Error} +%% @end +%%-------------------------------------------------------------------- +start_link(Args) -> + gen_server:start_link({local, ?SERVER}, ?MODULE, Args, []). + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Initializes the server +%% +%% @spec init(Args) -> {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% @end +%%-------------------------------------------------------------------- +init(Config) -> + Url = Config#config.url, + io:format("Monitoring ~s~n~n", [Url]), + {ok, Ref} = verx_client:start(), + {ok, [1]} = verx:auth_polkit(Ref), + ok = verx:connect_open(Ref, [Url, 0]), + {ok, #state{url=Url, verxref=Ref}, ?QUERY_INTERVAL}. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Handling call messages +%% +%% @spec handle_call(Request, From, State) -> +%% {reply, Reply, State} | +%% {reply, Reply, State, Timeout} | +%% {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, Reply, State} | +%% {stop, Reason, State} +%% @end +%%-------------------------------------------------------------------- +handle_call(Request, _From, State) -> + io:format("Call ~s~n~n", [Request]), + Reply = ok, + {reply, Reply, State}. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Handling cast messages +%% +%% @spec handle_cast(Msg, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% @end +%%-------------------------------------------------------------------- +handle_cast(Msg, State) -> + io:format("Msg ~s~n~n", [Msg]), + {noreply, State}. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Handling all non call/cast messages +%% +%% @spec handle_info(Info, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% @end +%%-------------------------------------------------------------------- +handle_info(timeout, State) -> + {ok, Res} = get_addresses(State#state.verxref), + case Res == State#state.cur of + false -> print_addresses(Res), + simplec_hostsfile:write(Res); + true -> true + end, + {noreply, State#state{cur=Res}, ?QUERY_INTERVAL}; +handle_info(Info, State) -> + io:format("Info ~s~n~n", [Info]), + {noreply, State}. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% This function is called by a gen_server when it is about to +%% terminate. It should be the opposite of Module:init/1 and do any +%% necessary cleaning up. When it returns, the gen_server terminates +%% with Reason. The return value is ignored. +%% +%% @spec terminate(Reason, State) -> void() +%% @end +%%-------------------------------------------------------------------- +terminate(_Reason, State) -> + io:format("Terminating"), + ok = verx:connect_close(State#state.verxref), + ok = verx_client:stop(State#state.verxref), + ok. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Convert process state when code is changed +%% +%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState} +%% @end +%%-------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +filter_addresses(Addrs) -> + [ begin + {_Iface, _Mac, [{_Type, Addr, _Netmask}]} = A, + Addr + end || A <- Addrs ]. + + +addresses(Ref, Domain) -> + {ok, [Addrs]} = verx:domain_interface_addresses(Ref, [Domain, 0, 0]), + Addrs. + + +domains(Ref, IDs) -> + [ begin + {ok, [Domain]} = verx:domain_lookup_by_id(Ref, [N]), + Domain + end || N <- IDs ]. + + +print_addr({Name, Adresses}) -> + io:format("~20s: ", [Name]), + [ io:format("~s ", [A]) || A <- Adresses ], + io:format("~n"). + + +print_addresses(Res) -> + [ print_addr(R) || R <- Res ], + io:format("~n"). + + +get_addresses(Ref) -> + {ok, [NumRun]} = verx:connect_num_of_domains(Ref), + {ok, [Running]} = verx:connect_list_domains(Ref, [NumRun]), + + Domains = domains(Ref, Running), + Res = [ begin + {Name, _, _} = D, + Addrs = addresses(Ref, D), + {Name, filter_addresses(Addrs)} + end || D <- Domains ], + {ok, Res}. |