Skip to content

Commit a6c09fa

Browse files
committed
MYSQLCLUSTER-8824 Support multiple OLM install modes
Enhanced NDB Operator to support multiple OLM install modes: - All Namespaces: Cluster-wide scope, allowing the NDB Operator to monitor NdbCluster resource changes across all namespaces. - Own Namespace: Limited scope, restricting the NDB Operator to monitor NdbCluster resource changes only in its own deployment namespace. - Single Namespace: Customizable scope, enabling the Ndb Operator to monitor NdbCluster resource changes in a user-specified namespace. Previously, the `-cluster-scoped` argument offered limited support for 'All Namespaces' and 'Own Namespace' modes, but lacked integration with OLM settings and proper documentation. This update introduces the `-watch-namespace` argument, which activates 'Single Namespace' mode when set with a specific namespace together with `-cluster-scoped=false`. Additionally, the implementation now seamlessly integrates with the OLM installation model by checking for the presence of the WATCH_NAMESPACE environment variable. Change-Id: I26617cf6678e4a8dde982f39d5f28eb4bbd81df7
1 parent 03fde57 commit a6c09fa

File tree

11 files changed

+87
-27
lines changed

11 files changed

+87
-27
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ kubectl apply -f https://raw.githubusercontent.com/mysql/mysql-ndb-operator/main
4747
```
4848

4949
To run the operator in a different namespace, the manifest file has to be updated before applying it to the K8s Server.
50+
To modify the install mode from the default cluster-wide scope, you can set the `-cluster-scoped` argument to `false` in the manifest file. Additionally, you can specify a custom namespace to monitor for NdbCluster resource changes using the `-watch-namespace` flag. If a namespace is provided, the NDB Operator will exclusively watch for changes within that namespace. Otherwise, it will default to monitoring the namespace where the operator itself is deployed.
5051

5152
### Verify Installation
5253

cmd/ndb-operator/main.go

+19-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020, 2023, Oracle and/or its affiliates.
1+
// Copyright (c) 2020, 2025, Oracle and/or its affiliates.
22
//
33
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
44

@@ -41,12 +41,24 @@ func main() {
4141
// Operator is running inside K8s Pods
4242
cfg, err = restclient.InClusterConfig()
4343

44-
if !config.ClusterScoped {
45-
// Operator is namespace-scoped.
46-
// Use the namespace it is deployed in to watch for changes.
47-
config.WatchNamespace, err = helpers.GetCurrentNamespace()
48-
if err != nil {
49-
klog.Fatalf("Could not get current namespace : %s", err)
44+
// First, we check if the namespace to watch is available from the environment.
45+
// Only if it could not be found, the command flags will be used.
46+
watchNamespace := helpers.GetWatchNamespaceFromEnvironment()
47+
if watchNamespace != "" {
48+
// Operator is in Single Namespace install mode
49+
klog.Infof("Getting watch namespace from environment: %s", watchNamespace)
50+
config.ClusterScoped = false
51+
config.WatchNamespace = watchNamespace
52+
} else {
53+
klog.Info("No namespace to watch found in environment. Using flags.")
54+
if !config.ClusterScoped && config.WatchNamespace == "" {
55+
// Operator is namespace-scoped.
56+
// If no namespace is specified
57+
// Use the namespace it is deployed in to watch for changes.
58+
config.WatchNamespace, err = helpers.GetCurrentNamespace()
59+
if err != nil {
60+
klog.Fatalf("Could not get current namespace : %s", err)
61+
}
5062
}
5163
}
5264
} else {

config/flags.go

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020, 2023, Oracle and/or its affiliates.
1+
// Copyright (c) 2020, 2025, Oracle and/or its affiliates.
22
//
33
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
44

@@ -23,17 +23,13 @@ var (
2323

2424
func ValidateFlags() {
2525

26-
runningInsideK8s := helpers.IsAppRunningInsideK8s()
27-
if runningInsideK8s && WatchNamespace != "" {
28-
// Ignore WatchNamespace if operator is running inside cluster
29-
klog.Warning("Ignoring option 'watch-namespace' as operator is running inside K8s Cluster")
30-
WatchNamespace = ""
31-
} else if ClusterScoped && WatchNamespace != "" {
26+
if ClusterScoped && WatchNamespace != "" {
3227
// Ignore WatchNamespace if operator is cluster-scoped
3328
klog.Warning("Ignoring option 'watch-namespace' as 'cluster-scoped' is enabled")
3429
WatchNamespace = ""
3530
}
3631

32+
runningInsideK8s := helpers.IsAppRunningInsideK8s()
3733
if !runningInsideK8s {
3834
if Kubeconfig == "" && MasterURL == "" {
3935
// Operator is running out of K8s Cluster but kubeconfig/masterURL are not specified.
@@ -56,8 +52,7 @@ func InitFlags() {
5652
flag.StringVar(&MasterURL, "master", "",
5753
"The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
5854
flag.StringVar(&WatchNamespace, "watch-namespace", "",
59-
"The namespace to be watched by the operator for NdbCluster resource changes."+
60-
"Only required if out-of-cluster.")
55+
"The namespace to be watched by the operator for NdbCluster resource changes.")
6156
flag.BoolVar(&ClusterScoped, "cluster-scoped", true, ""+
6257
"When enabled, operator looks for NdbCluster resource changes across K8s cluster.")
6358
}

deploy/charts/ndb-operator/README.md

+10-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This chart installs the NdbCluster CRD, deploys the Ndb Operator and the webhook
44

55
## License
66

7-
Copyright (c) 2021, 2024, Oracle and/or its affiliates.
7+
Copyright (c) 2021, 2025, Oracle and/or its affiliates.
88

99
License information can be found in the LICENSE file. This distribution may include materials developed by third parties. For license and attribution notices for these materials, please refer to the LICENSE file.
1010

@@ -64,16 +64,17 @@ Note that removing the NdbCluster CRD will also stop and delete any MySQL Cluste
6464

6565
## Configuration
6666

67-
The following table has the configurable options supported by the chart and their defaults.
67+
The following table lists the configurable options supported by the chart, along with their default values.
6868

69-
| Parameter | Description | Default |
70-
| ----------------------| ------------------------------------| ----------------------------|
71-
| `image` | NDB Operator image name with tag | `mysql/ndb-operator:latest` |
72-
| `imagePullPolicy` | NDB Operator image pull policy | `IfNotPresent` |
73-
| `imagePullSecretName` | NDB Operator image pull secret name | |
74-
| `clusterScoped` | Scope of the Ndb Operator.<br>If `true`, the operator is cluster-scoped and will watch for changes to any NdbCluster resource across all namespaces.<br>If `false`, the operator is namespace-scoped and will only watch for changes in the namespace it is released into. | `true`|
69+
| Parameter | Description | Default |
70+
| ----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|
71+
| `image` | The name of the NDB Operator image, including its tag. | `mysql/ndb-operator:latest` |
72+
| `imagePullPolicy` | The image pull policy for the NDB Operator. | `IfNotPresent` |
73+
| `imagePullSecretName` | The name of the secret used to authenticate image pulls for the NDB Operator. | None |
74+
| `clusterScoped` | Determines the scope of the NDB Operator.<br>When set to `true`, the operator watches for changes to any NdbCluster resource across all namespaces.<br>When set to `false`, the operator only watches for changes within its own namespace. | `true` |
75+
| `watchNamespace` | Specifies the namespace to monitor for NdbCluster resource changes.<br>This option is only applicable when `clusterScoped` is set to `false`. If not specified, the operator will only watch the namespace where it is deployed. | None |
7576

76-
These options can be set using the '–set' argument of the helm CLI.
77+
These options can be set using the '–set' argument of the Helm CLI.
7778

7879
For example, to specify a custom imagePullPolicy,
7980
```bash

