Skip to content

Commit

Permalink
pkg/apis/nfd: support templating of "vars"
Browse files Browse the repository at this point in the history
Support templating of var names in a similar manner as labels. Add
support for a new 'varsTemplate' field to the feature rule spec which is
treated similarly to the 'labelsTemplate' field. The value of the field
is processed through the golang "text/template" template engine and the
expanded value must contain variables in a raw <key>[=<value>] format
(where 'value' defaults to "true"), separated by
newlines i.e.:

  - name: <rule-name>
    varsTemplate: |
      <label-1>[=<value-1>]
      <label-2>[=<value-2>]
      ...

Similar rules as for 'labelsTemplate' apply, i.e.

1. In case of matchAny is specified, the template is executed separately
   against each individual matchFeatures matcher.
2. 'vars' field has priority over 'varsTemplate'
  • Loading branch information
marquiz committed Nov 24, 2021
1 parent db6e6be commit a302045
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
6 changes: 6 additions & 0 deletions deployment/base/nfd-crds/nodefeaturerule-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 (<key>[=<value>])
separated by newlines.
type: string
required:
- name
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (<key>[=<value>])
separated by newlines.
type: string
required:
- name
type: object
Expand Down
29 changes: 28 additions & 1 deletion pkg/apis/nfd/v1alpha1/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,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 {
Expand All @@ -78,6 +80,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
}
}
}

Expand Down Expand Up @@ -117,6 +122,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{}
Expand Down
15 changes: 15 additions & 0 deletions pkg/apis/nfd/v1alpha1/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@ label-2=
{{range .domain_1.vf_1}}vf-{{.Name}}=vf-{{.Value}}
{{end}}
{{range .domain_1.if_1}}if-{{index . "attr-1"}}_{{index . "attr-2"}}=present
{{end}}`,
Vars: map[string]string{"var-1": "var-val-1"},
VarsTemplate: `
var-1=value-will-be-overridden-by-vars
var-2=
{{range .domain_1.kf_1}}kf-{{.Name}}
{{end}}`,
MatchFeatures: FeatureMatcher{
FeatureMatcherTerm{
Expand Down Expand Up @@ -297,8 +303,17 @@ label-2=
"if-1_val-2": "present",
"if-10_val-20": "present",
}
expectedVars := map[string]string{
"var-1": "var-val-1",
"var-2": "",
// From template
"kf-key-a": "true",
"kf-key-c": "true",
"kf-foo": "true",
}

m, err := r1.Execute(f)
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")
}
6 changes: 6 additions & 0 deletions pkg/apis/nfd/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (<key>[=<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"`
Expand Down

0 comments on commit a302045

Please sign in to comment.