Permalink
Browse files

bump.

  • Loading branch information...
2 parents de5dbfb + 0f21fed commit 6826b3ba9aa65aea254eb27d108c99ead5feb09d @Licenser Licenser committed Feb 23, 2013
View
@@ -1,3 +1,4 @@
+*.version
apps/wiggle/src/wiggle_version.hrl
apps/wiggle/.eunit/
rel/pkg/packlist
View
@@ -5,9 +5,12 @@ REBAR = $(shell pwd)/rebar
all: deps 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
+ echo "$(shell git symbolic-ref HEAD 2> /dev/null | cut -b 12-)-$(shell git log --pretty=format:'%h, %ad' -1)" > wiggle.version
-compile: version
+version_header: version
+ echo "-define(VERSION, <<\"$(shell cat wiggle.version)\">>)." > apps/wiggle/src/wiggle_version.hrl
+
+compile: version_header
$(REBAR) compile
deps:
@@ -1,14 +1,15 @@
{application, wiggle,
[
{description, ""},
- {vsn, "0.4.3"},
+ {vsn, "0.4.4"},
{registered, []},
{applications, [
kernel,
stdlib,
libsnarl,
libsniffle,
libhowl,
+ libchunter,
jsx,
lager,
mimetypes,
@@ -0,0 +1,95 @@
+-module(wiggle_console_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) ->
+ {ok, Req1} = cowboy_http_req:reply(200, [], <<"">>, Req),
+ {ok, Req1, State}.
+
+terminate(_Req, _State) ->
+ ok.
+
+websocket_init(_Any, Req, []) ->
+ {[<<"api">>, _, <<"vms">>, ID, <<"console">>], 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(<<"hypervisor">>, VM) of
+ {ok, HID} ->
+ case libsniffle:hypervisor_get(HID) of
+ {ok, H} ->
+ HostBin = proplists:get_value(<<"host">>, H),
+ Host = binary_to_list(HostBin),
+ Port = proplists:get_value(<<"port">>, H),
+ {ok, Console} = libchunter:console_open(Host, Port, ID, self()),
+ {ok, Req5, {Console}};
+ _ ->
+ {ok, Req6} = cowboy_http_req:reply(505, [{'Content-Type', <<"text/html">>}],
+ <<"could not find hypervisor">>, Req5),
+ {shutdown, Req6}
+ end;
+ _ ->
+ {ok, Req6} = cowboy_http_req:reply(505, [{'Content-Type', <<"text/html">>}],
+ <<"could not find hypervisor">>, 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, {Console} = State) ->
+ libchunter_console_server:send(Console, Msg),
+ {ok, Req, State};
+
+websocket_handle(_Any, Req, State) ->
+ {ok, Req, State}.
+
+websocket_info({data, Data}, Req, State) ->
+ {reply, {text, Data}, Req, State};
+
+websocket_info(_Info, Req, State) ->
+ {ok, Req, State, hibernate}.
+
+websocket_terminate(_Reason, _Req, {Console} = _State) ->
+ libchunter_console_server:close(Console),
+ ok.
@@ -75,12 +75,15 @@ allowed_methods(_Version, _Token, []) ->
['GET'];
allowed_methods(_Version, _Token, [_Dataset]) ->
- ['GET', 'DELETE'].
+ ['GET', 'DELETE'];
+
+allowed_methods(_Version, _Token, [_Dataset, <<"metadata">>|_]) ->
+ ['PUT', 'DELETE'].
resource_exists(Req, State = #state{path = []}) ->
{true, Req, State};
-resource_exists(Req, State = #state{path = [Dataset]}) ->
+resource_exists(Req, State = #state{path = [Dataset | _]}) ->
case libsniffle:dataset_get(Dataset) of
{ok, not_found} ->
{false, Req, State};
@@ -112,6 +115,12 @@ forbidden(Req, State = #state{method = 'GET', path = [Dataset]}) ->
forbidden(Req, State = #state{method = 'DELETE', path = [Dataset]}) ->
{allowed(State#state.token, [<<"datasets">>, Dataset, <<"delete">>]), Req, State};
+forbidden(Req, State = #state{method = 'PUT', path = [Dataset, <<"metadata">> | _]}) ->
+ {allowed(State#state.token, [<<"datasets">>, Dataset, <<"edit">>]), Req, State};
+
+forbidden(Req, State = #state{method = 'DELETE', path = [Dataset, <<"metadata">> | _]}) ->
+ {allowed(State#state.token, [<<"datasets">>, Dataset, <<"edit">>]), Req, State};
+
forbidden(Req, State) ->
{true, Req, State}.
@@ -146,13 +155,21 @@ from_json(Req, State) ->
end,
{Reply, Req2, State1}.
+handle_write(Req, State = #state{path = [Dataset, <<"metadata">> | Path]}, [{K, V}]) ->
+ libsniffle:dataset_set(Dataset, [<<"metadata">> | Path] ++ [K], jsxd:from_list(V)),
+ {true, Req, State};
+
handle_write(Req, State, _Body) ->
{false, Req, State}.
%%--------------------------------------------------------------------
%% DELETE
%%--------------------------------------------------------------------
+delete_resource(Req, State = #state{path = [Dataset, <<"metadata">> | Path]}) ->
+ libsniffle:dataset_set(Dataset, [<<"metadata">> | Path], delete),
+ {true, Req, State};
+
delete_resource(Req, State = #state{path = [Dataset]}) ->
ok = libsniffle:dataset_delete(Dataset),
{true, Req, State}.
@@ -89,12 +89,15 @@ allowed_methods(_Version, _Token, [_Group]) ->
allowed_methods(_Version, _Token, [_Group, <<"permissions">>]) ->
['GET'];
+allowed_methods(_Version, _Token, [_Group, <<"metadata">> | _]) ->
+ ['PUT', 'DELETE'];
+
allowed_methods(_Version, _Token, [_Group, <<"permissions">> | _Permission]) ->
['PUT', 'DELETE'].
resource_exists(Req, State = #state{path = [Group, <<"permissions">> | Permission]}) ->
case {erlangify_permission(Permission), libsnarl:group_get(Group)} of
- {_, not_found} ->
+ {_, {ok, not_found}} ->
{false, Req, State};
{[], {ok, Obj}} ->
{true, Req, State#state{obj=Obj}};
@@ -162,6 +165,12 @@ forbidden(Req, State = #state{method = 'DELETE', path = [Group, <<"permissions">
{allowed(State#state.token, [<<"groups">>, Group, <<"revoke">>])
andalso allowed(State#state.token, [<<"permissions">>, P, <<"revoke">>]), Req, State};
+forbidden(Req, State = #state{method = 'PUT', path = [Group, <<"metadata">> | _]}) ->
+ {allowed(State#state.token, [<<"groups">>, Group, <<"edit">>]), Req, State};
+
+forbidden(Req, State = #state{method = 'DELETE', path = [Group, <<"metadata">> | _]}) ->
+ {allowed(State#state.token, [<<"groups">>, Group, <<"edit">>]), Req, State};
+
forbidden(Req, State) ->
{true, Req, State}.
@@ -220,6 +229,10 @@ from_json(Req, State) ->
handle_write(Req, State = #state{method = 'POST', path = []}, _) ->
{true, Req, State};
+handle_write(Req, State = #state{path = [Group, <<"metadata">> | Path]}, [{K, V}]) ->
+ libsnarl:group_set(Group, [<<"metadata">> | Path] ++ [K], jsxd:from_list(V)),
+ {true, Req, State};
+
handle_write(Req, State = #state{path = [Group]}, _Body) ->
ok = libsnarl:group_add(Group),
{true, Req, State};
@@ -234,6 +247,10 @@ handle_write(Req, State = #state{path = [Group, <<"permissions">> | Permission]}
%% DEETE
%%--------------------------------------------------------------------
+delete_resource(Req, State = #state{path = [Group, <<"metadata">> | Path]}) ->
+ libsnarl:group_set(Group, [<<"metadata">> | Path], delete),
+ {true, Req, State};
+
delete_resource(Req, State = #state{path = [Group, <<"permissions">> | Permission]}) ->
P = erlangify_permission(Permission),
ok = libsnarl:group_revoke(Group, P),
@@ -13,6 +13,7 @@
forbidden/2,
service_available/2,
options/2,
+ delete_resource/2,
is_authorized/2]).
-export([to_json/2,
@@ -76,8 +77,11 @@ allowed_methods(_Version, _Token, []) ->
allowed_methods(_Version, _Token, [_Hypervisor]) ->
['GET'];
-allowed_methods(_Version, _Token, [_Hypervisor, <<"metadata">>]) ->
- ['PUT'].
+allowed_methods(_Version, _Token, [_Hypervisor, <<"characteristics">>|_]) ->
+ ['PUT', 'DELETE'];
+
+allowed_methods(_Version, _Token, [_Hypervisor, <<"metadata">>|_]) ->
+ ['PUT', 'DELETE'].
resource_exists(Req, State = #state{path = []}) ->
{true, Req, State};
@@ -111,7 +115,16 @@ forbidden(Req, State = #state{path = []}) ->
forbidden(Req, State = #state{method = 'GET', path = [Hypervisor]}) ->
{allowed(State#state.token, [<<"hypervisors">>, Hypervisor, <<"get">>]), Req, State};
-forbidden(Req, State = #state{method = 'PUT', path = [Hypervisor, <<"metadata">>]}) ->
+forbidden(Req, State = #state{method = 'PUT', path = [Hypervisor, <<"metadata">> | _]}) ->
+ {allowed(State#state.token, [<<"hypervisors">>, Hypervisor, <<"edit">>]), Req, State};
+
+forbidden(Req, State = #state{method = 'DELETE', path = [Hypervisor, <<"metadata">> | _]}) ->
+ {allowed(State#state.token, [<<"hypervisors">>, Hypervisor, <<"edit">>]), Req, State};
+
+forbidden(Req, State = #state{method = 'PUT', path = [Hypervisor, <<"characteristics">> | _]}) ->
+ {allowed(State#state.token, [<<"hypervisors">>, Hypervisor, <<"edit">>]), Req, State};
+
+forbidden(Req, State = #state{method = 'DELETE', path = [Hypervisor, <<"characteristics">> | _]}) ->
{allowed(State#state.token, [<<"hypervisors">>, Hypervisor, <<"edit">>]), Req, State};
forbidden(Req, State) ->
@@ -131,10 +144,7 @@ handle_request(Req, State = #state{token = Token, path = []}) ->
{lists:map(fun ({E, _}) -> E end, Res), Req, State};
handle_request(Req, State = #state{path = [_Hypervisor], obj = Obj}) ->
- Res1 = jsxd:thread([{delete, <<"host">>},
- {delete, <<"port">>}],
- Obj),
- {Res1, Req, State}.
+ {Obj, Req, State}.
%%--------------------------------------------------------------------
%% PUT
@@ -151,8 +161,12 @@ from_json(Req, State) ->
end,
{Reply, Req2, State1}.
-handle_write(Req, State = #state{path = [Hypervisor, <<"metadata">>]}, [{K, V}]) ->
- libsniffle:hypervisor_set(Hypervisor, <<"metadata.", K/binary>>, jsxd:from_list(V)),
+handle_write(Req, State = #state{path = [Hypervisor, <<"characteristics">> | Path]}, [{K, V}]) ->
+ libsniffle:hypervisor_set(Hypervisor, [<<"characteristics">> | Path] ++ [K], jsxd:from_list(V)),
+ {true, Req, State};
+
+handle_write(Req, State = #state{path = [Hypervisor, <<"metadata">> | Path]}, [{K, V}]) ->
+ libsniffle:hypervisor_set(Hypervisor, [<<"metadata">> | Path] ++ [K], jsxd:from_list(V)),
{true, Req, State};
handle_write(Req, State, _Body) ->
@@ -163,6 +177,15 @@ handle_write(Req, State, _Body) ->
%% DELETE
%%--------------------------------------------------------------------
+delete_resource(Req, State = #state{path = [Hypervisor, <<"characteristics">> | Path]}) ->
+ libsniffle:hypervisor_set(Hypervisor, [<<"characteristics">> | Path], delete),
+ {true, Req, State};
+
+delete_resource(Req, State = #state{path = [Hypervisor, <<"metadata">> | Path]}) ->
+ libsniffle:hypervisor_set(Hypervisor, [<<"metadata">> | Path], delete),
+ {true, Req, State}.
+
+
%% Internal Functions
allowed(Token, Perm) ->
@@ -78,6 +78,9 @@ content_types_accepted(Req, State) ->
allowed_methods(Req, State) ->
{['HEAD', 'OPTIONS' | allowed_methods(State#state.version, State#state.token, State#state.path)], Req, State}.
+allowed_methods(_Version, _Token, [_Iprange, <<"metadata">>|_]) ->
+ ['PUT', 'DELETE'];
+
allowed_methods(_Version, _Token, []) ->
['GET', 'POST'];
@@ -87,7 +90,7 @@ allowed_methods(_Version, _Token, [_Iprange]) ->
resource_exists(Req, State = #state{path = []}) ->
{true, Req, State};
-resource_exists(Req, State = #state{path = [Iprange]}) ->
+resource_exists(Req, State = #state{path = [Iprange | _]}) ->
case libsniffle:iprange_get(Iprange) of
not_found ->
{false, Req, State};
@@ -125,6 +128,12 @@ forbidden(Req, State = #state{method = 'DELETE', path = [Iprange]}) ->
forbidden(Req, State = #state{method = 'PUT', path = [_Iprange]}) ->
{allowed(State#state.token, [<<"cloud">>, <<"ipranges">>, <<"create">>]), Req, State};
+forbidden(Req, State = #state{method = 'PUT', path = [Iprange, <<"metadata">> | _]}) ->
+ {allowed(State#state.token, [<<"ipranges">>, Iprange, <<"edit">>]), Req, State};
+
+forbidden(Req, State = #state{method = 'DELETE', path = [Iprange, <<"metadata">> | _]}) ->
+ {allowed(State#state.token, [<<"ipranges">>, Iprange, <<"edit">>]), Req, State};
+
forbidden(Req, State) ->
{true, Req, State}.
@@ -198,13 +207,21 @@ from_json(Req, State) ->
handle_write(Req, State = #state{method = 'POST', path = []}, _) ->
{true, Req, State};
+handle_write(Req, State = #state{path = [Iprange, <<"metadata">> | Path]}, [{K, V}]) ->
+ libsniffle:iprange_set(Iprange, [<<"metadata">> | Path] ++ [K], jsxd:from_list(V)),
+ {true, Req, State};
+
handle_write(Req, State, _Body) ->
{false, Req, State}.
%%--------------------------------------------------------------------
%% DEETE
%%--------------------------------------------------------------------
+delete_resource(Req, State = #state{path = [Iprange, <<"metadata">> | Path]}) ->
+ libsniffle:iprange_set(Iprange, [<<"metadata">> | Path], delete),
+ {true, Req, State};
+
delete_resource(Req, State = #state{path = [Iprange]}) ->
ok = libsniffle:iprange_delete(Iprange),
{true, Req, State}.
Oops, something went wrong.

0 comments on commit 6826b3b

Please sign in to comment.