aboutsummaryrefslogtreecommitdiff
path: root/apps/dreki_web/src/dreki_web_app.erl
blob: 5b3c1a09d52bb3fb476b4a7d9a76a00e411dc279 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
%%%-------------------------------------------------------------------
%% @doc dreki_web public API
%% @end
%%%-------------------------------------------------------------------

-module(dreki_web_app).

-behaviour(application).

-export([start/2, stop/1]).

start(_StartType, _StartArgs) ->
    Config = application:get_all_env(dreki_web),
    Transport = proplists:get_value(transport, Config),
    CowboyEnv = #{
                  middlewares => [dreki_web_auth, cowboy_router, dreki_web_handler],
                  stream_handlers => [cowboy_telemetry_h,
                                      cowboy_access_log_h,
                                      cowboy_metrics_h,
                                      cowboy_stream_h],
                  metrics_callback => fun prometheus_cowboy2_instrumenter:observe/1,
                  env => #{
                           dispatch => routes()
                          }
                 },
    {ok, _} = cowboy:start_clear(dreki_web_listener, Transport, CowboyEnv),
    opentelemetry_cowboy:setup(),
    IP = proplists:get_value(ip, Transport),
    Port = proplists:get_value(port, Transport),
    logger:notice("dreki_web listening on ~p:~p", [IP, Port]),
    dreki_web_sup:start_link().

stop(_State) ->
    ok.

%% internal functions

routes() ->
    Trails = [
              {"/", dreki_web_index, undefined},
              {"/static/[...]", cowboy_static,
               {priv_dir, dreki_web, "static", [{mimetypes, dreki_web, detect_web_mimetype}]}},
              {"/metrics/[:registry]", prometheus_cowboy2_handler, []},

              %% API
              {"/api/tasks/:id", dreki_web_task, undefined},

              %% Admin API
              {"/api/admin/world", dreki_web_admin_world, index},
              {"/api/admin/world/graph", dreki_web_admin_world, graph},
              {"/api/admin/world/graph.dot", dreki_web_admin_world, {graph, dot}},
              {"/api/admin/tasks", dreki_web_admin_tasks, undefined},
              {"/api/admin/tasks/:id", dreki_web_admin_task, undefined},

              %% Admin UI
              {"/admin", dreki_web_ui_index, undefined},
              {"/admin/nodes/:id", dreki_web_ui_node, undefined},
              {"/admin/tasks", dreki_web_ui_tasks, undefined},
              {"/admin/tasks/:id", dreki_web_ui_task, undefined},

              %%{"/admin/stores", dreki_web_ui_stores, undefined},
              %%{"/admin/:location/stores", dreki_web_ui_stores, undefined},
              {"/admin/:location/:namespace", dreki_web_ui_stores, undefined},
              {"/admin/:location/:namespace/:directory", dreki_web_ui_stores, undefined},
              {"/admin/:location/:namespace/:directory/_/:action", dreki_web_ui_stores, action},
              {"/admin/:location/:namespace/:directory/:id", dreki_web_ui_stores, undefined},
              {"/admin/:location/:namespace/:directory/:id/_/:action", dreki_web_ui_stores, action},

              {"/admin/[...]", dreki_web_ui_error, #{code => 404, status => <<"Not found">>}},

              %% 404 Catch all
              {'_', dreki_web_error, #{code => 404, status => <<"Not found">>}}
             ],
    trails:single_host_compile(Trails).