object: use advertise endpoint for admin ops
RGW can only serve a single certificate. This limitation means that the
prior behavior of using the default service for admin ops when TLS is
enabled may mean it requires additional complex certificate management
to make sure the object store uses a certificate valid for Rook internal
admin ops and user connections.
This is needlessly complex for users. Instead, change Rook's behavior
and documentation to clarify that it will use the same endpoint intended
for S3 client applications. This means that users have a more
straightforward path to enabling both Rook and consuming applications.
More info: https://github.com/rook/rook/issues/14530
Signed-off-by: Blaine Gardner <blaine.gardner@ibm.com>
(cherry picked from commit b4a2285aa6)
This commit is contained in:
1 parent
de644c1d6a
commit
ebba8bc4a2
4 files changed
+81
-91
No files matched your search
@@ -19,7 +19,6 @@ package object
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"regexp"
|
||||
@@ -64,9 +63,6 @@ type debugHTTPClient struct {
|
||||
logger *capnslog.PackageLogger
|
||||
}
|
||||
|
||||
// global rand source that can be overridden for unit tests
|
||||
var randSrc = rand.New(rand.NewSource(rand.Int63())) //nolint:gosec // G404: cryptographically weak RNG is fine here
|
||||
|
||||
// NewDebugHTTPClient helps us mutating the HTTP client to debug the request/response
|
||||
func NewDebugHTTPClient(client admin.HTTPClient, logger *capnslog.PackageLogger) *debugHTTPClient {
|
||||
return &debugHTTPClient{client, logger}
|
||||
@@ -136,28 +132,15 @@ func NewMultisiteContext(context *clusterd.Context, clusterInfo *cephclient.Clus
|
||||
}
|
||||
|
||||
// GetAdminOpsEndpoint returns an endpoint that can be used to perform RGW admin ops
|
||||
// It returns an HTTPS endpoint if available. It prefers direct routes to the RGW(s).
|
||||
func GetAdminOpsEndpoint(s *cephv1.CephObjectStore) (string, error) {
|
||||
nsName := fmt.Sprintf("%s/%s", s.Namespace, s.Name)
|
||||
|
||||
port, err := s.Spec.GetPort()
|
||||
// advertise endpoint should be most likely to have a valid cert, so use it for admin ops
|
||||
endpoint, err := s.GetAdvertiseEndpointUrl()
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to get port for object store %q", nsName)
|
||||
return "", errors.Wrapf(err, "failed to get advertise endpoint for object store %q", nsName)
|
||||
}
|
||||
|
||||
domain := s.GetServiceDomainName()
|
||||
if s.Spec.IsExternal() {
|
||||
// if the store is external, pick a random external endpoint to use. if the endpoint is down, this
|
||||
// reconcile may fail, but a future reconcile will eventually pick a different endpoint to try
|
||||
endpoints := []string{}
|
||||
for _, e := range s.Spec.Gateway.ExternalRgwEndpoints {
|
||||
endpoints = append(endpoints, e.String())
|
||||
}
|
||||
idx := randSrc.Intn(len(endpoints))
|
||||
domain = endpoints[idx]
|
||||
}
|
||||
|
||||
return BuildDNSEndpoint(domain, port, s.Spec.IsTLSEnabled()), nil
|
||||
return endpoint, nil
|
||||
}
|
||||
|
||||
// UpdateEndpointForAdminOps updates the object.Context endpoint with the latest admin ops endpoint
|
||||
|
||||
@@ -18,7 +18,6 @@ package object
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -742,14 +741,9 @@ func TestGetAdminOpsEndpoint(t *testing.T) {
|
||||
},
|
||||
Spec: cephv1.ObjectStoreSpec{
|
||||
Gateway: cephv1.GatewaySpec{},
|
||||
// configure hosting settings to ensure they don't affect admin ops endpoints
|
||||
Hosting: &cephv1.ObjectStoreHostingSpec{
|
||||
AdvertiseEndpoint: &cephv1.ObjectEndpointSpec{
|
||||
DnsName: "should.not.appear",
|
||||
Port: 7777,
|
||||
UseTls: false,
|
||||
},
|
||||
DNSNames: []string{"also.should.not.appear"},
|
||||
// dnsNames shouldn't affect admin ops endpoints
|
||||
DNSNames: []string{"should.not.appear"},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -800,16 +794,9 @@ func TestGetAdminOpsEndpoint(t *testing.T) {
|
||||
}
|
||||
s.Spec.Gateway.Port = 8080
|
||||
|
||||
// override rand src with known seed to keep tests stable
|
||||
randSrc = rand.New(rand.NewSource(3)) //nolint:gosec // G404: cryptographically weak RNG is fine here
|
||||
|
||||
got, err := GetAdminOpsEndpoint(s)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "http://192.168.1.1:8080", got)
|
||||
|
||||
got, err = GetAdminOpsEndpoint(s)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "http://s3.host.com:8080", got)
|
||||
})
|
||||
|
||||
t.Run("securePort, no cert", func(t *testing.T) {
|
||||
@@ -820,16 +807,9 @@ func TestGetAdminOpsEndpoint(t *testing.T) {
|
||||
}
|
||||
s.Spec.Gateway.SecurePort = 8443
|
||||
|
||||
// override rand src with known seed to keep tests stable
|
||||
randSrc = rand.New(rand.NewSource(3)) //nolint:gosec // G404: cryptographically weak RNG is fine here
|
||||
|
||||
got, err := GetAdminOpsEndpoint(s)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "", got)
|
||||
|
||||
got, err = GetAdminOpsEndpoint(s)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "", got)
|
||||
})
|
||||
|
||||
t.Run("securePort", func(t *testing.T) {
|
||||
@@ -841,16 +821,9 @@ func TestGetAdminOpsEndpoint(t *testing.T) {
|
||||
s.Spec.Gateway.SecurePort = 8443
|
||||
s.Spec.Gateway.SSLCertificateRef = "my-cert"
|
||||
|
||||
// override rand src with known seed to keep tests stable
|
||||
randSrc = rand.New(rand.NewSource(3)) //nolint:gosec // G404: cryptographically weak RNG is fine here
|
||||
|
||||
got, err := GetAdminOpsEndpoint(s)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://192.168.1.1:8443", got)
|
||||
|
||||
got, err = GetAdminOpsEndpoint(s)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://s3.host.com:8443", got)
|
||||
})
|
||||
|
||||
t.Run("port + securePort", func(t *testing.T) {
|
||||
@@ -863,16 +836,31 @@ func TestGetAdminOpsEndpoint(t *testing.T) {
|
||||
s.Spec.Gateway.SecurePort = 8443
|
||||
s.Spec.Gateway.SSLCertificateRef = "my-cert"
|
||||
|
||||
// override rand src with known seed to keep tests stable
|
||||
randSrc = rand.New(rand.NewSource(3)) //nolint:gosec // G404: cryptographically weak RNG is fine here
|
||||
|
||||
got, err := GetAdminOpsEndpoint(s)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://192.168.1.1:8443", got)
|
||||
})
|
||||
})
|
||||
|
||||
got, err = GetAdminOpsEndpoint(s)
|
||||
t.Run("advertise", func(t *testing.T) {
|
||||
t.Run("port + securePort", func(t *testing.T) {
|
||||
s := s.DeepCopy()
|
||||
s.Spec.Gateway.ExternalRgwEndpoints = []cephv1.EndpointAddress{
|
||||
{IP: "192.168.1.1"},
|
||||
{Hostname: "s3.host.com"},
|
||||
}
|
||||
s.Spec.Gateway.Port = 8080
|
||||
s.Spec.Gateway.SecurePort = 8443
|
||||
s.Spec.Gateway.SSLCertificateRef = "my-cert"
|
||||
s.Spec.Hosting.AdvertiseEndpoint = &cephv1.ObjectEndpointSpec{
|
||||
DnsName: "advertise.me",
|
||||
Port: 80,
|
||||
UseTls: false,
|
||||
}
|
||||
|
||||
got, err := GetAdminOpsEndpoint(s)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://s3.host.com:8443", got)
|
||||
assert.Equal(t, "http://advertise.me:80", got)
|
||||
})
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user