How to execute bash string manipulations in a kubernetes deployment yaml

12/3/2019

I am trying to deploy a kubernetes container, the image of which requires a URL pointing to a resource. This resource needs to be accessed through github authentication which is contained in a secret on the cluster. To get the access token from this secret I must do some string manipulation with bash commands. Here is the current container spec in the deployment yaml:

    - name: <container-name>
        image: stoplight/prism:latest
        env:
        - name: GITHUB_AUTH
          valueFrom:
            secretKeyRef:
              name: githubregistry
              key: .dockerconfigjson
        args:
        - "mock"
        - "https://$(echo $GITHUB_AUTH | sed 's/{auths:{docker.pkg.github.com:{auth://g' | sed 's/}}}//g' | base64 --decode | cut -d':' -f2)@raw.githubusercontent.com/<path-to-deployment>.yaml"
        - "-h"
        - "0.0.0.0"
        - "-p"
        - "8080"
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP

now this line:

    - "https://$(echo $GITHUB_AUTH | sed 's/{auths:{docker.pkg.github.com:{auth://g' | sed 's/}}}//g' | base64 --decode | cut -d':' -f2)@raw.githubusercontent.com/<path-to-deployment>.yaml"

obviously doesn't evaluate because this a deployment yaml not bash.

Any idea how I could replicate such behaviour? I suppose I could do something with an initcontainer but I'd like to avoid overcomplicating.

-- DazKins
docker
github
kubernetes

1 Answer

12/3/2019

The line [1] is not being evaluated because it's being sent as parameter to the ENTRYPOINT.

You will need to run the commands on a shell. Following the section "Run a command in a shell" on [2] you will need to something like this:

- name: <container-name>
        image: stoplight/prism:latest
        env:
        - name: GITHUB_AUTH
          valueFrom:
            secretKeyRef:
              name: githubregistry
              key: .dockerconfigjson
        command: ["/bin/sh"]
        args:
        - "-c"
        - "TOKEN_FETCHED=`https://$(echo $GITHUB_AUTH | sed 's/{auths:{docker.pkg.github.com:{auth://g' | sed 's/}}}//g' | base64 --decode | cut -d':' -f2)@raw.githubusercontent.com/<path-to-deployment>.yaml`"
        - "<your-entrypoint-location> mock $TOKEN_FETCHED -h 0.0.0.0 -p 8080"
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP

So, your last approach didn't work because you were sending line [1] as a parameter to the entrypoint. What I propose to you is to actually sent the output of your command (the line [1]) to a variable [3] and then pass that variable to the ENTRYPOINT.

Please, keep in mind that you you need to place the complete location of your entry point in the section. You can get this by inspecting the image you are using:

docker inspect stoplight/prism:latest

And look for the "CMD" output.

[1]

   - "https://$(echo $GITHUB_AUTH | sed 's/{auths:{docker.pkg.github.com:{auth://g' | sed 's/}}}//g' | base64 --decode | cut -d':' -f2)@raw.githubusercontent.com/<path-to-deployment>.yaml"

[2] https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/

[3] https://www.cyberciti.biz/faq/unix-linux-bsd-appleosx-bash-assign-variable-command-output/

-- Armando Cuevas
Source: StackOverflow