Skip to content

Commit 40291e3

Browse files
committed
fix invalid endpoint in secret if no port provided
1 parent ec285d5 commit 40291e3

File tree

6 files changed

+138
-11
lines changed

6 files changed

+138
-11
lines changed

internal/controller/user/reconcile.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,10 +634,11 @@ func (r *S3UserReconciler) handleCreate(
634634
"s3region": []byte(s3Client.GetConfig().Region),
635635
"s3CACertificate": []byte(strings.Join(s3Client.GetConfig().CaCertificatesBase64, ",")),
636636
"s3url": []byte(s3Client.GetConfig().S3Url),
637-
"s3ConnectionURL": []byte(fmt.Sprintf("https://%s:%s@%s",
637+
"s3ConnectionURL": []byte(fmt.Sprintf("%s://%s:%s@%s",
638+
s3Client.GetConfig().Scheme,
638639
userResource.Spec.AccessKey,
639640
secretKey,
640-
strings.TrimPrefix(s3Client.GetConfig().Endpoint, "https://"),
641+
s3Client.GetConfig().Endpoint,
641642
),
642643
),
643644
})

internal/controller/user/reconcile_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ func TestHandleCreate(t *testing.T) {
291291
assert.Equal(t, s3v1alpha1.Reconciled, s3UserResourceUpdated.Status.Conditions[0].Reason)
292292
assert.Equal(t, metav1.ConditionTrue, s3UserResourceUpdated.Status.Conditions[0].Status)
293293
assert.Contains(t, s3UserResourceUpdated.Status.Conditions[0].Message, "User reconciled")
294+
294295
})
295296

296297
t.Run("error if using invalidS3Instance", func(t *testing.T) {
@@ -310,6 +311,8 @@ func TestHandleCreate(t *testing.T) {
310311
assert.Equal(t, "example-user", string(secretCreated.Data["accessKey"]))
311312
assert.GreaterOrEqual(t, len(string(secretCreated.Data["secretKey"])), 20)
312313
assert.NotEmpty(t, string(secretCreated.Data["s3ConnectionURL"]))
314+
assert.Contains(t, string(secretCreated.Data["s3ConnectionURL"]), "@minio.example.com")
315+
assert.Contains(t, string(secretCreated.Data["s3ConnectionURL"]), "https://example-user")
313316
})
314317
}
315318

internal/s3/client/impl/minioS3Client.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,20 @@ func generateAdminMinioClient(
125125
return minioAdminClient, nil
126126
}
127127

