1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2024-12-14 11:57:51 +00:00

Merge branch 'kubernetes-sigs:master' into crds-in-subchart

This commit is contained in:
Carlos M. 2024-11-11 13:18:52 +01:00 committed by GitHub
commit 3f3ab44cb8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
70 changed files with 545 additions and 3114 deletions

View file

@ -19,8 +19,10 @@ Please do not remove items from the checklist
- [ ] Upload release artefacts generated by `prepare-release.sh` script above to the draft release
- [ ] An OWNER runs
`git tag -s -m "NFD release $VERSION" $VERSION`
- [ ] An OWNER runs
`git tag -s -m "NFD API release $VERSION" api/nfd/$VERSION`
- [ ] An OWNER pushes the tag with
`git push $VERSION`
`git push $VERSION api/nfd/$VERSION`
- Triggers prow to build and publish a staging container image
`gcr.io/k8s-staging-nfd/node-feature-discovery:$VERSION`
- Triggers build of the documentation and publish it at

View file

@ -28,8 +28,10 @@ Please do not remove items from the checklist
- [ ] Upload release artefacts generated by `prepare-release.sh` script above to the draft release
- [ ] An OWNER runs
`git tag -s -m "NFD release $VERSION" $VERSION`
- [ ] An OWNER runs
`git tag -s -m "NFD API release $VERSION" api/nfd/$VERSION`
- [ ] An OWNER pushes the tag with
`git push $VERSION`
`git push $VERSION api/nfd/$VERSION`
- Triggers prow to build and publish a staging container image
`gcr.io/k8s-staging-nfd/node-feature-discovery:$VERSION`
- Triggers build of the documentation and publish it at

View file

@ -4,8 +4,8 @@ FROM ${BUILDER_IMAGE} as builder
# Install tools
RUN --mount=type=cache,target=/go/pkg/mod/ \
go install github.com/vektra/mockery/v2@v2.42.0 && \
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0 && \
go install golang.org/x/tools/cmd/goimports@v0.11.0 && \
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.3 && \
go install golang.org/x/tools/cmd/goimports@v0.25.0 && \
go install github.com/golang/protobuf/protoc-gen-go@v1.4.3
RUN apt-get update && apt-get install unzip

View file

