DevUpdate Server for Test Server Updates

This commit is contained in:
Kenneth Endfinger 2021-12-22 23:45:36 -05:00
parent 795e99ad4f
commit 139ce551dc
No known key found for this signature in database
GPG Key ID: C4E68E5647420E10
4 changed files with 117 additions and 2 deletions

View File

@ -1,6 +1,7 @@
package cloud.kubelet.foundation.core
import cloud.kubelet.foundation.core.command.*
import cloud.kubelet.foundation.core.devupdate.DevUpdateServer
import cloud.kubelet.foundation.core.persist.PersistentStore
import cloud.kubelet.foundation.core.persist.setAllProperties
import io.papermc.paper.event.player.AsyncChatEvent
@ -19,6 +20,8 @@ import java.util.concurrent.ConcurrentHashMap
class FoundationCorePlugin : JavaPlugin(), Listener {
internal val persistentStores = ConcurrentHashMap<String, PersistentStore>()
private lateinit var _pluginDataPath: Path
private lateinit var chatLogStore: PersistentStore
private lateinit var devUpdateServer: DevUpdateServer
var pluginDataPath: Path
/**
@ -40,8 +43,6 @@ class FoundationCorePlugin : JavaPlugin(), Listener {
*/
fun getPersistentStore(name: String) = persistentStores.getOrPut(name) { PersistentStore(this, name) }
private lateinit var chatLogStore: PersistentStore
override fun onEnable() {
pluginDataPath = dataFolder.toPath()
val backupPath = pluginDataPath.resolve(BACKUPS_DIRECTORY)
@ -67,11 +68,14 @@ class FoundationCorePlugin : JavaPlugin(), Listener {
log.info("Features:")
Util.printFeatureStatus(log, "Backup", BACKUP_ENABLED)
chatLogStore = getPersistentStore("chat-logs")
devUpdateServer = DevUpdateServer(this)
devUpdateServer.enable()
}
override fun onDisable() {
persistentStores.values.forEach { store -> store.close() }
persistentStores.clear()
devUpdateServer.disable()
}
private fun registerCommandExecutor(name: String, executor: CommandExecutor) {

View File

@ -0,0 +1,10 @@
package cloud.kubelet.foundation.core.devupdate
import kotlinx.serialization.Serializable
@Serializable
class DevUpdateConfig(
val port: Int = 8484,
val token: String,
val ipAllowList: List<String> = listOf("*")
)

View File

@ -0,0 +1,89 @@
package cloud.kubelet.foundation.core.devupdate
import cloud.kubelet.foundation.core.FoundationCorePlugin
import cloud.kubelet.foundation.core.Util
import com.charleskorn.kaml.Yaml
import com.sun.net.httpserver.HttpExchange
import com.sun.net.httpserver.HttpServer
import java.net.InetSocketAddress
import kotlin.io.path.inputStream
class DevUpdateServer(val plugin: FoundationCorePlugin) {
private lateinit var config: DevUpdateConfig
private var server: HttpServer? = null
fun enable() {
val configPath = Util.copyDefaultConfig<FoundationCorePlugin>(
plugin.slF4JLogger,
plugin.pluginDataPath,
"devupdate.yaml"
)
config = Yaml.default.decodeFromStream(DevUpdateConfig.serializer(), configPath.inputStream())
start()
}
private fun start() {
if (config.token.isEmpty()) {
return
}
if (config.token.length < 8) {
plugin.slF4JLogger.warn("DevUpdate Token was too short (must be 8 or more characters)")
return
}
val server = HttpServer.create()
server.createContext("/").setHandler { exchange ->
val ip = exchange.remoteAddress.address.hostAddress
if (!config.ipAllowList.contains("*") && !config.ipAllowList.contains(ip)) {
plugin.slF4JLogger.warn("DevUpdate Server received request from IP $ip which is not allowed.")
exchange.close()
return@setHandler
}
plugin.slF4JLogger.info("DevUpdate Server Request $ip ${exchange.requestMethod} ${exchange.requestURI.path}")
if (exchange.requestMethod != "POST") {
exchange.respond(405, "Method not allowed.")
return@setHandler
}
if (exchange.requestURI.path != "/webhook/update") {
exchange.respond(404, "Not Found.")
return@setHandler
}
if (exchange.requestURI.query != config.token) {
exchange.respond(401, "Unauthorized.")
return@setHandler
}
exchange.respond(200, "Success.")
plugin.server.scheduler.runTask(plugin) { ->
plugin.slF4JLogger.info("DevUpdate Server Restart")
try {
plugin.server.dispatchCommand(plugin.server.consoleSender, "fupdate")
plugin.server.dispatchCommand(plugin.server.consoleSender, "stop")
} catch (e: Exception) {
plugin.slF4JLogger.error("DevUpdate Server failed to update server.", e)
}
}
}
server.bind(InetSocketAddress("0.0.0.0", config.port), 0)
server.start()
this.server = server
plugin.slF4JLogger.info("DevUpdate Server listening on port ${config.port}")
}
fun disable() {
server?.stop(0)
}
private fun HttpExchange.respond(code: Int, content: String) {
val encoded = content.encodeToByteArray()
sendResponseHeaders(code, encoded.size.toLong())
responseBody.write(encoded)
responseBody.close()
close()
}
}

View File

@ -0,0 +1,12 @@
# Server port to listen on.
port: 8484
# An authentication token. Should be random and 8 or more characters.
# If empty, the DevUpdate server is not enabled.
token: ""
# IP address allow list.
# If * is specified, all addresses are allowed.
# Specify IP addresses as a string that should be allowed to update the server.
ipAllowList:
- "*"