kapicorp / kapitan

Generic templated configuration management for Kubernetes, Terraform and other things
https://kapitan.dev
Apache License 2.0
1.83k stars 199 forks source link

b64encode jinja2 uses a wrong value of secret for encoding #210

Closed metacoma closed 5 years ago

metacoma commented 5 years ago

Describe the bug/feature Wrong b64encode behavior with secrets parameters in jinja2 templating

To Reproduce Steps to reproduce the behavior:

  1. create gpg secret
    echo -n "dockerhub_password" | kapitan secrets -vvv --write gpg:me/dockerhub/password -t common -f -
  2. create target with dockerhub_password parameter, for example inventory/targets/bug with content:
    parameters: 
    dockerhub:
    password: "?{gpg:me/dockerhub/password}"
    kapitan:
    vars:
    target: "bug"
    compile:
     - 
       input_path: 
        - templates/dockerhub.txt
       input_type: jinja2
       output_path: "data/" 

    templates/dockerhub.txt content:

    {% set p = inventory.parameters %}
    {{ p.dockerhub.password | b64encode }}
  3. run kapitan compile -t bug --reveal
  4. check compiled file: cat compiled/bug/data/dockerhub.txt
    P3tncGc6bWUvZG9ja2VyaHViL3Bhc3N3b3JkfQ==

Expected behavior cat compiled/bug/data/dockerhub.txt

ZG9ja2VyaHViX3Bhc3N3b3Jk

b64encode function in jinja2 filter caclulate b64sum from '?{gpg:me/dockerhub/password}' value instead of 'dockerhub_password'

kapitan 0.22.3
metacoma commented 5 years ago

Thanks!

ramaro commented 5 years ago

Because this is evaluated at compile time, you won't be able to base64 encode a secret like that.

Consider using instead

echo -n "dockerhub_password" | kapitan secrets -vvv--write gpg:me/dockerhub/password --base64 -t common -f -

And removing the base64encode filter.

frittentheke commented 5 years ago

@ramaro @metacoma ... so am I reading this correctly, there is NO way to store the password raw and only render it to be base64? One has to store it in base64 if one needs it to be base64 in the templated files?

uberspot commented 5 years ago

Not fully, You can use the reveal function to get a secret and then base64 it with jinja or whatever you want. See example here: https://github.com/deepmind/kapitan/blob/master/examples/kubernetes/inventory/classes/component/mysql.yml

ramaro commented 5 years ago

@frittentheke to answer directly to your question: that's correct, at the moment there's no way to store the same password raw and only render it to be base64. You will have to create 2 secrets for the same password with different encodings.