Skip to content

Commit

Permalink
add support for providing custom certs for OLS and Custom ca for UI
Browse files Browse the repository at this point in the history
  • Loading branch information
Nimer Naamneh authored and raptorsun committed Oct 9, 2024
1 parent f16a432 commit 69d3f30
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 17 deletions.
7 changes: 7 additions & 0 deletions api/v1alpha1/olsconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type OLSSpec struct {
// User data collection switches
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="User Data Collection"
UserDataCollection UserDataCollectionSpec `json:"userDataCollection,omitempty"`

UseUserProvidedTLSCerts bool `json:"useUserProvidedTLSCerts,omitempty"`
// Additional CA certificates for TLS communication between OLS service and LLM Provider
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Additional CA Configmap",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"}
AdditionalCAConfigMapRef *corev1.LocalObjectReference `json:"additionalCAConfigMapRef,omitempty"`
Expand Down Expand Up @@ -130,6 +132,11 @@ type ConsoleContainerConfig struct {
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Number of replicas",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
// +optional
Replicas *int32 `json:"replicas,omitempty"`
// Certificate Authority (CA) certificate used by the console proxy endpoint.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="CA Certificate",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:caCertificate"}
// +kubebuilder:validation:Pattern=`^-----BEGIN CERTIFICATE-----([\s\S]*)-----END CERTIFICATE-----\s?$`
// +optional
CAcertificate string `json:"caCertificate,omitempty"`
}

// +kubebuilder:validation:Enum=redis
Expand Down
11 changes: 8 additions & 3 deletions bundle/manifests/lightspeed-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ metadata:
]
capabilities: Basic Install
console.openshift.io/operator-monitoring-default: "true"
createdAt: "2024-10-03T09:25:52Z"
createdAt: "2024-10-09T12:51:43Z"
features.operators.openshift.io/cnf: "false"
features.operators.openshift.io/cni: "false"
features.operators.openshift.io/csi: "false"
Expand Down Expand Up @@ -161,6 +161,11 @@ spec:
- description: Console container settings.
displayName: Console Container
path: ols.deployment.console
- description: Certificate Authority (CA) certificate used by the console proxy endpoint.
displayName: CA Certificate
path: ols.deployment.console.caCertificate
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:caCertificate
- displayName: Node Selector
path: ols.deployment.console.nodeSelector
x-descriptors:
Expand Down Expand Up @@ -351,8 +356,8 @@ spec:
- --metrics-bind-address=:8443
- --secure-metrics-server
- --cert-dir=/etc/tls/private
- --service-image=registry.redhat.io/openshift-lightspeed-beta/lightspeed-service-api-rhel9@sha256:30a415728724d6cdac7836fe6f142544a01124633837e958c700c757fa0d82dd
- --console-image=registry.redhat.io/openshift-lightspeed-beta/lightspeed-console-plugin-rhel9@sha256:144af406ea4202b5d72a7630cc286881fe155b7f4600d498593ff65d67a2fbd0
- --service-image=registry.redhat.io/openshift-lightspeed-beta/lightspeed-service-api-rhel9@sha256:f2ae050ceb35a10cba0f1c056975314ea33f320e3a08cffde8b939274aebff0d
command:
- /manager
env:
Expand Down Expand Up @@ -540,8 +545,8 @@ spec:
type: AllNamespaces
keywords:
- ai
- openshift
- assistant
- openshift
- llm
links:
- name: Lightspeed Operator
Expand Down
8 changes: 8 additions & 0 deletions bundle/manifests/ols.openshift.io_olsconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ spec:
console:
description: Console container settings.
properties:
caCertificate:
description: Certificate Authority (CA) certificate used
by the console proxy endpoint.
pattern: ^-----BEGIN CERTIFICATE-----([\s\S]*)-----END
CERTIFICATE-----\s?$
type: string
nodeSelector:
additionalProperties:
type: string
Expand Down Expand Up @@ -491,6 +497,8 @@ spec:
type: string
type: object
type: array
useUserProvidedTLSCerts:
type: boolean
userDataCollection:
description: User data collection switches
properties:
Expand Down
8 changes: 8 additions & 0 deletions config/crd/bases/ols.openshift.io_olsconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ spec:
console:
description: Console container settings.
properties:
caCertificate:
description: Certificate Authority (CA) certificate used
by the console proxy endpoint.
pattern: ^-----BEGIN CERTIFICATE-----([\s\S]*)-----END
CERTIFICATE-----\s?$
type: string
nodeSelector:
additionalProperties:
type: string
Expand Down Expand Up @@ -491,6 +497,8 @@ spec:
type: string
type: object
type: array
useUserProvidedTLSCerts:
type: boolean
userDataCollection:
description: User data collection switches
properties:
Expand Down
2 changes: 1 addition & 1 deletion config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ resources:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- digest: sha256:e62a1e3e618b7bf6a9ca8b1e7b6ae500d6b0e47c9e5f3e4a8eeb259082c9199e
- digest: sha256:f395c217c9cb67205edc7061bdb5ae52e30c2c934c40f558b0403a9f0f4c96e5
name: controller
newName: registry.redhat.io/openshift-lightspeed-beta/lightspeed-rhel9-operator
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ spec:
- description: Console container settings.
displayName: Console Container
path: ols.deployment.console
- description: Certificate Authority (CA) certificate used by the console proxy
endpoint.
displayName: CA Certificate
path: ols.deployment.console.caCertificate
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:caCertificate
- displayName: Node Selector
path: ols.deployment.console.nodeSelector
x-descriptors:
Expand Down
32 changes: 32 additions & 0 deletions hack/custom_certs/cr-with-custom-certs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: ols.openshift.io/v1alpha1
kind: OLSConfig
metadata:
name: cluster
namespace: openshift-lightspeed
spec:
llm:
providers:
- credentialsSecretRef:
name: bam-api-keys
type: bam
models:
- name: ibm/granite-13b-chat-v2
name: bam
url: https://bam-api.res.ibm.com
ols:
conversationCache:
redis:
maxMemory: 2000mb
maxMemoryPolicy: allkeys-lru
type: redis
defaultModel: ibm/granite-13b-chat-v2
defaultProvider: bam
logLevel: INFO
useUserProvidedTLSCerts: true
deployment:
replicas: 1
console:
caCertificate: |
-----BEGIN CERTIFICATE-----
your-certificate content, syntax sensitive
-----END CERTIFICATE-----
46 changes: 46 additions & 0 deletions hack/custom_certs/generate-certs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

