diff --git a/controllers/deployment.go b/controllers/deployment.go index 816c9c17..81be18a5 100644 --- a/controllers/deployment.go +++ b/controllers/deployment.go @@ -38,6 +38,7 @@ type DeploymentConfig struct { CustomCertificatesBundle CustomCertificatesBundle Version string BatchSize int + UseDBTLSCerts bool } // createDeploymentObject returns a Deployment for the TrustyAI Service instance @@ -70,6 +71,20 @@ func (r *TrustyAIServiceReconciler) createDeploymentObject(ctx context.Context, BatchSize: batchSize, } + if instance.Spec.Storage.IsStorageDatabase() { + _, err := r.getSecret(ctx, instance.Name+"-db-tls", instance.Namespace) + if err != nil { + deploymentConfig.UseDBTLSCerts = false + log.FromContext(ctx).Error(err, "Using insecure database connection. Certificates "+instance.Name+"-db-tls not found") + } else { + deploymentConfig.UseDBTLSCerts = true + log.FromContext(ctx).Info("Using secure database connection with certificates " + instance.Name + "-db-tls") + } + } else { + deploymentConfig.UseDBTLSCerts = false + log.FromContext(ctx).Info("No need to check database secrets. Using PVC-mode.") + } + var deployment *appsv1.Deployment deployment, err = templateParser.ParseResource[appsv1.Deployment](deploymentTemplatePath, deploymentConfig, reflect.TypeOf(&appsv1.Deployment{})) if err != nil { diff --git a/controllers/inference_services.go b/controllers/inference_services.go index db426d4a..b49a5267 100644 --- a/controllers/inference_services.go +++ b/controllers/inference_services.go @@ -147,7 +147,7 @@ func (r *TrustyAIServiceReconciler) patchEnvVarsByLabelForDeployments(ctx contex } // Build the payload processor endpoint - url := generateServiceURL(crName, namespace) + "/consumer/kserve/v2" + url := generateTLSServiceURL(crName, namespace) + "/consumer/kserve/v2" // Patch environment variables for the Deployments if shouldContinue, err := r.patchEnvVarsForDeployments(ctx, instance, deployments, envVarName, url, remove); err != nil { @@ -240,7 +240,7 @@ func (r *TrustyAIServiceReconciler) handleInferenceServices(ctx context.Context, // patchKServe adds a TrustyAI service as an InferenceLogger to a KServe InferenceService func (r *TrustyAIServiceReconciler) patchKServe(ctx context.Context, instance *trustyaiopendatahubiov1alpha1.TrustyAIService, infService kservev1beta1.InferenceService, namespace string, crName string, remove bool) error { - url := generateServiceURL(crName, namespace) + url := generateNonTLSServiceURL(crName, namespace) if remove { if infService.Spec.Predictor.Logger == nil || *infService.Spec.Predictor.Logger.URL != url { diff --git a/controllers/secrets.go b/controllers/secrets.go index 6e2d49b7..090ab58d 100644 --- a/controllers/secrets.go +++ b/controllers/secrets.go @@ -9,34 +9,42 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +// getSecret retrieves a secret if it exists, returns an error if not +func (r *TrustyAIServiceReconciler) getSecret(ctx context.Context, name, namespace string) (*corev1.Secret, error) { + secret := &corev1.Secret{} + err := r.Get(ctx, client.ObjectKey{Name: name, Namespace: namespace}, secret) + if err != nil { + if errors.IsNotFound(err) { + return nil, fmt.Errorf("secret %s not found in namespace %s: %w", name, namespace, err) + } + return nil, fmt.Errorf("failed to get secret %s in namespace %s: %w", name, namespace, err) + } + return secret, nil +} + // findDatabaseSecret finds the DB configuration secret named (specified or default) in the same namespace as the CR func (r *TrustyAIServiceReconciler) findDatabaseSecret(ctx context.Context, instance *trustyaiopendatahubiov1alpha1.TrustyAIService) (*corev1.Secret, error) { databaseConfigurationsName := instance.Spec.Storage.DatabaseConfigurations defaultDatabaseConfigurationsName := instance.Name + dbCredentialsSuffix - secret := &corev1.Secret{} - if databaseConfigurationsName != "" { - secret := &corev1.Secret{} - err := r.Get(ctx, client.ObjectKey{Name: databaseConfigurationsName, Namespace: instance.Namespace}, secret) - if err == nil { - return secret, nil + secret, err := r.getSecret(ctx, databaseConfigurationsName, instance.Namespace) + if err != nil { + return nil, err } - if !errors.IsNotFound(err) { - return nil, fmt.Errorf("failed to get secret %s in namespace %s: %w", databaseConfigurationsName, instance.Namespace, err) + if secret != nil { + return secret, nil } } else { // If specified not found, try the default - - err := r.Get(ctx, client.ObjectKey{Name: defaultDatabaseConfigurationsName, Namespace: instance.Namespace}, secret) - if err == nil { - return secret, nil + secret, err := r.getSecret(ctx, defaultDatabaseConfigurationsName, instance.Namespace) + if err != nil { + return nil, err } - if !errors.IsNotFound(err) { - return nil, fmt.Errorf("failed to get secret %s in namespace %s: %w", defaultDatabaseConfigurationsName, instance.Namespace, err) + if secret != nil { + return secret, nil } - } return nil, fmt.Errorf("neither secret %s nor %s found in namespace %s", databaseConfigurationsName, defaultDatabaseConfigurationsName, instance.Namespace) diff --git a/controllers/templates/service/deployment.tmpl.yaml b/controllers/templates/service/deployment.tmpl.yaml index 840421f0..fa8a9c76 100644 --- a/controllers/templates/service/deployment.tmpl.yaml +++ b/controllers/templates/service/deployment.tmpl.yaml @@ -94,7 +94,11 @@ spec: name: {{ .Instance.Spec.Storage.DatabaseConfigurations }} key: databasePort - name: QUARKUS_DATASOURCE_JDBC_URL + {{ if .UseDBTLSCerts }} + value: "jdbc:${QUARKUS_DATASOURCE_DB_KIND}://${DATABASE_SERVICE}:${DATABASE_PORT}/trustyai_database?sslMode=verify-ca&serverSslCert=/etc/tls/db/tls.crt" + {{ else }} value: "jdbc:${QUARKUS_DATASOURCE_DB_KIND}://${DATABASE_SERVICE}:${DATABASE_PORT}/trustyai_database" + {{ end }} - name: SERVICE_DATA_FORMAT value: "HIBERNATE" - name: QUARKUS_DATASOURCE_GENERATION @@ -121,7 +125,12 @@ spec: - name: {{ .VolumeMountName }} mountPath: {{ .Instance.Spec.Storage.Folder }} readOnly: false - {{ end }} + {{ end }} + {{ if .UseDBTLSCerts }} + - name: db-tls-certs + mountPath: /etc/tls/db + readOnly: true + {{ end }} - resources: limits: cpu: 100m @@ -209,3 +218,9 @@ spec: secret: secretName: {{ .Instance.Name }}-internal defaultMode: 420 + {{ if .UseDBTLSCerts }} + - name: db-tls-certs + secret: + secretName: {{ .Instance.Name }}-db-tls + defaultMode: 420 + {{ end }} diff --git a/controllers/utils.go b/controllers/utils.go index 91ee9bdb..e96fc4e5 100644 --- a/controllers/utils.go +++ b/controllers/utils.go @@ -62,7 +62,12 @@ func (r *TrustyAIServiceReconciler) GetDeploymentsByLabel(ctx context.Context, n return deployments.Items, nil } -// generateServiceURL generates an internal URL for a TrustyAI service -func generateServiceURL(crName string, namespace string) string { +// generateTLSServiceURL generates an internal URL for a TLS-enabled TrustyAI service +func generateTLSServiceURL(crName string, namespace string) string { + return "https://" + crName + "." + namespace + ".svc" +} + +// generateNonTLSServiceURL generates an internal URL for a TrustyAI service +func generateNonTLSServiceURL(crName string, namespace string) string { return "http://" + crName + "." + namespace + ".svc" }