Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

merged master.

  • Loading branch information...
commit d9454b2d4963837aabf03306d531b4135681c24c 2 parents ac17bd6 + 9bc2c85
@Licenser Licenser authored
View
1  .gitignore
@@ -1,3 +1,4 @@
+apps/wiggle/src/wiggle_version.hrl
apps/wiggle/.eunit/
rel/pkg/packlist
rel/pkg/*.tgz
View
10 Makefile
@@ -1,10 +1,13 @@
REBAR = $(shell pwd)/rebar
-.PHONY: deps rel stagedevrel
+.PHONY: deps rel stagedevrel version
all: deps compile
-compile:
+version:
+ echo "-define(VERSION, <<\"$(shell git symbolic-ref HEAD 2> /dev/null | cut -b 12-)-$(shell git log --pretty=format:'%h, %ad' -1)\">>)." > apps/wiggle/src/wiggle_version.hrl
+
+compile: version
$(REBAR) compile
deps:
@@ -30,6 +33,9 @@ relclean:
package: rel
make -C rel/pkg package
+console: all
+ erl -pa deps/*/ebin apps/*/ebin -s wiggle -config standalone.config
+
###
### Docs
###
View
3  apps/wiggle/src/wiggle.app.src
@@ -1,13 +1,14 @@
{application, wiggle,
[
{description, ""},
- {vsn, "0.4.0"},
+ {vsn, "0.4.1"},
{registered, []},
{applications, [
kernel,
stdlib,
libsnarl,
libsniffle,
+ libhowl,
jsx,
lager,
mimetypes,
View
1  apps/wiggle/src/wiggle.erl
@@ -6,6 +6,7 @@
start() ->
application:start(mdns_client_lib),
+ application:start(libsnarlmatch),
application:start(libsnarl),
application:start(libsniffle),
application:start(jsx),
View
30 apps/wiggle/src/wiggle_app.erl
@@ -14,23 +14,21 @@ start(_StartType, _StartArgs) ->
{ok, Port} = application:get_env(wiggle, port),
{ok, Acceptors} = application:get_env(wiggle, acceptors),
- Dispatch = [
- {'_', [
- {[<<"api">>, '_', <<"users">>, '...'], wiggle_user_handler, []},
- {[<<"api">>, '_', <<"groups">>, '...'], wiggle_group_handler, []},
-
- {[<<"api">>, '_', <<"cloud">>, '...'], wiggle_cloud_handler, []},
- {[<<"api">>, '_', <<"hypervisors">>, '...'], wiggle_hypervisor_handler, []},
- {[<<"api">>, '_', <<"vms">>, '...'], wiggle_vm_handler, []},
- {[<<"api">>, '_', <<"ipranges">>, '...'], wiggle_iprange_handler, []},
- {[<<"api">>, '_', <<"datasets">>, '...'], wiggle_dataset_handler, []},
- {[<<"api">>, '_', <<"packages">>, '...'], wiggle_package_handler, []}
- ]}
- ],
+ Dispatch = [{'_', [{[<<"api">>, '_', <<"users">>, '...'], wiggle_user_handler, []},
+ {[<<"api">>, '_', <<"groups">>, '...'], wiggle_group_handler, []},
+ {[<<"api">>, '_', <<"cloud">>, '...'], wiggle_cloud_handler, []},
+ {[<<"api">>, '_', <<"hypervisors">>, '...'], wiggle_hypervisor_handler, []},
+ {[<<"api">>, '_', <<"vms">>, '_', <<"console">>], wiggle_console_handler, []},
+ {[<<"api">>, '_', <<"vms">>, '_', <<"vnc">>], wiggle_vnc_handler, []},
+ {[<<"api">>, '_', <<"vms">>, '...'], wiggle_vm_handler, []},
+ {[<<"api">>, '_', <<"ipranges">>, '...'], wiggle_iprange_handler, []},
+ {[<<"api">>, '_', <<"datasets">>, '...'], wiggle_dataset_handler, []},
+ {[<<"api">>, '_', <<"packages">>, '...'], wiggle_package_handler, []}]}],
{ok, _} = cowboy:start_listener(http, Acceptors,
- cowboy_tcp_transport, [{port, Port}],
- cowboy_http_protocol, [{dispatch, Dispatch}]
- ),
+ cowboy_tcp_transport, [{port, Port}],
+ cowboy_http_protocol, [{dispatch, Dispatch}]
+ ),
+
wiggle_sup:start_link().
stop(_State) ->
View
88 apps/wiggle/src/wiggle_cloud_handler.erl
@@ -3,32 +3,33 @@
%% @doc Hello world handler.
-module(wiggle_cloud_handler).
+-include("wiggle_version.hrl").
+
-export([init/3,
- rest_init/2]).
+ rest_init/2]).
-export([content_types_provided/2,
- content_types_accepted/2,
- allowed_methods/2,
- resource_exists/2,
- forbidden/2,
- options/2,
- is_authorized/2]).
+ content_types_accepted/2,
+ allowed_methods/2,
+ resource_exists/2,
+ forbidden/2,
+ options/2,
+ is_authorized/2]).
-export([to_json/2,
- from_json/2]).
+ from_json/2]).
-ignore_xref([to_json/2,
- from_json/2,
- allowed_methods/2,
- content_types_accepted/2,
- content_types_provided/2,
- forbidden/2,
- init/3,
- is_authorized/2,
- options/2,
- resource_exists/2,
- rest_init/2]).
-
+ from_json/2,
+ allowed_methods/2,
+ content_types_accepted/2,
+ content_types_provided/2,
+ forbidden/2,
+ init/3,
+ is_authorized/2,
+ options/2,
+ resource_exists/2,
+ rest_init/2]).
-record(state, {path, method, version, token, content, reply}).
@@ -41,10 +42,10 @@ rest_init(Req, _) ->
options(Req, State) ->
Methods = allowed_methods(Req, State, State#state.path),
{ok, Req1} = cowboy_http_req:set_resp_header(
- <<"Access-Control-Allow-Methods">>,
- string:join(
- lists:map(fun erlang:atom_to_list/1,
- ['HEAD', 'OPTIONS' | Methods]), ", "), Req),
+ <<"Access-Control-Allow-Methods">>,
+ string:join(
+ lists:map(fun erlang:atom_to_list/1,
+ ['HEAD', 'OPTIONS' | Methods]), ", "), Req),
{ok, Req1, State}.
content_types_provided(Req, State) ->
@@ -95,11 +96,30 @@ to_json(Req, State) ->
handle_request(Req, State = #state{path = []}) ->
case libsniffle:cloud_status() of
- {ok, {Metrics, Warnings}} ->
- {[{metrics, Metrics},
- {warnings, Warnings}], Req, State};
- _ ->
- {[{warnings, [{cloud, <<"down!">>}]}], Req, State}
+ {ok, {Metrics, Warnings}} ->
+ Vers0 = case libsnarl:version() of
+ SrvVer when is_binary(SrvVer) ->
+ [{snarl, SrvVer}];
+ _ ->
+ [{snarl, <<"not connected">>}]
+ end,
+ Vers1 = case libsniffle:version() of
+ SrvVer1 when is_binary(SrvVer1) ->
+ [{sniffle, SrvVer1} | Vers0];
+ _ ->
+ [{sniffle, <<"not connected">>} | Vers0]
+ end,
+ Vers2 = case libhowl:version() of
+ SrvVer2 when is_binary(SrvVer2) ->
+ [{howl, SrvVer2} | Vers1];
+ _ ->
+ [{howl, <<"not connected">>} | Vers1]
+ end,
+ {[{versions, [{wiggle, ?VERSION} | Vers2]},
+ {metrics, Metrics},
+ {warnings, Warnings}], Req, State};
+ _ ->
+ {[{warnings, [{cloud, <<"down!">>}]}], Req, State}
end.
@@ -116,10 +136,10 @@ from_json(Req, State) ->
allowed(Token, Perm) ->
case libsnarl:allowed({token, Token}, Perm) of
- not_found ->
- true;
- true ->
- false;
- false ->
- true
+ not_found ->
+ true;
+ true ->
+ false;
+ false ->
+ true
end.
View
4 apps/wiggle/src/wiggle_dataset_handler.erl
@@ -68,7 +68,7 @@ resource_exists(Req, State = #state{path = []}) ->
{true, Req, State};
resource_exists(Req, State = #state{path = [Dataset]}) ->
- case libsniffle:dataset_attribute_get(Dataset) of
+ case libsniffle:dataset_get(Dataset) of
not_found ->
{false, Req, State};
{ok, _} ->
@@ -113,7 +113,7 @@ handle_request(Req, State = #state{token = Token, path = []}) ->
{lists:map(fun ({E, _}) -> E end, Res), Req, State};
handle_request(Req, State = #state{path = [Dataset]}) ->
- {ok, Res} = libsniffle:dataset_attribute_get(Dataset),
+ {ok, Res} = libsniffle:dataset_get(Dataset),
{Res, Req, State}.
View
137 apps/wiggle/src/wiggle_group_handler.erl
@@ -8,36 +8,36 @@
-endif.
-export([init/3,
- rest_init/2]).
+ rest_init/2]).
-export([content_types_provided/2,
- content_types_accepted/2,
- allowed_methods/2,
- delete_resource/2,
- resource_exists/2,
- forbidden/2,
- options/2,
- is_authorized/2]).
+ content_types_accepted/2,
+ allowed_methods/2,
+ delete_resource/2,
+ resource_exists/2,
+ forbidden/2,
+ options/2,
+ is_authorized/2]).
-export([to_json/2,
- from_json/2]).
+ from_json/2]).
-ignore_xref([to_json/2,
- from_json/2,
- allowed_methods/2,
- content_types_accepted/2,
- content_types_provided/2,
- delete_resource/2,
- forbidden/2,
- init/3,
- is_authorized/2,
- options/2,
- resource_exists/2,
- rest_init/2]).
+ from_json/2,
+ allowed_methods/2,
+ content_types_accepted/2,
+ content_types_provided/2,
+ delete_resource/2,
+ forbidden/2,
+ init/3,
+ is_authorized/2,
+ options/2,
+ resource_exists/2,
+ rest_init/2]).
-record(state, {path, method, version, token, content, reply}).
init(_Transport, _Req, []) ->
- {upgrade, protocol, cowboy_http_rest}.
+ {upgrade, protocol, cowboy_http_rest}.
rest_init(Req, _) ->
wiggle_handler:initial_state(Req, <<"groups">>).
@@ -45,10 +45,10 @@ rest_init(Req, _) ->
options(Req, State) ->
Methods = allowed_methods(Req, State, State#state.path),
{ok, Req1} = cowboy_http_req:set_resp_header(
- <<"Access-Control-Allow-Methods">>,
- string:join(
- lists:map(fun erlang:atom_to_list/1,
- ['HEAD', 'OPTIONS' | Methods]), ", "), Req),
+ <<"Access-Control-Allow-Methods">>,
+ string:join(
+ lists:map(fun erlang:atom_to_list/1,
+ ['HEAD', 'OPTIONS' | Methods]), ", "), Req),
{ok, Req1, State}.
@@ -77,12 +77,12 @@ allowed_methods(_Version, _Token, [_Group, <<"permissions">> | _Permission]) ->
resource_exists(Req, State = #state{path = [Group, <<"permissions">> | Permission]}) ->
case {erlangify_permission(Permission), libsnarl:group_get(Group)} of
- {_, not_found} ->
- {false, Req, State};
- {[], {ok, _}} ->
- {true, Req, State};
- {P, {ok, {group, _Name, Permissions, _}}} ->
- {lists:member(P, Permissions), Req, State}
+ {_, not_found} ->
+ {false, Req, State};
+ {[], {ok, _}} ->
+ {true, Req, State};
+ {P, {ok, GroupObj}} ->
+ {lists:member(P, jsxd:get(<<"permissions">>, [], GroupObj)), Req, State}
end;
resource_exists(Req, State = #state{path = []}) ->
@@ -90,10 +90,10 @@ resource_exists(Req, State = #state{path = []}) ->
resource_exists(Req, State = #state{path = [Group | _]}) ->
case libsnarl:group_get(Group) of
- {ok, not_found} ->
- {false, Req, State};
- {ok, _} ->
- {true, Req, State}
+ {ok, not_found} ->
+ {false, Req, State};
+ {ok, _} ->
+ {true, Req, State}
end.
is_authorized(Req, State = #state{path = [_, <<"sessions">>]}) ->
@@ -154,18 +154,21 @@ to_json(Req, State) ->
{jsx:encode(Reply), Req1, State1}.
handle_request(Req, State = #state{token = _Token, path = []}) ->
-% {ok, Permissions} = libsnarl:user_cache({token, Token}),
+ % {ok, Permissions} = libsnarl:user_cache({token, Token}),
{ok, Res} = libsnarl:group_list(), %{must, 'allowed', [<<"vm">>, {<<"res">>, <<"uuid">>}, <<"get">>], Permissions}),
{Res, Req, State};
handle_request(Req, State = #state{path = [Group]}) ->
- {ok, {group, Name, Permissions, _}} = libsnarl:group_get(Group),
- {[{name, Name},
- {permissions, lists:map(fun jsonify_permissions/1, Permissions)}], Req, State};
+ {ok, GroupObj} = libsnarl:group_get(Group),
+ GroupObj1 = jsxd:update(<<"permissions">>,
+ fun (Permissions) ->
+ lists:map(fun jsonify_permissions/1, Permissions)
+ end, [], GroupObj),
+ {GroupObj1, Req, State};
handle_request(Req, State = #state{path = [Group, <<"permissions">>]}) ->
- {ok, {group, _Name, Permissions, _}} = libsnarl:group_get(Group),
- {lists:map(fun jsonify_permissions/1, Permissions), Req, State}.
+ {ok, GroupObj} = libsnarl:group_get(Group),
+ {lists:map(fun jsonify_permissions/1, jsxd:get(<<"permissions">>, [], GroupObj)), Req, State}.
%%--------------------------------------------------------------------
%% PUT
@@ -174,12 +177,12 @@ handle_request(Req, State = #state{path = [Group, <<"permissions">>]}) ->
from_json(Req, State) ->
{ok, Body, Req1} = cowboy_http_req:body(Req),
{Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, []);
- _ ->
- Decoded = jsx:decode(Body),
- handle_write(Req1, State, Decoded)
- end,
+ <<>> ->
+ handle_write(Req1, State, []);
+ _ ->
+ Decoded = jsx:decode(Body),
+ handle_write(Req1, State, Decoded)
+ end,
{Reply, Req2, State1}.
handle_write(Req, State = #state{path = [Group]}, _Body) ->
@@ -208,41 +211,33 @@ delete_resource(Req, State = #state{path = [Group]}) ->
%% Internal Functions
erlangify_permission(P) ->
- lists:map(fun(<<"...">>) ->
- '...';
- (<<"_">>) ->
- '_';
- (E) ->
- E
- end, P).
+ lists:map(fun(E) ->
+ E
+ end, P).
jsonify_permissions(P) ->
lists:map(fun('...') ->
- <<"...">>;
- ('_') ->
- <<"_">>;
- (E) ->
- E
- end, P).
+ <<"...">>;
+ ('_') ->
+ <<"_">>;
+ (E) ->
+ E
+ end, P).
allowed(Token, Perm) ->
case libsnarl:allowed({token, Token}, Perm) of
- not_found ->
- true;
- true ->
- false;
- false ->
- true
+ not_found ->
+ true;
+ true ->
+ false;
+ false ->
+ true
end.
-ifdef(TEST).
-erlangify_permission_test() ->
- ?assertEqual(['_', <<"a">>, '...'],
- erlangify_permission([<<"_">>, <<"a">>, <<"...">>])).
-
jsonify_permission_test() ->
?assertEqual([<<"_">>, <<"a">>, <<"...">>],
- jsonify_permissions(['_', <<"a">>, '...'])).
+ jsonify_permissions(['_', <<"a">>, '...'])).
-endif.
View
39 apps/wiggle/src/wiggle_handler.erl
@@ -1,9 +1,9 @@
-module(wiggle_handler).
-export([
- initial_state/2,
- accepted/0
- ]).
+ initial_state/2,
+ accepted/0
+ ]).
-record(state, {path, method, version, token, content, reply}).
@@ -12,25 +12,28 @@ initial_state(Req, Component) ->
{[<<"api">>, Version, Component | Path], Req2} = cowboy_http_req:path(Req1),
{ok, Req3} = cowboy_http_req:set_resp_header(<<"Access-Control-Allow-Origin">>, <<"*">>, Req2),
{Token, Req4} = case cowboy_http_req:header(<<"X-Snarl-Token">>, Req3) of
- {undefined, ReqX} ->
- {TokenX, ReqX1} = cowboy_http_req:cookie(<<"X-Snarl-Token">>, ReqX),
- {TokenX, ReqX1};
- {TokenX, ReqX} ->
- {ok, ReqX1} = cowboy_http_req:set_resp_header(<<"X-Snarl-Token">>, TokenX, ReqX),
- {TokenX, ReqX1}
- end,
+ {undefined, ReqX} ->
+ {TokenX, ReqX1} = cowboy_http_req:cookie(<<"X-Snarl-Token">>, ReqX),
+ {TokenX, ReqX1};
+ {TokenX, ReqX} ->
+ {ok, ReqX1} = cowboy_http_req:set_resp_header(<<"X-Snarl-Token">>, TokenX, ReqX),
+ {TokenX, ReqX1}
+ end,
{ok, Req5} = cowboy_http_req:set_resp_header(
- <<"Access-Control-Allow-Headers">>,
- <<"Content-Type, X-Snarl-Token">>, Req4),
+ <<"Access-Control-Allow-Headers">>,
+ <<"Content-Type, X-Snarl-Token">>, Req4),
{ok, Req6} = cowboy_http_req:set_resp_header(
- <<"Access-Control-Expose-Headers">>,
- <<"X-Snarl-Token">>, Req5),
+ <<"Access-Control-Expose-Headers">>,
+ <<"X-Snarl-Token">>, Req5),
+ {ok, Req7} = cowboy_http_req:set_resp_header(
+ <<"Allow-Access-Control-Credentials">>,
+ <<"true">>, Req6),
State = #state{version = Version,
- method = Method,
- token = Token,
- path = Path},
+ method = Method,
+ token = Token,
+ path = Path},
io:format("[~p] - ~p~n", [Method, Path]),
- {ok, Req6, State}.
+ {ok, Req7, State}.
accepted() ->
View
87 apps/wiggle/src/wiggle_hypervisor_handler.erl
@@ -4,36 +4,36 @@
-module(wiggle_hypervisor_handler).
-export([init/3,
- rest_init/2]).
+ rest_init/2]).
-export([content_types_provided/2,
- content_types_accepted/2,
- allowed_methods/2,
- resource_exists/2,
- forbidden/2,
- options/2,
- is_authorized/2]).
+ content_types_accepted/2,
+ allowed_methods/2,
+ resource_exists/2,
+ forbidden/2,
+ options/2,
+ is_authorized/2]).
-export([to_json/2,
- from_json/2]).
+ from_json/2]).
-ignore_xref([to_json/2,
- from_json/2,
- allowed_methods/2,
- content_types_accepted/2,
- content_types_provided/2,
- delete_resource/2,
- forbidden/2,
- init/3,
- is_authorized/2,
- options/2,
- resource_exists/2,
- rest_init/2]).
+ from_json/2,
+ allowed_methods/2,
+ content_types_accepted/2,
+ content_types_provided/2,
+ delete_resource/2,
+ forbidden/2,
+ init/3,
+ is_authorized/2,
+ options/2,
+ resource_exists/2,
+ rest_init/2]).
-record(state, {path, method, version, token, content, reply}).
init(_Transport, _Req, []) ->
- {upgrade, protocol, cowboy_http_rest}.
+ {upgrade, protocol, cowboy_http_rest}.
rest_init(Req, _) ->
wiggle_handler:initial_state(Req, <<"hypervisors">>).
@@ -41,10 +41,10 @@ rest_init(Req, _) ->
options(Req, State) ->
Methods = allowed_methods(Req, State, State#state.path),
{ok, Req1} = cowboy_http_req:set_resp_header(
- <<"Access-Control-Allow-Methods">>,
- string:join(
- lists:map(fun erlang:atom_to_list/1,
- ['HEAD', 'OPTIONS' | Methods]), ", "), Req),
+ <<"Access-Control-Allow-Methods">>,
+ string:join(
+ lists:map(fun erlang:atom_to_list/1,
+ ['HEAD', 'OPTIONS' | Methods]), ", "), Req),
{ok, Req1, State}.
content_types_provided(Req, State) ->
@@ -68,11 +68,11 @@ resource_exists(Req, State = #state{path = []}) ->
{true, Req, State};
resource_exists(Req, State = #state{path = [Hypervisor | _]}) ->
- case libsniffle:hypervisor_resource_get(Hypervisor) of
+ case libsniffle:hypervisor_get(Hypervisor) of
not_found ->
- {false, Req, State};
- {ok, _} ->
- {true, Req, State}
+ {false, Req, State};
+ {ok, _} ->
+ {true, Req, State}
end.
is_authorized(Req, State = #state{method = 'OPTIONS'}) ->
@@ -113,8 +113,11 @@ handle_request(Req, State = #state{token = Token, path = []}) ->
{lists:map(fun ({E, _}) -> E end, Res), Req, State};
handle_request(Req, State = #state{path = [Hypervisor]}) ->
- {ok, Res} = libsniffle:hypervisor_resource_get(Hypervisor),
- {[{name, Hypervisor}| Res], Req, State}.
+ {ok, Res} = libsniffle:hypervisor_get(Hypervisor),
+ Res1 = jsxd:thread([{delete, <<"host">>},
+ {delete, <<"port">>}],
+ Res),
+ {Res1, Req, State}.
%%--------------------------------------------------------------------
%% PUT
@@ -123,12 +126,12 @@ handle_request(Req, State = #state{path = [Hypervisor]}) ->
from_json(Req, State) ->
{ok, Body, Req1} = cowboy_http_req:body(Req),
{Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, []);
- _ ->
- Decoded = jsx:decode(Body),
- handle_write(Req1, State, Decoded)
- end,
+ <<>> ->
+ handle_write(Req1, State, []);
+ _ ->
+ Decoded = jsx:decode(Body),
+ handle_write(Req1, State, Decoded)
+ end,
{Reply, Req2, State1}.
handle_write(Req, State, _Body) ->
@@ -143,10 +146,10 @@ handle_write(Req, State, _Body) ->
allowed(Token, Perm) ->
case libsnarl:allowed({token, Token}, Perm) of
- not_found ->
- true;
- true ->
- false;
- false ->
- true
+ not_found ->
+ true;
+ true ->
+ false;
+ false ->
+ true
end.
View
33 apps/wiggle/src/wiggle_iprange_handler.erl
@@ -120,28 +120,17 @@ handle_request(Req, State = #state{token = Token, path = []}) ->
{lists:map(fun ({E, _}) -> E end, Res), Req, State};
handle_request(Req, State = #state{path = [Iprange]}) ->
- {ok, {iprange,
- Name,
- Network,
- Gateway,
- Netmask,
- First,
- Last,
- Current,
- Tag,
- Free}} = libsniffle:iprange_get(Iprange),
- {[
- {name, Name},
- {tag, Tag},
- {network, ip_to_str(Network)},
- {gateway, ip_to_str(Gateway)},
- {netmask, ip_to_str(Netmask)},
- {first, ip_to_str(First)},
- {last, ip_to_str(Last)},
- {current, ip_to_str(Current)},
- {free, lists:map(fun(IP) -> ip_to_str(IP) end, Free)}
- ], Req, State}.
-
+ {ok, Res} = libsniffle:iprange_get(Iprange),
+ {jsxd:thread([{update, <<"network">>, fun ip_to_str/1},
+ {update, <<"gateway">>, fun ip_to_str/1},
+ {update, <<"netmask">>, fun ip_to_str/1},
+ {update, <<"first">>, fun ip_to_str/1},
+ {update, <<"last">>, fun ip_to_str/1},
+ {update, <<"current">>, fun ip_to_str/1},
+ {update, <<"free">>,
+ fun (Free) ->
+ lists:map(fun ip_to_str/1, Free)
+ end}], Res), Req, State}.
%%--------------------------------------------------------------------
%% PUT
View
100 apps/wiggle/src/wiggle_package_handler.erl
@@ -4,32 +4,32 @@
-module(wiggle_package_handler).
-export([init/3,
- rest_init/2]).
+ rest_init/2]).
-export([content_types_provided/2,
- content_types_accepted/2,
- allowed_methods/2,
- resource_exists/2,
- delete_resource/2,
- forbidden/2,
- options/2,
- is_authorized/2]).
+ content_types_accepted/2,
+ allowed_methods/2,
+ resource_exists/2,
+ delete_resource/2,
+ forbidden/2,
+ options/2,
+ is_authorized/2]).
-export([to_json/2,
- from_json/2]).
+ from_json/2]).
-ignore_xref([to_json/2,
- from_json/2,
- allowed_methods/2,
- content_types_accepted/2,
- content_types_provided/2,
- delete_resource/2,
- forbidden/2,
- init/3,
- is_authorized/2,
- options/2,
- resource_exists/2,
- rest_init/2]).
+ from_json/2,
+ allowed_methods/2,
+ content_types_accepted/2,
+ content_types_provided/2,
+ delete_resource/2,
+ forbidden/2,
+ init/3,
+ is_authorized/2,
+ options/2,
+ resource_exists/2,
+ rest_init/2]).
-record(state, {path, method, version, token, content, reply}).
@@ -43,10 +43,10 @@ rest_init(Req, _) ->
options(Req, State) ->
Methods = allowed_methods(Req, State, State#state.path),
{ok, Req1} = cowboy_http_req:set_resp_header(
- <<"Access-Control-Allow-Methods">>,
- string:join(
- lists:map(fun erlang:atom_to_list/1,
- ['HEAD', 'OPTIONS' | Methods]), ", "), Req),
+ <<"Access-Control-Allow-Methods">>,
+ string:join(
+ lists:map(fun erlang:atom_to_list/1,
+ ['HEAD', 'OPTIONS' | Methods]), ", "), Req),
{ok, Req1, State}.
content_types_provided(Req, State) ->
@@ -70,11 +70,11 @@ resource_exists(Req, State = #state{path = []}) ->
{true, Req, State};
resource_exists(Req, State = #state{path = [Package]}) ->
- case libsniffle:package_attribute_get(Package) of
- not_found ->
- {false, Req, State};
- {ok, _} ->
- {true, Req, State}
+ case libsniffle:package_get(Package) of
+ not_found ->
+ {false, Req, State};
+ {ok, _} ->
+ {true, Req, State}
end.
is_authorized(Req, State = #state{method = 'OPTIONS'}) ->
@@ -121,8 +121,8 @@ handle_request(Req, State = #state{token = Token, path = []}) ->
{lists:map(fun ({E, _}) -> E end, Res), Req, State};
handle_request(Req, State = #state{path = [Package]}) ->
- {ok, Res} = libsniffle:package_attribute_get(Package),
- {[{name, Package}| Res], Req, State}.
+ {ok, Res} = libsniffle:package_get(Package),
+ {Res, Req, State}.
%%--------------------------------------------------------------------
@@ -132,27 +132,27 @@ handle_request(Req, State = #state{path = [Package]}) ->
from_json(Req, State) ->
{ok, Body, Req1} = cowboy_http_req:body(Req),
{Reply, Req2, State1} = case Body of
- <<>> ->
- handle_write(Req1, State, []);
- _ ->
- Decoded = jsx:decode(Body),
- handle_write(Req1, State, Decoded)
- end,
+ <<>> ->
+ handle_write(Req1, State, []);
+ _ ->
+ Decoded = jsx:decode(Body),
+ handle_write(Req1, State, Decoded)
+ end,
{Reply, Req2, State1}.
handle_write(Req, State = #state{path = [Package]}, Body) ->
{<<"ram">>, Ram} = lists:keyfind(<<"ram">>, 1, Body),
{<<"quota">>, Quota} = lists:keyfind(<<"quota">>, 1, Body),
Data = [{<<"quota">>, Quota},
- {<<"ram">>, Ram}],
+ {<<"ram">>, Ram}],
Data1 = case lists:keyfind(<<"cpu_cap">>, 1, Body) of
- {<<"cpu_cap">>, VCPUS} ->
- [{<<"cpu_cap">>, VCPUS} | Data];
- _ ->
- Data
- end,
+ {<<"cpu_cap">>, VCPUS} ->
+ [{<<"cpu_cap">>, VCPUS} | Data];
+ _ ->
+ Data
+ end,
ok = libsniffle:package_create(Package),
- ok = libsniffle:package_attribute_set(Package,Data1),
+ ok = libsniffle:package_set(Package, Data1),
{true, Req, State};
handle_write(Req, State, _Body) ->
@@ -168,10 +168,10 @@ delete_resource(Req, State = #state{path = [Package]}) ->
allowed(Token, Perm) ->
case libsnarl:allowed({token, Token}, Perm) of
- not_found ->
- true;
- true ->
- false;
- false ->
- true
+ not_found ->
+ true;
+ true ->
+ false;
+ false ->
+ true
end.
View
37 apps/wiggle/src/wiggle_user_handler.erl
@@ -95,16 +95,16 @@ resource_exists(Req, State = #state{path = [User, <<"permissions">> | Permission
{false, Req, State};
{[], {ok, _}} ->
{true, Req, State};
- {P, {ok, {user, _Name, _, Permissions, _Groups, _}}} ->
- {lists:member(P, Permissions), Req, State}
+ {P, {ok, UserObj}} ->
+ {lists:member(P, jsxd:get(<<"permissions">>, [], UserObj)), Req, State}
end;
resource_exists(Req, State = #state{method = 'DELETE', path = [User, <<"groups">>, Group]}) ->
case libsnarl:user_get(User) of
not_found ->
{false, Req, State};
- {ok, {user, _Name, _, _Permissions, _, Groups}} ->
- {lists:member(Group, Groups), Req, State}
+ {ok, UserObj} ->
+ {lists:member(Group, jsxd:get(<<"groups">>, [], UserObj)), Req, State}
end;
resource_exists(Req, State = #state{method = 'PUT', path = [User, <<"groups">>, Group]}) ->
@@ -205,18 +205,21 @@ handle_request(Req, State = #state{path = []}) ->
{Res, Req, State};
handle_request(Req, State = #state{path = [User]}) ->
- {ok, {user, Name, _, Permissions, _, Groups}} = libsnarl:user_get(User),
- {[{name, Name},
- {permissions, lists:map(fun jsonify_permissions/1, Permissions)},
- {groups, Groups}], Req, State};
+ {ok, UserObj} = libsnarl:user_get(User),
+ UserObj1 = jsxd:update(<<"permissions">>,
+ fun (Permissions) ->
+ lists:map(fun jsonify_permissions/1, Permissions)
+ end, [], UserObj),
+ UserObj2 = jsxd:delete(<<"password">>, UserObj1),
+ {UserObj2, Req, State};
handle_request(Req, State = #state{path = [User, <<"permissions">>]}) ->
- {ok, {user, _Name, _, Permissions, _, _Groups}} = libsnarl:user_get(User),
- {lists:map(fun jsonify_permissions/1, Permissions), Req, State};
+ {ok, UserObj} = libsnarl:user_get(User),
+ {lists:map(fun jsonify_permissions/1, jsxd:get(<<"permissions">>, [], UserObj)), Req, State};
handle_request(Req, State = #state{path = [User, <<"groups">>]}) ->
- {ok, {user, _Name, _, _Permissions, _, Groups}} = libsnarl:user_get(User),
- {Groups, Req, State}.
+ {ok, UserObj} = libsnarl:user_get(User),
+ {jsxd:get(<<"groups">>, [], UserObj), Req, State}.
%%--------------------------------------------------------------------
%% PUT
@@ -281,11 +284,7 @@ delete_resource(Req, State = #state{path = [User, <<"groups">>, Group]}) ->
%% Internal Functions
erlangify_permission(P) ->
- lists:map(fun(<<"...">>) ->
- '...';
- (<<"_">>) ->
- '_';
- (E) ->
+ lists:map(fun(E) ->
E
end, P).
@@ -310,10 +309,6 @@ allowed(Token, Perm) ->
-ifdef(TEST).
-erlangify_permission_test() ->
- ?assertEqual(['_', <<"a">>, '...'],
- erlangify_permission([<<"_">>, <<"a">>, <<"...">>])).
-
jsonify_permission_test() ->
?assertEqual([<<"_">>, <<"a">>, <<"...">>],
jsonify_permissions(['_', <<"a">>, '...'])).
View
17 apps/wiggle/src/wiggle_vm_handler.erl
@@ -132,16 +132,14 @@ handle_request(Req, State = #state{token = Token, path = []}) ->
{lists:map(fun ({E, _}) -> E end, Res), Req, State};
handle_request(Req, State = #state{path = [Vm]}) ->
- {ok, {vm, Name, _Alias, Hypervisor, _Log, Dict}} = libsniffle:vm_get(Vm),
- {[{<<"uuid">>, Name},
- {<<"hypervisor">>, Hypervisor} | dict:to_list(Dict)], Req, State}.
+ {ok, Res} = libsniffle:vm_get(Vm),
+ {Res, Req, State}.
%%--------------------------------------------------------------------
%% PUT
%%--------------------------------------------------------------------
-
create_path(Req, State = #state{path = [], version = Version, token = Token}) ->
{ok, Body, Req1} = cowboy_http_req:body(Req),
{Decoded, Req2} = case Body of
@@ -152,11 +150,12 @@ create_path(Req, State = #state{path = [], version = Version, token = Token}) ->
{D, Req1}
end,
io:format("~p", [Decoded]),
- {<<"dataset">>, Dataset} = lists:keyfind(<<"dataset">>, 1, Decoded),
- {<<"package">>, Package} = lists:keyfind(<<"package">>, 1, Decoded),
- {<<"config">>, Config} = lists:keyfind(<<"config">>, 1, Decoded),
- {ok, {user, Owner, _, _, _, _}} = libsnarl:user_get({token, Token}),
- {ok, UUID} = libsniffle:create(Package, Dataset, [{<<"owner">>, Owner} | Config]),
+ {ok, Dataset} = jsxd:get(<<"dataset">>, Decoded),
+ {ok, Package} = jsxd:get(<<"package">>, Decoded),
+ {ok, Config} = jsxd:get(<<"config">>, Decoded),
+ {ok, User} = libsnarl:user_get({token, Token}),
+ {ok, Owner} = jsxd:get(<<"name">>, User),
+ {ok, UUID} = libsniffle:create(Package, Dataset, jsxd:set(<<"owner">>, Owner, Config)),
{<<"/api/", Version/binary, "/vms/", UUID/binary>>, Req2, State}.
View
97 apps/wiggle/src/wiggle_vnc_handler.erl
@@ -0,0 +1,97 @@
+-module(wiggle_vnc_handler).
+
+-behaviour(cowboy_http_handler).
+-behaviour(cowboy_http_websocket_handler).
+
+-export([init/3,
+ handle/2,
+ terminate/2]).
+-export([websocket_init/3,
+ websocket_handle/3,
+ websocket_info/3,
+ websocket_terminate/3]).
+
+init({_Any, http}, Req, []) ->
+ case cowboy_http_req:header('Upgrade', Req) of
+ {undefined, Req2} -> {ok, Req2, undefined};
+ {<<"websocket">>, _Req2} -> {upgrade, protocol, cowboy_http_websocket};
+ {<<"WebSocket">>, _Req2} -> {upgrade, protocol, cowboy_http_websocket}
+ end.
+
+handle(Req, State) ->
+ io:format("~p~n", [Req]),
+ {ok, Req1} = cowboy_http_req:reply(200, [], <<"">>, Req),
+ {ok, Req1, State}.
+
+terminate(_Req, _State) ->
+ ok.
+
+websocket_init(_Any, Req, []) ->
+ {[<<"api">>, _, <<"vms">>, ID, <<"vnc">>], Req1} = cowboy_http_req:path(Req),
+ {ok, Req2} = cowboy_http_req:set_resp_header(
+ <<"Access-Control-Allow-Headers">>,
+ <<"X-Snarl-Token">>, Req1),
+ {ok, Req3} = cowboy_http_req:set_resp_header(
+ <<"Access-Control-Expose-Headers">>,
+ <<"X-Snarl-Token">>, Req2),
+ {ok, Req4} = cowboy_http_req:set_resp_header(
+ <<"Allow-Access-Control-Credentials">>,
+ <<"true">>, Req3),
+ {Token, Req5} = case cowboy_http_req:header(<<"X-Snarl-Token">>, Req4) of
+ {undefined, ReqX} ->
+ {TokenX, ReqX1} = cowboy_http_req:cookie(<<"X-Snarl-Token">>, ReqX),
+ {TokenX, ReqX1};
+ {TokenX, ReqX} ->
+ {ok, ReqX1} = cowboy_http_req:set_resp_header(<<"X-Snarl-Token">>, TokenX, ReqX),
+ {TokenX, ReqX1}
+ end,
+ case libsnarl:allowed({token, Token}, [<<"vms">>, ID, <<"console">>]) of
+ true ->
+ case libsniffle:vm_get(ID) of
+ {ok, VM} ->
+ case jsxd:get([<<"info">>, <<"vnc">>], VM) of
+ {ok, VNC} ->
+ Host = proplists:get_value(<<"host">>, VNC),
+ Port = proplists:get_value(<<"port">>, VNC),
+ case gen_tcp:connect(binary_to_list(Host), Port,
+ [binary,{nodelay, true}, {packet, 0}]) of
+ {ok, Socket} ->
+ gen_tcp:controlling_process(Socket, self()),
+ Req6 = cowboy_http_req:compact(Req5),
+ {ok, Req6, {Socket}, hibernate};
+ _ ->
+ Req6 = cowboy_http_req:compact(Req5),
+ {ok, Req6, undefined, hibernate}
+ end;
+ _ ->
+ {ok, Req6} = cowboy_http_req:reply(505, [{'Content-Type', <<"text/html">>}],
+ <<"could not find vnc">>, Req5),
+ {shutdown, Req6}
+ end;
+ E ->
+ {ok, Req6} = cowboy_http_req:reply(505, [{'Content-Type', <<"text/html">>}],
+ list_to_binary(io_lib:format("~p", [E])), Req5),
+ {shutdown, Req6}
+ end;
+ false ->
+ {ok, Req6} = cowboy_http_req:reply(401, [{'Content-Type', <<"text/html">>}], <<"">>, Req5),
+ {shutdown, Req6}
+ end.
+
+websocket_handle({text, Msg}, Req, {Socket} = State) ->
+ gen_tcp:send(Socket, base64:decode(Msg)),
+ {ok, Req, State};
+
+websocket_handle(_Any, Req, State) ->
+ {ok, Req, State}.
+
+websocket_info({tcp,_Socket,Data}, Req, State) ->
+ {reply, {text, base64:encode(Data)}, Req, State};
+
+websocket_info(_Info, Req, State) ->
+ {ok, Req, State, hibernate}.
+
+websocket_terminate(_Reason, _Req, {Socket} = _State) ->
+ Socket ! {ws, closed},
+ gen_tcp:close(Socket),
+ ok.
View
6 rebar.config
@@ -10,7 +10,9 @@
{jsx, ".*", {git, "http://github.com/talentdeficit/jsx.git", {tag, "v1.3.3"}}},
{mimetypes, ".*", {git, "http://github.com/spawngrid/mimetypes.git", {branch, master}}},
{cowboy, ".*", {git, "https://github.com/extend/cowboy.git", {tag, "0.6.1"}}},
+ {libhowl, ".*", {git, "http://github.com/project-fifo/libhowl.git", {tag, "0.1.1"}}},
+ {jsxd, ".*", {git, "https://github.com/Licenser/jsxd.git", {tag, "0.1.3"}}},
{fifo_spec, ".*", {git, "https://github.com/project-fifo/fifo_spec.git", {tag, "0.1.0"}}},
- {libsniffle, ".*", {git, "http://github.com/project-fifo/libsniffle.git", {tag, "0.2.0"}}},
- {libsnarl, ".*", {git, "http://github.com/project-fifo/libsnarl.git", {tag, "0.2.0"}}}
+ {libsniffle, ".*", {git, "http://github.com/project-fifo/libsniffle.git", {tag, "0.2.1"}}},
+ {libsnarl, ".*", {git, "http://github.com/project-fifo/libsnarl.git", {tag, "0.2.1"}}}
]}.
View
6 rel/files/wiggle.xml
@@ -47,7 +47,7 @@
exec='/opt/local/wiggle/bin/wiggle %m'
timeout_seconds='30'>
<method_context>
- <method_credential user='wiggle' group='wiggle' />
+ <method_credential user='wiggle' group='www' />
<method_environment>
<envvar name='PATH' value='/opt/local/gnu/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/usr/sbin'/>
<envvar name='HOME' value='/var/db/wiggle'/>
@@ -61,7 +61,7 @@
exec='/opt/local/wiggle/bin/wiggle %m'
timeout_seconds='60'>
<method_context>
- <method_credential user='wiggle' group='wiggle' />
+ <method_credential user='wiggle' group='www' />
<method_environment>
<envvar name='PATH' value='/opt/local/gnu/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/usr/sbin'/>
<envvar name='HOME' value='/var/db/wiggle'/>
@@ -75,7 +75,7 @@
exec='/opt/local/wiggle/bin/wiggle %m'
timeout_seconds='60'>
<method_context>
- <method_credential user='wiggle' group='wiggle' />
+ <method_credential user='wiggle' group='www' />
<method_environment>
<envvar name='PATH' value='/opt/local/gnu/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/usr/sbin'/>
<envvar name='HOME' value='/var/db/wiggle'/>
View
2  rel/pkg/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.4.0
+VERSION=0.4.1
COMPONENT=wiggle
.PHONY: build_info package package_list
View
82 rel/pkg/install.sh
@@ -1,49 +1,49 @@
#!/usr/bin/bash
USER=wiggle
-GROUP=$USER
+GROUP=wiggle
case $2 in
PRE-INSTALL)
- if grep "^$GROUP:" /etc/group > /dev/null 2>&1
- then
- echo "Group already exists, skipping creation."
- else
- echo Creating wiggle group ...
- groupadd $GROUP
- fi
- if id $USER > /dev/null 2>&1
- then
- echo "User already exists, skipping creation."
- else
- echo Creating wiggle user ...
- useradd -g $GROUP -d /var/db/wiggle -s /bin/false $USER
- fi
- echo Creating directories ...
- mkdir -p /var/db/wiggle
- chown -R wiggle:wiggle /var/db/wiggle
- mkdir -p /var/log/wiggle/sasl
- chown -R wiggle:wiggle /var/log/wiggle
- ;;
+ if grep "^$GROUP:" /etc/group > /dev/null 2>&1
+ then
+ echo "Group already exists, skipping creation."
+ else
+ echo Creating wiggle group ...
+ groupadd $GROUP
+ fi
+ if id $USER > /dev/null 2>&1
+ then
+ echo "User already exists, skipping creation."
+ else
+ echo Creating wiggle user ...
+ useradd -g $GROUP -d /var/db/wiggle -s /bin/false $USER
+ fi
+ echo Creating directories ...
+ mkdir -p /var/db/wiggle
+ chown -R $USER:$GROUP /var/db/wiggle
+ mkdir -p /var/log/wiggle/sasl
+ chown -R $USER:$GROUP /var/log/wiggle
+ ;;
POST-INSTALL)
- if svcs svc:/network/wiggle:default > /dev/null 2>&1
- then
- echo Service already existings ...
- else
- echo Importing service ...
- svccfg import /opt/local/wiggle/etc/wiggle.xml
- fi
- echo Trying to guess configuration ...
- IP=`ifconfig net0 | grep inet | awk -e '{print $2}'`
- if [ ! -f /opt/local/wiggle/etc/vm.args ]
- then
- cp /opt/local/wiggle/etc/vm.args.example /opt/local/wiggle/etc/vm.args
- sed --in-place -e "s/127.0.0.1/${IP}/g" /opt/local/wiggle/etc/vm.args
- fi
- if [ ! -f /opt/local/wiggle/etc/app.config ]
- then
- cp /opt/local/wiggle/etc/app.config.example /opt/local/wiggle/etc/app.config
- sed --in-place -e "s/127.0.0.1/${IP}/g" /opt/local/wiggle/etc/app.config
- fi
- ;;
+ if svcs svc:/network/wiggle:default > /dev/null 2>&1
+ then
+ echo Service already existings ...
+ else
+ echo Importing service ...
+ svccfg import /opt/local/wiggle/etc/wiggle.xml
+ fi
+ echo Trying to guess configuration ...
+ IP=`ifconfig net0 | grep inet | awk -e '{print $2}'`
+ if [ ! -f /opt/local/wiggle/etc/vm.args ]
+ then
+ cp /opt/local/wiggle/etc/vm.args.example /opt/local/wiggle/etc/vm.args
+ sed --in-place -e "s/127.0.0.1/${IP}/g" /opt/local/wiggle/etc/vm.args
+ fi
+ if [ ! -f /opt/local/wiggle/etc/app.config ]
+ then
+ cp /opt/local/wiggle/etc/app.config.example /opt/local/wiggle/etc/app.config
+ sed --in-place -e "s/127.0.0.1/${IP}/g" /opt/local/wiggle/etc/app.config
+ fi
+ ;;
esac
View
2  rel/reltool.config
@@ -1,6 +1,6 @@
{sys, [
{lib_dirs, ["../deps", "../apps"]},
- {rel, "wiggle", "0.4.0",
+ {rel, "wiggle", "0.4.1",
[
kernel,
stdlib,
Please sign in to comment.
Something went wrong with that request. Please try again.