Skip to content

Commit

Permalink
Add FeatureGate framework to handle new features
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
  • Loading branch information
ArangoGutierrez committed Mar 14, 2024
1 parent 52d4337 commit 9e54f44
Show file tree
Hide file tree
Showing 21 changed files with 879 additions and 88 deletions.
12 changes: 7 additions & 5 deletions cmd/nfd-master/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"k8s.io/klog/v2"
klogutils "sigs.k8s.io/node-feature-discovery/pkg/utils/klog"

"sigs.k8s.io/node-feature-discovery/pkg/features"
master "sigs.k8s.io/node-feature-discovery/pkg/nfd-master"
"sigs.k8s.io/node-feature-discovery/pkg/utils"
"sigs.k8s.io/node-feature-discovery/pkg/version"
Expand All @@ -42,6 +43,12 @@ func main() {
printVersion := flags.Bool("version", false, "Print version and exit.")

args, overrides := initFlags(flags)
// Add FeatureGates flag
if err := utils.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates); err != nil {
klog.ErrorS(err, "failed to add default feature gates")
os.Exit(1)
}
utils.NFDMutableFeatureGate.AddFlag(flags)

_ = flags.Parse(os.Args[1:])
if len(flags.Args()) > 0 {
Expand Down Expand Up @@ -74,8 +81,6 @@ func main() {
args.Overrides.ResyncPeriod = overrides.ResyncPeriod
case "nfd-api-parallelism":
args.Overrides.NfdApiParallelism = overrides.NfdApiParallelism
case "enable-nodefeature-api":
klog.InfoS("-enable-nodefeature-api is deprecated, will be removed in a future release along with the deprecated gRPC API")
case "ca-file":
klog.InfoS("-ca-file is deprecated, will be removed in a future release along with the deprecated gRPC API")
case "cert-file":
Expand Down Expand Up @@ -134,9 +139,6 @@ func initFlags(flagset *flag.FlagSet) (*master.Args, *master.ConfigOverrideArgs)
"Config file to use.")
flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
"Kubeconfig to use")
flagset.BoolVar(&args.EnableNodeFeatureApi, "enable-nodefeature-api", true,
"Enable the NodeFeature CRD API for receiving node features. This will automatically disable the gRPC communication."+
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
flagset.BoolVar(&args.CrdController, "featurerules-controller", true,
"Enable NFD CRD API controller. DEPRECATED: use -crd-controller instead")
flagset.BoolVar(&args.CrdController, "crd-controller", true,
Expand Down
10 changes: 7 additions & 3 deletions cmd/nfd-worker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"k8s.io/klog/v2"
klogutils "sigs.k8s.io/node-feature-discovery/pkg/utils/klog"

"sigs.k8s.io/node-feature-discovery/pkg/features"
worker "sigs.k8s.io/node-feature-discovery/pkg/nfd-worker"
"sigs.k8s.io/node-feature-discovery/pkg/utils"
"sigs.k8s.io/node-feature-discovery/pkg/version"
Expand Down Expand Up @@ -87,6 +88,12 @@ func main() {

func parseArgs(flags *flag.FlagSet, osArgs ...string) *worker.Args {
args, overrides := initFlags(flags)
// Add FeatureGates flag
if err := utils.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates); err != nil {
klog.ErrorS(err, "failed to add default feature gates")
os.Exit(1)
}
utils.NFDMutableFeatureGate.AddFlag(flags)

_ = flags.Parse(osArgs)
if len(flags.Args()) > 0 {
Expand Down Expand Up @@ -124,9 +131,6 @@ func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs)
flagset.StringVar(&args.KeyFile, "key-file", "",
"Private key matching -cert-file."+
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
flagset.BoolVar(&args.EnableNodeFeatureApi, "enable-nodefeature-api", true,
"Enable the NodeFeature CRD API for communicating with nfd-master. This will automatically disable the gRPC communication."+
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
"Kubeconfig to use")
flagset.BoolVar(&args.Oneshot, "oneshot", false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ rules:
- update
{{- end }}

{{- if and .Values.gc.enable .Values.gc.rbac.create (or .Values.enableNodeFeatureApi .Values.topologyUpdater.enable) }}
{{- if and .Values.gc.enable .Values.gc.rbac.create (or .Values.featureGates.NodeFeatureApi .Values.topologyUpdater.enable) }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ subjects:
namespace: {{ include "node-feature-discovery.namespace" . }}
{{- end }}

{{- if and .Values.gc.enable .Values.gc.rbac.create (or .Values.enableNodeFeatureApi .Values.topologyUpdater.enable) }}
{{- if and .Values.gc.enable .Values.gc.rbac.create (or .Values.featureGates.NodeFeatureApi .Values.topologyUpdater.enable) }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down
7 changes: 5 additions & 2 deletions deployment/helm/node-feature-discovery/templates/master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ spec:
{{- if .Values.master.instance | empty | not }}
- "-instance={{ .Values.master.instance }}"
{{- end }}
{{- if not .Values.enableNodeFeatureApi }}
{{- if not .Values.featureGates.NodeFeatureApi }}
- "-port={{ .Values.master.port | default "8080" }}"
- "-enable-nodefeature-api=false"
{{- else if gt (int .Values.master.replicaCount) 1 }}
- "-enable-leader-election"
{{- end }}
Expand Down Expand Up @@ -111,6 +110,10 @@ spec:
- "-key-file=/etc/kubernetes/node-feature-discovery/certs/tls.key"
- "-cert-file=/etc/kubernetes/node-feature-discovery/certs/tls.crt"
{{- end }}
# Go over .Values.featureGates and create a list of feature gates
{{- range $key, $value := .Values.featureGates }}
- "-feature-gates={{ $key }}={{ $value }}"
{{- end }}
- "-metrics={{ .Values.master.metricsPort | default "8081" }}"
volumeMounts:
{{- if .Values.tls.enable }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gc.enable (or .Values.enableNodeFeatureApi .Values.topologyUpdater.enable) -}}
{{- if and .Values.gc.enable (or .Values.featureGates.NodeFeatureApi .Values.topologyUpdater.enable) -}}
apiVersion: apps/v1
kind: Deployment
metadata:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and (not .Values.enableNodeFeatureApi) .Values.master.enable }}
{{- if and (not .Values.featureGates.NodeFeatureApi) .Values.master.enable }}
apiVersion: v1
kind: Service
metadata:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ metadata:
{{- end }}
{{- end }}

{{- if and .Values.gc.enable .Values.gc.serviceAccount.create (or .Values.enableNodeFeatureApi .Values.topologyUpdater.enable) }}
{{- if and .Values.gc.enable .Values.gc.serviceAccount.create (or .Values.featureGates.NodeFeatureApi .Values.topologyUpdater.enable) }}
---
apiVersion: v1
kind: ServiceAccount
Expand Down
7 changes: 5 additions & 2 deletions deployment/helm/node-feature-discovery/templates/worker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,18 @@ spec:
command:
- "nfd-worker"
args:
{{- if not .Values.enableNodeFeatureApi }}
{{- if not .Values.featureGates.NodeFeatureApi }}
- "-server={{ include "node-feature-discovery.fullname" . }}-master:{{ .Values.master.service.port }}"
- "-enable-nodefeature-api=false"
{{- end }}
{{- if .Values.tls.enable }}
- "-ca-file=/etc/kubernetes/node-feature-discovery/certs/ca.crt"
- "-key-file=/etc/kubernetes/node-feature-discovery/certs/tls.key"
- "-cert-file=/etc/kubernetes/node-feature-discovery/certs/tls.crt"
{{- end }}
# Go over .Values.featureGates and create a list of feature gates
{{- range $key, $value := .Values.featureGates }}
- "-feature-gates={{ $key }}={{ $value }}"
{{- end }}
- "-metrics={{ .Values.worker.metricsPort | default "8081"}}"
ports:
- name: metrics
Expand Down
3 changes: 2 additions & 1 deletion deployment/helm/node-feature-discovery/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ nameOverride: ""
fullnameOverride: ""
namespaceOverride: ""

enableNodeFeatureApi: true
featureGates:
NodeFeatureApi: true

priorityClassName: ""

Expand Down
2 changes: 1 addition & 1 deletion docs/deployment/helm.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Chart parameters are available.
| `tls.certManager` | bool | false | If enabled, requires [cert-manager](https://cert-manager.io/docs/) to be installed and will automatically create the required TLS certificates. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `tls.certManager.certManagerCertificate.issuerName` | string | | If specified, it will use a pre-existing issuer instead for the required TLS certificates. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `tls.certManager.certManagerCertificate.issuerKind` | string | | Specifies on what kind of issuer is used, can be either ClusterIssuer or Issuer (default). Requires `tls.certManager.certManagerCertificate.issuerName` to be set. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `enableNodeFeatureApi`| bool | true | Enable the [NodeFeature](../usage/custom-resources.md#nodefeature) CRD API for communicating node features. This will automatically disable the gRPC communication. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `featureGate.NodeFeatureApi`| bool | true | Enable the [NodeFeature](../usage/custom-resources.md#nodefeature) CRD API for communicating node features. This will automatically disable the gRPC communication. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `prometheus.enable` | bool | false | Specifies whether to expose metrics using prometheus operator |
| `prometheus.labels` | dict | {} | Specifies labels for use with the prometheus operator to control how it is selected |
| `priorityClassName` | string | | The name of the PriorityClass to be used for the NFD pods. |
Expand Down
23 changes: 23 additions & 0 deletions docs/reference/feature-gates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: "Feature Gates"
layout: default
sort: 10
---

# Feature Gates
{: .no_toc}

---

Feature gates are a set of key-value pairs that control the behavior of NFD.
They are used to enable or disable certain features of NFD.
The feature gates are set using the `-feature-gates` command line flag or
Helm values.featureGates. The following feature gates are available:

- `NodeFeatureApi`: Enable the NodeFeature API. When enabled, NFD uses the
NodeFeature API to communicate feature data between NFD master and worker
instances. When disabled, NFD uses gRPC to communicate feature data between
NFD master and worker instances. The NodeFeature API is the recommended
method for communicating feature data between NFD master and worker instances.
The gRPC method is deprecated and will be removed in a future release.
Default: `true`
30 changes: 12 additions & 18 deletions docs/reference/master-commandline-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ Print usage and exit.

Print version and exit.

### -feature-gates

The `-feature-gates` flag is used to enable or disable non GA features.
The list of available feature gates can be found in the [feature gates
documentation](../feature-gates.md).

Example:

```bash
nfd-master -feature-gates NodeFeatureApi=false
```

### -prune

The `-prune` flag is a sub-command like option for cleaning up the cluster. It
Expand Down Expand Up @@ -163,24 +175,6 @@ nfd-master -verify-node-name -ca-file=/opt/nfd/ca.crt \
-cert-file=/opt/nfd/master.crt -key-file=/opt/nfd/master.key
```

### -enable-nodefeature-api

> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-enable-nodefeature-api` flag enables/disables the
[NodeFeature](../usage/custom-resources.md#nodefeature) CRD API for receiving
feature requests. This will also automatically disable/enable the gRPC
interface.

Default: true

Example:

```bash
nfd-master -enable-nodefeature-api=false
```

### -enable-leader-election

The `-enable-leader-election` flag enables leader election for NFD-Master.
Expand Down
32 changes: 12 additions & 20 deletions docs/reference/worker-commandline-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ Print usage and exit.

Print version and exit.

### -feature-gates

The `-feature-gates` flag is used to enable or disable non GA features.
The list of available feature gates can be found in the [feature gates
documentation](../feature-gates.md).

Example:

```bash
nfd-master -feature-gates NodeFeatureApi=false
```

### -config

The `-config` flag specifies the path of the nfd-worker configuration file to
Expand Down Expand Up @@ -210,26 +222,6 @@ Example:
nfd-worker -label-sources=kernel,system,local
```

### -enable-nodefeature-api

> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-enable-nodefeature-api` flag enables/disables the
[NodeFeature](../usage/custom-resources.md#nodefeature) CRD API
for communicating with nfd-master. When enabled nfd-worker creates per-node
NodeFeature objects the contain all discovered node features and the set of
feature labels to be created. Setting the flag to false will enable
gRPC communication to nfd-master.

Default: true

Example:

```bash
nfd-worker -enable-nodefeature-api=false
```

### -metrics

The `-metrics` flag specifies the port on which to expose
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/nfd-gc.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ default garbage collector interval is set to 1h which is the value when no

In Helm deployments (see
[garbage collector parameters](../deployment/helm.md#garbage-collector-parameters))
NFD-GC will only be deployed when `enableNodeFeatureApi` or
NFD-GC will only be deployed when `featureGates.NodeFeatureApi` or
`topologyUpdater.enable` is set to true.
4 changes: 2 additions & 2 deletions docs/usage/nfd-master.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ received from nfd-worker instances through
[NodeFeature](custom-resources.md#nodefeature-custom-resource) objects.

> **NOTE**: when gRPC (**DEPRECATED**) is used for communicating
> the features (by setting the flag `-enable-nodefeature-api=false` on both
> nfd-master and nfd-worker, or via Helm values.enableNodeFeatureApi=false),
> the features (by setting the flag `-feature-gates NodeFeatureApi=false` on both
> nfd-master and nfd-worker, or via Helm values.featureGates.NodeFeatureApi=false),
> (re-)labelling only happens when a request is received from nfd-worker.
> That is, in practice rules are evaluated and labels for each node are created
> on intervals specified by the
Expand Down
29 changes: 29 additions & 0 deletions pkg/features/features.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package features

import (
utils "sigs.k8s.io/node-feature-discovery/pkg/utils"
)

const (
NodeFeatureAPI utils.Feature = "NodeFeatureApi"
)

var DefaultNFDFeatureGates = map[utils.Feature]utils.FeatureSpec{
NodeFeatureAPI: {Default: true, PreRelease: utils.Deprecated},
}
Loading

0 comments on commit 9e54f44

Please sign in to comment.