@@ -38,8 +38,8 @@ OLSConfigReconciler.Reconcile() →
3838
3939### Resource Management
4040- ** Pattern** : Get → Check if exists → Create/Update with error wrapping
41- - ** Caching** : Uses ` r.stateCache ` for hash-based change detection
4241- ** Annotations** : Extensive use for watching/change detection
42+ - ** Utilities** : Common helpers in ` utils/ ` for resource requirements, volume permissions, etc.
4343
4444## Testing Conventions
4545
@@ -99,6 +99,10 @@ var _ = Describe("Component Name", func() {
9999- ` api/v1alpha1/olsconfig_types.go ` - Main CRD struct definitions
100100- Includes: ` LLMSpec ` , ` OLSSpec ` , ` DeploymentConfig ` , etc.
101101
102+ ### Entry Point & Configuration
103+ - ` cmd/main.go ` - Operator entry point with command-line flags and watcher configuration
104+ - Contains ` WatcherConfig ` - Declarative configuration for external resource watching
105+
102106### Tests to Check
103107- ** Unit Tests** (co-located with source):
104108 - ` internal/controller/*_test.go ` - Main controller tests
@@ -210,18 +214,120 @@ var _ = Describe("<Component> Name", func() {
210214
211215## State Management
212216
213- ### Hash-Based Change Detection
217+ ### ResourceVersion-Based Change Detection
218+
219+ The operator uses Kubernetes' built-in ResourceVersion tracking for owned resources:
220+
214221``` go
215- r.stateCache [OLSConfigHashStateCacheKey] = configHash
216- r.stateCache [LLMProviderHashStateCacheKey] = providerHash
222+ // Owned resources are tracked automatically by controller-runtime
223+ // Changes detected via ResourceVersion comparison
224+ deployment := &appsv1.Deployment {}
225+ err := r.Get (ctx, types.NamespacedName {Name: deploymentName}, deployment)
226+ // ResourceVersion changes automatically trigger reconciliation
217227```
218228
229+ ### Multi-Level Watcher System
230+
231+ The operator implements a sophisticated ** three-layer watching architecture** for external resources:
232+
233+ ** Layer 1: Predicate Filtering (Performance)**
234+ - Fast O(1) checks at Kubernetes watch level
235+ - Filters 99% of irrelevant events before processing
236+ - Methods: ` shouldWatchSecret() ` , ` shouldWatchConfigMap() `
237+
238+ ** Layer 2: Data Comparison (Correctness)**
239+ - Deep comparison using ` apiequality.Semantic.DeepEqual() `
240+ - Only triggers on actual data changes, not metadata
241+ - Handlers: ` SecretUpdateHandler ` , ` ConfigMapUpdateHandler `
242+ - Handles Create events for recreated resources (with owner filtering)
243+ - Skips operator-owned resources managed via ` Owns() ` relationship
244+
245+ ** Layer 3: Restart Logic (Business)**
246+ - Data-driven configuration via ` WatcherConfig `
247+ - Maps resources to affected deployments
248+ - Backend-aware restart decisions
249+
250+ ### Watcher Configuration
251+
252+ All watcher behavior is centralized in ` cmd/main.go ` via ` WatcherConfig ` :
253+
254+ ``` go
255+ watcherConfig := &utils.WatcherConfig {
256+ Secrets : utils.SecretWatcherConfig {
257+ SystemResources: []utils.SystemSecret {
258+ {Name: " pull-secret" , Namespace: " openshift-config" ,
259+ AffectedDeployments: []string {" console-ui" }},
260+ },
261+ },
262+ ConfigMaps : utils.ConfigMapWatcherConfig {
263+ SystemResources: []utils.SystemConfigMap {
264+ {Name: " kube-root-ca.crt" ,
265+ AffectedDeployments: []string {" ACTIVE_BACKEND" }},
266+ },
267+ },
268+ }
269+ ```
270+
271+ ** Key Features:**
272+ - No hardcoded resource names in watcher logic
273+ - Easy to extend (just update configuration)
274+ - ` ACTIVE_BACKEND ` placeholder auto-resolves based on ` --enable-lcore ` flag
275+
219276### Reconciliation Triggers
220- - Config changes (detected via hash comparison)
221- - Secret updates (via annotations + ` watchers ` package)
222- - ConfigMap updates (via annotations + ` watchers ` package, triggers rolling restarts)
223- - Resource deletions/modifications
224- - Telemetry pull secret changes (special watcher)
277+
278+ - ** Config changes** : ResourceVersion comparison on OLSConfig CR
279+ - ** Owned resource changes** : Automatic via controller-runtime
280+ - ** External secret updates** : Multi-level watcher with annotation + data comparison
281+ - ** External configmap updates** : Multi-level watcher with annotation + data comparison + rolling restarts
282+ - ** System resources** : Watched by name (telemetry pull secret, OpenShift CA certs)
283+
284+ ### Resource Annotation Flow
285+
286+ 1 . User creates external resource (secret/configmap) referenced in OLSConfig
287+ 2 . ` annotateExternalResources() ` runs between Phase 1 & Phase 2
288+ 3 . Annotation ` ols.openshift.io/watch-olsconfig: "cluster" ` added
289+ 4 . Watchers activate via predicate layer
290+ 5 . Future changes trigger Layer 2 data comparison → Layer 3 restart logic
291+
292+ ### External Resource Iteration Pattern
293+
294+ For processing external secrets and configmaps referenced in the CR, use iterator functions:
295+
296+ ``` go
297+ // Iterate over all external secrets referenced in CR
298+ err := utils.ForEachExternalSecret (cr, func (name string , source string ) error {
299+ // Process secret: name = secret name, source = CR field path
300+ return nil
301+ })
302+
303+ // Iterate over all external configmaps referenced in CR
304+ err := utils.ForEachExternalConfigMap (cr, func (name string , source string ) error {
305+ // Process configmap: name = configmap name, source = CR field path
306+ return nil
307+ })
308+ ```
309+
310+ ** Benefits:**
311+ - Centralizes CR traversal logic
312+ - Prevents duplicate code across watchers, annotation, and asset generation
313+ - Supports early termination via error return
314+ - Provides source tracking for debugging
315+
316+ ## Common Utility Functions
317+
318+ ### Volume Permissions
319+ ``` go
320+ utils.VolumeDefaultMode = int32 (420 ) // 0644 - Standard readable permissions
321+ utils.VolumeRestrictedMode = int32 (0600 ) // 0600 - Secure, owner-only access
322+ ```
323+
324+ ### Resource Requirements
325+ ``` go
326+ // Returns custom resources from CR if specified, otherwise returns defaults
327+ resources := utils.GetResourcesOrDefault (cr.Spec .Component .Resources , defaultResources)
328+ ```
329+
330+
225331
226332## Token-Efficient Debugging Tips
227333
0 commit comments