diff --git a/deployment/base/nfd-crds/nodefeaturerule-crd.yaml b/deployment/base/nfd-crds/nodefeaturerule-crd.yaml index 519991bb1a..cd9b48bf46 100644 --- a/deployment/base/nfd-crds/nodefeaturerule-crd.yaml +++ b/deployment/base/nfd-crds/nodefeaturerule-crd.yaml @@ -197,6 +197,12 @@ spec: more complex rule hierarchies, without exposing intermediary output values as labels. type: object + varsTemplate: + description: VarsTemplate specifies a template to expand for + dynamically generating multiple variables. Data (after template + expansion) must be keys with an optional value ([=]) + separated by newlines. + type: string required: - name type: object diff --git a/deployment/helm/node-feature-discovery/manifests/nodefeaturerule-crd.yaml b/deployment/helm/node-feature-discovery/manifests/nodefeaturerule-crd.yaml index 519991bb1a..cd9b48bf46 100644 --- a/deployment/helm/node-feature-discovery/manifests/nodefeaturerule-crd.yaml +++ b/deployment/helm/node-feature-discovery/manifests/nodefeaturerule-crd.yaml @@ -197,6 +197,12 @@ spec: more complex rule hierarchies, without exposing intermediary output values as labels. type: object + varsTemplate: + description: VarsTemplate specifies a template to expand for + dynamically generating multiple variables. Data (after template + expansion) must be keys with an optional value ([=]) + separated by newlines. + type: string required: - name type: object diff --git a/pkg/apis/nfd/v1alpha1/rule.go b/pkg/apis/nfd/v1alpha1/rule.go index 0060e0e5f4..1bee62d4a6 100644 --- a/pkg/apis/nfd/v1alpha1/rule.go +++ b/pkg/apis/nfd/v1alpha1/rule.go @@ -57,7 +57,9 @@ func (r *Rule) Execute(features feature.Features) (RuleOutput, error) { if err := r.executeLabelsTemplate(m, labels); err != nil { return RuleOutput{}, err } - + if err := r.executeVarsTemplate(m, vars); err != nil { + return RuleOutput{}, err + } } } if !matched { @@ -75,6 +77,9 @@ func (r *Rule) Execute(features feature.Features) (RuleOutput, error) { if err := r.executeLabelsTemplate(m, labels); err != nil { return RuleOutput{}, err } + if err := r.executeVarsTemplate(m, vars); err != nil { + return RuleOutput{}, err + } } } @@ -111,6 +116,28 @@ func (r *Rule) executeLabelsTemplate(in matchedFeatures, out map[string]string) return nil } +func (r *Rule) executeVarsTemplate(in matchedFeatures, out map[string]string) error { + if r.VarsTemplate == "" { + return nil + } + if r.varsTemplate == nil { + t, err := newTemplateHelper(r.VarsTemplate) + if err != nil { + return err + } + r.varsTemplate = t + } + + vars, err := r.varsTemplate.expandMap(in) + if err != nil { + return err + } + for k, v := range vars { + out[k] = v + } + return nil +} + type matchedFeatures map[string]domainMatchedFeatures type domainMatchedFeatures map[string]interface{} diff --git a/pkg/apis/nfd/v1alpha1/types.go b/pkg/apis/nfd/v1alpha1/types.go index 84b3d045ad..d7bf89e7df 100644 --- a/pkg/apis/nfd/v1alpha1/types.go +++ b/pkg/apis/nfd/v1alpha1/types.go @@ -72,6 +72,12 @@ type Rule struct { // +optional Vars map[string]string `json:"vars"` + // VarsTemplate specifies a template to expand for dynamically generating + // multiple variables. Data (after template expansion) must be keys with an + // optional value ([=]) separated by newlines. + // +optional + VarsTemplate string `json:"varsTemplate"` + // MatchFeatures specifies a set of matcher terms all of which must match. // +optional MatchFeatures FeatureMatcher `json:"matchFeatures"`