From bdfa6dc9bfbd5693871b950c3fe703c4287d4e59 Mon Sep 17 00:00:00 2001 From: Daniel Valdivia Date: Sun, 9 Aug 2020 14:36:55 -0700 Subject: [PATCH] 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 --- restapi/admin_tenants.go | 20 ++++++-------------- restapi/admin_tenants_test.go | 3 ++- restapi/client-admin.go | 6 ++++-- restapi/client.go | 7 ++++--- restapi/tls.go | 22 ++++++++++++++++++---- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/restapi/admin_tenants.go b/restapi/admin_tenants.go index c6bb35187..56ffd8c01 100644 --- a/restapi/admin_tenants.go +++ b/restapi/admin_tenants.go @@ -178,7 +178,7 @@ func getTenantScheme(mi *operator.Tenant) string { 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 creds, err := client.getSecret(ctx, namespace, fmt.Sprintf("%s-secret", tenantName), metav1.GetOptions{}) 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") return nil, errorGeneric } - service, err := client.getService(ctx, namespace, serviceName, metav1.GetOptions{}) - if err != nil { - return nil, err - } - mAdmin, pErr := NewAdminClient(scheme+"://"+net.JoinHostPort(service.Spec.ClusterIP, strconv.Itoa(operator.MinIOPort)), string(accessKey), string(secretkey)) + mAdmin, pErr := NewAdminClientWithInsecure(scheme+"://"+net.JoinHostPort(serviceName, strconv.Itoa(operator.MinIOPort)), string(accessKey), string(secretkey), insecure) if pErr != nil { return nil, pErr.Cause } @@ -858,15 +854,10 @@ func getTenantUsageResponse(session *models.Principal, params admin_api.GetTenan log.Println("error getting minioTenant:", err) return nil, err } + minTenant.EnsureDefaults() tenantScheme := getTenantScheme(minTenant) - svcName := minTenant.Spec.ServiceName - if svcName == "" { - svcName = minTenant.Name - // TODO: - // 1 get tenant services - // 2 filter out cluster ip svc - } + svcName := fmt.Sprintf("%s.%s.svc.cluster.local", minTenant.MinIOCIServiceName(), minTenant.Namespace) mAdmin, err := getTenantAdminClient( ctx, @@ -874,7 +865,8 @@ func getTenantUsageResponse(session *models.Principal, params admin_api.GetTenan params.Namespace, params.Tenant, svcName, - tenantScheme) + tenantScheme, + true) if err != nil { log.Println("error getting tenant's admin client:", err) return nil, err diff --git a/restapi/admin_tenants_test.go b/restapi/admin_tenants_test.go index 8fcf1d328..ed28b2c6b 100644 --- a/restapi/admin_tenants_test.go +++ b/restapi/admin_tenants_test.go @@ -91,6 +91,7 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) { tenantName string serviceName string scheme string + insecure bool } tests := []struct { name string @@ -236,7 +237,7 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) { k8sclientGetSecretMock = tt.mockGetSecret k8sclientGetServiceMock = tt.mockGetService 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 tt.wantErr { return diff --git a/restapi/client-admin.go b/restapi/client-admin.go index 86de5ced0..6b5f4c61a 100644 --- a/restapi/client-admin.go +++ b/restapi/client-admin.go @@ -54,7 +54,8 @@ func NewAdminClientWithInsecure(url, accessKey, secretKey string, insecure bool) if err != nil { return nil, err.Trace(url) } - s3Client.SetCustomTransport(STSClient.Transport) + stsClient := PrepareSTSClient(insecure) + s3Client.SetCustomTransport(stsClient.Transport) return s3Client, nil } @@ -266,7 +267,8 @@ func newAdminFromClaims(claims *models.Principal) (*madmin.AdminClient, error) { if err != nil { return nil, err } - adminClient.SetCustomTransport(STSClient.Transport) + stsClient := PrepareSTSClient(false) + adminClient.SetCustomTransport(stsClient.Transport) return adminClient, nil } diff --git a/restapi/client.go b/restapi/client.go index 37db5f168..019089804 100644 --- a/restapi/client.go +++ b/restapi/client.go @@ -164,7 +164,6 @@ func (s consoleSTSAssumeRole) IsExpired() bool { // STSClient contains http.client configuration need it by STSAssumeRole var ( - STSClient = PrepareSTSClient() MinioEndpoint = getMinIOServer() ) @@ -204,8 +203,9 @@ func newConsoleCredentials(accessKey, secretKey, location string) (*credentials. Location: location, DurationSeconds: xjwt.GetConsoleSTSAndJWTDurationInSeconds(), } + stsClient := PrepareSTSClient(false) stsAssumeRole := &credentials.STSAssumeRole{ - Client: STSClient, + Client: stsClient, STSEndpoint: MinioEndpoint, Options: opts, } @@ -234,10 +234,11 @@ func getConsoleCredentialsFromSession(claims *models.Principal) *credentials.Cre // from the provided jwt func newMinioClient(claims *models.Principal) (*minio.Client, error) { creds := getConsoleCredentialsFromSession(claims) + stsClient := PrepareSTSClient(false) minioClient, err := minio.New(getMinIOEndpoint(), &minio.Options{ Creds: creds, Secure: getMinIOEndpointIsSecure(), - Transport: STSClient.Transport, + Transport: stsClient.Transport, }) if err != nil { return nil, err diff --git a/restapi/tls.go b/restapi/tls.go index 7b43d7c88..15a77f81e 100644 --- a/restapi/tls.go +++ b/restapi/tls.go @@ -30,12 +30,24 @@ var ( 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 // // DefaultTransport - this default transport is similar to // http.DefaultTransport but with additional param DisableCompression // 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{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ @@ -49,6 +61,7 @@ func prepareSTSClientTransport() *http.Transport { TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, DisableCompression: true, + TLSClientConfig: tlsConfig, } // 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 @@ -86,10 +99,11 @@ func prepareSTSClientTransport() *http.Transport { // PrepareSTSClient returns an http.Client with custom configurations need it by *credentials.STSAssumeRole // custom configurations include the use of CA certificates -func PrepareSTSClient() *http.Client { - transport := prepareSTSClientTransport() +func PrepareSTSClient(insecure bool) *http.Client { + transport := prepareSTSClientTransport(insecure) // Return http client with default configuration - return &http.Client{ + c := &http.Client{ Transport: transport, } + return c }