init Repo

This commit is contained in:
Niklas 2017-10-22 16:18:05 +02:00
commit 9641f9dd96
13 changed files with 1213 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.idea/
target/
*.sqlite3
*.iml

89
pom.xml Normal file
View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.gurkengewuerz.monitoring</groupId>
<artifactId>monitoring</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.15.1
</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>slf4j-binding</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.googlecode.lanterna</groupId>
<artifactId>lanterna</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>${project.artifactId}</finalName>
<descriptorRefs>
<descriptorRef>
jar-with-dependencies
</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>${project.groupId}.StartUp</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>assamble</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,254 @@
package de.gurkengewuerz.monitoring;
import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.TextColor;
import com.googlecode.lanterna.gui2.*;
import com.googlecode.lanterna.gui2.dialogs.ActionListDialogBuilder;
import com.googlecode.lanterna.gui2.dialogs.MessageDialog;
import com.googlecode.lanterna.gui2.dialogs.MessageDialogButton;
import com.googlecode.lanterna.gui2.dialogs.TextInputDialog;
import com.googlecode.lanterna.gui2.table.Table;
import com.googlecode.lanterna.screen.Screen;
import com.googlecode.lanterna.screen.TerminalScreen;
import com.googlecode.lanterna.terminal.DefaultTerminalFactory;
import com.googlecode.lanterna.terminal.Terminal;
import de.gurkengewuerz.monitoring.object.MassCommand;
import de.gurkengewuerz.monitoring.object.Server;
import de.gurkengewuerz.monitoring.object.ServerStatus;
import org.apache.commons.validator.routines.InetAddressValidator;
import org.pmw.tinylog.Logger;
import org.sqlite.date.DateFormatUtils;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
* Created by gurkengewuerz.de on 21.10.2017.
*/
public class GUI {
public GUI() {
HashMap<String, Server> serverlist = Server.getServerList(StartUp.getDb());
Poller poller = new Poller();
try {
Terminal terminal = new DefaultTerminalFactory()
.setTerminalEmulatorTitle("Servermanagment").createTerminal();
//TODO: Set GUI Icon
Screen screen = new TerminalScreen(terminal);
screen.startScreen();
Panel mainPanel = new Panel();
mainPanel.setLayoutManager(new LinearLayout(Direction.HORIZONTAL));
mainPanel.setPreferredSize(new TerminalSize(40, 20));
Panel leftPanel = new Panel();
mainPanel.addComponent(leftPanel.withBorder(Borders.singleLine("Serverliste")));
Panel rightPanel = new Panel();
mainPanel.addComponent(rightPanel.withBorder(Borders.singleLine("Aktionen")));
BasicWindow window = new BasicWindow();
window.setComponent(mainPanel.withBorder(Borders.singleLine("Servermanagment")));
window.setHints(Arrays.asList(Window.Hint.CENTERED));
MultiWindowTextGUI gui = new MultiWindowTextGUI(screen, new DefaultWindowManager(), new EmptySpace(TextColor.ANSI.BLUE));
CheckBoxList<String> checkBoxList = new CheckBoxList<String>().addTo(leftPanel);
updateList(checkBoxList, serverlist);
new Button("Server hinzufügen", () -> {
String servername = TextInputDialog.showDialog(gui, "Servername", "Wie soll der Identifiziert werden (Servername)", "Server_Cloud");
if (servername == null) return;
if (serverlist.containsKey(servername)) {
MessageDialog.showMessageDialog(gui, "ERROR!", "Server bereits vorhanden", MessageDialogButton.Cancel);
return;
}
String stringIPPort = TextInputDialog.showDialog(gui, "username@IP:Port", "Wie lautet der Hostname und Port des SSH Servers", "root@10.10.2.156:22");
if (stringIPPort == null) return;
String ss = "ssh://" + stringIPPort;
URI uri;
try {
uri = new URI(ss);
} catch (URISyntaxException e) {
MessageDialog.showMessageDialog(gui, "ERROR!", "Fehler beim lesen der URL", MessageDialogButton.Cancel);
return;
}
String ip = uri.getHost();
int port = uri.getPort();
String username = uri.getUserInfo() == null ? "root" : uri.getUserInfo();
if (port <= 0 || port > 65535) {
MessageDialog.showMessageDialog(gui, "ERROR!", "Port muss größer NUll und kleiner 65535 sein", MessageDialogButton.Cancel);
return;
}
InetAddressValidator inetAddressValidator = new InetAddressValidator();
if (!inetAddressValidator.isValid(ip)) {
MessageDialog.showMessageDialog(gui, "ERROR!", "Inkorrekte IP Adresse", MessageDialogButton.Cancel);
return;
}
try {
PreparedStatement ps = StartUp.getDb().getPreparedStatement("INSERT INTO server (servername, username, ip, port, adddate) VALUES (?, ?, ?, ?, ?);");
ps.setString(1, servername);
ps.setString(2, username);
ps.setString(3, ip);
ps.setInt(4, port);
ps.setLong(5, System.currentTimeMillis() / 1000);
ps.execute();
ResultSet rs = ps.getGeneratedKeys();
rs.next();
int serverid = rs.getInt(1);
Server server = new Server(serverid, servername, username, ip, port);
serverlist.put(servername, server);
checkBoxList.addItem(servername);
Logger.info("Added: " + ip + " " + port);
MessageDialog.showMessageDialog(gui, "INFO", "Server hinzugefügt.\n" +
"Gehe sicher das der Public Key von " + StartUp.getPrivate_key() + " auf dem Server abgelegt wurde.", MessageDialogButton.Continue);
} catch (SQLException e) {
Logger.error(e);
}
}).addTo(rightPanel).takeFocus();
new Button("Alle auswählen", () -> checkBoxList.getItems().forEach(s -> checkBoxList.setChecked(s, true))).addTo(rightPanel);
new Button("Aktion ausführen", () -> {
List<String> checkedItems = checkBoxList.getCheckedItems();
if (checkedItems.size() <= 0) {
MessageDialog.showMessageDialog(gui, "ERROR!", "Bitte wähle zuerst Server aus!");
return;
}
List<Server> serverarray = new ArrayList<>();
checkedItems.forEach(s -> serverarray.add(serverlist.get(s)));
new ActionListDialogBuilder()
.setTitle("Aktion ausführen")
.setDescription("Was möchtest du unternhmen")
.addAction("Server löschen", () -> {
try {
PreparedStatement ps = StartUp.getDb().getPreparedStatement("DELETE FROM server WHERE id = ?");
serverarray.forEach(server -> {
try {
ps.setInt(1, server.getId());
ps.addBatch();
serverlist.remove(server.getName());
} catch (SQLException e) {
Logger.error(e);
}
});
ps.executeBatch();
} catch (SQLException e) {
Logger.error(e);
}
updateList(checkBoxList, serverlist);
})
.addAction("Server Status", () -> {
BasicWindow windowStatus = getStatusWindow(checkBoxList, serverlist);
gui.addWindow(windowStatus);
gui.setActiveWindow(windowStatus);
})
.addAction("Server updaten", () -> MassCommand.run("apt-get update && apt-get upgrade -y", gui, serverarray, StartUp.getPrivate_key()))
.addAction("Herunterfahren", () -> MassCommand.run("shutdown -h now", gui, serverarray, StartUp.getPrivate_key()))
.addAction("Neustart", () -> MassCommand.run("reboot", gui, serverarray, StartUp.getPrivate_key()))
.build()
.showDialog(gui);
}).addTo(rightPanel);
new Button("Aktualisieren", () -> {
// TODO: serverlist = Server.getServerList(db);
updateList(checkBoxList, serverlist);
}).addTo(rightPanel);
new Button("Beenden", () -> {
poller.stop();
StartUp.getDb().closeConnection();
System.exit(0);
}).addTo(rightPanel);
screen.setCursorPosition(null);
gui.addWindowAndWait(window);
} catch (IOException e) {
Logger.error(e);
}
}
private void updateList(CheckBoxList<String> checkBoxList, HashMap<String, Server> serverlist) {
checkBoxList.clearItems();
serverlist.forEach((s, server) -> checkBoxList.addItem(s));
}
private BasicWindow getStatusWindow(CheckBoxList<String> checkBoxList, HashMap<String, Server> serverlist) {
Panel statusPanel = new Panel();
statusPanel.setLayoutManager(new LinearLayout(Direction.VERTICAL));
BasicWindow windowStatus = new BasicWindow();
windowStatus.setComponent(statusPanel.withBorder(Borders.singleLine("Server Status")));
windowStatus.setHints(Arrays.asList(Window.Hint.CENTERED));
Table<String> table = new Table<String>("Name", "OS", "CPU", "RAM", "Uptime", "Last", "Status").addTo(statusPanel);
updateTable(table, checkBoxList, serverlist);
Button back = new Button("Zurück", windowStatus::close).addTo(statusPanel);
back.takeFocus();
return windowStatus;
}
private void updateTable(Table<String> table, CheckBoxList<String> checkBoxList, HashMap<String, Server> serverlist) {
for (String s : checkBoxList.getCheckedItems()) {
Server server = serverlist.get(s);
ServerStatus status = server.getStatus();
if (status.getLastpoll() == 0) {
return;
}
double totalMB = round(status.getMemTotal() / 1024.0, 2);
double freeMB = round(status.getMemFree() / 1024.0, 2);
table.getTableModel().addRow(server.getName(),
status.getOS(), status.getCPUcount() + "x " + status.getCPUModel(),
freeMB + "MB/" + totalMB + "MB", DateFormatUtils.format(status.getUptime() * 1000, "HH:mm:ss"),
String.valueOf(status.getLoad()), status.getState().toString());
}
// "Name", "OS", "CPU", "RAM", "Uptime", "Last", "Status"
}
public static BasicWindow getCallbackWindow(Label label, Button abort) {
Panel statusPanel = new Panel();
statusPanel.setLayoutManager(new LinearLayout(Direction.VERTICAL));
BasicWindow windowStatus = new BasicWindow();
windowStatus.setComponent(statusPanel.withBorder(Borders.singleLine("Update Status")));
windowStatus.setHints(Arrays.asList(Window.Hint.CENTERED));
label.addTo(statusPanel);
abort.addTo(statusPanel);
return windowStatus;
}
private double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
}

