Skip to content

Commit 65d209c

Browse files
author
eliranb
committed
Phase 1: CRD and Initial Structure
1 parent 365e952 commit 65d209c

File tree

6 files changed

+120
-20
lines changed

6 files changed

+120
-20
lines changed

api/v1beta/lightrunjavaagent_types.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,13 @@ type LightrunJavaAgentSpec struct {
3838
ContainerSelector []string `json:"containerSelector"`
3939
InitContainer InitContainer `json:"initContainer"`
4040

41-
//Name of the Deployment that will be patched
42-
DeploymentName string `json:"deploymentName"`
41+
// Name of the Deployment that will be patched
42+
// +optional
43+
DeploymentName string `json:"deploymentName,omitempty"`
44+
45+
// Name of the StatefulSet that will be patched
46+
// +optional
47+
StatefulSetName string `json:"statefulSetName,omitempty"`
4348

4449
//Name of the Secret in the same namespace contains lightrun key and conmpany id
4550
SecretName string `json:"secretName"`
@@ -76,14 +81,15 @@ type LightrunJavaAgentSpec struct {
7681
type LightrunJavaAgentStatus struct {
7782
LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"`
7883
Conditions []metav1.Condition `json:"conditions,omitempty"`
79-
DeploymentStatus string `json:"deploymentStatus,omitempty"`
84+
WorkloadStatus string `json:"workloadStatus,omitempty"`
8085
}
8186

8287
//+kubebuilder:object:root=true
8388
//+kubebuilder:subresource:status
8489
//+kubebuilder:resource:shortName=lrja
8590
//+kubebuilder:printcolumn:priority=0,name=Deployment,type=string,JSONPath=".spec.deploymentName",description="Deployment name",format=""
86-
//+kubebuilder:printcolumn:priority=0,name="Status",type=string,JSONPath=".status.deploymentStatus",description="Status of Deployment Reconciliation",format=""
91+
//+kubebuilder:printcolumn:priority=0,name=StatefulSet,type=string,JSONPath=".spec.statefulSetName",description="StatefulSet name",format=""
92+
//+kubebuilder:printcolumn:priority=0,name="Status",type=string,JSONPath=".status.workloadStatus",description="Status of Workload Reconciliation",format=""
8793
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
8894

8995
// LightrunJavaAgent is the Schema for the lightrunjavaagents API

config/crd/bases/agents.lightrun.com_lightrunjavaagents.yaml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ spec:
2121
jsonPath: .spec.deploymentName
2222
name: Deployment
2323
type: string
24-
- description: Status of Deployment Reconciliation
25-
jsonPath: .status.deploymentStatus
24+
- description: StatefulSet name
25+
jsonPath: .spec.statefulSetName
26+
name: StatefulSet
27+
type: string
28+
- description: Status of Workload Reconciliation
29+
jsonPath: .status.workloadStatus
2630
name: Status
2731
type: string
2832
- jsonPath: .metadata.creationTimestamp
@@ -115,11 +119,13 @@ spec:
115119
Lightrun server hostname that will be used for downloading an agent
116120
Key and company id in the secret has to be taken from this server as well
117121
type: string
122+
statefulSetName:
123+
description: Name of the StatefulSet that will be patched
124+
type: string
118125
required:
119126
- agentEnvVarName
120127
- agentTags
121128
- containerSelector
122-
- deploymentName
123129
- initContainer
124130
- secretName
125131
- serverHostname
@@ -196,11 +202,11 @@ spec:
196202
- type
197203
type: object
198204
type: array
199-
deploymentStatus:
200-
type: string
201205
lastScheduleTime:
202206
format: date-time
203207
type: string
208+
workloadStatus:
209+
type: string
204210
type: object
205211
type: object
206212
served: true

config/rbac/role.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ rules:
3939
- list
4040
- patch
4141
- watch
42+
- apiGroups:
43+
- apps
44+
resources:
45+
- statefulsets
46+
verbs:
47+
- get
48+
- list
49+
- patch
50+
- watch
4251
- apiGroups:
4352
- ""
4453
resources:

internal/controller/helpers.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,31 @@ func (r *LightrunJavaAgentReconciler) mapDeploymentToAgent(ctx context.Context,
4848
return requests
4949
}
5050

51+
func (r *LightrunJavaAgentReconciler) mapStatefulSetToAgent(ctx context.Context, obj client.Object) []reconcile.Request {
52+
statefulSet := obj.(*appsv1.StatefulSet)
53+
54+
var lightrunJavaAgentList agentv1beta.LightrunJavaAgentList
55+
56+
if err := r.List(ctx, &lightrunJavaAgentList,
57+
client.InNamespace(statefulSet.Namespace),
58+
client.MatchingFields{statefulSetNameIndexField: statefulSet.Name},
59+
); err != nil {
60+
r.Log.Error(err, "could not list LightrunJavaAgentList. "+
61+
"change to statefulset will not be reconciled.",
62+
statefulSet.Name, statefulSet.Namespace)
63+
return nil
64+
}
65+
66+
requests := make([]reconcile.Request, len(lightrunJavaAgentList.Items))
67+
68+
for i, lightrunJavaAgent := range lightrunJavaAgentList.Items {
69+
requests[i] = reconcile.Request{
70+
NamespacedName: client.ObjectKeyFromObject(&lightrunJavaAgent),
71+
}
72+
}
73+
return requests
74+
}
75+
5176
func (r *LightrunJavaAgentReconciler) mapSecretToAgent(ctx context.Context, obj client.Object) []reconcile.Request {
5277
secret := obj.(*corev1.Secret)
5378

@@ -96,7 +121,7 @@ func (r *LightrunJavaAgentReconciler) successStatus(ctx context.Context, instanc
96121
Status: metav1.ConditionTrue,
97122
}
98123
SetStatusCondition(&instance.Status.Conditions, condition)
99-
instance.Status.DeploymentStatus = r.findLastConditionType(&instance.Status.Conditions)
124+
instance.Status.WorkloadStatus = r.findLastConditionType(&instance.Status.Conditions)
100125
err := r.Status().Update(ctx, instance)
101126
if err != nil {
102127
if apierrors.IsConflict(err) {
@@ -122,7 +147,7 @@ func (r *LightrunJavaAgentReconciler) errorStatus(ctx context.Context, instance
122147
Status: metav1.ConditionTrue,
123148
}
124149
SetStatusCondition(&instance.Status.Conditions, condition)
125-
instance.Status.DeploymentStatus = r.findLastConditionType(&instance.Status.Conditions)
150+
instance.Status.WorkloadStatus = r.findLastConditionType(&instance.Status.Conditions)
126151
err := r.Status().Update(ctx, instance)
127152
if err != nil {
128153
if apierrors.IsConflict(err) {

internal/controller/lightrunjavaagent_controller.go

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ import (
3636
)
3737

3838
const (
39-
deploymentNameIndexField = "spec.deployment"
40-
secretNameIndexField = "spec.secret"
41-
finalizerName = "agent.finalizers.lightrun.com"
39+
deploymentNameIndexField = "spec.deployment"
40+
statefulSetNameIndexField = "spec.statefulset"
41+
secretNameIndexField = "spec.secret"
42+
finalizerName = "agent.finalizers.lightrun.com"
4243
)
4344

4445
var err error
@@ -56,19 +57,40 @@ type LightrunJavaAgentReconciler struct {
5657
//+kubebuilder:rbac:groups=agents.lightrun.com,resources=lightrunjavaagents/finalizers,verbs=update
5758
//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete
5859
//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;watch;list;patch
60+
//+kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;watch;list;patch
5961
//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;watch;list
6062

6163
func (r *LightrunJavaAgentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
6264
log := r.Log.WithValues("lightrunJavaAgent", req.NamespacedName)
63-
fieldManager := "lightrun-conrtoller"
6465
lightrunJavaAgent := &agentv1beta.LightrunJavaAgent{}
6566
if err = r.Get(ctx, req.NamespacedName, lightrunJavaAgent); err != nil {
6667
return ctrl.Result{}, client.IgnoreNotFound(err)
6768
}
6869

70+
// Determine which workload type to reconcile
71+
if lightrunJavaAgent.Spec.DeploymentName != "" && lightrunJavaAgent.Spec.StatefulSetName != "" {
72+
log.Error(nil, "Both DeploymentName and StatefulSetName are set. Only one should be specified")
73+
return r.errorStatus(ctx, lightrunJavaAgent, errors.New("both deployment and statefulset specified"))
74+
} else if lightrunJavaAgent.Spec.DeploymentName != "" {
75+
// Handle Deployment reconciliation (existing code)
76+
return r.reconcileDeployment(ctx, lightrunJavaAgent, req.Namespace)
77+
} else if lightrunJavaAgent.Spec.StatefulSetName != "" {
78+
// Handle StatefulSet reconciliation (to be implemented)
79+
return r.reconcileStatefulSet(ctx, lightrunJavaAgent, req.Namespace)
80+
} else {
81+
log.Error(nil, "Neither DeploymentName nor StatefulSetName is set")
82+
return r.errorStatus(ctx, lightrunJavaAgent, errors.New("no workload specified"))
83+
}
84+
}
85+
86+
// reconcileDeployment handles the reconciliation logic for Deployment workloads
87+
func (r *LightrunJavaAgentReconciler) reconcileDeployment(ctx context.Context, lightrunJavaAgent *agentv1beta.LightrunJavaAgent, namespace string) (ctrl.Result, error) {
88+
log := r.Log.WithValues("lightrunJavaAgent", lightrunJavaAgent.Name, "deployment", lightrunJavaAgent.Spec.DeploymentName)
89+
fieldManager := "lightrun-conrtoller"
90+
6991
deplNamespacedObj := client.ObjectKey{
7092
Name: lightrunJavaAgent.Spec.DeploymentName,
71-
Namespace: req.Namespace,
93+
Namespace: namespace,
7294
}
7395
originalDeployment := &appsv1.Deployment{}
7496
err = r.Get(ctx, deplNamespacedObj, originalDeployment)
@@ -106,7 +128,7 @@ func (r *LightrunJavaAgentReconciler) Reconcile(ctx context.Context, req ctrl.Re
106128
log.V(2).Info("Searching for secret", "Name", lightrunJavaAgent.Spec.SecretName)
107129
secretNamespacedObj := client.ObjectKey{
108130
Name: lightrunJavaAgent.Spec.SecretName,
109-
Namespace: req.Namespace,
131+
Namespace: namespace,
110132
}
111133
secret = &corev1.Secret{}
112134
err = r.Get(ctx, secretNamespacedObj, secret)
@@ -289,6 +311,15 @@ func (r *LightrunJavaAgentReconciler) Reconcile(ctx context.Context, req ctrl.Re
289311
return r.successStatus(ctx, lightrunJavaAgent, reconcileTypeReady)
290312
}
291313

314+
// reconcileStatefulSet handles the reconciliation logic for StatefulSet workloads
315+
func (r *LightrunJavaAgentReconciler) reconcileStatefulSet(ctx context.Context, lightrunJavaAgent *agentv1beta.LightrunJavaAgent, namespace string) (ctrl.Result, error) {
316+
log := r.Log.WithValues("lightrunJavaAgent", lightrunJavaAgent.Name, "statefulSet", lightrunJavaAgent.Spec.StatefulSetName)
317+
318+
// This is a placeholder for Phase 2 implementation
319+
log.Info("StatefulSet reconciliation not yet implemented", "StatefulSet", lightrunJavaAgent.Spec.StatefulSetName)
320+
return r.errorStatus(ctx, lightrunJavaAgent, errors.New("statefulset reconciliation not yet implemented"))
321+
}
322+
292323
// SetupWithManager sets up the controller with the Manager.
293324
func (r *LightrunJavaAgentReconciler) SetupWithManager(mgr ctrl.Manager) error {
294325
// Add spec.container_selector.deployment field to cache for future filtering
@@ -310,6 +341,25 @@ func (r *LightrunJavaAgentReconciler) SetupWithManager(mgr ctrl.Manager) error {
310341
return err
311342
}
312343

344+
// Add spec.container_selector.statefulset field to cache for future filtering
345+
err = mgr.GetFieldIndexer().IndexField(
346+
context.Background(),
347+
&agentv1beta.LightrunJavaAgent{},
348+
statefulSetNameIndexField,
349+
func(object client.Object) []string {
350+
lightrunJavaAgent := object.(*agentv1beta.LightrunJavaAgent)
351+
352+
if lightrunJavaAgent.Spec.StatefulSetName == "" {
353+
return nil
354+
}
355+
356+
return []string{lightrunJavaAgent.Spec.StatefulSetName}
357+
})
358+
359+
if err != nil {
360+
return err
361+
}
362+
313363
// Add spec.container_selector.secret field to cache for future filtering
314364
err = mgr.GetFieldIndexer().IndexField(
315365
context.Background(),
@@ -336,6 +386,10 @@ func (r *LightrunJavaAgentReconciler) SetupWithManager(mgr ctrl.Manager) error {
336386
&appsv1.Deployment{},
337387
handler.EnqueueRequestsFromMapFunc(r.mapDeploymentToAgent),
338388
).
389+
Watches(
390+
&appsv1.StatefulSet{},
391+
handler.EnqueueRequestsFromMapFunc(r.mapStatefulSetToAgent),
392+
).
339393
Watches(
340394
&corev1.Secret{},
341395
handler.EnqueueRequestsFromMapFunc(r.mapSecretToAgent),

internal/controller/lightrunjavaagent_controller_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ var _ = Describe("LightrunJavaAgent controller", func() {
643643
if err := k8sClient.Get(ctx, lrAgentRequest2, &lrAgent2); err != nil {
644644
return false
645645
}
646-
return lrAgent2.Status.DeploymentStatus == "Ready"
646+
return lrAgent2.Status.WorkloadStatus == "Ready"
647647
}).Should(BeTrue())
648648
})
649649

@@ -678,7 +678,7 @@ var _ = Describe("LightrunJavaAgent controller", func() {
678678
if err := k8sClient.Get(ctx, lrAgentRequest3, &lrAgent3); err != nil {
679679
return false
680680
}
681-
return lrAgent3.Status.DeploymentStatus == "ReconcileFailed"
681+
return lrAgent3.Status.WorkloadStatus == "ReconcileFailed"
682682
}).Should(BeTrue())
683683
})
684684
It("Should not add finalizer to the duplicate CR", func() {
@@ -774,7 +774,7 @@ var _ = Describe("LightrunJavaAgent controller", func() {
774774
if err := k8sClient.Get(ctx, lrAgentRequest4, &lrAgent4); err != nil {
775775
return false
776776
}
777-
return lrAgent4.Status.DeploymentStatus == "" && lrAgent4.Status.Conditions == nil
777+
return lrAgent4.Status.WorkloadStatus == "" && lrAgent4.Status.Conditions == nil
778778
}).Should(BeTrue())
779779
})
780780
It("Should not patch the deployment", func() {

0 commit comments

Comments
 (0)