From 883001ddf188e7d8a905a69e26fbecb02f41259d Mon Sep 17 00:00:00 2001 From: Lukas Piwowarski Date: Tue, 10 Dec 2024 05:55:46 -0500 Subject: [PATCH] Change scope of test-operator to namespace Test-operator is currently designed to be a cluster scoped operator. This means it can watch and modify resources across all OCP cluster. This patch changes the operator to namespace scoped operator. By default it is going to watch only: - openstack-test-operator namespace: This is a namespace where we recommend to install the test-operator. Prior to the installation we recommend to create an OperatorGroup with targetNamespaces value set to openstack-test-operator and openstack. - openstack: This is a namespace where the openstack controll plane is deployed. Test-operator requires an access to this namespace in order to read openstack specific CMs and Secrets (e.g., clouds.yaml). Depends-On: https://github.com/openstack-k8s-operators/ci-framework/pull/2600 --- config/manager/manager.yaml | 5 ++ .../test-operator.clusterserviceversion.yaml | 2 +- config/rbac/role.yaml | 3 +- config/rbac/role_binding.yaml | 5 +- controllers/ansibletest_controller.go | 31 ++++++----- controllers/common.go | 9 ++-- controllers/horizontest_controller.go | 30 ++++++----- controllers/tempest_controller.go | 30 ++++++----- controllers/tobiko_controller.go | 31 ++++++----- main.go | 51 ++++++++++++++++++- 10 files changed, 135 insertions(+), 62 deletions(-) diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 69453a40..87be9a3f 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -101,5 +101,10 @@ spec: requests: cpu: 10m memory: 128Mi + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 diff --git a/config/manifests/bases/test-operator.clusterserviceversion.yaml b/config/manifests/bases/test-operator.clusterserviceversion.yaml index 0ba88774..d6333751 100644 --- a/config/manifests/bases/test-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/test-operator.clusterserviceversion.yaml @@ -11,7 +11,7 @@ metadata: features.operators.openshift.io/token-auth-aws: "false" features.operators.openshift.io/token-auth-azure: "false" features.operators.openshift.io/token-auth-gcp: "false" - operatorframework.io/suggested-namespace: openstack + operatorframework.io/suggested-namespace: openstack-test-operator name: test-operator.v0.0.0 namespace: placeholder spec: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index a71a020d..9253d81a 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -1,8 +1,9 @@ --- apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole +kind: Role metadata: name: manager-role + namespace: rules: - apiGroups: - "" diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml index d1692edc..a222bf9f 100644 --- a/config/rbac/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -1,5 +1,5 @@ apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: labels: app.kubernetes.io/name: clusterrolebinding @@ -11,9 +11,10 @@ metadata: name: manager-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: manager-role subjects: - kind: ServiceAccount name: controller-manager namespace: system + diff --git a/controllers/ansibletest_controller.go b/controllers/ansibletest_controller.go index c31ccc5a..e29d541d 100644 --- a/controllers/ansibletest_controller.go +++ b/controllers/ansibletest_controller.go @@ -39,6 +39,7 @@ import ( corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -51,19 +52,19 @@ func (r *AnsibleTestReconciler) GetLogger(ctx context.Context) logr.Logger { return log.FromContext(ctx).WithName("Controllers").WithName("AnsibleTest") } -// +kubebuilder:rbac:groups=test.openstack.org,resources=ansibletests,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=test.openstack.org,resources=ansibletests/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=test.openstack.org,resources=ansibletests/finalizers,verbs=update;patch -// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;patch;update;delete; -// +kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch -// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles,verbs=get;list;watch;create;update;patch -// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch -// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid;privileged;nonroot;nonroot-v2,resources=securitycontextconstraints,verbs=use -// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch -// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete; -// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch -// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,verbs=get;list;create;update;watch;patch;delete -// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=ansibletests,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=ansibletests/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=ansibletests/finalizers,verbs=update;patch +// +kubebuilder:rbac:groups=batch,namespace=,resources=jobs,verbs=get;list;watch;create;patch;update;delete; +// +kubebuilder:rbac:groups=k8s.cni.cncf.io,namespace=,resources=network-attachment-definitions,verbs=get;list;watch +// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",namespace=,resources=roles,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",namespace=,resources=rolebindings,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups="security.openshift.io",namespace=,resourceNames=anyuid;privileged;nonroot;nonroot-v2,resources=securitycontextconstraints,verbs=use +// +kubebuilder:rbac:groups="",resources=secrets,namespace=,verbs=get;list;watch +// +kubebuilder:rbac:groups="",resources=configmaps,namespace=,verbs=get;list;watch;create;update;patch;delete; +// +kubebuilder:rbac:groups="",resources=pods,namespace=,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,namespace=,verbs=get;list;create;update;watch;patch;delete +// +kubebuilder:rbac:groups="",resources=serviceaccounts,namespace=,verbs=get;list;watch;create;update;patch // Reconcile - AnsibleTest func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, _err error) { @@ -76,6 +77,7 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request) if k8s_errors.IsNotFound(err) { return ctrl.Result{}, nil } + return ctrl.Result{}, err } @@ -298,6 +300,9 @@ func (r *AnsibleTestReconciler) Reconcile(ctx context.Context, req ctrl.Request) // SetupWithManager sets up the controller with the Manager. func (r *AnsibleTestReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). + WithOptions(controller.Options{ + CacheSyncTimeout: r.CacheSyncTimeout, + }). For(&testv1beta1.AnsibleTest{}). Owns(&batchv1.Job{}). Owns(&corev1.Secret{}). diff --git a/controllers/common.go b/controllers/common.go index 4abed53b..cf3029a1 100644 --- a/controllers/common.go +++ b/controllers/common.go @@ -66,10 +66,11 @@ const ( ) type Reconciler struct { - Client client.Client - Kclient kubernetes.Interface - Log logr.Logger - Scheme *runtime.Scheme + CacheSyncTimeout time.Duration + Client client.Client + Kclient kubernetes.Interface + Log logr.Logger + Scheme *runtime.Scheme } // NextAction holds an action that should be performed by the Reconcile loop. diff --git a/controllers/horizontest_controller.go b/controllers/horizontest_controller.go index 62b8e021..840eba82 100644 --- a/controllers/horizontest_controller.go +++ b/controllers/horizontest_controller.go @@ -35,6 +35,7 @@ import ( corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -48,19 +49,19 @@ func (r *HorizonTestReconciler) GetLogger(ctx context.Context) logr.Logger { return log.FromContext(ctx).WithName("Controllers").WithName("HorizonTest") } -// +kubebuilder:rbac:groups=test.openstack.org,resources=horizontests,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=test.openstack.org,resources=horizontests/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=test.openstack.org,resources=horizontests/finalizers,verbs=update;patch -// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;patch;update;delete; -// +kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch -// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles,verbs=get;list;watch;create;update;patch -// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch -// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid;privileged;nonroot;nonroot-v2,resources=securitycontextconstraints,verbs=use -// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch -// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete; -// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch -// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,verbs=get;list;create;update;watch;patch;delete -// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=horizontests,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=horizontests/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=horizontests/finalizers,verbs=update;patch +// +kubebuilder:rbac:groups=batch,namespace=,resources=jobs,verbs=get;list;watch;create;patch;update;delete; +// +kubebuilder:rbac:groups=k8s.cni.cncf.io,namespace=,resources=network-attachment-definitions,verbs=get;list;watch +// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",namespace=,resources=roles,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",namespace=,resources=rolebindings,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups="security.openshift.io",namespace=,resourceNames=anyuid;privileged;nonroot;nonroot-v2,resources=securitycontextconstraints,verbs=use +// +kubebuilder:rbac:groups="",resources=secrets,namespace=,verbs=get;list;watch +// +kubebuilder:rbac:groups="",resources=configmaps,namespace=,verbs=get;list;watch;create;update;patch;delete; +// +kubebuilder:rbac:groups="",resources=pods,namespace=,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,namespace=,verbs=get;list;create;update;watch;patch;delete +// +kubebuilder:rbac:groups="",resources=serviceaccounts,namespace=,verbs=get;list;watch;create;update;patch // Reconcile - HorizonTest func (r *HorizonTestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, _err error) { @@ -285,6 +286,9 @@ func (r *HorizonTestReconciler) Reconcile(ctx context.Context, req ctrl.Request) // SetupWithManager sets up the controller with the Manager. func (r *HorizonTestReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). + WithOptions(controller.Options{ + CacheSyncTimeout: r.CacheSyncTimeout, + }). For(&testv1beta1.HorizonTest{}). Owns(&batchv1.Job{}). Owns(&corev1.Secret{}). diff --git a/controllers/tempest_controller.go b/controllers/tempest_controller.go index d82ff242..c38a923e 100644 --- a/controllers/tempest_controller.go +++ b/controllers/tempest_controller.go @@ -40,6 +40,7 @@ import ( corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -53,19 +54,19 @@ func (r *TempestReconciler) GetLogger(ctx context.Context) logr.Logger { return log.FromContext(ctx).WithName("Controllers").WithName("Tempest") } -// +kubebuilder:rbac:groups=test.openstack.org,resources=tempests,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=test.openstack.org,resources=tempests/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=test.openstack.org,resources=tempests/finalizers,verbs=update;patch -// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;patch;update;delete; -// +kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch -// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles,verbs=get;list;watch;create;update;patch -// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch -// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid;privileged;nonroot;nonroot-v2,resources=securitycontextconstraints,verbs=use -// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch -// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete; -// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch -// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,verbs=get;list;create;update;watch;patch;delete -// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=tempests,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=tempests/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=tempests/finalizers,verbs=update;patch +// +kubebuilder:rbac:groups=batch,resources=jobs,namespace=,verbs=get;list;watch;create;patch;update;delete; +// +kubebuilder:rbac:groups=k8s.cni.cncf.io,namespace=,resources=network-attachment-definitions,verbs=get;list;watch +// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",namespace=,resources=roles,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",namespace=,resources=rolebindings,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups="security.openshift.io",namespace=,resourceNames=anyuid;privileged;nonroot;nonroot-v2,resources=securitycontextconstraints,verbs=use +// +kubebuilder:rbac:groups="",resources=secrets,namespace=,verbs=get;list;watch +// +kubebuilder:rbac:groups="",resources=configmaps,namespace=,verbs=get;list;watch;create;update;patch;delete; +// +kubebuilder:rbac:groups="",resources=pods,namespace=,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,namespace=,verbs=get;list;create;update;watch;patch;delete +// +kubebuilder:rbac:groups="",resources=serviceaccounts,namespace=,verbs=get;list;watch;create;update;patch // Reconcile - Tempest func (r *TempestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, _err error) { @@ -424,6 +425,9 @@ func (r *TempestReconciler) reconcileDelete( // SetupWithManager sets up the controller with the Manager. func (r *TempestReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). + WithOptions(controller.Options{ + CacheSyncTimeout: r.CacheSyncTimeout, + }). For(&testv1beta1.Tempest{}). Owns(&batchv1.Job{}). Owns(&corev1.Secret{}). diff --git a/controllers/tobiko_controller.go b/controllers/tobiko_controller.go index ee602985..80b7f971 100644 --- a/controllers/tobiko_controller.go +++ b/controllers/tobiko_controller.go @@ -40,6 +40,7 @@ import ( corev1 "k8s.io/api/core/v1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -53,19 +54,19 @@ func (r *TobikoReconciler) GetLogger(ctx context.Context) logr.Logger { return log.FromContext(ctx).WithName("Controllers").WithName("Tobiko") } -// +kubebuilder:rbac:groups=test.openstack.org,resources=tobikoes,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=test.openstack.org,resources=tobikoes/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=test.openstack.org,resources=tobikoes/finalizers,verbs=update;patch -// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;patch;update;delete; -// +kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch -// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles,verbs=get;list;watch;create;update;patch -// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch -// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid;privileged;nonroot;nonroot-v2,resources=securitycontextconstraints,verbs=use -// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch -// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete; -// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch -// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,verbs=get;list;create;update;watch;patch;delete -// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=tobikoes,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=tobikoes/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=test.openstack.org,namespace=,resources=tobikoes/finalizers,verbs=update;patch +// +kubebuilder:rbac:groups=batch,namespace=,resources=jobs,verbs=get;list;watch;create;patch;update;delete; +// +kubebuilder:rbac:groups=k8s.cni.cncf.io,namespace=,resources=network-attachment-definitions,verbs=get;list;watch +// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",namespace=,resources=roles,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",namespace=,resources=rolebindings,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups="security.openshift.io",namespace=,resourceNames=anyuid;privileged;nonroot;nonroot-v2,resources=securitycontextconstraints,verbs=use +// +kubebuilder:rbac:groups="",namespace=,resources=secrets,verbs=get;list;watch +// +kubebuilder:rbac:groups="",namespace=,resources=configmaps,verbs=get;list;watch;create;update;patch;delete; +// +kubebuilder:rbac:groups="",namespace=,resources=pods,verbs=create;delete;get;list;patch;update;watch +// +kubebuilder:rbac:groups="",namespace=,resources=persistentvolumeclaims,verbs=get;list;create;update;watch;patch;delete +// +kubebuilder:rbac:groups="",namespace=,resources=serviceaccounts,verbs=get;list;watch;create;update;patch // Reconcile - Tobiko func (r *TobikoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, _err error) { @@ -77,6 +78,7 @@ func (r *TobikoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res if k8s_errors.IsNotFound(err) { return ctrl.Result{}, nil } + return ctrl.Result{}, err } @@ -374,6 +376,9 @@ func (r *TobikoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res // SetupWithManager sets up the controller with the Manager. func (r *TobikoReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). + WithOptions(controller.Options{ + CacheSyncTimeout: r.CacheSyncTimeout, + }). For(&testv1beta1.Tobiko{}). Owns(&batchv1.Job{}). Owns(&corev1.Secret{}). diff --git a/main.go b/main.go index 7a562c13..645f43bd 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,7 @@ import ( "flag" "os" "strings" + "time" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. @@ -31,6 +32,7 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -49,6 +51,10 @@ var ( setupLog = ctrl.Log.WithName("setup") ) +const ( + CacheSyncTimeout = time.Minute * 10 +) + func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(testv1beta1.AddToScheme(scheme)) @@ -56,6 +62,25 @@ func init() { //+kubebuilder:scaffold:scheme } +// getWatchNamespace returns the Namespace the operator should be watching for changes +func getWatchNamespace() ([]string, error) { + // WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE + // which specifies the Namespace to watch. + var watchNamespaceEnvVar = "WATCH_NAMESPACE" + + ns, found := os.LookupEnv(watchNamespaceEnvVar) + if !found { + defaultWatchNamespace := []string{"openstack-test-operator", "openstack"} + return defaultWatchNamespace, nil + } + + if len(ns) > 0 { + return strings.Split(ns, ","), nil + } else { + return []string{}, nil + } +} + func main() { var metricsAddr string var enableLeaderElection bool @@ -82,7 +107,7 @@ func main() { c.NextProtos = []string{"http/1.1"} } - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + ctrlOptions := ctrl.Options{ Scheme: scheme, Metrics: metricsserver.Options{ BindAddress: metricsAddr, @@ -106,7 +131,25 @@ func main() { // if you are doing or is intended to do any operation such as perform cleanups // after the manager stops then its usage might be unsafe. // LeaderElectionReleaseOnCancel: true, - }) + } + + watchNamespace, err := getWatchNamespace() + if err != nil { + setupLog.Error(err, "unable to get WatchNamespace, "+ + "the manager will watch and manage resources in all namespaces") + } + + defaultNamespaces := map[string]cache.Config{} + for _, namespace := range watchNamespace { + defaultNamespaces[namespace] = cache.Config{} + } + + if len(watchNamespace) > 0 { + ctrlOptions.Cache.DefaultNamespaces = defaultNamespaces + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrlOptions) + if err != nil { setupLog.Error(err, "unable to start manager") os.Exit(1) @@ -128,6 +171,7 @@ func main() { tempestReconciler.Client = mgr.GetClient() tempestReconciler.Scheme = mgr.GetScheme() tempestReconciler.Kclient = kclient + tempestReconciler.CacheSyncTimeout = CacheSyncTimeout if err = tempestReconciler.SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Tempest") os.Exit(1) @@ -137,6 +181,7 @@ func main() { tobikoReconciler.Client = mgr.GetClient() tobikoReconciler.Scheme = mgr.GetScheme() tobikoReconciler.Kclient = kclient + tobikoReconciler.CacheSyncTimeout = CacheSyncTimeout if err = tobikoReconciler.SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Tobiko") os.Exit(1) @@ -146,6 +191,7 @@ func main() { ansibleReconciler.Client = mgr.GetClient() ansibleReconciler.Scheme = mgr.GetScheme() ansibleReconciler.Kclient = kclient + ansibleReconciler.CacheSyncTimeout = CacheSyncTimeout if err = ansibleReconciler.SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "AnsibleTest") os.Exit(1) @@ -155,6 +201,7 @@ func main() { horizontestReconciler.Client = mgr.GetClient() horizontestReconciler.Scheme = mgr.GetScheme() horizontestReconciler.Kclient = kclient + horizontestReconciler.CacheSyncTimeout = CacheSyncTimeout if err = horizontestReconciler.SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "HorizonTest") os.Exit(1)