View File

@ -0,0 +1,109 @@
package de.gurkengewuerz.monitoring;
import de.gurkengewuerz.monitoring.object.SSHManager;
import de.gurkengewuerz.monitoring.object.Server;
import de.gurkengewuerz.monitoring.object.ServerStatus;
import de.gurkengewuerz.monitoring.object.State;
import org.pmw.tinylog.Logger;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Created by gurkengewuerz.de on 21.10.2017.
*/
public class Poller {
final ScheduledExecutorService scheduler;
public Poller() {
scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(() -> {
HashMap<String, Server> serverlist = Server.getServerList(StartUp.getDb());
serverlist.forEach((s, server) -> {
Logger.info("Poling " + s);
ServerStatus status = server.getStatus();
if (status.getState() == State.PAUSED) {
Logger.info("Paused!");
return;
}
SSHManager manager = server.getSSHSession(StartUp.getPrivate_key());
if (manager.hasError()) {
status.setState(State.OFFLINE);
Logger.error("Offline!");
try {
if (status.getLastpoll() == 0) return;
PreparedStatement ps = StartUp.getDb().getPreparedStatement("UPDATE status SET state = ?, lastpoll = ? WHERE server_id = ?;");
ps.setString(1, status.getState().toString());
ps.setLong(2, System.currentTimeMillis() / 1000);
ps.setInt(3, server.getId());
ps.execute();
} catch (SQLException e) {
Logger.error(e);
}
status.setLastpoll(System.currentTimeMillis() / 1000);
return;
}
try {
status.setState(State.ONLINE);
Logger.info("Online!");
NumberFormat format = NumberFormat.getInstance(Locale.US);
String os = manager.sendCommand(". /etc/os-release; echo ${PRETTY_NAME/*, /}").replace("\n", "");
status.setOS(os);
String cpumodel = manager.sendCommand("grep \"model name\" /proc/cpuinfo | cut -c14- | head -n 1").replace("\n", "");
status.setCPU(cpumodel);
String cpucount = manager.sendCommand("cat /proc/cpuinfo | grep processor | wc -l").replace("\n", "");
status.setCPUcount(format.parse(cpucount).intValue());
String memtotal = manager.sendCommand("awk '/MemTotal/ { print $2 }' /proc/meminfo").replace("\n", "");
status.setMemTotal(format.parse(memtotal).intValue());
String memfree = manager.sendCommand("awk '/MemFree/ { print $2 }' /proc/meminfo").replace("\n", "");
status.setMemFree(format.parse(memfree).intValue());
String load = manager.sendCommand("if [[ -z `uptime | awk '{print $12}' | cut -d \",\" -f 1` ]]; then uptime | awk '{print $10}' | cut -d \",\" -f 1; else uptime | awk '{print $12}' | cut -d \",\" -f 1; fi;").replace("\n", "");
status.setLoad(format.parse(load).floatValue());
String uptimeseconds = manager.sendCommand("awk '{print $1}' /proc/uptime").replace("\n", "");
status.setUptime(format.parse(uptimeseconds).longValue());
try {
PreparedStatement ps = StartUp.getDb().getPreparedStatement("UPDATE status SET os = ?, cpu = ?, cpucount = ?, max_ram = ?, current_ram = ?, load = ?, uptime = ?, state = ?, lastpoll = ? WHERE server_id = ?;");
if (status.getLastpoll() == 0) {
ps = StartUp.getDb().getPreparedStatement("INSERT INTO status (os, cpu, cpucount, max_ram, current_ram, load, uptime, state, lastpoll, server_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
}
ps.setString(1, os);
ps.setString(2, cpumodel);
ps.setInt(3, format.parse(cpucount).intValue());
ps.setInt(4, format.parse(memtotal).intValue());
ps.setInt(5, format.parse(memfree).intValue());
ps.setFloat(6, format.parse(load).floatValue());
ps.setLong(7, format.parse(uptimeseconds).longValue());
ps.setString(8, status.getState().toString());
ps.setLong(9, System.currentTimeMillis() / 1000);
ps.setInt(10, server.getId());
ps.execute();
} catch (SQLException e) {
Logger.error(e);
}
status.setLastpoll(System.currentTimeMillis() / 1000);
} catch (ParseException e) {
Logger.error(e);
}
manager.close();
});
}, 0, 90, TimeUnit.SECONDS);
}
public void stop() {
scheduler.shutdown();
}
}

View File

@ -0,0 +1,107 @@
package de.gurkengewuerz.monitoring;
import de.gurkengewuerz.monitoring.object.Database;
import org.apache.commons.cli.*;
import org.pmw.tinylog.Logger;
import java.io.File;
import java.sql.SQLException;
/**
* Created by gurkengewuerz.de on 21.10.2017.
*/
public class StartUp {
private static Database db;
private static String private_key;
public static void main(String... args) {
Options options = new Options();
Option database = new Option("d", "database", true, "Database Path");
database.setRequired(false);
options.addOption(database);
Option poller = new Option("p", "poller", false, "Start only the poller");
poller.setRequired(false);
options.addOption(poller);
Option sshkey = new Option("s", "key", true, "Set ssh private key");
sshkey.setRequired(false);
options.addOption(sshkey);
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd;
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
Logger.error(e);
formatter.printHelp("utility-name", options);
System.exit(1);
return;
}
try {
db = new Database(cmd.getOptionValue("d", Variables.DATABASE_NAME));
} catch (Exception e) {
Logger.error(e);
}
if (db == null) System.exit(1);
try {
createDatabase();
} catch (SQLException e) {
Logger.error(e);
System.exit(1);
}
private_key = cmd.getOptionValue("s", Variables.PRIVATE_KEY);
if (!new File(private_key).exists()) {
Logger.error(private_key + " wurde nicht gefunden!");
System.exit(1);
}
if (cmd.hasOption("p")) {
new Poller();
} else {
new GUI();
}
}
public static Database getDb() {
return db;
}
public static String getPrivate_key() {
return private_key;
}
private static void createDatabase() throws SQLException {
db.executeUpdate(
"CREATE TABLE IF NOT EXISTS server (" +
" id INTEGER PRIMARY KEY AUTOINCREMENT," +
" servername text NULL," +
" username text NULL," +
" ip text NULL," +
" port int NULL," +
" adddate float NOT NULL" +
");"
);
db.executeUpdate("CREATE TABLE IF NOT EXISTS status (" +
"server_id INTEGER," +
"os TEXT," +
"cpu TEXT," +
"cpucount INTEGER," +
"max_ram INTEGER," +
"current_ram INTEGER," +
"load float," +
"uptime INTEGER," +
"state text," +
"lastpoll INTEGER" +
");"
);
}
}

