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  })