Skip to content

Commit

Permalink
feat(shulker-proxy-agent): proper support of cluster reconnection
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremylvln committed Aug 23, 2024
1 parent 7c55347 commit 94ef4ba
Show file tree
Hide file tree
Showing 29 changed files with 422 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,23 @@ impl<'a> ResourceBuilder<'a> for MinecraftServerRoleBuilder {
..ObjectMeta::default()
},
rules: Some(vec![
PolicyRule {
api_groups: Some(vec!["".to_string()]),
resources: Some(vec!["events".to_string()]),
verbs: vec!["create".to_string(), "patch".to_string()],
..PolicyRule::default()
},
PolicyRule {
api_groups: Some(vec!["agones.dev".to_string()]),
resources: Some(vec!["gameservers".to_string()]),
verbs: vec![
"list".to_string(),
"watch".to_string(),
"update".to_string(),
"patch".to_string(),
],
..PolicyRule::default()
},
PolicyRule {
api_groups: Some(vec!["".to_string()]),
resources: Some(vec!["events".to_string()]),
verbs: vec!["create".to_string(), "patch".to_string()],
..PolicyRule::default()
},
]),
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,20 @@ impl<'a> ResourceBuilder<'a> for ProxyRoleBuilder {
"list".to_string(),
"watch".to_string(),
"update".to_string(),
"patch".to_string(),
],
..PolicyRule::default()
},
PolicyRule {
api_groups: Some(vec!["".to_string()]),
resources: Some(vec!["services".to_string()]),
verbs: vec!["get".to_string()],
..PolicyRule::default()
},
PolicyRule {
api_groups: Some(vec!["".to_string()]),
resources: Some(vec!["events".to_string()]),
verbs: vec!["create".to_string()],
verbs: vec!["create".to_string(), "patch".to_string()],
..PolicyRule::default()
},
]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ metadata:
name: "shulker:my-cluster:server"
namespace: default
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- agones.dev
resources:
Expand All @@ -30,4 +23,11 @@ rules:
- list
- watch
- update

- patch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ rules:
- list
- watch
- update
- patch
- apiGroups:
- ""
resources:
- services
verbs:
- get
- apiGroups:
- ""
resources:
- events
verbs:
- create

- patch
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ mod bungeecord {
prevent_proxy_connections: bool,
enforce_secure_profile: bool,
log_pings: bool,
reject_transfers: bool,
}

#[derive(Deserialize, Serialize, Clone, Debug)]
Expand Down Expand Up @@ -325,6 +326,7 @@ mod bungeecord {
prevent_proxy_connections: disallow_proxy_connections,
enforce_secure_profile: true,
log_pings: false,
reject_transfers: false,
}
}
}
Expand Down Expand Up @@ -446,6 +448,7 @@ mod bungeecord {
prevent_proxy_connections: true,
enforce_secure_profile: true,
log_pings: false,
reject_transfers: false,
};