View File

@ -0,0 +1,10 @@
package de.gurkengewuerz.monitoring;
/**
* Created by gurkengewuerz.de on 21.10.2017.
*/
public class Variables {
public static final String DATABASE_NAME = "data.sqlite3";
public static final String PRIVATE_KEY = System.getProperty("user.home") + "/.ssh/id_rsa";
}

View File

@ -0,0 +1,128 @@
package de.gurkengewuerz.monitoring.object;
import java.sql.*;
/**
* Created by gurkengewuerz.de on 08.04.2017.
*/
public class Database {
private String sUrl = null;
private int iTimeout = 30;
private Connection conn = null;
private Statement statement = null;
public Database(String sUrlToLoad) throws Exception {
setUrl(sUrlToLoad);
setConnection();
setStatement();
}
private void setUrl(String sUrlVar) {
sUrl = sUrlVar;
}
private void setConnection() throws Exception {
conn = DriverManager.getConnection("jdbc:sqlite:" + sUrl);
}
public Connection getConnection() {
return conn;
}
private void setStatement() throws Exception {
if (conn == null) {
setConnection();
}
statement = conn.createStatement();
statement.setQueryTimeout(iTimeout); // set timeout to 30 sec.
}
public PreparedStatement getPreparedStatement(String sql) throws SQLException {
return conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
}
public void executeUpdate(String instruction) throws SQLException {
statement.executeUpdate(instruction);
}
public ResultSet executeQuery(String instruction) throws SQLException {
return statement.executeQuery(instruction);
}
public void closeConnection() {
try {
conn.close();
} catch (Exception ignore) {
}
}
public static String escapeString(String x, boolean escapeDoubleQuotes) {
StringBuilder sBuilder = new StringBuilder(x.length() * 11 / 10);
int stringLength = x.length();
for (int i = 0; i < stringLength; ++i) {
char c = x.charAt(i);
switch (c) {
case 0: /* Must be escaped for 'mysql' */
sBuilder.append('\\');
sBuilder.append('0');
break;
case '\n': /* Must be escaped for logs */
sBuilder.append('\\');
sBuilder.append('n');
break;
case '\r':
sBuilder.append('\\');
sBuilder.append('r');
break;
case '\\':
sBuilder.append('\\');
sBuilder.append('\\');
break;
case '\'':
sBuilder.append('\\');
sBuilder.append('\'');
break;
case '"': /* Better safe than sorry */
if (escapeDoubleQuotes) {
sBuilder.append('\\');
}
sBuilder.append('"');
break;
case '\032': /* This gives problems on Win32 */
sBuilder.append('\\');
sBuilder.append('Z');
break;
case '\u00a5':
case '\u20a9':
// escape characters interpreted as backslash by mysql
// fall through
default:
sBuilder.append(c);
}
}
return sBuilder.toString();
}
}

