Skip to content

Commit

Permalink
feat(shulker-operator): deploy a managed single node redis (jeremylvl…
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremylvln authored Oct 26, 2023
1 parent f36d5b1 commit 3e99751
Show file tree
Hide file tree
Showing 46 changed files with 914 additions and 283 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ rules:
- serviceaccounts
- events
verbs: [create, delete, get, list, patch, update, watch]
- apiGroups:
- apps
resources:
- statefulsets
verbs: [create, delete, get, list, patch, update, watch]
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand Down
11 changes: 11 additions & 0 deletions kube/resources/crd/bases/shulkermc.io_minecraftclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ spec:
description: Auto-generated derived type for MinecraftClusterSpec via `CustomResource`
properties:
spec:
properties:
redis:
nullable: true
properties:
type:
enum:
- ManagedSingleNode
type: string
required:
- type
type: object
type: object
status:
description: The status object of `MinecraftCluster`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ public void onError(Throwable t) {}
public void onCompleted() {}
};

private final Alpha alphaSdk = new AlphaImpl();
private final Alpha alphaSdk;

private AgonesSDKImpl(ManagedChannel channel) {
this.channel = channel;
this.asyncStub = SDKGrpc.newFutureStub(channel);
this.alphaSdk = new AlphaImpl();
}

@Override
Expand Down
21 changes: 20 additions & 1 deletion packages/shulker-crds/src/v1alpha1/minecraft_cluster.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use strum::{Display, IntoStaticStr};

#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)]
#[kube(
Expand All @@ -12,7 +13,25 @@ use serde::{Deserialize, Serialize};
printcolumn = r#"{"name": "Age", "type": "date", "jsonPath": ".metadata.creationTimestamp"}"#
)]
#[serde(rename_all = "camelCase")]
pub struct MinecraftClusterSpec {}
pub struct MinecraftClusterSpec {
#[serde(skip_serializing_if = "Option::is_none")]
pub redis: Option<MinecraftClusterRedisSpec>,
}

#[derive(Deserialize, Serialize, Clone, Debug, Default, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct MinecraftClusterRedisSpec {
pub type_: MinecraftClusterRedisDeploymentType,
}

#[derive(
PartialEq, Deserialize, Serialize, Clone, Debug, Default, JsonSchema, IntoStaticStr, Display,
)]
pub enum MinecraftClusterRedisDeploymentType {
#[default]
ManagedSingleNode,
Provided,
}

/// The status object of `MinecraftCluster`
#[derive(Deserialize, Serialize, Clone, Debug, JsonSchema)]
Expand Down
4 changes: 4 additions & 0 deletions packages/shulker-operator/src/reconcilers/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ pub async fn reconcile_builder<
}
}

if !builder.is_needed(owner) {
return Ok(None);
}