// W
Expand Down Expand Up @@ -499,6 +502,7 @@ mod velocity {
pub struct VelocityAdvancedToml {
haproxy_protocol: bool,
tcp_fast_open: bool,
accepts_transfers: bool,
}

impl VelocityToml {
Expand All @@ -514,7 +518,7 @@ mod velocity {
.unwrap_or(false);

VelocityToml {
config_version: "2.6".to_string(),
config_version: "2.7".to_string(),
bind: "0.0.0.0:25577".to_string(),
motd: spec.motd.clone(),
show_max_players: spec.max_players,
Expand All @@ -532,6 +536,7 @@ mod velocity {
advanced: VelocityAdvancedToml {
haproxy_protocol: spec.proxy_protocol,
tcp_fast_open: true,
accepts_transfers: true,
},
}
}
Expand Down Expand Up @@ -646,6 +651,7 @@ mod velocity {
advanced: super::VelocityAdvancedToml {
haproxy_protocol: true,
tcp_fast_open: true,
accepts_transfers: true,
},
};

Expand Down
22 changes: 8 additions & 14 deletions packages/shulker-operator/src/reconcilers/proxy_fleet/fleet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use kube::Client;
use kube::ResourceExt;
use lazy_static::lazy_static;
use shulker_crds::v1alpha1::minecraft_cluster::MinecraftCluster;
use shulker_crds::v1alpha1::proxy_fleet::ProxyFleetServiceSpec;
use shulker_crds::v1alpha1::proxy_fleet::ProxyFleetTemplateVersion;
use url::Url;

Expand Down Expand Up @@ -495,19 +494,6 @@ impl<'a> FleetBuilder {
value: Some(spec.config.players_delta_before_exclusion.to_string()),
..EnvVar::default()
},
EnvVar {
name: "SHULKER_NETWORK_ADMINS".to_string(),
value: Some(
context
.cluster
.spec
.network_admins
.as_ref()
.map(|list| list.join(","))
.unwrap_or("".to_string()),
),
..EnvVar::default()
},
EnvVar {
name: "SHULKER_PROXY_REDIS_HOST".to_string(),
value: Some(redis_ref.host),
Expand Down Expand Up @@ -535,6 +521,14 @@ impl<'a> FleetBuilder {
},
];

if let Some(network_admins) = context.cluster.spec.network_admins.as_ref() {
env.push(EnvVar {
name: "SHULKER_NETWORK_ADMINS".to_string(),
value: Some(network_admins.join(",")),
..EnvVar::default()
})
}

if let Some(preferred_reconnection_address) = proxy_fleet
.spec
.service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ ip_forward: true
prevent_proxy_connections: true
enforce_secure_profile: true
log_pings: false

reject_transfers: false
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ ip_forward: true
prevent_proxy_connections: true
enforce_secure_profile: true
log_pings: false


reject_transfers: false
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ data:
init-fs.sh: "#!/bin/sh\nset -euo pipefail\nset -o xtrace\n\ncp \"${SHULKER_CONFIG_DIR}/probe-readiness.sh\" \"${SHULKER_PROXY_DATA_DIR}/probe-readiness.sh\"\ncat \"${SHULKER_CONFIG_DIR}/server-icon.png\" | base64 -d > \"${SHULKER_PROXY_DATA_DIR}/server-icon.png\"\n\nif [ \"${SHULKER_VERSION_CHANNEL}\" == \"Velocity\" ]; then\n cp \"${SHULKER_CONFIG_DIR}/velocity-config.toml\" \"${SHULKER_PROXY_DATA_DIR}/velocity.toml\"\n echo \"dummy\" > \"${SHULKER_PROXY_DATA_DIR}/forwarding.secret\"\nelse\n cp \"${SHULKER_CONFIG_DIR}/bungeecord-config.yml\" \"${SHULKER_PROXY_DATA_DIR}/config.yml\"\nfi\n\nif [ ! -z \"${SHULKER_PROXY_PLUGIN_URLS:-}\" ]; then\n mkdir -p \"${SHULKER_PROXY_DATA_DIR}/plugins\"\n for plugin_url in ${SHULKER_PROXY_PLUGIN_URLS//;/ }; do\n (cd \"${SHULKER_PROXY_DATA_DIR}/plugins\" && wget \"${plugin_url}\")\n done\nfi\n\nif [ ! -z \"${SHULKER_PROXY_PATCH_URLS:-}\" ]; then\n for patch_url in ${SHULKER_PROXY_PATCH_URLS//;/ }; do\n (cd \"${SHULKER_PROXY_DATA_DIR}\" && wget \"${patch_url}\" -O - | tar -xzv)\n done\nfi\n"
probe-readiness.sh: "#!/bin/sh\n\nset -euo pipefail\nset -o xtrace\n\nif [ -f \"/tmp/drain-lock\" ]; then\n echo \"Drain lock found\" && exit 1\nelif [ -f \"/tmp/readiness-lock\" ]; then\n echo \"Readiness lock found\" && exit 1\nfi\n\nbash /usr/bin/health.sh\n"
server-icon.png: abc==
velocity-config.toml: "config-version = \"2.6\"\nbind = \"0.0.0.0:25577\"\nmotd = \"A Motd\"\nshow-max-players = 1000\nonline-mode = true\nforce-key-authentication = true\nprevent-client-proxy-connections = true\nforwarding-secret-file = \"/mnt/shulker/forwarding-secret/key\"\nplayer-info-forwarding-mode = \"modern\"\n\n[servers]\nlobby = \"localhost:30000\"\nlimbo = \"localhost:30001\"\ntry = [\"lobby\", \"limbo\"]\n\n[forced-hosts]\n\n[advanced]\nhaproxy-protocol = true\ntcp-fast-open = true\n\n"
velocity-config.toml: "config-version = \"2.7\"\nbind = \"0.0.0.0:25577\"\nmotd = \"A Motd\"\nshow-max-players = 1000\nonline-mode = true\nforce-key-authentication = true\nprevent-client-proxy-connections = true\nforwarding-secret-file = \"/mnt/shulker/forwarding-secret/key\"\nplayer-info-forwarding-mode = \"modern\"\n\n[servers]\nlobby = \"localhost:30000\"\nlimbo = \"localhost:30001\"\ntry = [\"lobby\", \"limbo\"]\n\n[forced-hosts]\n\n[advanced]\nhaproxy-protocol = true\ntcp-fast-open = true\naccepts-transfers = true\n\n"
metadata:
labels:
app.kubernetes.io/component: proxy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
source: packages/shulker-operator/src/reconcilers/proxy_fleet/config_map.rs
expression: config
---
config-version = '2.6'
config-version = '2.7'
bind = '0.0.0.0:25577'
motd = 'A Motd'
show-max-players = 100
Expand All @@ -25,3 +25,4 @@ try = [
[advanced]
haproxy-protocol = true
tcp-fast-open = true
accepts-transfers = true
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ try = ["lobby", "limbo"]
[advanced]
haproxy-protocol = true
tcp-fast-open = true


accepts-transfers = true
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ spec:
value: "3600"
- name: SHULKER_PROXY_PLAYER_DELTA_BEFORE_EXCLUSION
value: "15"
- name: SHULKER_NETWORK_ADMINS
value: ""
- name: SHULKER_PROXY_REDIS_HOST
value: my-cluster-redis-managed
- name: SHULKER_PROXY_REDIS_PORT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ class ProxyInterfaceBungeeCord(
if (event.isCancelled) return
val result = hook(wrapPlayer(event.player), event.target.name)

if (result.newServerName.isPresent) {
if (!result.allowed) {
event.isCancelled = true
} else if (result.newServerName.isPresent) {
@Suppress("UnsafeCallOnNullableType")
event.target = proxy.servers[result.newServerName.get()]!!
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.shulkermc.proxyagent.bungeecord

import io.shulkermc.proxyagent.ShulkerProxyAgentCommon
import io.shulkermc.proxyagent.bungeecord.commands.GlobalControlCommand
import io.shulkermc.proxyagent.bungeecord.commands.GlobalFindCommand
import io.shulkermc.proxyagent.bungeecord.commands.GlobalListCommand
import io.shulkermc.proxyagent.bungeecord.commands.GlobalTeleportCommand
Expand All @@ -19,6 +20,7 @@ class ShulkerProxyAgentBungeeCord : Plugin() {
this.proxy.pluginManager.registerCommand(this, GlobalListCommand(this.agent, this.adventure, this.proxy))
this.proxy.pluginManager.registerCommand(this, GlobalTeleportCommand(this.agent, this.adventure))
this.proxy.pluginManager.registerCommand(this, GlobalFindCommand(this.agent, this.adventure))
this.proxy.pluginManager.registerCommand(this, GlobalControlCommand(this.agent, this.adventure))
}

override fun onDisable() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package io.shulkermc.proxyagent.bungeecord.commands

import io.shulkermc.proxyagent.ShulkerProxyAgentCommon
import io.shulkermc.proxyagent.commands.ControlCommandHandler
import net.kyori.adventure.audience.Audience
import net.kyori.adventure.platform.bungeecord.BungeeAudiences
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.NamedTextColor
import net.md_5.bungee.api.CommandSender
import net.md_5.bungee.api.plugin.Command

class GlobalControlCommand(
private val agent: ShulkerProxyAgentCommon,
private val adventure: BungeeAudiences,
) : Command(ControlCommandHandler.NAME, ControlCommandHandler.PERMISSION) {
companion object {
private val USAGE_MESSAGE =
Component.text("Usage: /shulker:ctl <...>").color(NamedTextColor.RED)
.appendNewline()
.append(Component.text("- drain <proxy>"))
.appendNewline()
.append(Component.text("- reconnect <proxy>"))
}

override fun execute(
sender: CommandSender,
args: Array<out String>,
) {
val audience = this.adventure.sender(sender)
if (!BungeeCordCommandHelper.testPermissionOrMessage(sender, audience, this.permission)) {
return
}

if (args.isEmpty()) {
audience.sendMessage(USAGE_MESSAGE)
return
}

val subArguments = args.copyOfRange(1, args.size)

when (args[0]) {
"drain" -> executeDrainSubcommand(audience, subArguments)
"reconnect" -> this.executeReconnectSubcommand(audience, subArguments)
}
}

private fun executeDrainSubcommand(
audience: Audience,
args: Array<out String>,
) {
if (args.isEmpty()) {
audience.sendMessage(USAGE_MESSAGE)
return
}

val proxyName = args[0]
ControlCommandHandler.executeDrainProxy(this.agent, audience, proxyName)
}

private fun executeReconnectSubcommand(
audience: Audience,
args: Array<out String>,
) {
if (args.isEmpty()) {
audience.sendMessage(USAGE_MESSAGE)
return
}

val proxyName = args[0]
ControlCommandHandler.executeReconnectProxy(this.agent, audience, proxyName)
}
}
Loading

0 comments on commit 94ef4ba

Please sign in to comment.