Skip to content
This repository has been archived by the owner on Jun 29, 2022. It is now read-only.

Commit

Permalink
Merge pull request #927 from kinvolk/surajssd/fix-metallb-toleration-…
Browse files Browse the repository at this point in the history
…regression

MetalLB: Fix regressions of tolerations and nodeSelectors
  • Loading branch information
surajssd authored Sep 10, 2020
2 parents d6e67fa + 0a452fd commit 2c42f34
Show file tree
Hide file tree
Showing 2 changed files with 226 additions and 20 deletions.
212 changes: 209 additions & 3 deletions pkg/components/metallb/component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
package metallb

import (
"reflect"
"testing"

"github.com/hashicorp/hcl/v2"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/yaml"

"github.com/kinvolk/lokomotive/pkg/components/util"
)
Expand All @@ -32,7 +36,7 @@ func TestEmptyConfig(t *testing.T) {
}
}

func testRenderManifest(t *testing.T, configHCL string) {
func renderManifest(t *testing.T, configHCL string) map[string]string {
component := newComponent()

body, diagnostics := util.GetComponentBody(configHCL, name)
Expand All @@ -45,11 +49,17 @@ func testRenderManifest(t *testing.T, configHCL string) {
t.Fatalf("Valid config should not return error, got: %s", diagnostics)
}

m, err := component.RenderManifests()
ret, err := component.RenderManifests()
if err != nil {
t.Fatalf("Rendering manifests with valid config should succeed, got: %s", err)
}
if len(m) <= 0 {

return ret
}

func testRenderManifest(t *testing.T, configHCL string) {
m := renderManifest(t, configHCL)
if len(m) == 0 {
t.Fatalf("Rendered manifests shouldn't be empty")
}
}
Expand Down Expand Up @@ -97,3 +107,199 @@ component "metallb" {
`
testRenderManifest(t, configHCL)
}

func getSpeakerDaemonset(t *testing.T, m map[string]string) *appsv1.DaemonSet {
dsStr, ok := m["daemonset-speaker.yaml"]
if !ok {
t.Fatalf("speaker daemonset config not found")
}

ds := &appsv1.DaemonSet{}
if err := yaml.Unmarshal([]byte(dsStr), ds); err != nil {
t.Fatalf("failed unmarshaling manifest: %v", err)
}

return ds
}

func getDeployController(t *testing.T, m map[string]string) *appsv1.Deployment {
deployStr, ok := m["deployment-controller.yaml"]
if !ok {
t.Fatalf("controller deployment config not found")
}

deploy := &appsv1.Deployment{}
if err := yaml.Unmarshal([]byte(deployStr), deploy); err != nil {
t.Fatalf("failed unmarshaling manifest: %v", err)
}

return deploy
}

// nolint:funlen
func TestConversion(t *testing.T) {
configHCL := `
component "metallb" {
address_pools = {
default = ["1.1.1.1/32", "2.2.2.2/32"]
}
speaker_toleration {
key = "speaker_key1"
operator = "Equal"
value = "value1"
}
speaker_toleration {
key = "speaker_key2"
operator = "Equal"
value = "value2"
}
speaker_node_selectors = {
"speaker_node_key1" = "speaker_node_value1"
"speaker_node_key2" = "speaker_node_value2"
}
controller_toleration {
key = "controller_key1"
operator = "Equal"
value = "value1"
}
controller_toleration {
key = "controller_key2"
operator = "Equal"
value = "value2"
}
controller_node_selectors = {
"controller_node_key1" = "controller_node_value1"
"controller_node_key2" = "controller_node_value2"
}
service_monitor = true
}`

m := renderManifest(t, configHCL)
if len(m) == 0 {
t.Fatalf("Rendered manifests shouldn't be empty")
}

tcs := []struct {
Name string
Test func(*testing.T, map[string]string)
}{
{
"SpeakerConversions", func(t *testing.T, m map[string]string) {
ds := getSpeakerDaemonset(t, m)
expected := []corev1.Toleration{
{Key: "speaker_key1", Operator: "Equal", Value: "value1"},
{Key: "speaker_key2", Operator: "Equal", Value: "value2"},
}
if !reflect.DeepEqual(expected, ds.Spec.Template.Spec.Tolerations) {
t.Fatalf("expected: %#v, got: %#v", expected, ds.Spec.Template.Spec.Tolerations)
}
},
},
{
"SpeakerNodeSelectors", func(t *testing.T, m map[string]string) {
ds := getSpeakerDaemonset(t, m)
expected := map[string]string{
"beta.kubernetes.io/os": "linux",
"speaker_node_key1": "speaker_node_value1",
"speaker_node_key2": "speaker_node_value2",
}
if !reflect.DeepEqual(expected, ds.Spec.Template.Spec.NodeSelector) {
t.Fatalf("expected: %v, got: %v", expected, ds.Spec.Template.Spec.NodeSelector)
}
},
},
{
"ControllerTolerations", func(t *testing.T, m map[string]string) {
deploy := getDeployController(t, m)
expected := []corev1.Toleration{
{Key: "controller_key1", Operator: "Equal", Value: "value1"},
{Key: "controller_key2", Operator: "Equal", Value: "value2"},
{Key: "node-role.kubernetes.io/master", Effect: "NoSchedule"},
}
if !reflect.DeepEqual(expected, deploy.Spec.Template.Spec.Tolerations) {
t.Fatalf("expected: %+v\ngot: %+v", expected, deploy.Spec.Template.Spec.Tolerations)
}
},
},
{
"ControllerNodeSelectors", func(t *testing.T, m map[string]string) {
deploy := getDeployController(t, m)
expected := map[string]string{
"beta.kubernetes.io/os": "linux",
"controller_node_key1": "controller_node_value1",
"controller_node_key2": "controller_node_value2",
"node.kubernetes.io/master": "",
}
if !reflect.DeepEqual(expected, deploy.Spec.Template.Spec.NodeSelector) {
t.Fatalf("expected: %v\ngot: %v", expected, deploy.Spec.Template.Spec.NodeSelector)
}
},
},
{
"MonitoringConfig", func(t *testing.T, m map[string]string) {
expectedConfig := []string{
"service.yaml",
"service-monitor.yaml",
"grafana-dashboard.yaml",
"grafana-alertmanager-rule.yaml",
}

for _, ec := range expectedConfig {
if _, ok := m[ec]; !ok {
t.Fatalf("expected %s to be generated but it is not available", ec)
}
}
},
},
{
"EIPConfig", func(t *testing.T, m map[string]string) {
expectedCM := `peer-autodiscovery:
from-labels:
my-asn: metallb.lokomotive.io/my-asn
peer-asn: metallb.lokomotive.io/peer-asn
peer-address: metallb.lokomotive.io/peer-address
address-pools:
- name: default
protocol: bgp
addresses:
- 1.1.1.1/32
- 2.2.2.2/32
`

cmStr, ok := m["configmap.yaml"]
if !ok {
t.Fatalf("metallb configmap not found")
}

cm := &corev1.ConfigMap{}
if err := yaml.Unmarshal([]byte(cmStr), cm); err != nil {
t.Fatalf("failed unmarshalling manifest: %v", err)
}

gotCM, ok := cm.Data["config"]
if !ok {
t.Fatalf("metallb configmap is missing 'config' key")
}

if gotCM != expectedCM {
t.Fatalf("expected: %s, got: %s", expectedCM, gotCM)
}
},
},
}

for _, tc := range tcs {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
t.Parallel()
tc.Test(t, m)
})
}
}
34 changes: 17 additions & 17 deletions pkg/components/metallb/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,6 @@ spec:
app: metallb
component: controller
spec:
{{- if .ControllerNodeSelectors }}
nodeSelector:
{{- range $key, $value := .ControllerNodeSelectors }}
{{ $key }}: "{{ $value }}"
{{- end }}
{{- end }}
containers:
- args:
- --port=7472
Expand All @@ -274,13 +268,19 @@ spec:
drop:
- all
readOnlyRootFilesystem: true
# XXX: Lokomotive specific change.
{{- if .ControllerNodeSelectors }}
nodeSelector:
beta.kubernetes.io/os: linux
{{- range $key, $value := .ControllerNodeSelectors }}
{{ $key }}: "{{ $value }}"
{{- end }}
{{- end }}
securityContext:
runAsNonRoot: true
runAsUser: 65534
serviceAccountName: controller
terminationGracePeriodSeconds: 0
# XXX: Lokomotive specific change.
{{- if .ControllerTolerationsJSON }}
tolerations: {{ .ControllerTolerationsJSON }}
{{- end }}
Expand Down Expand Up @@ -312,12 +312,6 @@ spec:
app: metallb
component: speaker
spec:
{{- if .SpeakerNodeSelectors }}
nodeSelector:
{{- range $key, $value := .SpeakerNodeSelectors }}
{{ $key }}: "{{ $value }}"
{{- end }}
{{- end }}
containers:
- args:
- --metrics-port=7472
Expand Down Expand Up @@ -371,13 +365,19 @@ spec:
- ALL
readOnlyRootFilesystem: true
hostNetwork: true
# XXX: Lokomotive specific change.
{{- if .SpeakerNodeSelectors }}
nodeSelector:
beta.kubernetes.io/os: linux
{{- range $key, $value := .SpeakerNodeSelectors }}
{{ $key }}: "{{ $value }}"
{{- end }}
{{- end }}
serviceAccountName: speaker
terminationGracePeriodSeconds: 2
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
# XXX: Lokomotive specific change.
{{- if .SpeakerTolerationsJSON }}
tolerations: {{ .SpeakerTolerationsJSON }}
{{- end }}
`

const pspMetallbController = `
Expand Down

0 comments on commit 2c42f34

Please sign in to comment.