Skip to content

Commit fe793dd

Browse files
authored
fix: Properly set additionalTrustBundle for Nutanix CCM (#874)
The helm values template contained an error meaning that the additionalTrustBundle setting would have been templated as part of the Helm install, rather than the CAAPH addon deployment, meaning that specifying an additional trust bundle would not work for Nutanix CCM deployments. This commit fixes that and adds tests that use the same template as the CAAPH addon would do from the Helm chart to ensure that the template is now correct.
1 parent c307efa commit fe793dd

File tree

2 files changed

+83
-22
lines changed

2 files changed

+83
-22
lines changed

charts/cluster-api-runtime-extensions-nutanix/templates/ccm/nutanix/manifests/helm-addon-installation.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ data:
1212
prismCentralEndPoint: {{ `{{ .PrismCentralHost }}` }}
1313
prismCentralPort: {{ `{{ .PrismCentralPort }}` }}
1414
prismCentralInsecure: {{ `{{ .PrismCentralInsecure }}` }}
15-
{{- with .PrismCentralAdditionalTrustBundle }}
16-
prismCentralAdditionalTrustBundle: {{ `{{ . }}` }}
17-
{{- end }}
15+
{{ `{{- with .PrismCentralAdditionalTrustBundle }}` }}
16+
prismCentralAdditionalTrustBundle: {{ `{{ printf "%q" . }}` }}
17+
{{ `{{- end }}` }}
1818
1919
# The Secret containing the credentials will be created by the handler.
2020
createSecret: false

pkg/handlers/generic/lifecycle/ccm/nutanix/handler_test.go

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,27 @@
44
package nutanix
55

66
import (
7+
"bytes"
78
"fmt"
9+
"os/exec"
10+
"path/filepath"
11+
"strings"
812
"testing"
13+
"text/template"
914

1015
"github.com/stretchr/testify/assert"
1116
"github.com/stretchr/testify/require"
17+
corev1 "k8s.io/api/core/v1"
18+
"sigs.k8s.io/yaml"
1219

1320
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/v1alpha1"
1421
apivariables "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/variables"
1522
)
1623

1724
const (
18-
in = `---
19-
prismCentralEndPoint: {{ .PrismCentralHost }}
20-
prismCentralPort: {{ .PrismCentralPort }}
21-
prismCentralInsecure: {{ .PrismCentralInsecure }}
22-
prismCentralAdditionalTrustBundle: "{{ or .PrismCentralAdditionalTrustBundle "" }}"
23-
24-
# The Secret containing the credentials will be created by the handler.
25-
createSecret: false
26-
secretName: nutanix-ccm-credentials
27-
`
2825
//nolint:lll // just a long string
2926
testCertBundle = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVjekNDQTF1Z0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRUUZBRC4uQWtHQTFVRUJoTUNSMEl4CkV6QVJCZ05WQkFnVENsTnZiV1V0VTNSaGRHVXhGREFTQmdOVkJBb1RDMC4uMEVnVEhSa01UY3dOUVlEClZRUUxFeTVEYkdGemN5QXhJRkIxWW14cFl5QlFjbWx0WVhKNUlFTmxjbi4uWFJwYjI0Z1FYVjBhRzl5CmFYUjVNUlF3RWdZRFZRUURFd3RDWlhOMElFTkJJRXgwWkRBZUZ3MHdNRC4uVFV3TVRaYUZ3MHdNVEF5Ck1EUXhPVFV3TVRaYU1JR0hNUXN3Q1FZRFZRUUdFd0pIUWpFVE1CRUdBMS4uMjl0WlMxVGRHRjBaVEVVCk1CSUdBMVVFQ2hNTFFtVnpkQ0JEUVNCTWRHUXhOekExQmdOVkJBc1RMay4uREVnVUhWaWJHbGpJRkJ5CmFXMWhjbmtnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa3hGRC4uQU1UQzBKbGMzUWdRMEVnClRIUmtNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZy4uVHoybXI3U1ppQU1mUXl1CnZCak05T2lKalJhelhCWjFCalA1Q0UvV20vUnI1MDBQUksrTGg5eDVlSi4uL0FOQkUwc1RLMFpzREdNCmFrMm0xZzdvcnVJM2RZM1ZIcUl4RlR6MFRhMWQrTkFqd25MZTRuT2I3Ly4uazA1U2hoQnJKR0JLS3hiCjhuMTA0by81cDhIQXNaUGR6YkZNSXlOakp6Qk0ybzV5NUExM3dpTGl0RS4uZnlZa1F6YXhDdzBBd3psCmtWSGlJeUN1YUY0d2o1NzFwU3prdjZzdis0SURNYlQvWHBDbzhMNndUYS4uc2grZXRMRDZGdFRqWWJiCnJ2WjhSUU0xdGxLZG9NSGcycXhyYUFWKytITkJZbU5XczBkdUVkalViSi4uWEk5VHRuUzRvMUNrajdQCk9mbGppUUlEQVFBQm80SG5NSUhrTUIwR0ExVWREZ1FXQkJROHVyTUNSTC4uNUFrSXA5TkpISnc1VENCCnRBWURWUjBqQklHc01JR3BnQlE4dXJNQ1JMWVlNSFVLVTVBa0lwOU5KSC4uYVNCaWpDQmh6RUxNQWtHCkExVUVCaE1DUjBJeEV6QVJCZ05WQkFnVENsTnZiV1V0VTNSaGRHVXhGRC4uQW9UQzBKbGMzUWdRMEVnClRIUmtNVGN3TlFZRFZRUUxFeTVEYkdGemN5QXhJRkIxWW14cFl5QlFjbS4uRU5sY25ScFptbGpZWFJwCmIyNGdRWFYwYUc5eWFYUjVNUlF3RWdZRFZRUURFd3RDWlhOMElFTkJJRS4uREFNQmdOVkhSTUVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQkFVQUE0SUJBUUMxdVlCY3NTbmN3QS4uRENzUWVyNzcyQzJ1Y3BYCnhRVUUvQzBwV1dtNmdEa3dkNUQwRFNNREpScVYvd2VvWjR3QzZCNzNmNS4uYkxoR1lIYVhKZVNENktyClhjb093TGRTYUdtSllzbExLWkIzWklERXAwd1lUR2hndGViNkpGaVR0bi4uc2YyeGRyWWZQQ2lJQjdnCkJNQVY3R3pkYzRWc3BTNmxqckFoYmlpYXdkQmlRbFFtc0JlRno5SmtGNC4uYjNsOEJvR04rcU1hNTZZCkl0OHVuYTJnWTRsMk8vL29uODhyNUlXSmxtMUwwb0E4ZTRmUjJ5ckJIWC4uYWRzR2VGS2t5TnJ3R2kvCjd2UU1mWGRHc1JyWE5HUkduWCt2V0RaMy96V0kwam9EdENrTm5xRXBWbi4uSG9YCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0="
30-
)
3127

32-
const (
3328
//nolint:lll // just a long string
3429
expectedWithAdditionalTrustBundle = `---
3530
prismCentralEndPoint: prism-central.nutanix.com
@@ -39,24 +34,34 @@ prismCentralAdditionalTrustBundle: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVj
3934
4035
# The Secret containing the credentials will be created by the handler.
4136
createSecret: false
42-
secretName: nutanix-ccm-credentials
43-
`
37+
secretName: nutanix-ccm-credentials`
4438

4539
expectedWithoutAdditionalTrustBundle = `---
4640
prismCentralEndPoint: prism-central.nutanix.com
4741
prismCentralPort: 9440
4842
prismCentralInsecure: true
49-
prismCentralAdditionalTrustBundle: ""
5043
5144
# The Secret containing the credentials will be created by the handler.
5245
createSecret: false
53-
secretName: nutanix-ccm-credentials
54-
`
46+
secretName: nutanix-ccm-credentials`
47+
)
48+
49+
var templateFile = filepath.Join(
50+
moduleRootDir(),
51+
"charts",
52+
"cluster-api-runtime-extensions-nutanix",
53+
"templates",
54+
"ccm",
55+
"nutanix",
56+
"manifests",
57+
"helm-addon-installation.yaml",
5558
)
5659

5760
func Test_templateValues(t *testing.T) {
5861
t.Parallel()
5962

63+
valuesTemplate := readCCMTemplateFromProjectHelmChart(t)
64+
6065
tests := []struct {
6166
name string
6267
clusterConfig *apivariables.ClusterConfigSpec
@@ -88,7 +93,7 @@ func Test_templateValues(t *testing.T) {
8893
},
8994
},
9095
},
91-
in: in,
96+
in: valuesTemplate,
9297
expected: expectedWithAdditionalTrustBundle,
9398
},
9499
{
@@ -115,7 +120,7 @@ func Test_templateValues(t *testing.T) {
115120
},
116121
},
117122
},
118-
in: in,
123+
in: valuesTemplate,
119124
expected: expectedWithoutAdditionalTrustBundle,
120125
},
121126
}
@@ -129,3 +134,59 @@ func Test_templateValues(t *testing.T) {
129134
})
130135
}
131136
}
137+
138+
// readCCMTemplateFromProjectHelmChart gets the CCM template from the Helm chart in the project
139+
// and renders it with dummy values, finally extracting the embedded template that will be used by
140+
// CAAPH when installing the Nutanix CCM addon.
141+
// This is important to do this way to ensure that the hard-to-read double templating works as expected.
142+
func readCCMTemplateFromProjectHelmChart(t *testing.T) string {
143+
t.Helper()
144+
145+
// Mimic the Helm templating using dummy values that will render the template correctly.
146+
const dummyValues = `---
147+
hooks:
148+
ccm:
149+
nutanix:
150+
helmAddonStrategy:
151+
defaultValueTemplateConfigMap:
152+
create: true
153+
`
154+
templateData := map[string]interface{}{}
155+
require.NoError(t, yaml.Unmarshal([]byte(dummyValues), &templateData))
156+
157+
// And set that as the value of Values in the templateData.
158+
templateData["Values"] = templateData
159+
160+
// Run the actual template as Helm would.
161+
var templatedBytes bytes.Buffer
162+
require.NoError(
163+
t,
164+
template.Must(
165+
template.New(
166+
"helm-addon-installation.yaml").ParseFiles(templateFile),
167+
).Execute(&templatedBytes, templateData),
168+
)
169+
cm := &corev1.ConfigMap{}
170+
require.NoError(t, yaml.UnmarshalStrict(templatedBytes.Bytes(), cm))
171+
172+
// And return the values from the template.
173+
return cm.Data["values.yaml"]
174+
}
175+
176+
func moduleRootDir() string {
177+
cmd := exec.Command("go", "list", "-m", "-f", "{{ .Dir }}")
178+
out, err := cmd.CombinedOutput()
179+
if err != nil {
180+
// We include the combined output because the error is usually
181+
// an exit code, which does not explain why the command failed.
182+
panic(
183+
fmt.Sprintf("cmd.Dir=%q, cmd.Env=%q, cmd.Args=%q, err=%q, output=%q",
184+
cmd.Dir,
185+
cmd.Env,
186+
cmd.Args,
187+
err,
188+
out),
189+
)
190+
}
191+
return strings.TrimSpace(string(out))
192+
}

0 commit comments

Comments
 (0)