Skip to content

Commit 2b876ce

Browse files
committed
implement multigateway controller
1 parent e3a0b4b commit 2b876ce

File tree

9 files changed

+519
-10
lines changed

9 files changed

+519
-10
lines changed

pkg/resource-handler/controller/etcd/etcd_env.go renamed to pkg/resource-handler/controller/etcd/container_env.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ import (
77
corev1 "k8s.io/api/core/v1"
88
)
99

10-
// buildEtcdEnv constructs all environment variables for etcd clustering in
10+
// buildContainerEnv constructs all environment variables for etcd clustering in
1111
// StatefulSets. This combines pod identity, etcd config, and cluster peer
1212
// discovery details.
13-
func buildEtcdEnv(etcdName, namespace string, replicas int32, serviceName string) []corev1.EnvVar {
13+
func buildContainerEnv(
14+
etcdName, namespace string,
15+
replicas int32,
16+
serviceName string,
17+
) []corev1.EnvVar {
1418
envVars := make([]corev1.EnvVar, 0)
1519

1620
// Add pod identity variables from downward API

pkg/resource-handler/controller/etcd/etcd_env_test.go renamed to pkg/resource-handler/controller/etcd/container_env_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ func TestBuildEtcdClusterPeerList(t *testing.T) {
178178
}
179179
}
180180

181-
func TestBuildEtcdEnv(t *testing.T) {
181+
func TestBuildContainerEnv(t *testing.T) {
182182
tests := map[string]struct {
183183
etcdName string
184184
namespace string
@@ -319,9 +319,9 @@ func TestBuildEtcdEnv(t *testing.T) {
319319

320320
for name, tc := range tests {
321321
t.Run(name, func(t *testing.T) {
322-
got := buildEtcdEnv(tc.etcdName, tc.namespace, tc.replicas, tc.serviceName)
322+
got := buildContainerEnv(tc.etcdName, tc.namespace, tc.replicas, tc.serviceName)
323323
if diff := cmp.Diff(tc.want, got); diff != "" {
324-
t.Errorf("BuildEtcdEnv() mismatch (-want +got):\n%s", diff)
324+
t.Errorf("BuildContainerEnv() mismatch (-want +got):\n%s", diff)
325325
}
326326
})
327327
}

pkg/resource-handler/controller/etcd/statefulset.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func BuildStatefulSet(
8484
Name: "etcd",
8585
Image: image,
8686
Resources: etcd.Spec.Resources,
87-
Env: buildEtcdEnv(
87+
Env: buildContainerEnv(
8888
etcd.Name,
8989
etcd.Namespace,
9090
replicas,

pkg/resource-handler/controller/etcd/statefulset_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func TestBuildStatefulSet(t *testing.T) {
102102
Name: "etcd",
103103
Image: DefaultImage,
104104
Resources: corev1.ResourceRequirements{},
105-
Env: buildEtcdEnv(
105+
Env: buildContainerEnv(
106106
"test-etcd",
107107
"default",
108108
3,
@@ -211,7 +211,7 @@ func TestBuildStatefulSet(t *testing.T) {
211211
Name: "etcd",
212212
Image: "quay.io/coreos/etcd:v3.5.15",
213213
Resources: corev1.ResourceRequirements{},
214-
Env: buildEtcdEnv(
214+
Env: buildContainerEnv(
215215
"etcd-custom",
216216
"test",
217217
5,
@@ -319,7 +319,7 @@ func TestBuildStatefulSet(t *testing.T) {
319319
Name: "etcd",
320320
Image: DefaultImage,
321321
Resources: corev1.ResourceRequirements{},
322-
Env: buildEtcdEnv(
322+
Env: buildContainerEnv(
323323
"test-etcd",
324324
"default",
325325
3,
@@ -435,7 +435,7 @@ func TestBuildStatefulSet(t *testing.T) {
435435
Name: "etcd",
436436
Image: DefaultImage,
437437
Resources: corev1.ResourceRequirements{},
438-
Env: buildEtcdEnv(
438+
Env: buildContainerEnv(
439439
"test-etcd",
440440
"default",
441441
3,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package multigateway
2+
3+
import (
4+
corev1 "k8s.io/api/core/v1"
5+
)
6+
7+
// buildContainerEnv constructs all environment variables for the MultiGateway
8+
// container.
9+
func buildContainerEnv() []corev1.EnvVar {
10+
envVars := []corev1.EnvVar{
11+
{
12+
// TODO: get etcd endpoints and forward them to MultiGateway
13+
Name: "ETCD_ENDPOINTS",
14+
Value: "",
15+
},
16+
{
17+
// TODO: is there an env var for HTTP port?
18+
Name: "HTTP_PORT",
19+
Value: "",
20+
},
21+
{
22+
// TODO: is there an env var for GRPC port?
23+
Name: "GRPC_PORT",
24+
Value: "",
25+
},
26+
{
27+
// TODO: is there an env var for Postgres port?
28+
Name: "POSTGRES_PORT",
29+
Value: "",
30+
},
31+
}
32+
33+
return envVars
34+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package multigateway
2+
3+
import (
4+
"fmt"
5+
6+
appsv1 "k8s.io/api/apps/v1"
7+
corev1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
"k8s.io/apimachinery/pkg/runtime"
10+
ctrl "sigs.k8s.io/controller-runtime"
11+
12+
multigresv1alpha1 "github.com/numtide/multigres-operator/api/v1alpha1"
13+
"github.com/numtide/multigres-operator/pkg/resource-handler/controller/metadata"
14+
)
15+
16+
const (
17+
// ComponentName is the component label value for MultiGateway resources
18+
ComponentName = "multigateway"
19+
20+
// DefaultReplicas is the default number of MultiGateway replicas
21+
DefaultReplicas int32 = 2
22+
23+
// DefaultImage is the default etcd container image
24+
DefaultImage = "numtide/multigres-operator:latest"
25+
)
26+
27+
// BuildDeployment creates a Deployment for the Etcd cluster.
28+
// Returns a deterministic Deployment based on the Etcd spec.
29+
func BuildDeployment(
30+
mg *multigresv1alpha1.MultiGateway,
31+
scheme *runtime.Scheme,
32+
) (*appsv1.Deployment, error) {
33+
replicas := DefaultReplicas
34+
// TODO: Debatable whether this defaulting makes sense.
35+
if mg.Spec.Replicas != nil {
36+
replicas = *mg.Spec.Replicas
37+
}
38+
39+
image := DefaultImage
40+
if mg.Spec.Image != "" {
41+
image = mg.Spec.Image
42+
}
43+
44+
labels := metadata.BuildStandardLabels(mg.Name, ComponentName, mg.Spec.CellName)
45+
podLabels := metadata.MergeLabels(labels, mg.Spec.PodLabels)
46+
47+
deployment := &appsv1.Deployment{
48+
ObjectMeta: metav1.ObjectMeta{
49+
Name: mg.Name,
50+
Namespace: mg.Namespace,
51+
Labels: labels,
52+
},
53+
Spec: appsv1.DeploymentSpec{
54+
Replicas: &replicas,
55+
Selector: &metav1.LabelSelector{
56+
MatchLabels: labels,
57+
},
58+
Template: corev1.PodTemplateSpec{
59+
ObjectMeta: metav1.ObjectMeta{
60+
Labels: podLabels,
61+
Annotations: mg.Spec.PodAnnotations,
62+
},
63+
Spec: corev1.PodSpec{
64+
ServiceAccountName: mg.Spec.ServiceAccountName,
65+
ImagePullSecrets: mg.Spec.ImagePullSecrets,
66+
Containers: []corev1.Container{
67+
{
68+
Name: "multigateway",
69+
Image: image,
70+
Resources: mg.Spec.Resources,
71+
Env: buildContainerEnv(),
72+
Ports: buildContainerPorts(mg),
73+
},
74+
},
75+
Affinity: mg.Spec.Affinity,
76+
Tolerations: mg.Spec.Tolerations,
77+
NodeSelector: mg.Spec.NodeSelector,
78+
TopologySpreadConstraints: mg.Spec.TopologySpreadConstraints,
79+
},
80+
},
81+
},
82+
}
83+
84+
if err := ctrl.SetControllerReference(mg, deployment, scheme); err != nil {
85+
return nil, fmt.Errorf("failed to set controller reference: %w", err)
86+
}
87+
88+
return deployment, nil
89+
}

0 commit comments

Comments
 (0)