From e936b0f6602eb1c186574e45fcfce21b57a3b6f3 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakivskyy Date: Fri, 4 Oct 2024 14:37:47 +0300 Subject: [PATCH] nfd-master: Add status for NodeFeatureRule CRD Signed-off-by: Oleg Zhurakivskyy --- .../clientset/versioned/clientset.go | 2 +- .../versioned/fake/clientset_generated.go | 2 +- api/generated/clientset/versioned/fake/doc.go | 2 +- .../clientset/versioned/fake/register.go | 2 +- .../clientset/versioned/scheme/doc.go | 2 +- .../clientset/versioned/scheme/register.go | 2 +- .../versioned/typed/nfd/v1alpha1/doc.go | 2 +- .../versioned/typed/nfd/v1alpha1/fake/doc.go | 2 +- .../nfd/v1alpha1/fake/fake_nfd_client.go | 2 +- .../nfd/v1alpha1/fake/fake_nodefeature.go | 2 +- .../v1alpha1/fake/fake_nodefeaturegroup.go | 2 +- .../nfd/v1alpha1/fake/fake_nodefeaturerule.go | 2 +- .../typed/nfd/v1alpha1/generated_expansion.go | 2 +- .../typed/nfd/v1alpha1/nfd_client.go | 2 +- .../typed/nfd/v1alpha1/nodefeature.go | 2 +- .../typed/nfd/v1alpha1/nodefeaturegroup.go | 2 +- .../typed/nfd/v1alpha1/nodefeaturerule.go | 4 +- .../informers/externalversions/factory.go | 2 +- .../informers/externalversions/generic.go | 2 +- .../internalinterfaces/factory_interfaces.go | 2 +- .../externalversions/nfd/interface.go | 2 +- .../nfd/v1alpha1/interface.go | 2 +- .../nfd/v1alpha1/nodefeature.go | 2 +- .../nfd/v1alpha1/nodefeaturegroup.go | 2 +- .../nfd/v1alpha1/nodefeaturerule.go | 2 +- .../nfd/v1alpha1/expansion_generated.go | 2 +- .../listers/nfd/v1alpha1/nodefeature.go | 2 +- .../listers/nfd/v1alpha1/nodefeaturegroup.go | 2 +- .../listers/nfd/v1alpha1/nodefeaturerule.go | 2 +- api/nfd/v1alpha1/types.go | 25 +++++ api/nfd/v1alpha1/zz_generated.deepcopy.go | 80 +++++++++++++++- deployment/base/nfd-crds/nfd-api-crds.yaml | 22 +++++ .../crds/nfd-api-crds.yaml | 22 +++++ pkg/apis/nfd/nodefeaturerule/rule.go | 2 + pkg/nfd-master/nfd-master.go | 95 ++++++++++++++++++- 35 files changed, 271 insertions(+), 35 deletions(-) diff --git a/api/generated/clientset/versioned/clientset.go b/api/generated/clientset/versioned/clientset.go index 44f129201..72ec0f5e1 100644 --- a/api/generated/clientset/versioned/clientset.go +++ b/api/generated/clientset/versioned/clientset.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/fake/clientset_generated.go b/api/generated/clientset/versioned/fake/clientset_generated.go index 635125b6a..aff6b01f4 100644 --- a/api/generated/clientset/versioned/fake/clientset_generated.go +++ b/api/generated/clientset/versioned/fake/clientset_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/fake/doc.go b/api/generated/clientset/versioned/fake/doc.go index c8342d4bd..ac8c1ec9e 100644 --- a/api/generated/clientset/versioned/fake/doc.go +++ b/api/generated/clientset/versioned/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/fake/register.go b/api/generated/clientset/versioned/fake/register.go index 3c4d45a31..4b8db01ff 100644 --- a/api/generated/clientset/versioned/fake/register.go +++ b/api/generated/clientset/versioned/fake/register.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/scheme/doc.go b/api/generated/clientset/versioned/scheme/doc.go index 0fe2de913..9e531af56 100644 --- a/api/generated/clientset/versioned/scheme/doc.go +++ b/api/generated/clientset/versioned/scheme/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/scheme/register.go b/api/generated/clientset/versioned/scheme/register.go index f822ef608..fbdcdfca9 100644 --- a/api/generated/clientset/versioned/scheme/register.go +++ b/api/generated/clientset/versioned/scheme/register.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/doc.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/doc.go index ecc546221..71824ed54 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/doc.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/doc.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/doc.go index d9bd9db27..18420d452 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/doc.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. 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 e84e6e3e1..5ce0c4ad3 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 @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. 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 a7356c9c8..efe9f63bc 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 @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. 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 cc4ae1070..94e2ea890 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 @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. 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 6986116dc..515a02733 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 @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/generated_expansion.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/generated_expansion.go index 02d3e3518..2e25d3c7c 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/generated_expansion.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. 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 4776a6c83..1529f40c6 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeature.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeature.go index 70b854046..ce5125a4c 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeature.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeature.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturegroup.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturegroup.go index cdee1eb7b..ab226adf2 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturegroup.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturegroup.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go index cf0719ad1..926707523 100644 --- a/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go +++ b/api/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. @@ -39,6 +39,8 @@ type NodeFeatureRulesGetter interface { type NodeFeatureRuleInterface interface { 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) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(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) (*nfdv1alpha1.NodeFeatureRule, error) diff --git a/api/generated/informers/externalversions/factory.go b/api/generated/informers/externalversions/factory.go index 0bc947593..0174d7fd4 100644 --- a/api/generated/informers/externalversions/factory.go +++ b/api/generated/informers/externalversions/factory.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/informers/externalversions/generic.go b/api/generated/informers/externalversions/generic.go index 1422eb95c..45f55ec36 100644 --- a/api/generated/informers/externalversions/generic.go +++ b/api/generated/informers/externalversions/generic.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/informers/externalversions/internalinterfaces/factory_interfaces.go b/api/generated/informers/externalversions/internalinterfaces/factory_interfaces.go index 7f1153741..619766590 100644 --- a/api/generated/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/api/generated/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/informers/externalversions/nfd/interface.go b/api/generated/informers/externalversions/nfd/interface.go index 8c6835831..b83e407ce 100644 --- a/api/generated/informers/externalversions/nfd/interface.go +++ b/api/generated/informers/externalversions/nfd/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/informers/externalversions/nfd/v1alpha1/interface.go b/api/generated/informers/externalversions/nfd/v1alpha1/interface.go index ea861a472..47163ad89 100644 --- a/api/generated/informers/externalversions/nfd/v1alpha1/interface.go +++ b/api/generated/informers/externalversions/nfd/v1alpha1/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeature.go b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeature.go index 34e14e434..4341709a7 100644 --- a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeature.go +++ b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeature.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturegroup.go b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturegroup.go index 30559f5ce..301123607 100644 --- a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturegroup.go +++ b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturegroup.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go index 37ad15dce..bc83a1480 100644 --- a/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go +++ b/api/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/listers/nfd/v1alpha1/expansion_generated.go b/api/generated/listers/nfd/v1alpha1/expansion_generated.go index 5890048ee..943ba3d55 100644 --- a/api/generated/listers/nfd/v1alpha1/expansion_generated.go +++ b/api/generated/listers/nfd/v1alpha1/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/listers/nfd/v1alpha1/nodefeature.go b/api/generated/listers/nfd/v1alpha1/nodefeature.go index f670b6e8a..348d294a2 100644 --- a/api/generated/listers/nfd/v1alpha1/nodefeature.go +++ b/api/generated/listers/nfd/v1alpha1/nodefeature.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/listers/nfd/v1alpha1/nodefeaturegroup.go b/api/generated/listers/nfd/v1alpha1/nodefeaturegroup.go index a59e53684..1f38d8878 100644 --- a/api/generated/listers/nfd/v1alpha1/nodefeaturegroup.go +++ b/api/generated/listers/nfd/v1alpha1/nodefeaturegroup.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/generated/listers/nfd/v1alpha1/nodefeaturerule.go b/api/generated/listers/nfd/v1alpha1/nodefeaturerule.go index 77cdcf0cb..4faea9b70 100644 --- a/api/generated/listers/nfd/v1alpha1/nodefeaturerule.go +++ b/api/generated/listers/nfd/v1alpha1/nodefeaturerule.go @@ -1,5 +1,5 @@ /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. diff --git a/api/nfd/v1alpha1/types.go b/api/nfd/v1alpha1/types.go index 67dfc1b06..fe3a7e2c5 100644 --- a/api/nfd/v1alpha1/types.go +++ b/api/nfd/v1alpha1/types.go @@ -111,6 +111,7 @@ type NodeFeatureRuleList struct { // customization of node objects, such as node labeling. // +kubebuilder:object:root=true // +kubebuilder:resource:scope=Cluster,shortName=nfr +// +kubebuilder:subresource:status // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +genclient // +genclient:nonNamespaced @@ -120,6 +121,8 @@ type NodeFeatureRule struct { // Spec defines the rules to be evaluated. Spec NodeFeatureRuleSpec `json:"spec"` + // +optional + Status NodeFeatureRuleStatus `json:"status,omitempty"` } // NodeFeatureRuleSpec describes a NodeFeatureRule. @@ -128,6 +131,28 @@ type NodeFeatureRuleSpec struct { Rules []Rule `json:"rules"` } +// NodeFeatureRuleStatus represents the status of a NodeFeatureRule +type NodeFeatureRuleStatus struct { + // +optional + Rules []RuleStatus `json:"rules,omitempty"` +} + +// RuleStatus contains information on matched rules and nodes +type RuleStatus struct { + Name string `json:"name"` + MatchedNodes []string `json:"matchedNodes"` +} + +// NodeFeatureRuleStatusList contains a list of NodeFeatureRuleStatus objects. +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type NodeFeatureRuleStatusList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NodeFeatureRuleStatus `json:"items"` +} + // NodeFeatureGroup resource holds Node pools by featureGroup // +kubebuilder:object:root=true // +kubebuilder:resource:scope=Namespaced,shortName=nfg diff --git a/api/nfd/v1alpha1/zz_generated.deepcopy.go b/api/nfd/v1alpha1/zz_generated.deepcopy.go index 491d9866c..792b58716 100644 --- a/api/nfd/v1alpha1/zz_generated.deepcopy.go +++ b/api/nfd/v1alpha1/zz_generated.deepcopy.go @@ -2,7 +2,7 @@ // +build !ignore_autogenerated /* -Copyright 2024 The Kubernetes Authors. +Copyright 2025 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. @@ -544,6 +544,7 @@ func (in *NodeFeatureRule) DeepCopyInto(out *NodeFeatureRule) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -621,6 +622,62 @@ func (in *NodeFeatureRuleSpec) DeepCopy() *NodeFeatureRuleSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureRuleStatus) DeepCopyInto(out *NodeFeatureRuleStatus) { + *out = *in + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]RuleStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRuleStatus. +func (in *NodeFeatureRuleStatus) DeepCopy() *NodeFeatureRuleStatus { + if in == nil { + return nil + } + out := new(NodeFeatureRuleStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureRuleStatusList) DeepCopyInto(out *NodeFeatureRuleStatusList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodeFeatureRuleStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRuleStatusList. +func (in *NodeFeatureRuleStatusList) DeepCopy() *NodeFeatureRuleStatusList { + if in == nil { + return nil + } + out := new(NodeFeatureRuleStatusList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeFeatureRuleStatusList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeFeatureSpec) DeepCopyInto(out *NodeFeatureSpec) { *out = *in @@ -709,3 +766,24 @@ func (in *Rule) DeepCopy() *Rule { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RuleStatus) DeepCopyInto(out *RuleStatus) { + *out = *in + if in.MatchedNodes != nil { + in, out := &in.MatchedNodes, &out.MatchedNodes + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuleStatus. +func (in *RuleStatus) DeepCopy() *RuleStatus { + if in == nil { + return nil + } + out := new(RuleStatus) + in.DeepCopyInto(out) + return out +} diff --git a/deployment/base/nfd-crds/nfd-api-crds.yaml b/deployment/base/nfd-crds/nfd-api-crds.yaml index 9f62da6f6..4278060e4 100644 --- a/deployment/base/nfd-crds/nfd-api-crds.yaml +++ b/deployment/base/nfd-crds/nfd-api-crds.yaml @@ -704,8 +704,30 @@ spec: required: - rules type: object + status: + description: NodeFeatureRuleStatus represents the status of a NodeFeatureRule + properties: + rules: + items: + description: RuleStatus contains information on matched rules and + nodes + properties: + matchedNodes: + items: + type: string + type: array + name: + type: string + required: + - matchedNodes + - name + type: object + type: array + type: object required: - spec type: object served: true storage: true + subresources: + status: {} 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 9f62da6f6..4278060e4 100644 --- a/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml +++ b/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml @@ -704,8 +704,30 @@ spec: required: - rules type: object + status: + description: NodeFeatureRuleStatus represents the status of a NodeFeatureRule + properties: + rules: + items: + description: RuleStatus contains information on matched rules and + nodes + properties: + matchedNodes: + items: + type: string + type: array + name: + type: string + required: + - matchedNodes + - name + type: object + type: array + type: object required: - spec type: object served: true storage: true + subresources: + status: {} diff --git a/pkg/apis/nfd/nodefeaturerule/rule.go b/pkg/apis/nfd/nodefeaturerule/rule.go index f243e67e7..0ebc90c1a 100644 --- a/pkg/apis/nfd/nodefeaturerule/rule.go +++ b/pkg/apis/nfd/nodefeaturerule/rule.go @@ -65,6 +65,7 @@ type RuleOutput struct { Vars map[string]string Taints []corev1.Taint MatchStatus *MatchStatus + Matched bool } // Execute the rule against a set of input features. @@ -143,6 +144,7 @@ func Execute(r *nfdv1alpha1.Rule, features *nfdv1alpha1.Features, failFast bool) ExtendedResources: maps.Clone(r.ExtendedResources), Taints: slices.Clone(r.Taints), MatchStatus: &matchStatus, + Matched: true, } klog.V(2).InfoS("rule matched", "ruleName", r.Name, "ruleOutput", utils.DelayedDumper(ret)) return ret, nil diff --git a/pkg/nfd-master/nfd-master.go b/pkg/nfd-master/nfd-master.go index 990ef380b..0e63ab395 100644 --- a/pkg/nfd-master/nfd-master.go +++ b/pkg/nfd-master/nfd-master.go @@ -633,6 +633,12 @@ func (m *nfdMaster) nfdAPIUpdateAllNodes() error { m.updaterPool.addNode(node.Name) } + err = m.updateRuleStatus() + if err != nil { + klog.ErrorS(err, "failed to update rule status") + return err + } + return nil } @@ -877,7 +883,7 @@ func (m *nfdMaster) refreshNodeFeatures(cli k8sclient.Interface, node *corev1.No labels = make(map[string]string) } - crLabels, crAnnotations, crExtendedResources, crTaints := m.processNodeFeatureRule(node.Name, features) + crLabels, crAnnotations, crExtendedResources, crTaints, _ := m.processNodeFeatureRule(node.Name, features) // Labels maps.Copy(labels, crLabels) @@ -988,9 +994,9 @@ func (m *nfdMaster) setTaints(cli k8sclient.Interface, taints []corev1.Taint, no return nil } -func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha1.Features) (Labels, Annotations, ExtendedResources, []corev1.Taint) { +func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha1.Features) (Labels, Annotations, ExtendedResources, []corev1.Taint, []*nfdv1alpha1.NodeFeatureRule) { if m.nfdController == nil { - return nil, nil, nil, nil + return nil, nil, nil, nil, nil } extendedResources := ExtendedResources{} @@ -1004,12 +1010,13 @@ func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha if err != nil { klog.ErrorS(err, "failed to list NodeFeatureRule resources") - return nil, nil, nil, nil + return nil, nil, nil, nil, nil } // Process all rule CRs processStart := time.Now() for _, spec := range ruleSpecs { + spec.Status.Rules = []nfdv1alpha1.RuleStatus{} t := time.Now() switch { case klog.V(3).Enabled(): @@ -1041,13 +1048,91 @@ func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha // Feed back rule output to features map for subsequent rules to match features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels) features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars) + + if ruleOut.Matched { + r := nfdv1alpha1.RuleStatus{ + Name: rule.Name, + MatchedNodes: []string{ + nodeName, + }, + } + spec.Status.Rules = append(spec.Status.Rules, r) + } } nfrProcessingTime.WithLabelValues(spec.Name, nodeName).Observe(time.Since(t).Seconds()) } processingTime := time.Since(processStart) klog.V(2).InfoS("processed NodeFeatureRule objects", "nodeName", nodeName, "objectCount", len(ruleSpecs), "duration", processingTime) - return labels, annotations, extendedResources, taints + return labels, annotations, extendedResources, taints, ruleSpecs +} + +func findRuleByName(ruleSpecs []*nfdv1alpha1.NodeFeatureRule, name string) *nfdv1alpha1.NodeFeatureRule { + var spec *nfdv1alpha1.NodeFeatureRule + for _, r := range ruleSpecs { + if r.Name == name { + spec = r + break + } + } + return spec +} + +func findStatusRuleByName(status *[]nfdv1alpha1.RuleStatus, name string) *nfdv1alpha1.RuleStatus { + var rule *nfdv1alpha1.RuleStatus + for _, r := range *status { + if r.Name == name { + rule = &r + break + } + } + return rule +} + +func (m *nfdMaster) updateRuleStatus() error { + nodes, err := getNodes(m.k8sClient) + if err != nil { + return err + } + + var ruleSpecs []*nfdv1alpha1.NodeFeatureRule + var outSpecs []*nfdv1alpha1.NodeFeatureRule + + for _, node := range nodes.Items { + nodeFeatures, err := m.getAndMergeNodeFeatures(node.Name) + if err != nil { + return fmt.Errorf("failed to merge NodeFeature objects for node %q: %w", node.Name, err) + } + + _, _, _, _, ruleSpecs = m.processNodeFeatureRule(node.Name, &nodeFeatures.Spec.Features) + } + + for _, spec := range ruleSpecs { + if len(spec.Status.Rules) > 0 { + s := findRuleByName(outSpecs, spec.Name) + if s != nil { + for _, r := range spec.Status.Rules { + s.Status.Rules = append(s.Status.Rules, r) + + sr := findStatusRuleByName(&s.Status.Rules, r.Name) + if sr != nil { + sr.MatchedNodes = append(sr.MatchedNodes, r.MatchedNodes...) + } + } + } else { + outSpecs = append(outSpecs, spec) + } + } + } + + for _, spec := range outSpecs { + _, err = m.nfdClient.NfdV1alpha1().NodeFeatureRules().Update(context.TODO(), spec, metav1.UpdateOptions{}) + if err != nil { + klog.ErrorS(err, "failed to update rule status", "nodefeaturerule", klog.KObj(spec)) + } + } + + return nil } // updateNodeObject ensures the Kubernetes node object is up to date,