Support Usage API talk to MinIO over TLS with Insecure (#241)
* Support Usage API talk to MinIO over TLS with Insecure Right now if MinIO is running with TLS, and the certificate is not trusted by console, we fail usage requests. We need to leverage the support for insecure connections so we can read Health Checks and Usage information. * Remove unusd import
This commit is contained in:
@@ -178,7 +178,7 @@ func getTenantScheme(mi *operator.Tenant) string {
|
|||||||
return scheme
|
return scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTenantAdminClient(ctx context.Context, client K8sClient, namespace, tenantName, serviceName, scheme string) (*madmin.AdminClient, error) {
|
func getTenantAdminClient(ctx context.Context, client K8sClient, namespace, tenantName, serviceName, scheme string, insecure bool) (*madmin.AdminClient, error) {
|
||||||
// get admin credentials from secret
|
// get admin credentials from secret
|
||||||
creds, err := client.getSecret(ctx, namespace, fmt.Sprintf("%s-secret", tenantName), metav1.GetOptions{})
|
creds, err := client.getSecret(ctx, namespace, fmt.Sprintf("%s-secret", tenantName), metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -194,11 +194,7 @@ func getTenantAdminClient(ctx context.Context, client K8sClient, namespace, tena
|
|||||||
log.Println("tenant's secret doesn't contain secretkey")
|
log.Println("tenant's secret doesn't contain secretkey")
|
||||||
return nil, errorGeneric
|
return nil, errorGeneric
|
||||||
}
|
}
|
||||||
service, err := client.getService(ctx, namespace, serviceName, metav1.GetOptions{})
|
mAdmin, pErr := NewAdminClientWithInsecure(scheme+"://"+net.JoinHostPort(serviceName, strconv.Itoa(operator.MinIOPort)), string(accessKey), string(secretkey), insecure)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mAdmin, pErr := NewAdminClient(scheme+"://"+net.JoinHostPort(service.Spec.ClusterIP, strconv.Itoa(operator.MinIOPort)), string(accessKey), string(secretkey))
|
|
||||||
if pErr != nil {
|
if pErr != nil {
|
||||||
return nil, pErr.Cause
|
return nil, pErr.Cause
|
||||||
}
|
}
|
||||||
@@ -858,15 +854,10 @@ func getTenantUsageResponse(session *models.Principal, params admin_api.GetTenan
|
|||||||
log.Println("error getting minioTenant:", err)
|
log.Println("error getting minioTenant:", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
minTenant.EnsureDefaults()
|
||||||
tenantScheme := getTenantScheme(minTenant)
|
tenantScheme := getTenantScheme(minTenant)
|
||||||
|
|
||||||
svcName := minTenant.Spec.ServiceName
|
svcName := fmt.Sprintf("%s.%s.svc.cluster.local", minTenant.MinIOCIServiceName(), minTenant.Namespace)
|
||||||
if svcName == "" {
|
|
||||||
svcName = minTenant.Name
|
|
||||||
// TODO:
|
|
||||||
// 1 get tenant services
|
|
||||||
// 2 filter out cluster ip svc
|
|
||||||
}
|
|
||||||
|
|
||||||
mAdmin, err := getTenantAdminClient(
|
mAdmin, err := getTenantAdminClient(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -874,7 +865,8 @@ func getTenantUsageResponse(session *models.Principal, params admin_api.GetTenan
|
|||||||
params.Namespace,
|
params.Namespace,
|
||||||
params.Tenant,
|
params.Tenant,
|
||||||
svcName,
|
svcName,
|
||||||
tenantScheme)
|
tenantScheme,
|
||||||
|
true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting tenant's admin client:", err)
|
log.Println("error getting tenant's admin client:", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) {
|
|||||||
tenantName string
|
tenantName string
|
||||||
serviceName string
|
serviceName string
|
||||||
scheme string
|
scheme string
|
||||||
|
insecure bool
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -236,7 +237,7 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) {
|
|||||||
k8sclientGetSecretMock = tt.mockGetSecret
|
k8sclientGetSecretMock = tt.mockGetSecret
|
||||||
k8sclientGetServiceMock = tt.mockGetService
|
k8sclientGetServiceMock = tt.mockGetService
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
got, err := getTenantAdminClient(tt.args.ctx, tt.args.client, tt.args.namespace, tt.args.tenantName, tt.args.serviceName, tt.args.scheme)
|
got, err := getTenantAdminClient(tt.args.ctx, tt.args.client, tt.args.namespace, tt.args.tenantName, tt.args.serviceName, tt.args.scheme, tt.args.insecure)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if tt.wantErr {
|
if tt.wantErr {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ func NewAdminClientWithInsecure(url, accessKey, secretKey string, insecure bool)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err.Trace(url)
|
return nil, err.Trace(url)
|
||||||
}
|
}
|
||||||
s3Client.SetCustomTransport(STSClient.Transport)
|
stsClient := PrepareSTSClient(insecure)
|
||||||
|
s3Client.SetCustomTransport(stsClient.Transport)
|
||||||
return s3Client, nil
|
return s3Client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +267,8 @@ func newAdminFromClaims(claims *models.Principal) (*madmin.AdminClient, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
adminClient.SetCustomTransport(STSClient.Transport)
|
stsClient := PrepareSTSClient(false)
|
||||||
|
adminClient.SetCustomTransport(stsClient.Transport)
|
||||||
return adminClient, nil
|
return adminClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ func (s consoleSTSAssumeRole) IsExpired() bool {
|
|||||||
|
|
||||||
// STSClient contains http.client configuration need it by STSAssumeRole
|
// STSClient contains http.client configuration need it by STSAssumeRole
|
||||||
var (
|
var (
|
||||||
STSClient = PrepareSTSClient()
|
|
||||||
MinioEndpoint = getMinIOServer()
|
MinioEndpoint = getMinIOServer()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -204,8 +203,9 @@ func newConsoleCredentials(accessKey, secretKey, location string) (*credentials.
|
|||||||
Location: location,
|
Location: location,
|
||||||
DurationSeconds: xjwt.GetConsoleSTSAndJWTDurationInSeconds(),
|
DurationSeconds: xjwt.GetConsoleSTSAndJWTDurationInSeconds(),
|
||||||
}
|
}
|
||||||
|
stsClient := PrepareSTSClient(false)
|
||||||
stsAssumeRole := &credentials.STSAssumeRole{
|
stsAssumeRole := &credentials.STSAssumeRole{
|
||||||
Client: STSClient,
|
Client: stsClient,
|
||||||
STSEndpoint: MinioEndpoint,
|
STSEndpoint: MinioEndpoint,
|
||||||
Options: opts,
|
Options: opts,
|
||||||
}
|
}
|
||||||
@@ -234,10 +234,11 @@ func getConsoleCredentialsFromSession(claims *models.Principal) *credentials.Cre
|
|||||||
// from the provided jwt
|
// from the provided jwt
|
||||||
func newMinioClient(claims *models.Principal) (*minio.Client, error) {
|
func newMinioClient(claims *models.Principal) (*minio.Client, error) {
|
||||||
creds := getConsoleCredentialsFromSession(claims)
|
creds := getConsoleCredentialsFromSession(claims)
|
||||||
|
stsClient := PrepareSTSClient(false)
|
||||||
minioClient, err := minio.New(getMinIOEndpoint(), &minio.Options{
|
minioClient, err := minio.New(getMinIOEndpoint(), &minio.Options{
|
||||||
Creds: creds,
|
Creds: creds,
|
||||||
Secure: getMinIOEndpointIsSecure(),
|
Secure: getMinIOEndpointIsSecure(),
|
||||||
Transport: STSClient.Transport,
|
Transport: stsClient.Transport,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -30,12 +30,24 @@ var (
|
|||||||
certDontExists = "File certificate doesn't exists: %s"
|
certDontExists = "File certificate doesn't exists: %s"
|
||||||
)
|
)
|
||||||
|
|
||||||
func prepareSTSClientTransport() *http.Transport {
|
func prepareSTSClientTransport(insecure bool) *http.Transport {
|
||||||
// This takes github.com/minio/minio/pkg/madmin/transport.go as an example
|
// This takes github.com/minio/minio/pkg/madmin/transport.go as an example
|
||||||
//
|
//
|
||||||
// DefaultTransport - this default transport is similar to
|
// DefaultTransport - this default transport is similar to
|
||||||
// http.DefaultTransport but with additional param DisableCompression
|
// http.DefaultTransport but with additional param DisableCompression
|
||||||
// is set to true to avoid decompressing content with 'gzip' encoding.
|
// is set to true to avoid decompressing content with 'gzip' encoding.
|
||||||
|
|
||||||
|
// Keep TLS config.
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
// Can't use SSLv3 because of POODLE and BEAST
|
||||||
|
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
|
||||||
|
// Can't use TLSv1.1 because of RC4 cipher usage
|
||||||
|
MinVersion: tls.VersionTLS12,
|
||||||
|
}
|
||||||
|
if insecure {
|
||||||
|
tlsConfig.InsecureSkipVerify = true
|
||||||
|
}
|
||||||
|
|
||||||
DefaultTransport := &http.Transport{
|
DefaultTransport := &http.Transport{
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
DialContext: (&net.Dialer{
|
DialContext: (&net.Dialer{
|
||||||
@@ -49,6 +61,7 @@ func prepareSTSClientTransport() *http.Transport {
|
|||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
DisableCompression: true,
|
DisableCompression: true,
|
||||||
|
TLSClientConfig: tlsConfig,
|
||||||
}
|
}
|
||||||
// If Minio instance is running with TLS enabled and it's using a self-signed certificate
|
// If Minio instance is running with TLS enabled and it's using a self-signed certificate
|
||||||
// or a certificate issued by a custom certificate authority we prepare a new custom *http.Transport
|
// or a certificate issued by a custom certificate authority we prepare a new custom *http.Transport
|
||||||
@@ -86,10 +99,11 @@ func prepareSTSClientTransport() *http.Transport {
|
|||||||
|
|
||||||
// PrepareSTSClient returns an http.Client with custom configurations need it by *credentials.STSAssumeRole
|
// PrepareSTSClient returns an http.Client with custom configurations need it by *credentials.STSAssumeRole
|
||||||
// custom configurations include the use of CA certificates
|
// custom configurations include the use of CA certificates
|
||||||
func PrepareSTSClient() *http.Client {
|
func PrepareSTSClient(insecure bool) *http.Client {
|
||||||
transport := prepareSTSClientTransport()
|
transport := prepareSTSClientTransport(insecure)
|
||||||
// Return http client with default configuration
|
// Return http client with default configuration
|
||||||
return &http.Client{
|
c := &http.Client{
|
||||||
Transport: transport,
|
Transport: transport,
|
||||||
}
|
}
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user