/**
* DeployMan # Thomas Uhrig (Stuttgart, 2014) # www.tuhrig.de
*/
package de.tuhrig.deployman.interfaces;
import static de.tuhrig.deployman.DeployMan.SYSTEM_WEB_PASSWORD;
import static de.tuhrig.deployman.DeployMan.SYSTEM_WEB_ROOT;
import static de.tuhrig.deployman.DeployMan.SYSTEM_WEB_USER;
import static spark.Spark.before;
import static spark.Spark.get;
import static spark.SparkBase.externalStaticFileLocation;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import spark.Filter;
import spark.Request;
import spark.Response;
import spark.Spark;
import com.google.gson.Gson;
import de.tuhrig.deployman.DeployMan;
import de.tuhrig.deployman.aws.Ec2;
import de.tuhrig.deployman.aws.Rds;
import de.tuhrig.deployman.docker.DockerRemoteClient;
import de.tuhrig.deployman.health.MachineStatus;
import de.tuhrig.deployman.launch.CloudInitScript;
import de.tuhrig.deployman.launch.LaunchJob;
import de.tuhrig.deployman.launch.LaunchJobStore;
import de.tuhrig.deployman.repo.ConfigRepository;
import de.tuhrig.deployman.repo.FormationRepository;
import de.tuhrig.deployman.repo.ImageRepository;
import de.tuhrig.deployman.repo.SetupRepository;
/**
* This class launches the web interface of DeployMan. It defines all routes to request data as
* JSON.
*/
public class WebInterface // NO_UCD (unused code)
{
private static final Logger log = Logger.getLogger(WebInterface.class.getName());
private static final Gson gson = new Gson();
@SuppressWarnings("nls")
public static void main(String[] args) throws IOException {
// load the initial config first
DeployMan.readSystemProperties();
org.apache.logging.julbridge.JULLog4jBridge.assimilate();
Properties props = new Properties();
props.load(new FileInputStream("log4j.properties"));
PropertyConfigurator.configure(props);
log.info("config end");
// get and set the web root folder where the static
// files (HTML, JS and CSS) are located
String webRoot = DeployMan.getSystemProperty(SYSTEM_WEB_ROOT);
log.info("Web root folder = " + webRoot);
externalStaticFileLocation(webRoot);
before(new Filter() {
/**
* This code is taken from https://github.com/qmetric/spark-authentication
*/
@Override
public void handle(final Request request, final Response response) {
String header = StringUtils.substringAfter(request.headers("Authorization"), "Basic");
String[] credentials = credentialsFrom(header);
if (!authenticatedWith(credentials)) {
response.header("WWW-Authenticate", "Basic");
Spark.halt(401);
}
}
private String[] credentialsFrom(final String encodedHeader) {
return StringUtils.split(encodedHeader != null ? decodeHeader(encodedHeader) : null, ":");
}
private String decodeHeader(final String encodedHeader) {
return new String(Base64.decodeBase64(encodedHeader));
}
private boolean authenticatedWith(final String[] credentials) {
if (credentials != null && credentials.length == 2) {
String submittedUsername = credentials[0];
String submittedPassword = credentials[1];
String webUser = DeployMan.getSystemProperty(SYSTEM_WEB_USER);
String webPassword = DeployMan.getSystemProperty(SYSTEM_WEB_PASSWORD);
return StringUtils.equals(submittedUsername, webUser)
&& StringUtils.equals(submittedPassword, webPassword);
}
return false;
}
});
get("/instances", (request, response) -> {
return gson.toJson(new Ec2().getEC2Instances());
});
get("/instances/:instance", (request, response) -> {
String instanceId = request.params(":instance");
return gson.toJson(MachineStatus.getMachineStatus(instanceId));
});
get("/instances/:instance/kill", (request, response) -> {
String instanceId = request.params(":instance");
new Ec2().terminateEC2InstanceById(instanceId);
response.redirect("/#/instances-view");
return "killing...";
});
get("/databases", (request, response) -> {
return gson.toJson(new Rds().getDatabases());
});
get("/inits", (request, response) -> {
return gson.toJson(new CloudInitScript("").getInitScripts());
});
get("/inits/:name", (request, response) -> {
String name = request.params(":name");
return gson.toJson(new CloudInitScript("").getInitScript(name));
});
get("/jobs", (request, response) -> {
return gson.toJson(LaunchJobStore.getJobs());
});
get("/jobs/:id", (request, response) -> {
String id = request.params(":id");
return gson.toJson(LaunchJobStore.getJob(id));
});
get("/docker/:instance/containers/:container", (request, response) -> {
String instanceId = request.params(":instance");
String containerId = request.params(":container");
return gson.toJson(new DockerRemoteClient().getContainer(instanceId, containerId));
});
get("/docker/:instance/containers/:container/restart", (request, response) -> {
String instanceId = request.params(":instance");
String containerId = request.params(":container");
new DockerRemoteClient().stopContainer(instanceId, containerId);
new DockerRemoteClient().startContainer(instanceId, containerId);
response.redirect("/#/instance-view/" + instanceId);
return "restarting...";
});
get("/docker/:instance/containers/:container/stop", (request, response) -> {
String instanceId = request.params(":instance");
String containerId = request.params(":container");
new DockerRemoteClient().stopContainer(instanceId, containerId);
response.redirect("/#/instance-view/" + instanceId);
return "stopping...";
});
get("/docker/:instance/containers/:container/remove", (request, response) -> {
String instanceId = request.params(":instance");
String containerId = request.params(":container");
new DockerRemoteClient().removeContainer(instanceId, containerId);
response.redirect("/#/instance-view/" + instanceId);
return "removing...";
});
get("/docker/:instance/containers/:container/start", (request, response) -> {
String instanceId = request.params(":instance");
String containerId = request.params(":container");
new DockerRemoteClient().startContainer(instanceId, containerId);
response.redirect("/#/instance-view/" + instanceId);
return "starting...";
});
get("/docker/:instance/containers/:container/log", (request, response) -> {
String instanceId = request.params(":instance");
String containerId = request.params(":container");
return new DockerRemoteClient().getLogOfContainer(instanceId, containerId);
});
get("/repo/locale/settings", (request, response) -> {
return gson.toJson(DeployMan.readUserProperties().entrySet());
});
get("/repo/locale/setups", (request, response) -> {
return gson.toJson(new SetupRepository().getLocaleFiles());
});
get("/repo/locale/formations", (request, response) -> {
return gson.toJson(new FormationRepository().getFormations());
});
get("/repo/locale/formations/:file", (request, response) -> {
String file = request.params(":file");
return gson.toJson(new FormationRepository().getFormationByFileName(file));
});
get("/repo/locale/formations/:file/run", (request, response) -> {
String file = request.params(":file");
LaunchJob launchJob = LaunchJobStore.createNewJob();
launchJob.launch(file);
response.redirect("/#/jobs-view");
return "launching...";
});
get("/repo/remote/configs", (request, response) -> {
return gson.toJson(new ConfigRepository().getRemoteConfigsWithUrl());
});
get("/repo/remote/images", (request, response) -> {
return gson.toJson(new ImageRepository().getRemoteImagesWithUrl());
});
}
}