View File

@ -0,0 +1,128 @@
package de.gurkengewuerz.monitoring.object;
import com.googlecode.lanterna.gui2.BasicWindow;
import com.googlecode.lanterna.gui2.Button;
import com.googlecode.lanterna.gui2.Label;
import com.googlecode.lanterna.gui2.MultiWindowTextGUI;
import com.googlecode.lanterna.gui2.dialogs.MessageDialog;
import com.googlecode.lanterna.gui2.dialogs.MessageDialogButton;
import de.gurkengewuerz.monitoring.GUI;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.List;
/**
* Created by gurkengewuerz.de on 22.10.2017.
*/
public class MassCommand {
private String command;
private String private_key;
private List<Server> serverList = new ArrayList<>();
private StatusReply answer;
private boolean stop = false;
private Thread t;
public MassCommand(String command, String private_key, List<Server> serverList, StatusReply answer) {
this.command = command;
this.private_key = private_key;
this.serverList = serverList;
this.answer = answer;
}
public MassCommand(String command, List<Server> serverList, StatusReply answer) {
this(command, "", serverList, answer);
}
public MassCommand setPrivateKey(String private_key) {
this.private_key = private_key;
return this;
}
public void start() {
t = new Thread(() -> {
final boolean[] failed = {false};
final int[] counter = {0};
answer.onStart();
serverList.forEach(server -> {
if (stop) return;
if (failed[0]) return;
SSHManager manager = server.getSSHSession(private_key);
if (manager.hasError()) {
failed[0] = true;
answer.onFail(manager.getErrorMessage());
return;
}
if (failed[0]) return;
String result = manager.sendCommand(command);
Logger.info(result);
manager.close();
answer.onUpdate(counter[0] + 1, serverList.size());
counter[0]++;
});
if (!failed[0]) answer.onFinish();
});
t.start();
}
public void stop() {
stop = true;
t.interrupt();
}
public static void run(String command, MultiWindowTextGUI gui, List<Server> serverarray, String ssh_private) {
Label label = new Label("[ ] 00%");
Button button = new Button("Abbruch");
BasicWindow windowStatus = GUI.getCallbackWindow(label, button);
gui.addWindow(windowStatus);
gui.setActiveWindow(windowStatus);
MassCommand mc = new MassCommand(command, serverarray, new StatusReply() {
@Override
public void onFinish() {
windowStatus.close();
MessageDialog.showMessageDialog(gui, "Erfolgreich", "Befehle erfolgreich auf allen Servern ausgeführt", MessageDialogButton.OK);
}
@Override
public void onStart() {
}
@Override
public void onUpdate(int current, int to_go) {
double perc = (double) current / (double) to_go;
double d = Math.round(perc * 20) / 20.0; // round up to multiple of 0.05
int percInt = (int) (d * 100);
int count = percInt / 5;
StringBuilder stringtext = new StringBuilder("[");
for (int i = 0; i < 20; i++) {
if (i + 1 <= count) {
stringtext.append("#");
} else {
stringtext.append(" ");
}
}
stringtext.append("] ").append(percInt).append("%");
label.setText(stringtext.toString());
}
@Override
public void onFail(String message) {
windowStatus.close();
MessageDialog.showMessageDialog(gui, "ERROR!", "Verbindung zum Server konnte nicht hergestellt werden!\n" + message, MessageDialogButton.Close);
}
}).setPrivateKey(ssh_private);
mc.start();
button.addListener(button1 -> mc.stop());
button.takeFocus();
}
}