128-
func ConstructEndpointFromURL(url string) (string, bool, error) {
128+
func ConstructEndpointFromURL(url string) (string, string, string, error) {
129129
parsedURL, err := neturl.Parse(url)
130130
if err != nil {
131-
return "", false, fmt.Errorf("cannot detect if url use ssl or not")
131+
return "", "", "", fmt.Errorf("cannot detect if url use ssl or not")
132132
}
133-
133+
scheme := parsedURL.Scheme
134134
endpoint := parsedURL.Hostname()
135-
if (parsedURL.Scheme != "https" || parsedURL.Port() != "443") &&
136-
(parsedURL.Scheme != "http" || parsedURL.Port() != "80") {
137-
endpoint = fmt.Sprintf("%s:%s", endpoint, parsedURL.Port())
135+
port := parsedURL.Port()
136+
if port != "" && (scheme != "https" || port != "443") &&
137+
(scheme != "http" || port != "80") {
138+
endpoint = fmt.Sprintf("%s:%s", endpoint, port)
138139
}
139140

140-
return endpoint, parsedURL.Scheme == "https", nil
141+
return endpoint, port, scheme, nil
141142
}
142143

143144
func addTlsClientConfigToMinioOptions(caCertificates []string, minioOptions *minio.Options) {
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
Copyright 2023.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package s3clientimpl
18+
19+
import (
20+
"testing"
21+
)
22+
23+
func TestConstructEndpointFromURL(t *testing.T) {
24+
tests := []struct {
25+
name string
26+
inputURL string
27+
wantEP string
28+
wantPort string
29+
wantSSL bool
30+
wantErr bool
31+
}{
32+
{
33+
name: "https without port",
34+
inputURL: "https://example.com",
35+
wantEP: "example.com",
36+
wantPort: "",
37+
wantSSL: true,
38+
wantErr: false,
39+
},
40+
{
41+
name: "https with default port 443",
42+
inputURL: "https://example.com:443",
43+
wantEP: "example.com",
44+
wantPort: "443",
45+
wantSSL: true,
46+
wantErr: false,
47+
},
48+
{
49+
name: "http without port",
50+
inputURL: "http://example.com",
51+
wantEP: "example.com",
52+
wantPort: "",
53+
wantSSL: false,
54+
wantErr: false,
55+
},
56+
{
57+
name: "http with default port 80",
58+
inputURL: "http://example.com:80",
59+
wantEP: "example.com",
60+
wantPort: "80",
61+
wantSSL: false,
62+
wantErr: false,
63+
},
64+
{
65+
name: "https with non standard port",
66+
inputURL: "https://example.com:8443",
67+
wantEP: "example.com:8443",
68+
wantPort: "8443",
69+
wantSSL: true,
70+
wantErr: false,
71+
},
72+
{
73+
name: "http with non standard port",
74+
inputURL: "http://example.com:8080",
75+
wantEP: "example.com:8080",
76+
wantPort: "8080",
77+
wantSSL: false,
78+
wantErr: false,
79+
},
80+
{
81+
name: "invalid url",
82+
inputURL: "://bad-url",
83+
wantEP: "",
84+
wantPort: "",
85+
wantSSL: false,
86+
wantErr: true,
87+
},
88+
}
89+
90+
for _, tt := range tests {
91+
t.Run(tt.name, func(t *testing.T) {
92+
endpoint, port, scheme, err := ConstructEndpointFromURL(tt.inputURL)
93+
ssl := scheme == "https"
94+
if tt.wantErr {
95+
if err == nil {
96+
t.Fatalf("expected error, got nil")
97+
}
98+
return
99+
}
100+
101+
if err != nil {
102+
t.Fatalf("unexpected error: %v", err)
103+
}
104+
105+
if endpoint != tt.wantEP {
106+
t.Errorf("endpoint = %q, want %q", endpoint, tt.wantEP)
107+
}
108+
109+
if port != tt.wantPort {
110+
t.Errorf("port = %q, want %q", port, tt.wantPort)
111+
}
112+
113+
if ssl != tt.wantSSL {
114+
t.Errorf("ssl = %v, want %v", ssl, tt.wantSSL)
115+
}
116+
})
117+
}
118+
}

internal/s3/client/s3client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ type S3Config struct {
3434
PolicyDeletionEnabled bool
3535
Secure bool
3636
Endpoint string
37+
Port string
38+
Scheme string
3739
PathStyle bool
3840
}
3941

internal/s3/factory/impl/s3factoryImpl.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,16 @@ func NewS3Factory() *S3Factory {
3232

3333
func (mockedS3Provider *S3Factory) GenerateS3Client(s3Provider string, s3Config *s3client.S3Config) (s3client.S3Client, error) {
3434
s3Logger := ctrl.Log.WithValues("logger", "s3factory")
35-
endpoint, isSSL, err := s3clientImpl.ConstructEndpointFromURL(s3Config.S3Url)
35+
endpoint, port, scheme, err := s3clientImpl.ConstructEndpointFromURL(s3Config.S3Url)
3636
if err != nil {
3737
s3Logger.Error(err, "an error occurred while creating a new minio client")
3838
return nil, err
3939
}
40-
s3Config.Secure = isSSL
40+
s3Config.Secure = scheme == "https"
4141
s3Config.Endpoint = endpoint
42+
s3Config.Scheme = scheme
4243
s3Config.PathStyle = false
44+
s3Config.Port = port
4345
if s3Provider == "mockedS3Provider" {
4446
return s3clientImpl.NewMockedS3Client(s3Config), nil
4547
}

0 commit comments

Comments
 (0)