@ -31,8 +31,12 @@ import (
// NewSimpleClientset returns a clientset that will respond with the provided objects.
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
// without applying any validations and/or defaults. It shouldn't be considered a replacement
// without applying any field management, validations and/or defaults. It shouldn't be considered a replacement
// for a real clientset and is mostly useful in simple unit tests.
//
// DEPRECATED: NewClientset replaces this with support for field management, which significantly improves
// server side apply testing. NewClientset is only available when apply configurations are generated (e.g.
// via --with-applyconfig).
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
for _, obj := range objects {

View file

@ -41,22 +41,24 @@ var nodefeaturesKind = v1alpha1.SchemeGroupVersion.WithKind("NodeFeature")
// Get takes name of the nodeFeature, and returns the corresponding nodeFeature object, and an error if there is any.
func (c *FakeNodeFeatures) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.NodeFeature, err error) {
emptyResult := &v1alpha1.NodeFeature{}
obj, err := c.Fake.
Invokes(testing.NewGetAction(nodefeaturesResource, c.ns, name), &v1alpha1.NodeFeature{})
Invokes(testing.NewGetActionWithOptions(nodefeaturesResource, c.ns, name, options), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeature), err
}
// List takes label and field selectors, and returns the list of NodeFeatures that match those selectors.
func (c *FakeNodeFeatures) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.NodeFeatureList, err error) {
emptyResult := &v1alpha1.NodeFeatureList{}
obj, err := c.Fake.
Invokes(testing.NewListAction(nodefeaturesResource, nodefeaturesKind, c.ns, opts), &v1alpha1.NodeFeatureList{})
Invokes(testing.NewListActionWithOptions(nodefeaturesResource, nodefeaturesKind, c.ns, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
@ -75,28 +77,30 @@ func (c *FakeNodeFeatures) List(ctx context.Context, opts v1.ListOptions) (resul
// Watch returns a watch.Interface that watches the requested nodeFeatures.
func (c *FakeNodeFeatures) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewWatchAction(nodefeaturesResource, c.ns, opts))
InvokesWatch(testing.NewWatchActionWithOptions(nodefeaturesResource, c.ns, opts))
}
// Create takes the representation of a nodeFeature and creates it. Returns the server's representation of the nodeFeature, and an error, if there is any.
func (c *FakeNodeFeatures) Create(ctx context.Context, nodeFeature *v1alpha1.NodeFeature, opts v1.CreateOptions) (result *v1alpha1.NodeFeature, err error) {
emptyResult := &v1alpha1.NodeFeature{}
obj, err := c.Fake.
Invokes(testing.NewCreateAction(nodefeaturesResource, c.ns, nodeFeature), &v1alpha1.NodeFeature{})
Invokes(testing.NewCreateActionWithOptions(nodefeaturesResource, c.ns, nodeFeature, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeature), err
}
// Update takes the representation of a nodeFeature and updates it. Returns the server's representation of the nodeFeature, and an error, if there is any.
func (c *FakeNodeFeatures) Update(ctx context.Context, nodeFeature *v1alpha1.NodeFeature, opts v1.UpdateOptions) (result *v1alpha1.NodeFeature, err error) {
emptyResult := &v1alpha1.NodeFeature{}
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(nodefeaturesResource, c.ns, nodeFeature), &v1alpha1.NodeFeature{})
Invokes(testing.NewUpdateActionWithOptions(nodefeaturesResource, c.ns, nodeFeature, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeature), err
}
@ -111,7 +115,7 @@ func (c *FakeNodeFeatures) Delete(ctx context.Context, name string, opts v1.Dele
// DeleteCollection deletes a collection of objects.
func (c *FakeNodeFeatures) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(nodefeaturesResource, c.ns, listOpts)
action := testing.NewDeleteCollectionActionWithOptions(nodefeaturesResource, c.ns, opts, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha1.NodeFeatureList{})
return err
@ -119,11 +123,12 @@ func (c *FakeNodeFeatures) DeleteCollection(ctx context.Context, opts v1.DeleteO
// Patch applies the patch and returns the patched nodeFeature.
func (c *FakeNodeFeatures) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeature, err error) {
emptyResult := &v1alpha1.NodeFeature{}
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(nodefeaturesResource, c.ns, name, pt, data, subresources...), &v1alpha1.NodeFeature{})
Invokes(testing.NewPatchSubresourceActionWithOptions(nodefeaturesResource, c.ns, name, pt, data, opts, subresources...), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeature), err
}

View file

@ -41,22 +41,24 @@ var nodefeaturegroupsKind = v1alpha1.SchemeGroupVersion.WithKind("NodeFeatureGro
// Get takes name of the nodeFeatureGroup, and returns the corresponding nodeFeatureGroup object, and an error if there is any.
func (c *FakeNodeFeatureGroups) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.NodeFeatureGroup, err error) {
emptyResult := &v1alpha1.NodeFeatureGroup{}
obj, err := c.Fake.
Invokes(testing.NewGetAction(nodefeaturegroupsResource, c.ns, name), &v1alpha1.NodeFeatureGroup{})
Invokes(testing.NewGetActionWithOptions(nodefeaturegroupsResource, c.ns, name, options), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureGroup), err
}
// List takes label and field selectors, and returns the list of NodeFeatureGroups that match those selectors.
func (c *FakeNodeFeatureGroups) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.NodeFeatureGroupList, err error) {
emptyResult := &v1alpha1.NodeFeatureGroupList{}
obj, err := c.Fake.
Invokes(testing.NewListAction(nodefeaturegroupsResource, nodefeaturegroupsKind, c.ns, opts), &v1alpha1.NodeFeatureGroupList{})
Invokes(testing.NewListActionWithOptions(nodefeaturegroupsResource, nodefeaturegroupsKind, c.ns, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
@ -75,40 +77,43 @@ func (c *FakeNodeFeatureGroups) List(ctx context.Context, opts v1.ListOptions) (
// Watch returns a watch.Interface that watches the requested nodeFeatureGroups.
func (c *FakeNodeFeatureGroups) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewWatchAction(nodefeaturegroupsResource, c.ns, opts))
InvokesWatch(testing.NewWatchActionWithOptions(nodefeaturegroupsResource, c.ns, opts))
}
// Create takes the representation of a nodeFeatureGroup and creates it. Returns the server's representation of the nodeFeatureGroup, and an error, if there is any.
func (c *FakeNodeFeatureGroups) Create(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.CreateOptions) (result *v1alpha1.NodeFeatureGroup, err error) {
emptyResult := &v1alpha1.NodeFeatureGroup{}
obj, err := c.Fake.
Invokes(testing.NewCreateAction(nodefeaturegroupsResource, c.ns, nodeFeatureGroup), &v1alpha1.NodeFeatureGroup{})
Invokes(testing.NewCreateActionWithOptions(nodefeaturegroupsResource, c.ns, nodeFeatureGroup, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureGroup), err
}
// Update takes the representation of a nodeFeatureGroup and updates it. Returns the server's representation of the nodeFeatureGroup, and an error, if there is any.
func (c *FakeNodeFeatureGroups) Update(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (result *v1alpha1.NodeFeatureGroup, err error) {
emptyResult := &v1alpha1.NodeFeatureGroup{}
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(nodefeaturegroupsResource, c.ns, nodeFeatureGroup), &v1alpha1.NodeFeatureGroup{})
Invokes(testing.NewUpdateActionWithOptions(nodefeaturegroupsResource, c.ns, nodeFeatureGroup, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureGroup), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeNodeFeatureGroups) UpdateStatus(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (*v1alpha1.NodeFeatureGroup, error) {
func (c *FakeNodeFeatureGroups) UpdateStatus(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (result *v1alpha1.NodeFeatureGroup, err error) {
emptyResult := &v1alpha1.NodeFeatureGroup{}
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(nodefeaturegroupsResource, "status", c.ns, nodeFeatureGroup), &v1alpha1.NodeFeatureGroup{})
Invokes(testing.NewUpdateSubresourceActionWithOptions(nodefeaturegroupsResource, "status", c.ns, nodeFeatureGroup, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureGroup), err
}
@ -123,7 +128,7 @@ func (c *FakeNodeFeatureGroups) Delete(ctx context.Context, name string, opts v1
// DeleteCollection deletes a collection of objects.
func (c *FakeNodeFeatureGroups) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(nodefeaturegroupsResource, c.ns, listOpts)
action := testing.NewDeleteCollectionActionWithOptions(nodefeaturegroupsResource, c.ns, opts, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha1.NodeFeatureGroupList{})
return err
@ -131,11 +136,12 @@ func (c *FakeNodeFeatureGroups) DeleteCollection(ctx context.Context, opts v1.De
// Patch applies the patch and returns the patched nodeFeatureGroup.
func (c *FakeNodeFeatureGroups) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeatureGroup, err error) {
emptyResult := &v1alpha1.NodeFeatureGroup{}
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(nodefeaturegroupsResource, c.ns, name, pt, data, subresources...), &v1alpha1.NodeFeatureGroup{})
Invokes(testing.NewPatchSubresourceActionWithOptions(nodefeaturegroupsResource, c.ns, name, pt, data, opts, subresources...), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureGroup), err
}

View file

@ -40,20 +40,22 @@ var nodefeaturerulesKind = v1alpha1.SchemeGroupVersion.WithKind("NodeFeatureRule
// Get takes name of the nodeFeatureRule, and returns the corresponding nodeFeatureRule object, and an error if there is any.
func (c *FakeNodeFeatureRules) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.NodeFeatureRule, err error) {
emptyResult := &v1alpha1.NodeFeatureRule{}
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(nodefeaturerulesResource, name), &v1alpha1.NodeFeatureRule{})
Invokes(testing.NewRootGetActionWithOptions(nodefeaturerulesResource, name, options), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureRule), err
}
// List takes label and field selectors, and returns the list of NodeFeatureRules that match those selectors.
func (c *FakeNodeFeatureRules) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.NodeFeatureRuleList, err error) {
emptyResult := &v1alpha1.NodeFeatureRuleList{}
obj, err := c.Fake.
Invokes(testing.NewRootListAction(nodefeaturerulesResource, nodefeaturerulesKind, opts), &v1alpha1.NodeFeatureRuleList{})
Invokes(testing.NewRootListActionWithOptions(nodefeaturerulesResource, nodefeaturerulesKind, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
@ -72,25 +74,27 @@ func (c *FakeNodeFeatureRules) List(ctx context.Context, opts v1.ListOptions) (r
// Watch returns a watch.Interface that watches the requested nodeFeatureRules.
func (c *FakeNodeFeatureRules) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(nodefeaturerulesResource, opts))
InvokesWatch(testing.NewRootWatchActionWithOptions(nodefeaturerulesResource, opts))
}
// Create takes the representation of a nodeFeatureRule and creates it. Returns the server's representation of the nodeFeatureRule, and an error, if there is any.
func (c *FakeNodeFeatureRules) Create(ctx context.Context, nodeFeatureRule *v1alpha1.NodeFeatureRule, opts v1.CreateOptions) (result *v1alpha1.NodeFeatureRule, err error) {
emptyResult := &v1alpha1.NodeFeatureRule{}
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(nodefeaturerulesResource, nodeFeatureRule), &v1alpha1.NodeFeatureRule{})
Invokes(testing.NewRootCreateActionWithOptions(nodefeaturerulesResource, nodeFeatureRule, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureRule), err
}
// Update takes the representation of a nodeFeatureRule and updates it. Returns the server's representation of the nodeFeatureRule, and an error, if there is any.
func (c *FakeNodeFeatureRules) Update(ctx context.Context, nodeFeatureRule *v1alpha1.NodeFeatureRule, opts v1.UpdateOptions) (result *v1alpha1.NodeFeatureRule, err error) {
emptyResult := &v1alpha1.NodeFeatureRule{}
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(nodefeaturerulesResource, nodeFeatureRule), &v1alpha1.NodeFeatureRule{})
Invokes(testing.NewRootUpdateActionWithOptions(nodefeaturerulesResource, nodeFeatureRule, opts), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureRule), err
}
@ -104,7 +108,7 @@ func (c *FakeNodeFeatureRules) Delete(ctx context.Context, name string, opts v1.
// DeleteCollection deletes a collection of objects.
func (c *FakeNodeFeatureRules) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(nodefeaturerulesResource, listOpts)
action := testing.NewRootDeleteCollectionActionWithOptions(nodefeaturerulesResource, opts, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha1.NodeFeatureRuleList{})
return err
@ -112,10 +116,11 @@ func (c *FakeNodeFeatureRules) DeleteCollection(ctx context.Context, opts v1.Del
// Patch applies the patch and returns the patched nodeFeatureRule.
func (c *FakeNodeFeatureRules) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeatureRule, err error) {
emptyResult := &v1alpha1.NodeFeatureRule{}
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(nodefeaturerulesResource, name, pt, data, subresources...), &v1alpha1.NodeFeatureRule{})
Invokes(testing.NewRootPatchSubresourceActionWithOptions(nodefeaturerulesResource, name, pt, data, opts, subresources...), emptyResult)
if obj == nil {
return nil, err
return emptyResult, err
}
return obj.(*v1alpha1.NodeFeatureRule), err
}

View file

@ -20,12 +20,11 @@ package v1alpha1
import (
"context"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
gentype "k8s.io/client-go/gentype"
scheme "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/scheme"
v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
)
@ -51,128 +50,18 @@ type NodeFeatureInterface interface {
// nodeFeatures implements NodeFeatureInterface
type nodeFeatures struct {
client rest.Interface
ns string
*gentype.ClientWithList[*v1alpha1.NodeFeature, *v1alpha1.NodeFeatureList]
}
// newNodeFeatures returns a NodeFeatures
func newNodeFeatures(c *NfdV1alpha1Client, namespace string) *nodeFeatures {
return &nodeFeatures{
client: c.RESTClient(),
ns: namespace,
gentype.NewClientWithList[*v1alpha1.NodeFeature, *v1alpha1.NodeFeatureList](
"nodefeatures",
c.RESTClient(),
scheme.ParameterCodec,
namespace,
func() *v1alpha1.NodeFeature { return &v1alpha1.NodeFeature{} },
func() *v1alpha1.NodeFeatureList { return &v1alpha1.NodeFeatureList{} }),
}
}
// Get takes name of the nodeFeature, and returns the corresponding nodeFeature object, and an error if there is any.
func (c *nodeFeatures) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.NodeFeature, err error) {
result = &v1alpha1.NodeFeature{}
err = c.client.Get().
Namespace(c.ns).
Resource("nodefeatures").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of NodeFeatures that match those selectors.
func (c *nodeFeatures) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.NodeFeatureList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.NodeFeatureList{}
err = c.client.Get().
Namespace(c.ns).
Resource("nodefeatures").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested nodeFeatures.
func (c *nodeFeatures) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("nodefeatures").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a nodeFeature and creates it. Returns the server's representation of the nodeFeature, and an error, if there is any.
func (c *nodeFeatures) Create(ctx context.Context, nodeFeature *v1alpha1.NodeFeature, opts v1.CreateOptions) (result *v1alpha1.NodeFeature, err error) {
result = &v1alpha1.NodeFeature{}
err = c.client.Post().
Namespace(c.ns).
Resource("nodefeatures").
VersionedParams(&opts, scheme.ParameterCodec).
Body(nodeFeature).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a nodeFeature and updates it. Returns the server's representation of the nodeFeature, and an error, if there is any.
func (c *nodeFeatures) Update(ctx context.Context, nodeFeature *v1alpha1.NodeFeature, opts v1.UpdateOptions) (result *v1alpha1.NodeFeature, err error) {
result = &v1alpha1.NodeFeature{}
err = c.client.Put().
Namespace(c.ns).
Resource("nodefeatures").
Name(nodeFeature.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(nodeFeature).
Do(ctx).
Into(result)
return
}
// Delete takes name of the nodeFeature and deletes it. Returns an error if one occurs.
func (c *nodeFeatures) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("nodefeatures").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *nodeFeatures) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Namespace(c.ns).
Resource("nodefeatures").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched nodeFeature.
func (c *nodeFeatures) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeature, err error) {
result = &v1alpha1.NodeFeature{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("nodefeatures").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View file

@ -20,12 +20,11 @@ package v1alpha1
import (
"context"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
gentype "k8s.io/client-go/gentype"
scheme "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/scheme"
v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
)
@ -40,6 +39,7 @@ type NodeFeatureGroupsGetter interface {
type NodeFeatureGroupInterface interface {
Create(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.CreateOptions) (*v1alpha1.NodeFeatureGroup, error)
Update(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (*v1alpha1.NodeFeatureGroup, error)
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
UpdateStatus(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (*v1alpha1.NodeFeatureGroup, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
@ -52,144 +52,18 @@ type NodeFeatureGroupInterface interface {
// nodeFeatureGroups implements NodeFeatureGroupInterface
type nodeFeatureGroups struct {
client rest.Interface
ns string
*gentype.ClientWithList[*v1alpha1.NodeFeatureGroup, *v1alpha1.NodeFeatureGroupList]
}
// newNodeFeatureGroups returns a NodeFeatureGroups
func newNodeFeatureGroups(c *NfdV1alpha1Client, namespace string) *nodeFeatureGroups {
return &nodeFeatureGroups{
client: c.RESTClient(),
ns: namespace,
gentype.NewClientWithList[*v1alpha1.NodeFeatureGroup, *v1alpha1.NodeFeatureGroupList](
"nodefeaturegroups",
c.RESTClient(),
scheme.ParameterCodec,
namespace,
func() *v1alpha1.NodeFeatureGroup { return &v1alpha1.NodeFeatureGroup{} },
func() *v1alpha1.NodeFeatureGroupList { return &v1alpha1.NodeFeatureGroupList{} }),
}
}
// Get takes name of the nodeFeatureGroup, and returns the corresponding nodeFeatureGroup object, and an error if there is any.
func (c *nodeFeatureGroups) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.NodeFeatureGroup, err error) {
result = &v1alpha1.NodeFeatureGroup{}
err = c.client.Get().
Namespace(c.ns).
Resource("nodefeaturegroups").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of NodeFeatureGroups that match those selectors.
func (c *nodeFeatureGroups) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.NodeFeatureGroupList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.NodeFeatureGroupList{}
err = c.client.Get().
Namespace(c.ns).
Resource("nodefeaturegroups").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested nodeFeatureGroups.
func (c *nodeFeatureGroups) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("nodefeaturegroups").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a nodeFeatureGroup and creates it. Returns the server's representation of the nodeFeatureGroup, and an error, if there is any.
func (c *nodeFeatureGroups) Create(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.CreateOptions) (result *v1alpha1.NodeFeatureGroup, err error) {
result = &v1alpha1.NodeFeatureGroup{}
err = c.client.Post().
Namespace(c.ns).
Resource("nodefeaturegroups").
VersionedParams(&opts, scheme.ParameterCodec).
Body(nodeFeatureGroup).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a nodeFeatureGroup and updates it. Returns the server's representation of the nodeFeatureGroup, and an error, if there is any.
func (c *nodeFeatureGroups) Update(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (result *v1alpha1.NodeFeatureGroup, err error) {
result = &v1alpha1.NodeFeatureGroup{}
err = c.client.Put().
Namespace(c.ns).
Resource("nodefeaturegroups").
Name(nodeFeatureGroup.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(nodeFeatureGroup).
Do(ctx).
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *nodeFeatureGroups) UpdateStatus(ctx context.Context, nodeFeatureGroup *v1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (result *v1alpha1.NodeFeatureGroup, err error) {
result = &v1alpha1.NodeFeatureGroup{}
err = c.client.Put().
Namespace(c.ns).
Resource("nodefeaturegroups").
Name(nodeFeatureGroup.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(nodeFeatureGroup).
Do(ctx).
Into(result)
return
}
// Delete takes name of the nodeFeatureGroup and deletes it. Returns an error if one occurs.
func (c *nodeFeatureGroups) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("nodefeaturegroups").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *nodeFeatureGroups) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Namespace(c.ns).
Resource("nodefeaturegroups").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched nodeFeatureGroup.
func (c *nodeFeatureGroups) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeatureGroup, err error) {
result = &v1alpha1.NodeFeatureGroup{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("nodefeaturegroups").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View file

@ -20,12 +20,11 @@ package v1alpha1
import (
"context"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
gentype "k8s.io/client-go/gentype"
scheme "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/scheme"
v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
)
@ -51,118 +50,18 @@ type NodeFeatureRuleInterface interface {
// nodeFeatureRules implements NodeFeatureRuleInterface
type nodeFeatureRules struct {
client rest.Interface
*gentype.ClientWithList[*v1alpha1.NodeFeatureRule, *v1alpha1.NodeFeatureRuleList]
}
// newNodeFeatureRules returns a NodeFeatureRules
func newNodeFeatureRules(c *NfdV1alpha1Client) *nodeFeatureRules {
return &nodeFeatureRules{
client: c.RESTClient(),
gentype.NewClientWithList[*v1alpha1.NodeFeatureRule, *v1alpha1.NodeFeatureRuleList](
"nodefeaturerules",
c.RESTClient(),
scheme.ParameterCodec,
"",
func() *v1alpha1.NodeFeatureRule { return &v1alpha1.NodeFeatureRule{} },
func() *v1alpha1.NodeFeatureRuleList { return &v1alpha1.NodeFeatureRuleList{} }),
}
}
// Get takes name of the nodeFeatureRule, and returns the corresponding nodeFeatureRule object, and an error if there is any.
func (c *nodeFeatureRules) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.NodeFeatureRule, err error) {
result = &v1alpha1.NodeFeatureRule{}
err = c.client.Get().
Resource("nodefeaturerules").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of NodeFeatureRules that match those selectors.
func (c *nodeFeatureRules) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.NodeFeatureRuleList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.NodeFeatureRuleList{}
err = c.client.Get().
Resource("nodefeaturerules").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested nodeFeatureRules.
func (c *nodeFeatureRules) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Resource("nodefeaturerules").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a nodeFeatureRule and creates it. Returns the server's representation of the nodeFeatureRule, and an error, if there is any.
func (c *nodeFeatureRules) Create(ctx context.Context, nodeFeatureRule *v1alpha1.NodeFeatureRule, opts v1.CreateOptions) (result *v1alpha1.NodeFeatureRule, err error) {
result = &v1alpha1.NodeFeatureRule{}
err = c.client.Post().
Resource("nodefeaturerules").
VersionedParams(&opts, scheme.ParameterCodec).
Body(nodeFeatureRule).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a nodeFeatureRule and updates it. Returns the server's representation of the nodeFeatureRule, and an error, if there is any.
func (c *nodeFeatureRules) Update(ctx context.Context, nodeFeatureRule *v1alpha1.NodeFeatureRule, opts v1.UpdateOptions) (result *v1alpha1.NodeFeatureRule, err error) {
result = &v1alpha1.NodeFeatureRule{}
err = c.client.Put().
Resource("nodefeaturerules").
Name(nodeFeatureRule.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(nodeFeatureRule).
Do(ctx).
Into(result)
return
}
// Delete takes name of the nodeFeatureRule and deletes it. Returns an error if one occurs.
func (c *nodeFeatureRules) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Resource("nodefeaturerules").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *nodeFeatureRules) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Resource("nodefeaturerules").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched nodeFeatureRule.
func (c *nodeFeatureRules) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeatureRule, err error) {
result = &v1alpha1.NodeFeatureRule{}
err = c.client.Patch(pt).
Resource("nodefeaturerules").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View file

@ -228,6 +228,7 @@ type SharedInformerFactory interface {
// Start initializes all requested informers. They are handled in goroutines
// which run until the stop channel gets closed.
// Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync.
Start(stopCh <-chan struct{})
// Shutdown marks a factory as shutting down. At that point no new

View file

@ -19,8 +19,8 @@ limitations under the License.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/listers"
"k8s.io/client-go/tools/cache"
v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
)
@ -38,25 +38,17 @@ type NodeFeatureLister interface {
// nodeFeatureLister implements the NodeFeatureLister interface.
type nodeFeatureLister struct {
indexer cache.Indexer
listers.ResourceIndexer[*v1alpha1.NodeFeature]
}
// NewNodeFeatureLister returns a new NodeFeatureLister.
func NewNodeFeatureLister(indexer cache.Indexer) NodeFeatureLister {
return &nodeFeatureLister{indexer: indexer}
}
// List lists all NodeFeatures in the indexer.
func (s *nodeFeatureLister) List(selector labels.Selector) (ret []*v1alpha1.NodeFeature, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.NodeFeature))
})
return ret, err
return &nodeFeatureLister{listers.New[*v1alpha1.NodeFeature](indexer, v1alpha1.Resource("nodefeature"))}
}
// NodeFeatures returns an object that can list and get NodeFeatures.
func (s *nodeFeatureLister) NodeFeatures(namespace string) NodeFeatureNamespaceLister {
return nodeFeatureNamespaceLister{indexer: s.indexer, namespace: namespace}
return nodeFeatureNamespaceLister{listers.NewNamespaced[*v1alpha1.NodeFeature](s.ResourceIndexer, namespace)}
}
// NodeFeatureNamespaceLister helps list and get NodeFeatures.
@ -74,26 +66,5 @@ type NodeFeatureNamespaceLister interface {
// nodeFeatureNamespaceLister implements the NodeFeatureNamespaceLister
// interface.
type nodeFeatureNamespaceLister struct {
indexer cache.Indexer
namespace string
}
// List lists all NodeFeatures in the indexer for a given namespace.
func (s nodeFeatureNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.NodeFeature, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.NodeFeature))
})
return ret, err
}
// Get retrieves the NodeFeature from the indexer for a given namespace and name.
func (s nodeFeatureNamespaceLister) Get(name string) (*v1alpha1.NodeFeature, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("nodefeature"), name)
}
return obj.(*v1alpha1.NodeFeature), nil
listers.ResourceIndexer[*v1alpha1.NodeFeature]
}

View file

@ -19,8 +19,8 @@ limitations under the License.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/listers"
"k8s.io/client-go/tools/cache"
v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
)
@ -38,25 +38,17 @@ type NodeFeatureGroupLister interface {
// nodeFeatureGroupLister implements the NodeFeatureGroupLister interface.
type nodeFeatureGroupLister struct {
indexer cache.Indexer
listers.ResourceIndexer[*v1alpha1.NodeFeatureGroup]
}
// NewNodeFeatureGroupLister returns a new NodeFeatureGroupLister.
func NewNodeFeatureGroupLister(indexer cache.Indexer) NodeFeatureGroupLister {
return &nodeFeatureGroupLister{indexer: indexer}
}
// List lists all NodeFeatureGroups in the indexer.
func (s *nodeFeatureGroupLister) List(selector labels.Selector) (ret []*v1alpha1.NodeFeatureGroup, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.NodeFeatureGroup))
})
return ret, err
return &nodeFeatureGroupLister{listers.New[*v1alpha1.NodeFeatureGroup](indexer, v1alpha1.Resource("nodefeaturegroup"))}
}
// NodeFeatureGroups returns an object that can list and get NodeFeatureGroups.
func (s *nodeFeatureGroupLister) NodeFeatureGroups(namespace string) NodeFeatureGroupNamespaceLister {
return nodeFeatureGroupNamespaceLister{indexer: s.indexer, namespace: namespace}
return nodeFeatureGroupNamespaceLister{listers.NewNamespaced[*v1alpha1.NodeFeatureGroup](s.ResourceIndexer, namespace)}
}
// NodeFeatureGroupNamespaceLister helps list and get NodeFeatureGroups.
@ -74,26 +66,5 @@ type NodeFeatureGroupNamespaceLister interface {
// nodeFeatureGroupNamespaceLister implements the NodeFeatureGroupNamespaceLister
// interface.
type nodeFeatureGroupNamespaceLister struct {
indexer cache.Indexer
namespace string
}
// List lists all NodeFeatureGroups in the indexer for a given namespace.
func (s nodeFeatureGroupNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.NodeFeatureGroup, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.NodeFeatureGroup))
})
return ret, err
}
// Get retrieves the NodeFeatureGroup from the indexer for a given namespace and name.
func (s nodeFeatureGroupNamespaceLister) Get(name string) (*v1alpha1.NodeFeatureGroup, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("nodefeaturegroup"), name)
}
return obj.(*v1alpha1.NodeFeatureGroup), nil
listers.ResourceIndexer[*v1alpha1.NodeFeatureGroup]
}

View file

@ -19,8 +19,8 @@ limitations under the License.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/listers"
"k8s.io/client-go/tools/cache"
v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
)
@ -39,30 +39,10 @@ type NodeFeatureRuleLister interface {
// nodeFeatureRuleLister implements the NodeFeatureRuleLister interface.
type nodeFeatureRuleLister struct {
indexer cache.Indexer
listers.ResourceIndexer[*v1alpha1.NodeFeatureRule]
}
// NewNodeFeatureRuleLister returns a new NodeFeatureRuleLister.
func NewNodeFeatureRuleLister(indexer cache.Indexer) NodeFeatureRuleLister {
return &nodeFeatureRuleLister{indexer: indexer}
}
// List lists all NodeFeatureRules in the indexer.
func (s *nodeFeatureRuleLister) List(selector labels.Selector) (ret []*v1alpha1.NodeFeatureRule, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.NodeFeatureRule))
})
return ret, err
}
// Get retrieves the NodeFeatureRule from the index for a given name.
func (s *nodeFeatureRuleLister) Get(name string) (*v1alpha1.NodeFeatureRule, error) {
obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("nodefeaturerule"), name)
}
return obj.(*v1alpha1.NodeFeatureRule), nil
return &nodeFeatureRuleLister{listers.New[*v1alpha1.NodeFeatureRule](indexer, v1alpha1.Resource("nodefeaturerule"))}
}

View file

@ -59,19 +59,12 @@ func main() {
// Check deprecated flags
flags.Visit(func(f *flag.Flag) {
switch f.Name {
case "featurerules-controller":
klog.InfoS("-featurerules-controller is deprecated, use '-crd-controller' flag instead")
case "crd-controller":
klog.InfoS("-crd-controller is deprecated, will be removed in a future release along with the deprecated gRPC API")
case "extra-label-ns":
args.Overrides.ExtraLabelNs = overrides.ExtraLabelNs
case "deny-label-ns":
args.Overrides.DenyLabelNs = overrides.DenyLabelNs
case "label-whitelist":
args.Overrides.LabelWhiteList = overrides.LabelWhiteList
case "resource-labels":
klog.InfoS("-resource-labels is deprecated, extended resources should be managed with NodeFeatureRule objects")
args.Overrides.ResourceLabels = overrides.ResourceLabels
case "enable-taints":
args.Overrides.EnableTaints = overrides.EnableTaints
case "no-publish":
@ -80,16 +73,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 +105,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")
@ -167,7 +129,6 @@ func initFlags(flagset *flag.FlagSet) (*master.Args, *master.ConfigOverrideArgs)
LabelWhiteList: &utils.RegexpVal{},
DenyLabelNs: &utils.StringSetVal{},
ExtraLabelNs: &utils.StringSetVal{},
ResourceLabels: &utils.StringSetVal{},
ResyncPeriod: &utils.DurationVal{Duration: time.Duration(1) * time.Hour},
}
flagset.Var(overrides.ExtraLabelNs, "extra-label-ns",
@ -181,8 +142,6 @@ func initFlags(flagset *flag.FlagSet) (*master.Args, *master.ConfigOverrideArgs)
"Do not publish feature labels")
flagset.Var(overrides.DenyLabelNs, "deny-label-ns",
"Comma separated list of denied label namespaces")
flagset.Var(overrides.ResourceLabels, "resource-labels",
"Comma separated list of labels to be exposed as extended resources. DEPRECATED: use NodeFeatureRule objects instead")
flagset.Var(overrides.ResyncPeriod, "resync-period",
"Specify the NFD API controller resync period."+
"It does not have effect when the NodeFeature API has been disabled (with -feature-gates NodeFeatureAPI=false).")

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

@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
controller-gen.kubebuilder.io/version: v0.16.3
name: nodefeatures.nfd.k8s-sigs.io
spec:
group: nfd.k8s-sigs.io
@ -124,7 +124,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
controller-gen.kubebuilder.io/version: v0.16.3
name: nodefeaturegroups.nfd.k8s-sigs.io
spec:
group: nfd.k8s-sigs.io
@ -395,7 +395,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
controller-gen.kubebuilder.io/version: v0.16.3
name: nodefeaturerules.nfd.k8s-sigs.io
spec:
group: nfd.k8s-sigs.io

View file

@ -19,9 +19,6 @@
- name: host-lib
hostPath:
path: "/lib"
- name: source-d
hostPath:
path: "/etc/kubernetes/node-feature-discovery/source.d/"
- name: features-d
hostPath:
path: "/etc/kubernetes/node-feature-discovery/features.d/"
@ -50,9 +47,6 @@
- name: host-lib
mountPath: "/host-lib"
readOnly: true
- name: source-d
mountPath: "/etc/kubernetes/node-feature-discovery/source.d/"
readOnly: true
- name: features-d
mountPath: "/etc/kubernetes/node-feature-discovery/features.d/"
readOnly: true

View file

@ -2,7 +2,6 @@
# autoDefaultNs: true
# extraLabelNs: ["added.ns.io","added.kubernets.io"]
# denyLabelNs: ["denied.ns.io","denied.kubernetes.io"]
# resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
# enableTaints: false
# labelWhiteList: "foo"
# resyncPeriod: "2h"

View file

@ -77,8 +77,6 @@
# - "class"
# - "vendor"
# - "device"
# local:
# hooksEnabled: false
# custom:
# # The following feature demonstrates the capabilities of the matchFeatures
# - name: "my custom rule"

View file

@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
controller-gen.kubebuilder.io/version: v0.16.3
name: nodefeatures.nfd.k8s-sigs.io
spec:
group: nfd.k8s-sigs.io
@ -124,7 +124,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
controller-gen.kubebuilder.io/version: v0.16.3
name: nodefeaturegroups.nfd.k8s-sigs.io
spec:
group: nfd.k8s-sigs.io
@ -395,7 +395,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
controller-gen.kubebuilder.io/version: v0.16.3
name: nodefeaturerules.nfd.k8s-sigs.io
spec:
group: nfd.k8s-sigs.io

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,29 +103,16 @@ 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 }}
{{- if .Values.master.denyLabelNs | empty | not }}
- "-deny-label-ns={{- join "," .Values.master.denyLabelNs }}"
{{- end }}
{{- if .Values.master.resourceLabels | empty | not }}
- "-resource-labels={{- join "," .Values.master.resourceLabels }}"
{{- end }}
{{- 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 +122,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 +132,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 }}"
@ -146,20 +141,12 @@ spec:
mountPath: "/host-usr/src"
readOnly: true
{{- end }}
- name: source-d
mountPath: "/etc/kubernetes/node-feature-discovery/source.d/"
readOnly: true
- name: features-d
mountPath: "/etc/kubernetes/node-feature-discovery/features.d/"
readOnly: true
- 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:
@ -184,9 +171,6 @@ spec:
hostPath:
path: "/usr/src"
{{- end }}
- name: source-d
hostPath:
path: "/etc/kubernetes/node-feature-discovery/source.d/"
- name: features-d
hostPath:
path: "/etc/kubernetes/node-feature-discovery/features.d/"
@ -196,11 +180,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

@ -33,7 +33,6 @@ master:
# autoDefaultNs: true
# extraLabelNs: ["added.ns.io","added.kubernets.io"]
# denyLabelNs: ["denied.ns.io","denied.kubernetes.io"]
# resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
# enableTaints: false
# labelWhiteList: "foo"
# resyncPeriod: "2h"
@ -75,10 +74,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:
@ -86,9 +81,7 @@ master:
resyncPeriod:
denyLabelNs: []
extraLabelNs: []
resourceLabels: []
enableTaints: false
crdController: null
featureRulesController: null
nfdApiParallelism: null
deploymentAnnotations: {}
@ -267,8 +260,6 @@ worker:
# - "class"
# - "vendor"
# - "device"
# local:
# hooksEnabled: false
# custom:
# # The following feature demonstrates the capabilities of the matchFeatures
# - name: "my custom rule"
@ -608,18 +599,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

View file

@ -160,10 +160,6 @@ Chart parameters are available.
| `imagePullSecrets` | array | [] | ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. [More info](https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod). |
| `nameOverride` | string | | Override the name of the chart |
| `fullnameOverride` | string | | Override a default fully qualified app name |
| `tls.enable` | bool | false | Specifies whether to use TLS for communications between components. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release. |
| `tls.certManager` | bool | false | If enabled, requires [cert-manager](https://cert-manager.io/docs/) to be installed and will automatically create the required TLS certificates. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `tls.certManager.certManagerCertificate.issuerName` | string | | If specified, it will use a pre-existing issuer instead for the required TLS certificates. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release. |
| `tls.certManager.certManagerCertificate.issuerKind` | string | | Specifies on what kind of issuer is used, can be either ClusterIssuer or Issuer (default). Requires `tls.certManager.certManagerCertificate.issuerName` to be set. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `featureGates.NodeFeatureAPI` | bool | true | Enable the [NodeFeature](../usage/custom-resources.md#nodefeature) CRD API for communicating node features. This will automatically disable the gRPC communication. |
| `featureGates.NodeFeatureGroupAPI` | bool | false | Enable the [NodeFeatureGroup](../usage/custom-resources.md#nodefeaturegroup) CRD API. |
| `featureGates.DisableAutoPrefix` | bool | false | Enable [DisableAutoPrefix](../reference/feature-gates.md#disableautoprefix) feature gate. Disables automatic prefixing of unprefixed labels, annotations and extended resources. |
@ -183,16 +179,12 @@ API's you need to install the prometheus operator in your cluster.
| `master.*` | dict | | NFD master deployment configuration |
| `master.enable` | bool | true | Specifies whether nfd-master should be deployed |
| `master.hostNetwork` | bool | false | Specifies whether to enable or disable running the container in the host's network namespace |
| `master.port` | integer | | Specifies the TCP port that nfd-master listens for incoming requests. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `master.metricsPort` | integer | 8081 | Port on which to expose metrics from components to prometheus operator |
| `master.healthPort` | integer | 8082 | Port on which to expose the grpc health endpoint, will be also used for the probes |
| `master.metricsPort` | integer | 8081 | Port on which to expose metrics from components to prometheus operator. **DEPRECATED**: will be replaced by `master.port` in NFD v0.18. |
| `master.healthPort` | integer | 8082 | Port on which to expose the grpc health endpoint, will be also used for the probes. **DEPRECATED**: will be replaced by `master.port` in NFD v0.18. |
| `master.instance` | string | | Instance name. Used to separate annotation namespaces for multiple parallel deployments |
| `master.resyncPeriod` | string | | NFD API controller resync period. |
| `master.extraLabelNs` | array | [] | List of allowed extra label namespaces |
| `master.resourceLabels` | array | [] | List of labels to be registered as extended resources |
| `master.enableTaints` | bool | false | Specifies whether to enable or disable node tainting |
| `master.crdController` | bool | null | Specifies whether the NFD CRD API controller is enabled. If not set, controller will be enabled if `master.instance` is empty. |
| `master.featureRulesController` | bool | null | DEPRECATED: use `master.crdController` instead |
| `master.replicaCount` | integer | 1 | Number of desired pods. This is a pointer to distinguish between explicit zero and not specified |
| `master.podSecurityContext` | dict | {} | [PodSecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) holds pod-level security attributes and common container settings |
| `master.securityContext` | dict | {} | Container [security settings](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) |
@ -200,8 +192,6 @@ API's you need to install the prometheus operator in your cluster.
| `master.serviceAccount.annotations` | dict | {} | Annotations to add to the service account |
| `master.serviceAccount.name` | string | | The name of the service account to use. If not set and create is true, a name is generated using the fullname template |
| `master.rbac.create` | bool | true | Specifies whether to create [RBAC][rbac] configuration for nfd-master |
| `master.service.type` | string | ClusterIP | NFD master service type. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `master.service.port` | integer | 8080 | NFD master service port. **NOTE**: this parameter is related to the deprecated gRPC API and will be removed with it in a future release |
| `master.resources.limits` | dict | {memory: 4Gi} | NFD master pod [resources limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits) |
| `master.resources.requests` | dict | {cpu: 100m, memory: 128Mi} | NFD master pod [resources requests](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits). See `[0]` for more info |
| `master.tolerations` | dict | _Schedule to control-plane node_ | NFD master pod [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) |
@ -241,8 +231,8 @@ API's you need to install the prometheus operator in your cluster.
| `worker.*` | dict | | NFD worker daemonset configuration |
| `worker.enable` | bool | true | Specifies whether nfd-worker should be deployed |
| `worker.hostNetwork` | bool | false | Specifies whether to enable or disable running the container in the host's network namespace |
| `worker.metricsPort` | int | 8081 | Port on which to expose metrics from components to prometheus operator |
| `worker.healthPort` | int | 8082 | Port on which to expose the grpc health endpoint, will be also used for the probes |
| `worker.metricsPort` | int | 8081 | Port on which to expose metrics from components to prometheus operator. **DEPRECATED**: will be replaced by `worker.port` in NFD v0.18. |
| `worker.healthPort` | int | 8082 | Port on which to expose the grpc health endpoint, will be also used for the probes. **DEPRECATED**: will be replaced by `worker.port` in NFD v0.18. |
| `worker.config` | dict | | NFD worker [configuration](../reference/worker-configuration-reference) |
| `worker.podSecurityContext` | dict | {} | [PodSecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) holds pod-level security attributes and common container settins |
| `worker.securityContext` | dict | {} | Container [security settings](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) |
@ -283,8 +273,8 @@ API's you need to install the prometheus operator in your cluster.
| `topologyUpdater.serviceAccount.annotations` | dict | {} | Annotations to add to the service account for topology updater |
| `topologyUpdater.serviceAccount.name` | string | | The name of the service account for topology updater to use. If not set and create is true, a name is generated using the fullname template and `-topology-updater` suffix |
| `topologyUpdater.rbac.create` | bool | true | Specifies whether to create [RBAC][rbac] configuration for topology updater |
| `topologyUpdater.metricsPort` | integer | 8081 | Port on which to expose prometheus metrics |
| `topologyUpdater.healthPort` | integer | 8082 | Port on which to expose the grpc health endpoint, will be also used for the probes |
| `topologyUpdater.metricsPort` | integer | 8081 | Port on which to expose prometheus metrics. **DEPRECATED**: will be replaced by `topologyUpdater.port` in NFD v0.18. |
| `topologyUpdater.healthPort` | integer | 8082 | Port on which to expose the grpc health endpoint, will be also used for the probes. **DEPRECATED**: will be replaced by `topologyUpdater.port` in NFD v0.18. |
| `topologyUpdater.kubeletConfigPath` | string | "" | Specifies the kubelet config host path |
| `topologyUpdater.kubeletPodResourcesSockPath` | string | "" | Specifies the kubelet sock path to read pod resources |
| `topologyUpdater.updateInterval` | string | 60s | Time to sleep between CR updates. Non-positive value implies no CR update. |
@ -329,7 +319,7 @@ API's you need to install the prometheus operator in your cluster.
| `gc.podSecurityContext` | dict | {} | [PodSecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) holds pod-level security attributes and common container settings |
| `gc.resources.limits` | dict | {memory: 1Gi} | NFD Garbage Collector pod [resources limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits) |
| `gc.resources.requests` | dict | {cpu: 10m, memory: 128Mi} | NFD Garbage Collector pod [resources requests](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits) |
| `gc.metricsPort` | integer | 8081 | Port on which to serve Prometheus metrics |
| `gc.metricsPort` | integer | 8081 | Port on which to serve Prometheus metrics. **DEPRECATED**: will be replaced by `gc.port` in NFD v0.18. |
| `gc.nodeSelector` | dict | {} | Garbage collector pod [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) |
| `gc.tolerations` | dict | {} | Garbage collector pod [node tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) |
| `gc.annotations` | dict | {} | Garbage collector pod [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) |

View file

@ -24,8 +24,8 @@ For backwards compatibility a container image tag with suffix `-minimal`
## Full
This image is based on [debian:bookworm-slim](https://hub.docker.com/_/debian)
and contains a full Linux system for running shell-based nfd-worker hooks and
doing live debugging and diagnosis of the NFD images.
and contains a full Linux system for doing live debugging and diagnosis
of the NFD images.
The container image tag has suffix `-full`
(e.g. `{{ site.container_image }}-full`).

View file

@ -59,11 +59,6 @@ scenarios under
- [`prune`](https://github.com/kubernetes-sigs/node-feature-discovery/blob/{{site.release}}/deployment/overlays/prune):
clean up the cluster after uninstallation, see
[Removing feature labels](uninstallation.md#removing-feature-labels)
- [`samples/cert-manager`](https://github.com/kubernetes-sigs/node-feature-discovery/blob/{{site.release}}/deployment/overlays/samples/cert-manager):
an example for supplementing the default deployment with cert-manager for TLS
authentication, see
[Automated TLS certificate management using cert-manager](tls.md)
for details
- [`samples/custom-rules`](https://github.com/kubernetes-sigs/node-feature-discovery/blob/{{site.release}}/deployment/overlays/samples/custom-rules):
an example for spicing up the default deployment with a separately managed
configmap of custom labeling rules, see

View file

@ -1,7 +1,7 @@
---
title: "Metrics"
layout: default
sort: 7
sort: 6
---
# Metrics

View file

@ -1,181 +0,0 @@
---
title: "TLS authentication"
layout: default
sort: 5
---
# Communication security with TLS
{: .no_toc}
## Table of contents
{: .no_toc .text-delta}
1. TOC
{:toc}
---
> **DEPRECATED**: this section only applies when the gRPC API is used, i.e.
> when the NodeFeature API is disabled (via the `-feature-gates
> NodeFeatureAPI=false` flag) on both nfd-master and nfd-worker. The gRPC API
> is deprecated and will be removed in a future release.
NFD supports mutual TLS authentication between the nfd-master and nfd-worker
instances. That is, nfd-worker and nfd-master both verify that the other end
presents a valid certificate.
TLS authentication is enabled by specifying `-ca-file`, `-key-file` and
`-cert-file` args, on both the nfd-master and nfd-worker instances. The
template specs provided with NFD contain (commented out) example configuration
for enabling TLS authentication.
The Common Name (CN) of the nfd-master certificate must match the DNS name of
the nfd-master Service of the cluster. By default, nfd-master only check that
the nfd-worker has been signed by the specified root certificate (-ca-file).
Additional hardening can be enabled by specifying `-verify-node-name` in
nfd-master args, in which case nfd-master verifies that the NodeName presented
by nfd-worker matches the Common Name (CN) or a Subject Alternative Name (SAN)
of its certificate.
## Automated TLS certificate management using cert-manager
[cert-manager](https://cert-manager.io/) can be used to automate certificate
management between nfd-master and the nfd-worker pods.
The NFD source code repository contains an example kustomize overlay and helm
chart that can be used to deploy NFD with cert-manager supplied certificates
enabled.
To install `cert-manager` itself, you can run:
```bash
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml
```
Alternatively, you can refer to cert-manager documentation for other
installation methods such as the Helm chart they provide.
When using the Helm chart to deploy NFD, override `values.yaml` to enable both the
`tls.enabled` and `tls.certManager` options. Note that if you do not enable
`tls.certManager`, helm will successfully install the application, but
deployment will wait until certificates are manually created, as demonstrated
below.
See the sample installation commands in the Helm [Deployment](helm.md#deployment)
and [Configuration](helm.md#configuration) sections above for how to either override
individual values, or provide a yaml file with which to override default
values.
## Manual TLS certificate management
If you do not with to make use of cert-manager, the certificates can be
manually created and stored as secrets within the NFD namespace.
Create a CA certificate
```bash
openssl req -x509 -newkey rsa:4096 -keyout ca.key -nodes \
-subj "/CN=nfd-ca" -days 10000 -out ca.crt
```
Create a common openssl config file.
```bash
cat <<EOF > nfd-common.conf
[ req ]
default_bits = 4096
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = XX
ST = some-state
L = some-city
O = some-company
OU = node-feature-discovery
[ req_ext ]
subjectAltName = @alt_names
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
EOF
```
Now, create the nfd-master certificate.
```bash
cat <<EOF > nfd-master.conf
.include nfd-common.conf
[ dn ]
CN = nfd-master
[ alt_names ]
DNS.1 = nfd-master
DNS.2 = nfd-master.node-feature-discovery.svc.cluster.local
DNS.3 = localhost
EOF
openssl req -new -newkey rsa:4096 -keyout nfd-master.key -nodes -out nfd-master.csr -config nfd-master.conf
```
Create certificates for nfd-worker and nfd-topology-updater
```bash
cat <<EOF > nfd-worker.conf
.include nfd-common.conf
[ dn ]
CN = nfd-worker
[ alt_names ]
DNS.1 = nfd-worker
DNS.2 = nfd-worker.node-feature-discovery.svc.cluster.local
EOF
# Config for topology updater is identical except for the DN and alt_names
sed -e 's/worker/topology-updater/g' < nfd-worker.conf > nfd-topology-updater.conf
openssl req -new -newkey rsa:4096 -keyout nfd-worker.key -nodes -out nfd-worker.csr -config nfd-worker.conf
openssl req -new -newkey rsa:4096 -keyout nfd-topology-updater.key -nodes -out nfd-topology-updater.csr -config nfd-topology-updater.conf
```
Now, sign the certificates with the CA created earlier.
```bash
for cert in nfd-master nfd-worker nfd-topology-updater; do
echo signing $cert
openssl x509 -req -in $cert.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out $cert.crt -days 10000 \
-extensions v3_ext -extfile $cert.conf
done
```
Finally, turn these certificates into secrets.
```bash
for cert in nfd-master nfd-worker nfd-topology-updater; do
echo creating secret for $cert in node-feature-discovery namespace
cat <<EOF | kubectl create -n node-feature-discovery -f -
---
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
name: ${cert}-cert
data:
ca.crt: $( cat ca.crt | base64 -w 0 )
tls.crt: $( cat $cert.crt | base64 -w 0 )
tls.key: $( cat $cert.key | base64 -w 0 )
EOF
done
```

View file

@ -1,7 +1,7 @@
---
title: "Uninstallation"
layout: default
sort: 6
sort: 5
---
# Uninstallation

View file

@ -171,29 +171,15 @@ e2e-tests:
| E2E_GINKGO_LABEL_FILTER | Ginkgo label filter to use for running e2e tests | *empty* |
| OPENSHIFT | Non-empty value enables OpenShift specific support (only affects e2e tests) | *empty* |
## Running locally
> ****DEPRECATED**: Running NFD locally is deprecated and will be removed in a
> future release. It depends on the gRPC API which is deprecated and will be
> removed in a future release. To run NFD locally, disable the NodeFeature API
> with `-feature-gates NodeFeatureAPI=false` flag.
You can run NFD locally, either directly on your host OS or in containers for
testing and development purposes. This may be useful e.g. for checking
features-detection.
### NFD-Master
When running as a standalone container labeling is expected to fail because
Kubernetes API is not available. Thus, it is recommended to use `-no-publish`
Also specify `-crd-controller=false` and `-feature-gates NodeFeatureAPI=false`
command line flags to disable CRD controller and enable gRPC. E.g.
Kubernetes API is not available. Thus, it is recommended to use `-no-publish`.
```bash
$ export NFD_CONTAINER_IMAGE={{ site.container_image }}
$ docker run --rm --name=nfd-test ${NFD_CONTAINER_IMAGE} nfd-master -no-publish -crd-controller=false -feature-gates NodeFeatureAPI=false
2019/02/01 14:48:21 Node Feature Discovery Master <NFD_VERSION>
2019/02/01 14:48:21 gRPC server serving on port: 8080
```
### NFD-Worker
@ -256,19 +242,27 @@ the steps below.
1. Install [kustomize](https://github.com/kubernetes-sigs/kustomize)
1. Install [tilt](https://docs.tilt.dev/install.html)
1. Create a local Kubernetes cluster
- Create image registry first
- Create a Kubernetes cluster. Please note that docker containers will be
served as controller node and worker nodes, and NFD-worker will run as a
DaemonSet in nested container. Therefore, to make sure the NFD-worker can
discover the host features, the host folders "/boot" and "/lib" should be
mounted into worker node docker containers when creating the Kubernetes
cluster.
1. Start up node feature discovery development environment
To start up your Tilt development environment, run at the root of your
local NFD codebase.
To start up your Tilt development environment, run
```shell
tilt up
```
```shell
tilt up
```
at the root of your local NFD codebase. Tilt will start a web interface in the
localhost and port 10350. From the web interface, you are able to see how NFD worker
and master are progressing, watch their build and runtime logs. Once your code changes
are saved locally, Tilt will notice it and re-build the container image from the
current code, push the image to the registry and re-deploy NFD pods with the latest
container image.
Tilt will start a web interface in the localhost and port 10350. From the
web interface, you are able to see how NFD worker and master are
progressing, watch their build and runtime logs. Once your code changes are
saved locally, Tilt will notice it and re-build the container image from
the current code, push the image to the registry and re-deploy NFD pods
with the latest container image.
### Environment variables

View file

@ -71,7 +71,7 @@ Feature discovery is divided into domain-specific feature sources:
- System
- USB
- Custom (rule-based custom features)
- Local (hooks for user-specific features)
- Local (features files)
Each feature source is responsible for detecting a set of features which. in
turn, are turned into node feature labels. Feature labels are prefixed with

View file

@ -16,7 +16,7 @@ The feature gates are set using the `-feature-gates` command line flag or
| Name | Default | Stage | Since | Until |
| --------------------- | ------- | ------ | ------- | ------ |
| `NodeFeatureAPI` | true | Beta | V0.14 | |
| `NodeFeatureAPI` | true | Beta | V0.14 | v0.16 |
| `NodeFeatureAPI` | true | GA | V0.17 | |
| `DisableAutoPrefix` | false | Alpha | V0.16 | |
| `NodeFeatureGroupAPI` | false | Alpha | V0.16 | |

View file

@ -47,20 +47,10 @@ The `-prune` flag is a sub-command like option for cleaning up the cluster. It
causes nfd-master to remove all NFD related labels, annotations and extended
resources from all Node objects of the cluster and exit.
### -port
The `-port` flag specifies the TCP port that nfd-master listens for incoming requests.
Default: 8080
Example:
```bash
nfd-master -port=443
```
### -metrics
**DEPRECATED**: Will be removed in NFD v0.17 and replaced by `-port`.
The `-metrics` flag specifies the port on which to expose
[Prometheus](https://prometheus.io/) metrics. Setting this to 0 disables the
metrics server on nfd-master.
@ -89,91 +79,6 @@ Example:
nfd-master -instance=network
```
### -ca-file
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-ca-file` is one of the three flags (together with `-cert-file` and
`-key-file`) controlling master-worker mutual TLS authentication on the
nfd-master side. This flag specifies the TLS root certificate that is used for
authenticating incoming connections. NFD-Worker side needs to have matching key
and cert files configured for the incoming requests to be accepted.
Default: *empty*
> **NOTE:** Must be specified together with `-cert-file` and `-key-file`
Example:
```bash
nfd-master -ca-file=/opt/nfd/ca.crt -cert-file=/opt/nfd/master.crt -key-file=/opt/nfd/master.key
```
### -cert-file
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-cert-file` is one of the three flags (together with `-ca-file` and
`-key-file`) controlling master-worker mutual TLS authentication on the
nfd-master side. This flag specifies the TLS certificate presented for
authenticating outgoing traffic towards nfd-worker.
Default: *empty*
> **NOTE:** Must be specified together with `-ca-file` and `-key-file`
Example:
```bash
nfd-master -cert-file=/opt/nfd/master.crt -key-file=/opt/nfd/master.key -ca-file=/opt/nfd/ca.crt
```
### -key-file
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-key-file` is one of the three flags (together with `-ca-file` and
`-cert-file`) controlling master-worker mutual TLS authentication on the
nfd-master side. This flag specifies the private key corresponding the given
certificate file (`-cert-file`) that is used for authenticating outgoing
traffic.
Default: *empty*
> **NOTE:** Must be specified together with `-cert-file` and `-ca-file`
Example:
```bash
nfd-master -key-file=/opt/nfd/master.key -cert-file=/opt/nfd/master.crt -ca-file=/opt/nfd/ca.crt
```
### -verify-node-name
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-verify-node-name` flag controls the NodeName based authorization of
incoming requests and only has effect when mTLS authentication has been enabled
(with `-ca-file`, `-cert-file` and `-key-file`). If enabled, the worker node
name of the incoming must match with the CN or a SAN in its TLS certificate. Thus,
workers are only able to label the node they are running on (or the node whose
certificate they present).
Node Name based authorization is disabled by default.
Default: *false*
Example:
```bash
nfd-master -verify-node-name -ca-file=/opt/nfd/ca.crt \
-cert-file=/opt/nfd/master.crt -key-file=/opt/nfd/master.key
```
### -enable-leader-election
The `-enable-leader-election` flag enables leader election for NFD-Master.
@ -212,28 +117,6 @@ Example:
nfd-master -no-publish
```
### -crd-controller
> **NOTE** This flag will be removed in a future release at the same time with
> the deprecated gRPC API.
The `-crd-controller` flag specifies whether the NFD CRD API controller is
enabled or not. The controller is responsible for processing
[NodeFeature](../usage/custom-resources.md#nodefeature) and
[NodeFeatureRule](../usage/custom-resources.md#nodefeaturerule) objects.
Default: *true*
Example:
```bash
nfd-master -crd-controller=false
```
### -featurerules-controller
**DEPRECATED**: use [`-crd-controller`](#-crd-controller) instead.
### -label-whitelist
The `-label-whitelist` specifies a regular expression for filtering feature
@ -260,9 +143,6 @@ other vendor or application specific namespaces for custom labels from the
local and custom feature sources, even though these labels were denied using
the `deny-label-ns` flag.
The same namespace control and this flag applies Extended Resources (created
with `-resource-labels`), too.
Default: *empty*
Example:
@ -293,23 +173,6 @@ Example:
nfd-master -deny-label-ns=*.vendor.com,vendor-2.io
```
### -resource-labels
**DEPRECATED**: [NodeFeatureRule](../usage/custom-resources.md#nodefeaturerule)
should be used for managing extended resources in NFD.
The `-resource-labels` flag specifies a comma-separated list of features to be
advertised as extended resources instead of labels. Features that have integer
values can be published as Extended Resources by listing them in this flag.
Default: *empty*
Example:
```bash
nfd-master -resource-labels=vendor-1.com/feature-1,vendor-2.io/feature-2
```
### -config
The `-config` flag specifies the path of the nfd-master configuration file to

View file

@ -40,9 +40,6 @@ other vendor or application specific namespaces for custom labels from the
local and custom feature sources, even though these labels were denied using
the `denyLabelNs` parameter.
The same namespace control and this option applies to Extended Resources (created
with `resourceLabels`), too.
Default: *empty*
Example:
@ -104,23 +101,6 @@ Example:
autoDefaultNs: false
```
## resourceLabels
**DEPRECATED**: [NodeFeatureRule](../usage/custom-resources.md#nodefeaturerule)
should be used for managing extended resources in NFD.
The `resourceLabels` option specifies a list of features to be
advertised as extended resources instead of labels. Features that have integer
values can be published as Extended Resources by listing them in this option.
Default: *empty*
Example:
```yaml
resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
```
## enableTaints
`enableTaints` enables/disables node tainting feature of NFD.

View file

@ -74,6 +74,8 @@ nfd-topology-updater -oneshot -no-publish
### -metrics
**DEPRECATED**: Will be removed in NFD v0.17 and replaced by `-port`.
The `-metrics` flag specifies the port on which to expose
[Prometheus](https://prometheus.io/) metrics. Setting this to 0 disables the
metrics server on nfd-topology-updater.

View file

@ -69,82 +69,6 @@ Example:
nfd-worker -options='{"sources":{"cpu":{"cpuid":{"attributeWhitelist":["AVX","AVX2"]}}}}'
```
### -server
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-server` flag specifies the address of the nfd-master endpoint where to
connect to.
Default: localhost:8080
Example:
```bash
nfd-worker -server=nfd-master.nfd.svc.cluster.local:443
```
### -ca-file
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-ca-file` is one of the three flags (together with `-cert-file` and
`-key-file`) controlling the mutual TLS authentication on the worker side.
This flag specifies the TLS root certificate that is used for verifying the
authenticity of nfd-master.
Default: *empty*
> **NOTE:** Must be specified together with `-cert-file` and `-key-file`
Example:
```bash
nfd-worker -ca-file=/opt/nfd/ca.crt -cert-file=/opt/nfd/worker.crt -key-file=/opt/nfd/worker.key
```
### -cert-file
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-cert-file` is one of the three flags (together with `-ca-file` and
`-key-file`) controlling mutual TLS authentication on the worker side. This
flag specifies the TLS certificate presented for authenticating outgoing
requests.
Default: *empty*
> **NOTE:** Must be specified together with `-ca-file` and `-key-file`
Example:
```bash
nfd-workerr -cert-file=/opt/nfd/worker.crt -key-file=/opt/nfd/worker.key -ca-file=/opt/nfd/ca.crt
```
### -key-file
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-key-file` is one of the three flags (together with `-ca-file` and
`-cert-file`) controlling the mutual TLS authentication on the worker side.
This flag specifies the private key corresponding the given certificate file
(`-cert-file`) that is used for authenticating outgoing requests.
Default: *empty*
> **NOTE:** Must be specified together with `-cert-file` and `-ca-file`
Example:
```bash
nfd-worker -key-file=/opt/nfd/worker.key -cert-file=/opt/nfd/worker.crt -ca-file=/opt/nfd/ca.crt
```
### -kubeconfig
The `-kubeconfig` flag specifies the kubeconfig to use for connecting to the
@ -160,23 +84,6 @@ Example:
nfd-worker -kubeconfig ${HOME}/.kube/config
```
### -server-name-override
> **NOTE** the gRPC API is deprecated and will be removed in a future release.
> and this flag will be removed as well.
The `-server-name-override` flag specifies the common name (CN) which to
expect from the nfd-master TLS certificate. This flag is mostly intended for
development and debugging purposes.
Default: *empty*
Example:
```bash
nfd-worker -server-name-override=localhost
```
### -feature-sources
The `-feature-sources` flag specifies a comma-separated list of enabled feature
@ -221,6 +128,8 @@ nfd-worker -label-sources=kernel,system,local
### -metrics
**DEPRECATED**: Will be removed in NFD v0.17 and replaced by `-port`.
The `-metrics` flag specifies the port on which to expose
[Prometheus](https://prometheus.io/) metrics. Setting this to 0 disables the
metrics server on nfd-worker.

View file

@ -304,32 +304,6 @@ sources:
### sources.local
### sources.local.hooksEnabled
**DEPRECATED**: Hooks are DEPRECATED since v0.12.0 release and support (and
this configuration option) will be removed in NFD v0.17. Use
[feature files](../usage//customization-guide.md#feature-files) instead.
Configuration option to disable/enable hooks execution. Disabled by default.
> **NOTE:** The default NFD container image only supports statically linked
> binaries. Use the [full](../deployment/image-variants.md#full) image variant
> for a slightly more extensive environment that additionally supports bash and
> perl runtimes.
GitHub tracking issue:
[Drop support for hooks (#856)](https://github.com/kubernetes-sigs/node-feature-discovery/issues/856).
Default: false
Example:
```yaml
sources:
local:
hooksEnabled: true
```
### sources.pci
#### sources.pci.deviceClassWhitelist

View file

@ -26,7 +26,7 @@ labeling:
- [`NodeFeatureRule`](#nodefeaturerule-custom-resource) objects provide a way to
deploy custom labeling rules via the Kubernetes API.
- [`local`](#local-feature-source) feature source of nfd-worker creates
labels by reading text files and executing hooks.
labels by reading text files.
- [`custom`](#custom-feature-source) feature source of nfd-worker creates
labels based on user-specified rules.
@ -156,8 +156,6 @@ available fields and how to write labeling rules.
### Node tainting
This feature is experimental.
In some circumstances, it is desirable to keep nodes with specialized hardware
away from running general workload and instead leave them for workloads that
need the specialized hardware. One way to achieve it is to taint the nodes with
@ -234,13 +232,12 @@ point for external feature detectors. It provides a mechanism for pluggable
extensions, allowing the creation of new user-specific features and even
overriding built-in labels.
The `local` feature source has two methods for detecting features, feature
files and hooks (hooks are deprecated and slated for removal in NFD v0.17). The
features discovered by the `local` source can further be used in label rules
specified in [`NodeFeatureRule`](#nodefeaturerule-custom-resource) objects and
The `local` feature source uses feature files. The features discovered by the
`local` source can further be used in label rules specified in
[`NodeFeatureRule`](#nodefeaturerule-custom-resource) objects and
the [`custom`](#custom-feature-source) feature source.
> **NOTE:** Be careful when creating and/or updating hook or feature files
> **NOTE:** Be careful when creating and/or updating feature files
> while NFD is running. To avoid race conditions you should write
> into a temporary file, and atomically create/update the original file by
> doing a file rename operation. NFD ignores dot files,
@ -252,9 +249,7 @@ the [`custom`](#custom-feature-source) feature source.
Consider a plaintext file
`/etc/kubernetes/node-feature-discovery/features.d/my-features`
having the following contents (or alternatively a shell script
`/etc/kubernetes/node-feature-discovery/source.d/my-hook.sh` having the
following stdout output):
having the following contents:
```plaintext
feature.node.kubernetes.io/my-feature.1
@ -276,47 +271,9 @@ The `local` source reads files found in
`/etc/kubernetes/node-feature-discovery/features.d/`. File content is parsed
and translated into node labels, see the [input format below](#input-format).
### Hooks
**DEPRECATED** Hooks are deprecated and will be completely removed in NFD
v0.17.
The `local` source executes hooks found in
`/etc/kubernetes/node-feature-discovery/source.d/`. The hook files must be
executable and they are supposed to print all discovered features in `stdout`.
Since NFD v0.13 the default container image only supports statically linked ELF
binaries.
`stderr` output of hooks is propagated to NFD log so it can be used for
debugging and logging.
NFD tries to execute any regular files found from the hooks directory.
Any additional data files the hook might need (e.g. a configuration file)
should be placed in a separate directory to avoid NFD unnecessarily
trying to execute them. A subdirectory under the hooks directory can be used,
for example `/etc/kubernetes/node-feature-discovery/source.d/conf/`.
> **NOTE:** Starting from release v0.14 hooks are disabled by default and can
> be enabled via `sources.local.hooksEnabled` field in the worker
> configuration.
```yaml
sources:
local:
hooksEnabled: true # true by default at this point
```
> **NOTE:** NFD will blindly run any executables placed/mounted in the hooks
> directory. It is the user's responsibility to review the hooks for e.g.
> possible security implications.
>
> **NOTE:** The [full](../deployment/image-variants.md#full) image variant
> provides backwards-compatibility with older NFD versions by including a more
> expanded environment, supporting bash and perl runtimes.
### Input format
The hook stdout and feature files are expected to contain features in simple
The feature files are expected to contain features in simple
key-value pairs, separated by newlines:
```plaintext
@ -412,19 +369,16 @@ vendor.io/my-feature=value
### Mounts
The standard NFD deployments contain `hostPath` mounts for
`/etc/kubernetes/node-feature-discovery/source.d/` and
`/etc/kubernetes/node-feature-discovery/features.d/`, making these directories
from the host available inside the nfd-worker container.
#### Injecting labels from other pods
One use case for the feature files and hooks is detecting features in other
One use case for the feature files is detecting features in other
Pods outside NFD, e.g. in Kubernetes device plugins. By using the same
`hostPath` mounts for `/etc/kubernetes/node-feature-discovery/source.d/` and
`/etc/kubernetes/node-feature-discovery/features.d/` in the side-car (e.g.
device plugin) creates a shared area for deploying feature files and hooks to
NFD. NFD periodically scans the directories and reads any feature files and
runs any hooks it finds.
`hostPath` mounts `/etc/kubernetes/node-feature-discovery/features.d/`
in the side-car (e.g. device plugin) creates a shared area for
deploying feature files to NFD.
## Custom feature source
@ -1002,8 +956,8 @@ The following features are available for matching:
| | | **`major`** | int | First component of the kernel version (e.g. 4') |
| | | **`minor`** | int | Second component of the kernel version (e.g. 5') |
| | | **`revision`** | int | Third component of the kernel version (e.g. 6') |
| **`local.label`** | attribute | | | Labels from feature files and hooks, i.e. labels from the [*local* feature source](#local-feature-source) |
| **`local.feature`** | attribute | | | Features from feature files and hooks, i.e. features from the [*local* feature source](#local-feature-source) |
| **`local.label`** | attribute | | | Labels from feature files, i.e. labels from the [*local* feature source](#local-feature-source) |
| **`local.feature`** | attribute | | | Features from feature files, i.e. features from the [*local* feature source](#local-feature-source) |
| | | **`<label-name>`** | string | Label `<label-name>` created by the local feature source, value equals the value of the label |
| **`memory.nv`** | instance | | | NVDIMM devices present in the system |
| | | **`<sysfs-attribute>`** | string | Value of the sysfs device attribute, available attributes: `devtype`, `mode` |

199
go.mod
View file

@ -3,39 +3,37 @@ module sigs.k8s.io/node-feature-discovery
go 1.23.0
require (
github.com/fsnotify/fsnotify v1.7.0
github.com/golang/protobuf v1.5.4
github.com/fsnotify/fsnotify v1.8.0
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
github.com/jaypipes/ghw v0.13.0
github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.1.2
github.com/k8stopologyawareschedwg/podfingerprint v0.2.2
github.com/klauspost/cpuid/v2 v2.2.8
github.com/onsi/ginkgo/v2 v2.20.2
github.com/onsi/gomega v1.34.2
github.com/opencontainers/runc v1.1.15
github.com/prometheus/client_golang v1.18.0
github.com/klauspost/cpuid/v2 v2.2.9
github.com/onsi/ginkgo/v2 v2.21.0
github.com/onsi/gomega v1.35.1
github.com/opencontainers/runc v1.2.1
github.com/prometheus/client_golang v1.19.1
github.com/smartystreets/goconvey v1.8.1
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
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
k8s.io/client-go v0.30.3
k8s.io/code-generator v0.30.3
k8s.io/component-base v0.30.3
golang.org/x/net v0.31.0
golang.org/x/time v0.8.0
google.golang.org/grpc v1.68.0
k8s.io/api v0.31.2
k8s.io/apiextensions-apiserver v0.31.2
k8s.io/apimachinery v0.31.2
k8s.io/client-go v0.31.2
k8s.io/code-generator v0.31.2
k8s.io/component-base v0.31.2
k8s.io/klog/v2 v2.130.1
k8s.io/kubectl v0.30.3
k8s.io/kubelet v0.30.3
k8s.io/kubernetes v1.30.3
k8s.io/pod-security-admission v0.30.3
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
k8s.io/kubectl v0.31.2
k8s.io/kubelet v0.31.2
k8s.io/kubernetes v1.31.2
k8s.io/pod-security-admission v0.31.2
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
sigs.k8s.io/node-feature-discovery/api/nfd v0.0.0-00010101000000-000000000000
sigs.k8s.io/yaml v1.4.0
)
@ -45,39 +43,39 @@ require (
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cilium/ebpf v0.12.3 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/cyphar/filepath-securejoin v0.3.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
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/google/cel-go v0.17.8 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/cel-go v0.20.1 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jaypipes/pcidb v1.0.1 // indirect
@ -85,68 +83,72 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/spdystream v0.4.0 // indirect
github.com/moby/sys/mountinfo v0.7.1 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/runtime-spec v1.1.0-rc.2 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smarty/assertions v1.15.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
go.etcd.io/etcd/api/v3 v3.5.10 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect
go.etcd.io/etcd/client/v3 v3.5.10 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 // indirect
go.opentelemetry.io/otel v1.20.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect
go.opentelemetry.io/otel/metric v1.20.0 // indirect
go.opentelemetry.io/otel/sdk v1.20.0 // indirect
go.opentelemetry.io/otel/trace v1.20.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.etcd.io/etcd/api/v3 v3.5.14 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect
go.etcd.io/etcd/client/v3 v3.5.14 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/oauth2 v0.17.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/tools v0.24.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/term v0.26.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/tools v0.26.0 // 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/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // 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
gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.0 // indirect
k8s.io/apiserver v0.30.3 // indirect
k8s.io/cloud-provider v0.30.3 // indirect
k8s.io/component-helpers v0.30.3 // indirect
k8s.io/controller-manager v0.30.3 // indirect
k8s.io/csi-translation-lib v0.30.3 // indirect
k8s.io/dynamic-resource-allocation v0.30.3 // indirect
k8s.io/apiserver v0.31.2 // indirect
k8s.io/cloud-provider v0.31.2 // indirect
k8s.io/component-helpers v0.31.2 // indirect
k8s.io/controller-manager v0.31.2 // indirect
k8s.io/cri-api v0.31.2 // indirect
k8s.io/cri-client v0.0.0 // indirect
k8s.io/csi-translation-lib v0.31.2 // indirect
k8s.io/dynamic-resource-allocation v0.31.2 // indirect
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect
k8s.io/kms v0.30.3 // indirect
k8s.io/kms v0.31.2 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/mount-utils v0.25.0 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)
@ -155,30 +157,31 @@ require (
// need to override with commits (corresponding their kubernetes-* tags)
replace (
github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2
k8s.io/api => k8s.io/api v0.30.3
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.30.3
k8s.io/apimachinery => k8s.io/apimachinery v0.30.3
k8s.io/apiserver => k8s.io/apiserver v0.30.3
k8s.io/cli-runtime => k8s.io/cli-runtime v0.30.3
k8s.io/client-go => k8s.io/client-go v0.30.3
k8s.io/cloud-provider => k8s.io/cloud-provider v0.30.3
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.30.3
k8s.io/code-generator => k8s.io/code-generator v0.30.3
k8s.io/component-base => k8s.io/component-base v0.30.3
k8s.io/component-helpers => k8s.io/component-helpers v0.30.3
k8s.io/controller-manager => k8s.io/controller-manager v0.30.3
k8s.io/cri-api => k8s.io/cri-api v0.30.3
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.30.3
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.30.3
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.30.3
k8s.io/kube-proxy => k8s.io/kube-proxy v0.30.3
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.30.3
k8s.io/kubectl => k8s.io/kubectl v0.30.3
k8s.io/kubelet => k8s.io/kubelet v0.30.3
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.30.3
k8s.io/metrics => k8s.io/metrics v0.30.3
k8s.io/mount-utils => k8s.io/mount-utils v0.30.3
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.30.3
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.30.3
k8s.io/api => k8s.io/api v0.31.2
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.31.2
k8s.io/apimachinery => k8s.io/apimachinery v0.31.2
k8s.io/apiserver => k8s.io/apiserver v0.31.2
k8s.io/cli-runtime => k8s.io/cli-runtime v0.31.2
k8s.io/client-go => k8s.io/client-go v0.31.2
k8s.io/cloud-provider => k8s.io/cloud-provider v0.31.2
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.31.2
k8s.io/code-generator => k8s.io/code-generator v0.31.2
k8s.io/component-base => k8s.io/component-base v0.31.2
k8s.io/component-helpers => k8s.io/component-helpers v0.31.2
k8s.io/controller-manager => k8s.io/controller-manager v0.31.2
k8s.io/cri-api => k8s.io/cri-api v0.31.2
k8s.io/cri-client => k8s.io/cri-client v0.31.2
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.31.2
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.31.2
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.31.2
k8s.io/kube-proxy => k8s.io/kube-proxy v0.31.2
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.31.2
k8s.io/kubectl => k8s.io/kubectl v0.31.2
k8s.io/kubelet => k8s.io/kubelet v0.31.2
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.31.2
k8s.io/metrics => k8s.io/metrics v0.31.2
k8s.io/mount-utils => k8s.io/mount-utils v0.31.2
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.31.2
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.31.2
sigs.k8s.io/node-feature-discovery/api/nfd => ./api/nfd
)

365
go.sum
View file

@ -1,8 +1,3 @@
cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM=
cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI=
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
@ -13,8 +8,8 @@ github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
@ -23,18 +18,14 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4=
github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM=
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ=
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/checkpoint-restore/go-criu/v6 v6.3.0 h1:mIdrSO2cPNWQY1truPg6uHLXyKHk3Z5Odx4wjKOASzA=
github.com/checkpoint-restore/go-criu/v6 v6.3.0/go.mod h1:rrRTN/uSwY2X+BPRl/gkulo9gsKOSAeVp9/K2tv7xZI=
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/containerd/ttrpc v1.2.2 h1:9vqZr0pxwOF5koz6N0N3kJ0zDHokrcPxIR/ZR2YFtOs=
github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
@ -43,11 +34,12 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8=
github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@ -56,16 +48,14 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
github.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY=
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@ -80,8 +70,9 @@ github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@ -93,34 +84,28 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/cadvisor v0.49.0 h1:1PYeiORXmcFYi609M4Qvq5IzcvcVaWgYxDt78uH8jYA=
github.com/google/cadvisor v0.49.0/go.mod h1:s6Fqwb2KiWG6leCegVhw4KW40tf9f7m+SF1aXiE8Wsk=
github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto=
github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY=
github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=
github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
@ -129,8 +114,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 h1:6UKoz5ujsI55KNpsJH3UwCq3T8kKbZwNZBNPuTTje8U=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1/go.mod h1:YvJ2f6MplWDhfxiUC3KpyTy76kYUZA4W3pTv/wdKQ9Y=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@ -156,8 +141,8 @@ github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwS
github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@ -167,16 +152,18 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8=
github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -188,37 +175,38 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/runc v1.1.15 h1:QMmSU2q1YUg3iOJX11phnaDi2A5/zhx4BR6h+XZ1DMA=
github.com/opencontainers/runc v1.1.15/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA=
github.com/opencontainers/runtime-spec v1.1.0-rc.2 h1:ucBtEms2tamYYW/SvGpvq9yUN0NEVL6oyLEwDcTSrk8=
github.com/opencontainers/runtime-spec v1.1.0-rc.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runc v1.2.1 h1:mQkmeFSUxqFaVmvIn1VQPeQIKpHFya5R07aJw0DKQa8=
github.com/opencontainers/runc v1.2.1/go.mod h1:/PXzF0h531HTMsYQnmxXkBD7YaGShm/2zcRB79dksUc=
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY=
github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smarty/assertions v1.15.1 h1:812oFiXI+G55vxsFf+8bIZ1ux30qtkdqzKbEFwyX3Tk=
github.com/smarty/assertions v1.15.1/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
@ -254,45 +242,46 @@ github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJ
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k=
go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI=
go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0=
go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U=
go.etcd.io/etcd/client/v2 v2.305.10 h1:MrmRktzv/XF8CvtQt+P6wLUlURaNpSDJHFZhe//2QE4=
go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA=
go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao=
go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc=
go.etcd.io/etcd/pkg/v3 v3.5.10 h1:WPR8K0e9kWl1gAhB5A7gEa5ZBTNkT9NdNWrR8Qpo1CM=
go.etcd.io/etcd/pkg/v3 v3.5.10/go.mod h1:TKTuCKKcF1zxmfKWDkfz5qqYaE3JncKKZPFf8c1nFUs=
go.etcd.io/etcd/raft/v3 v3.5.10 h1:cgNAYe7xrsrn/5kXMSaH8kM/Ky8mAdMqGOxyYwpP0LA=
go.etcd.io/etcd/raft/v3 v3.5.10/go.mod h1:odD6kr8XQXTy9oQnyMPBOr0TVe+gT0neQhElQ6jbGRc=
go.etcd.io/etcd/server/v3 v3.5.10 h1:4NOGyOwD5sUZ22PiWYKmfxqoeh72z6EhYjNosKGLmZg=
go.etcd.io/etcd/server/v3 v3.5.10/go.mod h1:gBplPHfs6YI0L+RpGkTQO7buDbHv5HJGG/Bst0/zIPo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 h1:PzIubN4/sjByhDRHLviCjJuweBXWFZWhghjg7cS28+M=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0/go.mod h1:Ct6zzQEuGK3WpJs2n4dn+wfJYzd/+hNnxMRTWjGn30M=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 h1:1eHu3/pUSWaOgltNK3WJFaywKsTIr/PwvHyDmi0lQA0=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0/go.mod h1:HyABWq60Uy1kjJSa2BVOxUVao8Cdick5AWSKPutqy6U=
go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc=
go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0=
go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA=
go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM=
go.opentelemetry.io/otel/sdk v1.20.0 h1:5Jf6imeFZlZtKv9Qbo6qt2ZkmWtdWx/wzcCbNUlAWGM=
go.opentelemetry.io/otel/sdk v1.20.0/go.mod h1:rmkSx1cZCm/tn16iWDn1GQbLtsW/LvsdEEFzCSRM6V0=
go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ=
go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0=
go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU=
go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ=
go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI=
go.etcd.io/etcd/client/v2 v2.305.13 h1:RWfV1SX5jTU0lbCvpVQe3iPQeAHETWdOTb6pxhd77C8=
go.etcd.io/etcd/client/v2 v2.305.13/go.mod h1:iQnL7fepbiomdXMb3om1rHq96htNNGv2sJkEcZGDRRg=
go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg=
go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk=
go.etcd.io/etcd/pkg/v3 v3.5.13 h1:st9bDWNsKkBNpP4PR1MvM/9NqUPfvYZx/YXegsYEH8M=
go.etcd.io/etcd/pkg/v3 v3.5.13/go.mod h1:N+4PLrp7agI/Viy+dUYpX7iRtSPvKq+w8Y14d1vX+m0=
go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA=
go.etcd.io/etcd/raft/v3 v3.5.13/go.mod h1:uUFibGLn2Ksm2URMxN1fICGhk8Wu96EfDQyuLhAcAmw=
go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok=
go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@ -302,84 +291,68 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0=
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
@ -394,56 +367,58 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ=
k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04=
k8s.io/apiextensions-apiserver v0.30.3 h1:oChu5li2vsZHx2IvnGP3ah8Nj3KyqG3kRSaKmijhB9U=
k8s.io/apiextensions-apiserver v0.30.3/go.mod h1:uhXxYDkMAvl6CJw4lrDN4CPbONkF3+XL9cacCT44kV4=
k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc=
k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
k8s.io/apiserver v0.30.3 h1:QZJndA9k2MjFqpnyYv/PH+9PE0SHhx3hBho4X0vE65g=
k8s.io/apiserver v0.30.3/go.mod h1:6Oa88y1CZqnzetd2JdepO0UXzQX4ZnOekx2/PtEjrOg=
k8s.io/client-go v0.30.3 h1:bHrJu3xQZNXIi8/MoxYtZBBWQQXwy16zqJwloXXfD3k=
k8s.io/client-go v0.30.3/go.mod h1:8d4pf8vYu665/kUbsxWAQ/JDBNWqfFeZnvFiVdmx89U=
k8s.io/cloud-provider v0.30.3 h1:SNWZmllTymOTzIPJuhtZH6il/qVi75dQARRQAm9k6VY=
k8s.io/cloud-provider v0.30.3/go.mod h1:Ax0AVdHnM7tMYnJH1Ycy4SMBD98+4zA+tboUR9eYsY8=
k8s.io/code-generator v0.30.3 h1:bmtnLJKagDS5f5uOEpLyJiDfIMKXGMKgOLBdde+w0Mc=
k8s.io/code-generator v0.30.3/go.mod h1:PFgBiv+miFV7TZYp+RXgROkhA+sWYZ+mtpbMLofMke8=
k8s.io/component-base v0.30.3 h1:Ci0UqKWf4oiwy8hr1+E3dsnliKnkMLZMVbWzeorlk7s=
k8s.io/component-base v0.30.3/go.mod h1:C1SshT3rGPCuNtBs14RmVD2xW0EhRSeLvBh7AGk1quA=
k8s.io/component-helpers v0.30.3 h1:KPc8l0eGx9Wg2OcKc58k9ozNcVcOInAi3NGiuS2xJ/c=
k8s.io/component-helpers v0.30.3/go.mod h1:VOQ7g3q+YbKWwKeACG2BwPv4ftaN8jXYJ5U3xpzuYAE=
k8s.io/controller-manager v0.30.3 h1:QRFGkWWD5gi/KCSU0qxyUoZRbt+BKgiCUXiTD1RO95w=
k8s.io/controller-manager v0.30.3/go.mod h1:F95rjHCOH2WwV9XlVxRo71CtddKLhF3FzE+s1lc7E/0=
k8s.io/cri-api v0.30.3 h1:o7AAGb3645Ik44WkHI0eqUc7JbQVmstlINLlLAtU/rI=
k8s.io/cri-api v0.30.3/go.mod h1://4/umPJSW1ISNSNng4OwjpkvswJOQwU8rnkvO8P+xg=
k8s.io/csi-translation-lib v0.30.3 h1:wBaPWnOi14/vANRIrp8pmbdx/Pgz2QRcroH7wkodezc=
k8s.io/csi-translation-lib v0.30.3/go.mod h1:3AizNZbDttVDH1RO0x1yGEQP74e9Xbfb60IBP1oWO1o=
k8s.io/dynamic-resource-allocation v0.30.3 h1:49aLgEhknKF8gPVhsquJ3ylOnfC8ddxnqVP6y3T+hkM=
k8s.io/dynamic-resource-allocation v0.30.3/go.mod h1:Dj7OzA3pYT/OfN9PvuYt9CH5e5KcjKBRAik8XeG0nB8=
k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0=
k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk=
k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0=
k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM=
k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4=
k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE=
k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc=
k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs=
k8s.io/cloud-provider v0.31.2 h1:ZdstxJOcHzP45j8giE79VJmgNckBbw1ldtIqnhZvKIA=
k8s.io/cloud-provider v0.31.2/go.mod h1:+4L8YpYCEx1Ko5EKS/PzXyBY5YREwDKChsJjAxHRf08=
k8s.io/code-generator v0.31.2 h1:xLWxG0HEpMSHfcM//3u3Ro2Hmc6AyyLINQS//Z2GEOI=
k8s.io/code-generator v0.31.2/go.mod h1:eEQHXgBU/m7LDaToDoiz3t97dUUVyOblQdwOr8rivqc=
k8s.io/component-base v0.31.2 h1:Z1J1LIaC0AV+nzcPRFqfK09af6bZ4D1nAOpWsy9owlA=
k8s.io/component-base v0.31.2/go.mod h1:9PeyyFN/drHjtJZMCTkSpQJS3U9OXORnHQqMLDz0sUQ=
k8s.io/component-helpers v0.31.2 h1:V2yjoNeyg8WfvwrJwzfYz+RUwjlbcAIaDaHEStBbaZM=
k8s.io/component-helpers v0.31.2/go.mod h1:cNz+1ck38R0qWrjcw/rhQgGP6+Gwgw8ngr2ziDNmSXM=
k8s.io/controller-manager v0.31.2 h1:S5FPrZo6wpcTwQHfwcklOkr3MKGvKYtroOtCqri67Ns=
k8s.io/controller-manager v0.31.2/go.mod h1:+MymA0Dg2pC+hYYNsca9shRZbrkK3HKIg2B11p6eC+Q=
k8s.io/cri-api v0.31.2 h1:O/weUnSHvM59nTio0unxIUFyRHMRKkYn96YDILSQKmo=
k8s.io/cri-api v0.31.2/go.mod h1:Po3TMAYH/+KrZabi7QiwQI4a692oZcUOUThd/rqwxrI=
k8s.io/cri-client v0.31.2 h1:GLuzaFre8WueBohexPSUQEOMha3tBuacjb3PT10X8bI=
k8s.io/cri-client v0.31.2/go.mod h1:vUPilfcW9LSyp1Kbc1nuMu5IkyeF1HDqik6FeSAtUhk=
k8s.io/csi-translation-lib v0.31.2 h1:nCOE28rTUVOjwUKs4wl8wIZBHEnbQU5MkI0P6YM/Ylg=
k8s.io/csi-translation-lib v0.31.2/go.mod h1:X0paKG/WAqDyrfpiTyj8ga4srG0guOm2Sj2pNi4kP10=
k8s.io/dynamic-resource-allocation v0.31.2 h1:zJWogzySxVrJnGvV3yyspKHzgUieNzrPpLkTSFj+D1Q=
k8s.io/dynamic-resource-allocation v0.31.2/go.mod h1:0txLYaTMMwne1V9opaKK/h0eM0tS07e6ZTcsI6MPLWw=
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo=
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kms v0.30.3 h1:NLg+oN45S2Y3U0WiLRzbS61AY/XrS5JBMZp531Z+Pho=
k8s.io/kms v0.30.3/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4=
k8s.io/kms v0.31.2 h1:pyx7l2qVOkClzFMIWMVF/FxsSkgd+OIGH7DecpbscJI=
k8s.io/kms v0.31.2/go.mod h1:OZKwl1fan3n3N5FFxnW5C4V3ygrah/3YXeJWS3O6+94=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
k8s.io/kube-scheduler v0.30.3 h1:Fn2sX+tOvOMkRG6W2kntNAQStIZlr3/X6DfpMcy/rik=
k8s.io/kube-scheduler v0.30.3/go.mod h1:wzEWmB9+4/e+x96n1d1BHuETHHrOxb22ESAtVS/fJts=
k8s.io/kubectl v0.30.3 h1:YIBBvMdTW0xcDpmrOBzcpUVsn+zOgjMYIu7kAq+yqiI=
k8s.io/kubectl v0.30.3/go.mod h1:IcR0I9RN2+zzTRUa1BzZCm4oM0NLOawE6RzlDvd1Fpo=
k8s.io/kubelet v0.30.3 h1:KvGWDdhzD0vEyDyGTCjsDc8D+0+lwRMw3fJbfQgF7ys=
k8s.io/kubelet v0.30.3/go.mod h1:D9or45Vkzcqg55CEiqZ8dVbwP3Ksj7DruEVRS9oq3Ys=
k8s.io/kubernetes v1.30.3 h1:A0qoXI1YQNzrQZiff33y5zWxYHFT/HeZRK98/sRDJI0=
k8s.io/kubernetes v1.30.3/go.mod h1:yPbIk3MhmhGigX62FLJm+CphNtjxqCvAIFQXup6RKS0=
k8s.io/mount-utils v0.30.3 h1:8Z3wSW5+GSvGNtlDhtoZrBCKLMIf5z/9tf8pie+G06s=
k8s.io/mount-utils v0.30.3/go.mod h1:9sCVmwGLcV1MPvbZ+rToMDnl1QcGozy+jBPd0MsQLIo=
k8s.io/pod-security-admission v0.30.3 h1:UDGZWR3ry/XrN/Ki/w7qrp49OwgQsKyh+6xWbexvJi8=
k8s.io/pod-security-admission v0.30.3/go.mod h1:T1EQSOLl9YyDMnXNJfsq2jeci6uoymY0mrRkkKihd98=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 h1:/U5vjBbQn3RChhv7P11uhYvCSm5G2GaIi5AIGBS6r4c=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0/go.mod h1:z7+wmGM2dfIiLRfrC6jb5kV2Mq/sK1ZP303cxzkV5Y4=
k8s.io/kube-scheduler v0.31.2 h1:OcSTxT7+1WD9rN9154IhA1xbKBoSD2hwSEDXJ7cM81g=
k8s.io/kube-scheduler v0.31.2/go.mod h1:pG4VnIaQxQ/ADxETxAYNvOHYxT5kzfThWenw58ibPI0=
k8s.io/kubectl v0.31.2 h1:gTxbvRkMBwvTSAlobiTVqsH6S8Aa1aGyBcu5xYLsn8M=
k8s.io/kubectl v0.31.2/go.mod h1:EyASYVU6PY+032RrTh5ahtSOMgoDRIux9V1JLKtG5xM=
k8s.io/kubelet v0.31.2 h1:6Hytyw4LqWqhgzoi7sPfpDGClu2UfxmPmaiXPC4FRgI=
k8s.io/kubelet v0.31.2/go.mod h1:0E4++3cMWi2cJxOwuaQP3eMBa7PSOvAFgkTPlVc/2FA=
k8s.io/kubernetes v1.31.2 h1:VNSu4O7Xn5FFRsh9ePXyEPg6ucR21fOftarSdi053Gs=
k8s.io/kubernetes v1.31.2/go.mod h1:9xmT2buyTYj8TRKwRae7FcuY8k5+xlxv7VivvO0KKfs=
k8s.io/mount-utils v0.31.2 h1:Q0ygX92Lj9d1wcObAzj+JZ4oE7CNKZrqSOn1XcIS+y4=
k8s.io/mount-utils v0.31.2/go.mod h1:HV/VYBUGqYUj4vt82YltzpWvgv8FPg0G9ItyInT3NPU=
k8s.io/pod-security-admission v0.31.2 h1:GQWWShWxYPJSRcMyN3xA1xyYa3ROrAaBBiP9BdIf5Z4=
k8s.io/pod-security-admission v0.31.2/go.mod h1:LXpZT9KdccDH/We169EycuFC79iXmiU4mgpUEJDrf9Q=
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=

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

@ -18,6 +18,7 @@ package nfdgarbagecollector
import (
"context"
"fmt"
"testing"
"time"
@ -41,7 +42,7 @@ func TestNRTGC(t *testing.T) {
errChan := make(chan error)
go func() { errChan <- gc.Run() }()
So(waitForNRT(gc.client), ShouldBeTrue)
So(gc.client, shouldEventuallyHaveNRTs)
gc.Stop()
So(<-errChan, ShouldBeNil)
@ -52,7 +53,7 @@ func TestNRTGC(t *testing.T) {
errChan := make(chan error)
go func() { errChan <- gc.Run() }()
So(waitForNRT(gc.client, "node1"), ShouldBeTrue)
So(gc.client, shouldEventuallyHaveNRTs, "node1")
gc.Stop()
So(<-errChan, ShouldBeNil)
@ -67,7 +68,7 @@ func TestNRTGC(t *testing.T) {
err := gc.client.Resource(gvr).Delete(context.TODO(), "node1", metav1.DeleteOptions{})
So(err, ShouldBeNil)
So(waitForNRT(gc.client, "node2"), ShouldBeTrue)
So(gc.client, shouldEventuallyHaveNRTs, "node2")
})
Convey("periodic GC should remove obsolete NRT", t, func() {
gc := newMockGC([]string{"node1", "node2"}, []string{"node1", "node2"})
@ -83,7 +84,7 @@ func TestNRTGC(t *testing.T) {
_, err := gc.client.Resource(gvr).(fake.MetadataClient).CreateFake(nrt, metav1.CreateOptions{})
So(err, ShouldBeNil)
So(waitForNRT(gc.client, "node1", "node2"), ShouldBeTrue)
So(gc.client, shouldEventuallyHaveNRTs, "node1", "node2")
})
}
@ -132,22 +133,29 @@ type mockGC struct {
client metadataclient.Interface
}
func waitForNRT(cli metadataclient.Interface, names ...string) bool {
nameSet := sets.NewString(names...)
func shouldEventuallyHaveNRTs(actualI interface{}, expectedI ...interface{}) string {
cli := actualI.(metadataclient.Interface)
expected := sets.Set[string]{}
for _, e := range expectedI {
expected.Insert(e.(string))
}
actual := sets.Set[string]{}
gvr := topologyv1alpha2.SchemeGroupVersion.WithResource("noderesourcetopologies")
for i := 0; i < 2; i++ {
rsp, err := cli.Resource(gvr).List(context.TODO(), metav1.ListOptions{})
So(err, ShouldBeNil)
nrtNames := sets.NewString()
for _, meta := range rsp.Items {
nrtNames.Insert(meta.Name)
if err != nil {
return fmt.Sprintf("failed to list: %v", err)
}
if nrtNames.Equal(nameSet) {
return true
actual = sets.New[string]()
for _, meta := range rsp.Items {
actual.Insert(meta.Name)
}
if actual.Equal(expected) {
return ""
}
time.Sleep(1 * time.Second)
}
return false
return fmt.Sprintf("Expected: %v\nActual: %v", sets.List(expected), sets.List(actual))
}

View file

@ -141,21 +141,18 @@ func newNfdController(config *restclient.Config, nfdApiControllerOptions nfdApiC
if !nfdApiControllerOptions.DisableNodeFeature {
c.updateAllNodes()
}
// else: rules will be processed only when gRPC requests are received
},
UpdateFunc: func(oldObject, newObject interface{}) {
klog.V(2).InfoS("NodeFeatureRule updated", "nodefeaturerule", klog.KObj(newObject.(metav1.Object)))
if !nfdApiControllerOptions.DisableNodeFeature {
c.updateAllNodes()
}
// else: rules will be processed only when gRPC requests are received
},
DeleteFunc: func(object interface{}) {
klog.V(2).InfoS("NodeFeatureRule deleted", "nodefeaturerule", klog.KObj(object.(metav1.Object)))
if !nfdApiControllerOptions.DisableNodeFeature {
c.updateAllNodes()
}
// else: rules will be processed only when gRPC requests are received
},
}); err != nil {
return nil, err

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)
}
@ -260,39 +272,39 @@ func TestAddingExtResources(t *testing.T) {
fakeMaster := newFakeMaster()
Convey("When there are no matching labels", func() {
testNode := newTestNode()
resourceLabels := ExtendedResources{}
patches := fakeMaster.createExtendedResourcePatches(testNode, resourceLabels)
extendedResources := ExtendedResources{}
patches := fakeMaster.createExtendedResourcePatches(testNode, extendedResources)
So(len(patches), ShouldEqual, 0)
})
Convey("When there are matching labels", func() {
testNode := newTestNode()
resourceLabels := ExtendedResources{"feature-1": "1", "feature-2": "2"}
extendedResources := ExtendedResources{"feature-1": "1", "feature-2": "2"}
expectedPatches := []utils.JsonPatch{
utils.NewJsonPatch("add", "/status/capacity", "feature-1", "1"),
utils.NewJsonPatch("add", "/status/capacity", "feature-2", "2"),
}
patches := fakeMaster.createExtendedResourcePatches(testNode, resourceLabels)
patches := fakeMaster.createExtendedResourcePatches(testNode, extendedResources)
So(sortJsonPatches(patches), ShouldResemble, sortJsonPatches(expectedPatches))
})
Convey("When the resource already exists", func() {
testNode := newTestNode()
testNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
resourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-1": "1"}
patches := fakeMaster.createExtendedResourcePatches(testNode, resourceLabels)
extendedResources := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-1": "1"}
patches := fakeMaster.createExtendedResourcePatches(testNode, extendedResources)
So(len(patches), ShouldEqual, 0)
})
Convey("When the resource already exists but its capacity has changed", func() {
testNode := newTestNode()
testNode.Status.Capacity[corev1.ResourceName("feature-1")] = *resource.NewQuantity(2, resource.BinarySI)
resourceLabels := ExtendedResources{"feature-1": "1"}
extendedResources := ExtendedResources{"feature-1": "1"}
expectedPatches := []utils.JsonPatch{
utils.NewJsonPatch("replace", "/status/capacity", "feature-1", "1"),
utils.NewJsonPatch("replace", "/status/allocatable", "feature-1", "1"),
}
patches := fakeMaster.createExtendedResourcePatches(testNode, resourceLabels)
patches := fakeMaster.createExtendedResourcePatches(testNode, extendedResources)
So(sortJsonPatches(patches), ShouldResemble, sortJsonPatches(expectedPatches))
})
})
@ -303,118 +315,34 @@ func TestRemovingExtResources(t *testing.T) {
fakeMaster := newFakeMaster()
Convey("When none are removed", func() {
testNode := newTestNode()
resourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-1": "1", nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
extendedResources := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-1": "1", nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
testNode.Annotations[nfdv1alpha1.AnnotationNs+"/extended-resources"] = "feature-1,feature-2"
testNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
testNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
patches := fakeMaster.createExtendedResourcePatches(testNode, resourceLabels)
patches := fakeMaster.createExtendedResourcePatches(testNode, extendedResources)
So(len(patches), ShouldEqual, 0)
})
Convey("When the related label is gone", func() {
testNode := newTestNode()
resourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-4": "", nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
extendedResources := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-4": "", nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
testNode.Annotations[nfdv1alpha1.AnnotationNs+"/extended-resources"] = "feature-4,feature-2"
testNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-4")] = *resource.NewQuantity(4, resource.BinarySI)
testNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
patches := fakeMaster.createExtendedResourcePatches(testNode, resourceLabels)
patches := fakeMaster.createExtendedResourcePatches(testNode, extendedResources)
So(len(patches), ShouldBeGreaterThan, 0)
})
Convey("When the extended resource is no longer wanted", func() {
testNode := newTestNode()
testNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
testNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
resourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
extendedResources := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
testNode.Annotations[nfdv1alpha1.AnnotationNs+"/extended-resources"] = "feature-1,feature-2"
patches := fakeMaster.createExtendedResourcePatches(testNode, resourceLabels)
patches := fakeMaster.createExtendedResourcePatches(testNode, extendedResources)
So(len(patches), ShouldBeGreaterThan, 0)
})
})
}
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": {}}
@ -600,7 +528,7 @@ func TestRemoveLabelsWithPrefix(t *testing.T) {
func TestConfigParse(t *testing.T) {
Convey("When parsing configuration", t, func() {
master := newFakeMaster()
overrides := `{"noPublish": true, "enableTaints": true, "extraLabelNs": ["added.ns.io","added.kubernetes.io"], "denyLabelNs": ["denied.ns.io","denied.kubernetes.io"], "resourceLabels": ["vendor-1.com/feature-1","vendor-2.io/feature-2"], "labelWhiteList": "foo"}`
overrides := `{"noPublish": true, "enableTaints": true, "extraLabelNs": ["added.ns.io","added.kubernetes.io"], "denyLabelNs": ["denied.ns.io","denied.kubernetes.io"], "labelWhiteList": "foo"}`
Convey("and no core cmdline flags have been specified", func() {
So(master.configure("non-existing-file", overrides), ShouldBeNil)
@ -609,7 +537,6 @@ func TestConfigParse(t *testing.T) {
So(master.config.EnableTaints, ShouldResemble, true)
So(master.config.ExtraLabelNs, ShouldResemble, utils.StringSetVal{"added.ns.io": struct{}{}, "added.kubernetes.io": struct{}{}})
So(master.config.DenyLabelNs, ShouldResemble, utils.StringSetVal{"denied.ns.io": struct{}{}, "denied.kubernetes.io": struct{}{}})
So(master.config.ResourceLabels, ShouldResemble, utils.StringSetVal{"vendor-1.com/feature-1": struct{}{}, "vendor-2.io/feature-2": struct{}{}})
So(master.config.LabelWhiteList.String(), ShouldEqual, "foo")
})
})
@ -635,7 +562,6 @@ func TestConfigParse(t *testing.T) {
_, err = f.WriteString(`
noPublish: true
denyLabelNs: ["denied.ns.io","denied.kubernetes.io"]
resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
enableTaints: false
labelWhiteList: "foo"
leaderElection:
@ -654,7 +580,6 @@ leaderElection:
So(master.config.NoPublish, ShouldBeTrue)
So(master.config.EnableTaints, ShouldBeFalse)
So(master.config.ExtraLabelNs, ShouldResemble, utils.StringSetVal{"override.added.ns.io": struct{}{}})
So(master.config.ResourceLabels, ShouldResemble, utils.StringSetVal{"vendor-1.com/feature-1": struct{}{}, "vendor-2.io/feature-2": struct{}{}}) // from cmdline
So(master.config.DenyLabelNs, ShouldResemble, utils.StringSetVal{"denied.ns.io": struct{}{}, "denied.kubernetes.io": struct{}{}})
So(master.config.LabelWhiteList.String(), ShouldEqual, "foo")
So(master.config.LeaderElection.LeaseDuration.Seconds(), ShouldEqual, float64(20))

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"
@ -92,7 +87,6 @@ type NFDConfig struct {
ExtraLabelNs utils.StringSetVal
LabelWhiteList *regexp.Regexp
NoPublish bool
ResourceLabels utils.StringSetVal
EnableTaints bool
ResyncPeriod utils.DurationVal
LeaderElection LeaderElectionConfig
@ -113,7 +107,6 @@ type ConfigOverrideArgs struct {
DenyLabelNs *utils.StringSetVal
ExtraLabelNs *utils.StringSetVal
LabelWhiteList *utils.RegexpVal
ResourceLabels *utils.StringSetVal
EnableTaints *bool
NoPublish *bool
ResyncPeriod *utils.DurationVal
@ -122,20 +115,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 +155,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 +182,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 +207,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)
@ -275,7 +250,6 @@ func newDefaultConfig() *NFDConfig {
NoPublish: false,
AutoDefaultNs: true,
NfdApiParallelism: 10,
ResourceLabels: utils.StringSetVal{},
EnableTaints: false,
ResyncPeriod: utils.DurationVal{Duration: time.Duration(1) * time.Hour},
LeaderElection: LeaderElectionConfig{
@ -311,11 +285,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 +315,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 +325,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 +374,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
@ -616,7 +523,7 @@ func (m *nfdMaster) updateMasterNode() error {
// into extended resources. This function also handles proper namespacing of
// labels and ERs, i.e. adds the possibly missing default namespace for labels
// arriving through the gRPC API.
func (m *nfdMaster) filterFeatureLabels(labels Labels, features *nfdv1alpha1.Features) (Labels, ExtendedResources) {
func (m *nfdMaster) filterFeatureLabels(labels Labels, features *nfdv1alpha1.Features) Labels {
outLabels := Labels{}
for name, value := range labels {
if value, err := m.filterFeatureLabel(name, value, features); err != nil {
@ -627,28 +534,12 @@ func (m *nfdMaster) filterFeatureLabels(labels Labels, features *nfdv1alpha1.Fea
}
}
// Remove labels which are intended to be extended resources
extendedResources := ExtendedResources{}
for extendedResourceName := range m.config.ResourceLabels {
extendedResourceName := addNs(extendedResourceName, nfdv1alpha1.FeatureLabelNs)
if value, ok := outLabels[extendedResourceName]; ok {
if _, err := strconv.Atoi(value); err != nil {
klog.ErrorS(err, "bad label value encountered for extended resource", "labelKey", extendedResourceName, "labelValue", value)
nodeERsRejected.Inc()
continue // non-numeric label can't be used
}
extendedResources[extendedResourceName] = value
delete(outLabels, extendedResourceName)
}
}
if len(outLabels) > 0 && m.config.Restrictions.DisableLabels {
klog.V(2).InfoS("node labels are disabled in configuration (restrictions.disableLabels=true)")
outLabels = Labels{}
}
return outLabels, extendedResources
return outLabels
}
func (m *nfdMaster) filterFeatureLabel(name, value string, features *nfdv1alpha1.Features) (string, error) {
@ -717,18 +608,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 +622,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 +765,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
@ -1033,16 +880,12 @@ func (m *nfdMaster) refreshNodeFeatures(cli k8sclient.Interface, node *corev1.No
crLabels, crAnnotations, crExtendedResources, crTaints := m.processNodeFeatureRule(node.Name, features)
// Mix in CR-originated labels
// Labels
maps.Copy(labels, crLabels)
labels = m.filterFeatureLabels(labels, features)
// Remove labels which are intended to be extended resources via
// -resource-labels or their NS is not whitelisted
labels, extendedResources := m.filterFeatureLabels(labels, features)
// Mix in CR-originated extended resources with -resource-labels
maps.Copy(extendedResources, crExtendedResources)
extendedResources = m.filterExtendedResources(features, extendedResources)
// Extended resources
extendedResources := m.filterExtendedResources(features, crExtendedResources)
if len(extendedResources) > 0 && m.config.Restrictions.DisableExtendedResources {
klog.V(2).InfoS("extended resources are disabled in configuration (restrictions.disableExtendedResources=true)")
@ -1146,30 +989,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
@ -1416,9 +1235,6 @@ func (m *nfdMaster) configure(filepath string, overrides string) error {
if m.args.Overrides.ExtraLabelNs != nil {
c.ExtraLabelNs = *m.args.Overrides.ExtraLabelNs
}
if m.args.Overrides.ResourceLabels != nil {
c.ResourceLabels = *m.args.Overrides.ResourceLabels
}
if m.args.Overrides.EnableTaints != nil {
c.EnableTaints = *m.args.Overrides.EnableTaints
}
@ -1533,7 +1349,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,13 +27,12 @@ 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 {
started bool
queue workqueue.RateLimitingInterface
nfgQueue workqueue.RateLimitingInterface
queue workqueue.TypedRateLimitingInterface[string]
nfgQueue workqueue.TypedRateLimitingInterface[string]
sync.RWMutex
wg sync.WaitGroup
@ -49,11 +48,10 @@ func newUpdaterPool(nfdMaster *nfdMaster) *updaterPool {
}
func (u *updaterPool) processNodeUpdateRequest(cli k8sclient.Interface) bool {
n, quit := u.queue.Get()
nodeName, quit := u.queue.Get()
if quit {
return false
}
nodeName := n.(string)
defer u.queue.Done(nodeName)
@ -103,7 +101,7 @@ func (u *updaterPool) processNodeFeatureGroupUpdateRequest(cli nfdclientset.Inte
// Check if NodeFeatureGroup exists
var nfg *nfdv1alpha1.NodeFeatureGroup
var err error
if nfg, err = getNodeFeatureGroup(cli, u.nfdMaster.namespace, nfgName.(string)); apierrors.IsNotFound(err) {
if nfg, err = getNodeFeatureGroup(cli, u.nfdMaster.namespace, nfgName); apierrors.IsNotFound(err) {
klog.InfoS("NodeFeatureGroup not found, skip update", "NodeFeatureGroupName", nfgName)
} else if err := u.nfdMaster.nfdAPIUpdateNodeFeatureGroup(u.nfdMaster.nfdClient, nfg); err != nil {
if n := u.nfgQueue.NumRequeues(nfgName); n < 15 {
@ -120,7 +118,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()
@ -139,20 +144,18 @@ func (u *updaterPool) start(parallelism int) {
// Create ratelimiter. Mimic workqueue.DefaultControllerRateLimiter() but
// with modified per-item (node) rate limiting parameters.
rl := workqueue.NewMaxOfRateLimiter(
workqueue.NewItemExponentialFailureRateLimiter(50*time.Millisecond, 100*time.Second),
&workqueue.BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
rl := workqueue.NewTypedMaxOfRateLimiter[string](
workqueue.NewTypedItemExponentialFailureRateLimiter[string](50*time.Millisecond, 100*time.Second),
&workqueue.TypedBucketRateLimiter[string]{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
)
u.queue = workqueue.NewRateLimitingQueue(rl)
u.nfgQueue = workqueue.NewRateLimitingQueue(rl)
u.queue = workqueue.NewTypedRateLimitingQueue[string](rl)
u.nfgQueue = workqueue.NewTypedRateLimitingQueue[string](rl)
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",
@ -675,7 +572,7 @@ func getFeatureLabels(source source.LabelSource, labelWhiteList regexp.Regexp) (
name := k
switch sourceName := source.Name(); sourceName {
case "local", "custom":
// No mangling of labels from the custom rules, hooks or feature files
// No mangling of labels from the custom rules or feature files
default:
// Prefix for labels from other sources
if !strings.Contains(name, "/") {
@ -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

@ -20,7 +20,6 @@ import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
@ -64,7 +63,6 @@ const MaxFeatureFileSize = 65536
// Config
var (
featureFilesDir = "/etc/kubernetes/node-feature-discovery/features.d/"
hookDir = "/etc/kubernetes/node-feature-discovery/source.d/"
)
// localSource implements the FeatureSource and LabelSource interfaces.
@ -74,7 +72,6 @@ type localSource struct {
}
type Config struct {
HooksEnabled bool `json:"hooksEnabled,omitempty"`
}
// parsingOpts contains options used for directives parsing
@ -86,7 +83,7 @@ type parsingOpts struct {
// Singleton source instance
var (
src = localSource{config: newDefaultConfig()}
src = localSource{}
_ source.FeatureSource = &src
_ source.LabelSource = &src
_ source.ConfigurableSource = &src
@ -96,7 +93,7 @@ var (
func (s *localSource) Name() string { return Name }
// NewConfig method of the LabelSource interface
func (s *localSource) NewConfig() source.Config { return newDefaultConfig() }
func (s *localSource) NewConfig() source.Config { return &Config{} }
// GetConfig method of the LabelSource interface
func (s *localSource) GetConfig() source.Config { return s.config }
@ -125,13 +122,6 @@ func (s *localSource) GetLabels() (source.FeatureLabels, error) {
return labels, nil
}
// newDefaultConfig returns a new config with pre-populated defaults
func newDefaultConfig() *Config {
return &Config{
HooksEnabled: false,
}
}
// Discover method of the FeatureSource interface
func (s *localSource) Discover() error {
s.features = nfdv1alpha1.NewFeatures()
@ -141,33 +131,6 @@ func (s *localSource) Discover() error {
klog.ErrorS(err, "failed to read feature files")
}
if s.config.HooksEnabled {
klog.InfoS("starting hooks...")
klog.InfoS("NOTE: hooks are deprecated and will be completely removed in a future release.")
featuresFromHooks, labelsFromHooks, err := getFeaturesFromHooks()
if err != nil {
klog.ErrorS(err, "failed to run hooks")
}
// Merge features from hooks and files
for k, v := range featuresFromHooks {
if old, ok := featuresFromFiles[k]; ok {
klog.InfoS("overriding feature value", "featureKey", k, "oldValue", old, "newValue", v)
}
featuresFromFiles[k] = v
}
// Merge labels from hooks and files
for k, v := range labelsFromHooks {
if old, ok := labelsFromFiles[k]; ok {
klog.InfoS("overriding label value", "labelKey", k, "oldValue", old, "newValue", v)
}
labelsFromFiles[k] = v
}
}
s.features.Attributes[LabelFeature] = nfdv1alpha1.NewAttributeFeatures(labelsFromFiles)
s.features.Attributes[RawFeature] = nfdv1alpha1.NewAttributeFeatures(featuresFromFiles)
@ -279,98 +242,6 @@ func updateFeatures(m map[string]string, lineSplit []string) {
}
}
// Run all hooks and get features
func getFeaturesFromHooks() (map[string]string, map[string]string, error) {
features := make(map[string]string)
labels := make(map[string]string)
files, err := os.ReadDir(hookDir)
if err != nil {
if os.IsNotExist(err) {
klog.InfoS("hook directory does not exist", "path", hookDir)
return features, labels, nil
}
return features, labels, fmt.Errorf("unable to access %v: %w", hookDir, err)
}
if len(files) > 0 {
klog.InfoS("hooks are DEPRECATED since v0.12.0 and support will be removed in a future release; use feature files instead")
}
for _, file := range files {
fileName := file.Name()
// ignore hidden feature file
if strings.HasPrefix(fileName, ".") {
continue
}
lines, err := runHook(fileName)
if err != nil {
klog.ErrorS(err, "failed to run hook", "fileName", fileName)
continue
}
// Append features
fileFeatures, fileLabels := parseFeatureFile(lines, fileName)
klog.V(4).InfoS("hook executed", "fileName", fileName, "features", utils.DelayedDumper(fileFeatures), "labels", utils.DelayedDumper(fileLabels))
for k, v := range fileFeatures {
if old, ok := features[k]; ok {
klog.InfoS("overriding feature value from another hook", "featureKey", k, "oldValue", old, "newValue", v, "fileName", fileName)
}
features[k] = v
}
for k, v := range fileLabels {
if old, ok := labels[k]; ok {
klog.InfoS("overriding label value from another hook", "labelKey", k, "oldValue", old, "newValue", v, "fileName", fileName)
}
labels[k] = v
}
}
return features, labels, nil
}
// Run one hook
func runHook(file string) ([][]byte, error) {
var lines [][]byte
path := filepath.Join(hookDir, file)
filestat, err := os.Stat(path)
if err != nil {
klog.ErrorS(err, "failed to get filestat, skipping hook", "path", path)
return lines, err
}
if filestat.Mode().IsRegular() {
cmd := exec.Command(path)
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
// Run hook
err = cmd.Run()
// Forward stderr to our logger
errLines := bytes.Split(stderr.Bytes(), []byte("\n"))
for i, line := range errLines {
if i == len(errLines)-1 && len(line) == 0 {
// Don't print the last empty string
break
}
klog.InfoS(fmt.Sprintf("%s: %s", file, line))
}
// Do not return any lines if an error occurred
if err != nil {
return lines, err
}
lines = bytes.Split(stdout.Bytes(), []byte("\n"))
}
return lines, nil
}
// Read all files to get features
func getFeaturesFromFiles() (map[string]string, map[string]string, error) {
features := make(map[string]string)

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

@ -112,9 +112,8 @@ func cleanupNode(ctx context.Context, cs clientset.Interface) {
// Remove extended resources
for key := range node.Status.Capacity {
// We check for FeatureLabelNs as -resource-labels can create ERs there
_, ok := nfdERs[string(key)]
if ok || strings.HasPrefix(string(key), nfdv1alpha1.FeatureLabelNs) {
if ok || strings.HasPrefix(string(key), nfdv1alpha1.ExtendedResourceNs) {
delete(node.Status.Capacity, key)
delete(node.Status.Allocatable, key)
updateStatus = true

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

View file

@ -273,8 +273,7 @@ func createClusterRoleTopologyUpdater(ctx context.Context, cs clientset.Interfac
Name: "nfd-topology-updater-e2e",
},
// the Topology Updater doesn't need to access any kube object:
// it reads from the podresources socket and it sends updates to the
// nfd-master using the gRPC interface.
// it reads from the podresources socket and it updates the noderesourcetopologies
Rules: []rbacv1.PolicyRule{
{
APIGroups: []string{""},