Skip to content

Commit d5c76dc

Browse files
committed
feat: switch to LSC app backend using magic configmap
Signed-off-by: Haoyu Sun <[email protected]>
1 parent d6cca73 commit d5c76dc

File tree

7 files changed

+438
-1
lines changed

7 files changed

+438
-1
lines changed

internal/controller/constants.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ const (
2828
/*** application server configuration file ***/
2929
// OLSConfigName is the name of the OLSConfig configmap
3030
OLSConfigCmName = "olsconfig"
31+
// AppServerConfigCmName is the name of the app server configmap
32+
AppServerConfigCmName = "olsconfig"
3133
// OLSCAConfigMap is the name of the OLS TLS ca certificate configmap
3234
OLSCAConfigMap = "openshift-service-ca.crt"
3335
// OLSNamespaceDefault is the default namespace for OLS
@@ -277,4 +279,6 @@ ssl_ca_file = '/etc/certs/cm-olspostgresca/service-ca.crt'
277279
OpenShiftMCPServerTimeout = 60
278280
// MCP server SSE read timeout, sec
279281
OpenShiftMCPServerHTTPReadTimeout = 30
282+
// LSCAppServerActivatorCmName is the name of the LSC app server activator configmap
283+
LSCAppServerActivatorCmName = "lsc-app-server-activator"
280284
)

