Skip to content

Commit f219cc6

Browse files
authored
fix: Misc. fixes to preflight check results (#1202)
**What problem does this PR solve?**: Fixes some issues with the check results, including: - Make the field more precise - Capitalize messages - Use valid JSONPath in fields Also: - Remove code that is never expected to run - Do not treat invalid credentials as an internal error **Which issue(s) this PR fixes**: Fixes # **How Has This Been Tested?**: <!-- Please describe the tests that you ran to verify your changes. Provide output from the tests and any manual steps needed to replicate the tests. --> All changes covered by unit tests. **Special notes for your reviewer**: <!-- Use this to provide any additional information to the reviewers. This may include: - Best way to review the PR. - Where the author wants the most review attention on. - etc. -->
1 parent a132279 commit f219cc6

12 files changed

+129
-116
lines changed

pkg/webhook/preflight/generic/registry.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func defaultRegClientGetter(opts ...regclient.Opt) regClientPinger {
5858
}
5959

6060
func pingFailedReasonString(registryURL string, err error) string {
61-
return fmt.Sprintf("failed to ping registry %s with err: %s", registryURL, err.Error())
61+
return fmt.Sprintf("Failed to ping registry %s with err: %s", registryURL, err.Error())
6262
}
6363

6464
func (r *registryCheck) checkRegistry(
@@ -80,7 +80,7 @@ func (r *registryCheck) checkRegistry(
8080
result.InternalError = false
8181
result.Causes = append(result.Causes,
8282
preflight.Cause{
83-
Message: fmt.Sprintf("failed to parse registry url %s with error: %s", registryURL, err),
83+
Message: fmt.Sprintf("Failed to parse registry URL %q with error: %s", registryURL, err),
8484
Field: r.field + ".url",
8585
},
8686
)
@@ -132,8 +132,11 @@ func (r *registryCheck) checkRegistry(
132132
result.InternalError = true
133133
result.Causes = append(result.Causes,
134134
preflight.Cause{
135-
Message: fmt.Sprintf("failed to get Registry credentials Secret: %s", err),
136-
Field: r.field + ".credentials.secretRef",
135+
Message: fmt.Sprintf("Failed to get Registry credentials Secret %q: %s",
136+
credentials.SecretRef.Name,
137+
err,
138+
),
139+
Field: r.field + ".credentials.secretRef",
137140
},
138141
)
139142
return result

pkg/webhook/preflight/generic/registry_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func TestRegistryCheck(t *testing.T) {
135135
InternalError: true,
136136
Causes: []preflight.Cause{
137137
{
138-
Message: "failed to get Registry credentials Secret: fake error",
138+
Message: "Failed to get Registry credentials Secret \"test-secret\": fake error",
139139
//nolint:lll // this is a test for a field.
140140
Field: "cluster.spec.topology.variables[.name=clusterConfig].value.globalImageRegistryMirror.credentials.secretRef",
141141
},
@@ -300,7 +300,7 @@ func TestRegistryCheck(t *testing.T) {
300300
InternalError: false,
301301
Causes: []preflight.Cause{
302302
{
303-
Message: fmt.Sprintf("failed to parse registry url %s with error: "+
303+
Message: fmt.Sprintf("Failed to parse registry URL %q with error: "+
304304
"parse \"invalid-url\": invalid URI for request", "invalid-url"),
305305
Field: "cluster.spec.topology.variables[.name=clusterConfig].value.imageRegistries[0].url",
306306
},

pkg/webhook/preflight/nutanix/credentials.go

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package nutanix
66
import (
77
"context"
88
"fmt"
9+
"strings"
910

1011
corev1 "k8s.io/api/core/v1"
1112
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -56,7 +57,7 @@ func newCredentialsCheck(
5657
credentialsCheck.result.Causes = append(credentialsCheck.result.Causes,
5758
preflight.Cause{
5859
Message: "Nutanix cluster configuration is not defined in the cluster spec",
59-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix",
60+
Field: "$.spec.topology.variables[?@.name==\"clusterConfig\"].value.nutanix",
6061
},
6162
)
6263
return credentialsCheck
@@ -71,8 +72,9 @@ func newCredentialsCheck(
7172
credentialsCheck.result.Allowed = false
7273
credentialsCheck.result.Causes = append(credentialsCheck.result.Causes,
7374
preflight.Cause{
74-
Message: fmt.Sprintf("failed to parse Prism Central endpoint URL: %s", err),
75-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix.prismCentralEndpoint.url",
75+
Message: fmt.Sprintf("Failed to parse Prism Central endpoint URL: %s", err),
76+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"]" +
77+
".value.nutanix.prismCentralEndpoint.url",
7678
},
7779
)
7880
return credentialsCheck
@@ -94,7 +96,8 @@ func newCredentialsCheck(
9496
preflight.Cause{
9597
Message: fmt.Sprintf("Prism Central credentials Secret %q not found",
9698
prismCentralEndpointSpec.Credentials.SecretRef.Name),
97-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix.prismCentralEndpoint.credentials.secretRef",
99+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"]" +
100+
".value.nutanix.prismCentralEndpoint.credentials.secretRef",
98101
},
99102
)
100103
return credentialsCheck
@@ -108,7 +111,8 @@ func newCredentialsCheck(
108111
prismCentralEndpointSpec.Credentials.SecretRef.Name,
109112
err,
110113
),
111-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix.prismCentralEndpoint.credentials.secretRef",
114+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"]" +
115+
".value.nutanix.prismCentralEndpoint.credentials.secretRef",
112116
},
113117
)
114118
return credentialsCheck
@@ -119,10 +123,11 @@ func newCredentialsCheck(
119123
credentialsCheck.result.Causes = append(credentialsCheck.result.Causes,
120124
preflight.Cause{
121125
Message: fmt.Sprintf(
122-
"credentials Secret %q is empty",
126+
"Credentials Secret %q is empty",
123127
prismCentralEndpointSpec.Credentials.SecretRef.Name,
124128
),
125-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix.prismCentralEndpoint.credentials.secretRef",
129+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"]" +
130+
".value.nutanix.prismCentralEndpoint.credentials.secretRef",
126131
},
127132
)
128133
return credentialsCheck
@@ -134,11 +139,12 @@ func newCredentialsCheck(
134139
credentialsCheck.result.Causes = append(credentialsCheck.result.Causes,
135140
preflight.Cause{
136141
Message: fmt.Sprintf(
137-
"credentials Secret %q does not contain key %q",
142+
"Credentials Secret %q does not contain key %q",
138143
prismCentralEndpointSpec.Credentials.SecretRef.Name,
139144
credentialsSecretDataKey,
140145
),
141-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix.prismCentralEndpoint.credentials.secretRef",
146+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"]" +
147+
".value.nutanix.prismCentralEndpoint.credentials.secretRef",
142148
},
143149
)
144150
return credentialsCheck
@@ -149,8 +155,9 @@ func newCredentialsCheck(
149155
credentialsCheck.result.Allowed = false
150156
credentialsCheck.result.Causes = append(credentialsCheck.result.Causes,
151157
preflight.Cause{
152-
Message: fmt.Sprintf("failed to parse Prism Central credentials: %s", err),
153-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix.prismCentralEndpoint.credentials",
158+
Message: fmt.Sprintf("Failed to parse Prism Central credentials: %s", err),
159+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"]" +
160+
".value.nutanix.prismCentralEndpoint.credentials.secretRef",
154161
},
155162
)
156163
return credentialsCheck
@@ -173,29 +180,40 @@ func newCredentialsCheck(
173180
credentialsCheck.result.Causes = append(credentialsCheck.result.Causes,
174181
preflight.Cause{
175182
Message: fmt.Sprintf("Failed to initialize Nutanix client: %s", err),
176-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix.prismCentralEndpoint.credentials",
183+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"]" +
184+
".value.nutanix.prismCentralEndpoint.credentials.secretRef",
177185
},
178186
)
179187
return credentialsCheck
180188
}
181189

182190
// Validate the credentials using an API call.
183191
_, err = nclient.GetCurrentLoggedInUser(ctx)
184-
if err != nil {
192+
if err == nil {
193+
// We initialized both clients, and verified the credentials using the v3 client.
194+
cd.nclient = nclient
195+
return credentialsCheck
196+
}
197+
198+
if strings.Contains(err.Error(), "invalid Nutanix credentials") {
185199
credentialsCheck.result.Allowed = false
186-
credentialsCheck.result.InternalError = true
187200
credentialsCheck.result.Causes = append(credentialsCheck.result.Causes,
188201
preflight.Cause{
189-
Message: fmt.Sprintf("Failed to validate credentials using the v3 API client. "+
190-
"The URL and/or credentials may be incorrect. (Error: %q)", err),
191-
Field: "cluster.spec.topology.variables[.name=clusterConfig].nutanix.prismCentralEndpoint",
202+
Message: fmt.Sprintf("Failed to validate credentials using the v3 API client: %s", err),
203+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"]" +
204+
".value.nutanix.prismCentralEndpoint.credentials.secretRef",
192205
},
193206
)
194207
return credentialsCheck
195208
}
196209

197-
// We initialized both clients, and verified the credentials using the v3 client.
198-
cd.nclient = nclient
199-
210+
credentialsCheck.result.Allowed = false
211+
credentialsCheck.result.InternalError = true
212+
credentialsCheck.result.Causes = append(credentialsCheck.result.Causes,
213+
preflight.Cause{
214+
Message: fmt.Sprintf("Failed to validate credentials using the v3 API client: %s", err),
215+
Field: "$.spec.topology.variables[[email protected]==\"clusterConfig\"].value.nutanix.prismCentralEndpoint",
216+
},
217+
)
200218
return credentialsCheck
201219
}

pkg/webhook/preflight/nutanix/credentials_test.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func TestNewCredentialsCheck_InvalidURL(t *testing.T) {
7070
result := check.Run(context.Background())
7171
assert.False(t, result.Allowed)
7272
assert.False(t, result.InternalError)
73-
assert.Contains(t, result.Causes[0].Message, "failed to parse Prism Central endpoint URL")
73+
assert.Contains(t, result.Causes[0].Message, "Failed to parse Prism Central endpoint URL")
7474
}
7575

7676
func TestNewCredentialsCheck_SecretNotFound(t *testing.T) {
@@ -145,7 +145,7 @@ func TestNewCredentialsCheck_SecretEmpty(t *testing.T) {
145145
result := check.Run(context.Background())
146146
assert.False(t, result.Allowed)
147147
assert.False(t, result.InternalError)
148-
assert.Contains(t, result.Causes[0].Message, "credentials Secret \"ntnx-creds\" is empty")
148+
assert.Contains(t, result.Causes[0].Message, "Credentials Secret \"ntnx-creds\" is empty")
149149
}
150150

151151
func TestNewCredentialsCheck_SecretMissingKey(t *testing.T) {
@@ -186,7 +186,7 @@ func TestNewCredentialsCheck_InvalidCredentialsFormat(t *testing.T) {
186186
result := check.Run(context.Background())
187187
assert.False(t, result.Allowed)
188188
assert.False(t, result.InternalError)
189-
assert.Contains(t, result.Causes[0].Message, "failed to parse Prism Central credentials")
189+
assert.Contains(t, result.Causes[0].Message, "Failed to parse Prism Central credentials")
190190
}
191191

192192
func TestNewCredentialsCheck_FailedToCreateClient(t *testing.T) {
@@ -212,7 +212,21 @@ func TestNewCredentialsCheck_FailedToGetCurrentLoggedInUser(t *testing.T) {
212212
result := check.Run(context.Background())
213213
assert.False(t, result.Allowed)
214214
assert.True(t, result.InternalError)
215-
assert.Contains(t, result.Causes[0].Message, "Failed to validate credentials using the v3 API client.")
215+
assert.Contains(t, result.Causes[0].Message, "Failed to validate credentials using the v3 API client: "+
216+
assert.AnError.Error())
217+
}
218+
219+
func TestNewCredentialsCheck_GetCurrentLoggedInUserInvalidCredentials(t *testing.T) {
220+
nclientFactory := func(_ prismgoclient.Credentials) (client, error) {
221+
return &mocknclient{err: fmt.Errorf("invalid Nutanix credentials")}, nil
222+
}
223+
cd := validCheckDependencies()
224+
check := newCredentialsCheck(context.Background(), nclientFactory, cd)
225+
result := check.Run(context.Background())
226+
assert.False(t, result.Allowed)
227+
assert.False(t, result.InternalError)
228+
assert.Contains(t, result.Causes[0].Message, "Failed to validate credentials using the v3 API client: "+
229+
"invalid Nutanix credentials")
216230
}
217231

218232
func validCheckDependencies() *checkDependencies {

pkg/webhook/preflight/nutanix/image.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (c *imageCheck) Run(ctx context.Context) preflight.CheckResult {
3333
result.Allowed = true
3434
result.Warnings = append(
3535
result.Warnings,
36-
fmt.Sprintf("%s uses imageLookup, which is not yet supported by checks", c.field),
36+
fmt.Sprintf("Field %s uses imageLookup, which is not yet supported by checks", c.field),
3737
)
3838
return result
3939
}
@@ -44,17 +44,17 @@ func (c *imageCheck) Run(ctx context.Context) preflight.CheckResult {
4444
result.Allowed = false
4545
result.InternalError = true
4646
result.Causes = append(result.Causes, preflight.Cause{
47-
Message: fmt.Sprintf("failed to get VM Image: %s", err),
48-
Field: c.field,
47+
Message: fmt.Sprintf("Failed to get VM Image: %s", err),
48+
Field: c.field + ".image",
4949
})
5050
return result
5151
}
5252

5353
if len(images) != 1 {
5454
result.Allowed = false
5555
result.Causes = append(result.Causes, preflight.Cause{
56-
Message: fmt.Sprintf("expected to find 1 VM Image, found %d", len(images)),
57-
Field: c.field,
56+
Message: fmt.Sprintf("Expected to find 1 VM Image, found %d", len(images)),
57+
Field: c.field + ".image",
5858
})
5959
return result
6060
}
@@ -82,7 +82,7 @@ func newVMImageChecks(
8282
checks = append(checks,
8383
&imageCheck{
8484
machineDetails: &cd.nutanixClusterConfigSpec.ControlPlane.Nutanix.MachineDetails,
85-
field: "cluster.spec.topology.variables[.name=clusterConfig]" +
85+
field: "$.spec.topology.variables[?@.name==\"clusterConfig\"]." +
8686
".value.nutanix.controlPlane.machineDetails",
8787
nclient: cd.nclient,
8888
},
@@ -94,8 +94,8 @@ func newVMImageChecks(
9494
checks = append(checks,
9595
&imageCheck{
9696
machineDetails: &nutanixWorkerNodeConfigSpec.Nutanix.MachineDetails,
97-
field: fmt.Sprintf("cluster.spec.topology.workers.machineDeployments[.name=%s]"+
98-
".variables[.name=workerConfig].value.nutanix.machineDetails", mdName),
97+
field: fmt.Sprintf("$.spec.topology.workers.machineDeployments[?@.name==%q]"+
98+
".variables[?@.name=workerConfig].value.nutanix.machineDetails", mdName),
9999
nclient: cd.nclient,
100100
},
101101
)

pkg/webhook/preflight/nutanix/image_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ func TestVMImageCheck(t *testing.T) {
126126
Allowed: false,
127127
Causes: []preflight.Cause{
128128
{
129-
Message: "expected to find 1 VM Image, found 0",
130-
Field: "test-field",
129+
Message: "Expected to find 1 VM Image, found 0",
130+
Field: "machineDetails.image",
131131
},
132132
},
133133
},
@@ -168,8 +168,8 @@ func TestVMImageCheck(t *testing.T) {
168168
Allowed: false,
169169
Causes: []preflight.Cause{
170170
{
171-
Message: "expected to find 1 VM Image, found 2",
172-
Field: "test-field",
171+
Message: "Expected to find 1 VM Image, found 2",
172+
Field: "machineDetails.image",
173173
},
174174
},
175175
},
@@ -192,8 +192,8 @@ func TestVMImageCheck(t *testing.T) {
192192
InternalError: true,
193193
Causes: []preflight.Cause{
194194
{
195-
Message: "failed to get VM Image: api error",
196-
Field: "test-field",
195+
Message: "Failed to get VM Image: api error",
196+
Field: "machineDetails.image",
197197
},
198198
},
199199
},
@@ -225,8 +225,8 @@ func TestVMImageCheck(t *testing.T) {
225225
InternalError: true,
226226
Causes: []preflight.Cause{
227227
{
228-
Message: "failed to get VM Image: api error",
229-
Field: "test-field",
228+
Message: "Failed to get VM Image: api error",
229+
Field: "machineDetails.image",
230230
},
231231
},
232232
},
@@ -261,8 +261,8 @@ func TestVMImageCheck(t *testing.T) {
261261
InternalError: true,
262262
Causes: []preflight.Cause{
263263
{
264-
Message: "failed to get VM Image: failed to get data returned by ListImages",
265-
Field: "test-field",
264+
Message: "Failed to get VM Image: failed to get data returned by ListImages",
265+
Field: "machineDetails.image",
266266
},
267267
},
268268
},
@@ -284,7 +284,7 @@ func TestVMImageCheck(t *testing.T) {
284284
// Create the check
285285
check := &imageCheck{
286286
machineDetails: tc.machineDetails,
287-
field: "test-field",
287+
field: "machineDetails",
288288
nclient: tc.nclient,
289289
}
290290

0 commit comments

Comments
 (0)