let mut new_resource = builder
.build(owner, &name, existing_resource.as_ref())
.await
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ lazy_static! {
name: Some("my-cluster".to_string()),
..ObjectMeta::default()
},
spec: MinecraftClusterSpec {},
spec: MinecraftClusterSpec { redis: None },
status: None,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ impl ResourceBuilder for ForwardingSecretBuilder {
metadata: ObjectMeta {
name: Some(name.to_string()),
namespace: Some(cluster.namespace().unwrap().clone()),
labels: Some(
MinecraftClusterReconciler::get_common_labels(cluster)
.into_iter()
.collect(),
),
labels: Some(MinecraftClusterReconciler::get_labels(
cluster,
"forwarding-secret".to_string(),
"proxy".to_string(),
)),
..ObjectMeta::default()
},
type_: Some("Opaque".to_string()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ impl ResourceBuilder for MinecraftServerRoleBuilder {
metadata: ObjectMeta {
name: Some(name.to_string()),
namespace: Some(cluster.namespace().unwrap().clone()),
labels: Some(
MinecraftClusterReconciler::get_common_labels(cluster)
.into_iter()
.collect(),
),
labels: Some(MinecraftClusterReconciler::get_labels(
cluster,
"role".to_string(),
"minecraft-server-rbac".to_string(),
)),
..ObjectMeta::default()
},
rules: Some(vec![
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ impl ResourceBuilder for MinecraftServerRoleBindingBuilder {
metadata: ObjectMeta {
name: Some(name.to_string()),
namespace: Some(cluster.namespace().unwrap().clone()),
labels: Some(
MinecraftClusterReconciler::get_common_labels(cluster)
.into_iter()
.collect(),
),
labels: Some(MinecraftClusterReconciler::get_labels(
cluster,
"role-binding".to_string(),
"mincraft-server-rbac".to_string(),
)),
..ObjectMeta::default()
},
role_ref: RoleRef {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ impl ResourceBuilder for MinecraftServerServiceAccountBuilder {
metadata: ObjectMeta {
name: Some(name.to_string()),
namespace: Some(cluster.namespace().unwrap().clone()),
labels: Some(
MinecraftClusterReconciler::get_common_labels(cluster)
.into_iter()
.collect(),
),
labels: Some(MinecraftClusterReconciler::get_labels(
cluster,
"service-account".to_string(),
"minecraft-server-rbac".to_string(),
)),
..ObjectMeta::default()
},
..ServiceAccount::default()
Expand Down
43 changes: 37 additions & 6 deletions packages/shulker-operator/src/reconcilers/minecraft_cluster/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::{collections::BTreeMap, sync::Arc, time::Duration};

use futures::StreamExt;
use k8s_openapi::api::{
core::v1::{Secret, ServiceAccount},
apps::v1::StatefulSet,
core::v1::{Secret, Service, ServiceAccount},
rbac::v1::{Role, RoleBinding},
};
use kube::{
Expand All @@ -24,7 +25,8 @@ use self::{
minecraft_server_role_binding::MinecraftServerRoleBindingBuilder,
minecraft_server_service_account::MinecraftServerServiceAccountBuilder,
proxy_role::ProxyRoleBuilder, proxy_role_binding::ProxyRoleBindingBuilder,
proxy_service_account::ProxyServiceAccountBuilder,
proxy_service_account::ProxyServiceAccountBuilder, redis_service::RedisServiceBuilder,
redis_stateful_set::RedisStatefulSetBuilder,
};

use super::{builder::reconcile_builder, ReconcilerError, Result};
Expand All @@ -36,6 +38,8 @@ mod minecraft_server_service_account;
mod proxy_role;
mod proxy_role_binding;
mod proxy_service_account;
mod redis_service;
mod redis_stateful_set;

#[cfg(test)]
mod fixtures;
Expand All @@ -53,6 +57,8 @@ struct MinecraftClusterReconciler {
minecraft_server_service_account_builder: MinecraftServerServiceAccountBuilder,
minecraft_server_role_builder: MinecraftServerRoleBuilder,
minecraft_server_role_binding_builder: MinecraftServerRoleBindingBuilder,
redis_service_builder: RedisServiceBuilder,
redis_stateful_set_builder: RedisStatefulSetBuilder,
}

impl MinecraftClusterReconciler {
Expand All @@ -76,6 +82,8 @@ impl MinecraftClusterReconciler {
cluster.as_ref(),
)
.await?;
reconcile_builder(&self.redis_service_builder, cluster.as_ref()).await?;
reconcile_builder(&self.redis_stateful_set_builder, cluster.as_ref()).await?;

Ok(Action::requeue(Duration::from_secs(5 * 60)))
}
Expand All @@ -90,12 +98,25 @@ impl MinecraftClusterReconciler {
Ok(Action::await_change())
}

fn get_common_labels(cluster: &MinecraftCluster) -> BTreeMap<String, String> {
fn get_labels(
cluster: &MinecraftCluster,
name: String,
component: String,
) -> BTreeMap<String, String> {
BTreeMap::from([
("app.kubernetes.io/name".to_string(), cluster.name_any()),
("app.kubernetes.io/name".to_string(), name.clone()),
(
"app.kubernetes.io/component".to_string(),
"cluster".to_string(),
"app.kubernetes.io/instance".to_string(),
format!("{}-{}", name, cluster.name_any()),
),
("app.kubernetes.io/component".to_string(), component),
(
"app.kubernetes.io/part-of".to_string(),
format!("cluster-{}", cluster.name_any()),
),
(
"app.kubernetes.io/managed-by".to_string(),
"shulker-operator".to_string(),
),
(
"minecraftcluster.shulkermc.io/name".to_string(),
Expand Down Expand Up @@ -159,6 +180,8 @@ pub async fn run(client: Client) {
minecraft_server_role_binding_builder: MinecraftServerRoleBindingBuilder::new(
client.clone(),
),
redis_service_builder: RedisServiceBuilder::new(client.clone()),
redis_stateful_set_builder: RedisStatefulSetBuilder::new(client.clone()),
};

Controller::new(clusters_api, Config::default().any_semantic())
Expand All @@ -178,6 +201,14 @@ pub async fn run(client: Client) {
Api::<RoleBinding>::all(client.clone()),
Config::default().any_semantic(),
)
.owns(
Api::<Service>::all(client.clone()),
Config::default().any_semantic(),
)
.owns(
Api::<StatefulSet>::all(client.clone()),
Config::default().any_semantic(),
)
.shutdown_on_signal()
.run(reconcile, error_policy, context.into())
.filter_map(|x| async move { std::result::Result::ok(x) })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ impl ResourceBuilder for ProxyRoleBuilder {
metadata: ObjectMeta {
name: Some(name.to_string()),
namespace: Some(cluster.namespace().unwrap().clone()),
labels: Some(
MinecraftClusterReconciler::get_common_labels(cluster)
.into_iter()
.collect(),
),
labels: Some(MinecraftClusterReconciler::get_labels(
cluster,
"role".to_string(),
"proxy-rbac".to_string(),
)),
..ObjectMeta::default()
},
rules: Some(vec![
Expand Down Expand Up @@ -94,12 +94,10 @@ mod tests {
// G
let client = create_client_mock();
let builder = super::ProxyRoleBuilder::new(client);
let name = super::ProxyRoleBuilder::name(&TEST_CLUSTER);

// W
let role = builder
.build(&TEST_CLUSTER, "my-cluster-proxy", None)
.await
.unwrap();
let role = builder.build(&TEST_CLUSTER, &name, None).await.unwrap();

// T
insta::assert_yaml_snapshot!(role);
Expand All @@ -110,12 +108,10 @@ mod tests {
// G
let client = create_client_mock();
let builder = super::ProxyRoleBuilder::new(client);
let name = super::ProxyRoleBuilder::name(&TEST_CLUSTER);

// W
let role = builder
.build(&TEST_CLUSTER, "my-cluster-proxy", None)
.await
.unwrap();
let role = builder.build(&TEST_CLUSTER, &name, None).await.unwrap();

// T
assert!(role.rules.as_ref().unwrap().iter().any(|rule| {
Expand All @@ -130,12 +126,10 @@ mod tests {
// G
let client = create_client_mock();
let builder = super::ProxyRoleBuilder::new(client);
let name = super::ProxyRoleBuilder::name(&TEST_CLUSTER);

// W
let role = builder
.build(&TEST_CLUSTER, "my-cluster-proxy", None)
.await
.unwrap();
let role = builder.build(&TEST_CLUSTER, &name, None).await.unwrap();

// T
assert!(role.rules.as_ref().unwrap().iter().any(|rule| {
Expand All @@ -155,12 +149,10 @@ mod tests {
// G
let client = create_client_mock();
let builder = super::ProxyRoleBuilder::new(client);
let name = super::ProxyRoleBuilder::name(&TEST_CLUSTER);

// W
let role = builder
.build(&TEST_CLUSTER, "my-cluster-proxy", None)
.await
.unwrap();
let role = builder.build(&TEST_CLUSTER, &name, None).await.unwrap();

// T
assert!(role.rules.as_ref().unwrap().iter().any(|rule| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ impl ResourceBuilder for ProxyRoleBindingBuilder {
metadata: ObjectMeta {
name: Some(name.to_string()),
namespace: Some(cluster.namespace().unwrap().clone()),
labels: Some(
MinecraftClusterReconciler::get_common_labels(cluster)
.into_iter()
.collect(),
),
labels: Some(MinecraftClusterReconciler::get_labels(
cluster,
"role-binding".to_string(),
"proxy-rbac".to_string(),
)),
..ObjectMeta::default()
},
role_ref: RoleRef {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ impl ResourceBuilder for ProxyServiceAccountBuilder {
metadata: ObjectMeta {
name: Some(name.to_string()),
namespace: Some(cluster.namespace().unwrap().clone()),
labels: Some(
MinecraftClusterReconciler::get_common_labels(cluster)
.into_iter()
.collect(),
),
labels: Some(MinecraftClusterReconciler::get_labels(
cluster,
"service-account".to_string(),
"proxy-rbac".to_string(),
)),
..ObjectMeta::default()
},
..ServiceAccount::default()
Expand Down Expand Up @@ -76,12 +76,10 @@ mod tests {
// G
let client = create_client_mock();
let builder = super::ProxyServiceAccountBuilder::new(client);
let name = super::ProxyServiceAccountBuilder::name(&TEST_CLUSTER);

// W
let service_account = builder
.build(&TEST_CLUSTER, "my-cluster-proxy", None)
.await
.unwrap();
let service_account = builder.build(&TEST_CLUSTER, &name, None).await.unwrap();

// T
insta::assert_yaml_snapshot!(service_account);
Expand Down
Loading

0 comments on commit 3e99751

Please sign in to comment.