1
0
Fork 0
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:
Carlos Eduardo Arango Gutierrez 2024-10-25 19:21:40 +02:00
parent c7e7877359
commit 0bd82cf82a
No known key found for this signature in database
GPG key ID: 42D9CB42F300A852
30 changed files with 51 additions and 1499 deletions

View file

@ -80,16 +80,6 @@ func main() {
args.Overrides.ResyncPeriod = overrides.ResyncPeriod
case "nfd-api-parallelism":
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) {
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", "",
"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",
"Config file to use.")
flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
"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,
"Port on which to expose metrics.")
flagset.IntVar(&args.GrpcHealthPort, "grpc-health", 8082,
"Port on which to expose the grpc health endpoint.")
flagset.BoolVar(&args.Prune, "prune", false,
"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", "",
"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")

View file

@ -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.")
}
// 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
utils.ConfigureGrpcKlog()
@ -119,17 +103,8 @@ func parseArgs(flags *flag.FlagSet, osArgs ...string) *worker.Args {
func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs) {
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",
"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", "",
"Kubeconfig to use")
flagset.BoolVar(&args.Oneshot, "oneshot", false,
@ -141,12 +116,6 @@ func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs)
flagset.StringVar(&args.Options, "options", "",
"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")
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)

View file

@ -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 }}

View file

@ -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 }}

View file