# Define variables
CERT_DIR="./certs"
CA_KEY="$CERT_DIR/ca.key"
CA_CERT="$CERT_DIR/ca.crt"
PRIVATE_KEY="$CERT_DIR/tls.key"
CERTIFICATE="$CERT_DIR/tls.crt"
DAYS_VALID=365
SECRET_NAME="lightspeed-tls"
NAMESPACE="openshift-lightspeed"

# Create directory for certificates if it doesn't exist
mkdir -p "$CERT_DIR"

# Generate CA private key and self-signed CA certificate
openssl req -x509 -newkey rsa:4096 -sha256 -days "$DAYS_VALID" -nodes \
-keyout "$CA_KEY" -out "$CA_CERT" -subj "/CN=MyCA" \
-addext "subjectAltName=DNS:MyCA"

echo "CA certificate and private key have been generated in $CERT_DIR"

# Generate private key and certificate signing request (CSR) for the server
openssl req -new -newkey rsa:4096 -nodes -keyout "$PRIVATE_KEY" -out "$CERT_DIR/server.csr" \
-subj "/CN=lightspeed-app-server" -addext "subjectAltName=DNS:lightspeed-app-server,DNS:lightspeed-app-server.openshift-lightspeed.svc.cluster.local,IP:127.0.0.1,IP:::1"

# Sign the server certificate with the CA certificate
openssl x509 -req -in "$CERT_DIR/server.csr" -CA "$CA_CERT" -CAkey "$CA_KEY" -CAcreateserial \
-out "$CERTIFICATE" -days "$DAYS_VALID" -sha256 -extfile <(echo "subjectAltName=DNS:lightspeed-app-server,DNS:lightspeed-app-server.openshift-lightspeed.svc.cluster.local,IP:127.0.0.1,IP:::1")

echo "Server certificate signed by CA has been generated in $CERT_DIR"

