10

I'm trying to implement an ingress helm template encoding the current application version into the url. This shall allow users to do soft migration by providing them different versions of the application.

Example:

mydomain.org/1.0/applicationpath
mydomain.org/1.1/applicationpath
mydomain.org/2.0/applicationpath

To prevent configuring this manually in the ingress on each update, I would prefer a regex determining the major.minor version automatically. The application is revised according to Semver 2.0.0, so a pattern like \d+.\d+ should do the work.

I tried something like this:

apiVersion: extensions/v1beta1
kind: Ingress
spec:
  backend:
    serviceName: {{ .Release.Name }}-my-srv
    servicePort: 80
  rules:
  - host: {{ .Values.app.ingress.host }}
    http:
      paths:
        - path: /{{ .Chart.AppVersion | regex \d+.\d+ }} 

Unfortunately I couldn't find a function for regular expressions. Is there an option to achieve this with a helm template?

12

Yes there is. However it is unfortunately undocumented.
Helm uses the sprig library to provide additional functions for templating. What is undocumented is many of the sprig functions that have been added to the code (ref issue #84), and the regex functions are some of them. You can find these functions here: https://github.com/Masterminds/sprig/blob/master/regex.go

Thus you can do {{ .Chart.AppVersion | regexFind "\d+\.\d+" }}

(note that I also added a \ before the . to escape it as . means to match any character, which does not seem to be your intent)

 

Not your use case, but one item of note for others which might be interested in using the regex* functions from sprig, is that unfortunately the sprig owner made the subject string the second argument of all the functions, and some of the functions have additional arguments after it (e.g. the regexReplaceAll function). The reason why this is a problem is that when a function is used in a pipeline, the result of the previous element in the pipeline becomes the last argument of the function. So this does not work: "foo subject string" | regexReplaceAll "foo" "bar", as it'll treat bar as the string to operate on, and foo subject string as the string to replace any occurrences of foo with (which in this example there would not be any).

2
  • 3
    Just in case anyone else has the same issue I did with this, I needed to escape the backslash in \d for this to work, making my template snippet .Capabilities.KubeVersion.Minor | regexFind "\\d+" – Dougc Sep 4 '19 at 15:55
  • See also issue #86 which is about the awkward usage of regexReplaceAll* functions in pipelines. You have to use {{ "bar" | regexReplaceAll "foo" "foo subject string" }} instead. – Ed Randall Sep 8 '20 at 13:02
9

Had to deal with this today, you will want something like:

{{ regexFind "\\d+\\.\\d+" .Chart.AppVersion }}

Requires the double escapes due to yaml.

Docs for this

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.