diff --git a/lib/krane/ejson_secret_provisioner.rb b/lib/krane/ejson_secret_provisioner.rb index a4a6e22fa..b2fdd01a3 100644 --- a/lib/krane/ejson_secret_provisioner.rb +++ b/lib/krane/ejson_secret_provisioner.rb @@ -134,10 +134,13 @@ def with_decrypted_ejson end def decrypt_ejson(key_dir) - # ejson seems to dump both errors and output to STDOUT - out_err, st = Open3.capture2e("EJSON_KEYDIR=#{key_dir} ejson decrypt #{@ejson_file}") - raise EjsonSecretError, out_err unless st.success? - JSON.parse(out_err) + out, err, st = Open3.capture3("EJSON_KEYDIR=#{key_dir} ejson decrypt #{@ejson_file}") + unless st.success? + # older ejson versions dump some errors to STDOUT + msg = out.present? && err.blank? ? out : err + raise EjsonSecretError, msg + end + JSON.parse(out) rescue JSON::ParserError raise EjsonSecretError, "Failed to parse decrypted ejson" end diff --git a/test/unit/krane/ejson_secret_provisioner_test.rb b/test/unit/krane/ejson_secret_provisioner_test.rb index 6daab7262..e1a03732b 100644 --- a/test/unit/krane/ejson_secret_provisioner_test.rb +++ b/test/unit/krane/ejson_secret_provisioner_test.rb @@ -48,6 +48,37 @@ def test_run_with_bad_private_key_in_cloud_keys end end + def test_decryption_failure_with_error_on_stdout_reports_error + # ejson < 1.2 prints errors on stdout + Open3.expects(:capture3).with(regexp_matches(/ejson decrypt/)) + .returns(["Some error from ejson", "", stub(success?: false)]) + msg = "Generation of Kubernetes secrets from ejson failed: Some error from ejson" + assert_raises_message(Krane::EjsonSecretError, msg) do + build_provisioner(fixture_path('ejson-cloud')).resources + end + end + + def test_decryption_successful_but_warning_on_stderr_does_not_confuse_us + valid_response = { + "_public_key" => fixture_public_key, + "kubernetes_secrets" => + { + "test" => { + "_type" => "Opaque", + "data" => { "test" => "true" }, + }, + }, + }.to_json + + Open3.expects(:capture3).with(regexp_matches(/ejson decrypt/)) + .returns([valid_response, "Permissions warning!", stub(success?: true)]) + stub_server_dry_run_version_request + stub_server_dry_run_validation_request + + resources = build_provisioner(fixture_path('ejson-cloud')).resources + refute_empty(resources) + end + def test_no_ejson_keys_secret_provided assert_raises_message(Krane::EjsonSecretError, /Generation of Kubernetes secrets from ejson failed: Secret ejson-keys not provided, cannot decrypt secrets/) do