# Generate the Kubernetes Secret YAML manifest for the TLS certificate and key for the ols-server
cat <<EOF > "$CERT_DIR/$SECRET_NAME.yaml"
apiVersion: v1
kind: Secret
metadata:
name: $SECRET_NAME
namespace: $NAMESPACE
type: kubernetes.io/tls
data:
tls.crt: $(base64 < "$CERTIFICATE")
tls.key: $(base64 < "$PRIVATE_KEY")
EOF

echo "Kubernetes Secret manifest for TLS has been generated at $CERT_DIR/$SECRET_NAME.yaml"
18 changes: 12 additions & 6 deletions internal/controller/ols_app_server_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,14 +320,20 @@ func (r *OLSConfigReconciler) getAdditionalCAFileNames(cr *olsv1alpha1.OLSConfig
}

func (r *OLSConfigReconciler) generateService(cr *olsv1alpha1.OLSConfig) (*corev1.Service, error) {
annotations := map[string]string{}

// Check if the flag for user-provided TLS certs is set
if !cr.Spec.OLSConfig.UseUserProvidedTLSCerts {
// Add the service-served certs annotations only if the flag is not set
annotations[ServingCertSecretAnnotationKey] = OLSCertsSecretName
}

service := corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: OLSAppServerServiceName,
Namespace: r.Options.Namespace,
Labels: generateAppServerSelectorLabels(),
Annotations: map[string]string{
ServingCertSecretAnnotationKey: OLSCertsSecretName,
},
Name: OLSAppServerServiceName,
Namespace: r.Options.Namespace,
Labels: generateAppServerSelectorLabels(),
Annotations: annotations,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
Expand Down
14 changes: 9 additions & 5 deletions internal/controller/ols_app_server_reconciliator.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,15 @@ func (r *OLSConfigReconciler) reconcileService(ctx context.Context, cr *olsv1alp
return fmt.Errorf("%s: %w", ErrGetAPIServiceAccount, err)
}

if serviceEqual(foundService, service) &&
foundService.ObjectMeta.Annotations != nil &&
foundService.ObjectMeta.Annotations[ServingCertSecretAnnotationKey] == service.ObjectMeta.Annotations[ServingCertSecretAnnotationKey] {
r.logger.Info("OLS service unchanged, reconciliation skipped", "service", service.Name)
return nil
if serviceEqual(foundService, service) && foundService.ObjectMeta.Annotations != nil {
if cr.Spec.OLSConfig.UseUserProvidedTLSCerts {
r.logger.Info("OLS service unchanged, reconciliation skipped", "service", service.Name)
return nil

} else if foundService.ObjectMeta.Annotations[ServingCertSecretAnnotationKey] == service.ObjectMeta.Annotations[ServingCertSecretAnnotationKey] {
r.logger.Info("OLS service unchanged, reconciliation skipped", "service", service.Name)
return nil
}
}

err = r.Update(ctx, service)
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/ols_console_reconciliator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1"
)

func (r *OLSConfigReconciler) reconcileConsoleUI(ctx context.Context, olsconfig *olsv1alpha1.OLSConfig) error {
func (r *OLSConfigReconciler) reconcileConsoleUI(ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
r.logger.Info("reconcileConsoleUI starts")
tasks := []ReconcileTask{
{
Expand Down Expand Up @@ -49,7 +49,7 @@ func (r *OLSConfigReconciler) reconcileConsoleUI(ctx context.Context, olsconfig
}

for _, task := range tasks {
err := task.Task(ctx, olsconfig)
err := task.Task(ctx, cr)
if err != nil {
r.logger.Error(err, "reconcileConsoleUI error", "task", task.Name)
return fmt.Errorf("failed to %s: %w", task.Name, err)
Expand Down
5 changes: 5 additions & 0 deletions internal/controller/ols_console_ui_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ func (r *OLSConfigReconciler) generateConsoleUIPlugin(cr *olsv1alpha1.OLSConfig)
},
}

// Conditionally add the CA certificate if provided in the CRD
if cr.Spec.OLSConfig.DeploymentConfig.ConsoleContainer.CAcertificate != "" {
plugin.Spec.Proxy[0].CACertificate = cr.Spec.OLSConfig.DeploymentConfig.ConsoleContainer.CAcertificate
}

if err := controllerutil.SetControllerReference(cr, plugin, r.Scheme); err != nil {
return nil, err
}
Expand Down

0 comments on commit 69d3f30

Please sign in to comment.