@ -103,11 +103,7 @@ spec:
{{- if .Values.master.instance | empty | not }}
- "-instance={{ .Values.master.instance }}"
{{- end }}
{{- if not .Values.featureGates.NodeFeatureAPI }}
- "-port={{ .Values.master.port | default "8080" }}"
{{- else if gt (int .Values.master.replicaCount) 1 }}
- "-enable-leader-election"
{{- end }}
{{- if .Values.master.extraLabelNs | empty | not }}
- "-extra-label-ns={{- join "," .Values.master.extraLabelNs }}"
{{- end }}
@ -120,12 +116,6 @@ spec:
{{- if .Values.master.enableTaints }}
- "-enable-taints"
{{- 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 }}
- "-featurerules-controller={{ .Values.master.featureRulesController }}"
{{- end }}
@ -135,11 +125,6 @@ spec:
{{- if .Values.master.nfdApiParallelism | empty | not }}
- "-nfd-api-parallelism={{ .Values.master.nfdApiParallelism }}"
{{- 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
{{- range $key, $value := .Values.featureGates }}
- "-feature-gates={{ $key }}={{ $value }}"
@ -150,20 +135,10 @@ spec:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
{{- if .Values.tls.enable }}
- name: nfd-master-cert
mountPath: "/etc/kubernetes/node-feature-discovery/certs"
readOnly: true
{{- end }}
- name: nfd-master-conf
mountPath: "/etc/kubernetes/node-feature-discovery"
readOnly: true
volumes:
{{- if .Values.tls.enable }}
- name: nfd-master-cert
secret:
secretName: nfd-master-cert
{{- end }}
- name: nfd-master-conf
configMap:
name: {{ include "node-feature-discovery.fullname" . }}-master-conf

View file

@ -103,11 +103,6 @@ spec:
{{- else }}
- "-watch-namespace=*"
{{- 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 }}
- "-pods-fingerprint=false"
{{- end }}
@ -142,11 +137,6 @@ spec:
mountPath: /host-var/lib/kubelet
readOnly: true
{{- 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
mountPath: "/etc/kubernetes/node-feature-discovery"
readOnly: true
@ -182,12 +172,6 @@ spec:
items:
- key: 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 }}
nodeSelector:

View file

@ -103,11 +103,6 @@ spec:
{{- if not .Values.featureGates.NodeFeatureAPI }}
- "-server={{ include "node-feature-discovery.fullname" . }}-master:{{ .Values.master.service.port }}"
{{- 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
{{- range $key, $value := .Values.featureGates }}
- "-feature-gates={{ $key }}={{ $value }}"
@ -155,11 +150,6 @@ spec:
- name: nfd-worker-conf
mountPath: "/etc/kubernetes/node-feature-discovery"
readOnly: true
{{- if .Values.tls.enable }}
- name: nfd-worker-cert
mountPath: "/etc/kubernetes/node-feature-discovery/certs"
readOnly: true
{{- end }}
volumes:
- name: host-boot
hostPath:
@ -196,11 +186,6 @@ spec:
items:
- key: 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 }}
nodeSelector:
{{- toYaml . | nindent 8 }}

View file

@ -68,10 +68,6 @@ master:
# retryPeriod: 2s
# nfdApiParallelism: 10
### <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
healthPort: 8082
instance:
@ -81,7 +77,6 @@ master:
extraLabelNs: []
resourceLabels: []
enableTaints: false
crdController: null
featureRulesController: null
nfdApiParallelism: null
deploymentAnnotations: {}
@ -601,18 +596,6 @@ gc:
# specify how many old ReplicaSets for the Deployment to retain.
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:
enable: false
scrapeInterval: 10s

4
go.mod
View file

@ -4,7 +4,6 @@ go 1.23.0
require (
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/uuid v1.6.0
github.com/jaypipes/ghw v0.13.0
@ -23,7 +22,6 @@ require (
golang.org/x/net v0.30.0
golang.org/x/time v0.7.0
google.golang.org/grpc v1.63.2
google.golang.org/protobuf v1.34.2
k8s.io/api v0.30.3
k8s.io/apiextensions-apiserver 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/gogo/protobuf v1.3.2 // 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/gnostic-models v0.6.8 // 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/googleapis/api 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/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

View file

@ -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

View file

@ -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",
}

View file

@ -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 {
}

View file

@ -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
}

View file

@ -40,12 +40,12 @@ import (
clienttesting "k8s.io/client-go/testing"
"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"
nfdscheme "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/scheme"
nfdinformers "sigs.k8s.io/node-feature-discovery/api/generated/informers/externalversions"
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/labeler"
"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 }}
}
// 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 {
nfdCli := fakenfdclient.NewSimpleClientset()
defaultOpts := []NfdMasterOption{
withNodeName(testNodeName),
withConfig(&NFDConfig{Restrictions: Restrictions{AllowOverwrite: true}}),
WithKubernetesClient(fakeclient.NewSimpleClientset()),
withNFDClient(nfdCli),
}
m, err := NewNfdMaster(append(defaultOpts, opts...)...)
if err != nil {
panic(err)
}
// Add FeatureGates
if err := features.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates); err != nil {
panic(err)
}
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) {
fakeMaster := newFakeMaster()
fakeMaster.config.ExtraLabelNs = map[string]struct{}{"example.io": {}}

View file

@ -17,8 +17,6 @@ limitations under the License.
package nfdmaster
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"maps"
@ -35,10 +33,8 @@ import (
"github.com/google/uuid"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/peer"
corev1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
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/validate"
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"
klogutils "sigs.k8s.io/node-feature-discovery/pkg/utils/klog"
"sigs.k8s.io/node-feature-discovery/pkg/version"
@ -122,20 +117,15 @@ type ConfigOverrideArgs struct {
// Args holds command line arguments
type Args struct {
CaFile string
CertFile string
ConfigFile string
Instance string
KeyFile string
Klog map[string]*utils.KlogFlagVal
Kubeconfig string
CrdController bool
Port int
ConfigFile string
Instance string
Klog map[string]*utils.KlogFlagVal
Kubeconfig string
Port int
// 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).
GrpcHealthPort int
Prune bool
VerifyNodeName bool
Options string
EnableLeaderElection bool
MetricsPort int
@ -167,7 +157,7 @@ type nfdMaster struct {
ready chan struct{}
kubeconfig *restclient.Config
k8sClient k8sclient.Interface
nfdClient *nfdclientset.Clientset
nfdClient nfdclientset.Interface
updaterPool *updaterPool
deniedNs
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 != "" {
nfd.configFilePath = filepath.Clean(nfd.args.ConfigFile)
}
@ -232,11 +209,11 @@ func NewNfdMaster(opts ...NfdMasterOption) (NfdMaster, error) {
return nfd, err
}
nfd.kubeconfig = kubeconfig
nfdClient, err := nfdclientset.NewForConfig(nfd.kubeconfig)
c, err := nfdclientset.NewForConfig(nfd.kubeconfig)
if err != nil {
return nfd, err
}
nfd.nfdClient = nfdClient
nfd.nfdClient = c
}
nfd.updaterPool = newUpdaterPool(nfd)
@ -311,11 +288,8 @@ func (m *nfdMaster) Run() error {
return m.prune()
}
if m.args.CrdController {
err := m.startNfdApiController()
if err != nil {
return err
}
if err := m.startNfdApiController(); err != nil {
return err
}
m.updaterPool.start(m.config.NfdApiParallelism)
@ -344,14 +318,6 @@ func (m *nfdMaster) Run() error {
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.
if m.nfdController != nil {
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")
grpcErr := make(chan error)
if m.args.GrpcHealthPort != 0 {
if err := m.startGrpcHealthServer(grpcErr); err != nil {
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
}
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.
func (m *nfdMaster) nfdAPIUpdateHandler() {
// We want to unconditionally update all nodes at startup if gRPC is
// disabled (i.e. NodeFeature API is enabled)
updateAll := nfdfeatures.NFDFeatureGate.Enabled(nfdfeatures.NodeFeatureAPI)
updateAll := true
updateNodes := make(map[string]struct{})
nodeFeatureGroup := make(map[string]struct{})
updateAllNodeFeatureGroups := false
@ -717,18 +627,6 @@ func filterTaints(taints []corev1.Taint) []corev1.Taint {
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 {
for deniedNs := range normalDeniedNs {
if labelNs == deniedNs {
@ -743,38 +641,6 @@ func isNamespaceDenied(labelNs string, wildcardDeniedNs map[string]struct{}, nor
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 {
klog.InfoS("will process all nodes in the cluster")
@ -918,7 +784,7 @@ func (m *nfdMaster) nfdAPIUpdateAllNodeFeatureGroups() error {
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))
if m.nfdController == nil || m.nfdController.featureLister == nil {
return nil
@ -1146,30 +1012,6 @@ func (m *nfdMaster) setTaints(cli k8sclient.Interface, taints []corev1.Taint, no
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) {
if m.nfdController == nil {
return nil, nil, nil, nil
@ -1533,7 +1375,6 @@ func (m *nfdMaster) startNfdApiController() error {
}
klog.InfoS("starting the nfd api controller")
m.nfdController, err = newNfdController(kubeconfig, nfdApiControllerOptions{
DisableNodeFeature: !nfdfeatures.NFDFeatureGate.Enabled(nfdfeatures.NodeFeatureAPI),
ResyncPeriod: m.config.ResyncPeriod.Duration,
K8sClient: m.k8sClient,
NodeFeatureNamespaceSelector: m.config.Restrictions.NodeFeatureNamespaceSelector,

View file

@ -26,23 +26,11 @@ import (
func TestNewNfdMaster(t *testing.T) {
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() {
_, err := m.NewNfdMaster(
m.WithArgs(&m.Args{
CertFile: "crt",
KeyFile: "key",
CaFile: "ca",
ConfigFile: "master-config.yaml"}),
ConfigFile: "master-config.yaml",
}),
m.WithKubernetesClient(fakeclient.NewSimpleClientset()))
Convey("An error should not be returned", func() {
So(err, ShouldBeNil)

View file

@ -27,7 +27,6 @@ import (
"k8s.io/klog/v2"
nfdclientset "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned"
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
"sigs.k8s.io/node-feature-discovery/pkg/features"
)
type updaterPool struct {
@ -120,7 +119,14 @@ func (u *updaterPool) processNodeFeatureGroupUpdateRequest(cli nfdclientset.Inte
}
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) {
}
u.nfgWg.Done()
@ -149,10 +155,8 @@ func (u *updaterPool) start(parallelism int) {
for i := 0; i < parallelism; i++ {
u.wg.Add(1)
go u.runNodeUpdater()
if features.NFDFeatureGate.Enabled(features.NodeFeatureGroupAPI) {
u.nfgWg.Add(1)
go u.runNodeFeatureGroupUpdater()
}
u.nfgWg.Add(1)
go u.runNodeFeatureGroupUpdater()
}
u.started = true
}

View file

@ -24,12 +24,10 @@ import (
"time"
. "github.com/smartystreets/goconvey/convey"
"github.com/stretchr/testify/mock"
"github.com/vektra/errors"
fakeclient "k8s.io/client-go/kubernetes/fake"
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/source"
"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)
})
})
})
}

View file

@ -17,8 +17,6 @@ limitations under the License.
package nfdworker
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"net"
@ -32,8 +30,6 @@ import (
"golang.org/x/exp/maps"
"golang.org/x/net/context"
"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/grpc_health_v1"
"k8s.io/apimachinery/pkg/api/errors"
@ -48,8 +44,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
nfdclient "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned"
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/version"
"sigs.k8s.io/node-feature-discovery/source"
@ -97,18 +91,13 @@ type Labels map[string]string
// Args are the command line arguments of NfdWorker.
type Args struct {
CaFile string
CertFile string
ConfigFile string
KeyFile string
Klog map[string]*utils.KlogFlagVal
Kubeconfig string
Oneshot bool
Options string
Server string
ServerNameOverride string
MetricsPort int
GrpcHealthPort int
ConfigFile string
Klog map[string]*utils.KlogFlagVal
Kubeconfig string
Oneshot bool
Options string
MetricsPort int
GrpcHealthPort int
Overrides ConfigOverrideArgs
}
@ -123,12 +112,9 @@ type ConfigOverrideArgs struct {
type nfdWorker struct {
args Args
certWatch *utils.FsWatcher
clientConn *grpc.ClientConn
configFilePath string
config *NFDConfig
kubernetesNamespace string
grpcClient pb.LabelerClient
healthServer *grpc.Server
k8sClient k8sclient.Interface
nfdClient nfdclient.Interface
@ -185,19 +171,6 @@ func NewNfdWorker(opts ...NfdWorkerOption) (NfdWorker, error) {
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 != "" {
nfd.configFilePath = filepath.Clean(nfd.args.ConfigFile)
}
@ -303,14 +276,6 @@ func (w *nfdWorker) Run() error {
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.
labelTrigger := infiniteTicker{Ticker: time.NewTicker(1)}
labelTrigger.Reset(w.config.Core.SleepInterval.Duration)
@ -387,16 +352,11 @@ func (w *nfdWorker) Run() error {
return err
}
case <-w.certWatch.Events:
klog.InfoS("TLS certificate update, renewing connection to nfd-master")
w.grpcDisconnect()
case <-w.stop:
klog.InfoS("shutting down nfd-worker")
if w.healthServer != nil {
w.healthServer.GracefulStop()
}
w.certWatch.Close()
return nil
}
}
@ -407,69 +367,6 @@ func (w *nfdWorker) 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() {
if c.SleepInterval.Duration > 0 && c.SleepInterval.Duration < time.Second {
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
func (w *nfdWorker) advertiseFeatures(labels Labels) error {
if features.NFDFeatureGate.Enabled(features.NodeFeatureAPI) {
// Create/update NodeFeature CR object
if err := w.updateNodeFeatureObject(labels); err != nil {
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
// Create/update NodeFeature CR object
if err := w.updateNodeFeatureObject(labels); err != nil {
return fmt.Errorf("failed to advertise features (via CRD API): %w", err)
}
return nil

View file

@ -17,11 +17,8 @@ limitations under the License.
package nfdworker_test
import (
"fmt"
"os"
"regexp"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
"golang.org/x/net/context"
@ -33,17 +30,10 @@ import (
"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"
master "sigs.k8s.io/node-feature-discovery/pkg/nfd-master"
worker "sigs.k8s.io/node-feature-discovery/pkg/nfd-worker"
"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() {
if err := features.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates); err != nil {
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) {
nfdCli := fakenfdclient.NewSimpleClientset()
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)
})
})
})
}

View file

@ -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
}

View file

@ -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-----

View file

@ -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)
}

View file

@ -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-----

View file

@ -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-----

View file

@ -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-----

View file

@ -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-----

View file

@ -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-----

View file

@ -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-----

View file

@ -256,7 +256,7 @@ func nfdWorkerSpec(opts ...SpecOption) *corev1.PodSpec {
Name: "node-feature-discovery",
ImagePullPolicy: pullPolicy(),
Command: []string{"nfd-worker"},
Args: []string{"-server=nfd-master-e2e:8080"},
Args: []string{},
Env: []corev1.EnvVar{
{
Name: "NODE_NAME",