Files
wlan-cloud-loadsim/src/utils.erl
Stephane Bourque d44d684cec Fixing API
2021-01-02 18:24:11 -08:00

369 lines
10 KiB
Erlang

%%%-------------------------------------------------------------------
%%% @author stephb
%%% @copyright (C) 2020, Arilia Wireless Inc.
%%% @doc
%%%
%%% @end
%%% Created : 15. Nov 2020 9:47 a.m.
%%%-------------------------------------------------------------------
-module(utils).
-author("stephb").
-include("../include/common.hrl").
%% API
-export([ make_dir/1,uuid/0,get_addr/0,get_addr2/0,app_name/0,app_name/1,priv_dir/0,app_env/2,to_string_list/2,to_binary_list/2,print_nodes_info/1,
do/2,pem_to_cert/1,pem_to_key/1,safe_binary/1,uuid_b/0,pem_key_is_encrypted/1,remove_pem_key_password/3,
noop/0,noop_mfa/0,split_into/2,select/3,adjust/2,apply_ntimes/4,
get_avg/1, new_avg/0,compute_avg/2,search_replace/3,json_node_info/1,
to_atom_list/2,to_atom_list/1,to_string_list/1,to_binary_list/1,
dump_data_in_file/2,identify/1,json_to_band/1,band_to_json/1,create_version/0,modify_mac/2]).
-type average() :: { CurrentValue::number(), HowManyValues::integer(), PastValues::[number()]}.
-export_type([average/0]).
-spec make_dir( DirName::string() ) -> ok | { error, atom() }.
make_dir(DirName)->
case file:make_dir(DirName) of
ok -> ok;
{error,eexist} -> ok;
Error -> Error
end.
-spec uuid()->string().
uuid()->
uuid:uuid_to_string(uuid:get_v4()).
-spec uuid_b()->binary().
uuid_b()->
list_to_binary(uuid:uuid_to_string(uuid:get_v4())).
-spec get_addr() -> IpAddress::string().
get_addr()->
{ok,Ifs} = inet:getifaddrs(),
case strip_ifs(Ifs) of
none -> "0.0.0.0";
[A|_] -> inet:ntoa(A)
end.
-spec get_addr2() -> IpAddress::string().
get_addr2()->
Node=atom_to_list(node()),
[_,Host]=string:tokens(Node,"@"),
case inet:gethostbyname(Host) of
{ok,{hostent,_Host2,_,inet,4,[Address1|_]}} ->
inet:ntoa(Address1);
Error->
Error
end.
-spec app_name( AppName::atom() )->ok.
app_name(AppName)->
persistent_term:put(running_app,AppName),
{ ok, RootDir } = file:get_cwd(),
PrivDir = filename:join([RootDir,"priv/"]),
persistent_term:put(priv_dir,PrivDir).
-spec app_name()->AppName::atom().
app_name()->
persistent_term:get(running_app).
-spec priv_dir()->DirName::string().
priv_dir()->
persistent_term:get(priv_dir).
-spec app_env(Key::atom(),Default::term())->Value::term().
app_env(Key,Default)->
application:get_env(app_name(),Key,Default).
print_nodes_info(Nodes)->
io:format("---------------------------------------------------------------------------------------------------------~n"),
io:format("|Node name | Total | Allocated | Biggest | Procs | Type |~n"),
io:format("---------------------------------------------------------------------------------------------------------~n"),
print_line(Nodes),
io:format("---------------------------------------------------------------------------------------------------------~n").
-spec json_node_info([{node(),atom()}])->binary().
json_node_info(Nodes)->
json_node_info(Nodes,[]).
json_node_info([],Acc)->
jiffy:encode(Acc);
json_node_info([{H,Type}|T],Acc)->
NodeInfo = node_info(H),
%% #{ total := Total , allocated := Allocated , worst := Worst , processes := Processes } = NodeInfo,
json_node_info(T,[NodeInfo#{ type => Type} |Acc]).
print_line([])->
ok;
print_line([{Node,Type}|T])->
NodeInfo = node_info(Node),
#{ total := Total , allocated := Allocated , worst := Worst , processes := Processes } = NodeInfo,
io:format("|~37s |~9.2f MB |~9.2f MB | ~9.2f MB | ~7b | ~10s|~n",[atom_to_list(Node),Total,Allocated,Worst,Processes,atom_to_list(Type)]),
print_line(T).
-spec node_info(Node::node())->#{ atom() => term()}.
node_info(Node)->
try
{Total,Allocated,{ _Pid, Worst}}=rpc:call(Node,memsup,get_memory_data,[]),
Processes = rpc:call(Node,cpu_sup,nprocs,[]),
#{ node => atom_to_binary(Node), total => Total/(1 bsl 20), allocated => Allocated/(1 bsl 20), worst => Worst/(1 bsl 20), processes => Processes }
catch
_:_ ->
#{ node => atom_to_binary(Node), total => 0, allocated => 0, worst => 0, processes => 0 }
end.
-spec apply_ntimes(Times::integer(),M::atom(),F::atom(),A::term())->[any()].
apply_ntimes(Times,M,F,A)->
apply_ntimes(Times,M,F,A,[]).
apply_ntimes(0,_,_,_,Acc)->
lists:reverse(Acc);
apply_ntimes(Times,M,F,A,Acc)->
R = apply(M,F,A),
apply_ntimes(Times-1,M,F,A,[R|Acc]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Local functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
strip_ifs(Ifs)->
strip_ifs(Ifs,[]).
strip_ifs([],[])->
none;
strip_ifs([],GoodAddresses)->
lists:reverse(GoodAddresses);
strip_ifs([{_IfName,Ifprops}|Tail],Addrs)->
Ifs=proplists:lookup_all(addr,Ifprops),
case Ifs of
[] ->
strip_ifs(Tail,Addrs);
Ifs ->
case good_address(Ifs) of
none ->
strip_ifs(Tail,Addrs);
Addr->
strip_ifs(Tail,[Addr|Addrs])
end
end.
good_address([])->
none;
good_address([{addr,{127,_,_,_}}|T]) ->
good_address(T);
good_address([{addr,{A,B,C,D}}|_Tail]) when A=/=127 ->
{A,B,C,D};
good_address([_|T])->
good_address(T).
to_string_list(L)->
to_string_list(L,[]).
to_atom_list(L)->
to_atom_list(L,[]).
to_binary_list(L)->
to_binary_list(L,[]).
-spec to_string_list([term()],[term()])->[string()].
to_string_list([],R)->
lists:reverse(R);
to_string_list([H|T],R) when is_list(H)->
to_string_list(T,[H|R]);
to_string_list([H|T],R) when is_atom(H)->
to_string_list(T,[atom_to_list(H)|R]);
to_string_list([H|T],R) when is_binary(H)->
to_string_list(T,[binary_to_list(H)|R]).
-spec to_binary_list([term()],[term()])->[string()].
to_binary_list([],R)->
lists:reverse(R);
to_binary_list([H|T],R) when is_list(H)->
to_binary_list(T,[list_to_binary(H)|R]);
to_binary_list([H|T],R) when is_atom(H)->
to_binary_list(T,[list_to_binary(atom_to_list(H))|R]);
to_binary_list([H|T],R) when is_binary(H)->
to_binary_list(T,[H|R]).
-spec to_atom_list([term()],[term()])->[string()].
to_atom_list([],R)->
lists:reverse(R);
to_atom_list([H|T],R) when is_list(H)->
to_atom_list(T,[list_to_atom(H)|R]);
to_atom_list([H|T],R) when is_atom(H)->
to_atom_list(T,[H|R]);
to_atom_list([H|T],R) when is_binary(H)->
to_atom_list(T,[binary_to_atom(H)|R]).
-spec do(boolean(),{atom(),atom(),term()})->ok.
do(true,{M,F,A})->
_=apply(M,F,A), ok;
do(false,_)->
ok.
pem_to_cert(FileName) when is_binary(FileName)->
pem_to_cert(binary_to_list(FileName));
pem_to_cert(FileName) when is_list(FileName)->
try
{ok,FileData}=file:read_file(FileName),
[{'Certificate',Cert,_}] = public_key:pem_decode(FileData),
{ ok , Cert }
catch
_:_ ->
{error,error_no_pem_file}
end.
pem_to_key(FileName) when is_binary(FileName)->
pem_to_key(binary_to_list(FileName));
pem_to_key(FileName) when is_list(FileName)->
try
{ok,FileData}=file:read_file(FileName),
[{T,K,_}]=public_key:pem_decode(FileData),
{ ok , {T,K}}
catch
_:_ ->
{error,error_no_pem_file}
end.
pem_key_is_encrypted(FileName) when is_binary(FileName)->
pem_to_key(binary_to_list(FileName));
pem_key_is_encrypted(FileName) when is_list(FileName)->
try
{ok,FileData}=file:read_file(FileName),
[{_,_,not_encrypted}]=public_key:pem_decode(FileData),
false
catch
_:_ ->
true
end.
-spec remove_pem_key_password(Password::string(),InFileName::string(),OutFileName::string()) -> boolean().
remove_pem_key_password(Password,InFileName,OutFilename)->
try
Cmd = io_lib:format("openssl rsa -passin pass:~s -in ~s -out ~s",[Password,InFileName,OutFilename]),
_Result = os:cmd(Cmd),
not pem_key_is_encrypted(OutFilename)
catch
_:_ ->
false
end.
-spec noop_mfa()->notification_cb().
noop_mfa()->
{utils,noop,[]}.
-spec noop()->ok.
noop()->
ok.
-spec safe_binary(binary()|string()|atom()|integer())->binary().
safe_binary(X) when is_binary(X)->
X;
safe_binary(X) when is_list(X)->
list_to_binary(X);
safe_binary(X) when is_atom(X)->
atom_to_binary(X);
safe_binary(X) when is_integer(X)->
integer_to_binary(X).
-spec split_into([term()],[term()])->[{term(),[term()]}].
split_into( A, B )->
LA = length(A),
LB = length(B),
Batch = LB div LA,
split_it(A,B,1,Batch,LB,[]).
split_it([H|T],B,Pos,Size,LB,Acc) when (Pos < LB) ->
SubList = lists:sublist(B,Pos,Size),
split_it(T,B,Pos+Size,Size,LB,[{H,SubList}|Acc]);
split_it(_,_,_,_,_,Acc)->
lists:reverse(Acc).
select(true,A,_B) ->A;
select(false,_A,B)->B.
-spec adjust(Max::integer(),Divisor::integer())->integer().
adjust(_Max,0)->
0;
adjust(Max,Divisor)->
min(Max, Max - ( Max rem Divisor)).
-spec new_avg()-> average().
new_avg()->
{0,10,[]}.
-spec compute_avg(number(),average())->average().
compute_avg(V,Avg)->
{_,L,Values}=Avg,
case length(Values) == L of
true ->
NV = [V|tl(Values)],
NewAverage = lists:sum(NV) / L,
{ NewAverage, L, NV };
false ->
NV = [V|Values],
NewAverage = lists:sum(NV) / length(NV),
{ NewAverage, L, NV }
end.
-spec get_avg(average())->number().
get_avg({V,_,_})->
V.
safe_list(I) when is_binary(I)->
binary_to_list(I);
safe_list(I) when is_list(I)->
I.
replace_data(Data,[])->
Data;
replace_data(Data,[{From,To}|T])->
NewData = string:replace(Data,From,To,all),
replace_data(NewData,T).
-spec search_replace(Infile::binary()|string(),OutFile::binary()|string(),[{From::string(),To::string()}]) -> ok.
search_replace(InFile,OutFile,Elements)->
{ ok , InData } = file:read_file(safe_list(InFile)),
NewData = replace_data(binary_to_list(InData),Elements),
file:write_file(safe_list(OutFile),list_to_binary(NewData)).
identify(D) when is_list(D) -> list;
identify(D) when is_binary(D) -> binary;
identify(D) when is_map(D) -> map;
identify(D) when is_integer(D) -> integer;
identify(_) -> unknown.
-spec dump_data_in_file(FileName::string(),Data::binary())->ok.
dump_data_in_file(FileName,Data)->
try
{ok,IoDev}=file:open(FileName,[append]),
io:fwrite(IoDev,"~s~n~n~n",[Data]),
_=file:close(IoDev),
ok
catch
_:_ -> ok
end.
-spec band_to_json(atom()) -> binary().
band_to_json('BAND2G') -> <<"2.4G">>;
band_to_json('BAND5G') -> <<"5G">>;
band_to_json('BAND5GL') -> <<"5GL">>;
band_to_json('BAND5GU') -> <<"5GU">>;
band_to_json(_) -> <<"2.4G">>.
-spec json_to_band(Band::binary())-> atom().
json_to_band(<<"2.4G">>) -> 'BAND2G';
json_to_band(<<"5G">>) -> 'BAND5G';
json_to_band(<<"5GL">>) -> 'BAND5GL';
json_to_band(<<"5GU">>) -> 'BAND5GU';
json_to_band(_) -> 'BAND2G'.
create_version()->
[<<"uuid">>,utils:uuid_b()].
modify_mac(MAC,N) ->
[X1,X2,$:,X3,X4,$:,X5,X6,$:,X7,X8,$:,X9,X10,$:,X11,_X12] = binary_to_list(MAC),
list_to_binary([X1,X2,$:,X3,X4,$:,X5,X6,$:,X7,X8,$:,X9,X10,$:,X11,N+$0]).