Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions internal/controller/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const (
/*** application server configuration file ***/
// OLSConfigName is the name of the OLSConfig configmap
OLSConfigCmName = "olsconfig"
// AppServerConfigCmName is the name of the app server configmap
AppServerConfigCmName = "olsconfig"
// OLSCAConfigMap is the name of the OLS TLS ca certificate configmap
OLSCAConfigMap = "openshift-service-ca.crt"
// OLSNamespaceDefault is the default namespace for OLS
Expand Down Expand Up @@ -285,4 +287,6 @@ ssl_ca_file = '/etc/certs/cm-olspostgresca/service-ca.crt'
MCPHeadersMountRoot = "/etc/mcp/headers"
// Header Secret Data Path
MCPSECRETDATAPATH = "header"
// LSCAppServerActivatorCmName is the name of the LSC app server activator configmap
LSCAppServerActivatorCmName = "lsc-app-server-activator"
)
1 change: 1 addition & 0 deletions internal/controller/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const (
ErrGetConsolePluginDeployment = "failed to get Console Plugin deployment"
ErrGetConsolePluginNetworkPolicy = "failed to get Console Plugin network policy"
ErrGetConsolePluginService = "failed to get Console Plugin service"
ErrGetLSCActivatorConfigmap = "failed to get LSC backend activator configmap"
ErrGetLLMSecret = "failed to get LLM provider secret" // #nosec G101
ErrGetOperatorNetworkPolicy = "failed to get operator network policy"
ErrGetPostgresNetworkPolicy = "failed to get OLS Postgres network policy"
Expand Down
64 changes: 64 additions & 0 deletions internal/controller/lsc_app_server_assets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package controller

import (
"context"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1"
)

// todo: implement LSC config map generation
//
//nolint:unused // Ignore unused lint error before implementation of reconciliation functions
func (r *OLSConfigReconciler) generateLSCConfigMap(ctx context.Context, cr *olsv1alpha1.OLSConfig) (*corev1.ConfigMap, error) { //lint:ignore U1000 Ignore unused lint error before implementation of reconciliation functions
configMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: AppServerConfigCmName,
Namespace: r.Options.Namespace,
},
}
return configMap, nil
}

// todo: implement LSC deployment generation
//
//nolint:unused // Ignore unused lint error before implementation of reconciliation functions
func (r *OLSConfigReconciler) generateLSCDeployment(ctx context.Context, cr *olsv1alpha1.OLSConfig) (*appsv1.Deployment, error) { //lint:ignore U1000 Ignore unused lint error before implementation of reconciliation functions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in deployment file rather than here to make it symmetric to the current one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's put the LSC backend related code in a dedicated file and when we remove the old code in future, we just need to remove the old deployment file and the switch code in the main controller loop.

deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: OLSAppServerDeploymentName,
Namespace: r.Options.Namespace,
},
Spec: appsv1.DeploymentSpec{
Replicas: cr.Spec.OLSConfig.DeploymentConfig.Replicas,
Selector: &metav1.LabelSelector{
MatchLabels: generateAppServerSelectorLabels(),
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: generateAppServerSelectorLabels(),
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "lsc-app-server",
Image: r.Options.LightspeedServiceImage,
},
},
},
},
},
}
return deployment, nil
}

// todo: implement LSC deployment update
//
//nolint:unused // Ignore unused lint error before implementation of reconciliation functions
func (r *OLSConfigReconciler) updateLSCDeployment(ctx context.Context, existingDeployment, desiredDeployment *appsv1.Deployment) error {

return nil
}
78 changes: 78 additions & 0 deletions internal/controller/lsc_app_server_assets_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package controller

import (
"context"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
logf "sigs.k8s.io/controller-runtime/pkg/log"

olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1"
)