internal/controller/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ const (
6868
ErrGetConsolePluginDeployment = "failed to get Console Plugin deployment"
6969
ErrGetConsolePluginNetworkPolicy = "failed to get Console Plugin network policy"
7070
ErrGetConsolePluginService = "failed to get Console Plugin service"
71+
ErrGetLSCActivatorConfigmap = "failed to get LSC backend activator configmap"
7172
ErrGetLLMSecret = "failed to get LLM provider secret" // #nosec G101
7273
ErrGetOperatorNetworkPolicy = "failed to get operator network policy"
7374
ErrGetPostgresNetworkPolicy = "failed to get OLS Postgres network policy"
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package controller
2+
3+
import (
4+
"context"
5+
6+
appsv1 "k8s.io/api/apps/v1"
7+
corev1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
10+
olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1"
11+
)
12+
13+
// todo: implement LSC config map generation
14+
func (r *OLSConfigReconciler) generateLSCConfigMap(ctx context.Context, cr *olsv1alpha1.OLSConfig) (*corev1.ConfigMap, error) {
15+
configMap := &corev1.ConfigMap{
16+
ObjectMeta: metav1.ObjectMeta{
17+
Name: AppServerConfigCmName,
18+
Namespace: r.Options.Namespace,
19+
},
20+
}
21+
return configMap, nil
22+
}
23+
24+
// todo: implement LSC deployment generation
25+
func (r *OLSConfigReconciler) generateLSCDeployment(ctx context.Context, cr *olsv1alpha1.OLSConfig) (*appsv1.Deployment, error) {
26+
deployment := &appsv1.Deployment{
27+
ObjectMeta: metav1.ObjectMeta{
28+
Name: OLSAppServerDeploymentName,
29+
Namespace: r.Options.Namespace,
30+
},
31+
Spec: appsv1.DeploymentSpec{
32+
Replicas: cr.Spec.OLSConfig.DeploymentConfig.Replicas,
33+
Selector: &metav1.LabelSelector{
34+
MatchLabels: generateAppServerSelectorLabels(),
35+
},
36+
Template: corev1.PodTemplateSpec{
37+
ObjectMeta: metav1.ObjectMeta{
38+
Labels: generateAppServerSelectorLabels(),
39+
},
40+
Spec: corev1.PodSpec{
41+
Containers: []corev1.Container{
42+
{
43+
Name: "lsc-app-server",
44+
Image: r.Options.LightspeedServiceImage,
45+
},
46+
},
47+
},
48+
},
49+
},
50+
}
51+
return deployment, nil
52+
}
53+
54+
// todo: implement LSC deployment update
55+
func (r *OLSConfigReconciler) updateLSCDeployment(ctx context.Context, existingDeployment, desiredDeployment *appsv1.Deployment) error {
56+
57+
return nil
58+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package controller
2+
3+
import (
4+
"context"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
appsv1 "k8s.io/api/apps/v1"
9+
logf "sigs.k8s.io/controller-runtime/pkg/log"
10+
11+
olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1"
12+
)
13+
14+
var _ = Describe("LSC App server assets", Label("LSCBackend"), Ordered, func() {
15+
var cr *olsv1alpha1.OLSConfig
16+
var r *OLSConfigReconciler
17+
var rOptions *OLSConfigReconcilerOptions
18+
var ctx context.Context
19+
20+
Context("LSC asset generation", func() {
21+
BeforeEach(func() {
22+
ctx = context.Background()
23+
rOptions = &OLSConfigReconcilerOptions{
24+
OpenShiftMajor: "123",
25+
OpenshiftMinor: "456",
26+
LightspeedServiceImage: "lightspeed-service:latest",
27+
OpenShiftMCPServerImage: "openshift-mcp-server:latest",
28+
Namespace: OLSNamespaceDefault,
29+
}
30+
cr = getDefaultOLSConfigCR()
31+
r = &OLSConfigReconciler{
32+
Options: *rOptions,
33+
logger: logf.Log.WithName("olsconfig.reconciler"),
34+
Client: k8sClient,
35+
Scheme: k8sClient.Scheme(),
36+
stateCache: make(map[string]string),
37+
}
38+
})
39+
40+
Describe("generateLSCConfigMap", func() {
41+
It("should generate a valid configmap", func() {
42+
cm, err := r.generateLSCConfigMap(ctx, cr)
43+
Expect(err).NotTo(HaveOccurred())
44+
Expect(cm).NotTo(BeNil())
45+
})
46+
47+
// TODO: Add more tests cases for once implementation is complete
48+
})
49+
50+
Describe("generateLSCDeployment", func() {
51+
It("should generate a valid deployment", func() {
52+
deployment, err := r.generateLSCDeployment(ctx, cr)
53+
Expect(err).NotTo(HaveOccurred())
54+
Expect(deployment).NotTo(BeNil())
55+
})
56+
57+
// TODO: Add more tests cases for once implementation is complete
58+
})
59+
60+
Describe("updateLSCDeployment", func() {
61+
var existingDeployment *appsv1.Deployment
62+
var desiredDeployment *appsv1.Deployment
63+
64+
BeforeEach(func() {
65+
existingDeployment, _ = r.generateLSCDeployment(ctx, cr)
66+
})
67+
68+
It("should successfully update deployment", func() {
69+
desiredDeployment, _ = r.generateLSCDeployment(ctx, cr)
70+
err := r.updateLSCDeployment(ctx, existingDeployment, desiredDeployment)
71+
Expect(err).NotTo(HaveOccurred())
72+
})
73+
74+
// TODO: Add more tests cases for once implementation is complete
75+
})
76+
})
77+
78+
})
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package controller
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
appsv1 "k8s.io/api/apps/v1"
8+
corev1 "k8s.io/api/core/v1"
9+
"k8s.io/apimachinery/pkg/api/errors"
10+
11+
"sigs.k8s.io/controller-runtime/pkg/client"
12+
13+
olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1"
14+
)
15+
16+
func (r *OLSConfigReconciler) reconcileAppServerLSC(ctx context.Context, olsconfig *olsv1alpha1.OLSConfig) error {
17+
r.logger.Info("reconcileAppServerLSC starts")
18+
tasks := []ReconcileTask{
19+
{
20+
Name: "reconcile ServiceAccount",
21+
Task: r.reconcileServiceAccount,
22+
},
23+
{
24+
Name: "reconcile SARRole",
25+
Task: r.reconcileSARRole,
26+
},
27+
{
28+
Name: "reconcile SARRoleBinding",
29+
Task: r.reconcileSARRoleBinding,
30+
},
31+
// todo: LSC config map generation
32+
{
33+
Name: "reconcile OLSConfigMap",
34+
Task: r.reconcileLSCConfigMap,
35+
},
36+
{
37+
Name: "reconcile Additional CA ConfigMap",
38+
Task: r.reconcileOLSAdditionalCAConfigMap,
39+
},
40+
{
41+
Name: "reconcile App Service",
42+
Task: r.reconcileService,
43+
},
44+
{
45+
Name: "reconcile App TLS Certs",
46+
Task: r.reconcileTLSSecret,
47+
},
48+
// todo: LSC deployment generation
49+
{
50+
Name: "reconcile App Deployment",
51+
Task: r.reconcileLSCDeployment,
52+
},
53+
{
54+
Name: "reconcile Metrics Reader Secret",
55+
Task: r.reconcileMetricsReaderSecret,
56+
},
57+
{
58+
Name: "reconcile App ServiceMonitor",
59+
Task: r.reconcileServiceMonitor,
60+
},
61+
{
62+
Name: "reconcile App PrometheusRule",
63+
Task: r.reconcilePrometheusRule,
64+
},
65+
{
66+
Name: "reconcile App NetworkPolicy",
67+
Task: r.reconcileAppServerNetworkPolicy,
68+
},
69+
{
70+
Name: "reconcile Proxy CA ConfigMap",
71+
Task: r.reconcileProxyCAConfigMap,
72+
},
73+
}
74+
75+
for _, task := range tasks {
76+
err := task.Task(ctx, olsconfig)
77+
if err != nil {
78+
r.logger.Error(err, "reconcileAppServer error", "task", task.Name)
79+
return fmt.Errorf("failed to %s: %w", task.Name, err)
80+
}
81+
}
82+
83+
r.logger.Info("reconcileAppServer completes")
84+
85+
return nil
86+
}
87+
88+
func (r *OLSConfigReconciler) reconcileLSCConfigMap(ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
89+
// TODO: implement LSC configmap reconciliation
90+
configMap, err := r.generateLSCConfigMap(ctx, cr)
91+
if err != nil {
92+
return fmt.Errorf("%s: %w", ErrGenerateAPIConfigmap, err)
93+
}
94+
95+
foundConfigMap := &corev1.ConfigMap{}
96+
err = r.Get(ctx, client.ObjectKey{Name: AppServerConfigCmName, Namespace: r.Options.Namespace}, foundConfigMap)
97+
if err != nil && errors.IsNotFound(err) {
98+
r.logger.Info("creating a new LSC configmap", "configmap", configMap.Name)
99+
err = r.Create(ctx, configMap)
100+
if err != nil {
101+
return fmt.Errorf("%s: %w", ErrCreateAPIConfigmap, err)
102+
}
103+
r.logger.Info("LSC configmap created", "configmap", configMap.Name)
104+
return nil
105+
} else if err != nil {
106+
return fmt.Errorf("%s: %w", ErrGetAPIConfigmap, err)
107+
}
108+
r.logger.Info("LSC configmap already exists, reconciliation skipped", "configmap", configMap.Name)
109+
return nil
110+
}
111+
112+
func (r *OLSConfigReconciler) reconcileLSCDeployment(ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
113+
// TODO: implement LSC deployment reconciliation
114+
r.logger.Info("reconcileLSCDeployment stub called - not yet implemented")
115+
desiredDeployment, err := r.generateLSCDeployment(ctx, cr)
116+
if err != nil {
117+
return fmt.Errorf("%s: %w", ErrGenerateAPIDeployment, err)
118+
}
119+
120+
existingDeployment := &appsv1.Deployment{}
121+
err = r.Get(ctx, client.ObjectKey{Name: OLSAppServerDeploymentName, Namespace: r.Options.Namespace}, existingDeployment)
122+
if err != nil && errors.IsNotFound(err) {
123+
r.logger.Info("creating a new deployment", "deployment", desiredDeployment.Name)
124+
err = r.Create(ctx, desiredDeployment)
125+
if err != nil {
126+
return fmt.Errorf("%s: %w", ErrCreateAPIDeployment, err)
127+
}
128+
return nil
129+
} else if err != nil {
130+
return fmt.Errorf("%s: %w", ErrGetAPIDeployment, err)
131+
}
132+
133+
err = r.updateLSCDeployment(ctx, existingDeployment, desiredDeployment)
134+
if err != nil {
135+
return fmt.Errorf("%s: %w", ErrUpdateAPIDeployment, err)
136+
}
137+
138+
return nil
139+
}

0 commit comments

Comments
 (0)