View File

@ -0,0 +1,140 @@
package de.gurkengewuerz.monitoring.object;
import com.jcraft.jsch.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* SSHManager
*
* @author cabbott
* @version 1.0
*/
public class SSHManager {
private static final Logger LOGGER =
Logger.getLogger(SSHManager.class.getName());
private JSch jschSSHChannel;
private String strUserName;
private String strConnectionIP;
private int intConnectionPort;
private String strPassword;
private Session sesConnection;
private String errorMessage = null;
private int intTimeOut;
private void doCommonConstructorActions(String userName,
String password, String connectionIP, String knownHostsFileName) {
jschSSHChannel = new JSch();
try {
jschSSHChannel.addIdentity(password);
jschSSHChannel.setKnownHosts(knownHostsFileName);
} catch (JSchException jschX) {
logError(jschX.getMessage());
}
strUserName = userName;
strPassword = password;
strConnectionIP = connectionIP;
}
public SSHManager(String userName, String password,
String connectionIP, String knownHostsFileName) {
doCommonConstructorActions(userName, password,
connectionIP, knownHostsFileName);
intConnectionPort = 22;
intTimeOut = 60000;
}
public SSHManager(String userName, String password, String connectionIP,
String knownHostsFileName, int connectionPort) {
doCommonConstructorActions(userName, password, connectionIP,
knownHostsFileName);
intConnectionPort = connectionPort;
intTimeOut = 60000;
}
public SSHManager(String userName, String password, String connectionIP,
String knownHostsFileName, int connectionPort, int timeOutMilliseconds) {
doCommonConstructorActions(userName, password, connectionIP,
knownHostsFileName);
intConnectionPort = connectionPort;
intTimeOut = timeOutMilliseconds;
}
public String connect() {
errorMessage = null;
try {
sesConnection = jschSSHChannel.getSession(strUserName,
strConnectionIP, intConnectionPort);
//sesConnection.setPassword(strPassword);
// UNCOMMENT THIS FOR TESTING PURPOSES, BUT DO NOT USE IN PRODUCTION
sesConnection.setConfig("StrictHostKeyChecking", "no");
sesConnection.connect(intTimeOut);
} catch (JSchException jschX) {
errorMessage = jschX.getMessage();
}
return errorMessage;
}
public boolean hasError() {
return errorMessage != null;
}
public String getErrorMessage() {
return errorMessage;
}
private String logError(String errorMessage) {
if (errorMessage != null) {
LOGGER.log(Level.SEVERE, "{0}:{1} - {2}",
new Object[]{strConnectionIP, intConnectionPort, errorMessage});
}
return errorMessage;
}
private String logWarning(String warnMessage) {
if (warnMessage != null) {
LOGGER.log(Level.WARNING, "{0}:{1} - {2}",
new Object[]{strConnectionIP, intConnectionPort, warnMessage});
}
return warnMessage;
}
public String sendCommand(String command) {
StringBuilder outputBuffer = new StringBuilder();
try {
Channel channel = sesConnection.openChannel("exec");
((ChannelExec) channel).setCommand(command);
InputStream commandOutput = channel.getInputStream();
channel.connect();
int readByte = commandOutput.read();
while (readByte != 0xffffffff) {
outputBuffer.append((char) readByte);
readByte = commandOutput.read();
}
channel.disconnect();
} catch (IOException | JSchException ioX) {
logWarning(ioX.getMessage());
return null;
}
return outputBuffer.toString();
}
public void close() {
sesConnection.disconnect();
}
}