var _ = Describe("LSC App server assets", Label("LSCBackend"), Ordered, func() {
var cr *olsv1alpha1.OLSConfig
var r *OLSConfigReconciler
var rOptions *OLSConfigReconcilerOptions
var ctx context.Context

Context("LSC asset generation", func() {
BeforeEach(func() {
ctx = context.Background()
rOptions = &OLSConfigReconcilerOptions{
OpenShiftMajor: "123",
OpenshiftMinor: "456",
LightspeedServiceImage: "lightspeed-service:latest",
OpenShiftMCPServerImage: "openshift-mcp-server:latest",
Namespace: OLSNamespaceDefault,
}
cr = getDefaultOLSConfigCR()
r = &OLSConfigReconciler{
Options: *rOptions,
logger: logf.Log.WithName("olsconfig.reconciler"),
Client: k8sClient,
Scheme: k8sClient.Scheme(),
stateCache: make(map[string]string),
}
})

Describe("generateLSCConfigMap", func() {
It("should generate a valid configmap", func() {
cm, err := r.generateLSCConfigMap(ctx, cr)
Expect(err).NotTo(HaveOccurred())
Expect(cm).NotTo(BeNil())
})

// TODO: Add more tests cases for once implementation is complete
})

Describe("generateLSCDeployment", func() {
It("should generate a valid deployment", func() {
deployment, err := r.generateLSCDeployment(ctx, cr)
Expect(err).NotTo(HaveOccurred())
Expect(deployment).NotTo(BeNil())
})

// TODO: Add more tests cases for once implementation is complete
})

Describe("updateLSCDeployment", func() {
var existingDeployment *appsv1.Deployment
var desiredDeployment *appsv1.Deployment

BeforeEach(func() {
existingDeployment, _ = r.generateLSCDeployment(ctx, cr)
})

It("should successfully update deployment", func() {
desiredDeployment, _ = r.generateLSCDeployment(ctx, cr)
err := r.updateLSCDeployment(ctx, existingDeployment, desiredDeployment)
Expect(err).NotTo(HaveOccurred())
})

// TODO: Add more tests cases for once implementation is complete
})
})

})
94 changes: 94 additions & 0 deletions internal/controller/lsc_app_server_reconciliator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package controller

import (
"context"
"fmt"

olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1"
)

func (r *OLSConfigReconciler) reconcileAppServerLSC(ctx context.Context, olsconfig *olsv1alpha1.OLSConfig) error {
r.logger.Info("reconcileAppServerLSC starts")
tasks := []ReconcileTask{
{
Name: "reconcile ServiceAccount",
Task: r.reconcileServiceAccount,
},
{
Name: "reconcile SARRole",
Task: r.reconcileSARRole,
},
{
Name: "reconcile SARRoleBinding",
Task: r.reconcileSARRoleBinding,
},
// todo: LSC config map generation
// todo: Llama Stack configmap generation
{
Name: "reconcile OLSConfigMap",
Task: r.reconcileLSCConfigMap,
},
{
Name: "reconcile Additional CA ConfigMap",
Task: r.reconcileOLSAdditionalCAConfigMap,
},
{
Name: "reconcile App Service",
Task: r.reconcileService,
},
{
Name: "reconcile App TLS Certs",
Task: r.reconcileTLSSecret,
},
// todo: LSC deployment generation
{
Name: "reconcile App Deployment",
Task: r.reconcileLSCDeployment,
},
{
Name: "reconcile Metrics Reader Secret",
Task: r.reconcileMetricsReaderSecret,
},
{
Name: "reconcile App ServiceMonitor",
Task: r.reconcileServiceMonitor,
},
{
Name: "reconcile App PrometheusRule",
Task: r.reconcilePrometheusRule,
},
{
Name: "reconcile App NetworkPolicy",
Task: r.reconcileAppServerNetworkPolicy,
},
{
Name: "reconcile Proxy CA ConfigMap",
Task: r.reconcileProxyCAConfigMap,
},
}

for _, task := range tasks {
err := task.Task(ctx, olsconfig)
if err != nil {
r.logger.Error(err, "reconcileAppServer error", "task", task.Name)
return fmt.Errorf("failed to %s: %w", task.Name, err)
}
}

r.logger.Info("reconcileAppServer completes")

return nil
}

func (r *OLSConfigReconciler) reconcileLSCConfigMap(ctx context.Context, cr *olsv1alpha1.OLSConfig) error {

return r.reconcileOLSConfigMap(ctx, cr)
// TODO: implement LSC configmap reconciliation
}

func (r *OLSConfigReconciler) reconcileLSCDeployment(ctx context.Context, cr *olsv1alpha1.OLSConfig) error {

return r.reconcileDeployment(ctx, cr)

// TODO: implement LSC deployment reconciliation
}
Loading