Skip to content

Commit d0298dc

Browse files
ChunyiLyumkuratczyk
andauthoredNov 2, 2020
Ensure MY_POD_NAME, MY_POD_NAMESPACE, and K8S_SERVICE_NAME envVar defined first (#437)
* Ensure MY_POD_NAME, MY_POD_NAMESPACE, and K8S_SERVICE_NAME envVar defined first - handle the rabbitmq container envVar list as a special case if it's overwritten by override - we need to ensure that MY_POD_NAME, MY_POD_NAMESPACE, and K8S_SERVICE_NAME are defined first so other envVars values can reference them Co-authored-by: Michal Kuratczyk <[email protected]>
1 parent 2a553b2 commit d0298dc

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed
 

‎internal/resource/statefulset.go

+34
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,34 @@ func patchPodSpec(podSpec, podSpecOverride *corev1.PodSpec) (corev1.PodSpec, err
233233
if err != nil {
234234
return corev1.PodSpec{}, fmt.Errorf("error unmarshalling patched Stateful Set: %v", err)
235235
}
236+
237+
// handle the rabbitmq container envVar list as a special case if it's overwritten
238+
// we need to ensure that MY_POD_NAME, MY_POD_NAMESPACE and K8S_SERVICE_NAME are defined first so other envVars values can reference them
239+
if rmqContainer := containerRabbitmq(podSpecOverride.Containers); rmqContainer.Env != nil {
240+
sortEnvVar(patchedPodSpec.Containers[0].Env)
241+
}
242+
236243
return patchedPodSpec, nil
237244
}
238245

246+
// sortEnvVar ensures that 'MY_POD_NAME', 'MY_POD_NAMESPACE' and 'K8S_SERVICE_NAME' envVars are defined first in the list
247+
// this is to enable other envVars to reference them as variables successfully
248+
func sortEnvVar(envVar []corev1.EnvVar) {
249+
for i, e := range envVar {
250+
if e.Name == "MY_POD_NAME" {
251+
envVar[0], envVar[i] = envVar[i], envVar[0]
252+
continue
253+
}
254+
if e.Name == "MY_POD_NAMESPACE" {
255+
envVar[1], envVar[i] = envVar[i], envVar[1]
256+
continue
257+
}
258+
if e.Name == "K8S_SERVICE_NAME" {
259+
envVar[2], envVar[i] = envVar[i], envVar[2]
260+
}
261+
}
262+
}
263+
239264
func (builder *StatefulSetBuilder) podTemplateSpec(annotations, labels map[string]string) corev1.PodTemplateSpec {
240265
//Init Container resources
241266
cpuRequest := k8sresource.MustParse(initContainerCPU)
@@ -703,3 +728,12 @@ func mergeMap(base, override map[string]string) map[string]string {
703728

704729
return result
705730
}
731+
732+
func containerRabbitmq(containers []corev1.Container) corev1.Container {
733+
for _, container := range containers {
734+
if container.Name == "rabbitmq" {
735+
return container
736+
}
737+
}
738+
return corev1.Container{}
739+
}

‎internal/resource/statefulset_test.go

+110
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,116 @@ var _ = Describe("StatefulSet", func() {
14211421
},
14221422
))
14231423
})
1424+
Context("Container EnvVar", func() {
1425+
It("Overrides the envVar list while making sure that 'MY_POD_NAME', 'MY_POD_NAMESPACE' and 'K8S_SERVICE_NAME' are always defined first", func() {
1426+
instance.Spec.Override.StatefulSet = &rabbitmqv1beta1.StatefulSet{
1427+
Spec: &rabbitmqv1beta1.StatefulSetSpec{
1428+
Template: &rabbitmqv1beta1.PodTemplateSpec{
1429+
Spec: &corev1.PodSpec{
1430+
Containers: []corev1.Container{
1431+
{
1432+
Name: "rabbitmq",
1433+
Env: []corev1.EnvVar{
1434+
{
1435+
Name: "test1",
1436+
Value: "test1",
1437+
},
1438+
{
1439+
Name: "RABBITMQ_USE_LONGNAME",
1440+
Value: "false",
1441+
},
1442+
{
1443+
Name: "RABBITMQ_STREAM_ADVERTISED_HOST",
1444+
Value: "$(MY_POD_NAME).$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE)",
1445+
},
1446+
},
1447+
},
1448+
},
1449+
},
1450+
},
1451+
},
1452+
}
1453+
1454+
builder = &resource.RabbitmqResourceBuilder{
1455+
Instance: &instance,
1456+
Scheme: scheme,
1457+
}
1458+
stsBuilder := builder.StatefulSet()
1459+
Expect(stsBuilder.Update(statefulSet)).To(Succeed())
1460+
Expect(extractContainer(statefulSet.Spec.Template.Spec.Containers, "rabbitmq").Env[0]).To(Equal(
1461+
corev1.EnvVar{
1462+
Name: "MY_POD_NAME",
1463+
ValueFrom: &corev1.EnvVarSource{
1464+
FieldRef: &corev1.ObjectFieldSelector{
1465+
FieldPath: "metadata.name",
1466+
APIVersion: "v1",
1467+
},
1468+
},
1469+
}))
1470+
Expect(extractContainer(statefulSet.Spec.Template.Spec.Containers, "rabbitmq").Env[1]).To(Equal(
1471+
corev1.EnvVar{
1472+
Name: "MY_POD_NAMESPACE",
1473+
ValueFrom: &corev1.EnvVarSource{
1474+
FieldRef: &corev1.ObjectFieldSelector{
1475+
FieldPath: "metadata.namespace",
1476+
APIVersion: "v1",
1477+
},
1478+
},
1479+
}))
1480+
Expect(extractContainer(statefulSet.Spec.Template.Spec.Containers, "rabbitmq").Env[2]).To(Equal(
1481+
corev1.EnvVar{
1482+
Name: "K8S_SERVICE_NAME",
1483+
Value: "foo-rabbitmq-headless",
1484+
}))
1485+
Expect(extractContainer(statefulSet.Spec.Template.Spec.Containers, "rabbitmq").Env).To(ConsistOf(
1486+
corev1.EnvVar{
1487+
Name: "MY_POD_NAME",
1488+
ValueFrom: &corev1.EnvVarSource{
1489+
FieldRef: &corev1.ObjectFieldSelector{
1490+
FieldPath: "metadata.name",
1491+
APIVersion: "v1",
1492+
},
1493+
},
1494+
},
1495+
corev1.EnvVar{
1496+
Name: "MY_POD_NAMESPACE",
1497+
ValueFrom: &corev1.EnvVarSource{
1498+
FieldRef: &corev1.ObjectFieldSelector{
1499+
FieldPath: "metadata.namespace",
1500+
APIVersion: "v1",
1501+
},
1502+
},
1503+
},
1504+
corev1.EnvVar{
1505+
Name: "test1",
1506+
Value: "test1",
1507+
},
1508+
corev1.EnvVar{
1509+
Name: "K8S_SERVICE_NAME",
1510+
Value: instance.ChildResourceName("headless"),
1511+
},
1512+
corev1.EnvVar{
1513+
Name: "RABBITMQ_USE_LONGNAME",
1514+
Value: "false",
1515+
},
1516+
corev1.EnvVar{
1517+
Name: "RABBITMQ_ENABLED_PLUGINS_FILE",
1518+
Value: "/operator/enabled_plugins",
1519+
},
1520+
corev1.EnvVar{
1521+
Name: "RABBITMQ_NODENAME",
1522+
Value: "rabbit@$(MY_POD_NAME).$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE)",
1523+
},
1524+
corev1.EnvVar{
1525+
Name: "K8S_HOSTNAME_SUFFIX",
1526+
Value: ".$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE)",
1527+
},
1528+
corev1.EnvVar{
1529+
Name: "RABBITMQ_STREAM_ADVERTISED_HOST",
1530+
Value: "$(MY_POD_NAME).$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE)",
1531+
}))
1532+
})
1533+
})
14241534
})
14251535

14261536
It("ensures override takes precedence when same property is set both at the top level and at the override level", func() {

0 commit comments

Comments
 (0)