From f626f7bc7fd2fbf96537af8b7767d0980dcec508 Mon Sep 17 00:00:00 2001 From: TJ Miller Date: Tue, 3 Nov 2020 12:27:41 -0800 Subject: [PATCH] Add RunHelm test --- .github/workflows/test.yaml | 32 +++++++++++++ helm_wrapper_test.go | 65 +++++++++++++++++++++++++- test/charts/test/.helmignore | 22 +++++++++ test/charts/test/Chart.yaml | 5 ++ test/charts/test/templates/test.yaml | 7 +++ test/charts/test/values-dec.yaml | 41 +++++++++++++++++ test/charts/test/values-enc.yaml | 69 ++++++++++++++++++++++++++++ test/charts/test/values.yaml | 15 ++++++ 8 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test.yaml create mode 100644 test/charts/test/.helmignore create mode 100644 test/charts/test/Chart.yaml create mode 100644 test/charts/test/templates/test.yaml create mode 100644 test/charts/test/values-dec.yaml create mode 100644 test/charts/test/values-enc.yaml create mode 100644 test/charts/test/values.yaml diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..44016af --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,32 @@ +name: "Test" + +on: + - push + - pull_request + +jobs: + test: + runs-on: "ubuntu-latest" + steps: + - name: "Checkout source code" + uses: "actions/checkout@v2" + with: + fetch-depth: 0 + - name: "Set up Go" + uses: "actions/setup-go@v2" + with: + go-version: "1.15" + - name: Get dependencies + run: go mod vendor + - name: Install PGP and SOPS Dev Key + run: | + sudo apt-get install pgpgpg && + gpg --import vendor/go.mozilla.org/sops/v3/pgp/sops_functional_tests_key.asc + - uses: azure/setup-helm@v1 + with: + version: 'latest' + id: install + - name: Build + run: go build . + - name: Test + run: go test -v . diff --git a/helm_wrapper_test.go b/helm_wrapper_test.go index d9226c5..0395095 100644 --- a/helm_wrapper_test.go +++ b/helm_wrapper_test.go @@ -2,6 +2,10 @@ package main import ( "os" + "os/exec" + "io" + "bytes" + "sync" "testing" ) @@ -107,5 +111,64 @@ func TestMkPipe(t *testing.T) { } func TestRunHelm(t *testing.T) { - // TODO + reader, writer, err := os.Pipe() + if err != nil { + panic(err) + } + os.Stdout = writer + wg := new(sync.WaitGroup) + var out1 bytes.Buffer + go func() { + wg.Add(1) + defer wg.Done() + _, err = io.Copy(&out1, reader) + if err != nil { + t.Errorf("io.Copy error: %s", err) + } + }() + + os.Args = []string{ + "./helm-sops", + "template", + "./test/charts/test", + "--values=test/charts/test/values-enc.yaml", + } + g_hw.RunHelm() + writer.Close() + wg.Wait() + + + reader, writer, err = os.Pipe() + if err != nil { + panic(err) + } + var out2 bytes.Buffer + go func() { + wg.Add(1) + defer wg.Done() + _, err = io.Copy(&out2, reader) + if err != nil { + t.Errorf("io.Copy error: %s", err) + } + }() + + args := []string{ + g_hw.helmBinPath, + "template", + "./test/charts/test", + "--values=test/charts/test/values-dec.yaml", + } + cmd := exec.Command(args[0], args[1:]...) + cmd.Env = os.Environ() + cmd.Stdin = os.Stdin + cmd.Stdout = writer + cmd.Stderr = os.Stderr + + cmd.Run() + writer.Close() + wg.Wait() + + if !bytes.Equal(out1.Bytes(), out2.Bytes()) { + t.Errorf("unexpected RunHelm output: \n%s", out1.String()) + } } diff --git a/test/charts/test/.helmignore b/test/charts/test/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/test/charts/test/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/test/charts/test/Chart.yaml b/test/charts/test/Chart.yaml new file mode 100644 index 0000000..3f69cd4 --- /dev/null +++ b/test/charts/test/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: "1.0" +description: A Helm chart just for testing +name: test +version: 0.1.0 diff --git a/test/charts/test/templates/test.yaml b/test/charts/test/templates/test.yaml new file mode 100644 index 0000000..971880b --- /dev/null +++ b/test/charts/test/templates/test.yaml @@ -0,0 +1,7 @@ +--- +myapp1: {{ .Values.myapp1 | quote }} +somebooleans: | + {{- .Values.somebooleans | toYaml | nindent 2 }} +this_is_a_nested_value: {{ .Values.this.is.a.nested.value | quote }} +somelist_unencrypted: | + {{- .Values.somelist_unencrypted | toYaml | nindent 2 }} diff --git a/test/charts/test/values-dec.yaml b/test/charts/test/values-dec.yaml new file mode 100644 index 0000000..4af8e90 --- /dev/null +++ b/test/charts/test/values-dec.yaml @@ -0,0 +1,41 @@ +myapp1: t00m4nys3cr3tzupdated +app2: + db: + user: eve + password: c4r1b0u + # private key for secret operations in app2 + key: | + -----BEGIN RSA PRIVATE KEY----- + MIIBPAIBAAJBAPTMNIyHuZtpLYc7VsHQtwOkWYobkUblmHWRmbXzlAX6K8tMf3Wf + ImcbNkqAKnELzFAPSBeEMhrBN0PyOC9lYlMCAwEAAQJBALXD4sjuBn1E7Y9aGiMz + bJEBuZJ4wbhYxomVoQKfaCu+kH80uLFZKoSz85/ySauWE8LgZcMLIBoiXNhDKfQL + vHECIQD6tCG9NMFWor69kgbX8vK5Y+QL+kRq+9HK6yZ9a+hsLQIhAPn4Ie6HGTjw + fHSTXWZpGSan7NwTkIu4U5q2SlLjcZh/AiEA78NYRRBwGwAYNUqzutGBqyXKUl4u + Erb0xAEyVV7e8J0CIQC8VBY8f8yg+Y7Kxbw4zDYGyb3KkXL10YorpeuZR4LuQQIg + bKGPkMM4w5blyE1tqGN0T7sJwEx+EUOgacRNqM2ljVA= + -----END RSA PRIVATE KEY----- +number: 1.234568e+09 +an_array: +- secretuser1 +- secretuser2 +- somelongvalueAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +- some other value +somebooleans: +- true +- false +this: + is: + a: + nested: + value: with something secret in it + # sops supports unencrypted fields + # by adding the `_unencrypted` suffix + # to any key +somelist_unencrypted: +- all elements of this list +- remain in clear text +- because of the _encrypted suffix in the key +nested_unencrypted: + this: + is: + all: going to remain in clear text diff --git a/test/charts/test/values-enc.yaml b/test/charts/test/values-enc.yaml new file mode 100644 index 0000000..e79b06e --- /dev/null +++ b/test/charts/test/values-enc.yaml @@ -0,0 +1,69 @@ +myapp1: ENC[AES256_GCM,data:zlGNmhTYX5xol4ZZFsiaoGkD73nn,iv:ql9mkhoU1I64E/FJi3iA0HaAe2U3kQVFee2ZLwPnBik=,tag:SqVSfu/JkRrwqidAT/i0pg==,type:str] +app2: + db: + user: ENC[AES256_GCM,data:tQ1l,iv:o9MiMveNYO7T82yDab+4pAt17DO6B4wl8yGy3oFbDb8=,tag:0RjvUUtSQwaUc9SF3RSTZQ==,type:str] + password: ENC[AES256_GCM,data:8Ll+TDCgzQ==,iv:aao0OSVdFwaB9EGZ0O+Wn5bRJ6do7hgiQioqiwDi1w0=,tag:WKj0nuSSPkm2dBOBwinYvg==,type:str] + #ENC[AES256_GCM,data:uPuUQAahmq1xL5L2B0+a2gHSl7zXucjqa4Kr0AgNKTpgHw3IPx2lCoK+,iv:qYxjRmWMir47YKhmrrHwV0atmGjcJ3Dts+xvQ+6skHQ=,tag:dsj+0DsfiDyJNGUmvZwnHg==,type:comment] + key: ENC[AES256_GCM,data:xRjmLiX4BCoSUElToUs5twDq1WNWQNvNMi8yitXly43iGQiwltIs0FsY5u+7fzLepS66oLTGdL0NfWwCGxksYYzUKz5OXRLEatacZP40D71861zu+njmGdXepY0q0q5VOG7ObgIAMMMElVKRIFdjpVgmgUa+/h6R77mEbDztk6lqb28r15XyR6GmdubierTE7aialFzNoC+XO/yk7bnMi0XA/aomj1H5RdZ37LBR2k+rhqXmhkPdGTdJ39t4Ou1Q2Oc4RHRGvgs/EeFqQHcq0AilqXsFIv/PE0bQP564LaOcXK33B+PnoV1D+lXZ7mLOjKlq04c+UojwXjpZeXBr6Ip4H3dAGkPAoQKMtyGwHYzuLCNesxwPv2tPqbxkbVev0AKezGhnPjvCNvRN3S1Y0LPf1atfwzOCBQBhdUTpmXtxCdTNG0cUUZjeIKAyJXDWJooYHlstzDti/dSGMEedOnKq6648Yp7tLNDjAg5CGbDEWjTWehtqgvixUoRdYc2/r/ie3t09XB9h70BzLFDnbNdTNHhg0/aivHeDf8LJ2Co8YvIjLTwlm7GV0mSwzJIoY/2YxXFtw+XFqt+BCt1G8wq3R6OdXZK/+6fUKH/D4EVym5nrGkZIuOCiTB+wpzy09QmZ80Fo+ba0x/1g9ZTMKHk=,iv:ZtzvrO7QSHEOCnKCrIYcaesKnyScV8KaHZr22tUMLlU=,tag:2A3nJBIPF2Q3FlwMYLvG2w==,type:str] +number: ENC[AES256_GCM,data:DX0qiTOWhQvG/w==,iv:ouWsby8JoFwCRj/mLVCnNcYhP2sdyf4h6nwZuGksE7Q=,tag:lPU6AId2JrlquHnYRw+E8Q==,type:float] +an_array: +- ENC[AES256_GCM,data:vyczE8EQr9qHkaM=,iv:sT5jKk3LZ61Zq/neTli5tcnDFxCxY5RuGr2k5oGQWJQ=,tag:1HgaHWfyh6EJLkI1V2kOrw==,type:str] +- ENC[AES256_GCM,data:XtBinnYXR7bx1GY=,iv:KvT9smKVmgMNrab+RzfuWscyvJav2r8j1P08ucNmhgQ=,tag:IllAEvIPPeKOfqi1XbmT8w==,type:str] +- ENC[AES256_GCM,data:gpZ7nwWTGaI+Ti+lk+CPQOoM0ypwK7UMMBUiZAniQHDNJelipqc8hyhNeV+tpJLNaRt74OHs04EX8g==,iv:mKcwVelqLvwVDPjR8NeyMZ7AhsjRgmnYmyEuwPNPrQ8=,tag:vrkoccUfJs105yLCmXYYCw==,type:str] +- ENC[AES256_GCM,data:L9jPh+7+XsdqEpUnFcD4nA==,iv:xyfKjOXVrBDCIQG5786pSu5yvHdl/PK8eVxkIUWoCIw=,tag:Q0wlTV2e2vZeU6eTF5Oacg==,type:str] +somebooleans: +- ENC[AES256_GCM,data:ExiXxg==,iv:K7FUwomqdA7o9lzvNoAMH/wbXs08FextTGGeJKnaatU=,tag:A9UntgvPIcappmeM3jsbdA==,type:bool] +- ENC[AES256_GCM,data:3I0AVdM=,iv:q4YKnRIKufREPmwT4sz8plcsOD6iem/tY3NMUV0STBE=,tag:0w4OMKClWTzjKhqsJZT8JA==,type:bool] +this: + is: + a: + nested: + value: ENC[AES256_GCM,data:oFn5fJS5+slb2sCdLY5SxZ+iWeowWtf4wn9g,iv:MZ7i4tZnfCQhQRUwXV2fYQPIJ0tTUFLiD9xuB+765e8=,tag:ZEjE5jvxE5HkN3mma84pKw==,type:str] + #ENC[AES256_GCM,data:WwWiKtMsD1shPe5kPHOh2bJqQPGHwxa6GYrR1y14wiid,iv:AZPaRyVDOl100PvBPMeq0lt6/O5ZUhzWX5UmWNABWvM=,tag:PBReK6Ap/VHxncn0G4qtEA==,type:comment] + #ENC[AES256_GCM,data:eYRaxgs3vGeS96+ZDV8GYrwbvsrMtnWHOtsT2045tD2mlfOD,iv:/RVNEWuBlxhhY8OlJPbS/81QJukXZu1EWnPUQwrcin4=,tag:DybgrXKGWxoRyIQOlc+UMA==,type:comment] + #ENC[AES256_GCM,data:JXKEWGBg4eeCdeQ=,iv:K5keuEjyekf7a3q7WBOKwljsHGXRdQteJcXeeKvHo28=,tag:60VtIdsy13qSKPIEWHUUNg==,type:comment] +somelist_unencrypted: +- all elements of this list +- remain in clear text +- because of the _encrypted suffix in the key +nested_unencrypted: + this: + is: + all: going to remain in clear text +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + lastmodified: '2019-12-10T22:45:53Z' + mac: ENC[AES256_GCM,data:WDjMv0eWcyPQzZlr3MppeAMQavN88xv5LzI/9wOlg+WPhRoTdrvgFpWowyWvTdUC/i0ybRQRg2u/Wam0kaqzMDpl/E806Gp9hgJcSneqydDJqPiMh+HpXkXWpc70xbYg8/gc1l7eIfSG7rS1dC2t2je60OAIfC/5zAXrL9KH4Ho=,iv:h0hWhb+46upix6K7hZfNNQoiX7WCapiMTv5I/keZsm4=,tag:v7mVbTN3HWmekol5iaO8FA==,type:str] + pgp: + - created_at: '2019-12-10T22:45:53Z' + enc: |- + -----BEGIN PGP MESSAGE----- + + wcBMAyUpShfNkFB/AQgAE0MaWAQGbTKY7Xg3fDNtzlvnVBkkQRHsLt5kUTu2nAy4 + sPX0NRXPVF/tAMxr9mI2fRjKnNBXKpOAecNis85D/QEkfflG8/syGkqiJqy9Nqon + WSm1bNriPfD4PL850688EJe49Xrsz6rVbW5FYZCHMbnPxvmoheMJRxLonW3/eWPy + IjJ9i6Z7W175mv1y7FELOimdQeelynp4r8bOuuq1BhePB4+wJXihw9n0ovuLklpl + Kr2iCmIUibSywlEO/LGQT/VXo6R7xgSN2Xg0RwWfflajYHNhVkHlnNYzkACjvdhj + ph1M5fLGDqPu+ySSe93EyahNhdwKgQ7R9yF8/13+QdLgAeRmrBgh0N54mQQAQyL7 + mH/i4SWi4BjgmeHgUeBL4qcm2avg6OUasVJQHlTeA8D+c3TwKSTRVDijN4GBadYJ + Z5/vXKOseeBk5JWCnIHC/MtjOkuPt53nvGzi3lYvW+F0FQA= + =RDyn + -----END PGP MESSAGE----- + fp: FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4 + - created_at: '2019-12-10T22:45:53Z' + enc: |- + -----BEGIN PGP MESSAGE----- + + wYwDXFUltYFwV4MBBABpm+tFhFhv3A7A/L/p6nL3HXKKhONrgguYgXA/hhSg4/bD + 1Po5pQhCM4yb3gqWewxgVpGNKFr/Gl+kN9eZ3LXp5nEdhei/aQn7BbWkhph5PKt6 + faiEZAL5PNHvktvEQwPsfNJvxe8QT2Z9oFmlueP0n3mCZz3UV9LZHNwOP7XfzdLg + AeRzUGrZK43KavmIjdgPXcd/4ZW14NPgNeGm8+BO4nD26Fvgh+UiCb0TpBiI7WsX + HQGUlFjuR6Vd7Q+vg8B/1Ovm3fUw7uCG5Gc2WeB0M+pXaLYS9bCDL9jisGOkD+Ef + ZAA= + =mqGc + -----END PGP MESSAGE----- + fp: D7229043384BCC60326C6FB9D8720D957C3D3074 + unencrypted_suffix: _unencrypted + version: 3.5.0 diff --git a/test/charts/test/values.yaml b/test/charts/test/values.yaml new file mode 100644 index 0000000..6d105d3 --- /dev/null +++ b/test/charts/test/values.yaml @@ -0,0 +1,15 @@ +# Default values for test. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +nameOverride: "" +fullnameOverride: "" + +myapp1: "" +somebooleans: [] +this: + is: + a: + nested: + value: "" +somelist_unencrypted: []