github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/topgun/core/database_encryption_test.go (about) 1 package topgun_test 2 3 import ( 4 "bytes" 5 "os" 6 7 . "github.com/onsi/ginkgo" 8 . "github.com/onsi/gomega" 9 10 . "github.com/pf-qiu/concourse/v6/topgun/common" 11 "github.com/onsi/gomega/gbytes" 12 "github.com/onsi/gomega/gexec" 13 ) 14 15 var _ = Describe("Database secrets encryption", func() { 16 configurePipelineAndTeamAndTriggerJob := func() { 17 By("setting a pipeline that contains secrets") 18 Fly.Run("set-pipeline", "-n", "-c", "pipelines/secrets.yml", "-p", "pipeline-secrets-test") 19 Fly.Run("unpause-pipeline", "-p", "pipeline-secrets-test") 20 21 By("creating a team with auth") 22 setTeamSession := Fly.SpawnInteractive( 23 bytes.NewBufferString("y\n"), 24 "set-team", 25 "--team-name", "victoria", 26 "--github-user", "victorias_id", 27 "--github-org", "victorias_secret_org", 28 ) 29 <-setTeamSession.Exited 30 31 buildSession := Fly.Start("trigger-job", "-w", "-j", "pipeline-secrets-test/simple-job") 32 <-buildSession.Exited 33 Expect(buildSession.ExitCode()).To(Equal(0)) 34 } 35 36 getPipeline := func() *gexec.Session { 37 session := Fly.Start("get-pipeline", "-p", "pipeline-secrets-test") 38 <-session.Exited 39 Expect(session.ExitCode()).To(Equal(0)) 40 return session 41 } 42 43 Describe("A deployment with encryption enabled immediately", func() { 44 BeforeEach(func() { 45 Deploy("deployments/concourse.yml", "-o", "operations/encryption.yml") 46 }) 47 48 It("encrypts pipeline credentials", func() { 49 configurePipelineAndTeamAndTriggerJob() 50 51 By("taking a dump") 52 session := PgDump() 53 Expect(session).ToNot(gbytes.Say("resource_secret")) 54 Expect(session).ToNot(gbytes.Say("resource_type_secret")) 55 Expect(session).ToNot(gbytes.Say("job_secret")) 56 }) 57 }) 58 59 Describe("A deployment with encryption initially not configured", func() { 60 BeforeEach(func() { 61 Deploy("deployments/concourse.yml") 62 }) 63 64 Context("with credentials in plaintext", func() { 65 BeforeEach(func() { 66 configurePipelineAndTeamAndTriggerJob() 67 68 By("taking a dump") 69 session := PgDump() 70 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_secret")) 71 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_type_secret")) 72 Expect(string(session.Out.Contents())).To(ContainSubstring("job_secret")) 73 }) 74 75 Context("when redeployed with encryption enabled", func() { 76 BeforeEach(func() { 77 Deploy("deployments/concourse.yml", "-o", "operations/encryption.yml") 78 }) 79 80 It("encrypts pipeline credentials", func() { 81 By("taking a dump") 82 session := PgDump() 83 Expect(session).ToNot(gbytes.Say("resource_secret")) 84 Expect(session).ToNot(gbytes.Say("concourse/time-resource")) 85 Expect(session).ToNot(gbytes.Say("job_secret")) 86 87 By("getting the pipeline config") 88 session = getPipeline() 89 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_secret")) 90 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_type_secret")) 91 Expect(string(session.Out.Contents())).To(ContainSubstring("job_secret")) 92 Expect(string(session.Out.Contents())).To(ContainSubstring("image_resource_secret")) 93 }) 94 95 Context("when the encryption key is rotated", func() { 96 BeforeEach(func() { 97 Deploy("deployments/concourse.yml", "-o", "operations/encryption-rotated.yml") 98 }) 99 100 It("can still get and set pipelines", func() { 101 By("taking a dump") 102 session := PgDump() 103 Expect(session).ToNot(gbytes.Say("resource_secret")) 104 Expect(session).ToNot(gbytes.Say("concourse/time-resource")) 105 Expect(session).ToNot(gbytes.Say("job_secret")) 106 107 By("getting the pipeline config") 108 session = getPipeline() 109 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_secret")) 110 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_type_secret")) 111 Expect(string(session.Out.Contents())).To(ContainSubstring("job_secret")) 112 Expect(string(session.Out.Contents())).To(ContainSubstring("image_resource_secret")) 113 114 By("setting the pipeline again") 115 Fly.Run("set-pipeline", "-n", "-c", "pipelines/secrets.yml", "-p", "pipeline-secrets-test") 116 117 By("getting the pipeline config again") 118 session = getPipeline() 119 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_secret")) 120 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_type_secret")) 121 Expect(string(session.Out.Contents())).To(ContainSubstring("job_secret")) 122 Expect(string(session.Out.Contents())).To(ContainSubstring("image_resource_secret")) 123 }) 124 }) 125 126 Context("when an old key is given but all the data is already using the new key", func() { 127 BeforeEach(func() { 128 Deploy("deployments/concourse.yml", "-o", "operations/encryption-already-rotated.yml") 129 }) 130 131 It("can still get and set pipelines", func() { 132 By("taking a dump") 133 session := PgDump() 134 Expect(session).ToNot(gbytes.Say("resource_secret")) 135 Expect(session).ToNot(gbytes.Say("concourse/time-resource")) 136 Expect(session).ToNot(gbytes.Say("job_secret")) 137 138 By("getting the pipeline config") 139 session = getPipeline() 140 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_secret")) 141 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_type_secret")) 142 Expect(string(session.Out.Contents())).To(ContainSubstring("job_secret")) 143 Expect(string(session.Out.Contents())).To(ContainSubstring("image_resource_secret")) 144 145 By("setting the pipeline again") 146 Fly.Run("set-pipeline", "-n", "-c", "pipelines/secrets.yml", "-p", "pipeline-secrets-test") 147 148 By("getting the pipeline config again") 149 session = getPipeline() 150 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_secret")) 151 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_type_secret")) 152 Expect(string(session.Out.Contents())).To(ContainSubstring("job_secret")) 153 Expect(string(session.Out.Contents())).To(ContainSubstring("image_resource_secret")) 154 }) 155 }) 156 157 Context("when an old key and new key are both given that do not match the key in use", func() { 158 var deploy *gexec.Session 159 var boshLogs *gexec.Session 160 161 BeforeEach(func() { 162 boshLogs = SpawnBosh("logs", "-f") 163 164 deploy = StartDeploy("deployments/concourse.yml", "-o", "operations/encryption-bogus.yml") 165 <-deploy.Exited 166 Expect(deploy.ExitCode()).To(Equal(1)) 167 }) 168 169 AfterEach(func() { 170 boshLogs.Signal(os.Interrupt) 171 <-boshLogs.Exited 172 }) 173 174 AfterEach(func() { 175 Deploy("deployments/concourse.yml", "-o", "operations/encryption.yml") 176 }) 177 178 It("fails to deploy with a useful message", func() { 179 Expect(deploy).To(gbytes.Say("Review logs for failed jobs: web")) 180 Expect(boshLogs).To(gbytes.Say("row encrypted with neither old nor new key")) 181 }) 182 }) 183 184 Context("when the encryption key is removed", func() { 185 BeforeEach(func() { 186 Deploy("deployments/concourse.yml", "-o", "operations/encryption-removed.yml") 187 }) 188 189 It("decrypts pipeline credentials", func() { 190 By("taking a dump") 191 session := PgDump() 192 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_secret")) 193 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_type_secret")) 194 Expect(string(session.Out.Contents())).To(ContainSubstring("job_secret")) 195 196 By("getting the pipeline config") 197 session = getPipeline() 198 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_secret")) 199 Expect(string(session.Out.Contents())).To(ContainSubstring("resource_type_secret")) 200 Expect(string(session.Out.Contents())).To(ContainSubstring("job_secret")) 201 Expect(string(session.Out.Contents())).To(ContainSubstring("image_resource_secret")) 202 }) 203 }) 204 }) 205 }) 206 }) 207 })