mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-14 11:57:51 +00:00
Drop NFD gRPC API
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
This commit is contained in:
parent
c7e7877359
commit
0bd82cf82a
30 changed files with 51 additions and 1499 deletions
|
@ -80,16 +80,6 @@ func main() {
|
||||||
args.Overrides.ResyncPeriod = overrides.ResyncPeriod
|
args.Overrides.ResyncPeriod = overrides.ResyncPeriod
|
||||||
case "nfd-api-parallelism":
|
case "nfd-api-parallelism":
|
||||||
args.Overrides.NfdApiParallelism = overrides.NfdApiParallelism
|
args.Overrides.NfdApiParallelism = overrides.NfdApiParallelism
|
||||||
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":
|
|
||||||
klog.InfoS("-cert-file is deprecated, will be removed in a future release along with the deprecated gRPC API")
|
|
||||||
case "key-file":
|
|
||||||
klog.InfoS("-key-file is deprecated, will be removed in a future release along with the deprecated gRPC API")
|
|
||||||
case "port":
|
|
||||||
klog.InfoS("-port is deprecated, will be removed in a future release along with the deprecated gRPC API")
|
|
||||||
case "verify-node-name":
|
|
||||||
klog.InfoS("-verify-node-name is deprecated, will be removed in a future release along with the deprecated gRPC API")
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -122,39 +112,18 @@ func main() {
|
||||||
func initFlags(flagset *flag.FlagSet) (*master.Args, *master.ConfigOverrideArgs) {
|
func initFlags(flagset *flag.FlagSet) (*master.Args, *master.ConfigOverrideArgs) {
|
||||||
args := &master.Args{}
|
args := &master.Args{}
|
||||||
|
|
||||||
flagset.StringVar(&args.CaFile, "ca-file", "",
|
|
||||||
"Root certificate for verifying connections."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
flagset.StringVar(&args.CertFile, "cert-file", "",
|
|
||||||
"Certificate used for authenticating connections."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
flagset.StringVar(&args.Instance, "instance", "",
|
flagset.StringVar(&args.Instance, "instance", "",
|
||||||
"Instance name. Used to separate annotation namespaces for multiple parallel deployments.")
|
"Instance name. Used to separate annotation namespaces for multiple parallel deployments.")
|
||||||
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.StringVar(&args.ConfigFile, "config", "/etc/kubernetes/node-feature-discovery/nfd-master.conf",
|
flagset.StringVar(&args.ConfigFile, "config", "/etc/kubernetes/node-feature-discovery/nfd-master.conf",
|
||||||
"Config file to use.")
|
"Config file to use.")
|
||||||
flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
|
flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
|
||||||
"Kubeconfig to use")
|
"Kubeconfig to use")
|
||||||
flagset.BoolVar(&args.CrdController, "featurerules-controller", true,
|
|
||||||
"Enable NFD CRD API controller. DEPRECATED: use -crd-controller instead")
|
|
||||||
flagset.BoolVar(&args.CrdController, "crd-controller", true,
|
|
||||||
"Enable NFD CRD API controller for processing NodeFeature and NodeFeatureRule objects."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
flagset.IntVar(&args.Port, "port", 8080,
|
|
||||||
"Port on which to listen for gRPC connections."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
flagset.IntVar(&args.MetricsPort, "metrics", 8081,
|
flagset.IntVar(&args.MetricsPort, "metrics", 8081,
|
||||||
"Port on which to expose metrics.")
|
"Port on which to expose metrics.")
|
||||||
flagset.IntVar(&args.GrpcHealthPort, "grpc-health", 8082,
|
flagset.IntVar(&args.GrpcHealthPort, "grpc-health", 8082,
|
||||||
"Port on which to expose the grpc health endpoint.")
|
"Port on which to expose the grpc health endpoint.")
|
||||||
flagset.BoolVar(&args.Prune, "prune", false,
|
flagset.BoolVar(&args.Prune, "prune", false,
|
||||||
"Prune all NFD related attributes from all nodes of the cluster and exit.")
|
"Prune all NFD related attributes from all nodes of the cluster and exit.")
|
||||||
flagset.BoolVar(&args.VerifyNodeName, "verify-node-name", false,
|
|
||||||
"Verify worker node name against the worker's TLS certificate. "+
|
|
||||||
"Only takes effect when TLS authentication has been enabled."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
flagset.StringVar(&args.Options, "options", "",
|
flagset.StringVar(&args.Options, "options", "",
|
||||||
"Specify config options from command line. Config options are specified "+
|
"Specify config options from command line. Config options are specified "+
|
||||||
"in the same format as in the config file (i.e. json or yaml). These options")
|
"in the same format as in the config file (i.e. json or yaml). These options")
|
||||||
|
|
|
@ -59,22 +59,6 @@ func main() {
|
||||||
klog.InfoS("version not set! Set -ldflags \"-X sigs.k8s.io/node-feature-discovery/pkg/version.version=`git describe --tags --dirty --always`\" during build or run.")
|
klog.InfoS("version not set! Set -ldflags \"-X sigs.k8s.io/node-feature-discovery/pkg/version.version=`git describe --tags --dirty --always`\" during build or run.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check deprecated flags
|
|
||||||
flags.Visit(func(f *flag.Flag) {
|
|
||||||
switch f.Name {
|
|
||||||
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":
|
|
||||||
klog.InfoS("-cert-file is deprecated, will be removed in a future release along with the deprecated gRPC API")
|
|
||||||
case "key-file":
|
|
||||||
klog.InfoS("-key-file is deprecated, will be removed in a future release along with the deprecated gRPC API")
|
|
||||||
case "server":
|
|
||||||
klog.InfoS("-server is deprecated, will be removed in a future release along with the deprecated gRPC API")
|
|
||||||
case "server-name-override":
|
|
||||||
klog.InfoS("-server-name-override is deprecated, will be removed in a future release along with the deprecated gRPC API")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Plug klog into grpc logging infrastructure
|
// Plug klog into grpc logging infrastructure
|
||||||
utils.ConfigureGrpcKlog()
|
utils.ConfigureGrpcKlog()
|
||||||
|
|
||||||
|
@ -119,17 +103,8 @@ func parseArgs(flags *flag.FlagSet, osArgs ...string) *worker.Args {
|
||||||
func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs) {
|
func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs) {
|
||||||
args := &worker.Args{}
|
args := &worker.Args{}
|
||||||
|
|
||||||
flagset.StringVar(&args.CaFile, "ca-file", "",
|
|
||||||
"Root certificate for verifying connections."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
flagset.StringVar(&args.CertFile, "cert-file", "",
|
|
||||||
"Certificate used for authenticating connections."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
flagset.StringVar(&args.ConfigFile, "config", "/etc/kubernetes/node-feature-discovery/nfd-worker.conf",
|
flagset.StringVar(&args.ConfigFile, "config", "/etc/kubernetes/node-feature-discovery/nfd-worker.conf",
|
||||||
"Config file to use.")
|
"Config file to use.")
|
||||||
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.StringVar(&args.Kubeconfig, "kubeconfig", "",
|
flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
|
||||||
"Kubeconfig to use")
|
"Kubeconfig to use")
|
||||||
flagset.BoolVar(&args.Oneshot, "oneshot", false,
|
flagset.BoolVar(&args.Oneshot, "oneshot", false,
|
||||||
|
@ -141,12 +116,6 @@ func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs)
|
||||||
flagset.StringVar(&args.Options, "options", "",
|
flagset.StringVar(&args.Options, "options", "",
|
||||||
"Specify config options from command line. Config options are specified "+
|
"Specify config options from command line. Config options are specified "+
|
||||||
"in the same format as in the config file (i.e. json or yaml). These options")
|
"in the same format as in the config file (i.e. json or yaml). These options")
|
||||||
flagset.StringVar(&args.Server, "server", "localhost:8080",
|
|
||||||
"NFD server address to connecto to."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
flagset.StringVar(&args.ServerNameOverride, "server-name-override", "",
|
|
||||||
"Hostname expected from server certificate, useful in testing."+
|
|
||||||
" DEPRECATED: will be removed in a future release along with the deprecated gRPC API.")
|
|
||||||
|
|
||||||
args.Klog = klogutils.InitKlogFlags(flagset)
|
args.Klog = klogutils.InitKlogFlags(flagset)
|
||||||
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
{{- if .Values.tls.certManager }}
|
|
||||||
{{- if .Values.master.enable }}
|
|
||||||
---
|
|
||||||
apiVersion: cert-manager.io/v1
|
|
||||||
kind: Certificate
|
|
||||||
metadata:
|
|
||||||
name: nfd-master-cert
|
|
||||||
namespace: {{ include "node-feature-discovery.namespace" . }}
|
|
||||||
spec:
|
|
||||||
secretName: nfd-master-cert
|
|
||||||
subject:
|
|
||||||
organizations:
|
|
||||||
- node-feature-discovery
|
|
||||||
commonName: nfd-master
|
|
||||||
dnsNames:
|
|
||||||
# must match the service name
|
|
||||||
- {{ include "node-feature-discovery.fullname" . }}-master
|
|
||||||
# first one is configured for use by the worker; below are for completeness
|
|
||||||
- {{ include "node-feature-discovery.fullname" . }}-master.{{ include "node-feature-discovery.namespace" . }}.svc
|
|
||||||
- {{ include "node-feature-discovery.fullname" . }}-master.{{ include "node-feature-discovery.namespace" . }}.svc.cluster.local
|
|
||||||
issuerRef:
|
|
||||||
name: {{ default "nfd-ca-issuer" .Values.tls.certManagerCertificate.issuerName }}
|
|
||||||
{{- if and .Values.tls.certManagerCertificate.issuerName .Values.tls.certManagerCertificate.issuerKind }}
|
|
||||||
kind: {{ .Values.tls.certManagerCertificate.issuerKind }}
|
|
||||||
{{- else }}
|
|
||||||
kind: Issuer
|
|
||||||
{{- end }}
|
|
||||||
group: cert-manager.io
|
|
||||||
{{- end }}
|
|
||||||
---
|
|
||||||
{{- if .Values.worker.enable }}
|
|
||||||
apiVersion: cert-manager.io/v1
|
|
||||||
kind: Certificate
|
|
||||||
metadata:
|
|
||||||
name: nfd-worker-cert
|
|
||||||
namespace: {{ include "node-feature-discovery.namespace" . }}
|
|
||||||
spec:
|
|
||||||
secretName: nfd-worker-cert
|
|
||||||
subject:
|
|
||||||
organizations:
|
|
||||||
- node-feature-discovery
|
|
||||||
commonName: nfd-worker
|
|
||||||
dnsNames:
|
|
||||||
- {{ include "node-feature-discovery.fullname" . }}-worker.{{ include "node-feature-discovery.namespace" . }}.svc.cluster.local
|
|
||||||
issuerRef:
|
|
||||||
name: {{ default "nfd-ca-issuer" .Values.tls.certManagerCertificate.issuerName }}
|
|
||||||
{{- if and .Values.tls.certManagerCertificate.issuerName .Values.tls.certManagerCertificate.issuerKind }}
|
|
||||||
kind: {{ .Values.tls.certManagerCertificate.issuerKind }}
|
|
||||||
{{- else }}
|
|
||||||
kind: Issuer
|
|
||||||
{{- end }}
|
|
||||||
group: cert-manager.io
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- if .Values.topologyUpdater.enable }}
|
|
||||||
---
|
|
||||||
apiVersion: cert-manager.io/v1
|
|
||||||
kind: Certificate
|
|
||||||
metadata:
|
|
||||||
name: nfd-topology-updater-cert
|
|
||||||
namespace: {{ include "node-feature-discovery.namespace" . }}
|
|
||||||
spec:
|
|
||||||
secretName: nfd-topology-updater-cert
|
|
||||||
subject:
|
|
||||||
organizations:
|
|
||||||
- node-feature-discovery
|
|
||||||
commonName: nfd-topology-updater
|
|
||||||
dnsNames:
|
|
||||||
- {{ include "node-feature-discovery.fullname" . }}-topology-updater.{{ include "node-feature-discovery.namespace" . }}.svc.cluster.local
|
|
||||||
issuerRef:
|
|
||||||
name: {{ default "nfd-ca-issuer" .Values.tls.certManagerCertificate.issuerName }}
|
|
||||||
{{- if and .Values.tls.certManagerCertificate.issuerName .Values.tls.certManagerCertificate.issuerKind }}
|
|
||||||
kind: {{ .Values.tls.certManagerCertificate.issuerKind }}
|
|
||||||
{{- else }}
|
|
||||||
kind: Issuer
|
|
||||||
{{- end }}
|
|
||||||
group: cert-manager.io
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- end }}
|
|
|
@ -1,42 +0,0 @@
|
||||||
{{- if and .Values.tls.certManager (not .Values.tls.certManagerCertificate.issuerName ) }}
|
|
||||||
# See https://cert-manager.io/docs/configuration/selfsigned/#bootstrapping-ca-issuers
|
|
||||||
# - Create a self signed issuer
|
|
||||||
# - Use this to create a CA cert
|
|
||||||
# - Use this to now create a CA issuer
|
|
||||||
---
|
|
||||||
apiVersion: cert-manager.io/v1
|
|
||||||
kind: Issuer
|
|
||||||
metadata:
|
|
||||||
name: nfd-ca-bootstrap
|
|
||||||
namespace: {{ include "node-feature-discovery.namespace" . }}
|
|
||||||
spec:
|
|
||||||
selfSigned: {}
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: cert-manager.io/v1
|
|
||||||
kind: Certificate
|
|
||||||
metadata:
|
|
||||||
name: nfd-ca-cert
|
|
||||||
namespace: {{ include "node-feature-discovery.namespace" . }}
|
|
||||||
spec:
|
|
||||||
isCA: true
|
|
||||||
secretName: nfd-ca-cert
|
|
||||||
subject:
|
|
||||||
organizations:
|
|
||||||
- node-feature-discovery
|
|
||||||
commonName: nfd-ca-cert
|
|
||||||
issuerRef:
|
|
||||||
name: nfd-ca-bootstrap
|
|
||||||
kind: Issuer
|
|
||||||
group: cert-manager.io
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: cert-manager.io/v1
|
|
||||||
kind: Issuer
|
|
||||||
metadata:
|
|
||||||
name: nfd-ca-issuer
|
|
||||||
namespace: {{ include "node-feature-discovery.namespace" . }}
|
|
||||||
spec:
|
|
||||||
ca:
|
|
||||||
secretName: nfd-ca-cert
|
|
||||||
{{- end }}
|
|
|
@ -103,11 +103,7 @@ spec:
|
||||||
{{- if .Values.master.instance | empty | not }}
|
{{- if .Values.master.instance | empty | not }}
|
||||||
- "-instance={{ .Values.master.instance }}"
|
- "-instance={{ .Values.master.instance }}"
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if not .Values.featureGates.NodeFeatureAPI }}
|
|
||||||
- "-port={{ .Values.master.port | default "8080" }}"
|
|
||||||
{{- else if gt (int .Values.master.replicaCount) 1 }}
|
|
||||||
- "-enable-leader-election"
|
- "-enable-leader-election"
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.master.extraLabelNs | empty | not }}
|
{{- if .Values.master.extraLabelNs | empty | not }}
|
||||||
- "-extra-label-ns={{- join "," .Values.master.extraLabelNs }}"
|
- "-extra-label-ns={{- join "," .Values.master.extraLabelNs }}"
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -120,12 +116,6 @@ spec:
|
||||||
{{- if .Values.master.enableTaints }}
|
{{- if .Values.master.enableTaints }}
|
||||||
- "-enable-taints"
|
- "-enable-taints"
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if .Values.master.crdController | kindIs "invalid" | not }}
|
|
||||||
- "-crd-controller={{ .Values.master.crdController }}"
|
|
||||||
{{- else }}
|
|
||||||
## By default, disable crd controller for other than the default instances
|
|
||||||
- "-crd-controller={{ .Values.master.instance | empty }}"
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.master.featureRulesController | kindIs "invalid" | not }}
|
{{- if .Values.master.featureRulesController | kindIs "invalid" | not }}
|
||||||
- "-featurerules-controller={{ .Values.master.featureRulesController }}"
|
- "-featurerules-controller={{ .Values.master.featureRulesController }}"
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -135,11 +125,6 @@ spec:
|
||||||
{{- if .Values.master.nfdApiParallelism | empty | not }}
|
{{- if .Values.master.nfdApiParallelism | empty | not }}
|
||||||
- "-nfd-api-parallelism={{ .Values.master.nfdApiParallelism }}"
|
- "-nfd-api-parallelism={{ .Values.master.nfdApiParallelism }}"
|
||||||
{{- end }}
|
{{- 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 featureGates and add the feature-gate flag
|
# Go over featureGates and add the feature-gate flag
|
||||||
{{- range $key, $value := .Values.featureGates }}
|
{{- range $key, $value := .Values.featureGates }}
|
||||||
- "-feature-gates={{ $key }}={{ $value }}"
|
- "-feature-gates={{ $key }}={{ $value }}"
|
||||||
|
@ -150,20 +135,10 @@ spec:
|
||||||
{{- toYaml . | nindent 12 }}
|
{{- toYaml . | nindent 12 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
{{- if .Values.tls.enable }}
|
|
||||||
- name: nfd-master-cert
|
|
||||||
mountPath: "/etc/kubernetes/node-feature-discovery/certs"
|
|
||||||
readOnly: true
|
|
||||||
{{- end }}
|
|
||||||
- name: nfd-master-conf
|
- name: nfd-master-conf
|
||||||
mountPath: "/etc/kubernetes/node-feature-discovery"
|
mountPath: "/etc/kubernetes/node-feature-discovery"
|
||||||
readOnly: true
|
readOnly: true
|
||||||
volumes:
|
volumes:
|
||||||
{{- if .Values.tls.enable }}
|
|
||||||
- name: nfd-master-cert
|
|
||||||
secret:
|
|
||||||
secretName: nfd-master-cert
|
|
||||||
{{- end }}
|
|
||||||
- name: nfd-master-conf
|
- name: nfd-master-conf
|
||||||
configMap:
|
configMap:
|
||||||
name: {{ include "node-feature-discovery.fullname" . }}-master-conf
|
name: {{ include "node-feature-discovery.fullname" . }}-master-conf
|
||||||
|
|
|
@ -103,11 +103,6 @@ spec:
|
||||||
{{- else }}
|
{{- else }}
|
||||||
- "-watch-namespace=*"
|
- "-watch-namespace=*"
|
||||||
{{- end }}
|
{{- 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 }}
|
|
||||||
{{- if not .Values.topologyUpdater.podSetFingerprint }}
|
{{- if not .Values.topologyUpdater.podSetFingerprint }}
|
||||||
- "-pods-fingerprint=false"
|
- "-pods-fingerprint=false"
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -142,11 +137,6 @@ spec:
|
||||||
mountPath: /host-var/lib/kubelet
|
mountPath: /host-var/lib/kubelet
|
||||||
readOnly: true
|
readOnly: true
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if .Values.tls.enable }}
|
|
||||||
- name: nfd-topology-updater-cert
|
|
||||||
mountPath: "/etc/kubernetes/node-feature-discovery/certs"
|
|
||||||
readOnly: true
|
|
||||||
{{- end }}
|
|
||||||
- name: nfd-topology-updater-conf
|
- name: nfd-topology-updater-conf
|
||||||
mountPath: "/etc/kubernetes/node-feature-discovery"
|
mountPath: "/etc/kubernetes/node-feature-discovery"
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
@ -182,12 +172,6 @@ spec:
|
||||||
items:
|
items:
|
||||||
- key: nfd-topology-updater.conf
|
- key: nfd-topology-updater.conf
|
||||||
path: nfd-topology-updater.conf
|
path: nfd-topology-updater.conf
|
||||||
{{- if .Values.tls.enable }}
|
|
||||||
- name: nfd-topology-updater-cert
|
|
||||||
secret:
|
|
||||||
secretName: nfd-topology-updater-cert
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
|
|
||||||
{{- with .Values.topologyUpdater.nodeSelector }}
|
{{- with .Values.topologyUpdater.nodeSelector }}
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
|
|
|
@ -103,11 +103,6 @@ spec:
|
||||||
{{- if not .Values.featureGates.NodeFeatureAPI }}
|
{{- if not .Values.featureGates.NodeFeatureAPI }}
|
||||||
- "-server={{ include "node-feature-discovery.fullname" . }}-master:{{ .Values.master.service.port }}"
|
- "-server={{ include "node-feature-discovery.fullname" . }}-master:{{ .Values.master.service.port }}"
|
||||||
{{- end }}
|
{{- 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 featureGate and add the feature-gate flag
|
# Go over featureGate and add the feature-gate flag
|
||||||
{{- range $key, $value := .Values.featureGates }}
|
{{- range $key, $value := .Values.featureGates }}
|
||||||
- "-feature-gates={{ $key }}={{ $value }}"
|
- "-feature-gates={{ $key }}={{ $value }}"
|
||||||
|
@ -155,11 +150,6 @@ spec:
|
||||||
- name: nfd-worker-conf
|
- name: nfd-worker-conf
|
||||||
mountPath: "/etc/kubernetes/node-feature-discovery"
|
mountPath: "/etc/kubernetes/node-feature-discovery"
|
||||||
readOnly: true
|
readOnly: true
|
||||||
{{- if .Values.tls.enable }}
|
|
||||||
- name: nfd-worker-cert
|
|
||||||
mountPath: "/etc/kubernetes/node-feature-discovery/certs"
|
|
||||||
readOnly: true
|
|
||||||
{{- end }}
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: host-boot
|
- name: host-boot
|
||||||
hostPath:
|
hostPath:
|
||||||
|
@ -196,11 +186,6 @@ spec:
|
||||||
items:
|
items:
|
||||||
- key: nfd-worker.conf
|
- key: nfd-worker.conf
|
||||||
path: nfd-worker.conf
|
path: nfd-worker.conf
|
||||||
{{- if .Values.tls.enable }}
|
|
||||||
- name: nfd-worker-cert
|
|
||||||
secret:
|
|
||||||
secretName: nfd-worker-cert
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.worker.nodeSelector }}
|
{{- with .Values.worker.nodeSelector }}
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|
|
@ -68,10 +68,6 @@ master:
|
||||||
# retryPeriod: 2s
|
# retryPeriod: 2s
|
||||||
# nfdApiParallelism: 10
|
# nfdApiParallelism: 10
|
||||||
### <NFD-MASTER-CONF-END-DO-NOT-REMOVE>
|
### <NFD-MASTER-CONF-END-DO-NOT-REMOVE>
|
||||||
# The TCP port that nfd-master listens for incoming requests. Default: 8080
|
|
||||||
# Deprecated this parameter is related to the deprecated gRPC API and will
|
|
||||||
# be removed with it in a future release
|
|
||||||
port: 8080
|
|
||||||
metricsPort: 8081
|
metricsPort: 8081
|
||||||
healthPort: 8082
|
healthPort: 8082
|
||||||
instance:
|
instance:
|
||||||
|
@ -81,7 +77,6 @@ master:
|
||||||
extraLabelNs: []
|
extraLabelNs: []
|
||||||
resourceLabels: []
|
resourceLabels: []
|
||||||
enableTaints: false
|
enableTaints: false
|
||||||
crdController: null
|
|
||||||
featureRulesController: null
|
featureRulesController: null
|
||||||
nfdApiParallelism: null
|
nfdApiParallelism: null
|
||||||
deploymentAnnotations: {}
|
deploymentAnnotations: {}
|
||||||
|
@ -601,18 +596,6 @@ gc:
|
||||||
# specify how many old ReplicaSets for the Deployment to retain.
|
# specify how many old ReplicaSets for the Deployment to retain.
|
||||||
revisionHistoryLimit:
|
revisionHistoryLimit:
|
||||||
|
|
||||||
# Optionally use encryption for worker <--> master comms
|
|
||||||
# TODO: verify hostname is not yet supported
|
|
||||||
#
|
|
||||||
# If you do not enable certManager (and have it installed) you will
|
|
||||||
# need to manually, or otherwise, provision the TLS certs as secrets
|
|
||||||
tls:
|
|
||||||
enable: false
|
|
||||||
certManager: false
|
|
||||||
certManagerCertificate:
|
|
||||||
issuerKind:
|
|
||||||
issuerName:
|
|
||||||
|
|
||||||
prometheus:
|
prometheus:
|
||||||
enable: false
|
enable: false
|
||||||
scrapeInterval: 10s
|
scrapeInterval: 10s
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -4,7 +4,6 @@ go 1.23.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fsnotify/fsnotify v1.7.0
|
github.com/fsnotify/fsnotify v1.7.0
|
||||||
github.com/golang/protobuf v1.5.4
|
|
||||||
github.com/google/go-cmp v0.6.0
|
github.com/google/go-cmp v0.6.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/jaypipes/ghw v0.13.0
|
github.com/jaypipes/ghw v0.13.0
|
||||||
|
@ -23,7 +22,6 @@ require (
|
||||||
golang.org/x/net v0.30.0
|
golang.org/x/net v0.30.0
|
||||||
golang.org/x/time v0.7.0
|
golang.org/x/time v0.7.0
|
||||||
google.golang.org/grpc v1.63.2
|
google.golang.org/grpc v1.63.2
|
||||||
google.golang.org/protobuf v1.34.2
|
|
||||||
k8s.io/api v0.30.3
|
k8s.io/api v0.30.3
|
||||||
k8s.io/apiextensions-apiserver v0.30.3
|
k8s.io/apiextensions-apiserver v0.30.3
|
||||||
k8s.io/apimachinery v0.30.3
|
k8s.io/apimachinery v0.30.3
|
||||||
|
@ -69,6 +67,7 @@ require (
|
||||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
github.com/google/cel-go v0.17.8 // indirect
|
github.com/google/cel-go v0.17.8 // indirect
|
||||||
github.com/google/gnostic-models v0.6.8 // indirect
|
github.com/google/gnostic-models v0.6.8 // indirect
|
||||||
github.com/google/gofuzz v1.2.0 // indirect
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
|
@ -132,6 +131,7 @@ require (
|
||||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||||
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 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 labeler
|
|
||||||
|
|
||||||
//go:generate protoc --go_opt=paths=source_relative --go_out=plugins=grpc:. -I . -I ../.. -I ../../vendor labeler.proto
|
|
||||||
//go:generate mockery --name=LabelerClient --inpackage
|
|
|
@ -1,354 +0,0 @@
|
||||||
//
|
|
||||||
//Copyright 2019 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.
|
|
||||||
|
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// protoc-gen-go v1.23.0
|
|
||||||
// protoc v4.25.3
|
|
||||||
// source: labeler.proto
|
|
||||||
|
|
||||||
package labeler
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
proto "github.com/golang/protobuf/proto"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
reflect "reflect"
|
|
||||||
v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
|
||||||
sync "sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Verify that this generated code is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
||||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
|
||||||
// of the legacy proto package is being used.
|
|
||||||
const _ = proto.ProtoPackageIsVersion4
|
|
||||||
|
|
||||||
type SetLabelsRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
NfdVersion string `protobuf:"bytes,1,opt,name=nfd_version,json=nfdVersion,proto3" json:"nfd_version,omitempty"`
|
|
||||||
NodeName string `protobuf:"bytes,2,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
|
|
||||||
Labels map[string]string `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
|
||||||
Features *v1alpha1.Features `protobuf:"bytes,4,opt,name=features,proto3" json:"features,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetLabelsRequest) Reset() {
|
|
||||||
*x = SetLabelsRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_labeler_proto_msgTypes[0]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetLabelsRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*SetLabelsRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *SetLabelsRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_labeler_proto_msgTypes[0]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use SetLabelsRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*SetLabelsRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_labeler_proto_rawDescGZIP(), []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetLabelsRequest) GetNfdVersion() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.NfdVersion
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetLabelsRequest) GetNodeName() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.NodeName
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetLabelsRequest) GetLabels() map[string]string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Labels
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetLabelsRequest) GetFeatures() *v1alpha1.Features {
|
|
||||||
if x != nil {
|
|
||||||
return x.Features
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SetLabelsReply struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetLabelsReply) Reset() {
|
|
||||||
*x = SetLabelsReply{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_labeler_proto_msgTypes[1]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SetLabelsReply) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*SetLabelsReply) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *SetLabelsReply) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_labeler_proto_msgTypes[1]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use SetLabelsReply.ProtoReflect.Descriptor instead.
|
|
||||||
func (*SetLabelsReply) Descriptor() ([]byte, []int) {
|
|
||||||
return file_labeler_proto_rawDescGZIP(), []int{1}
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_labeler_proto protoreflect.FileDescriptor
|
|
||||||
|
|
||||||
var file_labeler_proto_rawDesc = []byte{
|
|
||||||
0x0a, 0x0d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
|
|
||||||
0x07, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x1a, 0x43, 0x73, 0x69, 0x67, 0x73, 0x2e, 0x6b,
|
|
||||||
0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2d, 0x66, 0x65, 0x61, 0x74, 0x75,
|
|
||||||
0x72, 0x65, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69,
|
|
||||||
0x2f, 0x6e, 0x66, 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x67, 0x65,
|
|
||||||
0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfa, 0x01,
|
|
||||||
0x0a, 0x10, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
|
||||||
0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x66, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
|
||||||
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x66, 0x64, 0x56, 0x65, 0x72, 0x73,
|
|
||||||
0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
|
|
||||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65,
|
|
||||||
0x12, 0x3d, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
|
||||||
0x32, 0x25, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x61,
|
|
||||||
0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65,
|
|
||||||
0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12,
|
|
||||||
0x2e, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
|
|
||||||
0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x65, 0x61,
|
|
||||||
0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x1a,
|
|
||||||
0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
|
||||||
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
|
||||||
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
|
||||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x10, 0x0a, 0x0e, 0x53, 0x65,
|
|
||||||
0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x32, 0x4c, 0x0a, 0x07,
|
|
||||||
0x4c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x09, 0x53, 0x65, 0x74, 0x4c, 0x61,
|
|
||||||
0x62, 0x65, 0x6c, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53,
|
|
||||||
0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
|
||||||
0x17, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62,
|
|
||||||
0x65, 0x6c, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x30, 0x5a, 0x2e, 0x73, 0x69,
|
|
||||||
0x67, 0x73, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2d, 0x66,
|
|
||||||
0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79,
|
|
||||||
0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x33,
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
file_labeler_proto_rawDescOnce sync.Once
|
|
||||||
file_labeler_proto_rawDescData = file_labeler_proto_rawDesc
|
|
||||||
)
|
|
||||||
|
|
||||||
func file_labeler_proto_rawDescGZIP() []byte {
|
|
||||||
file_labeler_proto_rawDescOnce.Do(func() {
|
|
||||||
file_labeler_proto_rawDescData = protoimpl.X.CompressGZIP(file_labeler_proto_rawDescData)
|
|
||||||
})
|
|
||||||
return file_labeler_proto_rawDescData
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_labeler_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
|
||||||
var file_labeler_proto_goTypes = []interface{}{
|
|
||||||
(*SetLabelsRequest)(nil), // 0: labeler.SetLabelsRequest
|
|
||||||
(*SetLabelsReply)(nil), // 1: labeler.SetLabelsReply
|
|
||||||
nil, // 2: labeler.SetLabelsRequest.LabelsEntry
|
|
||||||
(*v1alpha1.Features)(nil), // 3: v1alpha1.Features
|
|
||||||
}
|
|
||||||
var file_labeler_proto_depIdxs = []int32{
|
|
||||||
2, // 0: labeler.SetLabelsRequest.labels:type_name -> labeler.SetLabelsRequest.LabelsEntry
|
|
||||||
3, // 1: labeler.SetLabelsRequest.features:type_name -> v1alpha1.Features
|
|
||||||
0, // 2: labeler.Labeler.SetLabels:input_type -> labeler.SetLabelsRequest
|
|
||||||
1, // 3: labeler.Labeler.SetLabels:output_type -> labeler.SetLabelsReply
|
|
||||||
3, // [3:4] is the sub-list for method output_type
|
|
||||||
2, // [2:3] is the sub-list for method input_type
|
|
||||||
2, // [2:2] is the sub-list for extension type_name
|
|
||||||
2, // [2:2] is the sub-list for extension extendee
|
|
||||||
0, // [0:2] is the sub-list for field type_name
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { file_labeler_proto_init() }
|
|
||||||
func file_labeler_proto_init() {
|
|
||||||
if File_labeler_proto != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !protoimpl.UnsafeEnabled {
|
|
||||||
file_labeler_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*SetLabelsRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_labeler_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*SetLabelsReply); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type x struct{}
|
|
||||||
out := protoimpl.TypeBuilder{
|
|
||||||
File: protoimpl.DescBuilder{
|
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
||||||
RawDescriptor: file_labeler_proto_rawDesc,
|
|
||||||
NumEnums: 0,
|
|
||||||
NumMessages: 3,
|
|
||||||
NumExtensions: 0,
|
|
||||||
NumServices: 1,
|
|
||||||
},
|
|
||||||
GoTypes: file_labeler_proto_goTypes,
|
|
||||||
DependencyIndexes: file_labeler_proto_depIdxs,
|
|
||||||
MessageInfos: file_labeler_proto_msgTypes,
|
|
||||||
}.Build()
|
|
||||||
File_labeler_proto = out.File
|
|
||||||
file_labeler_proto_rawDesc = nil
|
|
||||||
file_labeler_proto_goTypes = nil
|
|
||||||
file_labeler_proto_depIdxs = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
|
||||||
var _ context.Context
|
|
||||||
var _ grpc.ClientConnInterface
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
const _ = grpc.SupportPackageIsVersion6
|
|
||||||
|
|
||||||
// LabelerClient is the client API for Labeler service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
|
||||||
type LabelerClient interface {
|
|
||||||
SetLabels(ctx context.Context, in *SetLabelsRequest, opts ...grpc.CallOption) (*SetLabelsReply, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type labelerClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLabelerClient(cc grpc.ClientConnInterface) LabelerClient {
|
|
||||||
return &labelerClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *labelerClient) SetLabels(ctx context.Context, in *SetLabelsRequest, opts ...grpc.CallOption) (*SetLabelsReply, error) {
|
|
||||||
out := new(SetLabelsReply)
|
|
||||||
err := c.cc.Invoke(ctx, "/labeler.Labeler/SetLabels", in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LabelerServer is the server API for Labeler service.
|
|
||||||
type LabelerServer interface {
|
|
||||||
SetLabels(context.Context, *SetLabelsRequest) (*SetLabelsReply, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedLabelerServer can be embedded to have forward compatible implementations.
|
|
||||||
type UnimplementedLabelerServer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*UnimplementedLabelerServer) SetLabels(context.Context, *SetLabelsRequest) (*SetLabelsReply, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method SetLabels not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterLabelerServer(s *grpc.Server, srv LabelerServer) {
|
|
||||||
s.RegisterService(&_Labeler_serviceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Labeler_SetLabels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(SetLabelsRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(LabelerServer).SetLabels(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/labeler.Labeler/SetLabels",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(LabelerServer).SetLabels(ctx, req.(*SetLabelsRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _Labeler_serviceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "labeler.Labeler",
|
|
||||||
HandlerType: (*LabelerServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "SetLabels",
|
|
||||||
Handler: _Labeler_SetLabels_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "labeler.proto",
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2019 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option go_package = "sigs.k8s.io/node-feature-discovery/pkg/labeler";
|
|
||||||
|
|
||||||
import "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/generated.proto";
|
|
||||||
|
|
||||||
package labeler;
|
|
||||||
|
|
||||||
service Labeler{
|
|
||||||
rpc SetLabels(SetLabelsRequest) returns (SetLabelsReply) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetLabelsRequest {
|
|
||||||
string nfd_version = 1;
|
|
||||||
string node_name = 2;
|
|
||||||
map<string, string> labels = 3;
|
|
||||||
v1alpha1.Features features = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetLabelsReply {
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
// Code generated by mockery v2.42.0. DO NOT EDIT.
|
|
||||||
|
|
||||||
package labeler
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
|
|
||||||
mock "github.com/stretchr/testify/mock"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MockLabelerClient is an autogenerated mock type for the LabelerClient type
|
|
||||||
type MockLabelerClient struct {
|
|
||||||
mock.Mock
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLabels provides a mock function with given fields: ctx, in, opts
|
|
||||||
func (_m *MockLabelerClient) SetLabels(ctx context.Context, in *SetLabelsRequest, opts ...grpc.CallOption) (*SetLabelsReply, error) {
|
|
||||||
_va := make([]interface{}, len(opts))
|
|
||||||
for _i := range opts {
|
|
||||||
_va[_i] = opts[_i]
|
|
||||||
}
|
|
||||||
var _ca []interface{}
|
|
||||||
_ca = append(_ca, ctx, in)
|
|
||||||
_ca = append(_ca, _va...)
|
|
||||||
ret := _m.Called(_ca...)
|
|
||||||
|
|
||||||
if len(ret) == 0 {
|
|
||||||
panic("no return value specified for SetLabels")
|
|
||||||
}
|
|
||||||
|
|
||||||
var r0 *SetLabelsReply
|
|
||||||
var r1 error
|
|
||||||
if rf, ok := ret.Get(0).(func(context.Context, *SetLabelsRequest, ...grpc.CallOption) (*SetLabelsReply, error)); ok {
|
|
||||||
return rf(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
if rf, ok := ret.Get(0).(func(context.Context, *SetLabelsRequest, ...grpc.CallOption) *SetLabelsReply); ok {
|
|
||||||
r0 = rf(ctx, in, opts...)
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(*SetLabelsReply)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if rf, ok := ret.Get(1).(func(context.Context, *SetLabelsRequest, ...grpc.CallOption) error); ok {
|
|
||||||
r1 = rf(ctx, in, opts...)
|
|
||||||
} else {
|
|
||||||
r1 = ret.Error(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0, r1
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMockLabelerClient creates a new instance of MockLabelerClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
|
||||||
// The first argument is typically a *testing.T value.
|
|
||||||
func NewMockLabelerClient(t interface {
|
|
||||||
mock.TestingT
|
|
||||||
Cleanup(func())
|
|
||||||
}) *MockLabelerClient {
|
|
||||||
mock := &MockLabelerClient{}
|
|
||||||
mock.Mock.Test(t)
|
|
||||||
|
|
||||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
|
||||||
|
|
||||||
return mock
|
|
||||||
}
|
|
|
@ -40,12 +40,12 @@ import (
|
||||||
clienttesting "k8s.io/client-go/testing"
|
clienttesting "k8s.io/client-go/testing"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
|
|
||||||
|
nfdclientset "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned"
|
||||||
fakenfdclient "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/fake"
|
fakenfdclient "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/fake"
|
||||||
nfdscheme "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/scheme"
|
nfdscheme "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/scheme"
|
||||||
nfdinformers "sigs.k8s.io/node-feature-discovery/api/generated/informers/externalversions"
|
nfdinformers "sigs.k8s.io/node-feature-discovery/api/generated/informers/externalversions"
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/features"
|
"sigs.k8s.io/node-feature-discovery/pkg/features"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -109,16 +109,28 @@ func withConfig(config *NFDConfig) NfdMasterOption {
|
||||||
return &nfdMasterOpt{f: func(n *nfdMaster) { n.config = config }}
|
return &nfdMasterOpt{f: func(n *nfdMaster) { n.config = config }}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// withNFDClient forces to use the given client for the NFD API, without
|
||||||
|
// initializing one from kubeconfig.
|
||||||
|
func withNFDClient(cli nfdclientset.Interface) NfdMasterOption {
|
||||||
|
return &nfdMasterOpt{f: func(n *nfdMaster) { n.nfdClient = cli }}
|
||||||
|
}
|
||||||
|
|
||||||
func newFakeMaster(opts ...NfdMasterOption) *nfdMaster {
|
func newFakeMaster(opts ...NfdMasterOption) *nfdMaster {
|
||||||
|
nfdCli := fakenfdclient.NewSimpleClientset()
|
||||||
defaultOpts := []NfdMasterOption{
|
defaultOpts := []NfdMasterOption{
|
||||||
withNodeName(testNodeName),
|
withNodeName(testNodeName),
|
||||||
withConfig(&NFDConfig{Restrictions: Restrictions{AllowOverwrite: true}}),
|
withConfig(&NFDConfig{Restrictions: Restrictions{AllowOverwrite: true}}),
|
||||||
WithKubernetesClient(fakeclient.NewSimpleClientset()),
|
WithKubernetesClient(fakeclient.NewSimpleClientset()),
|
||||||
|
withNFDClient(nfdCli),
|
||||||
}
|
}
|
||||||
m, err := NewNfdMaster(append(defaultOpts, opts...)...)
|
m, err := NewNfdMaster(append(defaultOpts, opts...)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
// Add FeatureGates
|
||||||
|
if err := features.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return m.(*nfdMaster)
|
return m.(*nfdMaster)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,90 +343,6 @@ func TestRemovingExtResources(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetLabels(t *testing.T) {
|
|
||||||
Convey("When servicing SetLabels request", t, func() {
|
|
||||||
// Add feature gates as running nfd-master depends on that
|
|
||||||
err := features.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
testNode := newTestNode()
|
|
||||||
// We need to populate the node with some annotations or the patching in the fake client fails
|
|
||||||
testNode.Labels["feature.node.kubernetes.io/foo"] = "bar"
|
|
||||||
testNode.Annotations[nfdv1alpha1.FeatureLabelsAnnotation] = "foo"
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
// In the gRPC request the label names may omit the default ns
|
|
||||||
featureLabels := map[string]string{
|
|
||||||
"feature.node.kubernetes.io/feature-1": "1",
|
|
||||||
"example.io/feature-2": "val-2",
|
|
||||||
"feature.node.kubernetes.io/feature-3": "3",
|
|
||||||
}
|
|
||||||
req := &labeler.SetLabelsRequest{NodeName: testNodeName, NfdVersion: "0.1-test", Labels: featureLabels}
|
|
||||||
|
|
||||||
Convey("When node update succeeds", func() {
|
|
||||||
fakeCli := fakeclient.NewSimpleClientset(testNode)
|
|
||||||
fakeMaster := newFakeMaster(WithKubernetesClient(fakeCli))
|
|
||||||
|
|
||||||
_, err := fakeMaster.SetLabels(ctx, req)
|
|
||||||
Convey("No error should be returned", func() {
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
})
|
|
||||||
Convey("Node object should be updated", func() {
|
|
||||||
updatedNode, err := fakeCli.CoreV1().Nodes().Get(context.TODO(), testNodeName, metav1.GetOptions{})
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(updatedNode.Labels, ShouldEqual, featureLabels)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Convey("When -resource-labels is specified", func() {
|
|
||||||
fakeCli := fakeclient.NewSimpleClientset(testNode)
|
|
||||||
fakeMaster := newFakeMaster(
|
|
||||||
WithKubernetesClient(fakeCli),
|
|
||||||
withConfig(&NFDConfig{
|
|
||||||
ResourceLabels: map[string]struct{}{
|
|
||||||
"feature.node.kubernetes.io/feature-3": {},
|
|
||||||
"feature-1": {}},
|
|
||||||
}))
|
|
||||||
|
|
||||||
_, err := fakeMaster.SetLabels(ctx, req)
|
|
||||||
Convey("Error is nil", func() {
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
})
|
|
||||||
|
|
||||||
Convey("Node object should be updated", func() {
|
|
||||||
updatedNode, err := fakeCli.CoreV1().Nodes().Get(context.TODO(), testNodeName, metav1.GetOptions{})
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(updatedNode.Labels, ShouldEqual, map[string]string{"example.io/feature-2": "val-2"})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Convey("When node update fails", func() {
|
|
||||||
fakeCli := fakeclient.NewSimpleClientset(testNode)
|
|
||||||
fakeMaster := newFakeMaster(WithKubernetesClient(fakeCli))
|
|
||||||
|
|
||||||
fakeErr := errors.New("Fake error when patching node")
|
|
||||||
fakeCli.CoreV1().(*fakecorev1client.FakeCoreV1).PrependReactor("patch", "nodes", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
|
||||||
return true, &corev1.Node{}, fakeErr
|
|
||||||
})
|
|
||||||
_, err := fakeMaster.SetLabels(ctx, req)
|
|
||||||
Convey("An error should be returned", func() {
|
|
||||||
So(err, ShouldWrap, fakeErr)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Convey("With '-no-publish'", func() {
|
|
||||||
fakeCli := fakeclient.NewSimpleClientset(testNode)
|
|
||||||
fakeMaster := newFakeMaster(WithKubernetesClient(fakeCli))
|
|
||||||
|
|
||||||
fakeMaster.config.NoPublish = true
|
|
||||||
_, err := fakeMaster.SetLabels(ctx, req)
|
|
||||||
Convey("Operation should succeed", func() {
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterLabels(t *testing.T) {
|
func TestFilterLabels(t *testing.T) {
|
||||||
fakeMaster := newFakeMaster()
|
fakeMaster := newFakeMaster()
|
||||||
fakeMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}
|
fakeMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}
|
||||||
|
|
|
@ -17,8 +17,6 @@ limitations under the License.
|
||||||
package nfdmaster
|
package nfdmaster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
|
@ -35,10 +33,8 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
|
||||||
"google.golang.org/grpc/health"
|
"google.golang.org/grpc/health"
|
||||||
"google.golang.org/grpc/health/grpc_health_v1"
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
"google.golang.org/grpc/peer"
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
@ -60,7 +56,6 @@ import (
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/nodefeaturerule"
|
"sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/nodefeaturerule"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/validate"
|
"sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/validate"
|
||||||
nfdfeatures "sigs.k8s.io/node-feature-discovery/pkg/features"
|
nfdfeatures "sigs.k8s.io/node-feature-discovery/pkg/features"
|
||||||
pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
klogutils "sigs.k8s.io/node-feature-discovery/pkg/utils/klog"
|
klogutils "sigs.k8s.io/node-feature-discovery/pkg/utils/klog"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
||||||
|
@ -122,20 +117,15 @@ type ConfigOverrideArgs struct {
|
||||||
|
|
||||||
// Args holds command line arguments
|
// Args holds command line arguments
|
||||||
type Args struct {
|
type Args struct {
|
||||||
CaFile string
|
ConfigFile string
|
||||||
CertFile string
|
Instance string
|
||||||
ConfigFile string
|
Klog map[string]*utils.KlogFlagVal
|
||||||
Instance string
|
Kubeconfig string
|
||||||
KeyFile string
|
Port int
|
||||||
Klog map[string]*utils.KlogFlagVal
|
|
||||||
Kubeconfig string
|
|
||||||
CrdController bool
|
|
||||||
Port int
|
|
||||||
// GrpcHealthPort is only needed to avoid races between tests (by skipping the health server).
|
// GrpcHealthPort is only needed to avoid races between tests (by skipping the health server).
|
||||||
// Could be removed when gRPC labler service is dropped (when nfd-worker tests stop running nfd-master).
|
// Could be removed when gRPC labler service is dropped (when nfd-worker tests stop running nfd-master).
|
||||||
GrpcHealthPort int
|
GrpcHealthPort int
|
||||||
Prune bool
|
Prune bool
|
||||||
VerifyNodeName bool
|
|
||||||
Options string
|
Options string
|
||||||
EnableLeaderElection bool
|
EnableLeaderElection bool
|
||||||
MetricsPort int
|
MetricsPort int
|
||||||
|
@ -167,7 +157,7 @@ type nfdMaster struct {
|
||||||
ready chan struct{}
|
ready chan struct{}
|
||||||
kubeconfig *restclient.Config
|
kubeconfig *restclient.Config
|
||||||
k8sClient k8sclient.Interface
|
k8sClient k8sclient.Interface
|
||||||
nfdClient *nfdclientset.Clientset
|
nfdClient nfdclientset.Interface
|
||||||
updaterPool *updaterPool
|
updaterPool *updaterPool
|
||||||
deniedNs
|
deniedNs
|
||||||
config *NFDConfig
|
config *NFDConfig
|
||||||
|
@ -194,19 +184,6 @@ func NewNfdMaster(opts ...NfdMasterOption) (NfdMaster, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check TLS related args
|
|
||||||
if nfd.args.CertFile != "" || nfd.args.KeyFile != "" || nfd.args.CaFile != "" {
|
|
||||||
if nfd.args.CertFile == "" {
|
|
||||||
return nfd, fmt.Errorf("-cert-file needs to be specified alongside -key-file and -ca-file")
|
|
||||||
}
|
|
||||||
if nfd.args.KeyFile == "" {
|
|
||||||
return nfd, fmt.Errorf("-key-file needs to be specified alongside -cert-file and -ca-file")
|
|
||||||
}
|
|
||||||
if nfd.args.CaFile == "" {
|
|
||||||
return nfd, fmt.Errorf("-ca-file needs to be specified alongside -cert-file and -key-file")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if nfd.args.ConfigFile != "" {
|
if nfd.args.ConfigFile != "" {
|
||||||
nfd.configFilePath = filepath.Clean(nfd.args.ConfigFile)
|
nfd.configFilePath = filepath.Clean(nfd.args.ConfigFile)
|
||||||
}
|
}
|
||||||
|
@ -232,11 +209,11 @@ func NewNfdMaster(opts ...NfdMasterOption) (NfdMaster, error) {
|
||||||
return nfd, err
|
return nfd, err
|
||||||
}
|
}
|
||||||
nfd.kubeconfig = kubeconfig
|
nfd.kubeconfig = kubeconfig
|
||||||
nfdClient, err := nfdclientset.NewForConfig(nfd.kubeconfig)
|
c, err := nfdclientset.NewForConfig(nfd.kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nfd, err
|
return nfd, err
|
||||||
}
|
}
|
||||||
nfd.nfdClient = nfdClient
|
nfd.nfdClient = c
|
||||||
}
|
}
|
||||||
|
|
||||||
nfd.updaterPool = newUpdaterPool(nfd)
|
nfd.updaterPool = newUpdaterPool(nfd)
|
||||||
|
@ -311,11 +288,8 @@ func (m *nfdMaster) Run() error {
|
||||||
return m.prune()
|
return m.prune()
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.args.CrdController {
|
if err := m.startNfdApiController(); err != nil {
|
||||||
err := m.startNfdApiController()
|
return err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m.updaterPool.start(m.config.NfdApiParallelism)
|
m.updaterPool.start(m.config.NfdApiParallelism)
|
||||||
|
@ -344,14 +318,6 @@ func (m *nfdMaster) Run() error {
|
||||||
defer m.Stop()
|
defer m.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run gRPC server
|
|
||||||
grpcErr := make(chan error)
|
|
||||||
// If the NodeFeature API is enabled, don'tregister the labeler API
|
|
||||||
// server. Otherwise, register the labeler server.
|
|
||||||
if !nfdfeatures.NFDFeatureGate.Enabled(nfdfeatures.NodeFeatureAPI) {
|
|
||||||
go m.runGrpcServer(grpcErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run updater that handles events from the nfd CRD API.
|
// Run updater that handles events from the nfd CRD API.
|
||||||
if m.nfdController != nil {
|
if m.nfdController != nil {
|
||||||
if m.args.EnableLeaderElection {
|
if m.args.EnableLeaderElection {
|
||||||
|
@ -362,6 +328,7 @@ func (m *nfdMaster) Run() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start gRPC server for liveness probe (at this point we're "live")
|
// Start gRPC server for liveness probe (at this point we're "live")
|
||||||
|
grpcErr := make(chan error)
|
||||||
if m.args.GrpcHealthPort != 0 {
|
if m.args.GrpcHealthPort != 0 {
|
||||||
if err := m.startGrpcHealthServer(grpcErr); err != nil {
|
if err := m.startGrpcHealthServer(grpcErr); err != nil {
|
||||||
return fmt.Errorf("failed to start gRPC health server: %w", err)
|
return fmt.Errorf("failed to start gRPC health server: %w", err)
|
||||||
|
@ -410,68 +377,11 @@ func (m *nfdMaster) startGrpcHealthServer(errChan chan<- error) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *nfdMaster) runGrpcServer(errChan chan<- error) {
|
|
||||||
// Create server listening for TCP connections
|
|
||||||
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", m.args.Port))
|
|
||||||
if err != nil {
|
|
||||||
errChan <- fmt.Errorf("failed to listen: %w", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
serverOpts := []grpc.ServerOption{}
|
|
||||||
tlsConfig := utils.TlsConfig{}
|
|
||||||
// Create watcher for TLS cert files
|
|
||||||
certWatch, err := utils.CreateFsWatcher(time.Second, m.args.CertFile, m.args.KeyFile, m.args.CaFile)
|
|
||||||
if err != nil {
|
|
||||||
errChan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Enable mutual TLS authentication if -cert-file, -key-file or -ca-file
|
|
||||||
// is defined
|
|
||||||
if m.args.CertFile != "" || m.args.KeyFile != "" || m.args.CaFile != "" {
|
|
||||||
if err := tlsConfig.UpdateConfig(m.args.CertFile, m.args.KeyFile, m.args.CaFile); err != nil {
|
|
||||||
errChan <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsConfig := &tls.Config{GetConfigForClient: tlsConfig.GetConfig}
|
|
||||||
serverOpts = append(serverOpts, grpc.Creds(credentials.NewTLS(tlsConfig)))
|
|
||||||
}
|
|
||||||
m.server = grpc.NewServer(serverOpts...)
|
|
||||||
|
|
||||||
pb.RegisterLabelerServer(m.server, m)
|
|
||||||
|
|
||||||
klog.InfoS("gRPC server serving", "port", m.args.Port)
|
|
||||||
|
|
||||||
// Run gRPC server
|
|
||||||
grpcErr := make(chan error)
|
|
||||||
go func() {
|
|
||||||
defer lis.Close()
|
|
||||||
grpcErr <- m.server.Serve(lis)
|
|
||||||
}()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-certWatch.Events:
|
|
||||||
klog.InfoS("reloading TLS certificates")
|
|
||||||
if err := tlsConfig.UpdateConfig(m.args.CertFile, m.args.KeyFile, m.args.CaFile); err != nil {
|
|
||||||
errChan <- err
|
|
||||||
}
|
|
||||||
|
|
||||||
case err := <-grpcErr:
|
|
||||||
if err != nil {
|
|
||||||
errChan <- fmt.Errorf("gRPC server exited with an error: %w", err)
|
|
||||||
}
|
|
||||||
klog.InfoS("gRPC server stopped")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// nfdAPIUpdateHandler handles events from the nfd API controller.
|
// nfdAPIUpdateHandler handles events from the nfd API controller.
|
||||||
func (m *nfdMaster) nfdAPIUpdateHandler() {
|
func (m *nfdMaster) nfdAPIUpdateHandler() {
|
||||||
// We want to unconditionally update all nodes at startup if gRPC is
|
// We want to unconditionally update all nodes at startup if gRPC is
|
||||||
// disabled (i.e. NodeFeature API is enabled)
|
// disabled (i.e. NodeFeature API is enabled)
|
||||||
updateAll := nfdfeatures.NFDFeatureGate.Enabled(nfdfeatures.NodeFeatureAPI)
|
updateAll := true
|
||||||
updateNodes := make(map[string]struct{})
|
updateNodes := make(map[string]struct{})
|
||||||
nodeFeatureGroup := make(map[string]struct{})
|
nodeFeatureGroup := make(map[string]struct{})
|
||||||
updateAllNodeFeatureGroups := false
|
updateAllNodeFeatureGroups := false
|
||||||
|
@ -717,18 +627,6 @@ func filterTaints(taints []corev1.Taint) []corev1.Taint {
|
||||||
return outTaints
|
return outTaints
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyNodeName(cert *x509.Certificate, nodeName string) error {
|
|
||||||
if cert.Subject.CommonName == nodeName {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err := cert.VerifyHostname(nodeName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("certificate %q not valid for node %q: %v", cert.Subject.CommonName, nodeName, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isNamespaceDenied(labelNs string, wildcardDeniedNs map[string]struct{}, normalDeniedNs map[string]struct{}) bool {
|
func isNamespaceDenied(labelNs string, wildcardDeniedNs map[string]struct{}, normalDeniedNs map[string]struct{}) bool {
|
||||||
for deniedNs := range normalDeniedNs {
|
for deniedNs := range normalDeniedNs {
|
||||||
if labelNs == deniedNs {
|
if labelNs == deniedNs {
|
||||||
|
@ -743,38 +641,6 @@ func isNamespaceDenied(labelNs string, wildcardDeniedNs map[string]struct{}, nor
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLabels implements LabelerServer
|
|
||||||
func (m *nfdMaster) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.SetLabelsReply, error) {
|
|
||||||
nodeUpdateRequests.Inc()
|
|
||||||
err := authorizeClient(c, m.args.VerifyNodeName, r.NodeName)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "gRPC client authorization failed", "nodeName", r.NodeName)
|
|
||||||
return &pb.SetLabelsReply{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case klog.V(4).Enabled():
|
|
||||||
klog.InfoS("gRPC SetLabels request received", "setLabelsRequest", utils.DelayedDumper(r))
|
|
||||||
case klog.V(1).Enabled():
|
|
||||||
klog.InfoS("gRPC SetLabels request received", "nodeName", r.NodeName, "nfdVersion", r.NfdVersion, "labels", r.Labels)
|
|
||||||
default:
|
|
||||||
klog.InfoS("gRPC SetLabels request received", "nodeName", r.NodeName)
|
|
||||||
}
|
|
||||||
if !m.config.NoPublish {
|
|
||||||
// Fetch the node object.
|
|
||||||
node, err := getNode(m.k8sClient, r.NodeName)
|
|
||||||
if err != nil {
|
|
||||||
return &pb.SetLabelsReply{}, err
|
|
||||||
}
|
|
||||||
// Create labels et al
|
|
||||||
if err := m.refreshNodeFeatures(m.k8sClient, node, r.GetLabels(), r.GetFeatures()); err != nil {
|
|
||||||
nodeUpdateFailures.Inc()
|
|
||||||
return &pb.SetLabelsReply{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &pb.SetLabelsReply{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *nfdMaster) nfdAPIUpdateAllNodes() error {
|
func (m *nfdMaster) nfdAPIUpdateAllNodes() error {
|
||||||
klog.InfoS("will process all nodes in the cluster")
|
klog.InfoS("will process all nodes in the cluster")
|
||||||
|
|
||||||
|
@ -918,7 +784,7 @@ func (m *nfdMaster) nfdAPIUpdateAllNodeFeatureGroups() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *nfdMaster) nfdAPIUpdateNodeFeatureGroup(nfdClient *nfdclientset.Clientset, nodeFeatureGroup *nfdv1alpha1.NodeFeatureGroup) error {
|
func (m *nfdMaster) nfdAPIUpdateNodeFeatureGroup(nfdClient nfdclientset.Interface, nodeFeatureGroup *nfdv1alpha1.NodeFeatureGroup) error {
|
||||||
klog.V(2).InfoS("evaluating NodeFeatureGroup", "nodeFeatureGroup", klog.KObj(nodeFeatureGroup))
|
klog.V(2).InfoS("evaluating NodeFeatureGroup", "nodeFeatureGroup", klog.KObj(nodeFeatureGroup))
|
||||||
if m.nfdController == nil || m.nfdController.featureLister == nil {
|
if m.nfdController == nil || m.nfdController.featureLister == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -1146,30 +1012,6 @@ func (m *nfdMaster) setTaints(cli k8sclient.Interface, taints []corev1.Taint, no
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func authorizeClient(c context.Context, checkNodeName bool, nodeName string) error {
|
|
||||||
if checkNodeName {
|
|
||||||
// Client authorization.
|
|
||||||
// Check that the node name matches the CN from the TLS cert
|
|
||||||
client, ok := peer.FromContext(c)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("failed to get peer (client)")
|
|
||||||
}
|
|
||||||
tlsAuth, ok := client.AuthInfo.(credentials.TLSInfo)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("incorrect client credentials")
|
|
||||||
}
|
|
||||||
if len(tlsAuth.State.VerifiedChains) == 0 || len(tlsAuth.State.VerifiedChains[0]) == 0 {
|
|
||||||
return fmt.Errorf("client certificate verification failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := verifyNodeName(tlsAuth.State.VerifiedChains[0][0], nodeName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha1.Features) (Labels, Annotations, ExtendedResources, []corev1.Taint) {
|
func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha1.Features) (Labels, Annotations, ExtendedResources, []corev1.Taint) {
|
||||||
if m.nfdController == nil {
|
if m.nfdController == nil {
|
||||||
return nil, nil, nil, nil
|
return nil, nil, nil, nil
|
||||||
|
@ -1533,7 +1375,6 @@ func (m *nfdMaster) startNfdApiController() error {
|
||||||
}
|
}
|
||||||
klog.InfoS("starting the nfd api controller")
|
klog.InfoS("starting the nfd api controller")
|
||||||
m.nfdController, err = newNfdController(kubeconfig, nfdApiControllerOptions{
|
m.nfdController, err = newNfdController(kubeconfig, nfdApiControllerOptions{
|
||||||
DisableNodeFeature: !nfdfeatures.NFDFeatureGate.Enabled(nfdfeatures.NodeFeatureAPI),
|
|
||||||
ResyncPeriod: m.config.ResyncPeriod.Duration,
|
ResyncPeriod: m.config.ResyncPeriod.Duration,
|
||||||
K8sClient: m.k8sClient,
|
K8sClient: m.k8sClient,
|
||||||
NodeFeatureNamespaceSelector: m.config.Restrictions.NodeFeatureNamespaceSelector,
|
NodeFeatureNamespaceSelector: m.config.Restrictions.NodeFeatureNamespaceSelector,
|
||||||
|
|
|
@ -26,23 +26,11 @@ import (
|
||||||
|
|
||||||
func TestNewNfdMaster(t *testing.T) {
|
func TestNewNfdMaster(t *testing.T) {
|
||||||
Convey("When initializing new NfdMaster instance", t, func() {
|
Convey("When initializing new NfdMaster instance", t, func() {
|
||||||
Convey("When one of -cert-file, -key-file or -ca-file is missing", func() {
|
|
||||||
_, err := m.NewNfdMaster(m.WithArgs(&m.Args{CertFile: "crt", KeyFile: "key"}))
|
|
||||||
_, err2 := m.NewNfdMaster(m.WithArgs(&m.Args{KeyFile: "key", CaFile: "ca"}))
|
|
||||||
_, err3 := m.NewNfdMaster(m.WithArgs(&m.Args{CertFile: "crt", CaFile: "ca"}))
|
|
||||||
Convey("An error should be returned", func() {
|
|
||||||
So(err, ShouldNotBeNil)
|
|
||||||
So(err2, ShouldNotBeNil)
|
|
||||||
So(err3, ShouldNotBeNil)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Convey("When -config is supplied", func() {
|
Convey("When -config is supplied", func() {
|
||||||
_, err := m.NewNfdMaster(
|
_, err := m.NewNfdMaster(
|
||||||
m.WithArgs(&m.Args{
|
m.WithArgs(&m.Args{
|
||||||
CertFile: "crt",
|
ConfigFile: "master-config.yaml",
|
||||||
KeyFile: "key",
|
}),
|
||||||
CaFile: "ca",
|
|
||||||
ConfigFile: "master-config.yaml"}),
|
|
||||||
m.WithKubernetesClient(fakeclient.NewSimpleClientset()))
|
m.WithKubernetesClient(fakeclient.NewSimpleClientset()))
|
||||||
Convey("An error should not be returned", func() {
|
Convey("An error should not be returned", func() {
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
|
@ -27,7 +27,6 @@ import (
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
nfdclientset "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned"
|
nfdclientset "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned"
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/features"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type updaterPool struct {
|
type updaterPool struct {
|
||||||
|
@ -120,7 +119,14 @@ func (u *updaterPool) processNodeFeatureGroupUpdateRequest(cli nfdclientset.Inte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *updaterPool) runNodeFeatureGroupUpdater() {
|
func (u *updaterPool) runNodeFeatureGroupUpdater() {
|
||||||
cli := nfdclientset.NewForConfigOrDie(u.nfdMaster.kubeconfig)
|
var cli nfdclientset.Interface
|
||||||
|
if u.nfdMaster.kubeconfig != nil {
|
||||||
|
// For normal execution, initialize a separate api client for each updater
|
||||||
|
cli = nfdclientset.NewForConfigOrDie(u.nfdMaster.kubeconfig)
|
||||||
|
} else {
|
||||||
|
// For tests, re-use the api client from nfd-master
|
||||||
|
cli = u.nfdMaster.nfdClient
|
||||||
|
}
|
||||||
for u.processNodeFeatureGroupUpdateRequest(cli) {
|
for u.processNodeFeatureGroupUpdateRequest(cli) {
|
||||||
}
|
}
|
||||||
u.nfgWg.Done()
|
u.nfgWg.Done()
|
||||||
|
@ -149,10 +155,8 @@ func (u *updaterPool) start(parallelism int) {
|
||||||
for i := 0; i < parallelism; i++ {
|
for i := 0; i < parallelism; i++ {
|
||||||
u.wg.Add(1)
|
u.wg.Add(1)
|
||||||
go u.runNodeUpdater()
|
go u.runNodeUpdater()
|
||||||
if features.NFDFeatureGate.Enabled(features.NodeFeatureGroupAPI) {
|
u.nfgWg.Add(1)
|
||||||
u.nfgWg.Add(1)
|
go u.runNodeFeatureGroupUpdater()
|
||||||
go u.runNodeFeatureGroupUpdater()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
u.started = true
|
u.started = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
"github.com/stretchr/testify/mock"
|
|
||||||
"github.com/vektra/errors"
|
"github.com/vektra/errors"
|
||||||
fakeclient "k8s.io/client-go/kubernetes/fake"
|
fakeclient "k8s.io/client-go/kubernetes/fake"
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
"sigs.k8s.io/node-feature-discovery/source"
|
"sigs.k8s.io/node-feature-discovery/source"
|
||||||
"sigs.k8s.io/node-feature-discovery/source/cpu"
|
"sigs.k8s.io/node-feature-discovery/source/cpu"
|
||||||
|
@ -266,32 +264,3 @@ func TestCreateFeatureLabels(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAdvertiseFeatureLabels(t *testing.T) {
|
|
||||||
Convey("When advertising labels", t, func() {
|
|
||||||
w, err := NewNfdWorker(WithArgs(&Args{}), WithKubernetesClient(fakeclient.NewSimpleClientset()))
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
worker := w.(*nfdWorker)
|
|
||||||
|
|
||||||
mockClient := &labeler.MockLabelerClient{}
|
|
||||||
worker.grpcClient = mockClient
|
|
||||||
|
|
||||||
labels := map[string]string{"feature-1": "value-1"}
|
|
||||||
|
|
||||||
Convey("Correct labeling request is sent", func() {
|
|
||||||
mockClient.On("SetLabels", mock.AnythingOfType("*context.timerCtx"), mock.AnythingOfType("*labeler.SetLabelsRequest")).Return(&labeler.SetLabelsReply{}, nil)
|
|
||||||
err := worker.advertiseFeatureLabels(labels)
|
|
||||||
Convey("There should be no error", func() {
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Convey("Labeling request fails", func() {
|
|
||||||
mockErr := errors.New("mock-error")
|
|
||||||
mockClient.On("SetLabels", mock.AnythingOfType("*context.timerCtx"), mock.AnythingOfType("*labeler.SetLabelsRequest")).Return(&labeler.SetLabelsReply{}, mockErr)
|
|
||||||
err := worker.advertiseFeatureLabels(labels)
|
|
||||||
Convey("An error should be returned", func() {
|
|
||||||
So(err, ShouldEqual, mockErr)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,8 +17,6 @@ limitations under the License.
|
||||||
package nfdworker
|
package nfdworker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
@ -32,8 +30,6 @@ import (
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
|
||||||
"google.golang.org/grpc/health"
|
"google.golang.org/grpc/health"
|
||||||
"google.golang.org/grpc/health/grpc_health_v1"
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
@ -48,8 +44,6 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
nfdclient "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned"
|
nfdclient "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned"
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/features"
|
|
||||||
pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
||||||
"sigs.k8s.io/node-feature-discovery/source"
|
"sigs.k8s.io/node-feature-discovery/source"
|
||||||
|
@ -97,18 +91,13 @@ type Labels map[string]string
|
||||||
|
|
||||||
// Args are the command line arguments of NfdWorker.
|
// Args are the command line arguments of NfdWorker.
|
||||||
type Args struct {
|
type Args struct {
|
||||||
CaFile string
|
ConfigFile string
|
||||||
CertFile string
|
Klog map[string]*utils.KlogFlagVal
|
||||||
ConfigFile string
|
Kubeconfig string
|
||||||
KeyFile string
|
Oneshot bool
|
||||||
Klog map[string]*utils.KlogFlagVal
|
Options string
|
||||||
Kubeconfig string
|
MetricsPort int
|
||||||
Oneshot bool
|
GrpcHealthPort int
|
||||||
Options string
|
|
||||||
Server string
|
|
||||||
ServerNameOverride string
|
|
||||||
MetricsPort int
|
|
||||||
GrpcHealthPort int
|
|
||||||
|
|
||||||
Overrides ConfigOverrideArgs
|
Overrides ConfigOverrideArgs
|
||||||
}
|
}
|
||||||
|
@ -123,12 +112,9 @@ type ConfigOverrideArgs struct {
|
||||||
|
|
||||||
type nfdWorker struct {
|
type nfdWorker struct {
|
||||||
args Args
|
args Args
|
||||||
certWatch *utils.FsWatcher
|
|
||||||
clientConn *grpc.ClientConn
|
|
||||||
configFilePath string
|
configFilePath string
|
||||||
config *NFDConfig
|
config *NFDConfig
|
||||||
kubernetesNamespace string
|
kubernetesNamespace string
|
||||||
grpcClient pb.LabelerClient
|
|
||||||
healthServer *grpc.Server
|
healthServer *grpc.Server
|
||||||
k8sClient k8sclient.Interface
|
k8sClient k8sclient.Interface
|
||||||
nfdClient nfdclient.Interface
|
nfdClient nfdclient.Interface
|
||||||
|
@ -185,19 +171,6 @@ func NewNfdWorker(opts ...NfdWorkerOption) (NfdWorker, error) {
|
||||||
o.apply(nfd)
|
o.apply(nfd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check TLS related args
|
|
||||||
if nfd.args.CertFile != "" || nfd.args.KeyFile != "" || nfd.args.CaFile != "" {
|
|
||||||
if nfd.args.CertFile == "" {
|
|
||||||
return nfd, fmt.Errorf("-cert-file needs to be specified alongside -key-file and -ca-file")
|
|
||||||
}
|
|
||||||
if nfd.args.KeyFile == "" {
|
|
||||||
return nfd, fmt.Errorf("-key-file needs to be specified alongside -cert-file and -ca-file")
|
|
||||||
}
|
|
||||||
if nfd.args.CaFile == "" {
|
|
||||||
return nfd, fmt.Errorf("-ca-file needs to be specified alongside -cert-file and -key-file")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if nfd.args.ConfigFile != "" {
|
if nfd.args.ConfigFile != "" {
|
||||||
nfd.configFilePath = filepath.Clean(nfd.args.ConfigFile)
|
nfd.configFilePath = filepath.Clean(nfd.args.ConfigFile)
|
||||||
}
|
}
|
||||||
|
@ -303,14 +276,6 @@ func (w *nfdWorker) Run() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create watcher for TLS certificates
|
|
||||||
w.certWatch, err = utils.CreateFsWatcher(time.Second, w.args.CaFile, w.args.CertFile, w.args.KeyFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer w.grpcDisconnect()
|
|
||||||
|
|
||||||
// Create ticker for feature discovery and run feature discovery once before the loop.
|
// Create ticker for feature discovery and run feature discovery once before the loop.
|
||||||
labelTrigger := infiniteTicker{Ticker: time.NewTicker(1)}
|
labelTrigger := infiniteTicker{Ticker: time.NewTicker(1)}
|
||||||
labelTrigger.Reset(w.config.Core.SleepInterval.Duration)
|
labelTrigger.Reset(w.config.Core.SleepInterval.Duration)
|
||||||
|
@ -387,16 +352,11 @@ func (w *nfdWorker) Run() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-w.certWatch.Events:
|
|
||||||
klog.InfoS("TLS certificate update, renewing connection to nfd-master")
|
|
||||||
w.grpcDisconnect()
|
|
||||||
|
|
||||||
case <-w.stop:
|
case <-w.stop:
|
||||||
klog.InfoS("shutting down nfd-worker")
|
klog.InfoS("shutting down nfd-worker")
|
||||||
if w.healthServer != nil {
|
if w.healthServer != nil {
|
||||||
w.healthServer.GracefulStop()
|
w.healthServer.GracefulStop()
|
||||||
}
|
}
|
||||||
w.certWatch.Close()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,69 +367,6 @@ func (w *nfdWorker) Stop() {
|
||||||
close(w.stop)
|
close(w.stop)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getGrpcClient returns client connection to the NFD gRPC server. It creates a
|
|
||||||
// connection if one hasn't yet been established,.
|
|
||||||
func (w *nfdWorker) getGrpcClient() (pb.LabelerClient, error) {
|
|
||||||
if w.grpcClient != nil {
|
|
||||||
return w.grpcClient, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that if a connection already exists
|
|
||||||
if w.clientConn != nil {
|
|
||||||
return nil, fmt.Errorf("client connection already exists")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dial and create a client
|
|
||||||
dialCtx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
dialOpts := []grpc.DialOption{grpc.WithBlock()}
|
|
||||||
if w.args.CaFile != "" || w.args.CertFile != "" || w.args.KeyFile != "" {
|
|
||||||
// Load client cert for client authentication
|
|
||||||
cert, err := tls.LoadX509KeyPair(w.args.CertFile, w.args.KeyFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to load client certificate: %v", err)
|
|
||||||
}
|
|
||||||
// Load CA cert for server cert verification
|
|
||||||
caCert, err := os.ReadFile(w.args.CaFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to read root certificate file: %v", err)
|
|
||||||
}
|
|
||||||
caPool := x509.NewCertPool()
|
|
||||||
if ok := caPool.AppendCertsFromPEM(caCert); !ok {
|
|
||||||
return nil, fmt.Errorf("failed to add certificate from '%s'", w.args.CaFile)
|
|
||||||
}
|
|
||||||
// Create TLS config
|
|
||||||
tlsConfig := &tls.Config{
|
|
||||||
Certificates: []tls.Certificate{cert},
|
|
||||||
RootCAs: caPool,
|
|
||||||
ServerName: w.args.ServerNameOverride,
|
|
||||||
MinVersion: tls.VersionTLS13,
|
|
||||||
}
|
|
||||||
dialOpts = append(dialOpts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
|
|
||||||
} else {
|
|
||||||
dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
||||||
}
|
|
||||||
klog.InfoS("connecting to nfd-master", "address", w.args.Server)
|
|
||||||
conn, err := grpc.DialContext(dialCtx, w.args.Server, dialOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
w.clientConn = conn
|
|
||||||
|
|
||||||
w.grpcClient = pb.NewLabelerClient(w.clientConn)
|
|
||||||
|
|
||||||
return w.grpcClient, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// grpcDisconnect closes the gRPC connection to NFD master
|
|
||||||
func (w *nfdWorker) grpcDisconnect() {
|
|
||||||
if w.clientConn != nil {
|
|
||||||
klog.InfoS("closing connection to nfd-master")
|
|
||||||
w.clientConn.Close()
|
|
||||||
}
|
|
||||||
w.clientConn = nil
|
|
||||||
w.grpcClient = nil
|
|
||||||
}
|
|
||||||
func (c *coreConfig) sanitize() {
|
func (c *coreConfig) sanitize() {
|
||||||
if c.SleepInterval.Duration > 0 && c.SleepInterval.Duration < time.Second {
|
if c.SleepInterval.Duration > 0 && c.SleepInterval.Duration < time.Second {
|
||||||
klog.InfoS("too short sleep interval specified, forcing to 1s",
|
klog.InfoS("too short sleep interval specified, forcing to 1s",
|
||||||
|
@ -718,42 +615,9 @@ func getFeatureLabels(source source.LabelSource, labelWhiteList regexp.Regexp) (
|
||||||
|
|
||||||
// advertiseFeatures advertises the features of a Kubernetes node
|
// advertiseFeatures advertises the features of a Kubernetes node
|
||||||
func (w *nfdWorker) advertiseFeatures(labels Labels) error {
|
func (w *nfdWorker) advertiseFeatures(labels Labels) error {
|
||||||
if features.NFDFeatureGate.Enabled(features.NodeFeatureAPI) {
|
// Create/update NodeFeature CR object
|
||||||
// Create/update NodeFeature CR object
|
if err := w.updateNodeFeatureObject(labels); err != nil {
|
||||||
if err := w.updateNodeFeatureObject(labels); err != nil {
|
return fmt.Errorf("failed to advertise features (via CRD API): %w", err)
|
||||||
return fmt.Errorf("failed to advertise features (via CRD API): %w", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Create/update feature labels through gRPC connection to nfd-master
|
|
||||||
if err := w.advertiseFeatureLabels(labels); err != nil {
|
|
||||||
return fmt.Errorf("failed to advertise features (via gRPC): %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// advertiseFeatureLabels advertises the feature labels to a Kubernetes node
|
|
||||||
// via the NFD server.
|
|
||||||
func (w *nfdWorker) advertiseFeatureLabels(labels Labels) error {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
klog.InfoS("sending labeling request to nfd-master")
|
|
||||||
|
|
||||||
labelReq := pb.SetLabelsRequest{Labels: labels,
|
|
||||||
Features: source.GetAllFeatures(),
|
|
||||||
NfdVersion: version.Get(),
|
|
||||||
NodeName: utils.NodeName()}
|
|
||||||
|
|
||||||
cli, err := w.getGrpcClient()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = cli.SetLabels(ctx, &labelReq)
|
|
||||||
if err != nil {
|
|
||||||
klog.ErrorS(err, "failed to label node")
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -17,11 +17,8 @@ limitations under the License.
|
||||||
package nfdworker_test
|
package nfdworker_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
@ -33,17 +30,10 @@ import (
|
||||||
"sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
"sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/features"
|
"sigs.k8s.io/node-feature-discovery/pkg/features"
|
||||||
master "sigs.k8s.io/node-feature-discovery/pkg/nfd-master"
|
|
||||||
worker "sigs.k8s.io/node-feature-discovery/pkg/nfd-worker"
|
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/utils"
|
||||||
"sigs.k8s.io/node-feature-discovery/test/data"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type testContext struct {
|
|
||||||
master master.NfdMaster
|
|
||||||
errs chan error
|
|
||||||
}
|
|
||||||
|
|
||||||
func initializeFeatureGates() {
|
func initializeFeatureGates() {
|
||||||
if err := features.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates); err != nil {
|
if err := features.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates); err != nil {
|
||||||
klog.ErrorS(err, "failed to add default feature gates")
|
klog.ErrorS(err, "failed to add default feature gates")
|
||||||
|
@ -51,69 +41,6 @@ func initializeFeatureGates() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTest(args *master.Args) testContext {
|
|
||||||
// Fixed port and no-publish, for convenience
|
|
||||||
publish := true
|
|
||||||
args.Overrides = master.ConfigOverrideArgs{
|
|
||||||
NoPublish: &publish,
|
|
||||||
LabelWhiteList: &utils.RegexpVal{Regexp: *regexp.MustCompile("")},
|
|
||||||
}
|
|
||||||
args.Port = 8192
|
|
||||||
// Add FeatureGates flag
|
|
||||||
initializeFeatureGates()
|
|
||||||
_ = features.NFDMutableFeatureGate.OverrideDefault(features.NodeFeatureAPI, false)
|
|
||||||
_ = features.NFDMutableFeatureGate.OverrideDefault(features.NodeFeatureGroupAPI, false)
|
|
||||||
m, err := master.NewNfdMaster(
|
|
||||||
master.WithArgs(args),
|
|
||||||
master.WithKubernetesClient(fakeclient.NewSimpleClientset()))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Test setup failed: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
ctx := testContext{master: m, errs: make(chan error)}
|
|
||||||
|
|
||||||
// Run nfd-master instance, intended to be used as the server counterpart
|
|
||||||
go func() {
|
|
||||||
ctx.errs <- ctx.master.Run()
|
|
||||||
close(ctx.errs)
|
|
||||||
}()
|
|
||||||
ready := ctx.master.WaitForReady(5 * time.Second)
|
|
||||||
if !ready {
|
|
||||||
fmt.Println("Test setup failed: timeout while waiting for nfd-master")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
func teardownTest(ctx testContext) {
|
|
||||||
ctx.master.Stop()
|
|
||||||
for e := range ctx.errs {
|
|
||||||
if e != nil {
|
|
||||||
fmt.Printf("Error in test context: %v\n", e)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewNfdWorker(t *testing.T) {
|
|
||||||
Convey("When initializing new NfdWorker instance", t, func() {
|
|
||||||
Convey("When one of -cert-file, -key-file or -ca-file is missing", func() {
|
|
||||||
_, err := worker.NewNfdWorker(worker.WithArgs(&worker.Args{CertFile: "crt", KeyFile: "key"}),
|
|
||||||
worker.WithKubernetesClient(fakeclient.NewSimpleClientset()))
|
|
||||||
_, err2 := worker.NewNfdWorker(worker.WithArgs(&worker.Args{KeyFile: "key", CaFile: "ca"}),
|
|
||||||
worker.WithKubernetesClient(fakeclient.NewSimpleClientset()))
|
|
||||||
_, err3 := worker.NewNfdWorker(worker.WithArgs(&worker.Args{CertFile: "crt", CaFile: "ca"}),
|
|
||||||
worker.WithKubernetesClient(fakeclient.NewSimpleClientset()))
|
|
||||||
Convey("An error should be returned", func() {
|
|
||||||
So(err, ShouldNotBeNil)
|
|
||||||
So(err2, ShouldNotBeNil)
|
|
||||||
So(err3, ShouldNotBeNil)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRun(t *testing.T) {
|
func TestRun(t *testing.T) {
|
||||||
nfdCli := fakenfdclient.NewSimpleClientset()
|
nfdCli := fakenfdclient.NewSimpleClientset()
|
||||||
initializeFeatureGates()
|
initializeFeatureGates()
|
||||||
|
@ -207,36 +134,3 @@ func TestRun(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this test with the rest of the TLS code and docs.
|
|
||||||
// Also drop the certs from test/data/.
|
|
||||||
func TestRunTls(t *testing.T) {
|
|
||||||
t.Skip("gRPC cannot be enabled, NodeFeatureAPI GA")
|
|
||||||
masterArgs := &master.Args{
|
|
||||||
CaFile: data.FilePath("ca.crt"),
|
|
||||||
CertFile: data.FilePath("nfd-test-master.crt"),
|
|
||||||
KeyFile: data.FilePath("nfd-test-master.key"),
|
|
||||||
VerifyNodeName: false,
|
|
||||||
}
|
|
||||||
ctx := setupTest(masterArgs)
|
|
||||||
defer teardownTest(ctx)
|
|
||||||
Convey("When running nfd-worker against nfd-master with mutual TLS auth enabled", t, func() {
|
|
||||||
Convey("When publishing features from fake source", func() {
|
|
||||||
workerArgs := worker.Args{
|
|
||||||
CaFile: data.FilePath("ca.crt"),
|
|
||||||
CertFile: data.FilePath("nfd-test-worker.crt"),
|
|
||||||
KeyFile: data.FilePath("nfd-test-worker.key"),
|
|
||||||
Server: "localhost:8192",
|
|
||||||
ServerNameOverride: "nfd-test-master",
|
|
||||||
Oneshot: true,
|
|
||||||
Overrides: worker.ConfigOverrideArgs{LabelSources: &utils.StringSliceVal{"fake"}},
|
|
||||||
}
|
|
||||||
w, _ := worker.NewNfdWorker(worker.WithArgs(&workerArgs),
|
|
||||||
worker.WithKubernetesClient(fakeclient.NewSimpleClientset()))
|
|
||||||
err := w.Run()
|
|
||||||
Convey("No error should be returned", func() {
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 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 utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TlsConfig is a TLS config wrapper/helper for cert rotation
|
|
||||||
type TlsConfig struct {
|
|
||||||
sync.Mutex
|
|
||||||
config *tls.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetConfig returns the current TLS configuration. Intended to be used as the
|
|
||||||
// GetConfigForClient callback in tls.Config.
|
|
||||||
func (c *TlsConfig) GetConfig(*tls.ClientHelloInfo) (*tls.Config, error) {
|
|
||||||
c.Lock()
|
|
||||||
defer c.Unlock()
|
|
||||||
|
|
||||||
return c.config, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateConfig updates the wrapped TLS config
|
|
||||||
func (c *TlsConfig) UpdateConfig(certFile, keyFile, caFile string) error {
|
|
||||||
c.Lock()
|
|
||||||
defer c.Unlock()
|
|
||||||
|
|
||||||
// Load cert for authenticating this server
|
|
||||||
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to load server certificate: %w", err)
|
|
||||||
}
|
|
||||||
// Load CA cert for client cert verification
|
|
||||||
caCert, err := os.ReadFile(caFile)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to read root certificate file: %w", err)
|
|
||||||
}
|
|
||||||
caPool := x509.NewCertPool()
|
|
||||||
if ok := caPool.AppendCertsFromPEM(caCert); !ok {
|
|
||||||
return fmt.Errorf("failed to add certificate from '%s'", caFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create TLS config
|
|
||||||
c.config = &tls.Config{
|
|
||||||
Certificates: []tls.Certificate{cert},
|
|
||||||
ClientCAs: caPool,
|
|
||||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
|
||||||
GetConfigForClient: c.GetConfig,
|
|
||||||
MinVersion: tls.VersionTLS13,
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICAjCCAaygAwIBAgIJAOA69K1GekHnMA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV
|
|
||||||
BAYTAkZJMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
|
||||||
aWRnaXRzIFB0eSBMdGQxFDASBgNVBAMMC25mZC10ZXN0LWNhMB4XDTIwMTExODEz
|
|
||||||
MTQxNFoXDTMwMTExNjEzMTQxNFowWzELMAkGA1UEBhMCRkkxEzARBgNVBAgMClNv
|
|
||||||
bWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIG
|
|
||||||
A1UEAwwLbmZkLXRlc3QtY2EwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA/JUnIBRK
|
|
||||||
a3sktLZWAf2T6yAHXL5ZAqKRqQQABvCPKn1HBNdraDlmIrptrCBm8EaArmdMfdn0
|
|
||||||
F/G13eQpJD7NQQIDAQABo1MwUTAdBgNVHQ4EFgQUJM9Ncnmog7n3t5KA5SS67DTD
|
|
||||||
peIwHwYDVR0jBBgwFoAUJM9Ncnmog7n3t5KA5SS67DTDpeIwDwYDVR0TAQH/BAUw
|
|
||||||
AwEB/zANBgkqhkiG9w0BAQsFAANBAH25kXrAyI/akygdv77tQyz5Lc+wwLsduJfi
|
|
||||||
djDXYIfZSrUNaM7Jm4Wby1/0feeKEQjCOQ8Oa8SXn23A21SGhsc=
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2019 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 data
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
var packagePath string
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
_, thisFile, _, _ := runtime.Caller(0)
|
|
||||||
packagePath = filepath.Dir(thisFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func FilePath(filePath string) string {
|
|
||||||
return filepath.Join(packagePath, filePath)
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIBwzCCAW2gAwIBAgIJAMRplUIVEGN6MA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV
|
|
||||||
BAYTAkZJMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
|
||||||
aWRnaXRzIFB0eSBMdGQxFDASBgNVBAMMC25mZC10ZXN0LWNhMB4XDTIwMTExODEz
|
|
||||||
NTAzMVoXDTMwMTExNjEzNTAzMVowDTELMAkGA1UEBhMCRkkwgZ8wDQYJKoZIhvcN
|
|
||||||
AQEBBQADgY0AMIGJAoGBAOGUDjt7jPwZRoYLZVD8T9HnmRLZnCil4ai3JQpKUF3b
|
|
||||||
ONhEFdv23y3rVeGkqHsEYNcn//nxwedCYr6qZ8cNvvZC+x+I6IOq6VmFR94kmL8I
|
|
||||||
7IXPgX/3jylCxNpYb3tP4Dcpa4UX4YhQa/WB6tgWo+obvZAicKi/DIrE/sZDbbZJ
|
|
||||||
AgMBAAGjHjAcMBoGA1UdEQQTMBGCD25mZC10ZXN0LW1hc3RlcjANBgkqhkiG9w0B
|
|
||||||
AQsFAANBAOFHpexL1Ltl+fjRDY/P3gXe6YALJVZzXQfpQ4/xKP0wOWMFowcmnHaq
|
|
||||||
ew4vICQvfvO7I52UIE3d8srPv9ZPI8g=
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,16 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOGUDjt7jPwZRoYL
|
|
||||||
ZVD8T9HnmRLZnCil4ai3JQpKUF3bONhEFdv23y3rVeGkqHsEYNcn//nxwedCYr6q
|
|
||||||
Z8cNvvZC+x+I6IOq6VmFR94kmL8I7IXPgX/3jylCxNpYb3tP4Dcpa4UX4YhQa/WB
|
|
||||||
6tgWo+obvZAicKi/DIrE/sZDbbZJAgMBAAECgYEAvKHFQQJxA8LTEXZoE8/Zo4qK
|
|
||||||
m5OzHN6SFDaKV8+K4uFV6KsOqHEJcemwWE8LwEsJ/AFr8YOzhQIjdpMi0vZwrwWE
|
|
||||||
0wBTkKctYEpuKLCFROkIiDPV1c1m5i5+kjDpvHvhwnufIozgLz7rFcC5ucR5gSMq
|
|
||||||
Uy1V3sfF9DM0UBBuoX0CQQD3Ogmfgmffi8gCq1zsQcp99u5R3Yj/ApQjQgRz0k6g
|
|
||||||
IhbY1i3u+fY7pTc/nBO9ezbvy4SHFP0rkfVbINQ25mdnAkEA6ZVZxUmI0r3GnTsZ
|
|
||||||
Rrya2lYXA9KfhgLFvpx7eAaaejClQyCP+fpoyV3KXPlI9J9bWAazO4k0jbmeNEL9
|
|
||||||
F9DWzwJBAIdjfzWdQqlHcWcU1TSE6xGEkwq+GXIdxWZxluKev3QudviUgl8nAFO1
|
|
||||||
rMXnAWB5A6Laf19CfUrJCea32b+e+e0CQCdMW0gX8Q8ToqC9WqlN/feR2FlqTDBt
|
|
||||||
svs4tIUjB0ZbfNJoXhC+knaecvdlcWLGlMWgivMPSGo3umgshQxGtH0CQQDlTjdU
|
|
||||||
stoxEneM2vIv9doqmXo80zkoMIG4gdsaINnfcbpnh7Is+mEdDGll/eSrekgBDpGw
|
|
||||||
rk9C6sqYwFFCY3Re
|
|
||||||
-----END PRIVATE KEY-----
|
|
|
@ -1,12 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIBwzCCAW2gAwIBAgIJAMRplUIVEGN7MA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV
|
|
||||||
BAYTAkZJMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
|
||||||
aWRnaXRzIFB0eSBMdGQxFDASBgNVBAMMC25mZC10ZXN0LWNhMB4XDTIwMTExODEz
|
|
||||||
NTIxOFoXDTMwMTExNjEzNTIxOFowDTELMAkGA1UEBhMCRkkwgZ8wDQYJKoZIhvcN
|
|
||||||
AQEBBQADgY0AMIGJAoGBAOX+AzRK17SFuhgSeWrf+B8SZUEdBhZGjBK6ypmAZgMW
|
|
||||||
6JWwTbsdJRU6uorTX2XvgOtRolXbwSTwWjFpkvYgK0Eo8kKLU5tOE6XYi04UVYRv
|
|
||||||
Ha26pQKpfseUug641GOtUlWYUgGmvSMikEIilh+b/aAG+5/K+fNqi08fLmX6t2XL
|
|
||||||
AgMBAAGjHjAcMBoGA1UdEQQTMBGCD25mZC10ZXN0LXdvcmtlcjANBgkqhkiG9w0B
|
|
||||||
AQsFAANBAGuSwyPjduIQz4n7L+tRPs3+XPJ8fvbzC0pADYA0geow/m+X784If8nT
|
|
||||||
Pj+8quQn9zPsaQ+1bNahobTlHRmQcPE=
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,16 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOX+AzRK17SFuhgS
|
|
||||||
eWrf+B8SZUEdBhZGjBK6ypmAZgMW6JWwTbsdJRU6uorTX2XvgOtRolXbwSTwWjFp
|
|
||||||
kvYgK0Eo8kKLU5tOE6XYi04UVYRvHa26pQKpfseUug641GOtUlWYUgGmvSMikEIi
|
|
||||||
lh+b/aAG+5/K+fNqi08fLmX6t2XLAgMBAAECgYEAqsA7gMdP/iaKUvTkUASYIfl2
|
|
||||||
UzFJI6CcvgsP/4bkNcb8RqXuD81Dis9fT1I+sV9vR0YET9onO1V2oNjQ0wpvETjO
|
|
||||||
bk5veRfqFLOTavl64pAPGLEvOTWHSHQ9rtFZst1FFfehB1Vw69nBs9E40Zo2Y9yv
|
|
||||||
gkK+RIKUc2oPqMOigQECQQD8k2jxRX1COF+GO+pBTOTAr3pAmd0ahWAQGoqLwteQ
|
|
||||||
x+ARRZss1nuX0IGEyJ89hD6dHLv/FhhUxGE1R0xdQ31JAkEA6Rw5VYrAphATPCCX
|
|
||||||
h2gboAbHTOFAzwjnlW1pU6nlZI89kDAD3TF8d+eq906J8y7ji0YE89/G4HEzHqtQ
|
|
||||||
vMsucwJBAId2VAlauJRkga8PwVKmd+Vz98BgBTqtH9ljMr1EkbK/0EfTKieBHSZO
|
|
||||||
GLjrlKQ8ogxHlfh4lDIaZPxbMfSvNqkCQDkEfEmeHK0BtZK5bhbisg8cWVdGqXF6
|
|
||||||
fhqgnmimX8OO/cHs3KUX25gAhGLlRPzEdUe1orR8AcsYJSbVRHRJRl0CQQC7VBgp
|
|
||||||
04kaZzLFf61TmqMGVDoG2Wi5HwXYyzAEEEYFW61kwfZ6vuq3AP7NPMfW1F94welg
|
|
||||||
8LfkI2NBgjyKGiqn
|
|
||||||
-----END PRIVATE KEY-----
|
|
|
@ -1,12 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIBwzCCAW2gAwIBAgIJAMRplUIVEGN7MA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV
|
|
||||||
BAYTAkZJMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
|
||||||
aWRnaXRzIFB0eSBMdGQxFDASBgNVBAMMC25mZC10ZXN0LWNhMB4XDTIwMTExODEz
|
|
||||||
NTIxOFoXDTMwMTExNjEzNTIxOFowDTELMAkGA1UEBhMCRkkwgZ8wDQYJKoZIhvcN
|
|
||||||
AQEBBQADgY0AMIGJAoGBAOX+AzRK17SFuhgSeWrf+B8SZUEdBhZGjBK6ypmAZgMW
|
|
||||||
6JWwTbsdJRU6uorTX2XvgOtRolXbwSTwWjFpkvYgK0Eo8kKLU5tOE6XYi04UVYRv
|
|
||||||
Ha26pQKpfseUug641GOtUlWYUgGmvSMikEIilh+b/aAG+5/K+fNqi08fLmX6t2XL
|
|
||||||
AgMBAAGjHjAcMBoGA1UdEQQTMBGCD25mZC10ZXN0LXdvcmtlcjANBgkqhkiG9w0B
|
|
||||||
AQsFAANBAGuSwyPjduIQz4n7L+tRPs3+XPJ8fvbzC0pADYA0geow/m+X784If8nT
|
|
||||||
Pj+8quQn9zPsaQ+1bNahobTlHRmQcPE=
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,16 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOX+AzRK17SFuhgS
|
|
||||||
eWrf+B8SZUEdBhZGjBK6ypmAZgMW6JWwTbsdJRU6uorTX2XvgOtRolXbwSTwWjFp
|
|
||||||
kvYgK0Eo8kKLU5tOE6XYi04UVYRvHa26pQKpfseUug641GOtUlWYUgGmvSMikEIi
|
|
||||||
lh+b/aAG+5/K+fNqi08fLmX6t2XLAgMBAAECgYEAqsA7gMdP/iaKUvTkUASYIfl2
|
|
||||||
UzFJI6CcvgsP/4bkNcb8RqXuD81Dis9fT1I+sV9vR0YET9onO1V2oNjQ0wpvETjO
|
|
||||||
bk5veRfqFLOTavl64pAPGLEvOTWHSHQ9rtFZst1FFfehB1Vw69nBs9E40Zo2Y9yv
|
|
||||||
gkK+RIKUc2oPqMOigQECQQD8k2jxRX1COF+GO+pBTOTAr3pAmd0ahWAQGoqLwteQ
|
|
||||||
x+ARRZss1nuX0IGEyJ89hD6dHLv/FhhUxGE1R0xdQ31JAkEA6Rw5VYrAphATPCCX
|
|
||||||
h2gboAbHTOFAzwjnlW1pU6nlZI89kDAD3TF8d+eq906J8y7ji0YE89/G4HEzHqtQ
|
|
||||||
vMsucwJBAId2VAlauJRkga8PwVKmd+Vz98BgBTqtH9ljMr1EkbK/0EfTKieBHSZO
|
|
||||||
GLjrlKQ8ogxHlfh4lDIaZPxbMfSvNqkCQDkEfEmeHK0BtZK5bhbisg8cWVdGqXF6
|
|
||||||
fhqgnmimX8OO/cHs3KUX25gAhGLlRPzEdUe1orR8AcsYJSbVRHRJRl0CQQC7VBgp
|
|
||||||
04kaZzLFf61TmqMGVDoG2Wi5HwXYyzAEEEYFW61kwfZ6vuq3AP7NPMfW1F94welg
|
|
||||||
8LfkI2NBgjyKGiqn
|
|
||||||
-----END PRIVATE KEY-----
|
|
|
@ -256,7 +256,7 @@ func nfdWorkerSpec(opts ...SpecOption) *corev1.PodSpec {
|
||||||
Name: "node-feature-discovery",
|
Name: "node-feature-discovery",
|
||||||
ImagePullPolicy: pullPolicy(),
|
ImagePullPolicy: pullPolicy(),
|
||||||
Command: []string{"nfd-worker"},
|
Command: []string{"nfd-worker"},
|
||||||
Args: []string{"-server=nfd-master-e2e:8080"},
|
Args: []string{},
|
||||||
Env: []corev1.EnvVar{
|
Env: []corev1.EnvVar{
|
||||||
{
|
{
|
||||||
Name: "NODE_NAME",
|
Name: "NODE_NAME",
|
||||||
|
|
Loading…
Reference in a new issue