View File

@ -0,0 +1,90 @@
package de.gurkengewuerz.monitoring.object;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
/**
* Created by gurkengewuerz.de on 21.10.2017.
*/
public class Server {
private int id;
private String name;
private String username;
private String ip;
private int port;
private long timeAdded;
private ServerStatus status;
public Server(int id, String name, String username, String ip, int port, long timeAdded, ServerStatus status) {
this.id = id;
this.name = name;
this.username = username;
this.ip = ip;
this.port = port;
this.timeAdded = timeAdded;
this.status = status;
}
public Server(int id, String name, String username, String ip, int port) {
this(id, name, username, ip, port, System.currentTimeMillis() / 1000,
new ServerStatus(null, null, 0, 0, 0, 0, 0, State.OFFLINE, 0));
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getUsername() {
return username;
}
public long getTimeAdded() {
return timeAdded;
}
public ServerStatus getStatus() {
return status;
}
public void setStatus(ServerStatus status) {
this.status = status;
}
public SSHManager getSSHSession(String ssh_private) {
SSHManager instance = new SSHManager(getUsername(), ssh_private, ip, "", port);
String errorMessage = instance.connect();
if (errorMessage != null) {
Logger.error(errorMessage);
}
return instance;
}
public static HashMap<String, Server> getServerList(Database db) {
HashMap<String, Server> serverlist = new HashMap<>();
try {
ResultSet rs = db.executeQuery("SELECT * FROM server LEFT JOIN status ON server.id = status.server_id;");
while (rs.next()) {
ServerStatus status = new ServerStatus(rs.getString("os"),
rs.getString("cpu"), rs.getInt("cpucount"), rs.getInt("max_ram"),
rs.getInt("current_ram"), rs.getFloat("load"),
rs.getLong("uptime"), State.getByName(rs.getString("state")), rs.getLong("lastpoll"));
Server s = new Server(rs.getInt("id"), rs.getString("servername"), rs.getString("username"),
rs.getString("ip"), rs.getInt("port"), rs.getLong("adddate"), status);
serverlist.put(rs.getString("servername"), s);
}
} catch (SQLException e) {
Logger.error(e);
}
return serverlist;
}
}

View File

@ -0,0 +1,101 @@
package de.gurkengewuerz.monitoring.object;
/**
* Created by gurkengewuerz.de on 21.10.2017.
*/
public class ServerStatus {
private String os;
private String cpu;
private int cpucount;
private int memTotal;
private int memFree;
private float load;
private long uptime;
private State state;
private long lastpoll;
public ServerStatus(String os, String cpu, int cpucount, int memTotal, int memFree, float load, long uptime, State state, long lastpoll) {
this.os = os == null ? "Unknown" : os;
this.cpu = cpu == null ? "Unknown" : cpu;
this.cpucount = cpucount;
this.memTotal = memTotal;
this.memFree = memFree;
this.load = load;
this.uptime = uptime;
this.state = state;
this.lastpoll = lastpoll;
}
public String getOS() {
return os;
}
public String getCPUModel() {
return cpu;
}
public int getCPUcount() {
return cpucount;
}
public int getMemTotal() {
return memTotal;
}
public int getMemFree() {
return memFree;
}
public float getLoad() {
return load;
}
public long getUptime() {
return uptime;
}
public State getState() {
return state;
}
public long getLastpoll() {
return lastpoll;
}
public void setOS(String os) {
this.os = os;
}
public void setCPU(String cpu) {
this.cpu = cpu;
}
public void setCPUcount(int cpucount) {
this.cpucount = cpucount;
}
public void setMemTotal(int memTotal) {
this.memTotal = memTotal;
}
public void setMemFree(int memFree) {
this.memFree = memFree;
}
public void setLoad(float load) {
this.load = load;
}
public void setUptime(long uptime) {
this.uptime = uptime;
}
public void setState(State state) {
this.state = state;
}
public void setLastpoll(long lastpoll) {
this.lastpoll = lastpoll;
}
}

View File

@ -0,0 +1,38 @@
package de.gurkengewuerz.monitoring.object;
/**
* Created by gurkengewuerz.de on 21.10.2017.
*/
public enum State {
ONLINE {
@Override
public String toString() {
return "online";
}
},
OFFLINE {
@Override
public String toString() {
return "offline";
}
},
PAUSED {
@Override
public String toString() {
return "paused";
}
};
public static State getByName(String state) {
if (state == null) return null;
switch (state.toLowerCase()) {
case "offline":
return OFFLINE;
case "online":
return ONLINE;
case "paused":
return PAUSED;
}
return null;
}
}

View File

@ -0,0 +1,15 @@
package de.gurkengewuerz.monitoring.object;
/**
* Created by gurkengewuerz.de on 22.10.2017.
*/
public interface StatusReply {
void onFinish();
void onStart();
void onUpdate(int current, int to_go);
void onFail(String message);
}