jelastic

How can I preserve \n characters in my jelastic environment variable?


I am trying to install the following Jelastic manifest:

type: update
name: Not working

onInstall:
  - getPublicKey
  - forEach(nodes.cp):
    - api:
      - method: environment.control.SetContainerEnvVars
        params:
          nodeId: ${@i.id}
          vars:
            SOME_SECRET: '{"type": "RS256", "key": "${response.out}"}'
actions:
  getPublicKey:
    - cmd [cp]: |
        curl -s -H "Authorization: my-token" http://${nodes.auth.master.intIP}:9011/api/key | jq -r '.keys[] | select(.algorithm | contains("RS256")).publicKey'

The response output in the Jelastic console for the getPublicKey action reads:

cmd [cp: 113094].response: {"result":0,"errOut":"","nodeid":113094,"exitStatus":0,"out":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAprg9fCTMSfm6psfOnhfL\nUDdlrV39LU9p8msWsYUjO4M2E6m5GcADYPHkLdLV/c7W+vgDvpHLfxU8peP/21BS\nCVQVYEFpYCRY2NcOTsP2zLj7PTAFiw8wyOwK7u05EM7CgK7LS6rDotMIZFNzIPG5\nfJNz+hDyhvvNhWg56dcmPIrBxN26Piv+N6vtWqJDuVQNXKwEk/w4uUxiz9gNSEi/\nhJlLgHxTsSMh9YXUIyKn8QBACF4GQKmToBPW7ScEnX/Bm6y9g4JbYYIwWBTRwUfy\nkhbojk6mAPcKY+diWM2PE385pyjIWshKUgtBKcgPNJXDU3RPXAdzN0hQ1sJbNV5z\nzwIDAQAB\n-----END PUBLIC KEY-----"}

Here we can clearly see the newlines displayed as \n characters. For some reason, the newline characters \n are interpreted as true newlines in the environment variable SOME_SECRET, which now reads incorrectly (this is the result of the env command):

SOME_SECRET={"type": "RS256", "key": "-----BEGIN PUBLIC KEY-----

The variable value is displayed until the first newline character, which is not what I want.

How can I make sure the \n get outputted to the SOME_SECRET environment variable and that they are not replaced with a real new line? When I execute the env command on my ubuntu image, I want to see this:

SOME_SECRET={"type": "RS256", "key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAprg9fCTMSfm6psfOnhfL\nUDdlrV39LU9p8msWsYUjO4M2E6m5GcADYPHkLdLV/c7W+vgDvpHLfxU8peP/21BS\nCVQVYEFpYCRY2NcOTsP2zLj7PTAFiw8wyOwK7u05EM7CgK7LS6rDotMIZFNzIPG5\nfJNz+hDyhvvNhWg56dcmPIrBxN26Piv+N6vtWqJDuVQNXKwEk/w4uUxiz9gNSEi/\nhJlLgHxTsSMh9YXUIyKn8QBACF4GQKmToBPW7ScEnX/Bm6y9g4JbYYIwWBTRwUfy\nkhbojk6mAPcKY+diWM2PE385pyjIWshKUgtBKcgPNJXDU3RPXAdzN0hQ1sJbNV5z\nzwIDAQAB\n-----END PUBLIC KEY-----"}

Solution

  • The following manifest does exactly what I want:

    type: update
    name: Working
    
    onInstall:
      - getPublicKey
      - api:
        - method: environment.control.AddContainerEnvVars
          params:
            nodeGroup: cp
            vars:
              SOME_SECRET: '{"type": "RS256", "key": "${response.out}"}'
    actions:
      getPublicKey:
        - cmd [cp]: |
            curl -s -H "Authorization: some-key" http://${nodes.auth.master.intIP}:9011/api/key | jq -r '.keys[] | select(.algorithm | contains("RS256")).publicKey' | sed ':a;N;$!ba;s/\n/\\n/g'
    

    Note the use of sed in the getPublicKey to format the response output appropriately. Also, note the use of environment.control.AddContainerEnvVars instead of environment.control.SetContainerEnvVars. The latter removes all environment variables on the node group (except PATH), while the former really adds new environment variables (and overwrites existing ones with the new values).

    Finally, note that it is necessary to have the getPublicKey action. The following manifest would not work (I don't know why):

    type: update
    name: Not Working
    
    onInstall:
      - cmd [cp]: |
          curl -s -H "Authorization: some-key" http://${nodes.auth.master.intIP}:9011/api/key | jq -r '.keys[] | select(.algorithm | contains("RS256")).publicKey' | sed ':a;N;$!ba;s/\n/\\n/g'
      - api:
        - method: environment.control.AddContainerEnvVars
          params:
            nodeGroup: cp
            vars:
              SOME_SECRET: '{"type": "RS256", "key": "${response.out}"}'