diff --git a/README.md b/README.md index f7cbc59f..8c8bbdad 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ install it into Velocity plugins directory. Also, you have to fill in the config ```yml # The kubernetes namespace to use for the server discovery. namespace: "" +# The prefix to use for the keys of the server labels or annotations. +label-key-prefix: "kuvel.azisaba.net" # Server name synchronization by Redis is required in load-balanced environments using multiple Velocity. redis: group-name: "production" @@ -32,8 +34,9 @@ redis: ``` Alternatively you can use environment variables to configure Kuvel. The environment variable will override - the config.yml and are `KUVEL_NAMESPACE`, `KUVEL_REDIS_GROUPNAME`, `KUVEL_REDIS_CONNECTION_HOSTNAME`, -`KUVEL_REDIS_CONNECTION_PORT`, `KUVEL_REDIS_CONNECTION_USERNAME`, and `KUVEL_REDIS_CONNECTION_PASSWORD`. + the config.yml and are `KUVEL_NAMESPACE`, `KUVEL_LABEL_KEY_PREFIX`, `KUVEL_REDIS_GROUPNAME`, +`KUVEL_REDIS_CONNECTION_HOSTNAME`, `KUVEL_REDIS_CONNECTION_PORT`, `KUVEL_REDIS_CONNECTION_USERNAME`, and +`KUVEL_REDIS_CONNECTION_PASSWORD`. In order for Kuvel to monitor the server, you must request permission from Kubernetes to allow Velocity pods discovery Minecraft servers. For Velocity pods, please allow get/list/watch to Pods @@ -79,6 +82,8 @@ To tell Kuvel that the pod is a Minecraft server, use Label feature of Kubernete | kuvel.azisaba.net/preferred-server-name |Name of the server you wish to register with Velocity| | kuvel.azisaba.net/initial-server |true / false| +If server names longer than 63 characters are desired, the `kuvel.azisaba.net/preferred-server-name` annotation can be used instead of the label. + ### Pod ```yml diff --git a/src/main/java/net/azisaba/kuvel/discovery/impl/redis/RedisLoadBalancerDiscovery.java b/src/main/java/net/azisaba/kuvel/discovery/impl/redis/RedisLoadBalancerDiscovery.java index 526b5df2..5e320962 100644 --- a/src/main/java/net/azisaba/kuvel/discovery/impl/redis/RedisLoadBalancerDiscovery.java +++ b/src/main/java/net/azisaba/kuvel/discovery/impl/redis/RedisLoadBalancerDiscovery.java @@ -3,6 +3,7 @@ import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.ServerInfo; import com.velocitypowered.api.scheduler.ScheduledTask; +import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.apps.ReplicaSet; import io.fabric8.kubernetes.client.KubernetesClient; import java.net.InetSocketAddress; @@ -59,7 +60,6 @@ public void start() { .replicaSets() .inNamespace(namespace) .withLabel(LabelKeys.ENABLE_SERVER_DISCOVERY.getKey(labelKeyPrefix), "true") - .withLabel(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix)) .list() .getItems(); @@ -110,20 +110,25 @@ private void registerOrIgnore(ReplicaSet replicaSet) { } private void registerOrIgnore(ReplicaSet replicaSet, boolean isFetchedFromRedis) { - String uid = replicaSet.getMetadata().getUid(); + ObjectMeta metadata = replicaSet.getMetadata(); + String uid = metadata.getUid(); if (kuvelServiceHandler.getReplicaSetUidAndServerNameMap().getServerNameFromUid(uid) != null) { return; } String labelKeyPrefix = plugin.getKuvelConfig().getLabelKeyPrefix(); String serverName = - replicaSet - .getMetadata() - .getLabels() + metadata + .getAnnotations() .getOrDefault(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix), null); + if (serverName == null) { + serverName = + metadata + .getLabels() + .getOrDefault(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix), null); + } boolean initialServer = - replicaSet - .getMetadata() + metadata .getLabels() .getOrDefault(LabelKeys.INITIAL_SERVER.getKey(labelKeyPrefix), "false") .equalsIgnoreCase("true"); @@ -247,10 +252,14 @@ public void registerLoadBalancersForStartup() { .replicaSets() .inNamespace(namespace) .withLabel(LabelKeys.ENABLE_SERVER_DISCOVERY.getKey(labelKeyPrefix), "true") - .withLabel(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix)) .list() .getItems() .stream() + .filter(replicaSet -> { + ObjectMeta metadata = replicaSet.getMetadata(); + return metadata.getAnnotations().containsKey(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix)) + || metadata.getLabels().containsKey(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix)); + }) .filter(replicaSet -> replicaSet.getStatus().getReplicas() > 0) .filter( replicaSet -> @@ -279,10 +288,14 @@ private ReplicaSet getReplicaSetFromUid(String uid) { .replicaSets() .inNamespace(namespace) .withLabel(LabelKeys.ENABLE_SERVER_DISCOVERY.getKey(labelKeyPrefix), "true") - .withLabel(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix)) .list() .getItems() .stream() + .filter(replicaSet -> { + ObjectMeta metadata = replicaSet.getMetadata(); + return metadata.getAnnotations().containsKey(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix)) + || metadata.getLabels().containsKey(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix)); + }) .filter(replicaSet -> replicaSet.getMetadata().getUid().equals(uid)) .findAny() .orElse(null); diff --git a/src/main/java/net/azisaba/kuvel/discovery/impl/redis/RedisServerDiscovery.java b/src/main/java/net/azisaba/kuvel/discovery/impl/redis/RedisServerDiscovery.java index 88ad87f9..6b647c96 100644 --- a/src/main/java/net/azisaba/kuvel/discovery/impl/redis/RedisServerDiscovery.java +++ b/src/main/java/net/azisaba/kuvel/discovery/impl/redis/RedisServerDiscovery.java @@ -1,6 +1,7 @@ package net.azisaba.kuvel.discovery.impl.redis; import com.velocitypowered.api.scheduler.ScheduledTask; +import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.client.KubernetesClient; import java.text.ParseException; @@ -10,6 +11,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -122,17 +124,22 @@ public HashMap getServersForStartup() { .getItems() .forEach( pod -> { - String uid = pod.getMetadata().getUid(); + ObjectMeta metadata = pod.getMetadata(); + String uid = metadata.getUid(); if (podIdToServerNameMap.containsKey(uid)) { return; } String preferServerName = - pod.getMetadata() - .getLabels() - .getOrDefault( - LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix), - pod.getMetadata().getName()); + metadata + .getAnnotations() + .getOrDefault(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix), null); + if (preferServerName == null) { + preferServerName = + metadata + .getLabels() + .getOrDefault(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix), metadata.getName()); + } String serverName = getValidServerName( preferServerName, @@ -231,10 +238,18 @@ private void registerPodOrIgnore(Pod pod) { Map loadBalancerMap = jedis.hgetAll(RedisKeys.LOAD_BALANCERS_PREFIX.getKey() + groupName); + ObjectMeta metadata = pod.getMetadata(); + String labelKeyPrefix = plugin.getKuvelConfig().getLabelKeyPrefix(); String preferServerName = - pod.getMetadata() - .getLabels() - .getOrDefault(LabelKeys.PREFERRED_SERVER_NAME.getKey(plugin.getKuvelConfig().getLabelKeyPrefix()), pod.getMetadata().getName()); + metadata + .getAnnotations() + .getOrDefault(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix), null); + if (preferServerName == null) { + preferServerName = + metadata + .getLabels() + .getOrDefault(LabelKeys.PREFERRED_SERVER_NAME.getKey(labelKeyPrefix), metadata.getName()); + } serverName = getValidServerName( diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4e9acf5f..781b2f06 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,6 @@ # The kubernetes namespace to use for the server discovery. namespace: "" -# The prefix to use for the keys of the server labels. +# The prefix to use for the keys of the server labels or annotations. label-key-prefix: "kuvel.azisaba.net" # Server name synchronization by Redis is required in load-balanced environments using multiple Velocity. redis: