apiVersion: nfd.k8s-sigs.io/v1alpha1
kind: NodeFeatureRule
metadata:
  name: my-rule
spec:
  rules:
    # The following feature demonstrates the capabilities of the matchFeatures and
    # matchAny matchers.
    - name: "my feature rule"
      taints:
        - effect: PreferNoSchedule
          key: "feature.node.kubernetes.io/special-node"
          value: "true"
        - effect: NoExecute
          key: "feature.node.kubernetes.io/dedicated-node"
      labels:
        "my-complex-feature": "my-value"
      # matchFeatures implements a logical AND over feature matchers.
      matchFeatures:
        - feature: cpu.cpuid
          matchExpressions:
            AVX512F: {op: Exists}
        - feature: cpu.cstate
          matchExpressions:
            enabled: {op: IsTrue}
        - feature: cpu.pstate
          matchExpressions:
            no_turbo: {op: IsFalse}
            scaling_governor: {op: In, value: ["performance"]}
        - feature: cpu.rdt
          matchExpressions:
            RDTL3CA: {op: Exists}
        - feature: cpu.sst
          matchExpressions:
            bf.enabled: {op: IsTrue}
        - feature: cpu.topology
          matchExpressions:
            hardware_multithreading: {op: IsFalse}

        - feature: kernel.config
          matchExpressions:
            X86: {op: Exists}
            LSM: {op: InRegexp, value: ["apparmor"]}
        - feature: kernel.loadedmodule
          matchExpressions:
            e1000e: {op: Exists}
        - feature: kernel.selinux
          matchExpressions:
            enabled: {op: IsFalse}
        - feature: kernel.version
          matchExpressions:
            major: {op: In, value: ["5"]}
            minor: {op: Gt, value: ["10"]}

        - feature: storage.block
          matchExpressions:
            rotational: {op: In, value: ["0"]}
            dax: {op: In, value: ["0"]}

        - feature: network.device
          matchExpressions:
            operstate: {op: In, value: ["up"]}
            speed: {op: Gt, value: ["100"]}

        - feature: memory.numa
          matchExpressions:
            node_count: {op: Gt, value: ["2"]}
        - feature: memory.nv
          matchExpressions:
            devtype: {op: In, value: ["nd_dax"]}
            mode: {op: In, value: ["memory"]}

        - feature: system.osrelease
          matchExpressions:
            ID: {op: In, value: ["fedora", "centos"]}
        - feature: system.name
          matchExpressions:
            nodename: {op: InRegexp, value: ["^worker-X"]}

        - feature: local.label
          matchExpressions:
            custom-feature-knob: {op: Gt, value: ["100"]}

      # matchAny implements a logical IF over all listed matchers (i.e. at
      # least one must match)
      matchAny:
        - matchFeatures:
          - feature: pci.device
            matchExpressions:
              vendor: {op: In, value: ["8086"]}
              class: {op: In, value: ["0200"]}
          - feature: usb.device
            matchExpressions:
              vendor: {op: In, value: ["8086"]}
              class: {op: In, value: ["02"]}

    - name: "avx wildcard rule"
      labels:
        "my-avx-feature": "true"
      matchFeatures:
        - feature: cpu.cpuid
          matchName: {op: InRegexp, value: ["^AVX512"]}

    # The following features demonstreate label templating capabilities
    - name: "my system template feature"
      labelsTemplate: |
        {{ range .system.osrelease }}my-system-feature.{{ .Name }}={{ .Value }}
        {{ end }}
      matchFeatures:
        - feature: system.osrelease
          matchExpressions:
            ID: {op: InRegexp, value: ["^open.*"]}
            VERSION_ID.major: {op: In, value: ["13", "15"]}

    - name: "my pci template feature"
      labelsTemplate: |
        {{ range .pci.device }}my-pci-device.{{ .class }}-{{ .device }}=with-cpuid
        {{ end }}
      matchFeatures:
        - feature: pci.device
          matchExpressions:
            class: {op: InRegexp, value: ["^06"]}
            vendor: {op: In, value: ["8086"]}
        - feature: cpu.cpuid
          matchExpressions:
            AVX: {op: Exists}

    # The following examples demonstrate vars field and back-referencing
    # previous labels and vars
    - name: "my dummy kernel rule"
      labels:
        "my.kernel.feature": "true"
      matchFeatures:
        - feature: kernel.version
          matchExpressions:
            major: {op: Gt, value: ["2"]}

    - name: "my dummy rule with no labels"
      vars:
        "my.dummy.var": "1"
      matchFeatures:
        - feature: cpu.cpuid
          matchExpressions: {}

    - name: "my rule using backrefs"
      labels:
        "my.backref.feature": "true"
      matchFeatures:
        - feature: rule.matched
          matchExpressions:
            my.kernel.feature: {op: IsTrue}
            my.dummy.var: {op: Gt, value: ["0"]}

    - name: "kconfig template rule"
      labelsTemplate: |
        {{ range .kernel.config }}kconfig-{{ .Name }}={{ .Value }}
        {{ end }}
      matchFeatures:
        - feature: kernel.config
          matchName: {op: In, value: ["SWAP", "X86", "ARM"]}
