-
Notifications
You must be signed in to change notification settings - Fork 246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Templating of custom label names #550
Templating of custom label names #550
Conversation
Skipping CI for Draft Pull Request. |
730517e
to
18ef328
Compare
18ef328
to
19bad85
Compare
19bad85
to
0e514f7
Compare
0e514f7
to
afa7b39
Compare
afa7b39
to
7d02b9e
Compare
4802ab4
to
c26ba31
Compare
c26ba31
to
af65f6c
Compare
af65f6c
to
d4defac
Compare
3443f91
to
9a65fe2
Compare
e059df0
to
68f69a5
Compare
68f69a5
to
c0779a1
Compare
/unhold |
c0779a1
to
780bcc5
Compare
Implement a private helper type (nameTemplateHelper) for handling (executing and caching) of templated names. DeepCopy methods are manually implemented as controller-gen is not able to help with that.
780bcc5
to
fd34619
Compare
/test all |
/assign |
I am getting [eduardo@fedora node-feature-discovery]$ kubectl apply -f deployment/base/nfd-crds/cr-sample.yaml
error: error validating "deployment/base/nfd-crds/cr-sample.yaml": error validating data: [ValidationError(NodeFeatureRule.spec.rules[2].matchFeatures[0]): unknown field "cpu.cpuid" in io.k8s-sigs.nfd.v1alpha1.NodeFeatureRule.spec.rules.matchFeatures, ValidationError(NodeFeatureRule.spec.rules[2].matchFeatures[0].matchExpressions.vendor): invalid type for io.k8s-sigs.nfd.v1alpha1.NodeFeatureRule.spec.rules.matchFeatures.matchExpressions: got "array", expected "map"]; if you choose to ignore these errors, turn validation off with --validate=false aside from that NFD runs as expected |
@ArangoGutierrez looks like somewhere a missing colon |
fd34619
to
d5d8c7f
Compare
Support templating of label names in feature rules. It is available both in NodeFeatureRule CRs and in custom rule configuration of nfd-worker. This patch adds a new 'labelsTemplate' field to the rule spec, making it possible to dynamically generate multiple labels per rule based on the matched features. The feature relies on the golang "text/template" package. When expanded, the template must contain labels in a raw <key>[=<value>] format (where 'value' defaults to "true"), separated by newlines i.e.: - name: <rule-name> labelsTemplate: | <label-1>[=<value-1>] <label-2>[=<value-2>] ... All the matched features of 'matchFeatures' directives are available for templating engine in a nested data structure that can be described in yaml as: . <domain-1>: <key-feature-1>: - Name: <matched-key> - ... <value-feature-1: - Name: <matched-key> Value: <matched-value> - ... <instance-feature-1>: - <attribute-1-name>: <attribute-1-value> <attribute-2-name>: <attribute-2-value> ... - ... <domain-2>: ... That is, the per-feature data available for matching depends on the type of feature that was matched: - "key features": only 'Name' is available - "value features": 'Name' and 'Value' can be used - "instance features": all attributes of the matched instance are available NOTE: In case of matchAny is specified, the template is executed separately against each individual matchFeatures matcher and the eventual set of labels is a superset of all these expansions. Consider the following: - name: <name> labelsTemplate: <template> matchAny: - matchFeatures: <matcher#1> - matchFeatures: <matcher#2> matchFeatures: <matcher#3> In the example above (assuming the overall result is a match) the template would be executed on matcher#1 and/or matcher#2 (depending on whether both or only one of them match), and finally on matcher#3, and all the labels from these separate expansions would be created (i.e. the end result would be a union of all the individual expansions). NOTE 2: The 'labels' field has priority over 'labelsTemplate', i.e. labels specified in the 'labels' field will override any labels originating from the 'labelsTemplate' field. A special case of an empty match expression set matches everything (i.e. matches/returns all existing keys/values). This makes it simpler to write templates that run over all values. Also, makes it possible to later implement support for templates that run over all _keys_ of a feature. Some example configurations: - name: "my-pci-template-features" labelsTemplate: | {{ range .pci.device }}intel-{{ .class }}-{{ .device }}=present {{ end }} matchFeatures: - feature: pci.device matchExpressions: class: {op: InRegexp, value: ["^06"]} vendor: ["8086"] - name: "my-system-template-features" labelsTemplate: | {{ range .system.osrelease }}system-{{ .Name }}={{ .Value }} {{ end }} matchFeatures: - feature: system.osRelease matchExpressions: ID: {op: Exists} VERSION_ID.major: {op: Exists} Imaginative template pipelines are possible, of course, but care must be taken in order to produce understandable and maintainable rule sets.
d5d8c7f
to
c8d7366
Compare
Thanks @ArangoGutierrez for testing! Indeed there was a mistake in the cr-sample 🙄 Should be fixed, now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feature.node.kubernetes.io/my-pci-device.0600-1237=with-cpuid
feature.node.kubernetes.io/my-pci-device.0601-7000=with-cpuid
feature.node.kubernetes.io/my-pci-device.0680-7113=with-cpuid
It works as expected now
/lgtm
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ArangoGutierrez, marquiz The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Support templating of label names in feature rules. It is available both
in NodeFeatureRule CRs and in custom rule configuration of nfd-worker.
This patch adds a new 'labelsTemplate' field to the rule spec, making it
possible to dynamically generate multiple labels per rule based on the
matched features. The feature relies on the golang "text/template"
package. When expanded, the template must contain labels in a raw
[=] format (where 'value' defaults to "true"), separated by
newlines i.e.:
All the matched features of 'matchFeatures' directives are available for
templating engine in a nested data structure that can be described in
yaml as:
That is, the per-feature data available for matching depends on the type
of feature that was matched:
available
NOTE: In case of matchAny is specified, the template is executed
separately against each individual matchFeatures matcher and the
eventual set of labels is a superset of all these expansions. Consider
the following:
In the example above (assuming the overall result is a match) the
template would be executed on matcher#1 and/or matcher#2 (depending on
whether both or only one of them match), and finally on matcher#3, and
all the labels from these separate expansions would be created (i.e. the
end result would be a union of all the individual expansions).
NOTE 2: The 'labels' field has priority over 'labelsTemplate', i.e.
labels specified in the 'labels' field will override any labels
originating from the 'labelsTemplate' field.
A special case of an empty match expression set matches everything (i.e.
matches/returns all existing keys/values). This makes it simpler to
write templates that run over all values. Also, makes it possible to
later implement support for templates that run over all keys of a
feature.
Some example configurations:
Imaginative template pipelines are possible, of course, but care must be
taken in order to produce understandable and maintainable rule sets.