github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/creds/vault/vault_test.go (about)

     1  package vault_test
     2  
     3  import (
     4  	"github.com/pf-qiu/concourse/v6/atc/creds"
     5  	"github.com/pf-qiu/concourse/v6/atc/creds/vault"
     6  	"github.com/pf-qiu/concourse/v6/vars"
     7  	vaultapi "github.com/hashicorp/vault/api"
     8  	. "github.com/onsi/ginkgo"
     9  	. "github.com/onsi/gomega"
    10  )
    11  
    12  type MockSecret struct {
    13  	path   string
    14  	secret *vaultapi.Secret
    15  }
    16  
    17  type MockSecretReader struct {
    18  	secrets *[]MockSecret
    19  }
    20  
    21  func (msr *MockSecretReader) Read(lookupPath string) (*vaultapi.Secret, error) {
    22  	Expect(lookupPath).ToNot(BeNil())
    23  
    24  	for _, secret := range *msr.secrets {
    25  		if lookupPath == secret.path {
    26  			return secret.secret, nil
    27  		}
    28  	}
    29  
    30  	return nil, nil
    31  }
    32  
    33  var _ = Describe("Vault", func() {
    34  
    35  	var v *vault.Vault
    36  	var variables vars.Variables
    37  	var msr *MockSecretReader
    38  	var varFoo vars.Reference
    39  
    40  	BeforeEach(func() {
    41  
    42  		msr = &MockSecretReader{&[]MockSecret{
    43  			{
    44  				path: "/concourse/team",
    45  				secret: &vaultapi.Secret{
    46  					Data: map[string]interface{}{"foo": "bar"},
    47  				},
    48  			}},
    49  		}
    50  
    51  		p, _ := creds.BuildSecretTemplate("p", "/concourse/{{.Team}}/{{.Pipeline}}/{{.Secret}}")
    52  		t, _ := creds.BuildSecretTemplate("t", "/concourse/{{.Team}}/{{.Secret}}")
    53  
    54  		v = &vault.Vault{
    55  			SecretReader:    msr,
    56  			Prefix:          "/concourse",
    57  			LookupTemplates: []*creds.SecretTemplate{p, t},
    58  			SharedPath:      "shared",
    59  		}
    60  
    61  		variables = creds.NewVariables(v, "team", "pipeline", false)
    62  		varFoo = vars.Reference{Path: "foo"}
    63  	})
    64  
    65  	Describe("Get()", func() {
    66  		It("should get secret from pipeline", func() {
    67  			v.SecretReader = &MockSecretReader{&[]MockSecret{
    68  				{
    69  					path: "/concourse/team/pipeline/foo",
    70  					secret: &vaultapi.Secret{
    71  						Data: map[string]interface{}{"value": "bar"},
    72  					},
    73  				}},
    74  			}
    75  			value, found, err := variables.Get(varFoo)
    76  			Expect(value).To(BeEquivalentTo("bar"))
    77  			Expect(found).To(BeTrue())
    78  			Expect(err).To(BeNil())
    79  		})
    80  
    81  		It("should get secret from team", func() {
    82  			v.SecretReader = &MockSecretReader{&[]MockSecret{
    83  				{
    84  					path: "/concourse/team/foo",
    85  					secret: &vaultapi.Secret{
    86  						Data: map[string]interface{}{"value": "bar"},
    87  					},
    88  				}},
    89  			}
    90  			value, found, err := variables.Get(varFoo)
    91  			Expect(value).To(BeEquivalentTo("bar"))
    92  			Expect(found).To(BeTrue())
    93  			Expect(err).To(BeNil())
    94  		})
    95  
    96  		It("should get secret from shared", func() {
    97  			v.SecretReader = &MockSecretReader{&[]MockSecret{
    98  				{
    99  					path: "/concourse/shared/foo",
   100  					secret: &vaultapi.Secret{
   101  						Data: map[string]interface{}{"value": "bar"},
   102  					},
   103  				}},
   104  			}
   105  			value, found, err := variables.Get(varFoo)
   106  			Expect(value).To(BeEquivalentTo("bar"))
   107  			Expect(found).To(BeTrue())
   108  			Expect(err).To(BeNil())
   109  		})
   110  
   111  		It("should get secret from pipeline even its in shared", func() {
   112  			v.SecretReader = &MockSecretReader{&[]MockSecret{
   113  				{
   114  					path: "/concourse/shared/foo",
   115  					secret: &vaultapi.Secret{
   116  						Data: map[string]interface{}{"value": "foo"},
   117  					},
   118  				},
   119  				{
   120  					path: "/concourse/team/foo",
   121  					secret: &vaultapi.Secret{
   122  						Data: map[string]interface{}{"value": "bar"},
   123  					},
   124  				}},
   125  			}
   126  			value, found, err := variables.Get(varFoo)
   127  			Expect(value).To(BeEquivalentTo("bar"))
   128  			Expect(found).To(BeTrue())
   129  			Expect(err).To(BeNil())
   130  		})
   131  
   132  		Context("with custom lookup templates", func() {
   133  			BeforeEach(func() {
   134  				a, _ := creds.BuildSecretTemplate("a", "/concourse/place1/{{.Team}}/sub/{{.Pipeline}}/{{.Secret}}")
   135  				b, _ := creds.BuildSecretTemplate("b", "/concourse/place2/{{.Team}}/{{.Secret}}")
   136  				c, _ := creds.BuildSecretTemplate("c", "/concourse/place3/{{.Secret}}")
   137  
   138  				sr := &MockSecretReader{&[]MockSecret{
   139  					{
   140  						path: "/concourse/place1/team/sub/pipeline/foo",
   141  						secret: &vaultapi.Secret{
   142  							Data: map[string]interface{}{"value": "bar"},
   143  						},
   144  					},
   145  					{
   146  						path: "/concourse/place2/team/baz",
   147  						secret: &vaultapi.Secret{
   148  							Data: map[string]interface{}{"value": "qux"},
   149  						},
   150  					},
   151  					{
   152  						path: "/concourse/place3/global",
   153  						secret: &vaultapi.Secret{
   154  							Data: map[string]interface{}{"value": "shared"},
   155  						},
   156  					}},
   157  				}
   158  
   159  				v = &vault.Vault{
   160  					SecretReader:    sr,
   161  					Prefix:          "/concourse",
   162  					LookupTemplates: []*creds.SecretTemplate{a, b, c},
   163  				}
   164  
   165  				variables = creds.NewVariables(v, "team", "pipeline", false)
   166  			})
   167  
   168  			It("should find pipeline secrets in the configured place", func() {
   169  				value, found, err := variables.Get(varFoo)
   170  				Expect(value).To(BeEquivalentTo("bar"))
   171  				Expect(found).To(BeTrue())
   172  				Expect(err).To(BeNil())
   173  			})
   174  
   175  			It("should find team secrets in the configured place", func() {
   176  				value, found, err := variables.Get(vars.Reference{Path: "baz"})
   177  				Expect(value).To(BeEquivalentTo("qux"))
   178  				Expect(found).To(BeTrue())
   179  				Expect(err).To(BeNil())
   180  			})
   181  
   182  			It("should find static secrets in the configured place", func() {
   183  				value, found, err := variables.Get(vars.Reference{Path: "global"})
   184  				Expect(value).To(BeEquivalentTo("shared"))
   185  				Expect(found).To(BeTrue())
   186  				Expect(err).To(BeNil())
   187  			})
   188  		})
   189  
   190  		Context("without shared", func() {
   191  			BeforeEach(func() {
   192  				p, _ := creds.BuildSecretTemplate("p", "/concourse/{{.Team}}/{{.Pipeline}}/{{.Secret}}")
   193  				t, _ := creds.BuildSecretTemplate("t", "/concourse/{{.Team}}/{{.Secret}}")
   194  
   195  				v = &vault.Vault{
   196  					SecretReader:    msr,
   197  					Prefix:          "/concourse",
   198  					LookupTemplates: []*creds.SecretTemplate{p, t},
   199  				}
   200  
   201  				variables = creds.NewVariables(v, "team", "pipeline", false)
   202  			})
   203  
   204  			It("should not get secret from root", func() {
   205  				v.SecretReader = &MockSecretReader{&[]MockSecret{
   206  					{
   207  						path: "/concourse/foo",
   208  						secret: &vaultapi.Secret{
   209  							Data: map[string]interface{}{"value": "foo"},
   210  						},
   211  					}},
   212  				}
   213  				_, found, err := variables.Get(varFoo)
   214  				Expect(found).To(BeFalse())
   215  				Expect(err).To(BeNil())
   216  			})
   217  		})
   218  
   219  		Context("allowRootPath", func() {
   220  			BeforeEach(func() {
   221  				v.SecretReader = &MockSecretReader{&[]MockSecret{
   222  					{
   223  						path: "/concourse/foo",
   224  						secret: &vaultapi.Secret{
   225  							Data: map[string]interface{}{"value": "foo"},
   226  						},
   227  					}},
   228  				}
   229  			})
   230  
   231  			Context("is true", func() {
   232  				BeforeEach(func() {
   233  					variables = creds.NewVariables(v, "team", "pipeline", true)
   234  				})
   235  
   236  				It("should get secret from root", func() {
   237  					_, found, err := variables.Get(varFoo)
   238  					Expect(err).To(BeNil())
   239  					Expect(found).To(BeTrue())
   240  				})
   241  			})
   242  
   243  			Context("is false", func() {
   244  				BeforeEach(func() {
   245  					variables = creds.NewVariables(v, "team", "pipeline", false)
   246  				})
   247  
   248  				It("should not get secret from root", func() {
   249  					_, found, err := variables.Get(varFoo)
   250  					Expect(err).To(BeNil())
   251  					Expect(found).To(BeFalse())
   252  				})
   253  			})
   254  		})
   255  	})
   256  })