diff --git a/src/dog_api_router.erl b/src/dog_api_router.erl index d6c1674..73d1373 100644 --- a/src/dog_api_router.erl +++ b/src/dog_api_router.erl @@ -86,10 +86,12 @@ start_link() -> {"/api/publish", publish_api_handler, #{}}, {"/api/service", api_handler, #{}}, {"/api/service/:id", api_handler, #{}}, + {"/api/service/:id/:sub", api_handler, #{}}, {"/api/services", plural_api_handler, #{}}, {"/api/services/:sub", plural_api_handler, #{}}, {"/api/V2/service", api_handler_v2, #{}}, {"/api/V2/service/:id", api_handler_v2, #{}}, + {"/api/V2/service/:id/:sub", api_handler_v2, #{}}, {"/api/V2/services", plural_api_handler_v2, #{}}, {"/api/V2/services/:sub", plural_api_handler_v2, #{}}, {"/api/zone/", api_handler, #{}}, @@ -106,10 +108,12 @@ start_link() -> {"/api/V2/zones/ips", plural_api_handler_v2, #{}}, {"/api/fact", api_handler, #{}}, {"/api/fact/:id", api_handler, #{}}, + {"/api/fact/:id/:sub", api_handler, #{}}, {"/api/facts", plural_api_handler, #{}}, {"/api/facts/:sub", plural_api_handler, #{}}, {"/api/V2/fact", api_handler_v2, #{}}, {"/api/V2/fact/:id", api_handler_v2, #{}}, + {"/api/V2/fact/:id/:sub", api_handler_v2, #{}}, {"/api/V2/facts", plural_api_handler_v2, #{}}, {"/api/V2/facts/:sub", plural_api_handler_v2, #{}} ]} diff --git a/src/dog_common.erl b/src/dog_common.erl index 430a58d..4951ebc 100644 --- a/src/dog_common.erl +++ b/src/dog_common.erl @@ -13,6 +13,7 @@ lmm/2, merge_lists_in_tuples/1, merge_maps_of_lists/1, + quoted_comma_delimited/1, re_filter/2, rekey_map_of_maps/3, rkmm/3, @@ -226,3 +227,7 @@ format_value(Value) -> end, Value), "[" ++ lists:join(",",ListValues) ++ "]" end. + +-spec quoted_comma_delimited(List :: list()) -> iolist(). +quoted_comma_delimited(List) -> + string:join([io_lib:format("\"~s\"",[X]) || X <- List],","). diff --git a/src/dog_fact_api_v2.erl b/src/dog_fact_api_v2.erl index 954f279..9144985 100644 --- a/src/dog_fact_api_v2.erl +++ b/src/dog_fact_api_v2.erl @@ -14,6 +14,8 @@ get_by_id/1, get_by_name/1, get_schema/0, + to_hcl/1, + to_hcl_by_id/1, update/2 ]). @@ -127,3 +129,60 @@ update(Id, UpdateMap@0) -> -spec get_schema() -> binary(). get_schema() -> dog_json_schema:get_file(?VALIDATION_TYPE). + +-spec to_hcl_by_id(FactId :: iolist()) -> iolist(). +to_hcl_by_id(FactId) -> + {ok, Fact} = get_by_id(FactId), + to_hcl(Fact). + +-spec to_hcl(Fact :: map()) -> binary(). +to_hcl(Fact) -> + Bindings = #{ + 'TerraformName' => dog_common:to_terraform_name(maps:get(<<"name">>, Fact)), + 'Name' => maps:get(<<"name">>, Fact), + 'Environment' => <<"qa">>, + 'Groups' => to_hcl_group(maps:get(<<"groups">>, Fact)) + }, + {ok, Snapshot} = eel:compile(<< + "resource \"dog_fact\" \"<%= TerraformName .%>\n" + " name = <%= Name .%>\n" + " groups = {\n" + "<%= Groups .%>" + "}\n" + >>), + {ok, RenderSnapshot} = eel_renderer:render(Bindings, Snapshot), + {IoData, _} = {eel_evaluator:eval(RenderSnapshot), RenderSnapshot}, + erlang:iolist_to_binary(IoData). + +-spec to_hcl_group(Group :: map()) -> binary(). +to_hcl_group(Group) -> + All = maps:get(<<"all">>, Group), + Bindings = #{ + 'Children' => dog_common:format_value(maps:get(<<"children">>, All)), + 'Hosts' => dog_common:format_vars(maps:get(<<"hosts">>, All)), + 'Vars' => dog_common:format_vars(maps:get(<<"vars">>, All, [])) + }, + {ok, Snapshot} = eel:compile(<< + " all = {\n" + " children = <%= Children .%>\n" + " hosts = {\n" + "<%= case Hosts of %>" + "<% [] -> <<>> ; %>" + "<% _ -> %>" + " }\n" + " }\n" + "<% end .%>" + "<%= case Vars of %>" + "<% [] -> <<>> ; %>" + "<% _ -> %>" + " vars = jsonencode({\n" + "<%= lists:map(fun({Key,Value}) -> %>" + " <%= Key .%> = <%= Value .%> \n" + "<% end, maps:to_list(Vars)) .%>" + " })\n" + "<% end .%>" + " }\n" + >>), + {ok, RenderSnapshot} = eel_renderer:render(Bindings, Snapshot), + {IoData, _} = {eel_evaluator:eval(RenderSnapshot), RenderSnapshot}, + erlang:iolist_to_binary(IoData). diff --git a/src/dog_service_api_v2.erl b/src/dog_service_api_v2.erl index ac064b7..3597543 100644 --- a/src/dog_service_api_v2.erl +++ b/src/dog_service_api_v2.erl @@ -12,6 +12,8 @@ get_all/0, get_by_id/1, get_by_name/1, + to_hcl/1, + to_hcl_by_id/1, update/2 ]). @@ -131,3 +133,55 @@ update(Id, UpdateMap) -> {error, Error} -> {false, Error} end. + +-spec to_hcl_by_id(ServiceId :: iolist()) -> iolist(). +to_hcl_by_id(ServiceId) -> + {ok, Service} = get_by_id(ServiceId), + to_hcl(Service). + +-spec to_hcl(Service :: map()) -> binary(). +to_hcl(Service) -> + Bindings = #{ + 'TerraformName' => dog_common:to_terraform_name(maps:get(<<"name">>, Service)), + 'Name' => maps:get(<<"name">>, Service), + 'Version' => maps:get(<<"version">>, Service), + 'Environment' => <<"qa">>, + 'PortProtocols' => portprotocols_output(maps:get(<<"services">>, Service)) + }, + {ok, Snapshot} = eel:compile(<< + "resource \"dog_service\" \"<%= TerraformName .%>\" {\n" + " name = \"<%= Name .%>\"\n" + " version = \"<%= Version .%>\"\n" + " services = [\n" + "<%= PortProtocols .%>" + " ]\n" + " provider = dog.<%= Environment .%>\n" + "}\n" + "\n" + >>), + {ok, RenderSnapshot} = eel_renderer:render(Bindings, Snapshot), + {IoData, _} = {eel_evaluator:eval(RenderSnapshot), RenderSnapshot}, + erlang:iolist_to_binary(IoData). + +-spec portprotocols_output(PortProtocol :: map()) -> binary(). +portprotocols_output(PortProtocols) -> + PPs = lists:map(fun(PP) -> + Ports = maps:get(<<"ports">>, PP), + Protocol = io_lib:format("\"~s\"",[maps:get(<<"protocol">>, PP)]), + PortsString = dog_common:quoted_comma_delimited(Ports), + {Protocol, PortsString} + end, PortProtocols), + Bindings = #{ + 'PortProtocols' => PPs + }, + {ok, Snapshot} = eel:compile(<< + "<%= lists:map(fun({Protocol,Ports}) -> %>" + " {\n" + " protocol = <%= Protocol .%>\n" + " ports = [<%= Ports .%>]\n" + " },\n" + "<% end, PortProtocols) .%>" + >>), + {ok, RenderSnapshot} = eel_renderer:render(Bindings, Snapshot), + {IoData, _} = {eel_evaluator:eval(RenderSnapshot), RenderSnapshot}, + erlang:iolist_to_binary(IoData).