Skip to content

Commit 6f9f364

Browse files
committed
fix: use url parsing and allows users to not have usernames or passwords
1 parent 0287233 commit 6f9f364

File tree

3 files changed

+24
-104
lines changed

3 files changed

+24
-104
lines changed

pkg/webhook/preflight/generic/registry.go

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package generic
66
import (
77
"context"
88
"fmt"
9-
"regexp"
9+
"net/url"
1010

1111
"github.com/go-logr/logr"
1212
"github.com/regclient/regclient"
@@ -22,13 +22,7 @@ import (
2222
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/webhook/preflight"
2323
)
2424

25-
var (
26-
registryMirrorVarPath = "cluster.spec.topology.variables[.name=clusterConfig].value.globalImageRegistryMirror"
27-
mirrorURLValidationRegex = regexp.MustCompile(
28-
`^https?://`,
29-
) // in order to use regclient we need to pass just a hostname
30-
// this regex allows us to strip it so we can verify connectivity for this test.
31-
)
25+
var registryMirrorVarPath = "cluster.spec.topology.variables[.name=clusterConfig].value.globalImageRegistryMirror"
3226

3327
type registryCheck struct {
3428
registryMirror *carenv1.GlobalImageRegistryMirror
@@ -87,12 +81,23 @@ func (r *registryCheck) checkRegistry(
8781
credentials *carenv1.RegistryCredentials,
8882
regClientGetter regClientPingerFactory,
8983
) preflight.CheckResult {
90-
registryURL = mirrorURLValidationRegex.ReplaceAllString(registryURL, "")
9184
result := preflight.CheckResult{
9285
Allowed: false,
9386
}
87+
registryURLParsed, err := url.ParseRequestURI(registryURL)
88+
if err != nil {
89+
result.Allowed = false
90+
result.Error = true
91+
result.Causes = append(result.Causes,
92+
preflight.Cause{
93+
Message: fmt.Sprintf("failed to parse registry url %s with error : %s", registryURL, err),
94+
Field: registryMirrorVarPath,
95+
},
96+
)
97+
return result
98+
}
9499
mirrorHost := config.Host{
95-
Name: registryURL,
100+
Name: registryURLParsed.Host,
96101
}
97102
if credentials != nil && credentials.SecretRef != nil {
98103
mirrorCredentialsSecret := &corev1.Secret{}
@@ -116,31 +121,13 @@ func (r *registryCheck) checkRegistry(
116121
return result
117122
}
118123
username, ok := mirrorCredentialsSecret.Data["username"]
119-
if !ok {
120-
result.Allowed = false
121-
result.Error = true
122-
result.Causes = append(result.Causes,
123-
preflight.Cause{
124-
Message: "failed to get username from Registry credentials Secret. secret must have field username.",
125-
Field: fmt.Sprintf("%s.credentials.secretRef", registryMirrorVarPath),
126-
},
127-
)
128-
return result
124+
if ok {
125+
mirrorHost.User = string(username)
129126
}
130127
password, ok := mirrorCredentialsSecret.Data["password"]
131-
if !ok {
132-
result.Allowed = false
133-
result.Error = true
134-
result.Causes = append(result.Causes,
135-
preflight.Cause{
136-
Message: "failed to get password from Registry credentials Secret. secret must have field password.",
137-
Field: fmt.Sprintf("%s.credentials.secretRef", registryMirrorVarPath),
138-
},
139-
)
140-
return result
128+
if ok {
129+
mirrorHost.Pass = string(password)
141130
}
142-
mirrorHost.User = string(username)
143-
mirrorHost.Pass = string(password)
144131
if caCert, ok := mirrorCredentialsSecret.Data["ca.crt"]; ok {
145132
mirrorHost.RegCert = string(caCert)
146133
}
@@ -149,7 +136,7 @@ func (r *registryCheck) checkRegistry(
149136
regclient.WithConfigHost(mirrorHost),
150137
regclient.WithUserAgent("regclient/example"),
151138
)
152-
mirrorRef, err := ref.NewHost(registryURL)
139+
mirrorRef, err := ref.NewHost(registryURLParsed.Host)
153140
if err != nil {
154141
result.Allowed = false
155142
result.Error = true

pkg/webhook/preflight/generic/registry_test.go

Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -139,76 +139,6 @@ func TestRegistryCheck(t *testing.T) {
139139
},
140140
},
141141
},
142-
{
143-
name: "registry mirror with missing username in secret",
144-
registryMirror: &carenv1.GlobalImageRegistryMirror{
145-
URL: testRegistryURL,
146-
Credentials: &carenv1.RegistryCredentials{
147-
SecretRef: &carenv1.LocalObjectReference{
148-
Name: "test-secret",
149-
},
150-
},
151-
},
152-
kclient: &mockK8sClient{
153-
getSecretFunc: func(ctx context.Context,
154-
key types.NamespacedName,
155-
obj ctrlclient.Object,
156-
opts ...ctrlclient.GetOption,
157-
) error {
158-
secret := obj.(*corev1.Secret)
159-
secret.Data = map[string][]byte{
160-
"password": []byte("testpass"),
161-
}
162-
return nil
163-
},
164-
},
165-
want: preflight.CheckResult{
166-
Allowed: false,
167-
Error: true,
168-
Causes: []preflight.Cause{
169-
{
170-
Message: "failed to get username from Registry credentials Secret. secret must have field username.",
171-
//nolint:lll // this is a test for a field.
172-
Field: "cluster.spec.topology.variables[.name=clusterConfig].value.globalImageRegistryMirror.credentials.secretRef",
173-
},
174-
},
175-
},
176-
},
177-
{
178-
name: "registry mirror with missing password in secret",
179-
registryMirror: &carenv1.GlobalImageRegistryMirror{
180-
URL: testRegistryURL,
181-
Credentials: &carenv1.RegistryCredentials{
182-
SecretRef: &carenv1.LocalObjectReference{
183-
Name: "test-secret",
184-
},
185-
},
186-
},
187-
kclient: &mockK8sClient{
188-
getSecretFunc: func(ctx context.Context,
189-
key types.NamespacedName,
190-
obj ctrlclient.Object,
191-
opts ...ctrlclient.GetOption,
192-
) error {
193-
secret := obj.(*corev1.Secret)
194-
secret.Data = map[string][]byte{
195-
"username": []byte("testuser"),
196-
}
197-
return nil
198-
},
199-
},
200-
want: preflight.CheckResult{
201-
Allowed: false,
202-
Error: true,
203-
Causes: []preflight.Cause{
204-
{
205-
Message: "failed to get password from Registry credentials Secret. secret must have field password.",
206-
//nolint:lll // this is a test for a field.
207-
Field: "cluster.spec.topology.variables[.name=clusterConfig].value.globalImageRegistryMirror.credentials.secretRef",
208-
},
209-
},
210-
},
211-
},
212142
{
213143
name: "registry mirror ping failure",
214144
registryMirror: &carenv1.GlobalImageRegistryMirror{
@@ -224,7 +154,7 @@ func TestRegistryCheck(t *testing.T) {
224154
Causes: []preflight.Cause{
225155
{
226156
Message: pingFailedReasonString(
227-
mirrorURLValidationRegex.ReplaceAllString(testRegistryURL, ""),
157+
testRegistryURL,
228158
testPingFailedError,
229159
),
230160
Field: "cluster.spec.topology.variables[.name=clusterConfig].value.globalImageRegistryMirror",

pkg/webhook/preflight/generic/spec.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright 2024 Nutanix. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
14
package generic
25

36
import (

0 commit comments

Comments
 (0)