A common request from KOTS users is the ability to validate data entered in a Config field. Depending on your use case, there are a couple of options:
Option 1. Use Labels to Warn the User
Let’s say you want the user to provide an email address and would like to validate that the email is well formed. You could add a Label field that is only displayed if the email does not look right.
In the example below, a Label is displayed when the email address looks correct and another one when it does not (note that this includes the field being empty)
- name: email_addr
title: Enter Email Address
type: text
- name: email_validate
title: the email looks good
type: label
when: '{{repl regexMatch "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" (ConfigOption "email_addr") }}'
- name: email_not_validate
title: '***Please enter a valid email address!***'
type: label
when: '{{repl not (regexMatch "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" (ConfigOption "email_addr")) }}'
In the above example we are using the regexMatch sprig function to compare the value of the field against the regular expression.
To test the inverse, we used the not Go Template Function.
Here is a screenshot of the Config field containing a valid email address:
The label then changes as soon as the email address is changed and no longer valid:
Option 2. Use a PreFlight Check
Let’s say that during installation you want the user to provide some http address. Could be a database your app needs to connect to or some other service. Before installing your app, you want to make sure you can at least ping that address.
In this case since the validation requires an action, using labels will not work. But what we can do is create a PreFlight check to ping the address and determine if we were able to connect.
This preflight would first need a couple of Collector to get the address and then run ping
against it. We’ll then need an Analyzer to see the results and display a pass/fail message to the user.
If we named our field “service_addr” the preflight would look like this:
apiVersion: troubleshoot.replicated.com/v1beta1
kind: Preflight
metadata:
name: example-preflight-checks
spec:
collectors:
- run:
collectorName: "run-ping"
image: busybox:1
name: ping.txt
namespace: default
command: ["ping"]
args: ["-w", "10", "-c", "10", "-i", "0.3", '{{repl ConfigOption "service_addr"}}']
imagePullPolicy: IfNotPresent
analyzers:
- textAnalyze:
checkName: "Validate Address"
fileName: ping.txt/run-ping.log
regexGroups: '(?P<Transmitted>\d+) packets? transmitted, (?P<Received>\d+) packets? received, (?P<Loss>\d+)(\.\d+)?% packet loss'
outcomes:
- pass:
when: "Loss < 5"
message: Solid connection to {{repl ConfigOption "service_addr"}}
- fail:
message: Unable to establish a solid connection to {{repl ConfigOption "service_addr"}}, please ensure this is valid
There is a similar example in the docs.
Data Redaction
One note to make is that when you are using Collectors, some values will automatically be redacted. So the above example may not work if you want to validate an IP address, as that is one of the values that gets redacted
Debugging
One of the challenges debugging preflight checks is that collector results are not easily available. However, they are available if you add the collector to a SupportBundle.