diff --git a/Dockerfile_generator b/Dockerfile_generator index ece1fa44c..cc874bd57 100644 --- a/Dockerfile_generator +++ b/Dockerfile_generator @@ -5,18 +5,7 @@ FROM ${BUILDER_IMAGE} as builder 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.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 - -RUN curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protoc-25.3-linux-x86_64.zip && \ - unzip protoc-25.3-linux-x86_64.zip -d /usr/local && \ - rm protoc-25.3-linux-x86_64.zip && \ - chmod a+x /usr/local/bin/protoc && \ - find /usr/local -type d | xargs chmod 755 && \ - find /usr/local -type f | xargs chmod a+r - + go install golang.org/x/tools/cmd/goimports@v0.25.0 # Expect to be working with nfd WORKDIR /go/node-feature-discovery diff --git a/Makefile b/Makefile index 35e44dbb0..ed6c10df9 100644 --- a/Makefile +++ b/Makefile @@ -90,7 +90,7 @@ IMAGE_BUILD_ARGS_MINIMAL = --target minimal \ all: image -BUILD_BINARIES := nfd-master nfd-worker nfd-topology-updater nfd-gc kubectl-nfd +BUILD_BINARIES := nfd-master nfd-worker nfd-topology-updater nfd-gc kubectl-nfd nfd build-%: $(GO_CMD) build -v -o bin/ $(BUILD_FLAGS) ./cmd/$* diff --git a/api/generated/clientset/versioned/clientset.go b/api/generated/clientset/versioned/clientset.go index 9891a3436..44f129201 100644 --- a/api/generated/clientset/versioned/clientset.go +++ b/api/generated/clientset/versioned/clientset.go @@ -19,8 +19,8 @@ limitations under the License. package versioned import ( - "fmt" - "net/http" + fmt "fmt" + http "net/http" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nfd_client.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nfd_client.go index 282a6e717..e84e6e3e1 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nfd_client.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nfd_client.go @@ -29,15 +29,15 @@ type FakeNfdV1alpha1 struct { } func (c *FakeNfdV1alpha1) NodeFeatures(namespace string) v1alpha1.NodeFeatureInterface { - return &FakeNodeFeatures{c, namespace} + return newFakeNodeFeatures(c, namespace) } func (c *FakeNfdV1alpha1) NodeFeatureGroups(namespace string) v1alpha1.NodeFeatureGroupInterface { - return &FakeNodeFeatureGroups{c, namespace} + return newFakeNodeFeatureGroups(c, namespace) } func (c *FakeNfdV1alpha1) NodeFeatureRules() v1alpha1.NodeFeatureRuleInterface { - return &FakeNodeFeatureRules{c} + return newFakeNodeFeatureRules(c) } // RESTClient returns a RESTClient that is used to communicate diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeature.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeature.go index 186ce2388..a7356c9c8 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeature.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeature.go @@ -19,116 +19,34 @@ limitations under the License. package fake import ( - "context" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" + gentype "k8s.io/client-go/gentype" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/typed/nfd/v1alpha1" v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) -// FakeNodeFeatures implements NodeFeatureInterface -type FakeNodeFeatures struct { +// fakeNodeFeatures implements NodeFeatureInterface +type fakeNodeFeatures struct { + *gentype.FakeClientWithList[*v1alpha1.NodeFeature, *v1alpha1.NodeFeatureList] Fake *FakeNfdV1alpha1 - ns string } -var nodefeaturesResource = v1alpha1.SchemeGroupVersion.WithResource("nodefeatures") - -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.NewGetActionWithOptions(nodefeaturesResource, c.ns, name, options), emptyResult) - - if obj == nil { - return emptyResult, err +func newFakeNodeFeatures(fake *FakeNfdV1alpha1, namespace string) nfdv1alpha1.NodeFeatureInterface { + return &fakeNodeFeatures{ + gentype.NewFakeClientWithList[*v1alpha1.NodeFeature, *v1alpha1.NodeFeatureList]( + fake.Fake, + namespace, + v1alpha1.SchemeGroupVersion.WithResource("nodefeatures"), + v1alpha1.SchemeGroupVersion.WithKind("NodeFeature"), + func() *v1alpha1.NodeFeature { return &v1alpha1.NodeFeature{} }, + func() *v1alpha1.NodeFeatureList { return &v1alpha1.NodeFeatureList{} }, + func(dst, src *v1alpha1.NodeFeatureList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha1.NodeFeatureList) []*v1alpha1.NodeFeature { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1alpha1.NodeFeatureList, items []*v1alpha1.NodeFeature) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, } - 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.NewListActionWithOptions(nodefeaturesResource, nodefeaturesKind, c.ns, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.NodeFeatureList{ListMeta: obj.(*v1alpha1.NodeFeatureList).ListMeta} - for _, item := range obj.(*v1alpha1.NodeFeatureList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// 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.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.NewCreateActionWithOptions(nodefeaturesResource, c.ns, nodeFeature, opts), emptyResult) - - if obj == nil { - 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.NewUpdateActionWithOptions(nodefeaturesResource, c.ns, nodeFeature, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1alpha1.NodeFeature), err -} - -// Delete takes name of the nodeFeature and deletes it. Returns an error if one occurs. -func (c *FakeNodeFeatures) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(nodefeaturesResource, c.ns, name, opts), &v1alpha1.NodeFeature{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeNodeFeatures) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionActionWithOptions(nodefeaturesResource, c.ns, opts, listOpts) - - _, err := c.Fake.Invokes(action, &v1alpha1.NodeFeatureList{}) - return err -} - -// 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.NewPatchSubresourceActionWithOptions(nodefeaturesResource, c.ns, name, pt, data, opts, subresources...), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1alpha1.NodeFeature), err } diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturegroup.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturegroup.go index fdcacc968..cc4ae1070 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturegroup.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturegroup.go @@ -19,129 +19,34 @@ limitations under the License. package fake import ( - "context" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" + gentype "k8s.io/client-go/gentype" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/typed/nfd/v1alpha1" v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) -// FakeNodeFeatureGroups implements NodeFeatureGroupInterface -type FakeNodeFeatureGroups struct { +// fakeNodeFeatureGroups implements NodeFeatureGroupInterface +type fakeNodeFeatureGroups struct { + *gentype.FakeClientWithList[*v1alpha1.NodeFeatureGroup, *v1alpha1.NodeFeatureGroupList] Fake *FakeNfdV1alpha1 - ns string } -var nodefeaturegroupsResource = v1alpha1.SchemeGroupVersion.WithResource("nodefeaturegroups") - -var nodefeaturegroupsKind = v1alpha1.SchemeGroupVersion.WithKind("NodeFeatureGroup") - -// 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.NewGetActionWithOptions(nodefeaturegroupsResource, c.ns, name, options), emptyResult) - - if obj == nil { - return emptyResult, err +func newFakeNodeFeatureGroups(fake *FakeNfdV1alpha1, namespace string) nfdv1alpha1.NodeFeatureGroupInterface { + return &fakeNodeFeatureGroups{ + gentype.NewFakeClientWithList[*v1alpha1.NodeFeatureGroup, *v1alpha1.NodeFeatureGroupList]( + fake.Fake, + namespace, + v1alpha1.SchemeGroupVersion.WithResource("nodefeaturegroups"), + v1alpha1.SchemeGroupVersion.WithKind("NodeFeatureGroup"), + func() *v1alpha1.NodeFeatureGroup { return &v1alpha1.NodeFeatureGroup{} }, + func() *v1alpha1.NodeFeatureGroupList { return &v1alpha1.NodeFeatureGroupList{} }, + func(dst, src *v1alpha1.NodeFeatureGroupList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha1.NodeFeatureGroupList) []*v1alpha1.NodeFeatureGroup { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1alpha1.NodeFeatureGroupList, items []*v1alpha1.NodeFeatureGroup) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, } - 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.NewListActionWithOptions(nodefeaturegroupsResource, nodefeaturegroupsKind, c.ns, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.NodeFeatureGroupList{ListMeta: obj.(*v1alpha1.NodeFeatureGroupList).ListMeta} - for _, item := range obj.(*v1alpha1.NodeFeatureGroupList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// 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.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.NewCreateActionWithOptions(nodefeaturegroupsResource, c.ns, nodeFeatureGroup, opts), emptyResult) - - if obj == nil { - 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.NewUpdateActionWithOptions(nodefeaturegroupsResource, c.ns, nodeFeatureGroup, opts), emptyResult) - - if obj == nil { - 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) (result *v1alpha1.NodeFeatureGroup, err error) { - emptyResult := &v1alpha1.NodeFeatureGroup{} - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceActionWithOptions(nodefeaturegroupsResource, "status", c.ns, nodeFeatureGroup, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1alpha1.NodeFeatureGroup), err -} - -// Delete takes name of the nodeFeatureGroup and deletes it. Returns an error if one occurs. -func (c *FakeNodeFeatureGroups) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(nodefeaturegroupsResource, c.ns, name, opts), &v1alpha1.NodeFeatureGroup{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeNodeFeatureGroups) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionActionWithOptions(nodefeaturegroupsResource, c.ns, opts, listOpts) - - _, err := c.Fake.Invokes(action, &v1alpha1.NodeFeatureGroupList{}) - return err -} - -// 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.NewPatchSubresourceActionWithOptions(nodefeaturegroupsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1alpha1.NodeFeatureGroup), err } diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturerule.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturerule.go index b2916717c..6986116dc 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturerule.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturerule.go @@ -19,108 +19,34 @@ limitations under the License. package fake import ( - "context" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" + gentype "k8s.io/client-go/gentype" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/typed/nfd/v1alpha1" v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) -// FakeNodeFeatureRules implements NodeFeatureRuleInterface -type FakeNodeFeatureRules struct { +// fakeNodeFeatureRules implements NodeFeatureRuleInterface +type fakeNodeFeatureRules struct { + *gentype.FakeClientWithList[*v1alpha1.NodeFeatureRule, *v1alpha1.NodeFeatureRuleList] Fake *FakeNfdV1alpha1 } -var nodefeaturerulesResource = v1alpha1.SchemeGroupVersion.WithResource("nodefeaturerules") - -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.NewRootGetActionWithOptions(nodefeaturerulesResource, name, options), emptyResult) - if obj == nil { - return emptyResult, err +func newFakeNodeFeatureRules(fake *FakeNfdV1alpha1) nfdv1alpha1.NodeFeatureRuleInterface { + return &fakeNodeFeatureRules{ + gentype.NewFakeClientWithList[*v1alpha1.NodeFeatureRule, *v1alpha1.NodeFeatureRuleList]( + fake.Fake, + "", + v1alpha1.SchemeGroupVersion.WithResource("nodefeaturerules"), + v1alpha1.SchemeGroupVersion.WithKind("NodeFeatureRule"), + func() *v1alpha1.NodeFeatureRule { return &v1alpha1.NodeFeatureRule{} }, + func() *v1alpha1.NodeFeatureRuleList { return &v1alpha1.NodeFeatureRuleList{} }, + func(dst, src *v1alpha1.NodeFeatureRuleList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha1.NodeFeatureRuleList) []*v1alpha1.NodeFeatureRule { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1alpha1.NodeFeatureRuleList, items []*v1alpha1.NodeFeatureRule) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, } - 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.NewRootListActionWithOptions(nodefeaturerulesResource, nodefeaturerulesKind, opts), emptyResult) - if obj == nil { - return emptyResult, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.NodeFeatureRuleList{ListMeta: obj.(*v1alpha1.NodeFeatureRuleList).ListMeta} - for _, item := range obj.(*v1alpha1.NodeFeatureRuleList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// 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.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.NewRootCreateActionWithOptions(nodefeaturerulesResource, nodeFeatureRule, opts), emptyResult) - if obj == nil { - 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.NewRootUpdateActionWithOptions(nodefeaturerulesResource, nodeFeatureRule, opts), emptyResult) - if obj == nil { - return emptyResult, err - } - return obj.(*v1alpha1.NodeFeatureRule), err -} - -// Delete takes name of the nodeFeatureRule and deletes it. Returns an error if one occurs. -func (c *FakeNodeFeatureRules) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewRootDeleteActionWithOptions(nodefeaturerulesResource, name, opts), &v1alpha1.NodeFeatureRule{}) - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeNodeFeatureRules) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewRootDeleteCollectionActionWithOptions(nodefeaturerulesResource, opts, listOpts) - - _, err := c.Fake.Invokes(action, &v1alpha1.NodeFeatureRuleList{}) - return err -} - -// 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.NewRootPatchSubresourceActionWithOptions(nodefeaturerulesResource, name, pt, data, opts, subresources...), emptyResult) - if obj == nil { - return emptyResult, err - } - return obj.(*v1alpha1.NodeFeatureRule), err } diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go index 37a6f340a..4776a6c83 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go @@ -19,11 +19,11 @@ limitations under the License. package v1alpha1 import ( - "net/http" + http "net/http" rest "k8s.io/client-go/rest" - "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/scheme" - v1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" + scheme "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned/scheme" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) type NfdV1alpha1Interface interface { @@ -95,10 +95,10 @@ func New(c rest.Interface) *NfdV1alpha1Client { } func setConfigDefaults(config *rest.Config) error { - gv := v1alpha1.SchemeGroupVersion + gv := nfdv1alpha1.SchemeGroupVersion config.GroupVersion = &gv config.APIPath = "/apis" - config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() if config.UserAgent == "" { config.UserAgent = rest.DefaultKubernetesUserAgent() diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeature.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeature.go index 15e4e7013..70b854046 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeature.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeature.go @@ -19,14 +19,14 @@ limitations under the License. package v1alpha1 import ( - "context" + context "context" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" 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" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeaturesGetter has a method to return a NodeFeatureInterface. @@ -37,31 +37,32 @@ type NodeFeaturesGetter interface { // NodeFeatureInterface has methods to work with NodeFeature resources. type NodeFeatureInterface interface { - Create(ctx context.Context, nodeFeature *v1alpha1.NodeFeature, opts v1.CreateOptions) (*v1alpha1.NodeFeature, error) - Update(ctx context.Context, nodeFeature *v1alpha1.NodeFeature, opts v1.UpdateOptions) (*v1alpha1.NodeFeature, error) + Create(ctx context.Context, nodeFeature *nfdv1alpha1.NodeFeature, opts v1.CreateOptions) (*nfdv1alpha1.NodeFeature, error) + Update(ctx context.Context, nodeFeature *nfdv1alpha1.NodeFeature, opts v1.UpdateOptions) (*nfdv1alpha1.NodeFeature, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.NodeFeature, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.NodeFeatureList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*nfdv1alpha1.NodeFeature, error) + List(ctx context.Context, opts v1.ListOptions) (*nfdv1alpha1.NodeFeatureList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeature, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *nfdv1alpha1.NodeFeature, err error) NodeFeatureExpansion } // nodeFeatures implements NodeFeatureInterface type nodeFeatures struct { - *gentype.ClientWithList[*v1alpha1.NodeFeature, *v1alpha1.NodeFeatureList] + *gentype.ClientWithList[*nfdv1alpha1.NodeFeature, *nfdv1alpha1.NodeFeatureList] } // newNodeFeatures returns a NodeFeatures func newNodeFeatures(c *NfdV1alpha1Client, namespace string) *nodeFeatures { return &nodeFeatures{ - gentype.NewClientWithList[*v1alpha1.NodeFeature, *v1alpha1.NodeFeatureList]( + gentype.NewClientWithList[*nfdv1alpha1.NodeFeature, *nfdv1alpha1.NodeFeatureList]( "nodefeatures", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *v1alpha1.NodeFeature { return &v1alpha1.NodeFeature{} }, - func() *v1alpha1.NodeFeatureList { return &v1alpha1.NodeFeatureList{} }), + func() *nfdv1alpha1.NodeFeature { return &nfdv1alpha1.NodeFeature{} }, + func() *nfdv1alpha1.NodeFeatureList { return &nfdv1alpha1.NodeFeatureList{} }, + ), } } diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturegroup.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturegroup.go index 7d7e186c2..cdee1eb7b 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturegroup.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturegroup.go @@ -19,14 +19,14 @@ limitations under the License. package v1alpha1 import ( - "context" + context "context" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" 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" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeatureGroupsGetter has a method to return a NodeFeatureGroupInterface. @@ -37,33 +37,34 @@ type NodeFeatureGroupsGetter interface { // NodeFeatureGroupInterface has methods to work with NodeFeatureGroup resources. 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) + Create(ctx context.Context, nodeFeatureGroup *nfdv1alpha1.NodeFeatureGroup, opts v1.CreateOptions) (*nfdv1alpha1.NodeFeatureGroup, error) + Update(ctx context.Context, nodeFeatureGroup *nfdv1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (*nfdv1alpha1.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) + UpdateStatus(ctx context.Context, nodeFeatureGroup *nfdv1alpha1.NodeFeatureGroup, opts v1.UpdateOptions) (*nfdv1alpha1.NodeFeatureGroup, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.NodeFeatureGroup, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.NodeFeatureGroupList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*nfdv1alpha1.NodeFeatureGroup, error) + List(ctx context.Context, opts v1.ListOptions) (*nfdv1alpha1.NodeFeatureGroupList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeatureGroup, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *nfdv1alpha1.NodeFeatureGroup, err error) NodeFeatureGroupExpansion } // nodeFeatureGroups implements NodeFeatureGroupInterface type nodeFeatureGroups struct { - *gentype.ClientWithList[*v1alpha1.NodeFeatureGroup, *v1alpha1.NodeFeatureGroupList] + *gentype.ClientWithList[*nfdv1alpha1.NodeFeatureGroup, *nfdv1alpha1.NodeFeatureGroupList] } // newNodeFeatureGroups returns a NodeFeatureGroups func newNodeFeatureGroups(c *NfdV1alpha1Client, namespace string) *nodeFeatureGroups { return &nodeFeatureGroups{ - gentype.NewClientWithList[*v1alpha1.NodeFeatureGroup, *v1alpha1.NodeFeatureGroupList]( + gentype.NewClientWithList[*nfdv1alpha1.NodeFeatureGroup, *nfdv1alpha1.NodeFeatureGroupList]( "nodefeaturegroups", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *v1alpha1.NodeFeatureGroup { return &v1alpha1.NodeFeatureGroup{} }, - func() *v1alpha1.NodeFeatureGroupList { return &v1alpha1.NodeFeatureGroupList{} }), + func() *nfdv1alpha1.NodeFeatureGroup { return &nfdv1alpha1.NodeFeatureGroup{} }, + func() *nfdv1alpha1.NodeFeatureGroupList { return &nfdv1alpha1.NodeFeatureGroupList{} }, + ), } } diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go index e4a500732..cf0719ad1 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go @@ -19,14 +19,14 @@ limitations under the License. package v1alpha1 import ( - "context" + context "context" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" 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" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeatureRulesGetter has a method to return a NodeFeatureRuleInterface. @@ -37,31 +37,32 @@ type NodeFeatureRulesGetter interface { // NodeFeatureRuleInterface has methods to work with NodeFeatureRule resources. type NodeFeatureRuleInterface interface { - Create(ctx context.Context, nodeFeatureRule *v1alpha1.NodeFeatureRule, opts v1.CreateOptions) (*v1alpha1.NodeFeatureRule, error) - Update(ctx context.Context, nodeFeatureRule *v1alpha1.NodeFeatureRule, opts v1.UpdateOptions) (*v1alpha1.NodeFeatureRule, error) + Create(ctx context.Context, nodeFeatureRule *nfdv1alpha1.NodeFeatureRule, opts v1.CreateOptions) (*nfdv1alpha1.NodeFeatureRule, error) + Update(ctx context.Context, nodeFeatureRule *nfdv1alpha1.NodeFeatureRule, opts v1.UpdateOptions) (*nfdv1alpha1.NodeFeatureRule, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.NodeFeatureRule, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.NodeFeatureRuleList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*nfdv1alpha1.NodeFeatureRule, error) + List(ctx context.Context, opts v1.ListOptions) (*nfdv1alpha1.NodeFeatureRuleList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.NodeFeatureRule, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *nfdv1alpha1.NodeFeatureRule, err error) NodeFeatureRuleExpansion } // nodeFeatureRules implements NodeFeatureRuleInterface type nodeFeatureRules struct { - *gentype.ClientWithList[*v1alpha1.NodeFeatureRule, *v1alpha1.NodeFeatureRuleList] + *gentype.ClientWithList[*nfdv1alpha1.NodeFeatureRule, *nfdv1alpha1.NodeFeatureRuleList] } // newNodeFeatureRules returns a NodeFeatureRules func newNodeFeatureRules(c *NfdV1alpha1Client) *nodeFeatureRules { return &nodeFeatureRules{ - gentype.NewClientWithList[*v1alpha1.NodeFeatureRule, *v1alpha1.NodeFeatureRuleList]( + gentype.NewClientWithList[*nfdv1alpha1.NodeFeatureRule, *nfdv1alpha1.NodeFeatureRuleList]( "nodefeaturerules", c.RESTClient(), scheme.ParameterCodec, "", - func() *v1alpha1.NodeFeatureRule { return &v1alpha1.NodeFeatureRule{} }, - func() *v1alpha1.NodeFeatureRuleList { return &v1alpha1.NodeFeatureRuleList{} }), + func() *nfdv1alpha1.NodeFeatureRule { return &nfdv1alpha1.NodeFeatureRule{} }, + func() *nfdv1alpha1.NodeFeatureRuleList { return &nfdv1alpha1.NodeFeatureRuleList{} }, + ), } } diff --git a/api/generated/informers/externalversions/generic.go b/api/generated/informers/externalversions/generic.go index 86577fff5..1422eb95c 100644 --- a/api/generated/informers/externalversions/generic.go +++ b/api/generated/informers/externalversions/generic.go @@ -19,7 +19,7 @@ limitations under the License. package externalversions import ( - "fmt" + fmt "fmt" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" diff --git a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeature.go b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeature.go index 570a73114..34e14e434 100644 --- a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeature.go +++ b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeature.go @@ -19,7 +19,7 @@ limitations under the License. package v1alpha1 import ( - "context" + context "context" time "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -28,15 +28,15 @@ import ( cache "k8s.io/client-go/tools/cache" versioned "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned" internalinterfaces "sigs.k8s.io/node-feature-discovery/api/generated/informers/externalversions/internalinterfaces" - v1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/listers/nfd/v1alpha1" - nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/listers/nfd/v1alpha1" + apinfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeatureInformer provides access to a shared informer and lister for // NodeFeatures. type NodeFeatureInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.NodeFeatureLister + Lister() nfdv1alpha1.NodeFeatureLister } type nodeFeatureInformer struct { @@ -71,7 +71,7 @@ func NewFilteredNodeFeatureInformer(client versioned.Interface, namespace string return client.NfdV1alpha1().NodeFeatures(namespace).Watch(context.TODO(), options) }, }, - &nfdv1alpha1.NodeFeature{}, + &apinfdv1alpha1.NodeFeature{}, resyncPeriod, indexers, ) @@ -82,9 +82,9 @@ func (f *nodeFeatureInformer) defaultInformer(client versioned.Interface, resync } func (f *nodeFeatureInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&nfdv1alpha1.NodeFeature{}, f.defaultInformer) + return f.factory.InformerFor(&apinfdv1alpha1.NodeFeature{}, f.defaultInformer) } -func (f *nodeFeatureInformer) Lister() v1alpha1.NodeFeatureLister { - return v1alpha1.NewNodeFeatureLister(f.Informer().GetIndexer()) +func (f *nodeFeatureInformer) Lister() nfdv1alpha1.NodeFeatureLister { + return nfdv1alpha1.NewNodeFeatureLister(f.Informer().GetIndexer()) } diff --git a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturegroup.go b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturegroup.go index deebcae1f..30559f5ce 100644 --- a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturegroup.go +++ b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturegroup.go @@ -19,7 +19,7 @@ limitations under the License. package v1alpha1 import ( - "context" + context "context" time "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -28,15 +28,15 @@ import ( cache "k8s.io/client-go/tools/cache" versioned "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned" internalinterfaces "sigs.k8s.io/node-feature-discovery/api/generated/informers/externalversions/internalinterfaces" - v1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/listers/nfd/v1alpha1" - nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/listers/nfd/v1alpha1" + apinfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeatureGroupInformer provides access to a shared informer and lister for // NodeFeatureGroups. type NodeFeatureGroupInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.NodeFeatureGroupLister + Lister() nfdv1alpha1.NodeFeatureGroupLister } type nodeFeatureGroupInformer struct { @@ -71,7 +71,7 @@ func NewFilteredNodeFeatureGroupInformer(client versioned.Interface, namespace s return client.NfdV1alpha1().NodeFeatureGroups(namespace).Watch(context.TODO(), options) }, }, - &nfdv1alpha1.NodeFeatureGroup{}, + &apinfdv1alpha1.NodeFeatureGroup{}, resyncPeriod, indexers, ) @@ -82,9 +82,9 @@ func (f *nodeFeatureGroupInformer) defaultInformer(client versioned.Interface, r } func (f *nodeFeatureGroupInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&nfdv1alpha1.NodeFeatureGroup{}, f.defaultInformer) + return f.factory.InformerFor(&apinfdv1alpha1.NodeFeatureGroup{}, f.defaultInformer) } -func (f *nodeFeatureGroupInformer) Lister() v1alpha1.NodeFeatureGroupLister { - return v1alpha1.NewNodeFeatureGroupLister(f.Informer().GetIndexer()) +func (f *nodeFeatureGroupInformer) Lister() nfdv1alpha1.NodeFeatureGroupLister { + return nfdv1alpha1.NewNodeFeatureGroupLister(f.Informer().GetIndexer()) } diff --git a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go index 47fae6dfb..37ad15dce 100644 --- a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go +++ b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go @@ -19,7 +19,7 @@ limitations under the License. package v1alpha1 import ( - "context" + context "context" time "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -28,15 +28,15 @@ import ( cache "k8s.io/client-go/tools/cache" versioned "sigs.k8s.io/node-feature-discovery/api/generated/clientset/versioned" internalinterfaces "sigs.k8s.io/node-feature-discovery/api/generated/informers/externalversions/internalinterfaces" - v1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/listers/nfd/v1alpha1" - nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/generated/listers/nfd/v1alpha1" + apinfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeatureRuleInformer provides access to a shared informer and lister for // NodeFeatureRules. type NodeFeatureRuleInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.NodeFeatureRuleLister + Lister() nfdv1alpha1.NodeFeatureRuleLister } type nodeFeatureRuleInformer struct { @@ -70,7 +70,7 @@ func NewFilteredNodeFeatureRuleInformer(client versioned.Interface, resyncPeriod return client.NfdV1alpha1().NodeFeatureRules().Watch(context.TODO(), options) }, }, - &nfdv1alpha1.NodeFeatureRule{}, + &apinfdv1alpha1.NodeFeatureRule{}, resyncPeriod, indexers, ) @@ -81,9 +81,9 @@ func (f *nodeFeatureRuleInformer) defaultInformer(client versioned.Interface, re } func (f *nodeFeatureRuleInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&nfdv1alpha1.NodeFeatureRule{}, f.defaultInformer) + return f.factory.InformerFor(&apinfdv1alpha1.NodeFeatureRule{}, f.defaultInformer) } -func (f *nodeFeatureRuleInformer) Lister() v1alpha1.NodeFeatureRuleLister { - return v1alpha1.NewNodeFeatureRuleLister(f.Informer().GetIndexer()) +func (f *nodeFeatureRuleInformer) Lister() nfdv1alpha1.NodeFeatureRuleLister { + return nfdv1alpha1.NewNodeFeatureRuleLister(f.Informer().GetIndexer()) } diff --git a/api/generated/listers/nfd/v1alpha1/nodefeature.go b/api/generated/listers/nfd/v1alpha1/nodefeature.go index e1badec17..f670b6e8a 100644 --- a/api/generated/listers/nfd/v1alpha1/nodefeature.go +++ b/api/generated/listers/nfd/v1alpha1/nodefeature.go @@ -19,10 +19,10 @@ limitations under the License. package v1alpha1 import ( - "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" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeatureLister helps list NodeFeatures. @@ -30,7 +30,7 @@ import ( type NodeFeatureLister interface { // List lists all NodeFeatures in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.NodeFeature, err error) + List(selector labels.Selector) (ret []*nfdv1alpha1.NodeFeature, err error) // NodeFeatures returns an object that can list and get NodeFeatures. NodeFeatures(namespace string) NodeFeatureNamespaceLister NodeFeatureListerExpansion @@ -38,17 +38,17 @@ type NodeFeatureLister interface { // nodeFeatureLister implements the NodeFeatureLister interface. type nodeFeatureLister struct { - listers.ResourceIndexer[*v1alpha1.NodeFeature] + listers.ResourceIndexer[*nfdv1alpha1.NodeFeature] } // NewNodeFeatureLister returns a new NodeFeatureLister. func NewNodeFeatureLister(indexer cache.Indexer) NodeFeatureLister { - return &nodeFeatureLister{listers.New[*v1alpha1.NodeFeature](indexer, v1alpha1.Resource("nodefeature"))} + return &nodeFeatureLister{listers.New[*nfdv1alpha1.NodeFeature](indexer, nfdv1alpha1.Resource("nodefeature"))} } // NodeFeatures returns an object that can list and get NodeFeatures. func (s *nodeFeatureLister) NodeFeatures(namespace string) NodeFeatureNamespaceLister { - return nodeFeatureNamespaceLister{listers.NewNamespaced[*v1alpha1.NodeFeature](s.ResourceIndexer, namespace)} + return nodeFeatureNamespaceLister{listers.NewNamespaced[*nfdv1alpha1.NodeFeature](s.ResourceIndexer, namespace)} } // NodeFeatureNamespaceLister helps list and get NodeFeatures. @@ -56,15 +56,15 @@ func (s *nodeFeatureLister) NodeFeatures(namespace string) NodeFeatureNamespaceL type NodeFeatureNamespaceLister interface { // List lists all NodeFeatures in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.NodeFeature, err error) + List(selector labels.Selector) (ret []*nfdv1alpha1.NodeFeature, err error) // Get retrieves the NodeFeature from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.NodeFeature, error) + Get(name string) (*nfdv1alpha1.NodeFeature, error) NodeFeatureNamespaceListerExpansion } // nodeFeatureNamespaceLister implements the NodeFeatureNamespaceLister // interface. type nodeFeatureNamespaceLister struct { - listers.ResourceIndexer[*v1alpha1.NodeFeature] + listers.ResourceIndexer[*nfdv1alpha1.NodeFeature] } diff --git a/api/generated/listers/nfd/v1alpha1/nodefeaturegroup.go b/api/generated/listers/nfd/v1alpha1/nodefeaturegroup.go index 6315f9ef5..a59e53684 100644 --- a/api/generated/listers/nfd/v1alpha1/nodefeaturegroup.go +++ b/api/generated/listers/nfd/v1alpha1/nodefeaturegroup.go @@ -19,10 +19,10 @@ limitations under the License. package v1alpha1 import ( - "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" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeatureGroupLister helps list NodeFeatureGroups. @@ -30,7 +30,7 @@ import ( type NodeFeatureGroupLister interface { // List lists all NodeFeatureGroups in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.NodeFeatureGroup, err error) + List(selector labels.Selector) (ret []*nfdv1alpha1.NodeFeatureGroup, err error) // NodeFeatureGroups returns an object that can list and get NodeFeatureGroups. NodeFeatureGroups(namespace string) NodeFeatureGroupNamespaceLister NodeFeatureGroupListerExpansion @@ -38,17 +38,17 @@ type NodeFeatureGroupLister interface { // nodeFeatureGroupLister implements the NodeFeatureGroupLister interface. type nodeFeatureGroupLister struct { - listers.ResourceIndexer[*v1alpha1.NodeFeatureGroup] + listers.ResourceIndexer[*nfdv1alpha1.NodeFeatureGroup] } // NewNodeFeatureGroupLister returns a new NodeFeatureGroupLister. func NewNodeFeatureGroupLister(indexer cache.Indexer) NodeFeatureGroupLister { - return &nodeFeatureGroupLister{listers.New[*v1alpha1.NodeFeatureGroup](indexer, v1alpha1.Resource("nodefeaturegroup"))} + return &nodeFeatureGroupLister{listers.New[*nfdv1alpha1.NodeFeatureGroup](indexer, nfdv1alpha1.Resource("nodefeaturegroup"))} } // NodeFeatureGroups returns an object that can list and get NodeFeatureGroups. func (s *nodeFeatureGroupLister) NodeFeatureGroups(namespace string) NodeFeatureGroupNamespaceLister { - return nodeFeatureGroupNamespaceLister{listers.NewNamespaced[*v1alpha1.NodeFeatureGroup](s.ResourceIndexer, namespace)} + return nodeFeatureGroupNamespaceLister{listers.NewNamespaced[*nfdv1alpha1.NodeFeatureGroup](s.ResourceIndexer, namespace)} } // NodeFeatureGroupNamespaceLister helps list and get NodeFeatureGroups. @@ -56,15 +56,15 @@ func (s *nodeFeatureGroupLister) NodeFeatureGroups(namespace string) NodeFeature type NodeFeatureGroupNamespaceLister interface { // List lists all NodeFeatureGroups in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.NodeFeatureGroup, err error) + List(selector labels.Selector) (ret []*nfdv1alpha1.NodeFeatureGroup, err error) // Get retrieves the NodeFeatureGroup from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.NodeFeatureGroup, error) + Get(name string) (*nfdv1alpha1.NodeFeatureGroup, error) NodeFeatureGroupNamespaceListerExpansion } // nodeFeatureGroupNamespaceLister implements the NodeFeatureGroupNamespaceLister // interface. type nodeFeatureGroupNamespaceLister struct { - listers.ResourceIndexer[*v1alpha1.NodeFeatureGroup] + listers.ResourceIndexer[*nfdv1alpha1.NodeFeatureGroup] } diff --git a/api/generated/listers/nfd/v1alpha1/nodefeaturerule.go b/api/generated/listers/nfd/v1alpha1/nodefeaturerule.go index 15ecdd811..77cdcf0cb 100644 --- a/api/generated/listers/nfd/v1alpha1/nodefeaturerule.go +++ b/api/generated/listers/nfd/v1alpha1/nodefeaturerule.go @@ -19,10 +19,10 @@ limitations under the License. package v1alpha1 import ( - "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" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) // NodeFeatureRuleLister helps list NodeFeatureRules. @@ -30,19 +30,19 @@ import ( type NodeFeatureRuleLister interface { // List lists all NodeFeatureRules in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.NodeFeatureRule, err error) + List(selector labels.Selector) (ret []*nfdv1alpha1.NodeFeatureRule, err error) // Get retrieves the NodeFeatureRule from the index for a given name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.NodeFeatureRule, error) + Get(name string) (*nfdv1alpha1.NodeFeatureRule, error) NodeFeatureRuleListerExpansion } // nodeFeatureRuleLister implements the NodeFeatureRuleLister interface. type nodeFeatureRuleLister struct { - listers.ResourceIndexer[*v1alpha1.NodeFeatureRule] + listers.ResourceIndexer[*nfdv1alpha1.NodeFeatureRule] } // NewNodeFeatureRuleLister returns a new NodeFeatureRuleLister. func NewNodeFeatureRuleLister(indexer cache.Indexer) NodeFeatureRuleLister { - return &nodeFeatureRuleLister{listers.New[*v1alpha1.NodeFeatureRule](indexer, v1alpha1.Resource("nodefeaturerule"))} + return &nodeFeatureRuleLister{listers.New[*nfdv1alpha1.NodeFeatureRule](indexer, nfdv1alpha1.Resource("nodefeaturerule"))} } diff --git a/api/image-compatibility/v1alpha1/spec.go b/api/image-compatibility/v1alpha1/spec.go new file mode 100644 index 000000000..81a66c4ab --- /dev/null +++ b/api/image-compatibility/v1alpha1/spec.go @@ -0,0 +1,48 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" +) + +// ArtifactType is a type of OCI artifact that contains image compatibility metadata. +const ( + ArtifactType = "application/vnd.nfd.image-compatibility.v1alpha1" + Version = "v1alpha1" +) + +// Spec represents image compatibility metadata. +type Spec struct { + // Version of the spec. + Version string `json:"version"` + // Compatibilities contains list of compatibility sets. + Compatibilties []Compatibility `json:"compatibilities"` +} + +// Compatibility represents image compatibility metadata +// that describe the image requirements for the host and OS. +type Compatibility struct { + // Rules represents a list of Node Feature Rules. + Rules []nfdv1alpha1.Rule `json:"rules"` + // Weight indicates the priority of the compatibility set. + Weight int `json:"weight,omitempty"` + // Tag enables grouping or distinguishing between compatibility sets. + Tag string `json:"tag,omitempty"` + // Description of the compatibility set. + Description string `json:"description,omitempty"` +} diff --git a/api/nfd/go.mod b/api/nfd/go.mod index 41e7f972c..c626d2819 100644 --- a/api/nfd/go.mod +++ b/api/nfd/go.mod @@ -5,8 +5,8 @@ go 1.22.2 require ( github.com/gogo/protobuf v1.3.2 github.com/stretchr/testify v1.8.4 - k8s.io/api v0.30.7 - k8s.io/apimachinery v0.30.7 + k8s.io/api v0.30.8 + k8s.io/apimachinery v0.30.8 ) require ( diff --git a/api/nfd/go.sum b/api/nfd/go.sum index c016e091b..da58ef787 100644 --- a/api/nfd/go.sum +++ b/api/nfd/go.sum @@ -75,10 +75,10 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.30.7 h1:wB2eHI+IptVYsz5WsAQpI6+Dqi3+11wEWBqIh4fh980= -k8s.io/api v0.30.7/go.mod h1:bR0EwbmhYmJvUoeza7ZzBUmYCrVXccQ9JOdfv0BxhH0= -k8s.io/apimachinery v0.30.7 h1:CoQFxvzPFKwU1eJGN/8LgM3ZJBC3hKgvwGqRrL43uIY= -k8s.io/apimachinery v0.30.7/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/api v0.30.8 h1:Y+yZRF3c1WC0MTkLe0qBkiLCquRNa4I21/iDioGMCbo= +k8s.io/api v0.30.8/go.mod h1:89IE5MzirZ5HHxU/Hq1/KWGqXkhXClu/FHGesFhQ0A4= +k8s.io/apimachinery v0.30.8 h1:9jyTItYzmJc00cBDxZC5ArFNxUeKCwbw0m760iFUMKY= +k8s.io/apimachinery v0.30.8/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= diff --git a/api/nfd/v1alpha1/doc.go b/api/nfd/v1alpha1/doc.go index 17b8fc585..32b425965 100644 --- a/api/nfd/v1alpha1/doc.go +++ b/api/nfd/v1alpha1/doc.go @@ -19,5 +19,3 @@ limitations under the License. // +kubebuilder:object:generate=true // +groupName=nfd.k8s-sigs.io package v1alpha1 - -//go:generate ./generate.sh diff --git a/api/nfd/v1alpha1/generate.sh b/api/nfd/v1alpha1/generate.sh deleted file mode 100755 index d4fe85392..000000000 --- a/api/nfd/v1alpha1/generate.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -ex - -go-to-protobuf \ - --output-base=. \ - --go-header-file ../../../../hack/boilerplate.go.txt \ - --proto-import ../../../../vendor/ \ - --packages +sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1=v1alpha1 \ - --keep-gogoproto=false \ - --apimachinery-packages "-k8s.io/apimachinery/pkg/util/intstr" - -mv sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1/* . -rm -rf sigs.k8s.io diff --git a/api/nfd/v1alpha1/generated.pb.go b/api/nfd/v1alpha1/generated.pb.go deleted file mode 100644 index 4231691e4..000000000 --- a/api/nfd/v1alpha1/generated.pb.go +++ /dev/null @@ -1,2037 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1/generated.proto - -package v1alpha1 - -import ( - fmt "fmt" - - io "io" - math "math" - math_bits "math/bits" - reflect "reflect" - strings "strings" - - proto "github.com/gogo/protobuf/proto" - github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -func (m *AttributeFeatureSet) Reset() { *m = AttributeFeatureSet{} } -func (*AttributeFeatureSet) ProtoMessage() {} -func (*AttributeFeatureSet) Descriptor() ([]byte, []int) { - return fileDescriptor_6f67d44e41cfe439, []int{0} -} -func (m *AttributeFeatureSet) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AttributeFeatureSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *AttributeFeatureSet) XXX_Merge(src proto.Message) { - xxx_messageInfo_AttributeFeatureSet.Merge(m, src) -} -func (m *AttributeFeatureSet) XXX_Size() int { - return m.Size() -} -func (m *AttributeFeatureSet) XXX_DiscardUnknown() { - xxx_messageInfo_AttributeFeatureSet.DiscardUnknown(m) -} - -var xxx_messageInfo_AttributeFeatureSet proto.InternalMessageInfo - -func (m *Features) Reset() { *m = Features{} } -func (*Features) ProtoMessage() {} -func (*Features) Descriptor() ([]byte, []int) { - return fileDescriptor_6f67d44e41cfe439, []int{1} -} -func (m *Features) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Features) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *Features) XXX_Merge(src proto.Message) { - xxx_messageInfo_Features.Merge(m, src) -} -func (m *Features) XXX_Size() int { - return m.Size() -} -func (m *Features) XXX_DiscardUnknown() { - xxx_messageInfo_Features.DiscardUnknown(m) -} - -var xxx_messageInfo_Features proto.InternalMessageInfo - -func (m *FlagFeatureSet) Reset() { *m = FlagFeatureSet{} } -func (*FlagFeatureSet) ProtoMessage() {} -func (*FlagFeatureSet) Descriptor() ([]byte, []int) { - return fileDescriptor_6f67d44e41cfe439, []int{2} -} -func (m *FlagFeatureSet) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *FlagFeatureSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *FlagFeatureSet) XXX_Merge(src proto.Message) { - xxx_messageInfo_FlagFeatureSet.Merge(m, src) -} -func (m *FlagFeatureSet) XXX_Size() int { - return m.Size() -} -func (m *FlagFeatureSet) XXX_DiscardUnknown() { - xxx_messageInfo_FlagFeatureSet.DiscardUnknown(m) -} - -var xxx_messageInfo_FlagFeatureSet proto.InternalMessageInfo - -func (m *InstanceFeature) Reset() { *m = InstanceFeature{} } -func (*InstanceFeature) ProtoMessage() {} -func (*InstanceFeature) Descriptor() ([]byte, []int) { - return fileDescriptor_6f67d44e41cfe439, []int{3} -} -func (m *InstanceFeature) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *InstanceFeature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *InstanceFeature) XXX_Merge(src proto.Message) { - xxx_messageInfo_InstanceFeature.Merge(m, src) -} -func (m *InstanceFeature) XXX_Size() int { - return m.Size() -} -func (m *InstanceFeature) XXX_DiscardUnknown() { - xxx_messageInfo_InstanceFeature.DiscardUnknown(m) -} - -var xxx_messageInfo_InstanceFeature proto.InternalMessageInfo - -func (m *InstanceFeatureSet) Reset() { *m = InstanceFeatureSet{} } -func (*InstanceFeatureSet) ProtoMessage() {} -func (*InstanceFeatureSet) Descriptor() ([]byte, []int) { - return fileDescriptor_6f67d44e41cfe439, []int{4} -} -func (m *InstanceFeatureSet) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *InstanceFeatureSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *InstanceFeatureSet) XXX_Merge(src proto.Message) { - xxx_messageInfo_InstanceFeatureSet.Merge(m, src) -} -func (m *InstanceFeatureSet) XXX_Size() int { - return m.Size() -} -func (m *InstanceFeatureSet) XXX_DiscardUnknown() { - xxx_messageInfo_InstanceFeatureSet.DiscardUnknown(m) -} - -var xxx_messageInfo_InstanceFeatureSet proto.InternalMessageInfo - -func (m *Nil) Reset() { *m = Nil{} } -func (*Nil) ProtoMessage() {} -func (*Nil) Descriptor() ([]byte, []int) { - return fileDescriptor_6f67d44e41cfe439, []int{5} -} -func (m *Nil) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Nil) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *Nil) XXX_Merge(src proto.Message) { - xxx_messageInfo_Nil.Merge(m, src) -} -func (m *Nil) XXX_Size() int { - return m.Size() -} -func (m *Nil) XXX_DiscardUnknown() { - xxx_messageInfo_Nil.DiscardUnknown(m) -} - -var xxx_messageInfo_Nil proto.InternalMessageInfo - -func init() { - proto.RegisterType((*AttributeFeatureSet)(nil), "v1alpha1.AttributeFeatureSet") - proto.RegisterMapType((map[string]string)(nil), "v1alpha1.AttributeFeatureSet.ElementsEntry") - proto.RegisterType((*Features)(nil), "v1alpha1.Features") - proto.RegisterMapType((map[string]FlagFeatureSet)(nil), "v1alpha1.Features.FlagsEntry") - proto.RegisterMapType((map[string]InstanceFeatureSet)(nil), "v1alpha1.Features.InstancesEntry") - proto.RegisterMapType((map[string]AttributeFeatureSet)(nil), "v1alpha1.Features.VattributesEntry") - proto.RegisterType((*FlagFeatureSet)(nil), "v1alpha1.FlagFeatureSet") - proto.RegisterMapType((map[string]Nil)(nil), "v1alpha1.FlagFeatureSet.ElementsEntry") - proto.RegisterType((*InstanceFeature)(nil), "v1alpha1.InstanceFeature") - proto.RegisterMapType((map[string]string)(nil), "v1alpha1.InstanceFeature.AttributesEntry") - proto.RegisterType((*InstanceFeatureSet)(nil), "v1alpha1.InstanceFeatureSet") - proto.RegisterType((*Nil)(nil), "v1alpha1.Nil") -} - -func init() { - proto.RegisterFile("sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1/generated.proto", fileDescriptor_6f67d44e41cfe439) -} - -var fileDescriptor_6f67d44e41cfe439 = []byte{ - // 539 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xcd, 0x6e, 0xda, 0x40, - 0x10, 0xc7, 0xbd, 0x50, 0x24, 0x18, 0x44, 0x42, 0xb7, 0x3d, 0xb8, 0x56, 0xe3, 0xa4, 0x44, 0xaa, - 0x52, 0x55, 0xd8, 0x0a, 0xbd, 0xa0, 0x56, 0x3d, 0x04, 0x29, 0xe9, 0xc7, 0x21, 0x07, 0xb7, 0xaa, - 0x94, 0x48, 0x54, 0x5a, 0x60, 0x71, 0x56, 0x38, 0x36, 0xf2, 0xae, 0x91, 0xb8, 0xf5, 0x01, 0x7a, - 0xe8, 0x8b, 0x54, 0x95, 0xfa, 0x14, 0x1c, 0x73, 0xcc, 0x29, 0x2a, 0xee, 0x8b, 0x54, 0xf1, 0x07, - 0xb6, 0x83, 0x01, 0x35, 0x37, 0xef, 0xec, 0xcc, 0x6f, 0xe6, 0xff, 0xdf, 0x01, 0x78, 0xcf, 0x99, - 0xc9, 0xb5, 0x51, 0x9b, 0x6b, 0xcc, 0xd1, 0x6d, 0x67, 0x40, 0x9b, 0x43, 0x4a, 0x84, 0xe7, 0xd2, - 0xe6, 0x80, 0xf1, 0xbe, 0x33, 0xa1, 0xee, 0x54, 0x1f, 0x8f, 0x4c, 0x9d, 0x8c, 0x19, 0xd7, 0xed, - 0xe1, 0x40, 0x9f, 0x1c, 0x12, 0x6b, 0x7c, 0x41, 0x0e, 0x75, 0x93, 0xda, 0xd4, 0x25, 0x82, 0x0e, - 0xb4, 0xb1, 0xeb, 0x08, 0x07, 0x97, 0xe3, 0x1b, 0xa5, 0x69, 0x32, 0x71, 0xe1, 0xf5, 0xb4, 0xbe, - 0x73, 0xa9, 0x9b, 0x8e, 0xe9, 0xe8, 0x41, 0x42, 0xcf, 0x1b, 0x06, 0xa7, 0xe0, 0x10, 0x7c, 0x85, - 0x85, 0x8d, 0x9f, 0x08, 0x1e, 0x1d, 0x09, 0xe1, 0xb2, 0x9e, 0x27, 0xe8, 0x49, 0xd8, 0xfd, 0x13, - 0x15, 0xf8, 0x0c, 0xca, 0xd4, 0xa2, 0x97, 0xd4, 0x16, 0x5c, 0x46, 0x7b, 0xc5, 0x83, 0x6a, 0xeb, - 0xa5, 0x16, 0xf7, 0xd0, 0x72, 0x0a, 0xb4, 0xe3, 0x28, 0xfb, 0xd8, 0x16, 0xee, 0xb4, 0x53, 0x9f, - 0xdd, 0xec, 0x4a, 0xfe, 0xcd, 0x6e, 0x39, 0x0e, 0x1b, 0x0b, 0x9c, 0xf2, 0x06, 0x6a, 0x99, 0x64, - 0x5c, 0x87, 0xe2, 0x88, 0x4e, 0x65, 0xb4, 0x87, 0x0e, 0x2a, 0xc6, 0xed, 0x27, 0x7e, 0x0c, 0xa5, - 0x09, 0xb1, 0x3c, 0x2a, 0x17, 0x82, 0x58, 0x78, 0x78, 0x5d, 0x68, 0xa3, 0xc6, 0xf7, 0x07, 0x50, - 0x8e, 0xba, 0x72, 0xdc, 0x81, 0xd2, 0xd0, 0x22, 0x66, 0x3c, 0xe1, 0x4e, 0x32, 0x61, 0x9c, 0xa2, - 0x9d, 0xdc, 0xde, 0x87, 0x33, 0xd5, 0xa2, 0x99, 0x4a, 0x41, 0xcc, 0x08, 0x4b, 0xf1, 0x19, 0x54, - 0x27, 0x24, 0xd6, 0xc3, 0xe5, 0x42, 0x40, 0xda, 0xcf, 0x21, 0x7d, 0x49, 0xb2, 0x42, 0x1e, 0x8e, - 0x78, 0xb0, 0xb0, 0x83, 0x1b, 0x69, 0x16, 0x36, 0xa0, 0xc2, 0x6c, 0x2e, 0x88, 0xdd, 0xa7, 0x5c, - 0x2e, 0x06, 0xe0, 0x67, 0x39, 0xe0, 0x0f, 0x71, 0x4e, 0x88, 0x7d, 0x18, 0x61, 0x2b, 0x8b, 0xb8, - 0x91, 0x60, 0x14, 0x03, 0x20, 0x91, 0x94, 0xe3, 0x9c, 0x96, 0x76, 0xae, 0xda, 0x92, 0x53, 0xfd, - 0x2c, 0x62, 0x26, 0xef, 0x95, 0xf2, 0x54, 0xe9, 0x42, 0xfd, 0xae, 0xb8, 0x1c, 0xf2, 0xab, 0x2c, - 0x79, 0x67, 0xed, 0x3a, 0xa4, 0xf1, 0xe7, 0xb0, 0x95, 0x95, 0x98, 0x03, 0x6f, 0x65, 0xe1, 0x4f, - 0x13, 0x78, 0x5c, 0x9a, 0xcb, 0x6e, 0xfc, 0x46, 0xb0, 0x95, 0x15, 0x86, 0x3f, 0x2f, 0x6d, 0xee, - 0xf3, 0x55, 0x26, 0xfc, 0xc7, 0xd2, 0x7e, 0xdc, 0xbc, 0xb4, 0xfb, 0x59, 0x0d, 0xb5, 0xa4, 0xeb, - 0x29, 0xb3, 0xd2, 0x43, 0xff, 0x42, 0xb0, 0x7d, 0x47, 0x16, 0xee, 0x02, 0xa4, 0xb6, 0x30, 0x9c, - 0xfb, 0xc5, 0x4a, 0x17, 0x12, 0xcb, 0xd7, 0xec, 0x62, 0x0a, 0xa8, 0xbc, 0x85, 0xed, 0xa3, 0x8d, - 0x2f, 0xbc, 0xfa, 0x57, 0xd7, 0x05, 0xbc, 0xfc, 0x0e, 0xf8, 0xdd, 0x92, 0xd3, 0x4f, 0x56, 0x4e, - 0xbc, 0xce, 0xdc, 0x46, 0x09, 0x8a, 0xa7, 0xcc, 0xea, 0x7c, 0x9d, 0xcd, 0x55, 0xe9, 0x6a, 0xae, - 0x4a, 0xd7, 0x73, 0x55, 0xfa, 0xe6, 0xab, 0x68, 0xe6, 0xab, 0xe8, 0xca, 0x57, 0xd1, 0xb5, 0xaf, - 0xa2, 0x3f, 0xbe, 0x8a, 0x7e, 0xfc, 0x55, 0xa5, 0xf3, 0xf6, 0x7d, 0xff, 0x34, 0xff, 0x05, 0x00, - 0x00, 0xff, 0xff, 0xa9, 0x81, 0xcf, 0x6d, 0x6f, 0x05, 0x00, 0x00, -} - -func (m *AttributeFeatureSet) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AttributeFeatureSet) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AttributeFeatureSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Elements) > 0 { - keysForElements := make([]string, 0, len(m.Elements)) - for k := range m.Elements { - keysForElements = append(keysForElements, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForElements) - for iNdEx := len(keysForElements) - 1; iNdEx >= 0; iNdEx-- { - v := m.Elements[string(keysForElements[iNdEx])] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarintGenerated(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(keysForElements[iNdEx]) - copy(dAtA[i:], keysForElements[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(keysForElements[iNdEx]))) - i-- - dAtA[i] = 0xa - i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *Features) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Features) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Features) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Instances) > 0 { - keysForInstances := make([]string, 0, len(m.Instances)) - for k := range m.Instances { - keysForInstances = append(keysForInstances, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForInstances) - for iNdEx := len(keysForInstances) - 1; iNdEx >= 0; iNdEx-- { - v := m.Instances[string(keysForInstances[iNdEx])] - baseI := i - { - size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(keysForInstances[iNdEx]) - copy(dAtA[i:], keysForInstances[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(keysForInstances[iNdEx]))) - i-- - dAtA[i] = 0xa - i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x1a - } - } - if len(m.Attributes) > 0 { - keysForAttributes := make([]string, 0, len(m.Attributes)) - for k := range m.Attributes { - keysForAttributes = append(keysForAttributes, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForAttributes) - for iNdEx := len(keysForAttributes) - 1; iNdEx >= 0; iNdEx-- { - v := m.Attributes[string(keysForAttributes[iNdEx])] - baseI := i - { - size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(keysForAttributes[iNdEx]) - copy(dAtA[i:], keysForAttributes[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(keysForAttributes[iNdEx]))) - i-- - dAtA[i] = 0xa - i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x12 - } - } - if len(m.Flags) > 0 { - keysForFlags := make([]string, 0, len(m.Flags)) - for k := range m.Flags { - keysForFlags = append(keysForFlags, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForFlags) - for iNdEx := len(keysForFlags) - 1; iNdEx >= 0; iNdEx-- { - v := m.Flags[string(keysForFlags[iNdEx])] - baseI := i - { - size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(keysForFlags[iNdEx]) - copy(dAtA[i:], keysForFlags[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(keysForFlags[iNdEx]))) - i-- - dAtA[i] = 0xa - i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *FlagFeatureSet) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *FlagFeatureSet) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *FlagFeatureSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Elements) > 0 { - keysForElements := make([]string, 0, len(m.Elements)) - for k := range m.Elements { - keysForElements = append(keysForElements, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForElements) - for iNdEx := len(keysForElements) - 1; iNdEx >= 0; iNdEx-- { - v := m.Elements[string(keysForElements[iNdEx])] - baseI := i - { - size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - i -= len(keysForElements[iNdEx]) - copy(dAtA[i:], keysForElements[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(keysForElements[iNdEx]))) - i-- - dAtA[i] = 0xa - i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *InstanceFeature) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *InstanceFeature) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *InstanceFeature) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Attributes) > 0 { - keysForAttributes := make([]string, 0, len(m.Attributes)) - for k := range m.Attributes { - keysForAttributes = append(keysForAttributes, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForAttributes) - for iNdEx := len(keysForAttributes) - 1; iNdEx >= 0; iNdEx-- { - v := m.Attributes[string(keysForAttributes[iNdEx])] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarintGenerated(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(keysForAttributes[iNdEx]) - copy(dAtA[i:], keysForAttributes[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(keysForAttributes[iNdEx]))) - i-- - dAtA[i] = 0xa - i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *InstanceFeatureSet) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *InstanceFeatureSet) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *InstanceFeatureSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Elements) > 0 { - for iNdEx := len(m.Elements) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Elements[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *Nil) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Nil) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Nil) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - -func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { - offset -= sovGenerated(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *AttributeFeatureSet) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Elements) > 0 { - for k, v := range m.Elements { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - return n -} - -func (m *Features) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Flags) > 0 { - for k, v := range m.Flags { - _ = k - _ = v - l = v.Size() - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - if len(m.Attributes) > 0 { - for k, v := range m.Attributes { - _ = k - _ = v - l = v.Size() - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - if len(m.Instances) > 0 { - for k, v := range m.Instances { - _ = k - _ = v - l = v.Size() - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - return n -} - -func (m *FlagFeatureSet) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Elements) > 0 { - for k, v := range m.Elements { - _ = k - _ = v - l = v.Size() - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - return n -} - -func (m *InstanceFeature) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Attributes) > 0 { - for k, v := range m.Attributes { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) - } - } - return n -} - -func (m *InstanceFeatureSet) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Elements) > 0 { - for _, e := range m.Elements { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *Nil) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *AttributeFeatureSet) String() string { - if this == nil { - return "nil" - } - keysForElements := make([]string, 0, len(this.Elements)) - for k := range this.Elements { - keysForElements = append(keysForElements, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForElements) - mapStringForElements := "map[string]string{" - for _, k := range keysForElements { - mapStringForElements += fmt.Sprintf("%v: %v,", k, this.Elements[k]) - } - mapStringForElements += "}" - s := strings.Join([]string{`&AttributeFeatureSet{`, - `Elements:` + mapStringForElements + `,`, - `}`, - }, "") - return s -} -func (this *Features) String() string { - if this == nil { - return "nil" - } - keysForFlags := make([]string, 0, len(this.Flags)) - for k := range this.Flags { - keysForFlags = append(keysForFlags, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForFlags) - mapStringForFlags := "map[string]FlagFeatureSet{" - for _, k := range keysForFlags { - mapStringForFlags += fmt.Sprintf("%v: %v,", k, this.Flags[k]) - } - mapStringForFlags += "}" - keysForAttributes := make([]string, 0, len(this.Attributes)) - for k := range this.Attributes { - keysForAttributes = append(keysForAttributes, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForAttributes) - mapStringForAttributes := "map[string]AttributeFeatureSet{" - for _, k := range keysForAttributes { - mapStringForAttributes += fmt.Sprintf("%v: %v,", k, this.Attributes[k]) - } - mapStringForAttributes += "}" - keysForInstances := make([]string, 0, len(this.Instances)) - for k := range this.Instances { - keysForInstances = append(keysForInstances, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForInstances) - mapStringForInstances := "map[string]InstanceFeatureSet{" - for _, k := range keysForInstances { - mapStringForInstances += fmt.Sprintf("%v: %v,", k, this.Instances[k]) - } - mapStringForInstances += "}" - s := strings.Join([]string{`&Features{`, - `Flags:` + mapStringForFlags + `,`, - `Attributes:` + mapStringForAttributes + `,`, - `Instances:` + mapStringForInstances + `,`, - `}`, - }, "") - return s -} -func (this *FlagFeatureSet) String() string { - if this == nil { - return "nil" - } - keysForElements := make([]string, 0, len(this.Elements)) - for k := range this.Elements { - keysForElements = append(keysForElements, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForElements) - mapStringForElements := "map[string]Nil{" - for _, k := range keysForElements { - mapStringForElements += fmt.Sprintf("%v: %v,", k, this.Elements[k]) - } - mapStringForElements += "}" - s := strings.Join([]string{`&FlagFeatureSet{`, - `Elements:` + mapStringForElements + `,`, - `}`, - }, "") - return s -} -func (this *InstanceFeature) String() string { - if this == nil { - return "nil" - } - keysForAttributes := make([]string, 0, len(this.Attributes)) - for k := range this.Attributes { - keysForAttributes = append(keysForAttributes, k) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForAttributes) - mapStringForAttributes := "map[string]string{" - for _, k := range keysForAttributes { - mapStringForAttributes += fmt.Sprintf("%v: %v,", k, this.Attributes[k]) - } - mapStringForAttributes += "}" - s := strings.Join([]string{`&InstanceFeature{`, - `Attributes:` + mapStringForAttributes + `,`, - `}`, - }, "") - return s -} -func (this *InstanceFeatureSet) String() string { - if this == nil { - return "nil" - } - repeatedStringForElements := "[]InstanceFeature{" - for _, f := range this.Elements { - repeatedStringForElements += strings.Replace(strings.Replace(f.String(), "InstanceFeature", "InstanceFeature", 1), `&`, ``, 1) + "," - } - repeatedStringForElements += "}" - s := strings.Join([]string{`&InstanceFeatureSet{`, - `Elements:` + repeatedStringForElements + `,`, - `}`, - }, "") - return s -} -func (this *Nil) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&Nil{`, - `}`, - }, "") - return s -} -func valueToStringGenerated(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *AttributeFeatureSet) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AttributeFeatureSet: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AttributeFeatureSet: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Elements", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Elements == nil { - m.Elements = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Elements[mapkey] = mapvalue - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Features) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Features: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Features: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Flags", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Flags == nil { - m.Flags = make(map[string]FlagFeatureSet) - } - var mapkey string - mapvalue := &FlagFeatureSet{} - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthGenerated - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthGenerated - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &FlagFeatureSet{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Flags[mapkey] = *mapvalue - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Attributes == nil { - m.Attributes = make(map[string]AttributeFeatureSet) - } - var mapkey string - mapvalue := &AttributeFeatureSet{} - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthGenerated - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthGenerated - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &AttributeFeatureSet{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Attributes[mapkey] = *mapvalue - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Instances", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Instances == nil { - m.Instances = make(map[string]InstanceFeatureSet) - } - var mapkey string - mapvalue := &InstanceFeatureSet{} - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthGenerated - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthGenerated - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &InstanceFeatureSet{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Instances[mapkey] = *mapvalue - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *FlagFeatureSet) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: FlagFeatureSet: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: FlagFeatureSet: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Elements", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Elements == nil { - m.Elements = make(map[string]Nil) - } - var mapkey string - mapvalue := &Nil{} - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthGenerated - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthGenerated - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &Nil{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Elements[mapkey] = *mapvalue - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *InstanceFeature) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: InstanceFeature: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: InstanceFeature: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Attributes == nil { - m.Attributes = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Attributes[mapkey] = mapvalue - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *InstanceFeatureSet) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: InstanceFeatureSet: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: InstanceFeatureSet: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Elements", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Elements = append(m.Elements, InstanceFeature{}) - if err := m.Elements[len(m.Elements)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Nil) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Nil: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Nil: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenerated(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthGenerated - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupGenerated - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthGenerated - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") -) diff --git a/api/nfd/v1alpha1/generated.proto b/api/nfd/v1alpha1/generated.proto deleted file mode 100644 index dab35a16a..000000000 --- a/api/nfd/v1alpha1/generated.proto +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -// This file was autogenerated by go-to-protobuf. Do not edit it manually! - -syntax = "proto2"; - -package v1alpha1; - -// Package-wide variables from generator "generated". -option go_package = "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"; - -// AttributeFeatureSet is a set of features having string value. -// -// +protobuf=true -message AttributeFeatureSet { - map elements = 1; -} - -// Features is the collection of all discovered features. -// -// +protobuf=true -message Features { - // Flags contains all the flag-type features of the node. - // +optional - map flags = 1; - - // Attributes contains all the attribute-type features of the node. - // +optional - map vattributes = 2; - - // Instances contains all the instance-type features of the node. - // +optional - map instances = 3; -} - -// FlagFeatureSet is a set of simple features only containing names without values. -// -// +protobuf=true -message FlagFeatureSet { - map elements = 1; -} - -// InstanceFeature represents one instance of a complex features, e.g. a device. -// -// +protobuf=true -message InstanceFeature { - map attributes = 1; -} - -// InstanceFeatureSet is a set of features each of which is an instance having multiple attributes. -// -// +protobuf=true -message InstanceFeatureSet { - repeated InstanceFeature elements = 1; -} - -// Nil is a dummy empty struct for protobuf compatibility -// -// +protobuf=true -message Nil { -} - diff --git a/api/nfd/v1alpha1/types.go b/api/nfd/v1alpha1/types.go index c89efd818..67dfc1b06 100644 --- a/api/nfd/v1alpha1/types.go +++ b/api/nfd/v1alpha1/types.go @@ -56,55 +56,44 @@ type NodeFeatureSpec struct { } // Features is the collection of all discovered features. -// -// +protobuf=true type Features struct { // Flags contains all the flag-type features of the node. // +optional - Flags map[string]FlagFeatureSet `json:"flags" protobuf:"bytes,1,rep,name=flags"` + Flags map[string]FlagFeatureSet `json:"flags"` // Attributes contains all the attribute-type features of the node. // +optional - Attributes map[string]AttributeFeatureSet `json:"attributes" protobuf:"bytes,2,rep,name=vattributes"` + Attributes map[string]AttributeFeatureSet `json:"attributes"` // Instances contains all the instance-type features of the node. // +optional - Instances map[string]InstanceFeatureSet `json:"instances" protobuf:"bytes,3,rep,name=instances"` + Instances map[string]InstanceFeatureSet `json:"instances"` } // FlagFeatureSet is a set of simple features only containing names without values. -// -// +protobuf=true type FlagFeatureSet struct { // Individual features of the feature set. - Elements map[string]Nil `json:"elements" protobuf:"bytes,1,rep,name=elements"` + Elements map[string]Nil `json:"elements"` } // AttributeFeatureSet is a set of features having string value. -// -// +protobuf=true type AttributeFeatureSet struct { // Individual features of the feature set. - Elements map[string]string `json:"elements" protobuf:"bytes,1,rep,name=elements"` + Elements map[string]string `json:"elements"` } // InstanceFeatureSet is a set of features each of which is an instance having multiple attributes. -// -// +protobuf=true type InstanceFeatureSet struct { // Individual features of the feature set. - Elements []InstanceFeature `json:"elements" protobuf:"bytes,1,rep,name=elements"` + Elements []InstanceFeature `json:"elements"` } // InstanceFeature represents one instance of a complex features, e.g. a device. -// -// +protobuf=true type InstanceFeature struct { // Attributes of the instance feature. - Attributes map[string]string `json:"attributes" protobuf:"bytes,1,rep,name=attributes"` + Attributes map[string]string `json:"attributes"` } -// Nil is a dummy empty struct for protobuf compatibility -// -// +protobuf=true +// Nil is a dummy empty struct for protobuf compatibility. +// NOTE: protobuf definitions have been removed but this is kept for API compatibility. type Nil struct{} // NodeFeatureRuleList contains a list of NodeFeatureRule objects. diff --git a/api/nfd/v1alpha1/utils.go b/api/nfd/v1alpha1/utils.go new file mode 100644 index 000000000..49c34a426 --- /dev/null +++ b/api/nfd/v1alpha1/utils.go @@ -0,0 +1,29 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "fmt" +) + +// String represents the match expression as a string type. +func (m MatchExpression) String() string { + if len(m.Value) < 1 { + return fmt.Sprintf("{op: %q}", m.Op) + } + return fmt.Sprintf("{op: %q, value: %q}", m.Op, m.Value) +} diff --git a/cmd/nfd/main.go b/cmd/nfd/main.go new file mode 100644 index 000000000..f8d2517e5 --- /dev/null +++ b/cmd/nfd/main.go @@ -0,0 +1,27 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "sigs.k8s.io/node-feature-discovery/cmd/nfd/subcmd" +) + +const ProgramName = "nfd" + +func main() { + subcmd.Execute() +} diff --git a/cmd/nfd/subcmd/compat/compat.go b/cmd/nfd/subcmd/compat/compat.go new file mode 100644 index 000000000..cf46575dd --- /dev/null +++ b/cmd/nfd/subcmd/compat/compat.go @@ -0,0 +1,36 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package compat + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" +) + +var CompatCmd = &cobra.Command{ + Use: "compat", + Short: "Image compatibility commands", +} + +func Execute() { + if err := CompatCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/cmd/nfd/subcmd/compat/options/platform.go b/cmd/nfd/subcmd/compat/options/platform.go new file mode 100644 index 000000000..9a8f4a5ae --- /dev/null +++ b/cmd/nfd/subcmd/compat/options/platform.go @@ -0,0 +1,70 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package options + +import ( + "fmt" + "runtime" + "strings" + + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/spf13/cobra" +) + +// PlatformOption represents +type PlatformOption struct { + // PlatformStr contains the raw platform argument provided by the user. + PlatformStr string + // Platform represents the OCI platform specification, built from PlatformStr. + Platform *ocispec.Platform +} + +// Parse takes the PlatformStr argument provided by the user +// to build OCI platform specification. +func (opt *PlatformOption) Parse(*cobra.Command) error { + var pStr string + + if opt.PlatformStr == "" { + return nil + } + + platform := &ocispec.Platform{} + pStr, platform.OSVersion, _ = strings.Cut(opt.PlatformStr, ":") + parts := strings.Split(pStr, "/") + + switch len(parts) { + case 3: + platform.Variant = parts[2] + fallthrough + case 2: + platform.Architecture = parts[1] + case 1: + platform.Architecture = runtime.GOARCH + default: + return fmt.Errorf("failed to parse platform %q: expected format os[/arch[/variant]]", opt.PlatformStr) + } + + platform.OS = parts[0] + if platform.OS == "" { + return fmt.Errorf("invalid platform: OS cannot be empty") + } + if platform.Architecture == "" { + return fmt.Errorf("invalid platform: Architecture cannot be empty") + } + opt.Platform = platform + return nil +} diff --git a/cmd/nfd/subcmd/compat/validate-node.go b/cmd/nfd/subcmd/compat/validate-node.go new file mode 100644 index 000000000..a1a3abc30 --- /dev/null +++ b/cmd/nfd/subcmd/compat/validate-node.go @@ -0,0 +1,224 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package compat + +import ( + "context" + "encoding/json" + "fmt" + "io" + "os" + "strings" + "time" + + "github.com/jedib0t/go-pretty/v6/table" + "github.com/jedib0t/go-pretty/v6/text" + "github.com/spf13/cobra" + "oras.land/oras-go/v2/registry" + + "sigs.k8s.io/node-feature-discovery/cmd/nfd/subcmd/compat/options" + artifactcli "sigs.k8s.io/node-feature-discovery/pkg/client-nfd/compat/artifact-client" + nodevalidator "sigs.k8s.io/node-feature-discovery/pkg/client-nfd/compat/node-validator" + "sigs.k8s.io/node-feature-discovery/source" +) + +var ( + image string + tags []string + platform options.PlatformOption + plainHTTP bool + outputJSON bool + + // secrets + readPassword bool + readAccessToken bool + username string + password string + accessToken string +) + +var validateNodeCmd = &cobra.Command{ + Use: "validate-node", + Short: "Perform node validation based on its associated image compatibility artifact", + PreRunE: func(cmd *cobra.Command, args []string) error { + var err error + + if err = platform.Parse(cmd); err != nil { + return err + } + + if readAccessToken && readPassword { + return fmt.Errorf("cannot use --registry-token-stdin and --registry-password-stdin at the same time") + } else if readAccessToken { + accessToken, err = readStdin() + if err != nil { + return err + } + } else if readPassword { + password, err = readStdin() + if err != nil { + return err + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + ref, err := registry.ParseReference(image) + if err != nil { + return err + } + + sources := map[string]source.FeatureSource{} + for k, v := range source.GetAllFeatureSources() { + if ts, ok := v.(source.SupplementalSource); ok && ts.DisableByDefault() { + continue + } + sources[k] = v + } + + authOpt := artifactcli.WithAuthDefault() + if username != "" && password != "" { + authOpt = artifactcli.WithAuthPassword(username, password) + } else if accessToken != "" { + authOpt = artifactcli.WithAuthToken(accessToken) + } + + ac := artifactcli.New( + &ref, + artifactcli.WithArgs(artifactcli.Args{PlainHttp: plainHTTP}), + artifactcli.WithPlatform(platform.Platform), + authOpt, + ) + + nv := nodevalidator.New( + nodevalidator.WithArgs(&nodevalidator.Args{Tags: tags}), + nodevalidator.WithArtifactClient(ac), + nodevalidator.WithSources(sources), + ) + + out, err := nv.Execute(ctx) + if err != nil { + return err + } + if outputJSON { + b, err := json.Marshal(out) + if err != nil { + return err + } + fmt.Printf("%s", b) + } else { + pprintResult(out) + } + + return nil + }, +} + +func readStdin() (string, error) { + secretRaw, err := io.ReadAll(os.Stdin) + if err != nil { + return "", err + } + secret := strings.TrimSuffix(string(secretRaw), "\n") + secret = strings.TrimSuffix(secret, "\r") + + return secret, nil +} + +func pprintResult(css []*nodevalidator.CompatibilityStatus) { + for i, cs := range css { + fmt.Print(text.Colors{text.FgCyan, text.Bold}.Sprintf("COMPATIBILITY SET #%d ", i+1)) + fmt.Print(text.FgCyan.Sprintf("Weight: %d", cs.Weight)) + if cs.Tag != "" { + fmt.Print(text.FgCyan.Sprintf("; Tag: %s", cs.Tag)) + } + fmt.Println() + fmt.Println(text.FgWhite.Sprintf("Description: %s", cs.Description)) + + for _, r := range cs.Rules { + printTable(r) + } + fmt.Println() + } +} + +func printTable(rs nodevalidator.ProcessedRuleStatus) { + t := table.NewWriter() + t.SetStyle(table.StyleLight) + t.SetOutputMirror(os.Stdout) + t.Style().Format.Header = text.FormatDefault + t.SetAutoIndex(true) + + validTxt := text.BgRed.Sprint(" FAIL ") + if rs.IsMatch { + validTxt = text.BgGreen.Sprint(" OK ") + } + ruleTxt := strings.ToUpper(fmt.Sprintf("rule: %s", rs.Name)) + + t.SetTitle(text.Bold.Sprintf("%s - %s", ruleTxt, validTxt)) + t.AppendHeader(table.Row{"Feature", "Expression", "Matcher Type", "Status"}) + + if mf := rs.MatchedExpressions; len(mf) > 0 { + renderMatchFeatures(t, mf) + } + if ma := rs.MatchedAny; len(ma) > 0 { + for _, elem := range ma { + t.AppendSeparator() + renderMatchFeatures(t, elem.MatchedExpressions) + } + } + t.Render() +} + +func renderMatchFeatures(t table.Writer, matchedExpressions []nodevalidator.MatchedExpression) { + for _, fm := range matchedExpressions { + fullFeatureDomain := fm.Feature + if fm.Name != "" { + fullFeatureDomain = fmt.Sprintf("%s.%s", fm.Feature, fm.Name) + } + + addTableRows(t, fullFeatureDomain, fm.Expression.String(), fm.MatcherType, fm.IsMatch) + } +} + +func addTableRows(t table.Writer, fullFeatureDomain, expression string, matcherType nodevalidator.MatcherType, isMatch bool) { + status := text.FgHiRed.Sprint("FAIL") + if isMatch { + status = text.FgHiGreen.Sprint("OK") + } + t.AppendRow(table.Row{fullFeatureDomain, expression, matcherType, status}) +} + +func init() { + CompatCmd.AddCommand(validateNodeCmd) + validateNodeCmd.Flags().StringVar(&image, "image", "", "the URL of the image containing compatibility metadata") + validateNodeCmd.Flags().StringSliceVar(&tags, "tags", []string{}, "a list of tags that must match the tags set on the compatibility objects") + validateNodeCmd.Flags().StringVar(&platform.PlatformStr, "platform", "", "the artifact platform in the format os[/arch][/variant][:os_version]") + validateNodeCmd.Flags().BoolVar(&plainHTTP, "plain-http", false, "use of HTTP protocol for all registry communications") + validateNodeCmd.Flags().BoolVar(&outputJSON, "output-json", false, "print a JSON object") + validateNodeCmd.Flags().StringVar(&username, "registry-username", "", "registry username") + validateNodeCmd.Flags().BoolVar(&readPassword, "registry-password-stdin", false, "read registry password from stdin") + validateNodeCmd.Flags().BoolVar(&readAccessToken, "registry-token-stdin", false, "read registry access token from stdin") + + if err := validateNodeCmd.MarkFlagRequired("image"); err != nil { + panic(err) + } +} diff --git a/cmd/nfd/subcmd/root.go b/cmd/nfd/subcmd/root.go new file mode 100644 index 000000000..d58f6b982 --- /dev/null +++ b/cmd/nfd/subcmd/root.go @@ -0,0 +1,45 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package subcmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + + "sigs.k8s.io/node-feature-discovery/cmd/nfd/subcmd/compat" +) + +// RootCmd represents the base command when called without any subcommands +var RootCmd = &cobra.Command{ + Use: "nfd", + Short: "Node Feature Discovery client", +} + +func init() { + RootCmd.AddCommand(compat.CompatCmd) +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := RootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/deployment/base/nfd-crds/nfd-api-crds.yaml b/deployment/base/nfd-crds/nfd-api-crds.yaml index 56142c6ce..9f62da6f6 100644 --- a/deployment/base/nfd-crds/nfd-api-crds.yaml +++ b/deployment/base/nfd-crds/nfd-api-crds.yaml @@ -69,8 +69,9 @@ spec: properties: elements: additionalProperties: - description: Nil is a dummy empty struct for protobuf - compatibility + description: |- + Nil is a dummy empty struct for protobuf compatibility. + NOTE: protobuf definitions have been removed but this is kept for API compatibility. type: object description: Individual features of the feature set. type: object diff --git a/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml b/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml index 56142c6ce..9f62da6f6 100644 --- a/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml +++ b/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml @@ -69,8 +69,9 @@ spec: properties: elements: additionalProperties: - description: Nil is a dummy empty struct for protobuf - compatibility + description: |- + Nil is a dummy empty struct for protobuf compatibility. + NOTE: protobuf definitions have been removed but this is kept for API compatibility. type: object description: Individual features of the feature set. type: object diff --git a/docs/reference/feature-gates.md b/docs/reference/feature-gates.md index 315e91c16..a66643c62 100644 --- a/docs/reference/feature-gates.md +++ b/docs/reference/feature-gates.md @@ -1,7 +1,7 @@ --- title: "Feature Gates" layout: default -sort: 10 +sort: 11 --- # Feature Gates diff --git a/docs/reference/node-feature-client-reference.md b/docs/reference/node-feature-client-reference.md new file mode 100644 index 000000000..9a723a783 --- /dev/null +++ b/docs/reference/node-feature-client-reference.md @@ -0,0 +1,65 @@ +--- +title: "Node Feature client cmdline reference" +layout: default +sort: 9 +--- + +# Commandline flags of nfd client +{: .no_toc} + +## Table of contents +{: .no_toc .text-delta} + +1. TOC +{:toc} + +--- +**The client is in the experimental `v1alpha1` version.** + +To quickly view available command line flags execute `nfd --help`. + +### -h, --help + +Print usage and exit. + +## compat + +Image Compatibility commands. + +### validate-node + +Perform node validation based on its associated image compatibility artifact. + +#### --image + +The `--image` flag specifies the URL of the image containing compatibility metadata. + +#### --plain-http + +The `--plain-http` flag forces the use of HTTP protocol for all registry communications. +Default: `false` + +#### --platform + +The `--platform` flag specifies the artifact platform in the format `os[/arch][/variant][:os_version]`. + +#### --tags + +The `--tags` flag specifies a list of tags that must match the tags +set on the compatibility objects. + +#### --output-json + +The `--output-json` flag prints the output as a JSON object. + +#### --registry-username + +The `--registry-username` flag specifies the username for the registry. + +#### --registry-password-stdin + +The `--registry-password-stdin` flag enables reading of registry password from stdin. + +#### --registry-token-stdin + +The `--registry-token-stdin` flag enables reading of registry token from stdin. diff --git a/docs/reference/versions.md b/docs/reference/versions.md index 8754eaf39..b192250d6 100644 --- a/docs/reference/versions.md +++ b/docs/reference/versions.md @@ -1,7 +1,7 @@ --- title: "Versions" layout: default -sort: 9 +sort: 10 --- # Versions and deprecation diff --git a/docs/usage/image-compatibility.md b/docs/usage/image-compatibility.md new file mode 100644 index 000000000..6c5f38538 --- /dev/null +++ b/docs/usage/image-compatibility.md @@ -0,0 +1,226 @@ +--- +title: "Image Compatibility Artifact" +layout: default +sort: 11 +--- + +# Image Compatibility Artifact +{: .no_toc} + +## Table of contents +{: .no_toc .text-delta} + +1. TOC +{:toc} + +--- + +## Image Compatibility + +**Image Compatibility is in the experimental `v1alpha1` version.** + +Image compatibility metadata enables container image authors to define their +image requirements using [Node Feature Rules](./custom-resources.md#nodefeaturerule). +This complementary solution allows features discovered on nodes to be matched +directly from images. As a result, container requirements become discoverable +and programmable, supporting various consumers and use cases where applications +need a specific compatible environment. + +### Compatibility Specification + +The compatibility specification is a list of compatibility objects that contain +[Node Feature Rules](./custom-resources.md#nodefeaturerule), along with +additional fields to control the execution of validation between the image and +the host. + +### Schema + +- **version** - *string* + This REQUIRED property specifies the version of the API in use. + +- **compatibilities** - *array of object* + This REQUIRED property is a list of compatibility sets. + + - **rules** - *object* + This REQUIRED property is a reference to the spec of the [NodeFeatureRule API](./custom-resources.md#nodefeaturerule). + The spec allows image requirements to be described using the features + discovered from NFD sources. For more details, please refer to [the documentation](./custom-resources.md#nodefeaturerule). + + - **weight** - *int* + This OPTIONAL property specifies the [node affinity weight](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity-weight). + + - **tag** - *string* + This OPTIONAL property allows for the grouping or separation of + compatibility sets. + + - **description** - *string* + This OPTIONAL property provides a brief description of a compatibility set. + +#### Example + +```yaml +version: v1alpha1 +compatibilities: +- description: "My image requirements" + rules: + - name: "kernel and cpu" + matchFeatures: + - feature: kernel.loadedmodule + matchExpressions: + vfio-pci: {op: Exists} + - feature: cpu.model + matchExpressions: + vendor_id: {op: In, value: ["Intel", "AMD"]} + - name: "one of available nics" + matchAny: + - matchFeatures: + - feature: pci.device + matchExpressions: + vendor: {op: In, value: ["0eee"]} + class: {op: In, value: ["0200"]} + - matchFeatures: + - feature: pci.device + matchExpressions: + vendor: {op: In, value: ["0fff"]} + class: {op: In, value: ["0200"]} +``` + +### OCI Artifact + +An [OCI artifact](https://github.com/opencontainers/image-spec/blob/main/manifest.md#guidelines-for-artifact-usage) +is used to store image compatibility metadata. +The artifact can be associated with a specific image through [the subject field](https://github.com/opencontainers/distribution-spec/blob/11b8e3fba7d2d7329513d0cff53058243c334858/spec.md#pushing-manifests-with-subject) +and pushed to the registry along with the image. + +Example manifest: + +```json +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "artifactType": "application/vnd.nfd.image-compatibility.v1alpha1", + "config": { + "mediaType": "application/vnd.oci.empty.v1+json", + "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "size": 2 + }, + "layers": [ + { + "mediaType": "application/vnd.nfd.image-compatibility.spec.v1alpha1+yaml", + "digest": "sha256:4a47f8ae4c713906618413cb9795824d09eeadf948729e213a1ba11a1e31d052", + "size": 1710 + } + ], + "subject": { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270", + "size": 7682 + }, + "annotations": { + "oci.opencontainers.image.created": "2024-03-27T08:08:08Z" + } +} +``` + +#### Attach the artifact to the image + +Create an image compatibility specification for the image, then install the +[ORAS](https://github.com/oras-project/oras/) tool and execute `oras attach` +command. + +Example: + +```sh +oras attach --artifact-type application/vnd.nfd.image-compatibility.v1alpha1 \ + .yaml:application/vnd.nfd.image-compatibility.spec.v1alpha1+yaml +``` + +**Note**: The attach command is planned to be integrated into the `nfd` client +tool. This will streamline the process, allowing you to perform the operation +directly within the tool rather than using a separate command. + +### Validate the host against the image compatibility specification + +1. Build `nfd` client: `make build` +1. Run `./bin/nfd compat validate-node --image ` + +For more information about the available commands and flags, refer to +[the client documentation](../reference/node-feature-client-reference.md). + +### Validate the k8s cluster node with the validate-image Job + +**Note**: This does not require installation of NFD master and workers. +Additionally, public registry certificates must be included in the job. +In the example below, this is done using hostPath, +but it can be done using any Kubernetes-supported method. + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: validate-image +spec: + backoffLimit: 1 + template: + spec: + restartPolicy: Never + containers: + - name: image-compatibility + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + image: + command: ["nfd", "compat", "validate-node", "--image", ""] + volumeMounts: + - mountPath: /host-boot + name: host-boot + readOnly: true + - mountPath: /host-etc/os-release + name: host-os-release + readOnly: true + - mountPath: /host-sys + name: host-sys + readOnly: true + - mountPath: /host-usr/lib + name: host-usr-lib + readOnly: true + - mountPath: /host-lib + name: host-lib + readOnly: true + - mountPath: /host-proc + name: host-proc + readOnly: true + volumes: + - hostPath: + path: /boot + type: "" + name: host-boot + - hostPath: + path: /etc/os-release + type: "" + name: host-os-release + - hostPath: + path: /sys + type: "" + name: host-sys + - hostPath: + path: /usr/lib + type: "" + name: host-usr-lib + - hostPath: + path: /lib + type: "" + name: host-lib + - hostPath: + path: /proc + type: "" + name: host-proc + - hostPath: + path: "" + type: "" + name: certs +``` diff --git a/examples/image-compatibility.yaml b/examples/image-compatibility.yaml new file mode 100644 index 000000000..38cdc34b8 --- /dev/null +++ b/examples/image-compatibility.yaml @@ -0,0 +1,27 @@ +version: v1alpha1 +compatibilities: +- description: "my image requirements" + rules: + - name: "kernel and cpu" + matchFeatures: + - feature: kernel.loadedmodule + matchExpressions: + vfio-pci: {op: Exists} + ip_tables: {op: Exists} + - feature: cpu.model + matchExpressions: + vendor_id: {op: In, value: ["Intel", "AMD"]} + - feature: cpu.cpuid + matchName: {op: InRegexp, value: ["^AVX"]} + - name: "one of available nics" + matchAny: + - matchFeatures: + - feature: pci.device + matchExpressions: + vendor: {op: In, value: ["0eee"]} + class: {op: In, value: ["0200"]} + - matchFeatures: + - feature: pci.device + matchExpressions: + vendor: {op: In, value: ["0fff"]} + class: {op: In, value: ["0200"]} diff --git a/go.mod b/go.mod index 7ee89b549..de94b3265 100644 --- a/go.mod +++ b/go.mod @@ -7,12 +7,14 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/jaypipes/ghw v0.13.0 + github.com/jedib0t/go-pretty/v6 v6.6.1 github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.1.2 github.com/k8stopologyawareschedwg/podfingerprint v0.2.2 github.com/klauspost/cpuid/v2 v2.2.9 github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 - github.com/opencontainers/runc v1.2.2 + github.com/opencontainers/image-spec v1.1.0 + github.com/opencontainers/runc v1.2.3 github.com/prometheus/client_golang v1.19.1 github.com/smartystreets/goconvey v1.8.1 github.com/spf13/cobra v1.8.1 @@ -22,24 +24,27 @@ require ( golang.org/x/net v0.32.0 golang.org/x/time v0.8.0 google.golang.org/grpc v1.69.0 - k8s.io/api v0.31.3 - k8s.io/apiextensions-apiserver v0.31.3 - k8s.io/apimachinery v0.31.3 - k8s.io/client-go v0.31.3 - k8s.io/code-generator v0.31.3 - k8s.io/component-base v0.31.3 + k8s.io/api v0.32.0 + k8s.io/apiextensions-apiserver v0.32.0 + k8s.io/apimachinery v0.32.0 + k8s.io/client-go v0.32.0 + k8s.io/code-generator v0.32.0 + k8s.io/component-base v0.32.0 k8s.io/klog/v2 v2.130.1 - k8s.io/kubectl v0.31.3 - k8s.io/kubelet v0.31.3 - k8s.io/kubernetes v1.31.3 - k8s.io/pod-security-admission v0.31.3 - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 + k8s.io/kubectl v0.32.0 + k8s.io/kubelet v0.32.0 + k8s.io/kubernetes v1.32.0 + k8s.io/pod-security-admission v0.32.0 + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 + oras.land/oras-go/v2 v2.5.0 sigs.k8s.io/node-feature-discovery/api/nfd v0.0.0-00010101000000-000000000000 sigs.k8s.io/yaml v1.4.0 ) require ( - github.com/Microsoft/go-winio v0.6.0 // indirect + cel.dev/expr v0.18.0 // indirect + github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/StackExchange/wmi v1.2.1 // indirect @@ -49,26 +54,33 @@ require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/containerd/containerd/api v1.7.19 // indirect + github.com/containerd/errdefs v0.1.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/ttrpc v1.2.5 // 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.3.4 // indirect + github.com/cyphar/filepath-securejoin v0.3.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/distribution/reference v0.5.0 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/euank/go-kmsg-parser v2.0.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/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/swag v0.23.0 // 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/golang/protobuf v1.5.4 // indirect - github.com/google/cel-go v0.20.1 // indirect + github.com/google/btree v1.0.1 // indirect + github.com/google/cadvisor v0.51.0 // indirect + github.com/google/cel-go v0.22.0 // 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-20241029153458-d1b30febd7db // indirect @@ -76,16 +88,18 @@ require ( 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.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 github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect + github.com/karrick/godirwalk v1.17.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/moby/spdystream v0.4.0 // indirect - github.com/moby/sys/mountinfo v0.7.1 // indirect + github.com/moby/spdystream v0.5.0 // indirect + github.com/moby/sys/mountinfo v0.7.2 // 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 @@ -93,20 +107,22 @@ require ( 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.2.0 // indirect + github.com/opencontainers/selinux v1.11.1 // indirect github.com/pkg/errors v0.9.1 // 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/rivo/uniseg v0.2.0 // 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/stoewer/go-strcase v1.3.0 // indirect github.com/stretchr/objx v0.5.2 // 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.etcd.io/etcd/api/v3 v3.5.16 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect + go.etcd.io/etcd/client/v3 v3.5.16 // 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.31.0 // indirect @@ -117,7 +133,7 @@ require ( go.opentelemetry.io/otel/trace v1.31.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 + go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.31.0 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect @@ -133,55 +149,55 @@ require ( 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.31.3 // indirect - k8s.io/cloud-provider v0.31.3 // indirect - k8s.io/component-helpers v0.31.3 // indirect - k8s.io/controller-manager v0.31.3 // indirect - k8s.io/cri-api v0.31.3 // indirect + k8s.io/apiserver v0.32.0 // indirect + k8s.io/cloud-provider v0.32.0 // indirect + k8s.io/component-helpers v0.32.0 // indirect + k8s.io/controller-manager v0.32.0 // indirect + k8s.io/cri-api v0.32.0 // indirect k8s.io/cri-client v0.0.0 // indirect - k8s.io/csi-translation-lib v0.31.3 // indirect - k8s.io/dynamic-resource-allocation v0.31.3 // indirect - k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect - k8s.io/kms v0.31.3 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/mount-utils v0.31.3 // 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 + k8s.io/csi-translation-lib v0.32.0 // indirect + k8s.io/dynamic-resource-allocation v0.32.0 // indirect + k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 // indirect + k8s.io/kms v0.32.0 // indirect + k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + k8s.io/kube-scheduler v0.0.0 // indirect + k8s.io/mount-utils v0.32.0 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect ) // The k8s "sub-"packages do not have 'semver' compatible versions. Thus, we // 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.31.3 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.31.3 - k8s.io/apimachinery => k8s.io/apimachinery v0.31.3 - k8s.io/apiserver => k8s.io/apiserver v0.31.3 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.31.3 - k8s.io/client-go => k8s.io/client-go v0.31.3 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.31.3 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.31.3 - k8s.io/code-generator => k8s.io/code-generator v0.31.3 - k8s.io/component-base => k8s.io/component-base v0.31.3 - k8s.io/component-helpers => k8s.io/component-helpers v0.31.3 - k8s.io/controller-manager => k8s.io/controller-manager v0.31.3 - k8s.io/cri-api => k8s.io/cri-api v0.31.3 - k8s.io/cri-client => k8s.io/cri-client v0.31.3 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.31.3 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.31.3 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.31.3 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.31.3 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.31.3 - k8s.io/kubectl => k8s.io/kubectl v0.31.3 - k8s.io/kubelet => k8s.io/kubelet v0.31.3 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.31.3 - k8s.io/metrics => k8s.io/metrics v0.31.3 - k8s.io/mount-utils => k8s.io/mount-utils v0.31.3 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.31.3 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.31.3 + k8s.io/api => k8s.io/api v0.32.0 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.32.0 + k8s.io/apimachinery => k8s.io/apimachinery v0.32.0 + k8s.io/apiserver => k8s.io/apiserver v0.32.0 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.32.0 + k8s.io/client-go => k8s.io/client-go v0.32.0 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.32.0 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.32.0 + k8s.io/code-generator => k8s.io/code-generator v0.32.0 + k8s.io/component-base => k8s.io/component-base v0.32.0 + k8s.io/component-helpers => k8s.io/component-helpers v0.32.0 + k8s.io/controller-manager => k8s.io/controller-manager v0.32.0 + k8s.io/cri-api => k8s.io/cri-api v0.32.0 + k8s.io/cri-client => k8s.io/cri-client v0.32.0 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.32.0 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.32.0 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.32.0 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.32.0 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.32.0 + k8s.io/kubectl => k8s.io/kubectl v0.32.0 + k8s.io/kubelet => k8s.io/kubelet v0.32.0 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.32.0 + k8s.io/metrics => k8s.io/metrics v0.32.0 + k8s.io/mount-utils => k8s.io/mount-utils v0.32.0 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.32.0 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.32.0 sigs.k8s.io/node-feature-discovery/api/nfd => ./api/nfd ) diff --git a/go.sum b/go.sum index 897e9002f..b928c12ab 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,9 @@ +cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= +cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= 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= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= @@ -22,26 +24,34 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3 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/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA= +github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oLU= +github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= +github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= +github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= 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.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8= -github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM= +github.com/cyphar/filepath-securejoin v0.3.5 h1:L81NHjquoQmcPgXcttUS9qTSR/+bXry6pbSINQGpjj4= +github.com/cyphar/filepath-securejoin v0.3.5/go.mod h1:edhVd3c6OXKjUmSrVa/tGJRS9joFTxlslFCAyaxigkE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v26.1.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU= +github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -66,13 +76,14 @@ github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= 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/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-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= 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= @@ -82,16 +93,14 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= 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/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.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= -github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= +github.com/google/cadvisor v0.51.0 h1:BspqSPdZoLKrnvuZNOvM/KiJ/A+RdixwagN20n+2H8k= +github.com/google/cadvisor v0.51.0/go.mod h1:czGE/c/P/i0QFpVNKTFrIEzord9Y10YfpwuaSWXELc0= +github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g= +github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= 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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -116,17 +125,17 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 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= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jaypipes/ghw v0.13.0 h1:log8MXuB8hzTNnSktqpXMHc0c/2k/WgjOMSUtnI1RV4= github.com/jaypipes/ghw v0.13.0/go.mod h1:In8SsaDqlb1oTyrbmTC14uy+fbBMvp+xdqX51MidlD8= github.com/jaypipes/pcidb v1.0.1 h1:WB2zh27T3nwg8AE8ei81sNRb9yWBii3JGNJtT7K9Oic= github.com/jaypipes/pcidb v1.0.1/go.mod h1:6xYUz/yYEyOkIkUt2t2J2folIuZ4Yg6uByCGFXMCeE4= +github.com/jedib0t/go-pretty/v6 v6.6.1 h1:iJ65Xjb680rHcikRj6DSIbzCex2huitmc7bDtxYVWyc= +github.com/jedib0t/go-pretty/v6 v6.6.1/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -152,16 +161,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/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 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.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/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= +github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= 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= @@ -169,8 +180,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm/Q= -github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= 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= @@ -181,12 +190,14 @@ github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= github.com/onsi/gomega v1.36.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.2.2 h1:jTg3Vw2A5f0N9PoxFTEwUhvpANGaNPT3689Yfd/zaX0= -github.com/opencontainers/runc v1.2.2/go.mod h1:/PXzF0h531HTMsYQnmxXkBD7YaGShm/2zcRB79dksUc= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opencontainers/runc v1.2.3 h1:fxE7amCzfZflJO2lHXf4y/y8M1BoAqp+FVmG19oYB80= +github.com/opencontainers/runc v1.2.3/go.mod h1:nSxcWUydXrsBZVYNSkTjoQ/N6rcyTtn+1SD5D4+kRIM= 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/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8= +github.com/opencontainers/selinux v1.11.1/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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -200,11 +211,11 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G 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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 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.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= @@ -217,53 +228,46 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a h1:lUVfiMMY/te9icPKBqOKkBIMZNxSpM90dxokDeCcfBg= github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a/go.mod h1:KUxJS71XlMs+ztT+RzsLRoWUQRUpECo/+Rb0EBk8/Wc= -github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= -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/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk= +github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/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= -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.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= +go.etcd.io/etcd/api/v3 v3.5.16 h1:WvmyJVbjWqK4R1E+B12RRHz3bRGy9XVfh++MgbN+6n0= +go.etcd.io/etcd/api/v3 v3.5.16/go.mod h1:1P4SlIP/VwkDmGo3OlOD7faPeP8KDIFhqvciH5EfN28= +go.etcd.io/etcd/client/pkg/v3 v3.5.16 h1:ZgY48uH6UvB+/7R9Yf4x574uCO3jIx0TRDyetSfId3Q= +go.etcd.io/etcd/client/pkg/v3 v3.5.16/go.mod h1:V8acl8pcEK0Y2g19YlOV9m9ssUe6MgiDSobSoaBAM0E= +go.etcd.io/etcd/client/v2 v2.305.16 h1:kQrn9o5czVNaukf2A2At43cE9ZtWauOtf9vRZuiKXow= +go.etcd.io/etcd/client/v2 v2.305.16/go.mod h1:h9YxWCzcdvZENbfzBTFCnoNumr2ax3F19sKMqHFmXHE= +go.etcd.io/etcd/client/v3 v3.5.16 h1:sSmVYOAHeC9doqi0gv7v86oY/BTld0SEFGaxsU9eRhE= +go.etcd.io/etcd/client/v3 v3.5.16/go.mod h1:X+rExSGkyqxvu276cr2OwPLBaeqFu1cIl4vmRjAD/50= +go.etcd.io/etcd/pkg/v3 v3.5.16 h1:cnavs5WSPWeK4TYwPYfmcr3Joz9BH+TZ6qoUtz6/+mc= +go.etcd.io/etcd/pkg/v3 v3.5.16/go.mod h1:+lutCZHG5MBBFI/U4eYT5yL7sJfnexsoM20Y0t2uNuY= +go.etcd.io/etcd/raft/v3 v3.5.16 h1:zBXA3ZUpYs1AwiLGPafYAKKl/CORn/uaxYDwlNwndAk= +go.etcd.io/etcd/raft/v3 v3.5.16/go.mod h1:P4UP14AxofMJ/54boWilabqqWoW9eLodl6I5GdGzazI= +go.etcd.io/etcd/server/v3 v3.5.16 h1:d0/SAdJ3vVsZvF8IFVb1k8zqMZ+heGcNfft71ul9GWE= +go.etcd.io/etcd/server/v3 v3.5.16/go.mod h1:ynhyZZpdDp1Gq49jkUg5mfkDWZwXnn3eIqCqtJnrD/s= 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= @@ -288,8 +292,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= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= 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= @@ -318,7 +322,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h 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-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.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -360,70 +363,68 @@ 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= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8= -k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE= -k8s.io/apiextensions-apiserver v0.31.3 h1:+GFGj2qFiU7rGCsA5o+p/rul1OQIq6oYpQw4+u+nciE= -k8s.io/apiextensions-apiserver v0.31.3/go.mod h1:2DSpFhUZZJmn/cr/RweH1cEVVbzFw9YBu4T+U3mf1e4= -k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= -k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/apiserver v0.31.3 h1:+1oHTtCB+OheqFEz375D0IlzHZ5VeQKX1KGXnx+TTuY= -k8s.io/apiserver v0.31.3/go.mod h1:PrxVbebxrxQPFhJk4powDISIROkNMKHibTg9lTRQ0Qg= -k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4= -k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs= -k8s.io/cloud-provider v0.31.3 h1:7C3CHQUUwnv/HWWVIaibZH06iPg663RYQ6C6Zy4FnO8= -k8s.io/cloud-provider v0.31.3/go.mod h1:c7csKppoVb9Ej6upJ28AvHy4B3BtlRMzXfgezsDdPKw= -k8s.io/code-generator v0.31.3 h1:Pj0fYOBms+ZrsulLi4DMsCEx1jG8fWKRLy44onHsLBI= -k8s.io/code-generator v0.31.3/go.mod h1:/umCIlT84g1+Yu5ZXtP1KGSRTnGiIzzX5AzUAxsNlts= -k8s.io/component-base v0.31.3 h1:DMCXXVx546Rfvhj+3cOm2EUxhS+EyztH423j+8sOwhQ= -k8s.io/component-base v0.31.3/go.mod h1:xME6BHfUOafRgT0rGVBGl7TuSg8Z9/deT7qq6w7qjIU= -k8s.io/component-helpers v0.31.3 h1:0zGPD2PrekhFWgmz85XxlMEl7dfhlKC1tERZDe3onQc= -k8s.io/component-helpers v0.31.3/go.mod h1:HZ1HZx2TKXM7xSUV2cR9L5yDoyZPhhHQNaE3BPBLPUQ= -k8s.io/controller-manager v0.31.3 h1:TyUav69iNYwLGwA96JDhusoZoGRdh1sdrLjXmWTcPgs= -k8s.io/controller-manager v0.31.3/go.mod h1:yuhec+dbXmBz+4c32kxJxmcauB+1pjO2ttfYODWuv18= -k8s.io/cri-api v0.31.3 h1:dsZXzrGrCEwHjsTDlAV7rutEplpMLY8bfNRMIqrtXjo= -k8s.io/cri-api v0.31.3/go.mod h1:Po3TMAYH/+KrZabi7QiwQI4a692oZcUOUThd/rqwxrI= -k8s.io/cri-client v0.31.3 h1:9ZwddaNJomqkTBYQqSmB+Ccns3beY4HyYDwmRtWTCJM= -k8s.io/cri-client v0.31.3/go.mod h1:klbWiYkOatOQOkXOYZMZMGSTM8q9eC/efsYGuXcgPes= -k8s.io/csi-translation-lib v0.31.3 h1:hxcPRNdtEsk766jCXSKjgH1V8jUNx5tVqdooQ1Ars/M= -k8s.io/csi-translation-lib v0.31.3/go.mod h1:0B1gQwd868XUIDwJYy5gB2jDXWEwlcWvSsfcQEgzbRk= -k8s.io/dynamic-resource-allocation v0.31.3 h1:hiQMhyxrm7WA6tWJCLINE2P11Ii3rCVw+YzV3B6+eWo= -k8s.io/dynamic-resource-allocation v0.31.3/go.mod h1:l7OvYDokvnXhFAOhInQUY/z0/HezzmRuLlspld4Xfg4= -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/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= +k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= +k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= +k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= +k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= +k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs= +k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag= +k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= +k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/cloud-provider v0.32.0 h1:QXYJGmwME2q2rprymbmw2GroMChQYc/MWN6l/I4Kgp8= +k8s.io/cloud-provider v0.32.0/go.mod h1:cz3gVodkhgwi2ugj/JUPglIruLSdDaThxawuDyCHfr8= +k8s.io/code-generator v0.32.0 h1:s0lNN8VSWny8LBz5t5iy7MCdgwdOhdg7vAGVxvS+VWU= +k8s.io/code-generator v0.32.0/go.mod h1:b7Q7KMZkvsYFy72A79QYjiv4aTz3GvW0f1T3UfhFq4s= +k8s.io/component-base v0.32.0 h1:d6cWHZkCiiep41ObYQS6IcgzOUQUNpywm39KVYaUqzU= +k8s.io/component-base v0.32.0/go.mod h1:JLG2W5TUxUu5uDyKiH2R/7NnxJo1HlPoRIIbVLkK5eM= +k8s.io/component-helpers v0.32.0 h1:pQEEBmRt3pDJJX98cQvZshDgJFeKRM4YtYkMmfOlczw= +k8s.io/component-helpers v0.32.0/go.mod h1:9RuClQatbClcokXOcDWSzFKQm1huIf0FzQlPRpizlMc= +k8s.io/controller-manager v0.32.0 h1:tpQl1rvH4huFB6Avl1nhowZHtZoCNWqn6OYdZPl7Ybc= +k8s.io/controller-manager v0.32.0/go.mod h1:JRuYnYCkKj3NgBTy+KNQKIUm/lJRoDAvGbfdEmk9LhY= +k8s.io/cri-api v0.32.0 h1:pzXJfyG7Tm4acrEt5HPqAq3r4cN5guLeapAN/NM2b70= +k8s.io/cri-api v0.32.0/go.mod h1:DCzMuTh2padoinefWME0G678Mc3QFbLMF2vEweGzBAI= +k8s.io/cri-client v0.32.0 h1:K6aTYDyS2AS8O4h79eI5r26562xstdybprtaaszjn+E= +k8s.io/cri-client v0.32.0/go.mod h1:FB8qZNj8KrwIFfVIR2zBGb+l6KUhrp+k8YFsVp3D+kw= +k8s.io/csi-translation-lib v0.32.0 h1:RAn9RGgYXHJQtDSb6qQ7zvq6QObOejzmsXDARI+f4OQ= +k8s.io/csi-translation-lib v0.32.0/go.mod h1:TjCJzkTNstdOESAXNnEImrYOMIEzP14aqM7H+vkehqw= +k8s.io/dynamic-resource-allocation v0.32.0 h1:0ZLSCKzlLZLVwKHxg6vafpd2U8b7jPMO3k8bbMFodis= +k8s.io/dynamic-resource-allocation v0.32.0/go.mod h1:MfoAUi0vCJtchNirAVk7c3IYfGGB3n+zbZ9GuyX4eeo= +k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9 h1:si3PfKm8dDYxgfbeA6orqrtLkvvIeH8UqffFJDl0bz4= +k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= 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.31.3 h1:XCFmiJn5CCKs8xoOLpCmu42Ubm/KW85wNHybGFcSAYc= -k8s.io/kms v0.31.3/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.31.3 h1:indE2jtvbwyyEYDrQMjPR2EmnoM1pd4L6cK8r2/KY0I= -k8s.io/kube-scheduler v0.31.3/go.mod h1:vhDtABcWycLi8139K5ScOg54WKlbEZJRgtQmLhW0Wjo= -k8s.io/kubectl v0.31.3 h1:3r111pCjPsvnR98oLLxDMwAeM6OPGmPty6gSKaLTQes= -k8s.io/kubectl v0.31.3/go.mod h1:lhMECDCbJN8He12qcKqs2QfmVo9Pue30geovBVpH5fs= -k8s.io/kubelet v0.31.3 h1:DIXRAmvVGp42mV2vpA1GCLU6oO8who0/vp3Oq6kSpbI= -k8s.io/kubelet v0.31.3/go.mod h1:KSdbEfNy5VzqUlAHlytA/fH12s+sE1u8fb/8JY9sL/8= -k8s.io/kubernetes v1.31.3 h1:oqb7HdfnTelrGlZ6ziNugvQ/L/aJWR704114EAhUn9Q= -k8s.io/kubernetes v1.31.3/go.mod h1:9xmT2buyTYj8TRKwRae7FcuY8k5+xlxv7VivvO0KKfs= -k8s.io/mount-utils v0.31.3 h1:CANy3prUYvvDCc2X7ZKgpjpDhAidx4gjGh/WwDrCPq8= -k8s.io/mount-utils v0.31.3/go.mod h1:HV/VYBUGqYUj4vt82YltzpWvgv8FPg0G9ItyInT3NPU= -k8s.io/pod-security-admission v0.31.3 h1:8NzEV0HtdStX367AuSKfRMIZHn0hT4xuz8xNEf7/zO8= -k8s.io/pod-security-admission v0.31.3/go.mod h1:YMIcTe/7f9R9d+3ErCMMM3Wtbj9ejKo7Z9S0OxZQrRg= -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= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +k8s.io/kms v0.32.0 h1:jwOfunHIrcdYl5FRcA+uUKKtg6qiqoPCwmS2T3XTYL4= +k8s.io/kms v0.32.0/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= +k8s.io/kube-scheduler v0.32.0 h1:FCsF/3TPvR51ptx/gLUrqcoKqAMhQKrydYCJzPz9VGM= +k8s.io/kube-scheduler v0.32.0/go.mod h1:yof3vmyx70TWoQ6XZruYEGIUT/r0H/ELGdnWiqPF5EE= +k8s.io/kubectl v0.32.0 h1:rpxl+ng9qeG79YA4Em9tLSfX0G8W0vfaiPVrc/WR7Xw= +k8s.io/kubectl v0.32.0/go.mod h1:qIjSX+QgPQUgdy8ps6eKsYNF+YmFOAO3WygfucIqFiE= +k8s.io/kubelet v0.32.0 h1:uLyiKlz195Wo4an/K2tyge8o3QHx0ZkhVN3pevvp59A= +k8s.io/kubelet v0.32.0/go.mod h1:lAwuVZT/Hm7EdLn0jW2D+WdrJoorjJL2rVSdhOFnegw= +k8s.io/kubernetes v1.32.0 h1:4BDBWSolqPrv8GC3YfZw0CJvh5kA1TPnoX0FxDVd+qc= +k8s.io/kubernetes v1.32.0/go.mod h1:tiIKO63GcdPRBHW2WiUFm3C0eoLczl3f7qi56Dm1W8I= +k8s.io/mount-utils v0.32.0 h1:KOQAhPzJICATXnc6XCkWoexKbkOexRnMCUW8APFfwg4= +k8s.io/mount-utils v0.32.0/go.mod h1:Kun5c2svjAPx0nnvJKYQWhfeNW+O0EpzHgRhDcYoSY0= +k8s.io/pod-security-admission v0.32.0 h1:I+Og0uZIiMpIgTgPrTbW4jlwRI5RWazi8y+jrx1v10w= +k8s.io/pod-security-admission v0.32.0/go.mod h1:RvrcY0+5UAoCIJ7BscgDF3nbmXprgfnjTW+byCyXDvA= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c= +oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZHg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/pkg/apis/nfd/nodefeaturerule/expression-api_test.go b/pkg/apis/nfd/nodefeaturerule/expression-api_test.go index c6f778159..474b53ef8 100644 --- a/pkg/apis/nfd/nodefeaturerule/expression-api_test.go +++ b/pkg/apis/nfd/nodefeaturerule/expression-api_test.go @@ -116,7 +116,7 @@ bar: { op: Exists } t.Fatal("failed to parse data of test case") } - res, out, err := api.MatchGetKeys(mes, tc.input) + res, out, _, err := api.MatchGetKeys(mes, tc.input) tc.result(t, res) assert.Equal(t, tc.output, out) tc.err(t, err) @@ -183,12 +183,12 @@ baz: { op: Gt, value: ["10"] } t.Fatal("failed to parse data of test case") } - res, out, err := api.MatchGetValues(mes, tc.input) + res, out, _, err := api.MatchGetValues(mes, tc.input, true) tc.result(t, res) assert.Equal(t, tc.output, out) tc.err(t, err) - res, err = api.MatchValues(mes, tc.input) + res, _, err = api.MatchValues(mes, tc.input, true) tc.result(t, res) tc.err(t, err) }) @@ -248,12 +248,12 @@ bar: { op: Lt, value: ["10"] } t.Fatal("failed to parse data of test case") } - res, out, err := api.MatchGetInstances(mes, tc.input) + res, out, _, err := api.MatchGetInstances(mes, tc.input, true) assert.Equal(t, tc.output, out) tc.result(t, res) tc.err(t, err) - res, err = api.MatchInstances(mes, tc.input) + res, err = api.MatchInstances(mes, tc.input, true) tc.result(t, res) tc.err(t, err) }) @@ -745,7 +745,7 @@ func TestMatchMulti(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - res, out, err := api.MatchMulti(tc.mes, tc.inputKeys, tc.inputValues, tc.inputInstances) + res, out, _, err := api.MatchMulti(tc.mes, tc.inputKeys, tc.inputValues, tc.inputInstances, true) if tc.expectErr { assert.NotNil(t, err) } else { diff --git a/pkg/apis/nfd/nodefeaturerule/expression.go b/pkg/apis/nfd/nodefeaturerule/expression.go index 585ce2e1c..3220f0a6b 100644 --- a/pkg/apis/nfd/nodefeaturerule/expression.go +++ b/pkg/apis/nfd/nodefeaturerule/expression.go @@ -29,6 +29,13 @@ import ( nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" ) +const ( + // MatchedKeyName is the name of the matched flag/attribute element. + MatchedKeyName = "Name" + // MatchedKeyValue is the value of the matched attribute element. + MatchedKeyValue = "Value" +) + var matchOps = map[nfdv1alpha1.MatchOp]struct{}{ nfdv1alpha1.MatchAny: {}, nfdv1alpha1.MatchIn: {}, @@ -202,16 +209,16 @@ func MatchKeyNames(m *nfdv1alpha1.MatchExpression, keys map[string]nfdv1alpha1.N if match, err := evaluateMatchExpression(m, true, k); err != nil { return false, nil, err } else if match { - ret = append(ret, MatchedElement{"Name": k}) + ret = append(ret, MatchedElement{MatchedKeyName: k}) } } // Sort for reproducible output - sort.Slice(ret, func(i, j int) bool { return ret[i]["Name"] < ret[j]["Name"] }) + sort.Slice(ret, func(i, j int) bool { return ret[i][MatchedKeyName] < ret[j][MatchedKeyName] }) if klogV3 := klog.V(3); klogV3.Enabled() { mk := make([]string, len(ret)) for i, v := range ret { - mk[i] = v["Name"] + mk[i] = v[MatchedKeyName] } mkMsg := strings.Join(mk, ", ") @@ -238,16 +245,16 @@ func MatchValueNames(m *nfdv1alpha1.MatchExpression, values map[string]string) ( if match, err := evaluateMatchExpression(m, true, k); err != nil { return false, nil, err } else if match { - ret = append(ret, MatchedElement{"Name": k, "Value": v}) + ret = append(ret, MatchedElement{MatchedKeyName: k, MatchedKeyValue: v}) } } // Sort for reproducible output - sort.Slice(ret, func(i, j int) bool { return ret[i]["Name"] < ret[j]["Name"] }) + sort.Slice(ret, func(i, j int) bool { return ret[i][MatchedKeyName] < ret[j][MatchedKeyName] }) if klogV3 := klog.V(3); klogV3.Enabled() { mk := make([]string, len(ret)) for i, v := range ret { - mk[i] = v["Name"] + mk[i] = v[MatchedKeyName] } mkMsg := strings.Join(mk, ", ") @@ -278,7 +285,7 @@ func MatchInstanceAttributeNames(m *nfdv1alpha1.MatchExpression, instances []nfd // MatchKeys evaluates the MatchExpressionSet against a set of keys. func MatchKeys(m *nfdv1alpha1.MatchExpressionSet, keys map[string]nfdv1alpha1.Nil) (bool, error) { - matched, _, err := MatchGetKeys(m, keys) + matched, _, _, err := MatchGetKeys(m, keys) return matched, err } @@ -288,56 +295,65 @@ type MatchedElement map[string]string // MatchGetKeys evaluates the MatchExpressionSet against a set of keys and // returns all matched keys or nil if no match was found. Note that an empty // MatchExpressionSet returns a match with an empty slice of matched features. -func MatchGetKeys(m *nfdv1alpha1.MatchExpressionSet, keys map[string]nfdv1alpha1.Nil) (bool, []MatchedElement, error) { - ret := make([]MatchedElement, 0, len(*m)) +func MatchGetKeys(m *nfdv1alpha1.MatchExpressionSet, keys map[string]nfdv1alpha1.Nil) (bool, []MatchedElement, *nfdv1alpha1.MatchExpressionSet, error) { + matchedElements := make([]MatchedElement, 0, len(*m)) + matchedExpressions := make(nfdv1alpha1.MatchExpressionSet) for n, e := range *m { match, err := evaluateMatchExpressionKeys(e, n, keys) if err != nil { - return false, nil, err + return false, nil, nil, err } if !match { - return false, nil, nil + return false, nil, nil, nil } - ret = append(ret, MatchedElement{"Name": n}) + matchedElements = append(matchedElements, MatchedElement{MatchedKeyName: n}) + matchedExpressions[n] = e } // Sort for reproducible output - sort.Slice(ret, func(i, j int) bool { return ret[i]["Name"] < ret[j]["Name"] }) - return true, ret, nil + sort.Slice(matchedElements, func(i, j int) bool { return matchedElements[i][MatchedKeyName] < matchedElements[j][MatchedKeyName] }) + return true, matchedElements, &matchedExpressions, nil } // MatchValues evaluates the MatchExpressionSet against a set of key-value pairs. -func MatchValues(m *nfdv1alpha1.MatchExpressionSet, values map[string]string) (bool, error) { - matched, _, err := MatchGetValues(m, values) - return matched, err +func MatchValues(m *nfdv1alpha1.MatchExpressionSet, values map[string]string, failFast bool) (bool, *nfdv1alpha1.MatchExpressionSet, error) { + matched, _, matchedExpressions, err := MatchGetValues(m, values, failFast) + return matched, matchedExpressions, err } // MatchGetValues evaluates the MatchExpressionSet against a set of key-value // pairs and returns all matched key-value pairs. Note that an empty // MatchExpressionSet returns a match with an empty slice of matched features. -func MatchGetValues(m *nfdv1alpha1.MatchExpressionSet, values map[string]string) (bool, []MatchedElement, error) { - ret := make([]MatchedElement, 0, len(*m)) +func MatchGetValues(m *nfdv1alpha1.MatchExpressionSet, values map[string]string, failFast bool) (bool, []MatchedElement, *nfdv1alpha1.MatchExpressionSet, error) { + matchedElements := make([]MatchedElement, 0, len(*m)) + matchedExpressions := make(nfdv1alpha1.MatchExpressionSet) + isMatch := true for n, e := range *m { match, err := evaluateMatchExpressionValues(e, n, values) if err != nil { - return false, nil, err + return false, nil, nil, err } - if !match { - return false, nil, nil + if match { + matchedElements = append(matchedElements, MatchedElement{MatchedKeyName: n, MatchedKeyValue: values[n]}) + matchedExpressions[n] = e + } else { + if failFast { + return false, nil, nil, nil + } + isMatch = false } - ret = append(ret, MatchedElement{"Name": n, "Value": values[n]}) } // Sort for reproducible output - sort.Slice(ret, func(i, j int) bool { return ret[i]["Name"] < ret[j]["Name"] }) - return true, ret, nil + sort.Slice(matchedElements, func(i, j int) bool { return matchedElements[i][MatchedKeyName] < matchedElements[j][MatchedKeyName] }) + return isMatch, matchedElements, &matchedExpressions, nil } // MatchInstances evaluates the MatchExpressionSet against a set of instance // features, each of which is an individual set of key-value pairs // (attributes). -func MatchInstances(m *nfdv1alpha1.MatchExpressionSet, instances []nfdv1alpha1.InstanceFeature) (bool, error) { - isMatch, _, err := MatchGetInstances(m, instances) +func MatchInstances(m *nfdv1alpha1.MatchExpressionSet, instances []nfdv1alpha1.InstanceFeature, failFast bool) (bool, error) { + isMatch, _, _, err := MatchGetInstances(m, instances, failFast) return isMatch, err } @@ -346,17 +362,28 @@ func MatchInstances(m *nfdv1alpha1.MatchExpressionSet, instances []nfdv1alpha1.I // (attributes). Returns a boolean that reports whether the expression matched. // Also, returns a slice containing all matching instances. An empty (non-nil) // slice is returned if no matching instances were found. -func MatchGetInstances(m *nfdv1alpha1.MatchExpressionSet, instances []nfdv1alpha1.InstanceFeature) (bool, []MatchedElement, error) { - ret := []MatchedElement{} +func MatchGetInstances(m *nfdv1alpha1.MatchExpressionSet, instances []nfdv1alpha1.InstanceFeature, failFast bool) (bool, []MatchedElement, *nfdv1alpha1.MatchExpressionSet, error) { + var ( + match bool + err error + expressionSet *nfdv1alpha1.MatchExpressionSet + ) + matchedElements := []MatchedElement{} + matchedExpressions := &nfdv1alpha1.MatchExpressionSet{} for _, i := range instances { - if match, err := MatchValues(m, i.Attributes); err != nil { - return false, nil, err + if match, expressionSet, err = MatchValues(m, i.Attributes, failFast); err != nil { + return false, nil, nil, err } else if match { - ret = append(ret, i.Attributes) + matchedElements = append(matchedElements, i.Attributes) + } + if expressionSet != nil { + for name, exp := range *expressionSet { + (*matchedExpressions)[name] = exp + } } } - return len(ret) > 0, ret, nil + return len(matchedElements) > 0, matchedElements, matchedExpressions, nil } // MatchMulti evaluates a MatchExpressionSet against key, value and instance @@ -365,8 +392,9 @@ func MatchGetInstances(m *nfdv1alpha1.MatchExpressionSet, instances []nfdv1alpha // handled separately as the way of evaluating match expressions is different. // This function is written to handle "multi-type" features where one feature // (say "cpu.cpuid") contains multiple types (flag, attribute and/or instance). -func MatchMulti(m *nfdv1alpha1.MatchExpressionSet, keys map[string]nfdv1alpha1.Nil, values map[string]string, instances []nfdv1alpha1.InstanceFeature) (bool, []MatchedElement, error) { +func MatchMulti(m *nfdv1alpha1.MatchExpressionSet, keys map[string]nfdv1alpha1.Nil, values map[string]string, instances []nfdv1alpha1.InstanceFeature, failFast bool) (bool, []MatchedElement, *nfdv1alpha1.MatchExpressionSet, error) { matchedElems := []MatchedElement{} + matchedExpressions := nfdv1alpha1.MatchExpressionSet{} isMatch := false // Keys and values are handled as a union, it is enough to find a match in @@ -384,14 +412,19 @@ func MatchMulti(m *nfdv1alpha1.MatchExpressionSet, keys map[string]nfdv1alpha1.N if keys != nil { matchK, err = evaluateMatchExpressionKeys(e, n, keys) if err != nil { - return false, nil, err + return false, nil, nil, err } if matchK { - matchedElems = append(matchedElems, MatchedElement{"Name": n}) + matchedElems = append(matchedElems, MatchedElement{MatchedKeyName: n}) + matchedExpressions[n] = e } else if e.Op == nfdv1alpha1.MatchDoesNotExist { // DoesNotExist is special in that both "keys" and "values" should match (i.e. the name is not found in either of them). isMatch = false + if !failFast { + continue + } matchedElems = []MatchedElement{} + matchedExpressions = nfdv1alpha1.MatchExpressionSet{} break } } @@ -399,39 +432,53 @@ func MatchMulti(m *nfdv1alpha1.MatchExpressionSet, keys map[string]nfdv1alpha1.N if values != nil { matchV, err = evaluateMatchExpressionValues(e, n, values) if err != nil { - return false, nil, err + return false, nil, nil, err } if matchV { - matchedElems = append(matchedElems, MatchedElement{"Name": n, "Value": values[n]}) + matchedElems = append(matchedElems, MatchedElement{MatchedKeyName: n, MatchedKeyValue: values[n]}) + matchedExpressions[n] = e } else if e.Op == nfdv1alpha1.MatchDoesNotExist { // DoesNotExist is special in that both "keys" and "values" should match (i.e. the name is not found in either of them). isMatch = false + if !failFast { + continue + } matchedElems = []MatchedElement{} + matchedExpressions = nfdv1alpha1.MatchExpressionSet{} break } } if !matchK && !matchV { isMatch = false + if !failFast { + continue + } matchedElems = []MatchedElement{} + matchedExpressions = nfdv1alpha1.MatchExpressionSet{} break } } // Sort for reproducible output - sort.Slice(matchedElems, func(i, j int) bool { return matchedElems[i]["Name"] < matchedElems[j]["Name"] }) + sort.Slice(matchedElems, func(i, j int) bool { return matchedElems[i][MatchedKeyName] < matchedElems[j][MatchedKeyName] }) // Instances are handled separately as the logic is fundamentally different // from keys and values and cannot be combined with them. We want to find // instance(s) that match all match expressions. I.e. the set of all match // expressions are evaluated against every instance separately. - ma, me, err := MatchGetInstances(m, instances) + ma, melems, mexps, err := MatchGetInstances(m, instances, failFast) if err != nil { - return false, nil, err + return false, nil, nil, err } isMatch = isMatch || ma - matchedElems = append(matchedElems, me...) + matchedElems = append(matchedElems, melems...) + if mexps != nil { + for k, v := range *mexps { + matchedExpressions[k] = v + } + } - return isMatch, matchedElems, nil + return isMatch, matchedElems, &matchedExpressions, nil } // MatchNamesMulti evaluates the MatchExpression against the names of key, @@ -440,12 +487,11 @@ func MatchMulti(m *nfdv1alpha1.MatchExpressionSet, keys map[string]nfdv1alpha1.N // types (flag, attribute and/or instance). func MatchNamesMulti(m *nfdv1alpha1.MatchExpression, keys map[string]nfdv1alpha1.Nil, values map[string]string, instances []nfdv1alpha1.InstanceFeature) (bool, []MatchedElement, error) { ret := []MatchedElement{} - for k := range keys { if match, err := evaluateMatchExpression(m, true, k); err != nil { return false, nil, err } else if match { - ret = append(ret, MatchedElement{"Name": k}) + ret = append(ret, MatchedElement{MatchedKeyName: k}) } } @@ -453,12 +499,12 @@ func MatchNamesMulti(m *nfdv1alpha1.MatchExpression, keys map[string]nfdv1alpha1 if match, err := evaluateMatchExpression(m, true, k); err != nil { return false, nil, err } else if match { - ret = append(ret, MatchedElement{"Name": k, "Value": v}) + ret = append(ret, MatchedElement{MatchedKeyName: k, MatchedKeyValue: v}) } } // Sort for reproducible output - sort.Slice(ret, func(i, j int) bool { return ret[i]["Name"] < ret[j]["Name"] }) + sort.Slice(ret, func(i, j int) bool { return ret[i][MatchedKeyName] < ret[j][MatchedKeyName] }) _, me, err := MatchInstanceAttributeNames(m, instances) if err != nil { @@ -469,7 +515,7 @@ func MatchNamesMulti(m *nfdv1alpha1.MatchExpression, keys map[string]nfdv1alpha1 if klogV3 := klog.V(3); klogV3.Enabled() { mk := make([]string, len(ret)) for i, v := range ret { - mk[i] = v["Name"] + mk[i] = v[MatchedKeyName] } mkMsg := strings.Join(mk, ", ") diff --git a/pkg/apis/nfd/nodefeaturerule/rule.go b/pkg/apis/nfd/nodefeaturerule/rule.go index 4c7f1b59a..f243e67e7 100644 --- a/pkg/apis/nfd/nodefeaturerule/rule.go +++ b/pkg/apis/nfd/nodefeaturerule/rule.go @@ -31,6 +31,31 @@ import ( "sigs.k8s.io/node-feature-discovery/pkg/utils" ) +// MatchStatus represents the status of a processed rule. +// It includes information about successful expressions and their results, which are the matched host features. +// For example, for the expression: cpu.cpuid: {op: "InRegexp", value: ["^AVX"]}, +// the result could include matched host features such as AVX, AVX2, AVX512 etc. +// +k8s:deepcopy-gen=false +type MatchStatus struct { + *MatchFeatureStatus + + // IsMatch informes whether a rule succeeded or failed. + IsMatch bool + // MatchAny represents an array of logical OR conditions between MatchFeatureStatus entries. + MatchAny []*MatchFeatureStatus +} + +// MatchFeatureStatus represents a matched expression +// with its result, which is matched host features. +// +k8s:deepcopy-gen=false +type MatchFeatureStatus struct { + // MatchedFeatures represents the features matched on the host, + // which is a result of the FeatureMatcher. + MatchedFeatures matchedFeatures + // MatchedFeaturesTerms represents the expressions that successfully matched on the host. + MatchedFeaturesTerms nfdv1alpha1.FeatureMatcher +} + // RuleOutput contains the output out rule execution. // +k8s:deepcopy-gen=false type RuleOutput struct { @@ -39,56 +64,69 @@ type RuleOutput struct { Annotations map[string]string Vars map[string]string Taints []corev1.Taint + MatchStatus *MatchStatus } // Execute the rule against a set of input features. -func Execute(r *nfdv1alpha1.Rule, features *nfdv1alpha1.Features) (RuleOutput, error) { +func Execute(r *nfdv1alpha1.Rule, features *nfdv1alpha1.Features, failFast bool) (RuleOutput, error) { + var ( + matchStatus MatchStatus + isMatch bool + err error + ) labels := make(map[string]string) vars := make(map[string]string) - if len(r.MatchAny) > 0 { + if n := len(r.MatchAny); n > 0 { + matchStatus.MatchAny = make([]*MatchFeatureStatus, 0, n) // Logical OR over the matchAny matchers - matched := false + var ( + featureStatus *MatchFeatureStatus + matched bool + ) for _, matcher := range r.MatchAny { - if isMatch, matches, err := evaluateMatchAnyElem(&matcher, features); err != nil { + if matched, featureStatus, err = evaluateMatchAnyElem(&matcher, features, failFast); err != nil { return RuleOutput{}, err - } else if isMatch { - matched = true - klog.V(4).InfoS("matchAny matched", "ruleName", r.Name, "matchedFeatures", utils.DelayedDumper(matches)) + } else if matched { + isMatch = true + klog.V(4).InfoS("matchAny matched", "ruleName", r.Name, "matchedFeatures", utils.DelayedDumper(featureStatus.MatchedFeatures)) - if r.LabelsTemplate == "" && r.VarsTemplate == "" { + if r.LabelsTemplate == "" && r.VarsTemplate == "" && failFast { // there's no need to evaluate other matchers in MatchAny // if there are no templates to be executed on them - so // short-circuit and stop on first match here break } - if err := executeLabelsTemplate(r, matches, labels); err != nil { + if err := executeLabelsTemplate(r, featureStatus.MatchedFeatures, labels); err != nil { return RuleOutput{}, err } - if err := executeVarsTemplate(r, matches, vars); err != nil { + if err := executeVarsTemplate(r, featureStatus.MatchedFeatures, vars); err != nil { return RuleOutput{}, err } } + + matchStatus.MatchAny = append(matchStatus.MatchAny, featureStatus) } - if !matched { + + if !isMatch { klog.V(2).InfoS("rule did not match", "ruleName", r.Name) - return RuleOutput{}, nil + return RuleOutput{MatchStatus: &matchStatus}, nil } } if len(r.MatchFeatures) > 0 { - if isMatch, matches, err := evaluateFeatureMatcher(&r.MatchFeatures, features); err != nil { + if isMatch, matchStatus.MatchFeatureStatus, err = evaluateFeatureMatcher(&r.MatchFeatures, features, failFast); err != nil { return RuleOutput{}, err } else if !isMatch { klog.V(2).InfoS("rule did not match", "ruleName", r.Name) - return RuleOutput{}, nil + return RuleOutput{MatchStatus: &matchStatus}, nil } else { - klog.V(4).InfoS("matchFeatures matched", "ruleName", r.Name, "matchedFeatures", utils.DelayedDumper(matches)) - if err := executeLabelsTemplate(r, matches, labels); err != nil { + klog.V(4).InfoS("matchFeatures matched", "ruleName", r.Name, "matchedFeatures", utils.DelayedDumper(matchStatus.MatchedFeatures)) + if err := executeLabelsTemplate(r, matchStatus.MatchedFeatures, labels); err != nil { return RuleOutput{}, err } - if err := executeVarsTemplate(r, matches, vars); err != nil { + if err := executeVarsTemplate(r, matchStatus.MatchedFeatures, vars); err != nil { return RuleOutput{}, err } } @@ -96,6 +134,7 @@ func Execute(r *nfdv1alpha1.Rule, features *nfdv1alpha1.Features) (RuleOutput, e maps.Copy(labels, r.Labels) maps.Copy(vars, r.Vars) + matchStatus.IsMatch = true ret := RuleOutput{ Labels: labels, @@ -103,6 +142,7 @@ func Execute(r *nfdv1alpha1.Rule, features *nfdv1alpha1.Features) (RuleOutput, e Annotations: maps.Clone(r.Annotations), ExtendedResources: maps.Clone(r.ExtendedResources), Taints: slices.Clone(r.Taints), + MatchStatus: &matchStatus, } klog.V(2).InfoS("rule matched", "ruleName", r.Name, "ruleOutput", utils.DelayedDumper(ret)) return ret, nil @@ -110,12 +150,12 @@ func Execute(r *nfdv1alpha1.Rule, features *nfdv1alpha1.Features) (RuleOutput, e // ExecuteGroupRule executes the GroupRule against a set of input features, and return true if the // rule matches. -func ExecuteGroupRule(r *nfdv1alpha1.GroupRule, features *nfdv1alpha1.Features) (bool, error) { +func ExecuteGroupRule(r *nfdv1alpha1.GroupRule, features *nfdv1alpha1.Features, failFast bool) (bool, error) { matched := false if len(r.MatchAny) > 0 { // Logical OR over the matchAny matchers for _, matcher := range r.MatchAny { - if isMatch, matches, err := evaluateMatchAnyElem(&matcher, features); err != nil { + if isMatch, matches, err := evaluateMatchAnyElem(&matcher, features, failFast); err != nil { return false, err } else if isMatch { matched = true @@ -131,7 +171,7 @@ func ExecuteGroupRule(r *nfdv1alpha1.GroupRule, features *nfdv1alpha1.Features) } if len(r.MatchFeatures) > 0 { - if isMatch, _, err := evaluateFeatureMatcher(&r.MatchFeatures, features); err != nil { + if isMatch, _, err := evaluateFeatureMatcher(&r.MatchFeatures, features, failFast); err != nil { return false, err } else if !isMatch { klog.V(2).InfoS("rule did not match", "ruleName", r.Name) @@ -187,12 +227,18 @@ type matchedFeatures map[string]domainMatchedFeatures type domainMatchedFeatures map[string][]MatchedElement -func evaluateMatchAnyElem(e *nfdv1alpha1.MatchAnyElem, features *nfdv1alpha1.Features) (bool, matchedFeatures, error) { - return evaluateFeatureMatcher(&e.MatchFeatures, features) +func evaluateMatchAnyElem(e *nfdv1alpha1.MatchAnyElem, features *nfdv1alpha1.Features, failFast bool) (bool, *MatchFeatureStatus, error) { + return evaluateFeatureMatcher(&e.MatchFeatures, features, failFast) } -func evaluateFeatureMatcher(m *nfdv1alpha1.FeatureMatcher, features *nfdv1alpha1.Features) (bool, matchedFeatures, error) { - matches := make(matchedFeatures, len(*m)) +func evaluateFeatureMatcher(m *nfdv1alpha1.FeatureMatcher, features *nfdv1alpha1.Features, failFast bool) (bool, *MatchFeatureStatus, error) { + var ( + isMatch = true + isTermMatch = true + ) + status := &MatchFeatureStatus{ + MatchedFeatures: make(matchedFeatures, len(*m)), + } // Logical AND over the terms for _, term := range *m { @@ -207,14 +253,17 @@ func evaluateFeatureMatcher(m *nfdv1alpha1.FeatureMatcher, features *nfdv1alpha1 dom := nameSplit[0] nam := nameSplit[1] - if _, ok := matches[dom]; !ok { - matches[dom] = make(domainMatchedFeatures) + if _, ok := status.MatchedFeatures[dom]; !ok { + status.MatchedFeatures[dom] = make(domainMatchedFeatures) } - var isMatch = true var matchedElems []MatchedElement + var matchedExpressions *nfdv1alpha1.MatchExpressionSet var err error + matchedFeatureTerm := nfdv1alpha1.FeatureMatcherTerm{ + Feature: featureName, + } fF, okF := features.Flags[featureName] fA, okA := features.Attributes[featureName] fI, okI := features.Instances[featureName] @@ -224,24 +273,37 @@ func evaluateFeatureMatcher(m *nfdv1alpha1.FeatureMatcher, features *nfdv1alpha1 } if term.MatchExpressions != nil { - isMatch, matchedElems, err = MatchMulti(term.MatchExpressions, fF.Elements, fA.Elements, fI.Elements) + isTermMatch, matchedElems, matchedExpressions, err = MatchMulti(term.MatchExpressions, fF.Elements, fA.Elements, fI.Elements, failFast) + matchedFeatureTerm.MatchExpressions = matchedExpressions } - if err == nil && isMatch && term.MatchName != nil { + if err == nil && isTermMatch && term.MatchName != nil { var meTmp []MatchedElement - isMatch, meTmp, err = MatchNamesMulti(term.MatchName, fF.Elements, fA.Elements, fI.Elements) + isTermMatch, meTmp, err = MatchNamesMulti(term.MatchName, fF.Elements, fA.Elements, fI.Elements) matchedElems = append(matchedElems, meTmp...) + // MatchName has only one expression, in this case it's enough to check the isTermMatch flag + // to judge if the expression succeeded on the host. + if isTermMatch { + matchedFeatureTerm.MatchName = term.MatchName + } } - matches[dom][nam] = append(matches[dom][nam], matchedElems...) + status.MatchedFeatures[dom][nam] = append(status.MatchedFeatures[dom][nam], matchedElems...) + if matchedFeatureTerm.MatchName != nil || (matchedFeatureTerm.MatchExpressions != nil && len(*matchedFeatureTerm.MatchExpressions) > 0) { + status.MatchedFeaturesTerms = append(status.MatchedFeaturesTerms, matchedFeatureTerm) + } if err != nil { return false, nil, err - } else if !isMatch { - return false, nil, nil + } else if !isTermMatch { + if !failFast { + isMatch = false + } else { + return false, status, nil + } } } - return true, matches, nil + return isMatch, status, nil } type templateHelper struct { diff --git a/pkg/apis/nfd/nodefeaturerule/rule_test.go b/pkg/apis/nfd/nodefeaturerule/rule_test.go index 28f8d902d..45e178cbd 100644 --- a/pkg/apis/nfd/nodefeaturerule/rule_test.go +++ b/pkg/apis/nfd/nodefeaturerule/rule_test.go @@ -49,11 +49,11 @@ func TestRule(t *testing.T) { } // Test totally empty features - m, err := Execute(r1, f) + m, err := Execute(r1, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r1.Labels, m.Labels, "empty matcher should have matched empty features") - m, err = Execute(r2, f) + m, err = Execute(r2, f, true) assert.NoError(t, err, "matching against a missing feature should not have returned an error") assert.Empty(t, m.Labels) assert.Empty(t, m.Vars) @@ -61,12 +61,12 @@ func TestRule(t *testing.T) { // Test properly initialized empty features f = nfdv1alpha1.NewFeatures() - m, err = Execute(r1, f) + m, err = Execute(r1, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r1.Labels, m.Labels, "empty matcher should have matched empty features") assert.Empty(t, r1.Vars, "vars should be empty") - m, err = Execute(r2, f) + m, err = Execute(r2, f, true) assert.NoError(t, err, "matching against a missing feature should not have returned an error") assert.Empty(t, m.Labels) assert.Empty(t, m.Vars) @@ -76,11 +76,11 @@ func TestRule(t *testing.T) { f.Attributes["domain-1.vf-1"] = nfdv1alpha1.NewAttributeFeatures(nil) f.Instances["domain-1.if-1"] = nfdv1alpha1.NewInstanceFeatures() - m, err = Execute(r1, f) + m, err = Execute(r1, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r1.Labels, m.Labels, "empty matcher should have matched empty features") - m, err = Execute(r2, f) + m, err = Execute(r2, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Nil(t, m.Labels, "unexpected match") @@ -89,7 +89,7 @@ func TestRule(t *testing.T) { f.Attributes["domain-1.vf-1"].Elements["key-1"] = "val-x" f.Instances["domain-1.if-1"] = nfdv1alpha1.NewInstanceFeatures(*nfdv1alpha1.NewInstanceFeature(map[string]string{"attr-1": "val-x"})) - m, err = Execute(r1, f) + m, err = Execute(r1, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r1.Labels, m.Labels, "empty matcher should have matched empty features") @@ -100,17 +100,17 @@ func TestRule(t *testing.T) { MatchExpressions: &nfdv1alpha1.MatchExpressionSet{}, }, } - m, err = Execute(r1, f) + m, err = Execute(r1, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r1.Labels, m.Labels, "empty match expression set mathces anything") // Match "key" features - m, err = Execute(r2, f) + m, err = Execute(r2, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Nil(t, m.Labels, "keys should not have matched") f.Flags["domain-1.kf-1"].Elements["key-1"] = nfdv1alpha1.Nil{} - m, err = Execute(r2, f) + m, err = Execute(r2, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r2.Labels, m.Labels, "keys should have matched") assert.Equal(t, r2.Vars, m.Vars, "vars should be present") @@ -127,12 +127,12 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Nil(t, m.Labels, "values should not have matched") f.Attributes["domain-1.vf-1"].Elements["key-1"] = "val-1" - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "values should have matched") @@ -148,12 +148,12 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Nil(t, m.Labels, "instances should not have matched") f.Instances["domain-1.if-1"].Elements[0].Attributes["attr-1"] = "val-1" - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "instances should have matched") @@ -177,7 +177,7 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f2) + m, err = Execute(r3, f2, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "key in multi-type feature should have matched") @@ -189,7 +189,7 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f2) + m, err = Execute(r3, f2, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "attribute in multi-type feature should have matched") @@ -201,7 +201,7 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f2) + m, err = Execute(r3, f2, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "attribute in multi-type feature should have matched") @@ -214,7 +214,7 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f2) + m, err = Execute(r3, f2, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "features in multi-type feature should have matched flags and attributes") @@ -226,7 +226,7 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f2) + m, err = Execute(r3, f2, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "features in multi-type feature should have matched instance") @@ -248,12 +248,12 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Nil(t, m.Labels, "instances should not have matched") (*r3.MatchFeatures[0].MatchExpressions)["key-1"] = newMatchExpression(nfdv1alpha1.MatchIn, "val-1") - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "instances should have matched") @@ -270,7 +270,7 @@ func TestRule(t *testing.T) { }, }, } - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Nil(t, m.Labels, "instances should not have matched") @@ -286,7 +286,7 @@ func TestRule(t *testing.T) { }, }) (*r3.MatchFeatures[0].MatchExpressions)["key-1"] = newMatchExpression(nfdv1alpha1.MatchIn, "val-1") - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, r3.Labels, m.Labels, "instances should have matched") } @@ -437,12 +437,12 @@ var-2= "kf-foo": "true", } - m, err := Execute(r1, f) + m, err := Execute(r1, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, expectedLabels, m.Labels, "instances should have matched") assert.Equal(t, expectedVars, m.Vars, "instances should have matched") - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, expectedLabels, m.Labels, "instances should have matched") assert.Equal(t, expectedVars, m.Vars, "instances should have matched") @@ -468,7 +468,7 @@ var-2= "mf-key-d": "found", } expectedVars = map[string]string{} - m, err = Execute(r3, f) + m, err = Execute(r3, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, expectedLabels, m.Labels, "instances should have matched") assert.Equal(t, expectedVars, m.Vars, "instances should have matched") @@ -490,32 +490,32 @@ var-2= } r2.LabelsTemplate = "foo=bar" - m, err = Execute(r2, f) + m, err = Execute(r2, f, true) assert.Nil(t, err) assert.Equal(t, map[string]string{"foo": "bar"}, m.Labels, "instances should have matched") assert.Empty(t, m.Vars) r2.LabelsTemplate = "foo" - _, err = Execute(r2, f) + _, err = Execute(r2, f, true) assert.Error(t, err) r2.LabelsTemplate = "{{" - _, err = Execute(r2, f) + _, err = Execute(r2, f, true) assert.Error(t, err) r2.LabelsTemplate = "" r2.VarsTemplate = "bar=baz" - m, err = Execute(r2, f) + m, err = Execute(r2, f, true) assert.Nil(t, err) assert.Empty(t, m.Labels) assert.Equal(t, map[string]string{"bar": "baz"}, m.Vars, "instances should have matched") r2.VarsTemplate = "bar" - _, err = Execute(r2, f) + _, err = Execute(r2, f, true) assert.Error(t, err) r2.VarsTemplate = "{{" - _, err = Execute(r2, f) + _, err = Execute(r2, f, true) assert.Error(t, err) // @@ -539,7 +539,7 @@ var-2= "key-5": "", } - m, err = Execute(r4, f) + m, err = Execute(r4, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, expectedLabels, m.Labels, "instances should have matched") @@ -553,7 +553,7 @@ var-2= }, } - m, err = Execute(r4, f) + m, err = Execute(r4, f, true) assert.Nilf(t, err, "unexpected error: %v", err) assert.Equal(t, map[string]string(nil), m.Labels, "instances should have matched") } diff --git a/pkg/client-nfd/compat/artifact-client/client.go b/pkg/client-nfd/compat/artifact-client/client.go new file mode 100644 index 000000000..ef37f1fc3 --- /dev/null +++ b/pkg/client-nfd/compat/artifact-client/client.go @@ -0,0 +1,178 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package compat + +//go:generate mockery --name=ArtifactClient --inpackage + +import ( + "context" + "encoding/json" + "fmt" + + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + oras "oras.land/oras-go/v2" + "oras.land/oras-go/v2/registry" + "oras.land/oras-go/v2/registry/remote" + "oras.land/oras-go/v2/registry/remote/auth" + "oras.land/oras-go/v2/registry/remote/retry" + "sigs.k8s.io/yaml" + + compatv1alpha1 "sigs.k8s.io/node-feature-discovery/api/image-compatibility/v1alpha1" +) + +// ArtifactClient interface contain set of functions to manipulate compatibility artfact. +type ArtifactClient interface { + // FetchCompatibilitySpec downloads the compatibility specifcation associated with the image. + FetchCompatibilitySpec(ctx context.Context) (*compatv1alpha1.Spec, error) +} + +// Args holds command line arguments. +type Args struct { + PlainHttp bool +} + +// Client represents a client that is reposnible for all artifact operations. +type Client struct { + Args Args + RegReference *registry.Reference + Platform *ocispec.Platform + + orasClient *auth.Client +} + +// New returns a new compatibility spec object. +func New(regReference *registry.Reference, opts ...ArtifactClientOpts) *Client { + c := &Client{ + RegReference: regReference, + } + for _, opt := range opts { + opt.apply(c) + } + return c +} + +// FetchCompatibilitySpec pulls the image compatibility specification associated with the image. +func (c *Client) FetchCompatibilitySpec(ctx context.Context) (*compatv1alpha1.Spec, error) { + repo, err := remote.NewRepository(c.RegReference.String()) + if err != nil { + return nil, err + } + repo.Client = c.orasClient + repo.PlainHTTP = c.Args.PlainHttp + + opts := oras.DefaultResolveOptions + if c.Platform != nil { + opts.TargetPlatform = c.Platform + } + + targetDesc, err := oras.Resolve(ctx, repo, c.RegReference.Reference, opts) + if err != nil { + return nil, err + } + + descs, err := registry.Referrers(ctx, repo, targetDesc, compatv1alpha1.ArtifactType) + if err != nil { + return nil, nil + } else if len(descs) < 1 { + return nil, fmt.Errorf("compatibility artifact not found") + } + artifactDesc := descs[len(descs)-1] + + _, content, err := oras.FetchBytes(ctx, repo.Manifests(), artifactDesc.Digest.String(), oras.DefaultFetchBytesOptions) + if err != nil { + return nil, err + } + + manifest := ocispec.Manifest{} + if err := json.Unmarshal(content, &manifest); err != nil { + return nil, err + } + + // TODO: now it's a lazy check, verify in the future the media types and number of layers + if len(manifest.Layers) < 1 { + return nil, fmt.Errorf("compatibility layer not found") + } + specDesc := manifest.Layers[0] + + _, compatSpecRaw, err := oras.FetchBytes(ctx, repo.Blobs(), specDesc.Digest.String(), oras.DefaultFetchBytesOptions) + if err != nil { + return nil, err + } + + compatSpec := compatv1alpha1.Spec{} + err = yaml.Unmarshal(compatSpecRaw, &compatSpec) + if err != nil { + return nil, err + } + + return &compatSpec, nil +} + +// NodeValidatorOpts applies certain options to the node validator. +type ArtifactClientOpts interface { + apply(*Client) +} + +type artifactClientOpt struct { + f func(*Client) +} + +func (o *artifactClientOpt) apply(nv *Client) { + o.f(nv) +} + +// WithArgs applies arguments to the artifact client. +func WithArgs(args Args) ArtifactClientOpts { + return &artifactClientOpt{f: func(c *Client) { c.Args = args }} +} + +// WithPlatform applies OCI platform spec to the artifact client. +func WithPlatform(platform *ocispec.Platform) ArtifactClientOpts { + return &artifactClientOpt{f: func(c *Client) { c.Platform = platform }} +} + +// WithAuthPassword initializes oras client with user and password. +func WithAuthPassword(username, password string) ArtifactClientOpts { + return &artifactClientOpt{f: func(c *Client) { + c.orasClient = &auth.Client{ + Client: retry.DefaultClient, + Cache: auth.NewCache(), + Credential: auth.StaticCredential(c.RegReference.Registry, auth.Credential{ + Username: username, + Password: password, + }), + } + }} +} + +// WithAuthToken initializes oras client with auth token. +func WithAuthToken(token string) ArtifactClientOpts { + return &artifactClientOpt{f: func(c *Client) { + c.orasClient = &auth.Client{ + Client: retry.DefaultClient, + Cache: auth.NewCache(), + Credential: auth.StaticCredential(c.RegReference.Registry, auth.Credential{ + AccessToken: token, + }), + } + }} +} + +// WithAuthDefault initializes the default oras client that does not authenticate. +func WithAuthDefault() ArtifactClientOpts { + return &artifactClientOpt{f: func(c *Client) { c.orasClient = auth.DefaultClient }} +} diff --git a/pkg/client-nfd/compat/artifact-client/mock_ArtifactClient.go b/pkg/client-nfd/compat/artifact-client/mock_ArtifactClient.go new file mode 100644 index 000000000..3c246ee52 --- /dev/null +++ b/pkg/client-nfd/compat/artifact-client/mock_ArtifactClient.go @@ -0,0 +1,59 @@ +// Code generated by mockery v2.42.0. DO NOT EDIT. + +package compat + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + v1alpha1 "sigs.k8s.io/node-feature-discovery/api/image-compatibility/v1alpha1" +) + +// MockArtifactClient is an autogenerated mock type for the ArtifactClient type +type MockArtifactClient struct { + mock.Mock +} + +// FetchCompatibilitySpec provides a mock function with given fields: ctx +func (_m *MockArtifactClient) FetchCompatibilitySpec(ctx context.Context) (*v1alpha1.Spec, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for FetchCompatibilitySpec") + } + + var r0 *v1alpha1.Spec + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*v1alpha1.Spec, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *v1alpha1.Spec); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Spec) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewMockArtifactClient creates a new instance of MockArtifactClient. 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 NewMockArtifactClient(t interface { + mock.TestingT + Cleanup(func()) +}) *MockArtifactClient { + mock := &MockArtifactClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/client-nfd/compat/node-validator/node-validator.go b/pkg/client-nfd/compat/node-validator/node-validator.go new file mode 100644 index 000000000..ef907c00f --- /dev/null +++ b/pkg/client-nfd/compat/node-validator/node-validator.go @@ -0,0 +1,203 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package nodevalidator + +import ( + "context" + "slices" + "sort" + + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" + "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/nodefeaturerule" + artifactcli "sigs.k8s.io/node-feature-discovery/pkg/client-nfd/compat/artifact-client" + "sigs.k8s.io/node-feature-discovery/source" + + // register sources + _ "sigs.k8s.io/node-feature-discovery/source/cpu" + _ "sigs.k8s.io/node-feature-discovery/source/kernel" + _ "sigs.k8s.io/node-feature-discovery/source/memory" + _ "sigs.k8s.io/node-feature-discovery/source/network" + _ "sigs.k8s.io/node-feature-discovery/source/pci" + _ "sigs.k8s.io/node-feature-discovery/source/storage" + _ "sigs.k8s.io/node-feature-discovery/source/system" + _ "sigs.k8s.io/node-feature-discovery/source/usb" +) + +// Args holds command line arguments. +type Args struct { + Tags []string +} + +type nodeValidator struct { + args Args + + artifactClient artifactcli.ArtifactClient + sources map[string]source.FeatureSource +} + +// New builds a node validator with specified options. +func New(opts ...NodeValidatorOpts) nodeValidator { + n := nodeValidator{} + for _, opt := range opts { + opt.apply(&n) + } + return n +} + +// Execute pulls the compatibility artifact to compare described features with the ones discovered on the node. +func (nv *nodeValidator) Execute(ctx context.Context) ([]*CompatibilityStatus, error) { + spec, err := nv.artifactClient.FetchCompatibilitySpec(ctx) + if err != nil { + return nil, err + } + + for _, s := range nv.sources { + if err := s.Discover(); err != nil { + return nil, err + } + } + features := source.GetAllFeatures() + + compats := []*CompatibilityStatus{} + for _, c := range spec.Compatibilties { + if len(nv.args.Tags) > 0 && !slices.Contains(nv.args.Tags, c.Tag) { + continue + } + compat := newCompatibilityStatus(&c) + + for _, r := range c.Rules { + ruleOut, err := nodefeaturerule.Execute(&r, features, false) + if err != nil { + return nil, err + } + compat.Rules = append(compat.Rules, evaluateRuleStatus(&r, ruleOut.MatchStatus)) + + // Add the 'rule.matched' feature for backreference functionality + features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels) + features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars) + } + compats = append(compats, &compat) + } + + return compats, nil +} + +func evaluateRuleStatus(rule *nfdv1alpha1.Rule, matchStatus *nodefeaturerule.MatchStatus) ProcessedRuleStatus { + out := ProcessedRuleStatus{Name: rule.Name, IsMatch: matchStatus.IsMatch} + + evaluateFeatureMatcher := func(featureMatcher, matchedFeatureTerms nfdv1alpha1.FeatureMatcher) []MatchedExpression { + out := []MatchedExpression{} + for _, term := range featureMatcher { + if term.MatchExpressions != nil { + for name, exp := range *term.MatchExpressions { + isMatch := false + + // Check if the expression matches + for _, processedTerm := range matchedFeatureTerms { + if term.Feature != processedTerm.Feature || processedTerm.MatchExpressions == nil { + continue + } + pexp, ok := (*processedTerm.MatchExpressions)[name] + if isMatch = ok && exp.Op == pexp.Op && slices.Equal(exp.Value, pexp.Value); isMatch { + break + } + } + + out = append(out, MatchedExpression{ + Feature: term.Feature, + Name: name, + Expression: exp, + MatcherType: MatchExpressionType, + IsMatch: isMatch, + }) + } + } + + if term.MatchName != nil { + isMatch := false + for _, processedTerm := range matchStatus.MatchedFeaturesTerms { + if term.Feature != processedTerm.Feature || processedTerm.MatchName == nil { + continue + } + isMatch = term.MatchName.Op == processedTerm.MatchName.Op && slices.Equal(term.MatchName.Value, processedTerm.MatchName.Value) + if isMatch { + break + } + } + out = append(out, MatchedExpression{ + Feature: term.Feature, + Name: "", + Expression: term.MatchName, + MatcherType: MatchNameType, + IsMatch: isMatch, + }) + } + } + + // For reproducible output sort by name, feature, expression. + sort.Slice(out, func(i, j int) bool { + if out[i].Feature != out[j].Feature { + return out[i].Feature < out[j].Feature + } + if out[i].Name != out[j].Name { + return out[i].Name < out[j].Name + } + return out[i].Expression.String() < out[j].Expression.String() + }) + + return out + } + + if matchFeatures := rule.MatchFeatures; matchFeatures != nil { + out.MatchedExpressions = evaluateFeatureMatcher(matchFeatures, matchStatus.MatchedFeaturesTerms) + } + + for i, matchAnyElem := range rule.MatchAny { + matchedExpressions := evaluateFeatureMatcher(matchAnyElem.MatchFeatures, matchStatus.MatchAny[i].MatchedFeaturesTerms) + out.MatchedAny = append(out.MatchedAny, MatchAnyElem{MatchedExpressions: matchedExpressions}) + } + + return out +} + +// NodeValidatorOpts applies certain options to the node validator. +type NodeValidatorOpts interface { + apply(*nodeValidator) +} + +type nodeValidatorOpt struct { + f func(*nodeValidator) +} + +func (o *nodeValidatorOpt) apply(nv *nodeValidator) { + o.f(nv) +} + +// WithArgs applies command line arguments to the node validator object. +func WithArgs(args *Args) NodeValidatorOpts { + return &nodeValidatorOpt{f: func(nv *nodeValidator) { nv.args = *args }} +} + +// WithArtifactClient applies the client for all artifact operations. +func WithArtifactClient(cli artifactcli.ArtifactClient) NodeValidatorOpts { + return &nodeValidatorOpt{f: func(nv *nodeValidator) { nv.artifactClient = cli }} +} + +// WithSources applies the list of enabled feature sources. +func WithSources(sources map[string]source.FeatureSource) NodeValidatorOpts { + return &nodeValidatorOpt{f: func(nv *nodeValidator) { nv.sources = sources }} +} diff --git a/pkg/client-nfd/compat/node-validator/node-validator_test.go b/pkg/client-nfd/compat/node-validator/node-validator_test.go new file mode 100644 index 000000000..6977578a9 --- /dev/null +++ b/pkg/client-nfd/compat/node-validator/node-validator_test.go @@ -0,0 +1,418 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package nodevalidator + +import ( + "context" + "testing" + + . "github.com/smartystreets/goconvey/convey" + + compatv1alpha1 "sigs.k8s.io/node-feature-discovery/api/image-compatibility/v1alpha1" + "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" + artifactcli "sigs.k8s.io/node-feature-discovery/pkg/client-nfd/compat/artifact-client" + "sigs.k8s.io/node-feature-discovery/source" + "sigs.k8s.io/node-feature-discovery/source/fake" +) + +func init() { + fs := source.GetConfigurableSource(fake.Name) + fs.SetConfig(fs.NewConfig()) +} + +func TestNodeValidator(t *testing.T) { + ctx := context.Background() + + Convey("With a single compatibility set that contains flags, attributes and instances", t, func() { + spec := &compatv1alpha1.Spec{ + Version: compatv1alpha1.Version, + Compatibilties: []compatv1alpha1.Compatibility{ + { + Description: "Fake compatibility", + Rules: []v1alpha1.Rule{ + { + Name: "fake_1", + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.flag", + MatchName: &v1alpha1.MatchExpression{Op: v1alpha1.MatchInRegexp, Value: v1alpha1.MatchValue{"^flag"}}, + }, + }, + }, + { + Name: "fake_2", + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.flag", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "flag_unknown": &v1alpha1.MatchExpression{Op: v1alpha1.MatchExists}, + }, + }, + { + Feature: "fake.attribute", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "attr_1": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"true"}}, + }, + }, + }, + }, + { + Name: "fake_3", + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.instance", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "name": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"instance_1"}}, + "attr_1": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"true"}}, + }, + }, + { + Feature: "fake.instance", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "name": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"instance_2"}}, + "attr_1": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + }, + }, + }, + }, + { + Name: "fake_4", + MatchAny: []v1alpha1.MatchAnyElem{ + { + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.instance", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "name": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"instance_1"}}, + }, + }, + }, + }, + { + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.instance", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "name": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"instance_unknown"}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + // The output contains expressions in alphabetical order over the feature, name and expression string. + expectedOutput := []*CompatibilityStatus{ + { + Description: "Fake compatibility", + Rules: []ProcessedRuleStatus{ + { + Name: "fake_1", + IsMatch: true, + MatchedExpressions: []MatchedExpression{ + { + Feature: "fake.flag", + Name: "", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchInRegexp, Value: v1alpha1.MatchValue{"^flag"}}, + MatcherType: MatchNameType, + IsMatch: true, + }, + }, + }, + { + Name: "fake_2", + IsMatch: false, + MatchedExpressions: []MatchedExpression{ + { + Feature: "fake.attribute", + Name: "attr_1", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"true"}}, + MatcherType: MatchExpressionType, + IsMatch: true, + }, + { + Feature: "fake.flag", + Name: "flag_unknown", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchExists}, + MatcherType: MatchExpressionType, + IsMatch: false, + }, + }, + }, + { + Name: "fake_3", + IsMatch: false, + MatchedExpressions: []MatchedExpression{ + { + Feature: "fake.instance", + Name: "attr_1", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + MatcherType: MatchExpressionType, + IsMatch: false, + }, + { + Feature: "fake.instance", + Name: "attr_1", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"true"}}, + MatcherType: MatchExpressionType, + IsMatch: true, + }, + { + Feature: "fake.instance", + Name: "name", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"instance_1"}}, + MatcherType: MatchExpressionType, + IsMatch: true, + }, + { + Feature: "fake.instance", + Name: "name", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"instance_2"}}, + MatcherType: MatchExpressionType, + IsMatch: true, + }, + }, + }, + { + Name: "fake_4", + IsMatch: true, + MatchedAny: []MatchAnyElem{ + { + MatchedExpressions: []MatchedExpression{ + { + Feature: "fake.instance", + Name: "name", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"instance_1"}}, + MatcherType: MatchExpressionType, + IsMatch: true, + }, + }, + }, + { + MatchedExpressions: []MatchedExpression{ + { + Feature: "fake.instance", + Name: "name", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"instance_unknown"}}, + MatcherType: MatchExpressionType, + IsMatch: false, + }, + }, + }, + }, + }, + }, + }, + } + + validator := New( + WithArgs(&Args{}), + WithArtifactClient(newMock(ctx, spec)), + WithSources(map[string]source.FeatureSource{fake.Name: source.GetFeatureSource(fake.Name)}), + ) + output, err := validator.Execute(ctx) + + So(err, ShouldBeNil) + So(output, ShouldEqual, expectedOutput) + }) + + Convey("With multiple compatibility sets", t, func() { + spec := &compatv1alpha1.Spec{ + Version: compatv1alpha1.Version, + Compatibilties: []compatv1alpha1.Compatibility{ + { + Tag: "prefered", + Weight: 90, + Description: "Fake compatibility 1", + Rules: []v1alpha1.Rule{ + { + Name: "fake_1", + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.attribute", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "attr_1": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + }, + }, + }, + }, + }, + }, + { + Tag: "fallback", + Weight: 40, + Description: "Fake compatibility 2", + Rules: []v1alpha1.Rule{ + { + Name: "fake_1", + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.attribute", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "attr_2": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + }, + }, + }, + }, + }, + }, + }, + } + + expectedOutput := []*CompatibilityStatus{ + { + Tag: "prefered", + Weight: 90, + Description: "Fake compatibility 1", + Rules: []ProcessedRuleStatus{ + { + Name: "fake_1", + IsMatch: false, + MatchedExpressions: []MatchedExpression{ + { + Feature: "fake.attribute", + Name: "attr_1", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + MatcherType: MatchExpressionType, + IsMatch: false, + }, + }, + }, + }, + }, + { + Tag: "fallback", + Weight: 40, + Description: "Fake compatibility 2", + Rules: []ProcessedRuleStatus{ + { + Name: "fake_1", + IsMatch: true, + MatchedExpressions: []MatchedExpression{ + { + Feature: "fake.attribute", + Name: "attr_2", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + MatcherType: MatchExpressionType, + IsMatch: true, + }, + }, + }, + }, + }, + } + + validator := New( + WithArgs(&Args{}), + WithArtifactClient(newMock(ctx, spec)), + WithSources(map[string]source.FeatureSource{fake.Name: source.GetFeatureSource(fake.Name)}), + ) + output, err := validator.Execute(ctx) + + So(err, ShouldBeNil) + So(output, ShouldEqual, expectedOutput) + }) + + Convey("With compatibility sets filtered out by tags", t, func() { + spec := &compatv1alpha1.Spec{ + Version: compatv1alpha1.Version, + Compatibilties: []compatv1alpha1.Compatibility{ + { + Tag: "prefered", + Weight: 90, + Description: "Fake compatibility 1", + Rules: []v1alpha1.Rule{ + { + Name: "fake_1", + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.attribute", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "attr_1": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + }, + }, + }, + }, + }, + }, + { + Tag: "fallback", + Weight: 40, + Description: "Fake compatibility 2", + Rules: []v1alpha1.Rule{ + { + Name: "fake_1", + MatchFeatures: v1alpha1.FeatureMatcher{ + { + Feature: "fake.attribute", + MatchExpressions: &v1alpha1.MatchExpressionSet{ + "attr_2": &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + }, + }, + }, + }, + }, + }, + }, + } + + expectedOutput := []*CompatibilityStatus{ + { + Tag: "prefered", + Weight: 90, + Description: "Fake compatibility 1", + Rules: []ProcessedRuleStatus{ + { + Name: "fake_1", + IsMatch: false, + MatchedExpressions: []MatchedExpression{ + { + Feature: "fake.attribute", + Name: "attr_1", + Expression: &v1alpha1.MatchExpression{Op: v1alpha1.MatchIn, Value: v1alpha1.MatchValue{"false"}}, + MatcherType: MatchExpressionType, + IsMatch: false, + }, + }, + }, + }, + }, + } + + validator := New( + WithArgs(&Args{ + Tags: []string{"prefered"}, + }), + WithArtifactClient(newMock(ctx, spec)), + WithSources(map[string]source.FeatureSource{fake.Name: source.GetFeatureSource(fake.Name)}), + ) + output, err := validator.Execute(ctx) + + So(err, ShouldBeNil) + So(output, ShouldEqual, expectedOutput) + }) +} + +func newMock(ctx context.Context, result *compatv1alpha1.Spec) *artifactcli.MockArtifactClient { + artifactClient := &artifactcli.MockArtifactClient{} + artifactClient.On("FetchCompatibilitySpec", ctx).Return(result, nil) + return artifactClient +} diff --git a/pkg/client-nfd/compat/node-validator/status.go b/pkg/client-nfd/compat/node-validator/status.go new file mode 100644 index 000000000..68d92e041 --- /dev/null +++ b/pkg/client-nfd/compat/node-validator/status.go @@ -0,0 +1,89 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package nodevalidator + +import ( + compatv1alpha1 "sigs.k8s.io/node-feature-discovery/api/image-compatibility/v1alpha1" + nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" +) + +// MatcherType represents a type of the used matcher. +type MatcherType string + +const ( + // MatchExpressionType represents a matchExpression type. + MatchExpressionType MatcherType = "matchExpression" + // MatchNameType represents a matchName type. + MatchNameType MatcherType = "matchName" +) + +// CompatibilityStatus represents the state of +// feature matching between the image and the host. +type CompatibilityStatus struct { + // Rules contain information about the matching status + // of all Node Feature Rules. + Rules []ProcessedRuleStatus `json:"rules"` + // Description of the compatibility set. + Description string `json:"description,omitempty"` + // Weight provides information about the priority of the compatibility set. + Weight int `json:"weight,omitempty"` + // Tag provides information about the tag assigned to the compatibility set. + Tag string `json:"tag,omitempty"` +} + +func newCompatibilityStatus(c *compatv1alpha1.Compatibility) CompatibilityStatus { + cs := CompatibilityStatus{ + Description: c.Description, + Weight: c.Weight, + Tag: c.Tag, + } + + return cs +} + +// ProcessedRuleStatus provides information whether the expressions succeeded on the host. +type ProcessedRuleStatus struct { + // Name of the rule. + Name string `json:"name"` + // IsMatch provides information if the rule matches with the host. + IsMatch bool `json:"isMatch"` + + // MatchedExpressions represents the expressions that succeed on the host. + MatchedExpressions []MatchedExpression `json:"matchedExpressions,omitempty"` + // MatchAny represents an array of logical OR conditions between MatchedExpressions entries. + MatchedAny []MatchAnyElem `json:"matchedAny,omitempty"` +} + +// MatchAnyElem represents a single object of MatchAny that contains MatchedExpression entries. +type MatchAnyElem struct { + // MatchedExpressions contains MatchedExpression entries. + MatchedExpressions []MatchedExpression `json:"matchedExpressions"` +} + +// MatchedExpression represent all details about the expression that succeeded on the host. +type MatchedExpression struct { + // Feature which is available to be evaluated on the host. + Feature string `json:"feature"` + // Name of the element. + Name string `json:"name"` + // Expression represents the expression provided by users. + Expression *nfdv1alpha1.MatchExpression `json:"expression"` + // MatcherType represents the matcher type, e.g. MatchExpression, MatchName. + MatcherType MatcherType `json:"matcherType"` + // IsMatch provides information whether the expression suceeded on the host. + IsMatch bool `json:"isMatch"` +} diff --git a/pkg/kubectl-nfd/dryrun.go b/pkg/kubectl-nfd/dryrun.go index ec06a3c35..fdca04d88 100644 --- a/pkg/kubectl-nfd/dryrun.go +++ b/pkg/kubectl-nfd/dryrun.go @@ -70,7 +70,7 @@ func processNodeFeatureRule(nodeFeatureRule nfdv1alpha1.NodeFeatureRule, nodeFea for _, rule := range nodeFeatureRule.Spec.Rules { fmt.Println("Processing rule: ", rule.Name) - ruleOut, err := nodefeaturerule.Execute(&rule, &nodeFeature.Features) + ruleOut, err := nodefeaturerule.Execute(&rule, &nodeFeature.Features, true) if err != nil { errs = append(errs, fmt.Errorf("failed to process rule: %q - %w", rule.Name, err)) continue diff --git a/pkg/nfd-master/nfd-master.go b/pkg/nfd-master/nfd-master.go index 0c2625c0f..990ef380b 100644 --- a/pkg/nfd-master/nfd-master.go +++ b/pkg/nfd-master/nfd-master.go @@ -794,7 +794,7 @@ func (m *nfdMaster) nfdAPIUpdateNodeFeatureGroup(nfdClient nfdclientset.Interfac nodeGroupValidator := make(map[string]bool) for _, rule := range nodeFeatureGroup.Spec.Rules { for _, feature := range nodeFeaturesList { - match, err := nodefeaturerule.ExecuteGroupRule(&rule, &feature.Spec.Features) + match, err := nodefeaturerule.ExecuteGroupRule(&rule, &feature.Spec.Features, true) if err != nil { klog.ErrorS(err, "failed to evaluate rule", "ruleName", rule.Name) continue @@ -1018,7 +1018,7 @@ func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha klog.InfoS("executing NodeFeatureRule", "nodefeaturerule", klog.KObj(spec), "nodeName", nodeName) } for _, rule := range spec.Spec.Rules { - ruleOut, err := nodefeaturerule.Execute(&rule, features) + ruleOut, err := nodefeaturerule.Execute(&rule, features, true) if err != nil { klog.ErrorS(err, "failed to process rule", "ruleName", rule.Name, "nodefeaturerule", klog.KObj(spec), "nodeName", nodeName) nfrProcessingErrors.Inc() diff --git a/source/custom/custom.go b/source/custom/custom.go index 0e422ec2e..5c2af0139 100644 --- a/source/custom/custom.go +++ b/source/custom/custom.go @@ -93,7 +93,7 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) { klog.V(2).InfoS("resolving custom features", "configuration", utils.DelayedDumper(allFeatureConfig)) // Iterate over features for _, rule := range allFeatureConfig { - ruleOut, err := nodefeaturerule.Execute(&rule, features) + ruleOut, err := nodefeaturerule.Execute(&rule, features, true) if err != nil { klog.ErrorS(err, "failed to execute rule") continue