deploy/charts/ndb-operator/templates/cluster-roles.yaml

+5-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ apiVersion: rbac.authorization.k8s.io/v1
3535
kind: {{$userRoleKind}}
3636
metadata:
3737
name: {{.Release.Name}}-cr
38+
{{- if .Values.watchNamespace}}
39+
namespace: {{.Values.watchNamespace}}
40+
{{- end }}
3841
rules:
3942
- apiGroups: [""]
4043
resources: ["pods"]
@@ -101,7 +104,8 @@ rules:
101104
- delete
102105

103106
- apiGroups: ["policy"]
104-
resources: ["poddisruptionbudgets"]
107+
resources:
108+
- poddisruptionbudgets
105109
verbs:
106110
- list
107111
- watch

deploy/charts/ndb-operator/templates/deployments.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,18 @@ spec:
7777
- ndb-operator
7878
args:
7979
- -cluster-scoped={{.Values.clusterScoped}}
80+
- -watch-namespace={{.Values.watchNamespace}}
8081
ports:
8182
- containerPort: 1186
8283
env:
84+
- name: CURRENT_NAMESPACE
85+
valueFrom:
86+
fieldRef:
87+
fieldPath: metadata.namespace
88+
- name: WATCH_NAMESPACE
89+
valueFrom:
90+
fieldRef:
91+
fieldPath: metadata.annotations['olm.targetNamespaces']
8392
# Expose the image name via env to the operator app
8493
- name: NDB_OPERATOR_IMAGE
8594
value: {{.Values.image}}

