We would like to configure node selectors withing kots-config.yaml

Hi Team,

Kind of a weird question about formatting, and how it translates here, but for some of our applications we would like to set a nodeSelector.

Currently, I believe the HELM charts we have accept.

nodeSelector: {}

In the app, we have

        - name: example_node_selector
          title: Example
          help_text: The nodeSelector you would like to assign to the scanner ( Formatted like foo: "bar")
          type: text
          default: {}
          when: repl{{ ConfigOptionEquals "example_trigger" "1" }}

So in this example we would like this to be an empty array if it’s left blank, versus empty string.

And the example in our deployment.yaml would be…

foo:
  nodeSelector: '{{repl ConfigOption "example_node_selector" }}'

However, we’re unsure if that’s correct because it’s wrapped around in strings…

Would you be able to give us some guidance on how to create one that sets node selector labels properly that matches the kubernetes spec?

Hi @gkalmring,

A few things that you’d have to change:

type: text

to

type: textarea

and

default: {}

to

default: ""

and wrap the following in single quotes. so change this from:

help_text: The nodeSelector you would like to assign to the scanner ( Formatted like foo: "bar")

to

help_text: 'The nodeSelector you would like to assign to the scanner ( Formatted like foo: "bar")'

and change this from:

nodeSelector: '{{repl ConfigOption "example_node_selector" }}'

to

nodeSelector: 'repl{{ if ConfigOptionEquals "example_node_selector" "" }}{}repl{{ else }}repl{{ ConfigOption "example_node_selector" | nindent 6 }}repl{{end}}'

Note: indentation number might differ. I specified 6 because you mentioned this is for a deployment.

Also, I would recommend passing --lint when creating releases via the CLI as it would’ve caught some of these issues. Or you can try using the vendor portal UI and the lint results would show up as you’re modifying the release resources.

Let me know if the above helps.

Hi @salahalsaleh

Thanks for clarifying, I was just wondering primarily about the spec of how the kubernetes deployment would interpret the above since it’s a nodeLabel.

For example, most nodeLabels are read in as…

nodeSelector: { foo: "bar" }

Which I believe translates to.

nodeSelector:
  foo: "bar"

I was just wondering if it would properly interpret the braces here specifically for nodeLabels I just didn’t want it to interpret the key as a stringified value as well, since I don’t believe they should be.

If you follow the changes I recommended above, it wouldn’t translate to a stringified value, it would end up as a map/object of key/value pairs and the deployment should interpret them correctly. and the default value would end up as {} not “{}” so that should also work just fine.

Try it and let me know if you have any issues.

1 Like

Thank you so much, just wanted to validate.

Greatly appreciated!

Any time. You got it!

One last note, when listing node selectors in the config text area in the admin console, you should do it as so (without quoting the values):

foo1: bar1
foo2: bar2
1 Like

So we hit the same question, but now for hard mode. :slight_smile:

We want to take another “foo: bar” string from a ConfigOption and optionally add it to the node selector map. The naive approach did not work for us,

      nodeSelector:
        kubernetes.io/arch: amd64
        'repl{{if ConfigOptionNotEquals "" "cust_node_selector"}}repl{{ConfigOption "cust_node_selector"}}repl{{end}'

hoping that template line will just expand to nothing, but which fails replicated release lint with yaml: line 24: could not find expected ':' That and various experiments with different quoting types. Is there a right way to make that work?

This seems better, at least it passes lint. I parse the option and reconstruct the dict using merge and convert to one-line json.

      nodeSelector: |-
        repl{{ $kvs := split ":" (ConfigOption "cust_node_selector") }}
        repl{{ $extra := dict $kvs._0 $kvs._1 }}
        repl{{ $base := dict "kubernetes.io/arch" "amd64" }}
        repl{{ if ConfigOptionEquals "cust_node_selector" "" }}repl{{$base | toJson}}repl{{else}}repl{{ merge $base $extra | toJson}} repl{{end}}

Side discovery: ternary does not short circuit its “false” leg, and merge is destructive on its arguments, otherwise I’d do that here.

Yeah this was painful. Guidance appreciated! Thanks.

@salahalsaleh :slight_smile: