Skip to content

Commit a3c5a9e

Browse files
committed
Dynamic controller namespace
Signed-off-by: jyejare <[email protected]>
1 parent 5f99d38 commit a3c5a9e

File tree

3 files changed

+66
-46
lines changed

3 files changed

+66
-46
lines changed

infra/feast-operator/docs/namespace-registry.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ This implementation addresses the following requirements from [RHOAIENG-33698](h
2222

2323
### ConfigMap Structure
2424

25-
The namespace registry ConfigMap (`feast-namespace-registry`) contains the following data:
25+
The namespace registry ConfigMap (`feast-configs-registry`) contains the following data:
2626

2727
```json
2828
{
@@ -44,10 +44,10 @@ External applications can discover Feast instances by:
4444
1. Reading the ConfigMap from the appropriate namespace:
4545
```bash
4646
# For OpenShift
47-
kubectl get configmap feast-namespace-registry -n redhat-ods-applications -o jsonpath='{.data.namespaces}'
47+
kubectl get configmap feast-configs-registry -n redhat-ods-applications -o jsonpath='{.data.namespaces}'
4848

4949
# For Kubernetes
50-
kubectl get configmap feast-namespace-registry -n feast-operator-system -o jsonpath='{.data.namespaces}'
50+
kubectl get configmap feast-configs-registry -n feast-operator-system -o jsonpath='{.data.namespaces}'
5151
```
5252

5353
### Lifecycle Management

infra/feast-operator/internal/controller/services/namespace_registry.go

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package services
1919
import (
2020
"encoding/json"
2121
"fmt"
22+
"os"
2223

2324
corev1 "k8s.io/api/core/v1"
2425
rbacv1 "k8s.io/api/rbac/v1"
@@ -51,7 +52,10 @@ func (feast *FeastServices) createNamespaceRegistryConfigMap() error {
5152
logger := log.FromContext(feast.Handler.Context)
5253

5354
// Determine the target namespace based on platform
54-
targetNamespace := feast.getNamespaceRegistryNamespace()
55+
targetNamespace, err := feast.getNamespaceRegistryNamespace()
56+
if err != nil {
57+
return fmt.Errorf("failed to get namespace registry namespace: %w", err)
58+
}
5559

5660
cm := &corev1.ConfigMap{
5761
ObjectMeta: metav1.ObjectMeta{
@@ -133,7 +137,10 @@ func (feast *FeastServices) setNamespaceRegistryConfigMap(cm *corev1.ConfigMap)
133137
func (feast *FeastServices) createNamespaceRegistryRoleBinding() error {
134138
logger := log.FromContext(feast.Handler.Context)
135139

136-
targetNamespace := feast.getNamespaceRegistryNamespace()
140+
targetNamespace, err := feast.getNamespaceRegistryNamespace()
141+
if err != nil {
142+
return fmt.Errorf("failed to get namespace registry namespace: %w", err)
143+
}
137144

138145
roleBinding := &rbacv1.RoleBinding{
139146
ObjectMeta: metav1.ObjectMeta{
@@ -182,7 +189,7 @@ func (feast *FeastServices) setNamespaceRegistryRoleBinding(rb *rbacv1.RoleBindi
182189
Verbs: []string{"get", "list"},
183190
},
184191
}
185-
role.Labels = feast.getLabels()
192+
186193
return nil
187194
})); err != nil {
188195
return err
@@ -203,22 +210,27 @@ func (feast *FeastServices) setNamespaceRegistryRoleBinding(rb *rbacv1.RoleBindi
203210
},
204211
}
205212

206-
rb.Labels = feast.getLabels()
207-
208213
return nil
209214
}
210215

211216
// getNamespaceRegistryNamespace determines the target namespace for the namespace registry ConfigMap
212-
func (feast *FeastServices) getNamespaceRegistryNamespace() string {
217+
func (feast *FeastServices) getNamespaceRegistryNamespace() (string, error) {
213218
// Check if we're running on OpenShift
219+
logger := log.FromContext(feast.Handler.Context)
214220
if IsOpenShiftForNamespaceRegistry() {
215-
// For OpenShift, use redhat-ods-applications or check for DSCi configuration
216-
// For now, we'll use the default OpenShift namespace
217221
// TODO: Add support for reading DSCi configuration
218-
return DefaultOpenShiftNamespace
222+
if data, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
223+
if ns := string(data); len(ns) > 0 {
224+
logger.V(1).Info("Using OpenShift namespace", "namespace", ns)
225+
return ns, nil
226+
}
227+
}
228+
// This is what notebook controller team is doing, we are following them
229+
// They are not defaulting to redhat-ods-applications namespace
230+
return "", fmt.Errorf("unable to determine the namespace")
219231
}
220232

221-
return DefaultKubernetesNamespace
233+
return DefaultKubernetesNamespace, nil
222234
}
223235

224236
// IsOpenShiftForNamespaceRegistry returns true if the operator is running on OpenShift
@@ -229,11 +241,14 @@ func IsOpenShiftForNamespaceRegistry() bool {
229241
// RemoveFromNamespaceRegistry removes a feature store instance from the namespace registry
230242
func (feast *FeastServices) AddToNamespaceRegistry() error {
231243
logger := log.FromContext(feast.Handler.Context)
232-
targetNamespace := feast.getNamespaceRegistryNamespace()
244+
targetNamespace, err := feast.getNamespaceRegistryNamespace()
245+
if err != nil {
246+
return fmt.Errorf("failed to get namespace registry namespace: %w", err)
247+
}
233248

234249
// Get the existing ConfigMap
235250
cm := &corev1.ConfigMap{}
236-
err := feast.Handler.Client.Get(feast.Handler.Context, types.NamespacedName{
251+
err = feast.Handler.Client.Get(feast.Handler.Context, types.NamespacedName{
237252
Name: NamespaceRegistryConfigMapName,
238253
Namespace: targetNamespace,
239254
}, cm)
@@ -312,15 +327,17 @@ func (feast *FeastServices) RemoveFromNamespaceRegistry() error {
312327
logger := log.FromContext(feast.Handler.Context)
313328

314329
// Determine the target namespace based on platform
315-
targetNamespace := feast.getNamespaceRegistryNamespace()
330+
targetNamespace, err := feast.getNamespaceRegistryNamespace()
331+
if err != nil {
332+
return fmt.Errorf("failed to get namespace registry namespace: %w", err)
333+
}
316334

317335
// Get the existing ConfigMap
318336
cm := &corev1.ConfigMap{}
319-
err := feast.Handler.Client.Get(feast.Handler.Context, client.ObjectKey{
337+
err = feast.Handler.Client.Get(feast.Handler.Context, client.ObjectKey{
320338
Name: NamespaceRegistryConfigMapName,
321339
Namespace: targetNamespace,
322340
}, cm)
323-
324341
if err != nil {
325342
if apierrors.IsNotFound(err) {
326343
// ConfigMap doesn't exist, nothing to clean up
@@ -346,42 +363,45 @@ func (feast *FeastServices) RemoveFromNamespaceRegistry() error {
346363
// Remove current feature store instance from the registry
347364
featureStoreNamespace := feast.Handler.FeatureStore.Namespace
348365
clientConfigName := feast.Handler.FeatureStore.Status.ClientConfigMap
366+
featureStoreName := feast.Handler.FeatureStore.Name
367+
368+
// Generate expected client config name using the same logic as creation
369+
expectedClientConfigName := "feast-" + featureStoreName + "-client"
370+
371+
logger.Info("Removing feature store from registry",
372+
"featureStoreName", featureStoreName,
373+
"featureStoreNamespace", featureStoreNamespace,
374+
"clientConfigName", clientConfigName,
375+
"expectedClientConfigName", expectedClientConfigName)
349376

350377
if existingData.Namespaces[featureStoreNamespace] != nil {
351-
if clientConfigName != "" {
352-
// Remove the specific client config from the list
353-
var updatedConfigs []string
354-
for _, config := range existingData.Namespaces[featureStoreNamespace] {
355-
if config != clientConfigName {
356-
updatedConfigs = append(updatedConfigs, config)
357-
}
358-
}
359-
existingData.Namespaces[featureStoreNamespace] = updatedConfigs
360-
} else {
361-
// If we don't have the client config name, try to find and remove the config
362-
// that was created for this FeatureStore (it should follow the pattern: feast-{name}-client)
363-
featureStoreName := feast.Handler.FeatureStore.Name
364-
expectedClientConfigName := "feast-" + featureStoreName + "-client"
365-
logger.Info("Attempting to remove config by name pattern",
366-
"featureStoreName", featureStoreName,
367-
"expectedClientConfigName", expectedClientConfigName,
368-
"existingConfigs", existingData.Namespaces[featureStoreNamespace])
369-
var updatedConfigs []string
370-
for _, config := range existingData.Namespaces[featureStoreNamespace] {
371-
// Remove configs that match the FeatureStore name pattern
372-
if config != expectedClientConfigName {
373-
updatedConfigs = append(updatedConfigs, config)
374-
} else {
375-
logger.Info("Removing config from registry", "config", config)
376-
}
378+
var updatedConfigs []string
379+
removed := false
380+
381+
for _, config := range existingData.Namespaces[featureStoreNamespace] {
382+
// Remove if it matches the client config name or the expected pattern
383+
if config == clientConfigName || config == expectedClientConfigName {
384+
logger.Info("Removing config from registry", "config", config)
385+
removed = true
386+
} else {
387+
updatedConfigs = append(updatedConfigs, config)
377388
}
378-
existingData.Namespaces[featureStoreNamespace] = updatedConfigs
379389
}
380390

391+
existingData.Namespaces[featureStoreNamespace] = updatedConfigs
392+
381393
// If no configs left for this namespace, remove the namespace entry
382394
if len(existingData.Namespaces[featureStoreNamespace]) == 0 {
383395
delete(existingData.Namespaces, featureStoreNamespace)
396+
logger.Info("Removed empty namespace entry from registry", "namespace", featureStoreNamespace)
397+
}
398+
399+
if !removed {
400+
logger.V(1).Info("No matching config found to remove from registry",
401+
"existingConfigs", existingData.Namespaces[featureStoreNamespace])
384402
}
403+
} else {
404+
logger.V(1).Info("Namespace not found in registry", "namespace", featureStoreNamespace)
385405
}
386406

387407
// Marshal the updated data back to JSON

infra/feast-operator/internal/controller/services/services_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const (
3636
svcDomain = ".svc.cluster.local"
3737

3838
// Namespace registry ConfigMap constants
39-
NamespaceRegistryConfigMapName = "feast-namespace-registry"
39+
NamespaceRegistryConfigMapName = "feast-configs-registry"
4040
NamespaceRegistryDataKey = "namespaces"
4141
DefaultOpenShiftNamespace = "redhat-ods-applications" // TODO: make this configurable
4242
DefaultKubernetesNamespace = "feast-operator-system"

0 commit comments

Comments
 (0)