From ba51c382dc25f356700a16c63511faf299086145 Mon Sep 17 00:00:00 2001 From: Tapajit Chandra Paul Date: Fri, 13 Sep 2024 19:07:29 +0600 Subject: [PATCH] Add TLS config to druid client Signed-off-by: Tapajit Chandra Paul --- druid/client.go | 126 ++++-------------- druid/kubedb_client_builder.go | 108 ++++++++++++--- go.mod | 2 + go.sum | 2 - .../apimachinery/apis/kubedb/constants.go | 51 ++++++- .../apis/kubedb/v1alpha2/druid_helpers.go | 107 +++++++++++++-- .../apis/kubedb/v1alpha2/druid_types.go | 21 ++- .../kubedb/v1alpha2/mssqlserver_helpers.go | 10 ++ .../apis/kubedb/v1alpha2/openapi_generated.go | 21 ++- .../apis/kubedb/v1alpha2/pgpool_webhook.go | 51 +++---- .../kubedb/v1alpha2/zz_generated.deepcopy.go | 10 ++ .../apimachinery/crds/kubedb.com_druids.yaml | 112 ++++++++++++++++ vendor/modules.txt | 3 +- 13 files changed, 442 insertions(+), 182 deletions(-) diff --git a/druid/client.go b/druid/client.go index 24f28349..88d61b67 100644 --- a/druid/client.go +++ b/druid/client.go @@ -17,14 +17,11 @@ limitations under the License. package druid import ( - "bytes" "encoding/json" "fmt" - "log" "time" druidgo "github.com/grafadruid/go-druid" - "github.com/hashicorp/go-retryablehttp" "github.com/pkg/errors" "k8s.io/klog/v2" health "kmodules.xyz/client-go/tools/healthchecker" @@ -117,55 +114,15 @@ func (c *Client) CheckDataSourceExistence() (bool, error) { return false, errors.Wrap(err, "failed to marshal json response") } rawMessage := json.RawMessage(jsonData) - response, err := c.SubmitRequest(method, path, rawMessage) - if err != nil { - return false, err - } - - exists, err := parseDatasourceExistenceQueryResponse(response) - if err != nil { - return false, errors.Wrap(err, "Failed to parse response of datasource existence request") - } - - if err := closeResponse(response); err != nil { - return exists, err - } - return exists, nil -} - -func (c *Client) SubmitRequest(method, path string, opts interface{}) (*druidgo.Response, error) { - res, err := c.NewRequest(method, path, opts) - if err != nil { - return nil, errors.Wrap(err, "failed to submit API request") - } - http := retryablehttp.NewClient() - - var b []byte - buf := bytes.NewBuffer(b) - http.Logger = log.New(buf, "", 0) - resp, err := http.Do(res) + var result []map[string]interface{} + _, err = c.ExecuteRequest(method, path, rawMessage, &result) if err != nil { - return nil, err - } - response := &druidgo.Response{Response: resp} - return response, nil -} - -func parseDatasourceExistenceQueryResponse(res *druidgo.Response) (bool, error) { - var responseBody []map[string]interface{} - if err := json.NewDecoder(res.Body).Decode(&responseBody); err != nil { - return false, errors.Wrap(err, "failed to deserialize the response") + klog.Error("Failed to execute request", err) + return false, err } - return len(responseBody) != 0, nil -} -func closeResponse(response *druidgo.Response) error { - err := response.Body.Close() - if err != nil { - return errors.Wrap(err, "Failed to close the response body") - } - return nil + return len(result) > 0, nil } // CheckDBReadWriteAccess checks read and write access in the DB @@ -238,41 +195,25 @@ func (c *Client) GetData() (string, error) { func (c *Client) runSelectQuery() (string, error) { method := "POST" path := "druid/v2/sql" - data := map[string]interface{}{ "query": "SELECT * FROM \"kubedb-datasource\"", } + jsonData, err := json.Marshal(data) if err != nil { return "", errors.Wrap(err, "failed to marshal query json data") } rawMessage := json.RawMessage(jsonData) - response, err := c.SubmitRequest(method, path, rawMessage) - if err != nil { - return "", err - } - if response == nil { - return "", errors.New("response body is empty") - } - id, err := parseSelectQueryResponse(response, "id") + var result []map[string]interface{} + _, err = c.ExecuteRequest(method, path, rawMessage, &result) if err != nil { - return "", errors.Wrap(err, "failed to parse the response body") - } - - if err := closeResponse(response); err != nil { + klog.Error("Failed to execute request", err) return "", err } - return id.(string), nil -} + id := result[0]["id"] -func parseSelectQueryResponse(res *druidgo.Response, key string) (interface{}, error) { - var responseBody []map[string]interface{} - if err := json.NewDecoder(res.Body).Decode(&responseBody); err != nil { - return "", errors.Wrap(err, "failed to deserialize the response") - } - value := responseBody[0][key] - return value, nil + return id.(string), nil } func (c *Client) updateCoordinatorsWaitBeforeDeletingConfig(value int32) error { @@ -296,11 +237,9 @@ func (c *Client) updateCoordinatorDynamicConfig(data map[string]interface{}) err } rawMessage := json.RawMessage(jsonData) - response, err := c.SubmitRequest(method, path, rawMessage) + _, err = c.ExecuteRequest(method, path, rawMessage, nil) if err != nil { - return err - } - if err := closeResponse(response); err != nil { + klog.Error("Failed to execute coordinator config update request", err) return err } return nil @@ -336,33 +275,19 @@ func (c *Client) submitTask(taskType DruidTaskType, dataSource string, data stri } else { task = GetKillTaskDefinition() } - rawMessage := json.RawMessage(task) method := "POST" path := "druid/indexer/v1/task" - response, err := c.SubmitRequest(method, path, rawMessage) - if err != nil { - return "", err - } - - taskID, err := GetValueFromClusterResponse(response, "task") + var result map[string]interface{} + _, err := c.ExecuteRequest(method, path, rawMessage, &result) if err != nil { - return "", errors.Wrap(err, "failed to parse response of task api request") - } - if err = closeResponse(response); err != nil { + klog.Error("Failed to execute request", err) return "", err } - return fmt.Sprintf("%v", taskID), nil -} -func GetValueFromClusterResponse(res *druidgo.Response, key string) (interface{}, error) { - responseBody := make(map[string]interface{}) - if err := json.NewDecoder(res.Body).Decode(&responseBody); err != nil { - return "", errors.Wrap(err, "failed to deserialize the response") - } - value := responseBody[key] - return value, nil + taskID := result["task"] + return taskID.(string), nil } func GetIngestionTaskDefinition(dataSource string, data string) string { @@ -419,21 +344,18 @@ func GetKillTaskDefinition() string { func (c *Client) CheckTaskStatus(taskID string) (bool, error) { method := "GET" path := fmt.Sprintf("druid/indexer/v1/task/%s/status", taskID) - response, err := c.SubmitRequest(method, path, nil) - if err != nil { - return false, errors.Wrap(err, "failed to check task status") - } - statusRes, err := GetValueFromClusterResponse(response, "status") + var result map[string]interface{} + _, err := c.ExecuteRequest(method, path, nil, &result) if err != nil { - return false, errors.Wrap(err, "failed to parse respons of task ingestion request") + klog.Error("Failed to execute GET task status request", err) + return false, err } + + statusRes := result["status"] statusMap := statusRes.(map[string]interface{}) status := statusMap["status"].(string) - if err = closeResponse(response); err != nil { - return false, err - } return status == "SUCCESS", nil } diff --git a/druid/kubedb_client_builder.go b/druid/kubedb_client_builder.go index d4998010..dca10483 100644 --- a/druid/kubedb_client_builder.go +++ b/druid/kubedb_client_builder.go @@ -18,8 +18,12 @@ package druid import ( "context" + "crypto/tls" + "crypto/x509" "errors" "fmt" + dbapi "kubedb.dev/apimachinery/apis/kubedb/v1" + "net/http" druidgo "github.com/grafadruid/go-druid" _ "github.com/lib/pq" @@ -74,28 +78,24 @@ func (o *KubeDBClientBuilder) WithNodeRole(nodeRole olddbapi.DruidNodeRoleType) func (o *KubeDBClientBuilder) GetDruidClient() (*Client, error) { var druidOpts []druidgo.ClientOption + // Add druid auth credential to the client if !*o.db.Spec.DisableSecurity { - if o.db.Spec.AuthSecret == nil { - klog.Error("AuthSecret not set") - return nil, errors.New("auth-secret is not set") + authOpts, err := o.getClientAuthOpts() + if err != nil { + klog.Error(err, "failed to get client auth options") + return nil, err } + druidOpts = append(druidOpts, *authOpts) + } - authSecret := &core.Secret{} - err := o.kc.Get(o.ctx, types.NamespacedName{ - Namespace: o.db.Namespace, - Name: o.db.Spec.AuthSecret.Name, - }, authSecret) + // Add druid ssl configs to the client + if o.db.Spec.EnableSSL { + sslOpts, err := o.getClientSSLConfig() if err != nil { - if kerr.IsNotFound(err) { - klog.Error(err, "AuthSecret not found") - return nil, errors.New("auth-secret not found") - } + klog.Error(err, "failed to get client ssl options") return nil, err } - userName := string(authSecret.Data[core.BasicAuthUsernameKey]) - password := string(authSecret.Data[core.BasicAuthPasswordKey]) - - druidOpts = append(druidOpts, druidgo.WithBasicAuth(userName, password)) + druidOpts = append(druidOpts, *sslOpts) } druidClient, err := druidgo.NewClient(o.url, druidOpts...) @@ -107,8 +107,82 @@ func (o *KubeDBClientBuilder) GetDruidClient() (*Client, error) { }, nil } +func (o *KubeDBClientBuilder) getClientAuthOpts() (*druidgo.ClientOption, error) { + if o.db.Spec.AuthSecret == nil { + klog.Error("AuthSecret not set") + return nil, errors.New("auth-secret is not set") + } + + authSecret := &core.Secret{} + err := o.kc.Get(o.ctx, types.NamespacedName{ + Namespace: o.db.Namespace, + Name: o.db.Spec.AuthSecret.Name, + }, authSecret) + if err != nil { + if kerr.IsNotFound(err) { + klog.Error(err, "AuthSecret not found") + return nil, errors.New("auth-secret not found") + } + return nil, err + } + userName := string(authSecret.Data[core.BasicAuthUsernameKey]) + password := string(authSecret.Data[core.BasicAuthPasswordKey]) + + druidAuthOpts := druidgo.WithBasicAuth(userName, password) + return &druidAuthOpts, nil +} + +func (o *KubeDBClientBuilder) getClientSSLConfig() (*druidgo.ClientOption, error) { + certSecret := &core.Secret{} + err := o.kc.Get(o.ctx, types.NamespacedName{ + Namespace: o.db.Namespace, + Name: o.db.GetCertSecretName(olddbapi.DruidClientCert), + }, certSecret) + if err != nil { + if kerr.IsNotFound(err) { + klog.Error(err, "Client certificate secret not found") + return nil, errors.New("client certificate secret is not found") + } + klog.Error(err, "Failed to get client certificate Secret") + return nil, err + } + + // get tls cert, clientCA and rootCA for tls config + clientCA := x509.NewCertPool() + rootCA := x509.NewCertPool() + + crt, err := tls.X509KeyPair(certSecret.Data[core.TLSCertKey], certSecret.Data[core.TLSPrivateKeyKey]) + if err != nil { + klog.Error(err, "Failed to parse private key pair") + return nil, err + } + clientCA.AppendCertsFromPEM(certSecret.Data[dbapi.TLSCACertFileName]) + rootCA.AppendCertsFromPEM(certSecret.Data[dbapi.TLSCACertFileName]) + + httpClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + Certificates: []tls.Certificate{crt}, + ClientAuth: tls.RequireAndVerifyClientCert, + ClientCAs: clientCA, + RootCAs: rootCA, + MaxVersion: tls.VersionTLS12, + }, + }, + } + tlsOpts := druidgo.WithHTTPClient(httpClient) + return &tlsOpts, nil +} + // GetNodesAddress returns DNS for the nodes based on type of the node func (o *KubeDBClientBuilder) GetNodesAddress() string { - baseUrl := fmt.Sprintf("http://%s-0.%s.%s.svc.cluster.local:%d", o.db.PetSetName(o.nodeRole), o.db.GoverningServiceName(), o.db.Namespace, o.db.DruidNodeContainerPort(o.nodeRole)) + var scheme string + if o.db.Spec.EnableSSL { + scheme = "https" + } else { + scheme = "http" + } + + baseUrl := fmt.Sprintf("%s://%s-0.%s.%s.svc.cluster.local:%d", scheme, o.db.PetSetName(o.nodeRole), o.db.GoverningServiceName(), o.db.Namespace, o.db.DruidNodeContainerPort(o.nodeRole)) return baseUrl } diff --git a/go.mod b/go.mod index 004c25a6..cdc14eab 100644 --- a/go.mod +++ b/go.mod @@ -159,3 +159,5 @@ replace sigs.k8s.io/controller-runtime => github.com/kmodules/controller-runtime replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.6 replace k8s.io/apiserver => github.com/kmodules/apiserver v0.30.2-0.20240519082755-d7b8c2d9e699 + +replace kubedb.dev/apimachinery => ../apimachinery diff --git a/go.sum b/go.sum index b8edbea0..8c2fb726 100644 --- a/go.sum +++ b/go.sum @@ -793,8 +793,6 @@ kmodules.xyz/monitoring-agent-api v0.29.0 h1:gpFl6OZrlMLb/ySMHdREI9EwGtnJ91oZBn9 kmodules.xyz/monitoring-agent-api v0.29.0/go.mod h1:iNbvaMTgVFOI5q2LJtGK91j4Dmjv4ZRiRdasGmWLKQI= kmodules.xyz/offshoot-api v0.30.0 h1:dq9F93pu4Q8rL9oTcCk+vGGy8vpS7RNt0GSwx7Bvhec= kmodules.xyz/offshoot-api v0.30.0/go.mod h1:o9VoA3ImZMDBp3lpLb8+kc2d/KBxioRwCpaKDfLIyDw= -kubedb.dev/apimachinery v0.47.0 h1:QhcjY2wJb/5L0YmfJAUiPw0VU1mMJqvILL2t8znniJo= -kubedb.dev/apimachinery v0.47.0/go.mod h1:W/uKm13rLuaz+uqZUt6piU/qA0EdLKHuN53V2DYheJI= kubeops.dev/petset v0.0.6 h1:0IbvxD9fadZfH+3iMZWzN6ZHsO0vX458JlioamwyPKQ= kubeops.dev/petset v0.0.6/go.mod h1:A15vh0r979NsvL65DTIZKWsa/NoX9VapHBAEw1ZsdYI= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/constants.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/constants.go index f8459091..5a2ad2a6 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/constants.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/constants.go @@ -982,14 +982,23 @@ const ( EnvDruidCoordinatorAsOverlord = "DRUID_COORDINATOR_AS_OVERLORD" EnvDruidMetadataTLSEnable = "DRUID_METADATA_TLS_ENABLE" EnvDruidMetadataStorageType = "DRUID_METADATA_STORAGE_TYPE" + EnvDruidKeyStorePassword = "DRUID_KEY_STORE_PASSWORD" - DruidPortCoordinators = 8081 - DruidPortOverlords = 8090 - DruidPortHistoricals = 8083 - DruidPortMiddleManagers = 8091 - DruidPortBrokers = 8082 - DruidPortRouters = 8888 - DruidExporterPort = 9104 + DruidPlainTextPortCoordinators = 8081 + DruidPlainTextPortOverlords = 8090 + DruidPlainTextPortHistoricals = 8083 + DruidPlainTextPortMiddleManagers = 8091 + DruidPlainTextPortBrokers = 8082 + DruidPlainTextPortRouters = 8888 + + DruidTLSPortCoordinators = 8281 + DruidTLSPortOverlords = 8290 + DruidTLSPortHistoricals = 8283 + DruidTLSPortMiddleManagers = 8291 + DruidTLSPortBrokers = 8282 + DruidTLSPortRouters = 9088 + + DruidExporterPort = 9104 DruidMetadataStorageTypePostgres = "Postgres" @@ -1012,6 +1021,33 @@ const ( DruidMetadataStorageConnectorPasswordEnvConfig = "{\"type\": \"environment\", \"variable\": \"DRUID_METADATA_STORAGE_PASSWORD\"}" DruidMetadataStorageCreateTables = "druid.metadata.storage.connector.createTables" + // Druid TLS + DruidKeystorePasswordKey = "keystore_password" + DruidTrustStorePasswordKey = "truststore_password" + DruidKeystoreSecretKey = "keystore-cred" + + DruidEnablePlaintextPort = "druid.enablePlaintextPort" + DruidEnableTLSPort = "druid.enableTlsPort" + DruidKeyStorePath = "druid.server.https.keyStorePath" + DruidKeyStoreType = "druid.server.https.keyStoreType" + DruidCertAlias = "druid.server.https.certAlias" + DruidKeyStorePassword = "druid.server.https.keyStorePassword" + DruidRequireClientCertificate = "druid.server.https.requireClientCertificate" + DruidTrustStoreType = "druid.server.https.trustStoreType" + + DruidTrustStorePassword = "druid.client.https.trustStorePassword" + DruidTrustStorePath = "druid.client.https.trustStorePath" + DruidHTTPSProtocolKey = "druid.client.https.protocol" + DruidHTTPSProtocolValue = "TLSv1.2" + + DruidKeyStoreTypeJKS = "jks" + DruidKeyStorePasswordEnvConfig = "{\"type\": \"environment\", \"variable\": \"DRUID_KEY_STORE_PASSWORD\"}" + + DruidValueTrue = "true" + DruidValueFalse = "false" + + DruidCertDir = "/opt/druid/ssl" + // MySQL TLS DruidMetadataMySQLUseSSL = "druid.metadata.mysql.ssl.useSSL" DruidMetadataMySQLClientCertKeyStoreURL = "druid.metadata.mysql.ssl.clientCertificateKeyStoreUrl" @@ -1084,6 +1120,7 @@ const ( DruidExtensionBasicSecurity = "druid-basic-security" DruidExtensionMultiStageQuery = "druid-multi-stage-query" DruidExtensionPrometheusEmitter = "prometheus-emitter" + DruidExtensionSSLContext = "simple-client-sslcontext" DruidService = "druid.service" // Monitoring Configurations diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/druid_helpers.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/druid_helpers.go index 45fd8c66..68f36a4c 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/druid_helpers.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/druid_helpers.go @@ -19,6 +19,7 @@ package v1alpha2 import ( "context" "fmt" + "path/filepath" "strconv" "strings" @@ -133,6 +134,10 @@ func (d *Druid) DefaultUserCredSecretName(username string) string { return meta_util.NameWithSuffix(d.Name, strings.ReplaceAll(fmt.Sprintf("%s-cred", username), "_", "-")) } +func (d *Druid) DruidSecretName(suffix string) string { + return strings.Join([]string{d.Name, suffix}, "-") +} + type DruidStatsService struct { *Druid } @@ -235,19 +240,41 @@ func (d *Druid) DruidNodeRoleStringSingular(nodeRole DruidNodeRoleType) string { } func (d *Druid) DruidNodeContainerPort(nodeRole DruidNodeRoleType) int32 { - if nodeRole == DruidNodeRoleCoordinators { - return kubedb.DruidPortCoordinators - } else if nodeRole == DruidNodeRoleOverlords { - return kubedb.DruidPortOverlords - } else if nodeRole == DruidNodeRoleMiddleManagers { - return kubedb.DruidPortMiddleManagers - } else if nodeRole == DruidNodeRoleHistoricals { - return kubedb.DruidPortHistoricals - } else if nodeRole == DruidNodeRoleBrokers { - return kubedb.DruidPortBrokers + if !d.Spec.EnableSSL { + switch nodeRole { + case DruidNodeRoleCoordinators: + return kubedb.DruidPlainTextPortCoordinators + case DruidNodeRoleOverlords: + return kubedb.DruidPlainTextPortOverlords + case DruidNodeRoleMiddleManagers: + return kubedb.DruidPlainTextPortMiddleManagers + case DruidNodeRoleHistoricals: + return kubedb.DruidPlainTextPortHistoricals + case DruidNodeRoleBrokers: + return kubedb.DruidPlainTextPortBrokers + case DruidNodeRoleRouters: + return kubedb.DruidPlainTextPortRouters + default: + panic("Node role name does not match any known types") + } + } else { + switch nodeRole { + case DruidNodeRoleCoordinators: + return kubedb.DruidTLSPortCoordinators + case DruidNodeRoleOverlords: + return kubedb.DruidTLSPortOverlords + case DruidNodeRoleMiddleManagers: + return kubedb.DruidTLSPortMiddleManagers + case DruidNodeRoleHistoricals: + return kubedb.DruidTLSPortHistoricals + case DruidNodeRoleBrokers: + return kubedb.DruidTLSPortBrokers + case DruidNodeRoleRouters: + return kubedb.DruidTLSPortRouters + default: + panic("Node role name does not match any known types") + } } - // Routers - return kubedb.DruidPortRouters } func (d *Druid) SetHealthCheckerDefaults() { @@ -369,9 +396,26 @@ func (d Druid) OffshootLabels() map[string]string { return d.offshootLabels(d.OffshootSelectors(), nil) } -func (e Druid) offshootLabels(selector, override map[string]string) map[string]string { +func (d Druid) offshootLabels(selector, override map[string]string) map[string]string { selector[meta_util.ComponentLabelKey] = kubedb.ComponentDatabase - return meta_util.FilterKeys(kubedb.GroupName, selector, meta_util.OverwriteKeys(nil, e.Labels, override)) + return meta_util.FilterKeys(kubedb.GroupName, selector, meta_util.OverwriteKeys(nil, d.Labels, override)) +} + +// CertificateName returns the default certificate name and/or certificate secret name for a certificate alias +func (d *Druid) CertificateName(alias DruidCertificateAlias) string { + return meta_util.NameWithSuffix(d.Name, fmt.Sprintf("%s-cert", string(alias))) +} + +// GetCertSecretName returns the secret name for a certificate alias if any, +// otherwise returns default certificate secret name for the given alias. +func (d *Druid) GetCertSecretName(alias DruidCertificateAlias) string { + if d.Spec.TLS != nil { + name, ok := kmapi.GetCertificateSecretName(d.Spec.TLS.Certificates, string(alias)) + if ok { + return name + } + } + return d.CertificateName(alias) } func (d *Druid) SetDefaults() { @@ -391,6 +435,16 @@ func (d *Druid) SetDefaults() { } } + if d.Spec.EnableSSL { + if d.Spec.KeystoreCredSecret == nil { + d.Spec.KeystoreCredSecret = &SecretReference{ + LocalObjectReference: core.LocalObjectReference{ + Name: d.DruidSecretName(kubedb.DruidKeystoreSecretKey), + }, + } + } + } + var druidVersion catalog.DruidVersion err := DefaultClient.Get(context.TODO(), types.NamespacedName{ Name: d.Spec.Version, @@ -523,6 +577,18 @@ func (d *Druid) SetDefaults() { } d.Spec.Monitor.SetDefaults() } + + if d.Spec.EnableSSL { + d.SetTLSDefaults() + } +} + +func (k *Druid) SetTLSDefaults() { + if k.Spec.TLS == nil || k.Spec.TLS.IssuerRef == nil { + return + } + k.Spec.TLS.Certificates = kmapi.SetMissingSecretNameForCertificate(k.Spec.TLS.Certificates, string(DruidServerCert), k.CertificateName(DruidServerCert)) + k.Spec.TLS.Certificates = kmapi.SetMissingSecretNameForCertificate(k.Spec.TLS.Certificates, string(DruidClientCert), k.CertificateName(DruidClientCert)) } func (d *Druid) SetDefaultsToMetadataStorage() { @@ -725,3 +791,16 @@ func (d *Druid) GetZooKeeperName() string { func (d *Druid) GetInitConfigMapName() string { return d.OffShootName() + "-init-script" } + +// CertSecretVolumeName returns the CertSecretVolumeName +// Values will be like: client-certs, server-certs etc. +func (d *Druid) CertSecretVolumeName(alias DruidCertificateAlias) string { + return string(alias) + "-certs" +} + +// CertSecretVolumeMountPath returns the CertSecretVolumeMountPath +// if configDir is "/var/druid/ssl", +// mountPath will be, "/var/druid/ssl/". +func (k *Druid) CertSecretVolumeMountPath(configDir string, cert string) string { + return filepath.Join(configDir, cert) +} diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/druid_types.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/druid_types.go index 62860264..dea80c78 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/druid_types.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/druid_types.go @@ -75,9 +75,16 @@ type DruidSpec struct { // +optional ConfigSecret *core.LocalObjectReference `json:"configSecret,omitempty"` - //// TLS contains tls configurations - //// +optional - //TLS *kmapi.TLSConfig `json:"tls,omitempty"` + // To enable ssl for http layer + EnableSSL bool `json:"enableSSL,omitempty"` + + // Keystore encryption secret + // +optional + KeystoreCredSecret *SecretReference `json:"keystoreCredSecret,omitempty"` + + // TLS contains tls configurations + // +optional + TLS *kmapi.TLSConfig `json:"tls,omitempty"` // MetadataStorage contains information for Druid to connect to external dependency metadata storage // +optional @@ -270,3 +277,11 @@ const ( DruidDeepStorageAzure DruidDeepStorageType = "azure" DruidDeepStorageHDFS DruidDeepStorageType = "hdfs" ) + +// +kubebuilder:validation:Enum=server;client;metrics-exporter +type DruidCertificateAlias string + +const ( + DruidServerCert DruidCertificateAlias = "server" + DruidClientCert DruidCertificateAlias = "client" +) diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/mssqlserver_helpers.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/mssqlserver_helpers.go index 6f0a31d4..482185db 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/mssqlserver_helpers.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/mssqlserver_helpers.go @@ -377,6 +377,16 @@ func (m *MSSQLServer) SetDefaults() { m.SetHealthCheckerDefaults() m.setDefaultContainerResourceLimits(m.Spec.PodTemplate) + + m.Spec.Monitor.SetDefaults() + if m.Spec.Monitor != nil && m.Spec.Monitor.Prometheus != nil { + if m.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsUser == nil { + m.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsUser = mssqlVersion.Spec.SecurityContext.RunAsUser + } + if m.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsGroup == nil { + m.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsGroup = mssqlVersion.Spec.SecurityContext.RunAsUser + } + } } func (m *MSSQLServer) setDefaultContainerSecurityContext(mssqlVersion *catalog.MSSQLServerVersion, podTemplate *ofst.PodTemplateSpec) { diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/openapi_generated.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/openapi_generated.go index 012da0a8..0db185ea 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/openapi_generated.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/openapi_generated.go @@ -26367,6 +26367,25 @@ func schema_apimachinery_apis_kubedb_v1alpha2_DruidSpec(ref common.ReferenceCall Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), }, }, + "enableSSL": { + SchemaProps: spec.SchemaProps{ + Description: "To enable ssl for http layer", + Type: []string{"boolean"}, + Format: "", + }, + }, + "keystoreCredSecret": { + SchemaProps: spec.SchemaProps{ + Description: "Keystore encryption secret", + Ref: ref("kubedb.dev/apimachinery/apis/kubedb/v1alpha2.SecretReference"), + }, + }, + "tls": { + SchemaProps: spec.SchemaProps{ + Description: "TLS contains tls configurations", + Ref: ref("kmodules.xyz/client-go/api/v1.TLSConfig"), + }, + }, "metadataStorage": { SchemaProps: spec.SchemaProps{ Description: "MetadataStorage contains information for Druid to connect to external dependency metadata storage", @@ -26431,7 +26450,7 @@ func schema_apimachinery_apis_kubedb_v1alpha2_DruidSpec(ref common.ReferenceCall }, }, Dependencies: []string{ - "k8s.io/api/core/v1.LocalObjectReference", "kmodules.xyz/client-go/api/v1.HealthCheckSpec", "kmodules.xyz/monitoring-agent-api/api/v1.AgentSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.DeepStorageSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.DruidClusterTopology", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.MetadataStorage", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.NamedServiceTemplateSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.ZookeeperRef"}, + "k8s.io/api/core/v1.LocalObjectReference", "kmodules.xyz/client-go/api/v1.HealthCheckSpec", "kmodules.xyz/client-go/api/v1.TLSConfig", "kmodules.xyz/monitoring-agent-api/api/v1.AgentSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.DeepStorageSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.DruidClusterTopology", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.MetadataStorage", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.NamedServiceTemplateSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.SecretReference", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.ZookeeperRef"}, } } diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_webhook.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_webhook.go index 5e5498da..7476ca18 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_webhook.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_webhook.go @@ -129,51 +129,32 @@ func (p *Pgpool) ValidateCreateOrUpdate() field.ErrorList { "use either `spec.configSecret` or `spec.initConfig`")) } - if p.Spec.ConfigSecret != nil { - secret := core.Secret{} + if p.ObjectMeta.DeletionTimestamp == nil { + apb := appcat.AppBinding{} err := DefaultClient.Get(context.TODO(), types.NamespacedName{ - Name: p.Spec.ConfigSecret.Name, - Namespace: p.Namespace, - }, &secret) + Name: p.Spec.PostgresRef.Name, + Namespace: p.Spec.PostgresRef.Namespace, + }, &apb) if err != nil { - errorList = append(errorList, field.Invalid(field.NewPath("spec").Child("configSecret"), + errorList = append(errorList, field.Invalid(field.NewPath("spec").Child("postgresRef"), p.Name, err.Error(), )) } - _, ok := secret.Data[kubedb.PgpoolCustomConfigFile] - if !ok { - errorList = append(errorList, field.Invalid(field.NewPath("spec").Child("configSecret"), + + backendSSL, err := p.IsBackendTLSEnabled() + if err != nil { + errorList = append(errorList, field.Invalid(field.NewPath("spec").Child("postgresRef"), p.Name, - fmt.Sprintf("`%v` is missing", kubedb.PgpoolCustomConfigFile), + err.Error(), )) } - } - - apb := appcat.AppBinding{} - err := DefaultClient.Get(context.TODO(), types.NamespacedName{ - Name: p.Spec.PostgresRef.Name, - Namespace: p.Spec.PostgresRef.Namespace, - }, &apb) - if err != nil { - errorList = append(errorList, field.Invalid(field.NewPath("spec").Child("postgresRef"), - p.Name, - err.Error(), - )) - } - - backendSSL, err := p.IsBackendTLSEnabled() - if err != nil { - errorList = append(errorList, field.Invalid(field.NewPath("spec").Child("postgresRef"), - p.Name, - err.Error(), - )) - } - if p.Spec.TLS == nil && backendSSL { - errorList = append(errorList, field.Required(field.NewPath("spec").Child("tls"), - "`spec.tls` must be set because backend postgres is tls enabled", - )) + if p.Spec.TLS == nil && backendSSL { + errorList = append(errorList, field.Required(field.NewPath("spec").Child("tls"), + "`spec.tls` must be set because backend postgres is tls enabled", + )) + } } if p.Spec.TLS == nil { diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/zz_generated.deepcopy.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/zz_generated.deepcopy.go index 3eb974ef..1dd07a69 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/zz_generated.deepcopy.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/zz_generated.deepcopy.go @@ -769,6 +769,16 @@ func (in *DruidSpec) DeepCopyInto(out *DruidSpec) { *out = new(corev1.LocalObjectReference) **out = **in } + if in.KeystoreCredSecret != nil { + in, out := &in.KeystoreCredSecret, &out.KeystoreCredSecret + *out = new(SecretReference) + **out = **in + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(apiv1.TLSConfig) + (*in).DeepCopyInto(*out) + } if in.MetadataStorage != nil { in, out := &in.MetadataStorage, &out.MetadataStorage *out = new(MetadataStorage) diff --git a/vendor/kubedb.dev/apimachinery/crds/kubedb.com_druids.yaml b/vendor/kubedb.dev/apimachinery/crds/kubedb.com_druids.yaml index 6473f6d1..e964b4ad 100644 --- a/vendor/kubedb.dev/apimachinery/crds/kubedb.com_druids.yaml +++ b/vendor/kubedb.dev/apimachinery/crds/kubedb.com_druids.yaml @@ -88,6 +88,8 @@ spec: type: string disableSecurity: type: boolean + enableSSL: + type: boolean halted: type: boolean healthChecker: @@ -111,6 +113,15 @@ spec: format: int32 type: integer type: object + keystoreCredSecret: + properties: + externallyManaged: + type: boolean + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic metadataStorage: properties: createTables: @@ -405,6 +416,107 @@ spec: - alias type: object type: array + tls: + properties: + certificates: + items: + properties: + alias: + type: string + dnsNames: + items: + type: string + type: array + duration: + type: string + emailAddresses: + items: + type: string + type: array + ipAddresses: + items: + type: string + type: array + issuerRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + privateKey: + properties: + encoding: + enum: + - PKCS1 + - PKCS8 + type: string + type: object + renewBefore: + type: string + secretName: + type: string + subject: + properties: + countries: + items: + type: string + type: array + localities: + items: + type: string + type: array + organizationalUnits: + items: + type: string + type: array + organizations: + items: + type: string + type: array + postalCodes: + items: + type: string + type: array + provinces: + items: + type: string + type: array + serialNumber: + type: string + streetAddresses: + items: + type: string + type: array + type: object + uris: + items: + type: string + type: array + required: + - alias + type: object + type: array + issuerRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: object topology: properties: brokers: diff --git a/vendor/modules.txt b/vendor/modules.txt index 0de11016..65c0eb6b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1552,7 +1552,7 @@ kmodules.xyz/offshoot-api/api/v1 kmodules.xyz/offshoot-api/api/v1/conversion kmodules.xyz/offshoot-api/api/v2 kmodules.xyz/offshoot-api/util -# kubedb.dev/apimachinery v0.47.0 +# kubedb.dev/apimachinery v0.47.0 => ../apimachinery ## explicit; go 1.22.1 kubedb.dev/apimachinery/apis kubedb.dev/apimachinery/apis/catalog @@ -1660,3 +1660,4 @@ xorm.io/xorm/tags # sigs.k8s.io/controller-runtime => github.com/kmodules/controller-runtime v0.18.4-0.20240603164526-fa88ec2314fe # github.com/imdario/mergo => github.com/imdario/mergo v0.3.6 # k8s.io/apiserver => github.com/kmodules/apiserver v0.30.2-0.20240519082755-d7b8c2d9e699 +# kubedb.dev/apimachinery => ../apimachinery