diff --git a/spectrum_manager/src/APIServer.cpp b/spectrum_manager/src/APIServer.cpp index 359f6d483a1b9a4c90f61657a449065d3d140bb4..8dd645c3f1cd28bbfbe6c42c15903f157b8914b2 100644 --- a/spectrum_manager/src/APIServer.cpp +++ b/spectrum_manager/src/APIServer.cpp @@ -12,6 +12,12 @@ #include #include +#define ALLOW_ONLY_ADMIN() if (!session->admin) { \ + std::string _json = "{\"error\":1, \"message\": \"Only administrators can do this API call.\"}"; \ + send_json(conn, _json); \ + return; \ + } + static std::string get_http_var(const struct http_message *hm, const char *name) { char data[4096]; data[0] = '\0'; @@ -29,6 +35,11 @@ static std::string get_http_var(const struct http_message *hm, const char *name) return ""; } +static int has_prefix(const struct mg_str *uri, const char *prefix) { + size_t prefix_len = strlen(prefix); + return uri->len >= prefix_len && memcmp(uri->p, prefix, prefix_len) == 0; +} + APIServer::APIServer(ManagerConfig *config, StorageBackend *storage) { m_config = config; m_storage = storage; @@ -37,7 +48,15 @@ APIServer::APIServer(ManagerConfig *config, StorageBackend *storage) { APIServer::~APIServer() { } +std::string &APIServer::safe_arg(std::string &arg) { + boost::replace_all(arg, "\n", ""); + boost::replace_all(arg, "\"", "'"); + return arg; +} + void APIServer::send_json(struct mg_connection *conn, const std::string &json) { + std::cout << "Sending JSON:\n"; + std::cout << json << "\n"; mg_printf(conn, "HTTP/1.1 200 OK\r\n" "Content-Type: text/json\r\n" @@ -70,7 +89,13 @@ void APIServer::serve_instances(Server *server, Server::session *session, struct else if (*(status.end() - 1) == '\n') { status.erase(status.end() - 1); } - json += "\"status\":\"" + status + "\""; + json += "\"status\":\"" + safe_arg(status) + "\","; + + bool running = true; + if (status.find("Running") == std::string::npos) { + running = false; + } + json += "\"running\":" + (running ? std::string("1") : std::string("0")); json += "},"; } json.erase(json.end() - 1); @@ -79,8 +104,42 @@ void APIServer::serve_instances(Server *server, Server::session *session, struct send_json(conn, json); } +void APIServer::serve_instances_start(Server *server, Server::session *session, struct mg_connection *conn, struct http_message *hm) { + ALLOW_ONLY_ADMIN(); + + std::string uri(hm->uri.p, hm->uri.len); + std::string instance = uri.substr(uri.rfind("/") + 1); + start_instances(m_config, instance); + std::string response = get_response(); + std::string error = response.find("OK") == std::string::npos ? "1" : "0"; + std::string json = "{\"error\":" + error + ", \"message\": \"" + safe_arg(response) + "\"}"; + + // TODO: So far it needs some time to reload Spectrum 2, so just sleep here. + sleep(1); + + send_json(conn, json); +} + +void APIServer::serve_instances_stop(Server *server, Server::session *session, struct mg_connection *conn, struct http_message *hm) { + ALLOW_ONLY_ADMIN(); + + std::string uri(hm->uri.p, hm->uri.len); + std::string instance = uri.substr(uri.rfind("/") + 1); + stop_instances(m_config, instance); + std::string response = get_response(); + std::string error = response.find("OK") == std::string::npos ? "1" : "0"; + std::string json = "{\"error\":" + error + ", \"message\": \"" + safe_arg(response) + "\"}"; \ + send_json(conn, json); +} + void APIServer::handleRequest(Server *server, Server::session *sess, struct mg_connection *conn, struct http_message *hm) { - if (mg_vcmp(&hm->uri, "/api/v1/instances") == 0) { + if (has_prefix(&hm->uri, "/api/v1/instances/start/")) { + serve_instances_start(server, sess, conn, hm); + } + else if (has_prefix(&hm->uri, "/api/v1/instances/stop/")) { + serve_instances_stop(server, sess, conn, hm); + } + else if (mg_vcmp(&hm->uri, "/api/v1/instances") == 0) { serve_instances(server, sess, conn, hm); } } diff --git a/spectrum_manager/src/APIServer.h b/spectrum_manager/src/APIServer.h index fdc7104545137cdd51d19627a2a46c49a3663caf..c90714a707956e3b56964560b59afeeb60fbb3a4 100644 --- a/spectrum_manager/src/APIServer.h +++ b/spectrum_manager/src/APIServer.h @@ -50,6 +50,9 @@ class APIServer { private: void serve_instances(Server *server, Server::session *sess, struct mg_connection *conn, struct http_message *hm); + void serve_instances_start(Server *server, Server::session *sess, struct mg_connection *conn, struct http_message *hm); + void serve_instances_stop(Server *server, Server::session *sess, struct mg_connection *conn, struct http_message *hm); + std::string &safe_arg(std::string &); void send_json(struct mg_connection *conn, const std::string &json); private: diff --git a/spectrum_manager/src/html/header.html b/spectrum_manager/src/html/header.html index b3dce4d9ee7bfc0930a58747c50e39d6f50249fc..9f574d6f8d1676afb57cf01c12c6b68134ee2cff 100644 --- a/spectrum_manager/src/html/header.html +++ b/spectrum_manager/src/html/header.html @@ -7,7 +7,10 @@ - + + + + Spectrum 2 @@ -20,7 +23,7 @@ @@ -30,3 +33,4 @@
+ \ No newline at end of file diff --git a/spectrum_manager/src/html/instances/index.shtml b/spectrum_manager/src/html/instances/index.shtml new file mode 100644 index 0000000000000000000000000000000000000000..f7992f9236b86fcf3e57e96f1f869e54847d8168 --- /dev/null +++ b/spectrum_manager/src/html/instances/index.shtml @@ -0,0 +1,9 @@ + + + + + diff --git a/spectrum_manager/src/html/js/app.js b/spectrum_manager/src/html/js/app.js new file mode 100644 index 0000000000000000000000000000000000000000..146a2f798622778dfddb6c542f833d6d402f89c1 --- /dev/null +++ b/spectrum_manager/src/html/js/app.js @@ -0,0 +1,20 @@ +function show_instances() { + $.get("/api/v1/instances", function(data) { + $("#main_content").html("

List of Spectrum 2 instances

"); + $.each(data.instances, function(i, instance) { + var command = instance.running ? "stop" : "start"; + var row = ''; + $("#main_result > tbody:last-child").append(row); + $(".button_command").click(function(e) { + e.preventDefault(); + $(this).parent().empty().progressbar( {value: false} ).css('height', '1em'); + var url = $(this).attr('href'); + $.get(url, function(data) { + show_instances(); + }); + }) + }); +}); +} diff --git a/spectrum_manager/src/server.cpp b/spectrum_manager/src/server.cpp index 4d156e18c35de3649d2d3b47f880b6bfddd87fa0..44e4c13bbd2153b54c683fc5d7ee1719b704363c 100644 --- a/spectrum_manager/src/server.cpp +++ b/spectrum_manager/src/server.cpp @@ -180,7 +180,7 @@ void Server::authorize(struct mg_connection *conn, struct http_message *hm) { "Set-Cookie: user=%s\r\n" // Set user, needed by Javascript code "Set-Cookie: admin=%s\r\n" // Set user, needed by Javascript code "Set-Cookie: original_url=/; max-age=0\r\n" // Delete original_url - "Location: /\r\n\r\n", + "Location: /instances\r\n\r\n", session->session_id, session->user, session->admin ? "1" : "0"); } else { // Authentication failure, redirect to login.
HostnameStatusCommand
'+ instance.name + '' + + instance.status + '' + command + '' + '