diff --git a/cmd/nginx-ingress/flags.go b/cmd/nginx-ingress/flags.go index 13d68abfb5..c4bf503e76 100644 --- a/cmd/nginx-ingress/flags.go +++ b/cmd/nginx-ingress/flags.go @@ -31,6 +31,11 @@ var ( watchNamespaces []string + watchSecretNamespace = flag.String("watch-secret-namespace", "", + `Comma separated list of namespaces the Ingress Controller should watch for secrets. If this arg is not configured, the Ingress Controller watches the same namespaces for all resources. See "watch-namespace". `) + + watchSecretNamespaces []string + nginxConfigMaps = flag.String("nginx-configmaps", "", `A ConfigMap resource for customizing NGINX configuration. If a ConfigMap is set, but the Ingress Controller is not able to fetch it from Kubernetes API, the Ingress Controller will fail to start. @@ -188,6 +193,16 @@ func parseFlags() { initialChecks() watchNamespaces = strings.Split(*watchNamespace, ",") + glog.Infof("Namespaces watched: %v", watchNamespaces) + + if len(*watchSecretNamespace) > 0 { + watchSecretNamespaces = strings.Split(*watchSecretNamespace, ",") + } else { + // empty => default to watched namespaces + watchSecretNamespaces = watchNamespaces + } + + glog.Infof("Namespaces watched for secrets: %v", watchSecretNamespaces) validationChecks() @@ -297,6 +312,11 @@ func validationChecks() { glog.Fatalf("Invalid values for namespaces: %v", namespacesNameValidationError) } + namespacesNameValidationError = validateNamespaceNames(watchSecretNamespaces) + if namespacesNameValidationError != nil { + glog.Fatalf("Invalid values for secret namespaces: %v", namespacesNameValidationError) + } + statusPortValidationError := validatePort(*nginxStatusPort) if statusPortValidationError != nil { glog.Fatalf("Invalid value for nginx-status-port: %v", statusPortValidationError) diff --git a/cmd/nginx-ingress/main.go b/cmd/nginx-ingress/main.go index ef7f48e850..3c2bd743d6 100644 --- a/cmd/nginx-ingress/main.go +++ b/cmd/nginx-ingress/main.go @@ -53,7 +53,9 @@ func main() { validateIngressClass(kubeClient) - checkNamespaceExists(kubeClient) + checkNamespaceExists(kubeClient, watchNamespaces) + + checkNamespaceExists(kubeClient, watchSecretNamespaces) dynClient, confClient := createCustomClients(config) @@ -127,6 +129,7 @@ func main() { RestConfig: config, ResyncPeriod: 30 * time.Second, Namespace: watchNamespaces, + SecretNamespace: watchSecretNamespaces, NginxConfigurator: cnf, DefaultServerSecret: *defaultServerSecret, AppProtectEnabled: *appProtect, @@ -240,8 +243,8 @@ func validateIngressClass(kubeClient kubernetes.Interface) { } } -func checkNamespaceExists(kubeClient kubernetes.Interface) { - for _, ns := range watchNamespaces { +func checkNamespaceExists(kubeClient kubernetes.Interface, namespaces []string) { + for _, ns := range namespaces { if ns != "" { _, err := kubeClient.CoreV1().Namespaces().Get(context.TODO(), ns, meta_v1.GetOptions{}) if err != nil { diff --git a/deployments/helm-chart/README.md b/deployments/helm-chart/README.md index bbac839578..65a402e799 100644 --- a/deployments/helm-chart/README.md +++ b/deployments/helm-chart/README.md @@ -187,6 +187,7 @@ Parameter | Description | Default `controller.ingressClass` | A class of the Ingress Controller. An IngressClass resource with the name equal to the class must be deployed. Otherwise, the Ingress Controller will fail to start. The Ingress Controller only processes resources that belong to its class - i.e. have the "ingressClassName" field resource equal to the class. The Ingress Controller processes all the VirtualServer/VirtualServerRoute/TransportServer resources that do not have the "ingressClassName" field for all versions of kubernetes. | nginx `controller.setAsDefaultIngress` | New Ingresses without an `"ingressClassName"` field specified will be assigned the class specified in `controller.ingressClass`. | false `controller.watchNamespace` | Comma separated list of namespaces the Ingress Controller should watch for resources. By default the Ingress Controller watches all namespaces. Please note that if configuring multiple namespaces using the Helm cli `--set` option, the string needs to wrapped in double quotes and the commas escaped using a backslash - e.g. `--set controller.watchNamespace="default\,nginx-ingress"`. | "" +`controller.watchSecretNamespace` | Comma separated list of namespaces the Ingress Controller should watch for resources of type Secret. If this arg is not configured, the Ingress Controller watches the same namespaces for all resources. See `watch-namespace`. Please note that if configuring multiple namespaces using the Helm cli `--set` option, the string needs to wrapped in double quotes and the commas escaped using a backslash - e.g. `--set controller.watchSecretNamespace="default\,nginx-ingress"`. | "" `controller.enableCustomResources` | Enable the custom resources. | true `controller.enablePreviewPolicies` | Enable preview policies. This parameter is deprecated. To enable OIDC Policies please use `controller.enableOIDC` instead. | false `controller.enableOIDC` | Enable OIDC policies. | false diff --git a/deployments/helm-chart/templates/controller-daemonset.yaml b/deployments/helm-chart/templates/controller-daemonset.yaml index 6a109bfe1c..7b311fa2d8 100644 --- a/deployments/helm-chart/templates/controller-daemonset.yaml +++ b/deployments/helm-chart/templates/controller-daemonset.yaml @@ -163,6 +163,9 @@ spec: - -ingress-class={{ .Values.controller.ingressClass }} {{- if .Values.controller.watchNamespace }} - -watch-namespace={{ .Values.controller.watchNamespace }} +{{- end }} +{{- if .Values.controller.watchSecretNamespace }} + - -watch-secret-namespace={{ .Values.controller.watchSecretNamespace }} {{- end }} - -health-status={{ .Values.controller.healthStatus }} - -health-status-uri={{ .Values.controller.healthStatusURI }} diff --git a/deployments/helm-chart/templates/controller-deployment.yaml b/deployments/helm-chart/templates/controller-deployment.yaml index ba1cb22ce2..9ec53bf972 100644 --- a/deployments/helm-chart/templates/controller-deployment.yaml +++ b/deployments/helm-chart/templates/controller-deployment.yaml @@ -166,6 +166,9 @@ spec: - -ingress-class={{ .Values.controller.ingressClass }} {{- if .Values.controller.watchNamespace }} - -watch-namespace={{ .Values.controller.watchNamespace }} +{{- end }} +{{- if .Values.controller.watchSecretNamespace }} + - -watch-secret-namespace={{ .Values.controller.watchSecretNamespace }} {{- end }} - -health-status={{ .Values.controller.healthStatus }} - -health-status-uri={{ .Values.controller.healthStatusURI }} diff --git a/deployments/helm-chart/values.yaml b/deployments/helm-chart/values.yaml index 984e2da311..85788bd8b8 100644 --- a/deployments/helm-chart/values.yaml +++ b/deployments/helm-chart/values.yaml @@ -186,6 +186,9 @@ controller: ## Comma separated list of namespaces to watch for Ingress resources. By default the Ingress Controller watches all namespaces. watchNamespace: "" + ## Comma separated list of namespaces to watch for Secret resources. By default the Ingress Controller watches all namespaces. + watchSecretNamespace: "" + ## Enable the custom resources. enableCustomResources: true diff --git a/docs/content/installation/installation-with-helm.md b/docs/content/installation/installation-with-helm.md index 204565bb0a..646b4a749e 100644 --- a/docs/content/installation/installation-with-helm.md +++ b/docs/content/installation/installation-with-helm.md @@ -185,6 +185,7 @@ The following tables lists the configurable parameters of the NGINX Ingress Cont |``controller.ingressClass`` | A class of the Ingress Controller. An IngressClass resource with the name equal to the class must be deployed. Otherwise, the Ingress Controller will fail to start. The Ingress Controller only processes resources that belong to its class - i.e. have the "ingressClassName" field resource equal to the class. The Ingress Controller processes all the VirtualServer/VirtualServerRoute/TransportServer resources that do not have the "ingressClassName" field for all versions of kubernetes. | nginx | |``controller.setAsDefaultIngress`` | New Ingresses without an ingressClassName field specified will be assigned the class specified in `controller.ingressClass`. | false | |``controller.watchNamespace`` | Comma separated list of namespaces the Ingress Controller should watch for resources. By default the Ingress Controller watches all namespaces. Please note that if configuring multiple namespaces using the Helm cli `--set` option, the string needs to wrapped in double quotes and the commas escaped using a backslash - e.g. ``--set controller.watchNamespace="default\,nginx-ingress"``. | "" | +|``controller.watchSecretNamespace`` | Comma separated list of namespaces the Ingress Controller should watch for resources of type Secret. If this arg is not configured, the Ingress Controller watches the same namespaces for all resources. See `watch-namespace`. Please note that if configuring multiple namespaces using the Helm cli `--set` option, the string needs to wrapped in double quotes and the commas escaped using a backslash - e.g. ``--set controller.watchSecretNamespace="default\,nginx-ingress"``. | "" | |``controller.enableCustomResources`` | Enable the custom resources. | true | |``controller.enablePreviewPolicies`` | Enable preview policies. This parameter is deprecated. To enable OIDC Policies please use ``controller.enableOIDC`` instead. | false | |``controller.enableOIDC`` | Enable OIDC policies. | false | diff --git a/internal/k8s/controller.go b/internal/k8s/controller.go index cf5a9d4e5b..64822d1d62 100644 --- a/internal/k8s/controller.go +++ b/internal/k8s/controller.go @@ -150,6 +150,7 @@ type LoadBalancerController struct { leaderElectionLockName string resync time.Duration namespaceList []string + secretNamespaceList []string controllerNamespace string wildcardTLSSecret string areCustomResourcesEnabled bool @@ -184,6 +185,7 @@ type NewLoadBalancerControllerInput struct { RestConfig *rest.Config ResyncPeriod time.Duration Namespace []string + SecretNamespace []string NginxConfigurator *configs.Configurator DefaultServerSecret string AppProtectEnabled bool @@ -234,6 +236,7 @@ func NewLoadBalancerController(input NewLoadBalancerControllerInput) *LoadBalanc leaderElectionLockName: input.LeaderElectionLockName, resync: input.ResyncPeriod, namespaceList: input.Namespace, + secretNamespaceList: input.SecretNamespace, controllerNamespace: input.ControllerNamespace, wildcardTLSSecret: input.WildcardTLSSecret, areCustomResourcesEnabled: input.AreCustomResourcesEnabled, @@ -297,7 +300,7 @@ func NewLoadBalancerController(input NewLoadBalancerControllerInput) *LoadBalanc } // Creating a separate informer for secrets. - for _, ns := range lbc.namespaceList { + for _, ns := range lbc.secretNamespaceList { lbc.secretInformerFactory = append(lbc.secretInformerFactory, informers.NewSharedInformerFactoryWithOptions(lbc.client, input.ResyncPeriod, informers.WithNamespace(ns), informers.WithTweakListOptions(secretsTweakListOptionsFunc))) }