deploy/charts/ndb-operator/templates/rolebindings.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ kind: {{$bindingKind}}
4141
apiVersion: rbac.authorization.k8s.io/v1
4242
metadata:
4343
name: {{.Release.Name}}-crb
44+
{{- if .Values.watchNamespace }}
45+
namespace: {{.Values.watchNamespace}}
46+
{{- else }}
4447
namespace: {{.Release.Namespace}}
48+
{{- end }}
4549
roleRef:
4650
apiGroup: rbac.authorization.k8s.io
4751
kind: {{$userRoleKind}}

deploy/charts/ndb-operator/values.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ imagePullSecretName:
1010
# will be watching for NdbCluster resource changes only in the namespace
1111
# it is released into (controlled by helm's --namespace option).
1212
clusterScoped: true
13+
watchNamespace:

deploy/manifests/ndb-operator.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -2365,9 +2365,18 @@ spec:
23652365
containers:
23662366
- args:
23672367
- -cluster-scoped=true
2368+
- -watch-namespace=
23682369
command:
23692370
- ndb-operator
23702371
env:
2372+
- name: CURRENT_NAMESPACE
2373+
valueFrom:
2374+
fieldRef:
2375+
fieldPath: metadata.namespace
2376+
- name: WATCH_NAMESPACE
2377+
valueFrom:
2378+
fieldRef:
2379+
fieldPath: metadata.annotations['olm.targetNamespaces']
23712380
- name: NDB_OPERATOR_IMAGE
23722381
value: container-registry.oracle.com/mysql/community-ndb-operator:9.2.0-1.7.0
23732382
- name: NDB_OPERATOR_IMAGE_PULL_SECRET_NAME

operator_hub_bundle/patch_bundle_operatorhub.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,15 @@ spec:
155155
replaces: 1.6.0
156156
#skips: []
157157
minKubeVersion: 1.23.0
158+
installModes:
159+
- supported: true
160+
type: OwnNamespace
161+
- supported: true
162+
type: SingleNamespace
163+
- supported: false
164+
type: MultiNamespace
165+
- supported: true
166+
type: AllNamespaces
158167
keywords:
159168
- mysql
160169
- ndb

pkg/helpers/k8s_utils.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2021, 2022, Oracle and/or its affiliates.
1+
// Copyright (c) 2021, 2025, Oracle and/or its affiliates.
22
//
33
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
44

@@ -67,8 +67,23 @@ func GetServiceAddressAndPort(service *corev1.Service) (string, int32) {
6767
// GetCurrentNamespace returns the current namespace value,
6868
// on failure to fetch current namespace value it returns error.
6969
func GetCurrentNamespace() (string, error) {
70+
// First, it checks the environment for value set with CURRENT_NAMESPACE environment variable
71+
var currentNamespaceEnvVariable = "CURRENT_NAMESPACE"
72+
currentNamespace, variableFound := os.LookupEnv(currentNamespaceEnvVariable)
73+
74+
if variableFound {
75+
return currentNamespace, nil
76+
}
77+
7078
// Default namespace to be used by containers are placed in,
7179
// "/var/run/secrets/kubernetes.io/serviceaccount/namespace" file in each container
7280
namespace, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
81+
7382
return string(namespace), err
7483
}
84+
85+
func GetWatchNamespaceFromEnvironment() string {
86+
var watchNamespaceEnvVariable = "WATCH_NAMESPACE"
87+
namespace, _ := os.LookupEnv(watchNamespaceEnvVariable)
88+
return namespace
89+
}

0 commit comments

Comments
 (0)