diff --git a/CHANGELOG.md b/CHANGELOG.md index 44cc72d24..ea375c691 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ IMPROVEMENTS: BUG FIXES: + * replication: Fix an issue causing startup problems if a namespace policy + wasn't replicated properly + * replication: Properly update mount entry cache on a secondary to apply all + new values after a tune * ui: fix an issue where sensitive input values weren't being saved to the server [GH-6586] diff --git a/api/go.sum b/api/go.sum index dd8eaf304..24e7dfde4 100644 --- a/api/go.sum +++ b/api/go.sum @@ -12,7 +12,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= -github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= diff --git a/api/sys_mounts.go b/api/sys_mounts.go index 993a1b67b..354b1ee93 100644 --- a/api/sys_mounts.go +++ b/api/sys_mounts.go @@ -159,6 +159,7 @@ type MountConfigInput struct { } type MountOutput struct { + UUID string `json:"uuid"` Type string `json:"type"` Description string `json:"description"` Accessor string `json:"accessor"` diff --git a/builtin/credential/cert/backend_test.go b/builtin/credential/cert/backend_test.go index 25b7fcb73..7facab041 100644 --- a/builtin/credential/cert/backend_test.go +++ b/builtin/credential/cert/backend_test.go @@ -1112,18 +1112,34 @@ func TestBackend_ext_singleCert(t *testing.T) { // Test a self-signed client with URI alt names (root CA) that is trusted func TestBackend_dns_singleCert(t *testing.T) { - connState, err := testConnState( - "test-fixtures/root/rootcawdnscert.pem", - "test-fixtures/root/rootcawdnskey.pem", - "test-fixtures/root/rootcacert.pem", - ) + certTemplate := &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "example.com", + }, + DNSNames: []string{"example.com"}, + IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + x509.ExtKeyUsageClientAuth, + }, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageKeyAgreement, + SerialNumber: big.NewInt(mathrand.Int63()), + NotBefore: time.Now().Add(-30 * time.Second), + NotAfter: time.Now().Add(262980 * time.Hour), + } + + tempDir, connState, err := generateTestCertAndConnState(t, certTemplate) + if tempDir != "" { + defer os.RemoveAll(tempDir) + } if err != nil { t.Fatalf("error testing connection state: %v", err) } - ca, err := ioutil.ReadFile("test-fixtures/root/rootcacert.pem") + ca, err := ioutil.ReadFile(filepath.Join(tempDir, "ca_cert.pem")) if err != nil { t.Fatalf("err: %v", err) } + logicaltest.Test(t, logicaltest.TestCase{ CredentialBackend: testFactory(t), Steps: []logicaltest.TestStep{ @@ -1143,18 +1159,34 @@ func TestBackend_dns_singleCert(t *testing.T) { // Test a self-signed client with URI alt names (root CA) that is trusted func TestBackend_email_singleCert(t *testing.T) { - connState, err := testConnState( - "test-fixtures/root/rootcawemailcert.pem", - "test-fixtures/root/rootcawemailkey.pem", - "test-fixtures/root/rootcacert.pem", - ) + certTemplate := &x509.Certificate{ + Subject: pkix.Name{ + CommonName: "example.com", + }, + EmailAddresses: []string{"valid@example.com"}, + IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + x509.ExtKeyUsageClientAuth, + }, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageKeyAgreement, + SerialNumber: big.NewInt(mathrand.Int63()), + NotBefore: time.Now().Add(-30 * time.Second), + NotAfter: time.Now().Add(262980 * time.Hour), + } + + tempDir, connState, err := generateTestCertAndConnState(t, certTemplate) + if tempDir != "" { + defer os.RemoveAll(tempDir) + } if err != nil { t.Fatalf("error testing connection state: %v", err) } - ca, err := ioutil.ReadFile("test-fixtures/root/rootcacert.pem") + ca, err := ioutil.ReadFile(filepath.Join(tempDir, "ca_cert.pem")) if err != nil { t.Fatalf("err: %v", err) } + logicaltest.Test(t, logicaltest.TestCase{ CredentialBackend: testFactory(t), Steps: []logicaltest.TestStep{ diff --git a/builtin/credential/cert/test-fixtures/root/rootcawdns.cnf b/builtin/credential/cert/test-fixtures/root/rootcawdns.cnf deleted file mode 100644 index 3c576a95c..000000000 --- a/builtin/credential/cert/test-fixtures/root/rootcawdns.cnf +++ /dev/null @@ -1,17 +0,0 @@ -[ req ] -default_bits = 2048 -encrypt_key = no -prompt = no -default_md = sha256 -req_extensions = req_v3 -distinguished_name = dn - -[ dn ] -CN = example.com - -[ req_v3 ] -subjectAltName = @alt_names - -[ alt_names ] -IP.1 = 127.0.0.1 -DNS.1 = example.com diff --git a/builtin/credential/cert/test-fixtures/root/rootcawdns.csr b/builtin/credential/cert/test-fixtures/root/rootcawdns.csr deleted file mode 100644 index b56d32314..000000000 --- a/builtin/credential/cert/test-fixtures/root/rootcawdns.csr +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIEijCCAnICAQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3 -DQEBAQUAA4ICDwAwggIKAoICAQDUJ6s97BFxR295bCjpwQ85Vo8DnBFa/awNH107 -QFn/zw0ZDdJMLtEBc/bw7pTYw5ulKbiZDFrmzPEY+QZlo+t1TeWgPRJg0CbYNukS -aNv0vKXjDXYwbrCyOvZucy8hte6IKjZfH+kAsgbbUxfD75BCKsxMxbVHkg0W9Ma2 -pnZj/kpvQE5lkMj5mDvtWdfCRsVg4zL6jhRHkPZ6fOkF3mrfTbQu3oyOcbKLEE/G -t3QRKw3uv0vMDmhg62ZPvD1k70UMjUV2MVqEPZuWY7/bbW8OsfzMyBOGY9LLp7QS -krxWYRj6SPUR4f1bZq7pRbqOfS0okq/XDLf1k6Na5cT6iNdyjEVdSJl7vR7kSreX -8hkwK46Oup8v/vJLu/cRDCpAas0gJJkJDPt5114V0/Xww7EFxs5GijXP8i5RLlgK -/nRscbK+fgjQOnQ5cp0pcP8HAriy2vil7E0fQvMvt5QTyINEYgiYaCIT9WGRC8Xo -WcoUGI2vyrGy6RU6A3/TKeBLtikaSPjFKa1dFTAHfrUkTBpfqc+sbiJ334Bvucg5 -WyS8oAC5Vf++iMnETSdzx1k0/QARVLD38PO8wPaPU1M2XaSA+RHTB9SGFc4VTauT -B167NLlmgJHYuhp+KM1RTy1TEoDlJh2qKj21BLcR1GJ0KgDze6Vpf9xdRTdqMpo2 -h20wdQIDAQABoC8wLQYJKoZIhvcNAQkOMSAwHjAcBgNVHREEFTAThwR/AAABggtl -eGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAGtds+2IUVKzw9bi130mBbb9K -CrXw2NXSp+LJwneIEy0bjAaNr7zCGQsj7q57qFwjc7vLTtGRheP5myrAOq00lp8J -1sGZSETS/y4yeITLZSYWVq2dtF/hY9I+X3uOoibdsQgzYqhBcUr4oTDapf1ZEs0i -wA2J5IcasfaBpWFc9wRN79BBACLGyCbX6VwUISrGe3Hgzkeqtg97cU62ecQsgXiZ -LdQgERvC0wSfAmI4lGulXi1oYYSRxXQ8pEKEAMeJrJVQfvhdbS/o4Bdf3Yj6ibtD -tFSdKLcdRCfMQBEHNpSh665LfBbwU55Fh89tBdGmf6uqsimUY6AxNncnLsc1Kq6F -oINXix3GsBNmCahDeHdGOlNjw0Lpl0m6bnu6LXSDwwuNWAEdDfEmxR+5T/GkGxcG -TTWPwEkpnCe4VmGl9Y10uPSvqneNsdNWjDVK4BeW4VSf9Lp1Zeme1dYFvpyzow+r -4ogpvMPf5vy5I/0HCEf1KlaPyhs8ZGK6YBGaeEDYSaysAWJfYm8eiqwUuKYj/FUe -G3KkaFpOGsQHFNRtG8GukV3r2AK97HFHKNfygZ2xvk5isXz2ZsNX1/J0+GGjalJl -cWBBEiXFM94XJHE9rACsL2UKn8cWCh9lHNLlePOkQuoNY9CUd63xx4Hg97XWP3+U -DhpG7CADsKcPJfbMgrk= ------END CERTIFICATE REQUEST----- diff --git a/builtin/credential/cert/test-fixtures/root/rootcawdnscert.pem b/builtin/credential/cert/test-fixtures/root/rootcawdnscert.pem deleted file mode 100644 index 2ce633e3a..000000000 --- a/builtin/credential/cert/test-fixtures/root/rootcawdnscert.pem +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDzzCCAregAwIBAgIJAJIiPq+77herMA0GCSqGSIb3DQEBBQUAMBYxFDASBgNV -BAMTC2V4YW1wbGUuY29tMB4XDTE4MDQyNjEyMDEzMFoXDTE5MDQyNjEyMDEzMFow -FjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDUJ6s97BFxR295bCjpwQ85Vo8DnBFa/awNH107QFn/zw0ZDdJMLtEB -c/bw7pTYw5ulKbiZDFrmzPEY+QZlo+t1TeWgPRJg0CbYNukSaNv0vKXjDXYwbrCy -OvZucy8hte6IKjZfH+kAsgbbUxfD75BCKsxMxbVHkg0W9Ma2pnZj/kpvQE5lkMj5 -mDvtWdfCRsVg4zL6jhRHkPZ6fOkF3mrfTbQu3oyOcbKLEE/Gt3QRKw3uv0vMDmhg -62ZPvD1k70UMjUV2MVqEPZuWY7/bbW8OsfzMyBOGY9LLp7QSkrxWYRj6SPUR4f1b -Zq7pRbqOfS0okq/XDLf1k6Na5cT6iNdyjEVdSJl7vR7kSreX8hkwK46Oup8v/vJL -u/cRDCpAas0gJJkJDPt5114V0/Xww7EFxs5GijXP8i5RLlgK/nRscbK+fgjQOnQ5 -cp0pcP8HAriy2vil7E0fQvMvt5QTyINEYgiYaCIT9WGRC8XoWcoUGI2vyrGy6RU6 -A3/TKeBLtikaSPjFKa1dFTAHfrUkTBpfqc+sbiJ334Bvucg5WyS8oAC5Vf++iMnE -TSdzx1k0/QARVLD38PO8wPaPU1M2XaSA+RHTB9SGFc4VTauTB167NLlmgJHYuhp+ -KM1RTy1TEoDlJh2qKj21BLcR1GJ0KgDze6Vpf9xdRTdqMpo2h20wdQIDAQABoyAw -HjAcBgNVHREEFTAThwR/AAABggtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQUFAAOC -AQEA2JswcCYtHvOm2QmSEVeFcCeVNkzr35FXATamJv0oMMjjUFix78MW03EW6vJa -E52e3pBvRdy+k2fuq/RtHIUKzB6jNbv0Vds26Dq+pmGeoaQZOW94/Wht7f9pZgBi -IRPBg9oACtyNAuDsCOdetOyvyoU29sjUOUoQZbEXF+FK4lRJrEmZUJHbp/BOD58V -mQRtjTMjQlZZropqBQmooMRYU0qgWHaIjyoQpu2MgEj3+/1b1IX6SCfRuit0auh/ -YI3/cCtyAG/DpZ6zfyXuyY+iN+l8B6t0nXyV3g8JgBWYPGJv1hgVIgnnqlwuL517 -mEAT5RnHCNJQNuzS1dwfuBrX3w== ------END CERTIFICATE----- diff --git a/builtin/credential/cert/test-fixtures/root/rootcawdnskey.pem b/builtin/credential/cert/test-fixtures/root/rootcawdnskey.pem deleted file mode 100644 index 15db567e0..000000000 --- a/builtin/credential/cert/test-fixtures/root/rootcawdnskey.pem +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDUJ6s97BFxR295 -bCjpwQ85Vo8DnBFa/awNH107QFn/zw0ZDdJMLtEBc/bw7pTYw5ulKbiZDFrmzPEY -+QZlo+t1TeWgPRJg0CbYNukSaNv0vKXjDXYwbrCyOvZucy8hte6IKjZfH+kAsgbb -UxfD75BCKsxMxbVHkg0W9Ma2pnZj/kpvQE5lkMj5mDvtWdfCRsVg4zL6jhRHkPZ6 -fOkF3mrfTbQu3oyOcbKLEE/Gt3QRKw3uv0vMDmhg62ZPvD1k70UMjUV2MVqEPZuW -Y7/bbW8OsfzMyBOGY9LLp7QSkrxWYRj6SPUR4f1bZq7pRbqOfS0okq/XDLf1k6Na -5cT6iNdyjEVdSJl7vR7kSreX8hkwK46Oup8v/vJLu/cRDCpAas0gJJkJDPt5114V -0/Xww7EFxs5GijXP8i5RLlgK/nRscbK+fgjQOnQ5cp0pcP8HAriy2vil7E0fQvMv -t5QTyINEYgiYaCIT9WGRC8XoWcoUGI2vyrGy6RU6A3/TKeBLtikaSPjFKa1dFTAH -frUkTBpfqc+sbiJ334Bvucg5WyS8oAC5Vf++iMnETSdzx1k0/QARVLD38PO8wPaP -U1M2XaSA+RHTB9SGFc4VTauTB167NLlmgJHYuhp+KM1RTy1TEoDlJh2qKj21BLcR -1GJ0KgDze6Vpf9xdRTdqMpo2h20wdQIDAQABAoICAQDJxszUQQC554I7TsZ+xBJx -q0Sr3zSWgOuxM2Jdpy+x38AKUx3vPRulsSBtN8yzeR9Ab7TVQ231U3f/E2GlK8kW -sTazN0KSd4ZqX5c+3iJM21s+3p/JIo3FhdS5aa2q9zjdoqBByry135wr3xScUu22 -MLRMVEG8x0jRy45vS1UQd1teAiBN8u1ijgp5DNjrOpohMxVaPeVFx7bU+pY58bdd -mK7FYP73v2VbY/EsA3FNntBKgQBbHFzjyR9uuI7/v53BeV9WMUxwt5OR7l8cGDHn -HRtdvPDtAWYMMf1PKOYdlY3HBbqn/nMUCk5TKPFs8dsQWqsI8lzIIVndauj0i0+0 -M/lVMXu4x48o5FfLa4HjkpcDxAU6QDHA9thaDkasZebixVH/p1ZJkLORl5jDLYkU -Av+B3i1efITwNYgosZNjPpw0PyYh9PV9JvB87d5wFpgISfZyRXpBVGeJbt6gg++8 -8/5A/GzSpGy0FhLcP3vuVTcX2VOexjqeaoi4U3cHrbWv/wNj5a4BNk5EJT8fVeSb -+Emqydl9u3n2E315GPC8kwxdE3r3hGrWdZQn9byGvqzwDaLWXQLQWvQN4GOpGTrP -Yxj2Oi8s1MJHkppj4eo52O4J7cBlAJn3RFmlCKGOoWJZMdPktp/gWeT+xIGSaa21 -qB+l/ZFEWLPMxdTBMGFmYQKCAQEA8DgozaZBXr7mb1H25EbW9YmtLc61JMapQrZb -ObygiGR6RZsxCXEvGdhvvmwpO8rA9wAOWqI8NV5GU8EvuRuwvGoX4HqbXkB6ZcyC -6RuZzki2lrKVGUaLc1v6MyhX4IzrqTYWDgQvwd9lMcUGR7r007KPE5ft4v3/TuxQ -qPKxQE7NO2xnTloUchd5g0/d975GZi0g6XDecFOuj43Pi0c/wRcFH6zfVirdcm+M -yP9CsJ/LUgtV1voLqyhfybwHvzpxJ0l25Fw+P85I4czosBp+FaFAwogxZEDnY8Fr -Hqcwdc7vwGDjTbtflDsUdppt2h8nD8bBZGysG8+P8HAt3i5D+QKCAQEA4heKueRQ -Y8nTZlmRSRtB6usRAeymQBJjO+yWwu/06Efg8VW5QRwtP0sx+syrLaQDy8MT07II -XQZmq55xATWbHCxULiceIY2KG5LHCovVotYAll8ov58exJva19C7/41uVrkl3H9j -xFLX0Bn3zMFKBOxKhygP2xqqEJdb1JJt27c2CbXvXOzqIZ4RCaNQdBdrlEiXQihR -JCGMUBfrYIwALQFzYuPGULhg77YcAi5owCPnfK+dDOOvMmW8BwPnRUc14WFIVV+m -dbY22WonLNPP055W5755Xl9RHKW1bcmIH6E4QZpMrlnd1UzPBQq1PJtcO3uRc5T6 -CMQSUmwMGSQ3XQKCAQBiuVHborY+8AnYOkFTc+GoK5rmtosvwA2UA0neoqz/IPw3 -Wx5+GOwYnSDfi6gukJdZa8Z6bS59aG9SwJSSaNTrulZxxTHRPIKRD8nFb7h4VN3l -dSNdreZl1KkxGSV0fbXkZvwNap8N+HeoSqbYF/fCgSHYFZqIrYadsvU7WfKK0Vf7 -UgPq6Y55jTg9RTeeN67LE0Txa5efZmTZTpi7Tt7exk0uxWdMDHXSMBIWEQIhgKqY -31u57C2bfA5R5FrytlwGn2SjWV2j7214jzQaG+kxjoIE8OALqbjvAHC7uk5qPE/A -KpGAQr93Ngik7baz7BWroC2eziK1k0o+sHvJUg5RAoIBABF+ftZ5axr9j+T4gzxj -5orV24AJnqeQhKsrWFMHHC0o+qfR2T7HflzKZbihQ5GJgl2u34be3LTN/P3Eibvt -OO5KI81aa4NvH0OY7NvNDB/IbU01WcLR/iB6asmONi3E9MezFdHk7YRQYLCSgdEP -F7ofyniAyhFLE+OqwolFN0jr+TtxH29SSZ+GSo0zXNNOyJ01rLaKxhSEoAXGhAj5 -bD4PQa1iMIMocR+7OJmWm7ZaUNwd/onzyCefJZhpXejHZMzmqSEqAIhVLBNQmm1m -iks2kkTmQR/jQjR0QgCXunewEtlIpixLedW6Vr5uIK3q240it5N48IvjGAPWpmz/ -l2UCggEBALRlARlBdYcPhWbcyhq9suq2PJqHVvNdP9vVTZpPgmWgxmj9mPQ731Q/ -UpRlBIk6U0qAxBXP9kzPqSivWhY8Jto80Jdr+/80PkdANDkpnXoDlxPk095sD2uN -Jv5FffFgMZH9MGpPTEuZ571/YtVi+1qFt0i3oazpF/g8gU23f2oxaX4xzsltVl8J -rWXYzmYE0i5Qiy81+zZ9dZlnmlKhcYpD6m2t/0hRAoNaoxOUV7WFcIzYIxpKvzYL -QTDL/Se2Ooc0xLQvM1oZ9/1NE2hpGQ/ipASEPlx9KO5ktYW7+LwdcSCMXtx84I/D -VQpWjPdILMpiVrB/9NsENTNv2DUvc+o= ------END PRIVATE KEY----- diff --git a/builtin/credential/cert/test-fixtures/root/rootcawemail.cnf b/builtin/credential/cert/test-fixtures/root/rootcawemail.cnf deleted file mode 100644 index f679fb987..000000000 --- a/builtin/credential/cert/test-fixtures/root/rootcawemail.cnf +++ /dev/null @@ -1,17 +0,0 @@ -[ req ] -default_bits = 2048 -encrypt_key = no -prompt = no -default_md = sha256 -distinguished_name = dn -req_extensions = req_v3 - -[ req_v3 ] -subjectAltName = @alt_names - -[ dn ] -CN = example.com - -[ alt_names ] -IP.1 = 127.0.0.1 -email = valid@example.com diff --git a/builtin/credential/cert/test-fixtures/root/rootcawemail.csr b/builtin/credential/cert/test-fixtures/root/rootcawemail.csr deleted file mode 100644 index 44b191495..000000000 --- a/builtin/credential/cert/test-fixtures/root/rootcawemail.csr +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIEkDCCAngCAQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3 -DQEBAQUAA4ICDwAwggIKAoICAQDO7stcdJQwUtVeJriwpAswDAirO827peSlgdxs -fW8X9M2hE9ihvESEILb7TRMRiFlDyQYg1BxKMrJ0DZmixFi8RvUCZbH6TFOUMsk+ -w1FhpzjuqAqxNQ51s7u30sfruJg7XN3YJLEPelom62wvzhvLXJFLQZlQCDrMx+PC -ofWs4IA7jR8JaXZjIGdkEU0GgRPy8zKPUe3dUBHi2UR4eKT4cRCn4IwCrFx4BQjV -AxNKNDGpe+fTVOzII/UX+FppDdGZZ4g0y3E1mQUEKkff4dKCK7vhlGJR9D+5v/V0 -/stwP72aXczijuVtnXXyli+oj24NaijoqQluNCD3MvV/INovLL2Tyk54H3/GvpU1 -+sJbpE2+UPh+Rh8DNkT6RPRguymJO8MSsdLt/qvVD8BlZ7I9V3XZlDKosCRTUyxf -jjFpa+VzB3nt7uFtIXZ9HNGhQIpOULvkFGizWV+tS8PpGdTFVzDjyWg0HUKWn8g8 -IiWR9S40h6mHjVuTuxA9tlO69PuTjGK7MlAvFTDaPC8seau1LUiqtQ+prnSLI0h1 -6GfI9W2G7BKKVPloErODhLcsOcwRcmaJVW+yBda3te8+cMBIvtQYKAYSCtg8qXws -xyfPLo4GChbGGRbRCuM3mB1lG1qHEivJ0vynsgolp0t8jaXSFVBVgYj+C6Vd9/hl -ieUcOwIDAQABoDUwMwYJKoZIhvcNAQkOMSYwJDAiBgNVHREEGzAZhwR/AAABgRF2 -YWxpZEBleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAe1u3wYMMKaZ3d5Wz -jKH971CF3sl+KYl+oV0ekD8dbYe+szERgajn6Y5IYVxxi5o9UgeAWqnyHCiqsW8T -MQdUwMa67Ym/pHKSVoBlGePAKHqock0+iSsVBMcPpU9RkxdSW2aVtdb0DGfyB952 -t3dSb0LaITu30fe8p7lxrL0DKESbwd4N2XQE1F5Vf+1OodvpJinn4Wqzn45hqRf0 -imxrCgVjT5VtR+NRzKCK3Msmh+cJGpR3zgXwGKqgHLWzhvSoQwRWYE3apMK5xLk7 -N1sWVxEKK5+L/CDaMNGQFx5lPiCN3bUudCq4uSZcPLO5AuDpSeLKnknBrWA6HcbB -WvnwtKmHeVe2qogPViKGuwE16rnPlp9hysPl2ckmtqEsXRagIAh5fMI3OoRbZmVV -jfJm21U4YkUWuMKet3EU1StT6T8T6O7QEFA4w4s5+m3dsjDZ9iTuK9/dCs1xnIke -4uJYmh3YrNl8IjMffJuWxA+/de3JO1UljC2EAFxa5KAc24+qyeWwky4tMv72gTOp -6q3k2wnsrK5B1errRV37OLgxtoh1I3Rgp+0B77SOK/PpD/JJazJG5O9bBJOvHJc0 -STW9Td2CzgC2lKGfvkX6UYgVy/9HDq7/EKXP/G2f3kRik2NPUhGcnAH9nyL9SvpP -+T4CZ+FumDj5DulARk6arSq+uy4= ------END CERTIFICATE REQUEST----- diff --git a/builtin/credential/cert/test-fixtures/root/rootcawemailcert.pem b/builtin/credential/cert/test-fixtures/root/rootcawemailcert.pem deleted file mode 100644 index f774a7182..000000000 --- a/builtin/credential/cert/test-fixtures/root/rootcawemailcert.pem +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID1TCCAr2gAwIBAgIJAJIiPq+77hevMA0GCSqGSIb3DQEBBQUAMBYxFDASBgNV -BAMTC2V4YW1wbGUuY29tMB4XDTE4MDQyNjEyMjE1MloXDTE5MDQyNjEyMjE1Mlow -FjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDO7stcdJQwUtVeJriwpAswDAirO827peSlgdxsfW8X9M2hE9ihvESE -ILb7TRMRiFlDyQYg1BxKMrJ0DZmixFi8RvUCZbH6TFOUMsk+w1FhpzjuqAqxNQ51 -s7u30sfruJg7XN3YJLEPelom62wvzhvLXJFLQZlQCDrMx+PCofWs4IA7jR8JaXZj -IGdkEU0GgRPy8zKPUe3dUBHi2UR4eKT4cRCn4IwCrFx4BQjVAxNKNDGpe+fTVOzI -I/UX+FppDdGZZ4g0y3E1mQUEKkff4dKCK7vhlGJR9D+5v/V0/stwP72aXczijuVt -nXXyli+oj24NaijoqQluNCD3MvV/INovLL2Tyk54H3/GvpU1+sJbpE2+UPh+Rh8D -NkT6RPRguymJO8MSsdLt/qvVD8BlZ7I9V3XZlDKosCRTUyxfjjFpa+VzB3nt7uFt -IXZ9HNGhQIpOULvkFGizWV+tS8PpGdTFVzDjyWg0HUKWn8g8IiWR9S40h6mHjVuT -uxA9tlO69PuTjGK7MlAvFTDaPC8seau1LUiqtQ+prnSLI0h16GfI9W2G7BKKVPlo -ErODhLcsOcwRcmaJVW+yBda3te8+cMBIvtQYKAYSCtg8qXwsxyfPLo4GChbGGRbR -CuM3mB1lG1qHEivJ0vynsgolp0t8jaXSFVBVgYj+C6Vd9/hlieUcOwIDAQABoyYw -JDAiBgNVHREEGzAZhwR/AAABgRF2YWxpZEBleGFtcGxlLmNvbTANBgkqhkiG9w0B -AQUFAAOCAQEAp2T99t93hxPyCDaqfTF0lsdzIgxZ5GkSzYTYQ2pekLfMDUUy4WFQ -AppdnSJSpm6b+xWO2DkO8UAgOdSEORf/Qpfm+UpHaEYZlQiWQ0zNmIQgBoh6indU -bEZKeL6aAOfIshPNfmqjFt+DpEClrQvCHJggG/rB77Ujj6hPY2+8h4JjbjeX7Pe9 -oUEx9LpZ5Qpo6PK5vB537PP7Q2qp2PIr29DLz1VeLCbqUnV+j7qT0T3hhqurnpTA -QUiRZI0etgeP/B5lw/S4AWijq+R6RasdPAS4UNHsYK+PSGiqdhW/bJvSx5UBXQbk -DuY2A4kdv60H5Aw45/F6enH2Fg1kg7PlQA== ------END CERTIFICATE----- diff --git a/builtin/credential/cert/test-fixtures/root/rootcawemailkey.pem b/builtin/credential/cert/test-fixtures/root/rootcawemailkey.pem deleted file mode 100644 index 13b165782..000000000 --- a/builtin/credential/cert/test-fixtures/root/rootcawemailkey.pem +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDO7stcdJQwUtVe -JriwpAswDAirO827peSlgdxsfW8X9M2hE9ihvESEILb7TRMRiFlDyQYg1BxKMrJ0 -DZmixFi8RvUCZbH6TFOUMsk+w1FhpzjuqAqxNQ51s7u30sfruJg7XN3YJLEPelom -62wvzhvLXJFLQZlQCDrMx+PCofWs4IA7jR8JaXZjIGdkEU0GgRPy8zKPUe3dUBHi -2UR4eKT4cRCn4IwCrFx4BQjVAxNKNDGpe+fTVOzII/UX+FppDdGZZ4g0y3E1mQUE -Kkff4dKCK7vhlGJR9D+5v/V0/stwP72aXczijuVtnXXyli+oj24NaijoqQluNCD3 -MvV/INovLL2Tyk54H3/GvpU1+sJbpE2+UPh+Rh8DNkT6RPRguymJO8MSsdLt/qvV -D8BlZ7I9V3XZlDKosCRTUyxfjjFpa+VzB3nt7uFtIXZ9HNGhQIpOULvkFGizWV+t -S8PpGdTFVzDjyWg0HUKWn8g8IiWR9S40h6mHjVuTuxA9tlO69PuTjGK7MlAvFTDa -PC8seau1LUiqtQ+prnSLI0h16GfI9W2G7BKKVPloErODhLcsOcwRcmaJVW+yBda3 -te8+cMBIvtQYKAYSCtg8qXwsxyfPLo4GChbGGRbRCuM3mB1lG1qHEivJ0vynsgol -p0t8jaXSFVBVgYj+C6Vd9/hlieUcOwIDAQABAoICAQDFitqh6TxqITlFBwv6vK9d -b696371XrFdo1F57RwcdxHnkklCUnWh/BcgIgJx6eUJV3nq2LibPgjQva6hF5NCc -89QDNNfBjMmgyRaqjsSKx5sm4U5Lus2R+UFzi4mEcpUI3m99XhGVKAUV8Fo4DLcl -3LlrMTVNXH3dbdj0va4NGcfwkZiWYJI+sPliYs24LtK/dADJJro/MqfQef7OTsWV -0kHHMSoXhzlC7fNvfd8VUFw0Ym99pC3iJclc155feWyk2FwDok7xjqFmR4KTrD1M -PLm/7+ooOFX5WdHVnULSZlb3HSJxCV7l1JJ7QXo/nKS/s59X875n8OWjdoc7lD4T -Xw/K9CzJCyhJ/HDhTAea1+MNTig4a6wjdSim6vasig/Gkot6jjS2lhnZae8ZhYxP -GUx4JcPthHppgHt8s6Jb2PHuqNVRmVB0x41c5mmXOnJcSqOX0XhbSbeS1TUV8BiC -HMaa+agt7RpQOb5uxpb+Hath/88tsjDXI0ZHNAG43ndkHxSQQ9P/q/m5uaLwuJyo -Yb06yUy/g7ceXpJFjGsjO+33DmamvligqOswgg+oazMFo8S9ZUJw6sSXhM/XiHla -JOj+Vatfj0ViVcaGlO2kWughuCT5thn92bgC9V2VnJhbaSzSaQlRphlbuSYJEYj0 -S1uIbwPzTrcBQuekwY50YQKCAQEA/vve5K/nAnw4KLSrKwwCp9trYSm8C5czv2jV -tn6vQtckQMrw/hubX7TcTTgTuGboGdHMwZMFJBKpx6AlRHCR5IBw8fR1z+58c+2V -VJgllc23eKwCcBMKoe6LmsiUXOWmc7MuHc+qQS+9OemO93nNafsSwFCkucBFQs/3 -Yx7J3zNvMOuy+dq3jrxO0xl2jBF0pcmJF/czrvbMCD7tvDntgqvpAnybgrwm2cu3 -Q5F6i+E5w6VDhCprQL/aK95iT7cPmfdGxsUCdfNzDGIJFHZp2Hrar1TsOP6ESsDl -Q/Oz9oO1vMy7MymJjWFoVELBlCBxDEgubyM1f8cE1tQ6UAqFSwKCAQEAz8HnKWPe -NWZtqdAzSmY+3ZxSe1BbukOo4XtCV8LfRHGazKpXMTqsO9l7ynK7ifXv3b3GHTr+ -ck2Af/vyiVx6f7Ty2dmBotFQDzg0HfKD2skAPyH8cHpA8TUeL3yMOR3XQU5/pOnG -tn84n7KWpAyZXh8gzMnmzWjMlb9pUlkKcATUj0gb8iSa9PV0zBwMKYKY0ngznJT2 -CgE1vhy59rpuUVMrQ8i5iW9jbqYVrqID+ta2DWgcLsEXft7jKfupnRHF0Dvc650p -+Lkxv0YgKjUg5sYc2QJbIiBxXaW0cTRrw/KfOe4kvdG5RMF60Six+W1DIW2l+qi3 -irnDRvRm1N6e0QKCAQEA86d5MaxJIl3TSEqEeikK7J3GuV0pHSZKQ7EI70+VaFiv -gt6qdReqXEU2cu+QIJjtV6bcc2lq8zKGXITSt9ieAO0fgIWqgpyQ/jJcjS6qU8D1 -fnFYDwKTGXQaoTjkVPT6HvtsqP4E4i+dMZbWj/MrcAeEvpMRJZLuXE7gRi5ol0nO -CcBhEVKILvQQmrZtSqFvhvDTeTw2fg3FoGeJw2DTbheaHE84RzBGK774C7Abm0kI -asUkhEoInSH3eA4UgbobRXQ+hLhDhrSxDncr2ArjUALtr7eF11yWy9wR+OIK6Rio -9JXqmJQrphcbm9ECq+poPGVJQdgySjzCigrZAh1biwKCAQBiBnFVXCOaOov/lZa9 -weRjl8BrIo1FI2tpiEjTM8U4fAm4C588QRzG2GTKLrxB6eKVU1dIr28i62J4AJ59 -JT8/RldXZoL+GZiWtcQRZT3FWxVctGJxh51gsdleOnvG70eDLtCXNR5nOTu0TgU5 -viAXAsTtG05lGM9+0GOXUR/VntHUEQfuhkr+zVmgfJNYeqA0njZr6PT134BGBTPR -MEGg6Yb+YpT4PbBCouaUESmjju8zAC5b+Qtm9y9jvbRXwez9xWEFYpBNJMROJX5D -q/GsMUmnMq9hOMGEmAy9ZSh7udxa7vwy++NYh5m1Wmgu8di8ywmHbVe8gs2aivKB -+dAhAoIBAQC7nSuRSmRGeKJCAqikMFPVdFdLaTnEw4i/fcyYsPa+o2hTWXyLll8K -lwSnBxe+BCvdeQ8cWzg3rPaIBVzUjDecZjdwjcHnhlHvgHjEvFX339rvpD7J2HIb -DaVqvtPniCFdNK4Jyvd3JMtNq34SIHFAcmB9358JuKsOwCmk8CpMAqKPVsKj7m6H -ETISh/K8aI2vZxVZ4WN4FsQTCqmtQDXFSGpZF5EZSpMJIB3ZZLt2jyyDW2DaZ+1T -yuVl9jU56fTtacQROQY7cvrwznX0lFpmniwl0Aj0wln/svFAqKo1+RujqApw5iYn -ssH1dH2tESx6RpMMyLYihjHVDC/ULUVu ------END PRIVATE KEY----- diff --git a/builtin/logical/aws/backend_test.go b/builtin/logical/aws/backend_test.go index 709089d67..234489027 100644 --- a/builtin/logical/aws/backend_test.go +++ b/builtin/logical/aws/backend_test.go @@ -7,6 +7,7 @@ import ( "net/http" "os" "reflect" + "strings" "sync" "testing" "time" @@ -556,6 +557,27 @@ func describeAzsTestUnauthorized(accessKey, secretKey, token string) error { }) } +func assertCreatedIAMUser(accessKey, secretKey, token string) error { + creds := credentials.NewStaticCredentials(accessKey, secretKey, token) + awsConfig := &aws.Config{ + Credentials: creds, + Region: aws.String("us-east-1"), + HTTPClient: cleanhttp.DefaultClient(), + } + client := iam.New(session.New(awsConfig)) + log.Printf("[WARN] Checking if IAM User is created properly...") + userOutput, err := client.GetUser(&iam.GetUserInput{}) + if err != nil { + return err + } + + if *userOutput.User.Path != "/path/" { + return fmt.Errorf("bad: got: %#v\nexpected: %#v", userOutput.User.Path, "/path/") + } + + return nil +} + func listIamUsersTest(accessKey, secretKey, token string) error { creds := credentials.NewStaticCredentials(accessKey, secretKey, token) awsConfig := &aws.Config{ @@ -647,12 +669,13 @@ func testAccStepReadPolicy(t *testing.T, name string, value string) logicaltest. } expected := map[string]interface{}{ - "policy_arns": []string(nil), - "role_arns": []string(nil), - "policy_document": value, - "credential_types": []string{iamUserCred, federationTokenCred}, - "default_sts_ttl": int64(0), - "max_sts_ttl": int64(0), + "policy_arns": []string(nil), + "role_arns": []string(nil), + "policy_document": value, + "credential_type": strings.Join([]string{iamUserCred, federationTokenCred}, ","), + "default_sts_ttl": int64(0), + "max_sts_ttl": int64(0), + "user_path": "", } if !reflect.DeepEqual(resp.Data, expected) { return fmt.Errorf("bad: got: %#v\nexpected: %#v", resp.Data, expected) @@ -743,15 +766,18 @@ func TestBackend_iamUserManagedInlinePolicies(t *testing.T) { "policy_document": testDynamoPolicy, "policy_arns": []string{ec2PolicyArn, iamPolicyArn}, "credential_type": iamUserCred, + "user_path": "/path/", } expectedRoleData := map[string]interface{}{ - "policy_document": compacted, - "policy_arns": []string{ec2PolicyArn, iamPolicyArn}, - "credential_types": []string{iamUserCred}, - "role_arns": []string(nil), - "default_sts_ttl": int64(0), - "max_sts_ttl": int64(0), + "policy_document": compacted, + "policy_arns": []string{ec2PolicyArn, iamPolicyArn}, + "credential_type": iamUserCred, + "role_arns": []string(nil), + "default_sts_ttl": int64(0), + "max_sts_ttl": int64(0), + "user_path": "/path/", } + logicaltest.Test(t, logicaltest.TestCase{ AcceptanceTest: true, PreCheck: func() { testAccPreCheck(t) }, @@ -760,7 +786,7 @@ func TestBackend_iamUserManagedInlinePolicies(t *testing.T) { testAccStepConfig(t), testAccStepWriteRole(t, "test", roleData), testAccStepReadRole(t, "test", expectedRoleData), - testAccStepRead(t, "creds", "test", []credentialTestFunc{describeInstancesTest, listIamUsersTest, listDynamoTablesTest}), + testAccStepRead(t, "creds", "test", []credentialTestFunc{describeInstancesTest, listIamUsersTest, listDynamoTablesTest, assertCreatedIAMUser}), testAccStepRead(t, "sts", "test", []credentialTestFunc{describeInstancesTest, listIamUsersTest, listDynamoTablesTest}), }, }) @@ -881,12 +907,13 @@ func testAccStepReadArnPolicy(t *testing.T, name string, value string) logicalte } expected := map[string]interface{}{ - "policy_arns": []string{value}, - "role_arns": []string(nil), - "policy_document": "", - "credential_types": []string{iamUserCred}, - "default_sts_ttl": int64(0), - "max_sts_ttl": int64(0), + "policy_arns": []string{value}, + "role_arns": []string(nil), + "policy_document": "", + "credential_type": iamUserCred, + "default_sts_ttl": int64(0), + "max_sts_ttl": int64(0), + "user_path": "", } if !reflect.DeepEqual(resp.Data, expected) { return fmt.Errorf("bad: got: %#v\nexpected: %#v", resp.Data, expected) diff --git a/builtin/logical/aws/path_roles.go b/builtin/logical/aws/path_roles.go index 40e53c474..6091d9310 100644 --- a/builtin/logical/aws/path_roles.go +++ b/builtin/logical/aws/path_roles.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "regexp" "strings" "time" @@ -16,6 +17,10 @@ import ( "github.com/hashicorp/vault/sdk/logical" ) +var ( + userPathRegex = regexp.MustCompile(`^\/([\x21-\x7F]{0,510}\/)?$`) +) + func pathListRoles(b *backend) *framework.Path { return &framework.Path{ Pattern: "roles/?$", @@ -89,6 +94,13 @@ or IAM role to assume`, Description: "Deprecated; use policy_document instead. IAM policy document", Deprecated: true, }, + + "user_path": &framework.FieldSchema{ + Type: framework.TypeString, + Description: "Path for IAM User. Only valid when credential_type is " + iamUserCred, + DisplayName: "User Path", + Default: "/", + }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -245,6 +257,20 @@ func (b *backend) pathRolesWrite(ctx context.Context, req *logical.Request, d *f roleEntry.MaxSTSTTL = time.Duration(maxSTSTTLRaw.(int)) * time.Second } + if userPathRaw, ok := d.GetOk("user_path"); ok { + if legacyRole != "" { + return logical.ErrorResponse("cannot supply deprecated role or policy parameters with user_path"), nil + } + if !strutil.StrListContains(roleEntry.CredentialTypes, iamUserCred) { + return logical.ErrorResponse(fmt.Sprintf("user_path parameter only valid for %s credential type", iamUserCred)), nil + } + if !userPathRegex.MatchString(userPathRaw.(string)) { + return logical.ErrorResponse(fmt.Sprintf("The specified value for user_path is invalid. It must match '%s' regexp", userPathRegex.String())), nil + } + + roleEntry.UserPath = userPathRaw.(string) + } + if roleEntry.MaxSTSTTL > 0 && roleEntry.DefaultSTSTTL > 0 && roleEntry.DefaultSTSTTL > roleEntry.MaxSTSTTL { @@ -432,6 +458,7 @@ type awsRoleEntry struct { Version int `json:"version"` // Version number of the role format DefaultSTSTTL time.Duration `json:"default_sts_ttl"` // Default TTL for STS credentials MaxSTSTTL time.Duration `json:"max_sts_ttl"` // Max allowed TTL for STS credentials + UserPath string `json:"user_path"` // The path for the IAM user when using "iam_user" credential type } func (r *awsRoleEntry) toResponseData() map[string]interface{} { @@ -442,7 +469,9 @@ func (r *awsRoleEntry) toResponseData() map[string]interface{} { "policy_document": r.PolicyDocument, "default_sts_ttl": int64(r.DefaultSTSTTL.Seconds()), "max_sts_ttl": int64(r.MaxSTSTTL.Seconds()), + "user_path": r.UserPath, } + if r.InvalidData != "" { respData["invalid_data"] = r.InvalidData } diff --git a/builtin/logical/aws/path_roles_test.go b/builtin/logical/aws/path_roles_test.go index 3f9ae1977..c421da606 100644 --- a/builtin/logical/aws/path_roles_test.go +++ b/builtin/logical/aws/path_roles_test.go @@ -4,6 +4,7 @@ import ( "context" "reflect" "strconv" + "strings" "testing" "github.com/hashicorp/vault/sdk/logical" @@ -154,3 +155,61 @@ func TestUpgradeLegacyPolicyEntry(t *testing.T) { t.Fatalf("bad: expected %#v; received %#v", expected, *output) } } + +func TestUserPathValidity(t *testing.T) { + + testCases := []struct { + description string + userPath string + isValid bool + }{ + { + description: "Default", + userPath: "/", + isValid: true, + }, + { + description: "Empty", + userPath: "", + isValid: false, + }, + { + description: "Valid", + userPath: "/path/", + isValid: true, + }, + { + description: "Missing leading slash", + userPath: "path/", + isValid: false, + }, + { + description: "Missing trailing slash", + userPath: "/path", + isValid: false, + }, + { + description: "Invalid character", + userPath: "/šiauliai/", + isValid: false, + }, + { + description: "Max length", + userPath: "/" + strings.Repeat("a", 510) + "/", + isValid: true, + }, + { + description: "Too long", + userPath: "/" + strings.Repeat("a", 511) + "/", + isValid: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + if tc.isValid != userPathRegex.MatchString(tc.userPath) { + t.Fatalf("bad: expected %s", strconv.FormatBool(tc.isValid)) + } + }) + } +} diff --git a/builtin/logical/aws/secret_access_keys.go b/builtin/logical/aws/secret_access_keys.go index a8439b6b2..a597b1712 100644 --- a/builtin/logical/aws/secret_access_keys.go +++ b/builtin/logical/aws/secret_access_keys.go @@ -180,9 +180,15 @@ func (b *backend) secretAccessKeysCreate( return nil, errwrap.Wrapf("error writing WAL entry: {{err}}", err) } + userPath := role.UserPath + if userPath == "" { + userPath = "/" + } + // Create the user _, err = iamClient.CreateUser(&iam.CreateUserInput{ UserName: aws.String(username), + Path: aws.String(userPath), }) if err != nil { if walErr := framework.DeleteWAL(ctx, s, walID); walErr != nil { diff --git a/command/auth_list.go b/command/auth_list.go index d7032e87b..48780efba 100644 --- a/command/auth_list.go +++ b/command/auth_list.go @@ -143,7 +143,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri } } - out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Token Type | Replication | Seal Wrap | Options | Description"} + out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Token Type | Replication | Seal Wrap | Options | Description | UUID"} for _, path := range paths { mount := auths[path] @@ -160,7 +160,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri pluginName = mount.Config.PluginName } - out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s | %t | %v | %s", + out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s | %t | %v | %s | %s", path, pluginName, mount.Accessor, @@ -171,6 +171,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri mount.SealWrap, mount.Options, mount.Description, + mount.UUID, )) } diff --git a/command/secrets_list.go b/command/secrets_list.go index c88e2b286..87a95fe58 100644 --- a/command/secrets_list.go +++ b/command/secrets_list.go @@ -143,7 +143,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) } } - out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Force No Cache | Replication | Seal Wrap | Options | Description"} + out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Force No Cache | Replication | Seal Wrap | Options | Description | UUID "} for _, path := range paths { mount := mounts[path] @@ -160,7 +160,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) pluginName = mount.Config.PluginName } - out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %t | %s | %t | %v | %s", + out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %t | %s | %t | %v | %s | %s", path, pluginName, mount.Accessor, @@ -171,6 +171,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) mount.SealWrap, mount.Options, mount.Description, + mount.UUID, )) } diff --git a/go.mod b/go.mod index 8255e3d57..7a301bf88 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190412020505-60e2075261b6 github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2 - github.com/araddon/gou v0.0.0-20190110011759-c797efecbb61 // indirect github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da github.com/armon/go-proxyproto v0.0.0-20190211145416-68259f75880e github.com/armon/go-radix v1.0.0 @@ -37,10 +36,7 @@ require ( github.com/cockroachdb/apd v1.1.0 // indirect github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 // indirect - github.com/coreos/bbolt v1.3.2 // indirect - github.com/coreos/etcd v3.3.12+incompatible // indirect github.com/coreos/go-semver v0.2.0 - github.com/dancannon/gorethink v4.0.0+incompatible // indirect github.com/denisenkom/go-mssqldb v0.0.0-20190412130859-3b1d194e553a github.com/dnaeon/go-vcr v1.0.1 // indirect github.com/docker/go-connections v0.4.0 // indirect @@ -49,11 +45,9 @@ require ( github.com/fatih/color v1.7.0 github.com/fatih/structs v1.1.0 github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa - github.com/garyburd/redigo v1.6.0 // indirect github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/go-errors/errors v1.0.1 github.com/go-sql-driver/mysql v1.4.1 - github.com/go-stomp/stomp v2.0.2+incompatible // indirect github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31 github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df github.com/golang/protobuf v1.3.1 @@ -99,7 +93,6 @@ require ( github.com/kr/text v0.1.0 github.com/lib/pq v1.0.0 github.com/marstr/guid v1.1.0 // indirect - github.com/mattbaird/elastigo v0.0.0-20170123220020-2fe47fd29e4b // indirect github.com/mattn/go-colorable v0.0.9 github.com/michaelklishin/rabbit-hole v1.5.0 github.com/mitchellh/cli v1.0.0 @@ -113,11 +106,8 @@ require ( github.com/opencontainers/go-digest v1.0.0-rc1 // indirect github.com/opencontainers/image-spec v1.0.1 // indirect github.com/opencontainers/runc v0.1.1 // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect - github.com/ory-am/common v0.4.0 // indirect github.com/ory/dockertest v3.3.4+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/pborman/uuid v1.2.0 // indirect github.com/pkg/errors v0.8.1 github.com/posener/complete v1.2.1 github.com/pquerna/otp v1.1.0 @@ -136,9 +126,7 @@ require ( google.golang.org/api v0.3.2 google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 google.golang.org/grpc v1.20.0 - gopkg.in/gorethink/gorethink.v4 v4.1.0 // indirect gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce - gopkg.in/ory-am/dockertest.v2 v2.2.3 gopkg.in/ory-am/dockertest.v3 v3.3.4 gopkg.in/square/go-jose.v2 v2.3.1 gotest.tools v2.2.0+incompatible // indirect diff --git a/go.sum b/go.sum index cbe59a957..ce7a6082d 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,6 @@ github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2 h1:VoHKYIXEQU5LWoambPBOvYxyLqZYHuj+rj5DVnMUc3k= github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2/go.mod h1:OMVSB21p9+xQUIqlGizHPZfjK+SHws1ht+ZytVDoz9U= -github.com/araddon/gou v0.0.0-20190110011759-c797efecbb61 h1:Xz25cuW4REGC5W5UtpMU3QItMIImag615HiQcRbxqKQ= -github.com/araddon/gou v0.0.0-20190110011759-c797efecbb61/go.mod h1:ikc1XA58M+Rx7SEbf0bLJCfBkwayZ8T5jBo5FXK8Uz8= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -65,7 +63,6 @@ github.com/boombuler/barcode v1.0.0 h1:s1TvRnXwL2xJRaccrdcBQMZxq6X7DvsMogtmJeHDd github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f h1:ZMEzE7R0WNqgbHplzSBaYJhJi5AZWTCK9baU0ebzG6g= github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f/go.mod h1:HQhVmdUf7dBNwIIdBTivnCDxcf6IZY3/zrb+uKSJz6Y= -github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= @@ -85,10 +82,6 @@ github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c h1:2zRrJW github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882bXEDKfWIf0wa8HRvpnBoPszJJXL+TVbBw4M= github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.12+incompatible h1:pAWNwdf7QiT1zfaWyqCtNZQWCLByQyA3JrSQyuYAqnQ= -github.com/coreos/etcd v3.3.12+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-oidc v2.0.0+incompatible h1:+RStIopZ8wooMx+Vs5Bt8zMXxV1ABl5LbakNExNmZIg= github.com/coreos/go-oidc v2.0.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= @@ -97,8 +90,6 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5t github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBtyYFaUT/WmOqsJjgtihT0vMI= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/dancannon/gorethink v4.0.0+incompatible h1:KFV7Gha3AuqT+gr0B/eKvGhbjmUv0qGF43aKCIKVE9A= -github.com/dancannon/gorethink v4.0.0+incompatible/go.mod h1:BLvkat9KmZc1efyYwhz3WnybhRZtgF1K929FD8z1avU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -139,8 +130,6 @@ github.com/gammazero/deque v0.0.0-20190130191400-2afb3858e9c7 h1:D2LrfOPgGHQprIx github.com/gammazero/deque v0.0.0-20190130191400-2afb3858e9c7/go.mod h1:GeIq9qoE43YdGnDXURnmKTnGg15pQz4mYkXSTChbneI= github.com/gammazero/workerpool v0.0.0-20190406235159-88d534f22b56 h1:VzbudKn/nvxYKOdzgkEBS6SSreRjAgoJ+ZeS4wPFkgc= github.com/gammazero/workerpool v0.0.0-20190406235159-88d534f22b56/go.mod h1:w9RqFVO2BM3xwWEcAB8Fwp0OviTBBEiRmSBDfbXnd3w= -github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= -github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= @@ -153,8 +142,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stomp/stomp v2.0.2+incompatible h1:0yPknMJh32lE2xiCFGW5t/KgamhUC4OgCv10wIjx5aw= -github.com/go-stomp/stomp v2.0.2+incompatible/go.mod h1:VqCtqNZv1226A1/79yh+rMiFUcfY3R109np+7ke4n0c= github.com/go-test/deep v1.0.1 h1:UQhStjbkDClarlmv0am7OXXO4/GaPdCGiUiMTvi28sg= github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31 h1:28FVBuwkwowZMjbA7M0wXsI6t3PYulRTMio3SO+eKCM= @@ -350,8 +337,6 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= -github.com/mattbaird/elastigo v0.0.0-20170123220020-2fe47fd29e4b h1:v29yPGHhOqw7VHEnTeQFAth3SsBrmwc8JfuhNY0G34k= -github.com/mattbaird/elastigo v0.0.0-20170123220020-2fe47fd29e4b/go.mod h1:5MWrJXKRQyhQdUCF+vu6U5c4nQpg70vW3eHaU0/AYbU= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -410,13 +395,8 @@ github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVo github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/ory-am/common v0.4.0 h1:edGPoxYX4hno0IJHXh9TCMUPR6ZcJp+y6aClFYxeuUE= -github.com/ory-am/common v0.4.0/go.mod h1:oCYGuwwM8FyYMKqh9vrhBaeUoyz/edx0bgJN6uS6/+k= github.com/ory/dockertest v3.3.4+incompatible h1:VrpM6Gqg7CrPm3bL4Wm1skO+zFWLbh7/Xb5kGEbJRh8= github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= @@ -425,8 +405,6 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= @@ -478,7 +456,6 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t4 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/sirupsen/logrus v1.0.5 h1:8c8b5uO0zS4X6RPl/sd1ENwSkIc0/H2PaHxE3udaE8I= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= @@ -527,7 +504,6 @@ go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180608092829-8ac0e0d97ce4 h1:wviDUSmtheHRBfoY8B9U8ELl2USoXi2YFwdGdpIIkzI= golang.org/x/crypto v0.0.0-20180608092829-8ac0e0d97ce4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -568,7 +544,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180828065106-d99a578cf41b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= @@ -635,13 +610,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/fatih/pool.v2 v2.0.0 h1:xIFeWtxifuQJGk/IEPKsTduEKcKvPmhoiVDGpC40nKg= -gopkg.in/fatih/pool.v2 v2.0.0/go.mod h1:8xVGeu1/2jr2wm5V9SPuMht2H5AEmf5aFMGSQixtjTY= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/gorethink/gorethink.v4 v4.1.0 h1:xoE9qJ9Ae9KdKEsiQGCF44u2JdnjyohrMBRDtts3Gjw= -gopkg.in/gorethink/gorethink.v4 v4.1.0/go.mod h1:M7JgwrUAmshJ3iUbEK0Pt049MPyPK+CYDGGaEjdZb/c= gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -649,8 +620,6 @@ gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/ory-am/dockertest.v2 v2.2.3 h1:vSYvP7tvyfAm9merq0gHmcI4yk5nkPpfXmoBCnSP3/4= -gopkg.in/ory-am/dockertest.v2 v2.2.3/go.mod h1:kDHEsan1UcKFYH1c28sDmqnmeqIpB4Nj682gSNhYDYM= gopkg.in/ory-am/dockertest.v3 v3.3.4 h1:oen8RiwxVNxtQ1pRoV4e4jqh6UjNsOuIZ1NXns6jdcw= gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/http/handler_test.go b/http/handler_test.go index ff22b7fb7..2c4bc87a9 100644 --- a/http/handler_test.go +++ b/http/handler_test.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "errors" - "github.com/go-test/deep" "net/http" "net/http/httptest" "net/textproto" @@ -12,6 +11,8 @@ import ( "strings" "testing" + "github.com/go-test/deep" + cleanhttp "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/consts" @@ -375,8 +376,14 @@ func TestSysMounts_headerAuth(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } + expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { diff --git a/http/sys_auth_test.go b/http/sys_auth_test.go index 33f631429..e20f3fd10 100644 --- a/http/sys_auth_test.go +++ b/http/sys_auth_test.go @@ -62,8 +62,14 @@ func TestSysAuth(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } + expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if !reflect.DeepEqual(actual, expected) { @@ -156,8 +162,14 @@ func TestSysEnableAuth(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } + expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); diff != nil { @@ -227,8 +239,14 @@ func TestSysDisableAuth(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } + expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); diff != nil { diff --git a/http/sys_mount_test.go b/http/sys_mount_test.go index cddc18ce5..c4cc88505 100644 --- a/http/sys_mount_test.go +++ b/http/sys_mount_test.go @@ -2,10 +2,11 @@ package http import ( "encoding/json" - "github.com/go-test/deep" "reflect" "testing" + "github.com/go-test/deep" + "github.com/fatih/structs" "github.com/hashicorp/vault/vault" ) @@ -134,8 +135,13 @@ func TestSysMounts(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { @@ -300,8 +306,13 @@ func TestSysMount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { @@ -486,8 +497,13 @@ func TestSysRemount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if !reflect.DeepEqual(actual, expected) { @@ -628,8 +644,13 @@ func TestSysUnmount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { @@ -876,8 +897,13 @@ func TestSysTuneMount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { @@ -1069,8 +1095,13 @@ func TestSysTuneMount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { diff --git a/physical/mssql/mssql.go b/physical/mssql/mssql.go index 7488c4e3f..f6e390623 100644 --- a/physical/mssql/mssql.go +++ b/physical/mssql/mssql.go @@ -123,16 +123,13 @@ func NewMSSQLBackend(conf map[string]string, logger log.Logger) (physical.Backen "') CREATE TABLE " + dbTable + " (Path VARCHAR(512) PRIMARY KEY, Value VARBINARY(MAX))" if schema != "dbo" { - if _, err := db.Exec("USE " + database); err != nil { - return nil, errwrap.Wrapf("failed to switch mssql database: {{err}}", err) - } var num int - err = db.QueryRow("SELECT 1 FROM sys.schemas WHERE name = '" + schema + "'").Scan(&num) + err = db.QueryRow("SELECT 1 FROM " + database + ".sys.schemas WHERE name = '" + schema + "'").Scan(&num) switch { case err == sql.ErrNoRows: - if _, err := db.Exec("CREATE SCHEMA " + schema); err != nil { + if _, err := db.Exec("USE " + database + "; EXEC ('CREATE SCHEMA " + schema + "')"); err != nil { return nil, errwrap.Wrapf("failed to create mssql schema: {{err}}", err) } diff --git a/physical/mssql/mssql_test.go b/physical/mssql/mssql_test.go index 23d12cd06..9f682b193 100644 --- a/physical/mssql/mssql_test.go +++ b/physical/mssql/mssql_test.go @@ -27,6 +27,11 @@ func TestMSSQLBackend(t *testing.T) { table = "test" } + schema := os.Getenv("MSSQL_SCHEMA") + if schema == "" { + schema = "test" + } + username := os.Getenv("MSSQL_USERNAME") password := os.Getenv("MSSQL_PASSWORD") @@ -37,6 +42,59 @@ func TestMSSQLBackend(t *testing.T) { "server": server, "database": database, "table": table, + "schema": schema, + "username": username, + "password": password, + }, logger) + + if err != nil { + t.Fatalf("Failed to create new backend: %v", err) + } + + defer func() { + mssql := b.(*MSSQLBackend) + _, err := mssql.client.Exec("DROP TABLE " + mssql.dbTable) + if err != nil { + t.Fatalf("Failed to drop table: %v", err) + } + }() + + physical.ExerciseBackend(t, b) + physical.ExerciseBackend_ListPrefix(t, b) +} + +func TestMSSQLBackend_schema(t *testing.T) { + server := os.Getenv("MSSQL_SERVER") + if server == "" { + t.SkipNow() + } + + database := os.Getenv("MSSQL_DB") + if database == "" { + database = "test" + } + + table := os.Getenv("MSSQL_TABLE") + if table == "" { + table = "test" + } + + schema := os.Getenv("MSSQL_SCHEMA") + if schema == "" { + schema = "test" + } + + username := os.Getenv("MSSQL_USERNAME") + password := os.Getenv("MSSQL_PASSWORD") + + // Run vault tests + logger := logging.NewVaultLogger(log.Debug) + + b, err := NewMSSQLBackend(map[string]string{ + "server": server, + "database": database, + "schema": schema, + "table": table, "username": username, "password": password, }, logger) diff --git a/vault/external_tests/misc/kvv2_upgrade_test.go b/vault/external_tests/misc/kvv2_upgrade_test.go index 021b4d1dd..f962404f7 100644 --- a/vault/external_tests/misc/kvv2_upgrade_test.go +++ b/vault/external_tests/misc/kvv2_upgrade_test.go @@ -12,8 +12,8 @@ import ( "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/helper/testhelpers" vaulthttp "github.com/hashicorp/vault/http" - "github.com/hashicorp/vault/logical" - "github.com/hashicorp/vault/physical" + "github.com/hashicorp/vault/sdk/logical" + "github.com/hashicorp/vault/sdk/physical" "github.com/hashicorp/vault/vault" "github.com/kr/pretty" ) diff --git a/vault/logical_system.go b/vault/logical_system.go index 5af7b69a8..a0749b441 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -661,6 +661,7 @@ func mountInfo(entry *MountEntry) map[string]interface{} { "local": entry.Local, "seal_wrap": entry.SealWrap, "options": entry.Options, + "uuid": entry.UUID, } entryConfig := map[string]interface{}{ "default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()), diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index f8f48ab0a..88ade571f 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -153,6 +153,7 @@ func TestSystemBackend_mounts(t *testing.T) { "type": "kv", "description": "key/value secret storage", "accessor": resp.Data["secret/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -168,6 +169,7 @@ func TestSystemBackend_mounts(t *testing.T) { "type": "system", "description": "system endpoints used for control, policy and debugging", "accessor": resp.Data["sys/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["sys/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -182,6 +184,7 @@ func TestSystemBackend_mounts(t *testing.T) { "description": "per-token private secret storage", "type": "cubbyhole", "accessor": resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["cubbyhole/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -195,6 +198,7 @@ func TestSystemBackend_mounts(t *testing.T) { "description": "identity store", "type": "identity", "accessor": resp.Data["identity/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["identity/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -246,6 +250,7 @@ func TestSystemBackend_mount(t *testing.T) { "type": "kv", "description": "key/value secret storage", "accessor": resp.Data["secret/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -261,6 +266,7 @@ func TestSystemBackend_mount(t *testing.T) { "type": "system", "description": "system endpoints used for control, policy and debugging", "accessor": resp.Data["sys/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["sys/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -275,6 +281,7 @@ func TestSystemBackend_mount(t *testing.T) { "description": "per-token private secret storage", "type": "cubbyhole", "accessor": resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["cubbyhole/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -288,6 +295,7 @@ func TestSystemBackend_mount(t *testing.T) { "description": "identity store", "type": "identity", "accessor": resp.Data["identity/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["identity/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -301,6 +309,7 @@ func TestSystemBackend_mount(t *testing.T) { "description": "", "type": "kv", "accessor": resp.Data["prod/secret/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["prod/secret/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": int64(2100), "max_lease_ttl": int64(2700), @@ -1441,6 +1450,7 @@ func TestSystemBackend_authTable(t *testing.T) { "type": "token", "description": "token based credentials", "accessor": resp.Data["token/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["token/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": int64(0), "max_lease_ttl": int64(0), @@ -1494,6 +1504,7 @@ func TestSystemBackend_enableAuth(t *testing.T) { "type": "noop", "description": "", "accessor": resp.Data["foo/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["foo/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": int64(2100), "max_lease_ttl": int64(2700), @@ -1508,6 +1519,7 @@ func TestSystemBackend_enableAuth(t *testing.T) { "type": "token", "description": "token based credentials", "accessor": resp.Data["token/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["token/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": int64(0), "max_lease_ttl": int64(0), @@ -2270,6 +2282,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "type": "kv", "description": "key/value secret storage", "accessor": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -2285,6 +2298,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "type": "system", "description": "system endpoints used for control, policy and debugging", "accessor": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -2299,6 +2313,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "description": "per-token private secret storage", "type": "cubbyhole", "accessor": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -2312,6 +2327,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "description": "identity store", "type": "identity", "accessor": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -2334,6 +2350,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "type": "token", "description": "token based credentials", "accessor": resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["uuid"], "local": false, "seal_wrap": false, }, diff --git a/vault/plugin_reload.go b/vault/plugin_reload.go index 2170e43cd..3b38c1a44 100644 --- a/vault/plugin_reload.go +++ b/vault/plugin_reload.go @@ -106,6 +106,10 @@ func (c *Core) reloadMatchingPlugin(ctx context.Context, pluginName string) erro // reloadBackendCommon is a generic method to reload a backend provided a // MountEntry. func (c *Core) reloadBackendCommon(ctx context.Context, entry *MountEntry, isAuth bool) error { + // Make sure our cache is up-to-date. Since some singleton mounts can be + // tuned, we do this before the below check. + entry.SyncCache() + // We don't want to reload the singleton mounts. They often have specific // inmemory elements and we don't want to touch them here. if strutil.StrListContains(singletonMounts, entry.Type) { diff --git a/vault/seal/transit/transit.go b/vault/seal/transit/transit.go index bcb14ec21..eface946a 100644 --- a/vault/seal/transit/transit.go +++ b/vault/seal/transit/transit.go @@ -2,12 +2,7 @@ package transit import ( "context" - "encoding/base64" "errors" - "fmt" - "os" - "path" - "strconv" "strings" "sync/atomic" "time" @@ -15,7 +10,6 @@ import ( "github.com/armon/go-metrics" log "github.com/hashicorp/go-hclog" - "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/sdk/physical" "github.com/hashicorp/vault/vault/seal" ) @@ -23,13 +17,8 @@ import ( // Seal is a seal that leverages Vault's Transit secret // engine type Seal struct { - logger log.Logger - client *api.Client - renewer *api.Renewer - - mountPath string - keyName string - + logger log.Logger + client transitClientEncryptor currentKeyID *atomic.Value } @@ -47,142 +36,16 @@ func NewSeal(logger log.Logger) *Seal { // SetConfig processes the config info from the server config func (s *Seal) SetConfig(config map[string]string) (map[string]string, error) { - if config == nil { - config = map[string]string{} + client, sealInfo, err := newTransitClient(s.logger, config) + if err != nil { + return nil, err } + s.client = client - switch { - case os.Getenv("VAULT_TRANSIT_SEAL_MOUNT_PATH") != "": - s.mountPath = os.Getenv("VAULT_TRANSIT_SEAL_MOUNT_PATH") - case config["mount_path"] != "": - s.mountPath = config["mount_path"] - default: - return nil, fmt.Errorf("mount_path is required") - } - - switch { - case os.Getenv("VAULT_TRANSIT_SEAL_KEY_NAME") != "": - s.keyName = os.Getenv("VAULT_TRANSIT_SEAL_KEY_NAME") - case config["key_name"] != "": - s.keyName = config["key_name"] - default: - return nil, fmt.Errorf("key_name is required") - } - - var disableRenewal bool - var disableRenewalRaw string - switch { - case os.Getenv("VAULT_TRANSIT_SEAL_DISABLE_RENEWAL") != "": - disableRenewalRaw = os.Getenv("VAULT_TRANSIT_SEAL_DISABLE_RENEWAL") - case config["disable_renewal"] != "": - disableRenewalRaw = config["disable_renewal"] - } - if disableRenewalRaw != "" { - var err error - disableRenewal, err = strconv.ParseBool(disableRenewalRaw) - if err != nil { - return nil, err - } - } - - var namespace string - switch { - case os.Getenv("VAULT_NAMESPACE") != "": - namespace = os.Getenv("VAULT_NAMESPACE") - case config["namespace"] != "": - namespace = config["namespace"] - } - - apiConfig := api.DefaultConfig() - if config["address"] != "" { - apiConfig.Address = config["address"] - } - if config["tls_ca_cert"] != "" || config["tls_ca_path"] != "" || config["tls_client_cert"] != "" || config["tls_client_key"] != "" || - config["tls_server_name"] != "" || config["tls_skip_verify"] != "" { - var tlsSkipVerify bool - if config["tls_skip_verify"] != "" { - var err error - tlsSkipVerify, err = strconv.ParseBool(config["tls_skip_verify"]) - if err != nil { - return nil, err - } - } - - tlsConfig := &api.TLSConfig{ - CACert: config["tls_ca_cert"], - CAPath: config["tls_ca_path"], - ClientCert: config["tls_client_cert"], - ClientKey: config["tls_client_key"], - TLSServerName: config["tls_server_name"], - Insecure: tlsSkipVerify, - } - if err := apiConfig.ConfigureTLS(tlsConfig); err != nil { - return nil, err - } - } - - if s.client == nil { - client, err := api.NewClient(apiConfig) - if err != nil { - return nil, err - } - if config["token"] != "" { - client.SetToken(config["token"]) - } - if namespace != "" { - client.SetNamespace(namespace) - } - if client.Token() == "" { - return nil, errors.New("missing token") - } - s.client = client - - // Send a value to test the seal and to set the current key id - if _, err := s.Encrypt(context.Background(), []byte("a")); err != nil { - return nil, err - } - - if !disableRenewal { - // Renew the token immediately to get a secret to pass to renewer - secret, err := client.Auth().Token().RenewTokenAsSelf(s.client.Token(), 0) - // If we don't get an error renewing, set up a renewer. The token may not be renewable or not have - // permission to renew-self. - if err == nil { - renewer, err := s.client.NewRenewer(&api.RenewerInput{ - Secret: secret, - }) - if err != nil { - return nil, err - } - s.renewer = renewer - - go func() { - for { - select { - case err := <-renewer.DoneCh(): - s.logger.Info("shutting down token renewal") - if err != nil { - s.logger.Error("error renewing token", "error", err) - } - return - case <-renewer.RenewCh(): - s.logger.Trace("successfully renewed token") - } - } - }() - go s.renewer.Renew() - } else { - s.logger.Info("unable to renew token, disabling renewal", "err", err) - } - } - } - - sealInfo := make(map[string]string) - sealInfo["address"] = s.client.Address() - sealInfo["mount_path"] = s.mountPath - sealInfo["key_name"] = s.keyName - if namespace != "" { - sealInfo["namespace"] = namespace + // Send a value to test the seal and to set the current key id + if _, err := s.Encrypt(context.Background(), []byte("a")); err != nil { + client.Close() + return nil, err } return sealInfo, nil @@ -195,10 +58,7 @@ func (s *Seal) Init(_ context.Context) error { // Finalize is called during shutdown func (s *Seal) Finalize(_ context.Context) error { - if s.renewer != nil { - s.renewer.Stop() - } - + s.client.Close() return nil } @@ -227,17 +87,12 @@ func (s *Seal) Encrypt(_ context.Context, plaintext []byte) (blob *physical.Encr metrics.IncrCounter([]string{"seal", "encrypt"}, 1) metrics.IncrCounter([]string{"seal", "transit", "encrypt"}, 1) - encPlaintext := base64.StdEncoding.EncodeToString(plaintext) - path := path.Join(s.mountPath, "encrypt", s.keyName) - secret, err := s.client.Logical().Write(path, map[string]interface{}{ - "plaintext": encPlaintext, - }) + ciphertext, err := s.client.Encrypt(plaintext) if err != nil { return nil, err } - ciphertext := secret.Data["ciphertext"].(string) - splitKey := strings.Split(ciphertext, ":") + splitKey := strings.Split(string(ciphertext), ":") if len(splitKey) != 3 { return nil, errors.New("invalid ciphertext returned") } @@ -245,7 +100,7 @@ func (s *Seal) Encrypt(_ context.Context, plaintext []byte) (blob *physical.Encr s.currentKeyID.Store(keyID) ret := &physical.EncryptedBlobInfo{ - Ciphertext: []byte(ciphertext), + Ciphertext: ciphertext, KeyInfo: &physical.SealKeyInfo{ KeyID: keyID, }, @@ -268,18 +123,9 @@ func (s *Seal) Decrypt(_ context.Context, in *physical.EncryptedBlobInfo) (pt [] metrics.IncrCounter([]string{"seal", "decrypt"}, 1) metrics.IncrCounter([]string{"seal", "transit", "decrypt"}, 1) - path := path.Join(s.mountPath, "decrypt", s.keyName) - secret, err := s.client.Logical().Write(path, map[string]interface{}{ - "ciphertext": string(in.Ciphertext), - }) + plaintext, err := s.client.Decrypt(in.Ciphertext) if err != nil { return nil, err } - - plaintext, err := base64.StdEncoding.DecodeString(secret.Data["plaintext"].(string)) - if err != nil { - return nil, err - } - return plaintext, nil } diff --git a/vault/seal/transit/transit_acc_test.go b/vault/seal/transit/transit_acc_test.go index 405cbd339..11896b76b 100644 --- a/vault/seal/transit/transit_acc_test.go +++ b/vault/seal/transit/transit_acc_test.go @@ -1,4 +1,4 @@ -package transit +package transit_test import ( "context" @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/helper/testhelpers/docker" "github.com/hashicorp/vault/sdk/helper/logging" + "github.com/hashicorp/vault/vault/seal/transit" "github.com/ory/dockertest" ) @@ -30,7 +31,7 @@ func TestTransitSeal_Lifecycle(t *testing.T) { "mount_path": mountPath, "key_name": keyName, } - s := NewSeal(logging.NewVaultLogger(log.Trace)) + s := transit.NewSeal(logging.NewVaultLogger(log.Trace)) _, err := s.SetConfig(sealConfig) if err != nil { t.Fatalf("error setting seal config: %v", err) @@ -87,7 +88,7 @@ func TestTransitSeal_TokenRenewal(t *testing.T) { "mount_path": mountPath, "key_name": keyName, } - s := NewSeal(logging.NewVaultLogger(log.Trace)) + s := transit.NewSeal(logging.NewVaultLogger(log.Trace)) _, err = s.SetConfig(sealConfig) if err != nil { t.Fatalf("error setting seal config: %v", err) diff --git a/vault/seal/transit/transit_client.go b/vault/seal/transit/transit_client.go new file mode 100644 index 000000000..b9d6c1f12 --- /dev/null +++ b/vault/seal/transit/transit_client.go @@ -0,0 +1,203 @@ +package transit + +import ( + "encoding/base64" + "errors" + "fmt" + "os" + "path" + "strconv" + + log "github.com/hashicorp/go-hclog" + "github.com/hashicorp/vault/api" +) + +type transitClientEncryptor interface { + Close() + Encrypt(plaintext []byte) (ciphertext []byte, err error) + Decrypt(ciphertext []byte) (plaintext []byte, err error) +} + +type transitClient struct { + client *api.Client + renewer *api.Renewer + + mountPath string + keyName string +} + +func newTransitClient(logger log.Logger, config map[string]string) (*transitClient, map[string]string, error) { + if config == nil { + config = map[string]string{} + } + + var mountPath, keyName string + switch { + case os.Getenv("VAULT_TRANSIT_SEAL_MOUNT_PATH") != "": + mountPath = os.Getenv("VAULT_TRANSIT_SEAL_MOUNT_PATH") + case config["mount_path"] != "": + mountPath = config["mount_path"] + default: + return nil, nil, fmt.Errorf("mount_path is required") + } + + switch { + case os.Getenv("VAULT_TRANSIT_SEAL_KEY_NAME") != "": + keyName = os.Getenv("VAULT_TRANSIT_SEAL_KEY_NAME") + case config["key_name"] != "": + keyName = config["key_name"] + default: + return nil, nil, fmt.Errorf("key_name is required") + } + + var disableRenewal bool + var disableRenewalRaw string + switch { + case os.Getenv("VAULT_TRANSIT_SEAL_DISABLE_RENEWAL") != "": + disableRenewalRaw = os.Getenv("VAULT_TRANSIT_SEAL_DISABLE_RENEWAL") + case config["disable_renewal"] != "": + disableRenewalRaw = config["disable_renewal"] + } + if disableRenewalRaw != "" { + var err error + disableRenewal, err = strconv.ParseBool(disableRenewalRaw) + if err != nil { + return nil, nil, err + } + } + + var namespace string + switch { + case os.Getenv("VAULT_NAMESPACE") != "": + namespace = os.Getenv("VAULT_NAMESPACE") + case config["namespace"] != "": + namespace = config["namespace"] + } + + apiConfig := api.DefaultConfig() + if config["address"] != "" { + apiConfig.Address = config["address"] + } + if config["tls_ca_cert"] != "" || config["tls_ca_path"] != "" || config["tls_client_cert"] != "" || config["tls_client_key"] != "" || + config["tls_server_name"] != "" || config["tls_skip_verify"] != "" { + var tlsSkipVerify bool + if config["tls_skip_verify"] != "" { + var err error + tlsSkipVerify, err = strconv.ParseBool(config["tls_skip_verify"]) + if err != nil { + return nil, nil, err + } + } + + tlsConfig := &api.TLSConfig{ + CACert: config["tls_ca_cert"], + CAPath: config["tls_ca_path"], + ClientCert: config["tls_client_cert"], + ClientKey: config["tls_client_key"], + TLSServerName: config["tls_server_name"], + Insecure: tlsSkipVerify, + } + if err := apiConfig.ConfigureTLS(tlsConfig); err != nil { + return nil, nil, err + } + } + + apiClient, err := api.NewClient(apiConfig) + if err != nil { + return nil, nil, err + } + if config["token"] != "" { + apiClient.SetToken(config["token"]) + } + if namespace != "" { + apiClient.SetNamespace(namespace) + } + if apiClient.Token() == "" { + return nil, nil, errors.New("missing token") + } + + client := &transitClient{ + client: apiClient, + mountPath: mountPath, + keyName: keyName, + } + + if !disableRenewal { + // Renew the token immediately to get a secret to pass to renewer + secret, err := apiClient.Auth().Token().RenewTokenAsSelf(apiClient.Token(), 0) + // If we don't get an error renewing, set up a renewer. The token may not be renewable or not have + // permission to renew-self. + if err == nil { + renewer, err := apiClient.NewRenewer(&api.RenewerInput{ + Secret: secret, + }) + if err != nil { + return nil, nil, err + } + client.renewer = renewer + + go func() { + for { + select { + case err := <-renewer.DoneCh(): + logger.Info("shutting down token renewal") + if err != nil { + logger.Error("error renewing token", "error", err) + } + return + case <-renewer.RenewCh(): + logger.Trace("successfully renewed token") + } + } + }() + go renewer.Renew() + } else { + logger.Info("unable to renew token, disabling renewal", "err", err) + } + } + + sealInfo := make(map[string]string) + sealInfo["address"] = apiClient.Address() + sealInfo["mount_path"] = mountPath + sealInfo["key_name"] = keyName + if namespace != "" { + sealInfo["namespace"] = namespace + } + + return client, sealInfo, nil +} + +func (c *transitClient) Close() { + if c.renewer != nil { + c.renewer.Stop() + } +} + +func (c *transitClient) Encrypt(plaintext []byte) ([]byte, error) { + encPlaintext := base64.StdEncoding.EncodeToString(plaintext) + path := path.Join(c.mountPath, "encrypt", c.keyName) + secret, err := c.client.Logical().Write(path, map[string]interface{}{ + "plaintext": encPlaintext, + }) + if err != nil { + return nil, err + } + + return []byte(secret.Data["ciphertext"].(string)), nil +} + +func (c *transitClient) Decrypt(ciphertext []byte) ([]byte, error) { + path := path.Join(c.mountPath, "decrypt", c.keyName) + secret, err := c.client.Logical().Write(path, map[string]interface{}{ + "ciphertext": string(ciphertext), + }) + if err != nil { + return nil, err + } + + plaintext, err := base64.StdEncoding.DecodeString(secret.Data["plaintext"].(string)) + if err != nil { + return nil, err + } + return plaintext, nil +} diff --git a/vault/seal/transit/transit_test.go b/vault/seal/transit/transit_test.go new file mode 100644 index 000000000..e0c7a3870 --- /dev/null +++ b/vault/seal/transit/transit_test.go @@ -0,0 +1,82 @@ +package transit + +import ( + "context" + "errors" + "fmt" + "reflect" + "strings" + "testing" + + log "github.com/hashicorp/go-hclog" + "github.com/hashicorp/vault/sdk/helper/logging" + "github.com/hashicorp/vault/sdk/physical" + "github.com/hashicorp/vault/vault/seal" +) + +type testTransitClient struct { + keyID string + seal seal.Access +} + +func newTestTransitClient(keyID string) *testTransitClient { + return &testTransitClient{ + keyID: keyID, + seal: seal.NewTestSeal(nil), + } +} + +func (m *testTransitClient) Close() {} + +func (m *testTransitClient) Encrypt(plaintext []byte) ([]byte, error) { + v, err := m.seal.Encrypt(context.Background(), plaintext) + if err != nil { + return nil, err + } + + return []byte(fmt.Sprintf("v1:%s:%s", m.keyID, string(v.Ciphertext))), nil +} + +func (m *testTransitClient) Decrypt(ciphertext []byte) ([]byte, error) { + splitKey := strings.Split(string(ciphertext), ":") + if len(splitKey) != 3 { + return nil, errors.New("invalid ciphertext returned") + } + + data := &physical.EncryptedBlobInfo{ + Ciphertext: []byte(splitKey[2]), + } + v, err := m.seal.Decrypt(context.Background(), data) + if err != nil { + return nil, err + } + + return v, nil +} + +func TestTransitSeal_Lifecycle(t *testing.T) { + s := NewSeal(logging.NewVaultLogger(log.Trace)) + + keyID := "test-key" + s.client = newTestTransitClient(keyID) + + // Test Encrypt and Decrypt calls + input := []byte("foo") + swi, err := s.Encrypt(context.Background(), input) + if err != nil { + t.Fatalf("err: %s", err.Error()) + } + + pt, err := s.Decrypt(context.Background(), swi) + if err != nil { + t.Fatalf("err: %s", err.Error()) + } + + if !reflect.DeepEqual(input, pt) { + t.Fatalf("expected %s, got %s", input, pt) + } + + if s.KeyID() != keyID { + t.Fatalf("key id does not match: expected %s, got %s", keyID, s.KeyID()) + } +} diff --git a/vendor/github.com/go-test/deep/.travis.yml b/vendor/github.com/go-test/deep/.travis.yml index 2279c6142..89dc9815e 100644 --- a/vendor/github.com/go-test/deep/.travis.yml +++ b/vendor/github.com/go-test/deep/.travis.yml @@ -1,9 +1,9 @@ language: go go: - - 1.7 - - 1.8 - - 1.9 + - "1.9" + - "1.10" + - "1.11" before_install: - go get github.com/mattn/goveralls diff --git a/vendor/github.com/go-test/deep/deep.go b/vendor/github.com/go-test/deep/deep.go index 4ea14cb04..3d2591819 100644 --- a/vendor/github.com/go-test/deep/deep.go +++ b/vendor/github.com/go-test/deep/deep.go @@ -19,8 +19,9 @@ var ( // MaxDiff specifies the maximum number of differences to return. MaxDiff = 10 - // MaxDepth specifies the maximum levels of a struct to recurse into. - MaxDepth = 10 + // MaxDepth specifies the maximum levels of a struct to recurse into, + // if greater than zero. If zero, there is no limit. + MaxDepth = 0 // LogErrors causes errors to be logged to STDERR when true. LogErrors = false @@ -50,8 +51,9 @@ type cmp struct { var errorType = reflect.TypeOf((*error)(nil)).Elem() // Equal compares variables a and b, recursing into their structure up to -// MaxDepth levels deep, and returns a list of differences, or nil if there are -// none. Some differences may not be found if an error is also returned. +// MaxDepth levels deep (if greater than zero), and returns a list of differences, +// or nil if there are none. Some differences may not be found if an error is +// also returned. // // If a type has an Equal method, like time.Equal, it is called to check for // equality. @@ -66,7 +68,7 @@ func Equal(a, b interface{}) []string { if a == nil && b == nil { return nil } else if a == nil && b != nil { - c.saveDiff(b, "") + c.saveDiff("", b) } else if a != nil && b == nil { c.saveDiff(a, "") } @@ -82,7 +84,7 @@ func Equal(a, b interface{}) []string { } func (c *cmp) equals(a, b reflect.Value, level int) { - if level > MaxDepth { + if MaxDepth > 0 && level > MaxDepth { logError(ErrMaxRecursion) return } @@ -140,16 +142,6 @@ func (c *cmp) equals(a, b reflect.Value, level int) { return } - // Types with an Equal(), like time.Time. - eqFunc := a.MethodByName("Equal") - if eqFunc.IsValid() { - retVals := eqFunc.Call([]reflect.Value{b}) - if !retVals[0].Bool() { - c.saveDiff(a, b) - } - return - } - switch aKind { ///////////////////////////////////////////////////////////////////// @@ -167,6 +159,29 @@ func (c *cmp) equals(a, b reflect.Value, level int) { Iterate through the fields (FirstName, LastName), recurse into their values. */ + + // Types with an Equal() method, like time.Time, only if struct field + // is exported (CanInterface) + if eqFunc := a.MethodByName("Equal"); eqFunc.IsValid() && eqFunc.CanInterface() { + // Handle https://github.com/go-test/deep/issues/15: + // Don't call T.Equal if the method is from an embedded struct, like: + // type Foo struct { time.Time } + // First, we'll encounter Equal(Ttime, time.Time) but if we pass b + // as the 2nd arg we'll panic: "Call using pkg.Foo as type time.Time" + // As far as I can tell, there's no way to see that the method is from + // time.Time not Foo. So we check the type of the 1st (0) arg and skip + // unless it's b type. Later, we'll encounter the time.Time anonymous/ + // embedded field and then we'll have Equal(time.Time, time.Time). + funcType := eqFunc.Type() + if funcType.NumIn() == 1 && funcType.In(0) == bType { + retVals := eqFunc.Call([]reflect.Value{b}) + if !retVals[0].Bool() { + c.saveDiff(a, b) + } + return + } + } + for i := 0; i < a.NumField(); i++ { if aType.Field(i).PkgPath != "" && !CompareUnexportedFields { continue // skip unexported field, e.g. s in type T struct {s string} diff --git a/vendor/github.com/hashicorp/vault/api/go.sum b/vendor/github.com/hashicorp/vault/api/go.sum index dd8eaf304..24e7dfde4 100644 --- a/vendor/github.com/hashicorp/vault/api/go.sum +++ b/vendor/github.com/hashicorp/vault/api/go.sum @@ -12,7 +12,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= -github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= diff --git a/vendor/github.com/hashicorp/vault/api/sys_mounts.go b/vendor/github.com/hashicorp/vault/api/sys_mounts.go index 993a1b67b..354b1ee93 100644 --- a/vendor/github.com/hashicorp/vault/api/sys_mounts.go +++ b/vendor/github.com/hashicorp/vault/api/sys_mounts.go @@ -159,6 +159,7 @@ type MountConfigInput struct { } type MountOutput struct { + UUID string `json:"uuid"` Type string `json:"type"` Description string `json:"description"` Accessor string `json:"accessor"` diff --git a/vendor/github.com/ory-am/common/LICENSE b/vendor/github.com/ory-am/common/LICENSE deleted file mode 100644 index c0e58a901..000000000 --- a/vendor/github.com/ory-am/common/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2015 Ory GmbH & Aeneas Rekkas - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/vendor/github.com/ory-am/common/env/README.md b/vendor/github.com/ory-am/common/env/README.md deleted file mode 100644 index cecdd0611..000000000 --- a/vendor/github.com/ory-am/common/env/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# ory-libs/env - -Adds defaults to `os.GetEnv()` and saves you 3 lines of code: - -```go -import "github.com/ory-am/common/env" - -func main() { - port := env.Getenv("PORT", "80") -} -``` - -versus - -```go -import "os" - -func main() { - port := os.Getenv("PORT") - if port == "" { - port = "80" - } -} -``` diff --git a/vendor/github.com/ory-am/common/env/env.go b/vendor/github.com/ory-am/common/env/env.go deleted file mode 100644 index 6c9a22a06..000000000 --- a/vendor/github.com/ory-am/common/env/env.go +++ /dev/null @@ -1,13 +0,0 @@ -// A very handy library which adds defaults to os.GetEnv() -package env - -import "os" - -// Getenv retrieves the value of the environment variable named by the key. It returns the value, which will return the fallback if the variable is not present. -func Getenv(key string, fallback string) string { - value := os.Getenv(key) - if value == "" { - return fallback - } - return value -} diff --git a/vendor/github.com/pborman/uuid/.travis.yml b/vendor/github.com/pborman/uuid/.travis.yml deleted file mode 100644 index 3deb4a124..000000000 --- a/vendor/github.com/pborman/uuid/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: go - -go: - - "1.9" - - "1.10" - - "1.11" - - tip - -script: - - go test -v ./... diff --git a/vendor/github.com/pborman/uuid/CONTRIBUTING.md b/vendor/github.com/pborman/uuid/CONTRIBUTING.md deleted file mode 100644 index 04fdf09f1..000000000 --- a/vendor/github.com/pborman/uuid/CONTRIBUTING.md +++ /dev/null @@ -1,10 +0,0 @@ -# How to contribute - -We definitely welcome patches and contribution to this project! - -### Legal requirements - -In order to protect both you and ourselves, you will need to sign the -[Contributor License Agreement](https://cla.developers.google.com/clas). - -You may have already signed it for other Google projects. diff --git a/vendor/github.com/pborman/uuid/CONTRIBUTORS b/vendor/github.com/pborman/uuid/CONTRIBUTORS deleted file mode 100644 index b382a04ed..000000000 --- a/vendor/github.com/pborman/uuid/CONTRIBUTORS +++ /dev/null @@ -1 +0,0 @@ -Paul Borman diff --git a/vendor/github.com/pborman/uuid/LICENSE b/vendor/github.com/pborman/uuid/LICENSE deleted file mode 100644 index 5dc68268d..000000000 --- a/vendor/github.com/pborman/uuid/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009,2014 Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pborman/uuid/README.md b/vendor/github.com/pborman/uuid/README.md deleted file mode 100644 index 810ad40dc..000000000 --- a/vendor/github.com/pborman/uuid/README.md +++ /dev/null @@ -1,15 +0,0 @@ -This project was automatically exported from code.google.com/p/go-uuid - -# uuid ![build status](https://travis-ci.org/pborman/uuid.svg?branch=master) -The uuid package generates and inspects UUIDs based on [RFC 4122](http://tools.ietf.org/html/rfc4122) and DCE 1.1: Authentication and Security Services. - -This package now leverages the github.com/google/uuid package (which is based off an earlier version of this package). - -###### Install -`go get github.com/pborman/uuid` - -###### Documentation -[![GoDoc](https://godoc.org/github.com/pborman/uuid?status.svg)](http://godoc.org/github.com/pborman/uuid) - -Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: -http://godoc.org/github.com/pborman/uuid diff --git a/vendor/github.com/pborman/uuid/dce.go b/vendor/github.com/pborman/uuid/dce.go deleted file mode 100644 index 50a0f2d09..000000000 --- a/vendor/github.com/pborman/uuid/dce.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" - "fmt" - "os" -) - -// A Domain represents a Version 2 domain -type Domain byte - -// Domain constants for DCE Security (Version 2) UUIDs. -const ( - Person = Domain(0) - Group = Domain(1) - Org = Domain(2) -) - -// NewDCESecurity returns a DCE Security (Version 2) UUID. -// -// The domain should be one of Person, Group or Org. -// On a POSIX system the id should be the users UID for the Person -// domain and the users GID for the Group. The meaning of id for -// the domain Org or on non-POSIX systems is site defined. -// -// For a given domain/id pair the same token may be returned for up to -// 7 minutes and 10 seconds. -func NewDCESecurity(domain Domain, id uint32) UUID { - uuid := NewUUID() - if uuid != nil { - uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 - uuid[9] = byte(domain) - binary.BigEndian.PutUint32(uuid[0:], id) - } - return uuid -} - -// NewDCEPerson returns a DCE Security (Version 2) UUID in the person -// domain with the id returned by os.Getuid. -// -// NewDCEPerson(Person, uint32(os.Getuid())) -func NewDCEPerson() UUID { - return NewDCESecurity(Person, uint32(os.Getuid())) -} - -// NewDCEGroup returns a DCE Security (Version 2) UUID in the group -// domain with the id returned by os.Getgid. -// -// NewDCEGroup(Group, uint32(os.Getgid())) -func NewDCEGroup() UUID { - return NewDCESecurity(Group, uint32(os.Getgid())) -} - -// Domain returns the domain for a Version 2 UUID or false. -func (uuid UUID) Domain() (Domain, bool) { - if v, _ := uuid.Version(); v != 2 { - return 0, false - } - return Domain(uuid[9]), true -} - -// Id returns the id for a Version 2 UUID or false. -func (uuid UUID) Id() (uint32, bool) { - if v, _ := uuid.Version(); v != 2 { - return 0, false - } - return binary.BigEndian.Uint32(uuid[0:4]), true -} - -func (d Domain) String() string { - switch d { - case Person: - return "Person" - case Group: - return "Group" - case Org: - return "Org" - } - return fmt.Sprintf("Domain%d", int(d)) -} diff --git a/vendor/github.com/pborman/uuid/doc.go b/vendor/github.com/pborman/uuid/doc.go deleted file mode 100644 index 727d76167..000000000 --- a/vendor/github.com/pborman/uuid/doc.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// The uuid package generates and inspects UUIDs. -// -// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security -// Services. -// -// This package is a partial wrapper around the github.com/google/uuid package. -// This package represents a UUID as []byte while github.com/google/uuid -// represents a UUID as [16]byte. -package uuid diff --git a/vendor/github.com/pborman/uuid/go.mod b/vendor/github.com/pborman/uuid/go.mod deleted file mode 100644 index 099fc7de0..000000000 --- a/vendor/github.com/pborman/uuid/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/pborman/uuid - -require github.com/google/uuid v1.0.0 diff --git a/vendor/github.com/pborman/uuid/go.sum b/vendor/github.com/pborman/uuid/go.sum deleted file mode 100644 index db2574a9c..000000000 --- a/vendor/github.com/pborman/uuid/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/vendor/github.com/pborman/uuid/hash.go b/vendor/github.com/pborman/uuid/hash.go deleted file mode 100644 index a0420c1ef..000000000 --- a/vendor/github.com/pborman/uuid/hash.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "crypto/md5" - "crypto/sha1" - "hash" -) - -// Well known Name Space IDs and UUIDs -var ( - NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8") - NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8") - NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8") - NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8") - NIL = Parse("00000000-0000-0000-0000-000000000000") -) - -// NewHash returns a new UUID derived from the hash of space concatenated with -// data generated by h. The hash should be at least 16 byte in length. The -// first 16 bytes of the hash are used to form the UUID. The version of the -// UUID will be the lower 4 bits of version. NewHash is used to implement -// NewMD5 and NewSHA1. -func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { - h.Reset() - h.Write(space) - h.Write([]byte(data)) - s := h.Sum(nil) - uuid := make([]byte, 16) - copy(uuid, s) - uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) - uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant - return uuid -} - -// NewMD5 returns a new MD5 (Version 3) UUID based on the -// supplied name space and data. -// -// NewHash(md5.New(), space, data, 3) -func NewMD5(space UUID, data []byte) UUID { - return NewHash(md5.New(), space, data, 3) -} - -// NewSHA1 returns a new SHA1 (Version 5) UUID based on the -// supplied name space and data. -// -// NewHash(sha1.New(), space, data, 5) -func NewSHA1(space UUID, data []byte) UUID { - return NewHash(sha1.New(), space, data, 5) -} diff --git a/vendor/github.com/pborman/uuid/marshal.go b/vendor/github.com/pborman/uuid/marshal.go deleted file mode 100644 index 35b89352a..000000000 --- a/vendor/github.com/pborman/uuid/marshal.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2016 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "errors" - "fmt" - - guuid "github.com/google/uuid" -) - -// MarshalText implements encoding.TextMarshaler. -func (u UUID) MarshalText() ([]byte, error) { - if len(u) != 16 { - return nil, nil - } - var js [36]byte - encodeHex(js[:], u) - return js[:], nil -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (u *UUID) UnmarshalText(data []byte) error { - if len(data) == 0 { - return nil - } - id := Parse(string(data)) - if id == nil { - return errors.New("invalid UUID") - } - *u = id - return nil -} - -// MarshalBinary implements encoding.BinaryMarshaler. -func (u UUID) MarshalBinary() ([]byte, error) { - return u[:], nil -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (u *UUID) UnmarshalBinary(data []byte) error { - if len(data) == 0 { - return nil - } - if len(data) != 16 { - return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) - } - var id [16]byte - copy(id[:], data) - *u = id[:] - return nil -} - -// MarshalText implements encoding.TextMarshaler. -func (u Array) MarshalText() ([]byte, error) { - var js [36]byte - encodeHex(js[:], u[:]) - return js[:], nil -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (u *Array) UnmarshalText(data []byte) error { - id, err := guuid.ParseBytes(data) - if err != nil { - return err - } - *u = Array(id) - return nil -} - -// MarshalBinary implements encoding.BinaryMarshaler. -func (u Array) MarshalBinary() ([]byte, error) { - return u[:], nil -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (u *Array) UnmarshalBinary(data []byte) error { - if len(data) != 16 { - return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) - } - copy(u[:], data) - return nil -} diff --git a/vendor/github.com/pborman/uuid/node.go b/vendor/github.com/pborman/uuid/node.go deleted file mode 100644 index e524e0101..000000000 --- a/vendor/github.com/pborman/uuid/node.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - guuid "github.com/google/uuid" -) - -// NodeInterface returns the name of the interface from which the NodeID was -// derived. The interface "user" is returned if the NodeID was set by -// SetNodeID. -func NodeInterface() string { - return guuid.NodeInterface() -} - -// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. -// If name is "" then the first usable interface found will be used or a random -// Node ID will be generated. If a named interface cannot be found then false -// is returned. -// -// SetNodeInterface never fails when name is "". -func SetNodeInterface(name string) bool { - return guuid.SetNodeInterface(name) -} - -// NodeID returns a slice of a copy of the current Node ID, setting the Node ID -// if not already set. -func NodeID() []byte { - return guuid.NodeID() -} - -// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes -// of id are used. If id is less than 6 bytes then false is returned and the -// Node ID is not set. -func SetNodeID(id []byte) bool { - return guuid.SetNodeID(id) -} - -// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is -// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. -func (uuid UUID) NodeID() []byte { - if len(uuid) != 16 { - return nil - } - node := make([]byte, 6) - copy(node, uuid[10:]) - return node -} diff --git a/vendor/github.com/pborman/uuid/sql.go b/vendor/github.com/pborman/uuid/sql.go deleted file mode 100644 index 929c3847e..000000000 --- a/vendor/github.com/pborman/uuid/sql.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2015 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "database/sql/driver" - "errors" - "fmt" -) - -// Scan implements sql.Scanner so UUIDs can be read from databases transparently -// Currently, database types that map to string and []byte are supported. Please -// consult database-specific driver documentation for matching types. -func (uuid *UUID) Scan(src interface{}) error { - switch src.(type) { - case string: - // if an empty UUID comes from a table, we return a null UUID - if src.(string) == "" { - return nil - } - - // see uuid.Parse for required string format - parsed := Parse(src.(string)) - - if parsed == nil { - return errors.New("Scan: invalid UUID format") - } - - *uuid = parsed - case []byte: - b := src.([]byte) - - // if an empty UUID comes from a table, we return a null UUID - if len(b) == 0 { - return nil - } - - // assumes a simple slice of bytes if 16 bytes - // otherwise attempts to parse - if len(b) == 16 { - parsed := make([]byte, 16) - copy(parsed, b) - *uuid = UUID(parsed) - } else { - u := Parse(string(b)) - - if u == nil { - return errors.New("Scan: invalid UUID format") - } - - *uuid = u - } - - default: - return fmt.Errorf("Scan: unable to scan type %T into UUID", src) - } - - return nil -} - -// Value implements sql.Valuer so that UUIDs can be written to databases -// transparently. Currently, UUIDs map to strings. Please consult -// database-specific driver documentation for matching types. -func (uuid UUID) Value() (driver.Value, error) { - return uuid.String(), nil -} diff --git a/vendor/github.com/pborman/uuid/time.go b/vendor/github.com/pborman/uuid/time.go deleted file mode 100644 index 5c0960d87..000000000 --- a/vendor/github.com/pborman/uuid/time.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2014 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "encoding/binary" - - guuid "github.com/google/uuid" -) - -// A Time represents a time as the number of 100's of nanoseconds since 15 Oct -// 1582. -type Time = guuid.Time - -// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and -// clock sequence as well as adjusting the clock sequence as needed. An error -// is returned if the current time cannot be determined. -func GetTime() (Time, uint16, error) { return guuid.GetTime() } - -// ClockSequence returns the current clock sequence, generating one if not -// already set. The clock sequence is only used for Version 1 UUIDs. -// -// The uuid package does not use global static storage for the clock sequence or -// the last time a UUID was generated. Unless SetClockSequence a new random -// clock sequence is generated the first time a clock sequence is requested by -// ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated -// for -func ClockSequence() int { return guuid.ClockSequence() } - -// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to -// -1 causes a new sequence to be generated. -func SetClockSequence(seq int) { guuid.SetClockSequence(seq) } - -// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in -// uuid. It returns false if uuid is not valid. The time is only well defined -// for version 1 and 2 UUIDs. -func (uuid UUID) Time() (Time, bool) { - if len(uuid) != 16 { - return 0, false - } - time := int64(binary.BigEndian.Uint32(uuid[0:4])) - time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 - time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 - return Time(time), true -} - -// ClockSequence returns the clock sequence encoded in uuid. It returns false -// if uuid is not valid. The clock sequence is only well defined for version 1 -// and 2 UUIDs. -func (uuid UUID) ClockSequence() (int, bool) { - if len(uuid) != 16 { - return 0, false - } - return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true -} diff --git a/vendor/github.com/pborman/uuid/util.go b/vendor/github.com/pborman/uuid/util.go deleted file mode 100644 index 255b5e248..000000000 --- a/vendor/github.com/pborman/uuid/util.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -// xvalues returns the value of a byte as a hexadecimal digit or 255. -var xvalues = [256]byte{ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -} - -// xtob converts the the first two hex bytes of x into a byte. -func xtob(x string) (byte, bool) { - b1 := xvalues[x[0]] - b2 := xvalues[x[1]] - return (b1 << 4) | b2, b1 != 255 && b2 != 255 -} diff --git a/vendor/github.com/pborman/uuid/uuid.go b/vendor/github.com/pborman/uuid/uuid.go deleted file mode 100644 index 337000420..000000000 --- a/vendor/github.com/pborman/uuid/uuid.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - "bytes" - "crypto/rand" - "encoding/hex" - "io" - - guuid "github.com/google/uuid" -) - -// Array is a pass-by-value UUID that can be used as an effecient key in a map. -type Array [16]byte - -// UUID converts uuid into a slice. -func (uuid Array) UUID() UUID { - return uuid[:] -} - -// String returns the string representation of uuid, -// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. -func (uuid Array) String() string { - return guuid.UUID(uuid).String() -} - -// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC -// 4122. -type UUID []byte - -// A Version represents a UUIDs version. -type Version = guuid.Version - -// A Variant represents a UUIDs variant. -type Variant = guuid.Variant - -// Constants returned by Variant. -const ( - Invalid = guuid.Invalid // Invalid UUID - RFC4122 = guuid.RFC4122 // The variant specified in RFC4122 - Reserved = guuid.Reserved // Reserved, NCS backward compatibility. - Microsoft = guuid.Microsoft // Reserved, Microsoft Corporation backward compatibility. - Future = guuid.Future // Reserved for future definition. -) - -var rander = rand.Reader // random function - -// New returns a new random (version 4) UUID as a string. It is a convenience -// function for NewRandom().String(). -func New() string { - return NewRandom().String() -} - -// Parse decodes s into a UUID or returns nil. See github.com/google/uuid for -// the formats parsed. -func Parse(s string) UUID { - gu, err := guuid.Parse(s) - if err == nil { - return gu[:] - } - return nil -} - -// ParseBytes is like Parse, except it parses a byte slice instead of a string. -func ParseBytes(b []byte) (UUID, error) { - gu, err := guuid.ParseBytes(b) - if err == nil { - return gu[:], nil - } - return nil, err -} - -// Equal returns true if uuid1 and uuid2 are equal. -func Equal(uuid1, uuid2 UUID) bool { - return bytes.Equal(uuid1, uuid2) -} - -// Array returns an array representation of uuid that can be used as a map key. -// Array panics if uuid is not valid. -func (uuid UUID) Array() Array { - if len(uuid) != 16 { - panic("invalid uuid") - } - var a Array - copy(a[:], uuid) - return a -} - -// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -// , or "" if uuid is invalid. -func (uuid UUID) String() string { - if len(uuid) != 16 { - return "" - } - var buf [36]byte - encodeHex(buf[:], uuid) - return string(buf[:]) -} - -// URN returns the RFC 2141 URN form of uuid, -// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. -func (uuid UUID) URN() string { - if len(uuid) != 16 { - return "" - } - var buf [36 + 9]byte - copy(buf[:], "urn:uuid:") - encodeHex(buf[9:], uuid) - return string(buf[:]) -} - -func encodeHex(dst []byte, uuid UUID) { - hex.Encode(dst[:], uuid[:4]) - dst[8] = '-' - hex.Encode(dst[9:13], uuid[4:6]) - dst[13] = '-' - hex.Encode(dst[14:18], uuid[6:8]) - dst[18] = '-' - hex.Encode(dst[19:23], uuid[8:10]) - dst[23] = '-' - hex.Encode(dst[24:], uuid[10:]) -} - -// Variant returns the variant encoded in uuid. It returns Invalid if -// uuid is invalid. -func (uuid UUID) Variant() Variant { - if len(uuid) != 16 { - return Invalid - } - switch { - case (uuid[8] & 0xc0) == 0x80: - return RFC4122 - case (uuid[8] & 0xe0) == 0xc0: - return Microsoft - case (uuid[8] & 0xe0) == 0xe0: - return Future - default: - return Reserved - } -} - -// Version returns the version of uuid. It returns false if uuid is not -// valid. -func (uuid UUID) Version() (Version, bool) { - if len(uuid) != 16 { - return 0, false - } - return Version(uuid[6] >> 4), true -} - -// SetRand sets the random number generator to r, which implements io.Reader. -// If r.Read returns an error when the package requests random data then -// a panic will be issued. -// -// Calling SetRand with nil sets the random number generator to the default -// generator. -func SetRand(r io.Reader) { - guuid.SetRand(r) -} diff --git a/vendor/github.com/pborman/uuid/version1.go b/vendor/github.com/pborman/uuid/version1.go deleted file mode 100644 index 7af948da7..000000000 --- a/vendor/github.com/pborman/uuid/version1.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import ( - guuid "github.com/google/uuid" -) - -// NewUUID returns a Version 1 UUID based on the current NodeID and clock -// sequence, and the current time. If the NodeID has not been set by SetNodeID -// or SetNodeInterface then it will be set automatically. If the NodeID cannot -// be set NewUUID returns nil. If clock sequence has not been set by -// SetClockSequence then it will be set automatically. If GetTime fails to -// return the current NewUUID returns nil. -func NewUUID() UUID { - gu, err := guuid.NewUUID() - if err == nil { - return UUID(gu[:]) - } - return nil -} diff --git a/vendor/github.com/pborman/uuid/version4.go b/vendor/github.com/pborman/uuid/version4.go deleted file mode 100644 index b459d46d1..000000000 --- a/vendor/github.com/pborman/uuid/version4.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2011 Google Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package uuid - -import guuid "github.com/google/uuid" - -// Random returns a Random (Version 4) UUID or panics. -// -// The strength of the UUIDs is based on the strength of the crypto/rand -// package. -// -// A note about uniqueness derived from the UUID Wikipedia entry: -// -// Randomly generated UUIDs have 122 random bits. One's annual risk of being -// hit by a meteorite is estimated to be one chance in 17 billion, that -// means the probability is about 0.00000000006 (6 × 10−11), -// equivalent to the odds of creating a few tens of trillions of UUIDs in a -// year and having one duplicate. -func NewRandom() UUID { - if gu, err := guuid.NewRandom(); err == nil { - return UUID(gu[:]) - } - return nil -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/.gitignore b/vendor/gopkg.in/ory-am/dockertest.v2/.gitignore deleted file mode 100644 index 972e5a257..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.idea/ -node_modules/ -*.iml -*.exe -.cover/ -vendor/ \ No newline at end of file diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/.travis.yml b/vendor/gopkg.in/ory-am/dockertest.v2/.travis.yml deleted file mode 100644 index e72b74c30..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -sudo: required - -language: go - -services: - - docker - -env: - - DOCKER_BIND_LOCALHOST=true GO15VENDOREXPERIMENT=1 - -go: - - 1.4 - - 1.5 - - 1.6 - - tip - -matrix: - allow_failures: - - go: tip - - go: 1.4 - -install: - - go get github.com/mattn/goveralls golang.org/x/tools/cmd/cover github.com/pierrre/gotestcover github.com/Masterminds/glide - - glide install - -script: - - go vet -x . - - gotestcover -coverprofile="cover.out" -race -covermode="count" . - - goveralls -coverprofile="cover.out" diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/LICENSE b/vendor/gopkg.in/ory-am/dockertest.v2/LICENSE deleted file mode 100644 index 1f8f689ce..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014 The Camlistore Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/README.md b/vendor/gopkg.in/ory-am/dockertest.v2/README.md deleted file mode 100644 index 783fa6959..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/README.md +++ /dev/null @@ -1,295 +0,0 @@ -# [ory.am](https://ory.am)/dockertest - -[![Build Status](https://travis-ci.org/ory-am/dockertest.svg)](https://travis-ci.org/ory-am/dockertest?branch=master) -[![Coverage Status](https://coveralls.io/repos/ory-am/dockertest/badge.svg?branch=master&service=github)](https://coveralls.io/github/ory-am/dockertest?branch=master) - -Use Docker to run your Go language integration tests against third party services on **Microsoft Windows, Mac OSX and Linux**! -Dockertest uses [Docker](https://www.docker.com/toolbox) to spin up images on Windows and Mac OSX as well. -Dockertest is based on [docker.go](https://github.com/camlistore/camlistore/blob/master/pkg/test/dockertest/docker.go) -from [camlistore](https://github.com/camlistore/camlistore). - -Dockertest currently supports these backends: -* PostgreSQL -* MySQL -* MongoDB -* NSQ -* Redis -* Elastic Search -* RethinkDB -* RabbitMQ -* Mockserver -* ActiveMQ -* ZooKeeper -* Cassandra -* Etcd - - - -**Table of Contents** - -- [Why should I use Dockertest?](#why-should-i-use-dockertest) -- [Installing and using Dockertest](#installing-and-using-dockertest) - - [Start a container](#start-a-container) -- [Write awesome tests](#write-awesome-tests) - - [Setting up Travis-CI](#setting-up-travis-ci) -- [Troubleshoot & FAQ](#troubleshoot-&-faq) - - [I need to use a specific container version for XYZ](#i-need-to-use-a-specific-container-version-for-xyz) - - [My build is broken!](#my-build-is-broken) - - [Out of disk space](#out-of-disk-space) - - [I am using docker machine (OSX / Linux)](#i-am-using-docker-machine-osx--linux) - - [Removing old containers](#removing-old-containers) - - [Customized database](#customized-database) - - - -## Why should I use Dockertest? - -When developing applications, it is often necessary to use services that talk to a database system. -Unit Testing these services can be cumbersome because mocking database/DBAL is strenuous. Making slight changes to the -schema implies rewriting at least some, if not all of the mocks. The same goes for API changes in the DBAL. -To avoid this, it is smarter to test these specific services against a real database that is destroyed after testing. -Docker is the perfect system for running unit tests as you can spin up containers in a few seconds and kill them when -the test completes. The Dockertest library provides easy to use commands for spinning up Docker containers and using -them for your tests. - -## Installing and using Dockertest - -Using Dockertest is straightforward and simple. Check the [releases tab](https://github.com/ory-am/dockertest/releases) -for available releases. - -To install dockertest, run - -``` -go get gopkg.in/ory-am/dockertest.vX -``` - -where `X` is your desired version. For example: - -``` -go get gopkg.in/ory-am/dockertest.v2 -``` - -**Note:** -When using the Docker Toolbox (Windows / OSX), make sure that the VM is started by running `docker-machine start default`. - -### Start a container - -```go -package main - -import ( - "gopkg.in/ory-am/dockertest.v2" - "gopkg.in/mgo.v2" - "time" -) - -func main() { - var db *mgo.Session - c, err := dockertest.ConnectToMongoDB(15, time.Millisecond*500, func(url string) bool { - // This callback function checks if the image's process is responsive. - // Sometimes, docker images are booted but the process (in this case MongoDB) is still doing maintenance - // before being fully responsive which might cause issues like "TCP Connection reset by peer". - var err error - db, err = mgo.Dial(url) - if err != nil { - return false - } - - // Sometimes, dialing the database is not enough because the port is already open but the process is not responsive. - // Most database conenctors implement a ping function which can be used to test if the process is responsive. - // Alternatively, you could execute a query to see if an error occurs or not. - return db.Ping() == nil - }) - - if err != nil { - log.Fatalf("Could not connect to database: %s", err) - } - - // Close db connection and kill the container when we leave this function body. - defer db.Close() - defer c.KillRemove() - - // The image is now responsive. -} -``` - -You can start PostgreSQL and MySQL in a similar fashion. - -There are some cases where it's useful to test how your application/code handles -remote resources failing / shutting down. For example, what if your database -goes offline? Does your application handle it gracefully? - -This can be tested by stopping and starting an existing container: - -```go - var hosts []string - c, err := ConnectToZooKeeper(15, time.Millisecond*500, func(url string) bool { - conn, _, err := zk.Connect([]string{url}, time.Second) - if err != nil { - return false - } - defer conn.Close() - hosts = []string{url} - - return true - }) - defer c.KillRemove() - - conn, _, _ := zk.Connect(hosts, time.Second) - conn.Create("/test", []byte("hello"), 0, zk.WorldACL(zk.PermAll)) - - c.Stop() - - _, _, err = zk.Get("/test") // err == zk.ErrNoServer - - c.Start() - - data, _, _ = zk.Get("/test") // data == []byte("hello") -``` - -It is also possible to start a custom container (in this example, a RabbitMQ container): - -```go - c, ip, port, err := dockertest.SetupCustomContainer("rabbitmq", 5672, 10*time.Second) - if err != nil { - log.Fatalf("Could not setup container: %s", err - } - defer c.KillRemove() - - err = dockertest.ConnectToCustomContainer(fmt.Sprintf("%v:%v", ip, port), 15, time.Millisecond*500, func(url string) bool { - amqp, err := amqp.Dial(fmt.Sprintf("amqp://%v", url)) - if err != nil { - return false - } - defer amqp.Close() - return true - }) - - ... -``` - -## Write awesome tests - -It is a good idea to start up the container only once when running tests. - -```go - -import ( - "fmt" - "testing" - "log" - "os" - - "database/sql" - _ "github.com/lib/pq" - "gopkg.in/ory-am/dockertest.v2" -) - -var db *sql.DB - -func TestMain(m *testing.M) { - c, err := dockertest.ConnectToPostgreSQL(15, time.Second, func(url string) bool { - // Check if postgres is responsive... - var err error - db, err = sql.Open("postgres", url) - if err != nil { - return false - } - return db.Ping() == nil - }) - if err != nil { - log.Fatalf("Could not connect to database: %s", err) - } - - // Execute tasks like setting up schemata. - - // Run tests - result := m.Run() - - // Close database connection. - db.Close() - - // Clean up image. - c.KillRemove() - - // Exit tests. - os.Exit(result) -} - -func TestFunction(t *testing.T) { - // db.Exec(... -} -``` - -### Setting up Travis-CI - -You can run the Docker integration on Travis easily: - -```yml -# Sudo is required for docker -sudo: required - -# Enable docker -services: - - docker - -# In Travis, we need to bind to 127.0.0.1 in order to get a working connection. This environment variable -# tells dockertest to do that. -env: - - DOCKERTEST_BIND_LOCALHOST=true -``` - -## Troubleshoot & FAQ - -### I need to use a specific container version for XYZ - -You can specify a container version by setting environment variables or globals. For more information, check [vars.go](vars.go). - -### My build is broken! - -With v2, we removed all `Open*` methods to reduce duplicate code, unnecessary dependencies and make maintenance easier. -If you relied on these, run `go get gopkg.in/ory-am/dockertest.v1` and replace -`import "github.com/ory-am/dockertest"` with `import "gopkg.in/ory-am/dockertest.v1"`. - -### Out of disk space - -Try cleaning up the images with [docker-cleanup-volumes](https://github.com/chadoe/docker-cleanup-volumes). - -### I am using docker machine (OSX / Linux) - -First of all, consider upgrading! If that's not an option, there are some steps you need to take: - -* Set `dockertest.UseDockerMachine = "1"` or set the environment variable `DOCKERTEST_LEGACY_DOCKER_MACHINE=1` -* Set `docker.BindDockerToLocalhost = ""` or alternatively `DOCKER_BIND_LOCALHOST=` - -### Removing old containers - -Sometimes container clean up fails. Check out -[this stackoverflow question](http://stackoverflow.com/questions/21398087/how-to-delete-dockers-images) on how to fix this. - -### Customized database - -I am using postgres (or mysql) driver, how do I use customized database instead of default one? -You can alleviate this helper function to do that, see testcase or example below: - -```go - -func TestMain(m *testing.M) { - if c, err := dockertest.ConnectToPostgreSQL(15, time.Second, func(url string) bool { - customizedDB := "cherry" // here I am connecting cherry database - newURL, err := SetUpPostgreDatabase(customizedDB, url) - - // or use SetUpMysqlDatabase for mysql driver - - if err != nil { - log.Fatal(err) - } - db, err := sql.Open("postgres", newURL) - if err != nil { - return false - } - return db.Ping() == nil - }); err != nil { - log.Fatal(err) - } -``` diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/activemq.go b/vendor/gopkg.in/ory-am/dockertest.v2/activemq.go deleted file mode 100644 index 22c33206d..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/activemq.go +++ /dev/null @@ -1,43 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupActiveMQContainer sets up a real ActiveMQ instance for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupActiveMQContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 61613) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(ActiveMQImageName, port, 10*time.Second, func() (string, error) { - res, err := run("--name", GenerateContainerID(), "-d", "-P", "-p", forward, ActiveMQImageName) - return res, err - }) - return -} - -// ConnectToActiveMQ starts a ActiveMQ image and passes the amqp url to the connector callback. -// The url will match the ip:port pattern (e.g. 123.123.123.123:4241) -func ConnectToActiveMQ(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupActiveMQContainer() - if err != nil { - return c, fmt.Errorf("Could not set up ActiveMQ container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%d", ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up ActiveMQ container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/cassandra.go b/vendor/gopkg.in/ory-am/dockertest.v2/cassandra.go deleted file mode 100644 index 20844ccb9..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/cassandra.go +++ /dev/null @@ -1,47 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupCassandraContainer sets up a real Cassandra node for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupCassandraContainer(versionTag string, optionalParams ...string) (c ContainerID, ip string, port int, err error) { - port = RandomPort() - - // Forward for the CQL port. - forward := fmt.Sprintf("%d:%d", port, 9042) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - - imageName := fmt.Sprintf("%s:%s", CassandraImageName, versionTag) - - c, ip, err = SetupContainer(imageName, port, 10*time.Second, func() (string, error) { - return run(append(optionalParams, "--name", GenerateContainerID(), "-d", "-p", forward, imageName)...) - }) - return -} - -// ConnectToCassandra starts a Cassandra image and passes the nodes connection string to the connector callback function. -// The connection string will match the ip:port pattern, where port is the mapped CQL port. -func ConnectToCassandra(versionTag string, tries int, delay time.Duration, connector func(url string) bool, optionalParams ...string) (c ContainerID, err error) { - c, ip, port, err := SetupCassandraContainer(versionTag, optionalParams...) - if err != nil { - return c, fmt.Errorf("Could not setup Cassandra container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%d", ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not setup Cassandra container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/consul.go b/vendor/gopkg.in/ory-am/dockertest.v2/consul.go deleted file mode 100644 index cfc6261dc..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/consul.go +++ /dev/null @@ -1,95 +0,0 @@ -package dockertest - -import ( - "encoding/json" - "errors" - "fmt" - "log" - "time" -) - -var ( - // ConsulDatacenter must be defined when starting a Consul datacenter; this - // value will be used for both the datacenter and the ACL datacenter - ConsulDatacenter = "test" - - // ConsulACLDefaultPolicy defines the default policy to use with Consul ACLs - ConsulACLDefaultPolicy = "deny" - - // ConsulACLMasterToken defines the master ACL token - ConsulACLMasterToken = "test" - - // A function with no arguments that outputs a valid JSON string to be used - // as the value of the environment variable CONSUL_LOCAL_CONFIG. - ConsulLocalConfigGen = DefaultConsulLocalConfig -) - -func DefaultConsulLocalConfig() (string, error) { - type d struct { - Datacenter string `json:"datacenter,omitempty"` - ACLDatacenter string `json:"acl_datacenter,omitempty"` - ACLDefaultPolicy string `json:"acl_default_policy,omitempty"` - ACLMasterToken string `json:"acl_master_token,omitempty"` - } - - vals := &d{ - Datacenter: ConsulDatacenter, - ACLDatacenter: ConsulDatacenter, - ACLDefaultPolicy: ConsulACLDefaultPolicy, - ACLMasterToken: ConsulACLMasterToken, - } - - ret, err := json.Marshal(vals) - if err != nil { - return "", err - } - - return string(ret), nil -} - -// SetupConsulContainer sets up a real Consul instance for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupConsulContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 8500) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - localConfig, err := ConsulLocalConfigGen() - if err != nil { - return "", "", 0, err - } - c, ip, err = SetupContainer(ConsulImageName, port, 15*time.Second, func() (string, error) { - return run( - "--name", GenerateContainerID(), - "-d", - "-p", forward, - "-e", fmt.Sprintf("CONSUL_LOCAL_CONFIG=%s", localConfig), - ConsulImageName, - "agent", - "-dev", // Run in dev mode - "-client", "0.0.0.0", // Allow clients from any IP, otherwise the bridge IP will be where clients come from and it will be rejected - ) - }) - return -} - -// ConnectToConsul starts a Consul image and passes the address to the -// connector callback function. -func ConnectToConsul(tries int, delay time.Duration, connector func(address string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupConsulContainer() - if err != nil { - return c, fmt.Errorf("Could not set up Consul container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - address := fmt.Sprintf("%s:%d", ip, port) - if connector(address) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up Consul container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/container.go b/vendor/gopkg.in/ory-am/dockertest.v2/container.go deleted file mode 100644 index 964fedcdb..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/container.go +++ /dev/null @@ -1,90 +0,0 @@ -package dockertest - -import ( - "fmt" - "net" - "os/exec" - "strings" - "time" -) - -// AwaitReachable tries to make a TCP connection to addr regularly. -// It returns an error if it's unable to make a connection before maxWait. -func AwaitReachable(addr string, maxWait time.Duration) error { - done := time.Now().Add(maxWait) - for time.Now().Before(done) { - c, err := net.Dial("tcp", addr) - if err == nil { - c.Close() - return nil - } - time.Sleep(100 * time.Millisecond) - } - return fmt.Errorf("%v unreachable for %v", addr, maxWait) -} - -// ContainerID represents a container and offers methods like Kill or IP. -type ContainerID string - -// IP retrieves the container's IP address. -func (c ContainerID) IP() (string, error) { - return IP(string(c)) -} - -// Kill runs "docker kill" on the container. -func (c ContainerID) Kill() error { - return KillContainer(string(c)) -} - -// Start runs "docker start" on the container. -func (c ContainerID) Start() error { - return StartContainer(string(c)) -} - -// Stop runs "docker stop" on the container. -func (c ContainerID) Stop() error { - return StopContainer(string(c)) -} - -// Remove runs "docker rm" on the container -func (c ContainerID) Remove() error { - if Debug || c == "nil" { - return nil - } - return runDockerCommand("docker", "rm", "-v", string(c)).Run() -} - -// KillRemove calls Kill on the container, and then Remove if there was -// no error. -func (c ContainerID) KillRemove() error { - if err := c.Kill(); err != nil { - return err - } - return c.Remove() -} - -// lookup retrieves the ip address of the container, and tries to reach -// before timeout the tcp address at this ip and given port. -func (c ContainerID) lookup(ports []int, timeout time.Duration) (ip string, err error) { - if DockerMachineAvailable { - var out []byte - out, err = exec.Command("docker-machine", "ip", DockerMachineName).Output() - ip = strings.TrimSpace(string(out)) - } else if BindDockerToLocalhost != "" { - ip = "127.0.0.1" - } else { - ip, err = c.IP() - } - if err != nil { - err = fmt.Errorf("error getting IP: %v", err) - return - } - for _, port := range ports { - addr := fmt.Sprintf("%s:%d", ip, port) - err = AwaitReachable(addr, timeout) - if err != nil { - return - } - } - return -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/custom.go b/vendor/gopkg.in/ory-am/dockertest.v2/custom.go deleted file mode 100644 index 84dcb3715..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/custom.go +++ /dev/null @@ -1,39 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupCustomContainer sets up a real an instance of the given image for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupCustomContainer(imageName string, exposedPort int, timeOut time.Duration, extraDockerArgs ...string) (c ContainerID, ip string, localPort int, err error) { - localPort = RandomPort() - forward := fmt.Sprintf("%d:%d", localPort, exposedPort) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(imageName, localPort, timeOut, func() (string, error) { - args := make([]string, 0, len(extraDockerArgs)+7) - args = append(args, "--name", GenerateContainerID(), "-d", "-P", "-p", forward) - args = append(args, extraDockerArgs...) - args = append(args, imageName) - return run(args...) - }) - return -} - -// ConnectToCustomContainer attempts to connect to a custom container until successful or the maximum number of tries is reached. -func ConnectToCustomContainer(url string, tries int, delay time.Duration, connector func(url string) bool) error { - for try := 0; try <= tries; try++ { - time.Sleep(delay) - if connector(url) { - return nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return errors.New("Could not set up custom container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/doc.go b/vendor/gopkg.in/ory-am/dockertest.v2/doc.go deleted file mode 100644 index 127838ba0..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package dockertest contains helper functions for setting up and tearing down docker containers to aid in testing. -// dockertest supports spinning up MySQL, PostgreSQL and MongoDB out of the box. -// -// Dockertest provides two environment variables -package dockertest diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/docker.go b/vendor/gopkg.in/ory-am/dockertest.v2/docker.go deleted file mode 100644 index 9a1e34a8f..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/docker.go +++ /dev/null @@ -1,276 +0,0 @@ -package dockertest - -/* -Copyright 2014 The Camlistore Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "log" - "math/rand" - "os/exec" - "regexp" - "strings" - "time" - - // Import postgres driver - _ "github.com/lib/pq" - "github.com/pborman/uuid" -) - -/// runLongTest checks all the conditions for running a docker container -// based on image. -func runLongTest(image string) error { - DockerMachineAvailable = false - if haveDockerMachine() && UseDockerMachine != "" { - DockerMachineAvailable = true - if !startDockerMachine() { - log.Printf(`Starting docker machine "%s" failed. -This could be because the image is already running or because the image does not exist. -Tests will fail if the image does not exist.`, DockerMachineName) - } - } else if !haveDocker() { - return errors.New("Neither 'docker' nor 'docker-machine' available on this system.") - } - if ok, err := HaveImage(image); !ok || err != nil { - if err != nil { - return fmt.Errorf("Error checking for docker image %s: %v", image, err) - } - log.Printf("Pulling docker image %s ...", image) - if err := Pull(image); err != nil { - return fmt.Errorf("Error pulling %s: %v", image, err) - } - } - return nil -} - -func runDockerCommand(command string, args ...string) *exec.Cmd { - if DockerMachineAvailable { - command = "/usr/local/bin/" + strings.Join(append([]string{command}, args...), " ") - cmd := exec.Command("docker-machine", "ssh", DockerMachineName, command) - return cmd - } - return exec.Command(command, args...) -} - -// haveDockerMachine returns whether the "docker" command was found. -func haveDockerMachine() bool { - _, err := exec.LookPath("docker-machine") - return err == nil -} - -// startDockerMachine starts the docker machine and returns false if the command failed to execute -func startDockerMachine() bool { - _, err := exec.Command("docker-machine", "start", DockerMachineName).Output() - return err == nil -} - -// haveDocker returns whether the "docker" command was found. -func haveDocker() bool { - _, err := exec.LookPath("docker") - return err == nil -} - -type dockerImage struct { - repo string - tag string -} - -type dockerImageList []dockerImage - -func (l dockerImageList) contains(repo string, tag string) bool { - if tag == "" { - tag = "latest" - } - for _, image := range l { - if image.repo == repo && image.tag == tag { - return true - } - } - return false -} - -func parseDockerImagesOutput(data []byte) (images dockerImageList) { - lines := strings.Split(string(data), "\n") - if len(lines) < 2 { - return - } - - // skip first line with columns names - images = make(dockerImageList, 0, len(lines)-1) - for _, line := range lines[1:] { - cols := strings.Fields(line) - if len(cols) < 2 { - continue - } - - image := dockerImage{ - repo: cols[0], - tag: cols[1], - } - images = append(images, image) - } - - return -} - -func parseImageName(name string) (repo string, tag string) { - if fields := strings.SplitN(name, ":", 2); len(fields) == 2 { - repo, tag = fields[0], fields[1] - } else { - repo = name - } - return -} - -// HaveImage reports if docker have image 'name'. -func HaveImage(name string) (bool, error) { - out, err := runDockerCommand("docker", "images", "--no-trunc").Output() - if err != nil { - return false, err - } - repo, tag := parseImageName(name) - images := parseDockerImagesOutput(out) - return images.contains(repo, tag), nil -} - -func run(args ...string) (containerID string, err error) { - var stdout, stderr bytes.Buffer - validID := regexp.MustCompile(`^([a-zA-Z0-9]+)$`) - cmd := runDockerCommand("docker", append([]string{"run"}, args...)...) - - cmd.Stdout, cmd.Stderr = &stdout, &stderr - if err = cmd.Run(); err != nil { - err = fmt.Errorf("Error running docker\nStdOut: %s\nStdErr: %s\nError: %v\n\n", stdout.String(), stderr.String(), err) - return - } - containerID = strings.TrimSpace(string(stdout.String())) - if !validID.MatchString(containerID) { - return "", fmt.Errorf("Error running docker: %s", containerID) - } - if containerID == "" { - return "", errors.New("Unexpected empty output from `docker run`") - } - return containerID, nil -} - -// KillContainer runs docker kill on a container. -func KillContainer(container string) error { - if container != "" { - return runDockerCommand("docker", "kill", container).Run() - } - return nil -} - -// StartContainer runs 'docker start' on a container. -func StartContainer(container string) error { - if container != "" { - return runDockerCommand("docker", "start", container).Run() - } - return nil -} - -// StopContainer runs 'docker stop' on a container. -func StopContainer(container string) error { - if container != "" { - return runDockerCommand("docker", "stop", container).Run() - } - return nil -} - -// Pull retrieves the docker image with 'docker pull'. -func Pull(image string) error { - out, err := runDockerCommand("docker", "pull", image).CombinedOutput() - if err != nil { - err = fmt.Errorf("%v: %s", err, out) - } - return err -} - -// IP returns the IP address of the container. -func IP(containerID string) (string, error) { - out, err := runDockerCommand("docker", "inspect", containerID).Output() - if err != nil { - return "", err - } - type networkSettings struct { - IPAddress string - } - type container struct { - NetworkSettings networkSettings - } - var c []container - if err := json.NewDecoder(bytes.NewReader(out)).Decode(&c); err != nil { - return "", err - } - if len(c) == 0 { - return "", errors.New("no output from docker inspect") - } - if ip := c[0].NetworkSettings.IPAddress; ip != "" { - return ip, nil - } - return "", errors.New("could not find an IP. Not running?") -} - -// SetupMultiportContainer sets up a container, using the start function to run the given image. -// It also looks up the IP address of the container, and tests this address with the given -// ports and timeout. It returns the container ID and its IP address, or makes the test -// fail on error. -func SetupMultiportContainer(image string, ports []int, timeout time.Duration, start func() (string, error)) (c ContainerID, ip string, err error) { - err = runLongTest(image) - if err != nil { - return "", "", err - } - - containerID, err := start() - if err != nil { - return "", "", err - } - - c = ContainerID(containerID) - ip, err = c.lookup(ports, timeout) - if err != nil { - c.KillRemove() - return "", "", err - } - return c, ip, nil -} - -// SetupContainer sets up a container, using the start function to run the given image. -// It also looks up the IP address of the container, and tests this address with the given -// port and timeout. It returns the container ID and its IP address, or makes the test -// fail on error. -func SetupContainer(image string, port int, timeout time.Duration, start func() (string, error)) (c ContainerID, ip string, err error) { - return SetupMultiportContainer(image, []int{port}, timeout, start) -} - -// RandomPort returns a random non-priviledged port. -func RandomPort() int { - min := 1025 - max := 65534 - return min + rand.Intn(max-min) -} - -// GenerateContainerID generated a random container id. -func GenerateContainerID() string { - return ContainerPrefix + uuid.New() -} - -func init() { - rand.Seed(time.Now().UTC().UnixNano()) -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/elasticsearch.go b/vendor/gopkg.in/ory-am/dockertest.v2/elasticsearch.go deleted file mode 100644 index 25f7e88c0..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/elasticsearch.go +++ /dev/null @@ -1,42 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupElasticSearchContainer sets up a real ElasticSearch instance for testing purposes -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupElasticSearchContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 9200) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(ElasticSearchImageName, port, 15*time.Second, func() (string, error) { - return run("--name", GenerateContainerID(), "-d", "-P", "-p", forward, ElasticSearchImageName) - }) - return -} - -// ConnectToElasticSearch starts an ElasticSearch image and passes the database url to the connector callback function. -// The url will match the ip:port pattern (e.g. 123.123.123.123:4241) -func ConnectToElasticSearch(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupElasticSearchContainer() - if err != nil { - return c, fmt.Errorf("Could not set up ElasticSearch container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%d", ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up ElasticSearch container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/etcd.go b/vendor/gopkg.in/ory-am/dockertest.v2/etcd.go deleted file mode 100644 index 3f1be1b4c..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/etcd.go +++ /dev/null @@ -1,52 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupEtcdContainer sets up a real etcd instance for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupEtcdContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 2379) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(EtcdImageName, port, 10*time.Second, func() (string, error) { - return run( - "--name", GenerateContainerID(), - "-d", - "-p", forward, - EtcdImageName, - "etcd", - "-name", "etcd-test", - "-advertise-client-urls", "http://127.0.0.1:2379", - "-listen-client-urls", "http://0.0.0.0:2379", // Allow clients from any IP - ) - }) - - return c, ip, port, err -} - -// ConnectToEtcd starts a etcd image and passes the address to the -// connector callback function. -func ConnectToEtcd(tries int, delay time.Duration, connector func(address string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupEtcdContainer() - if err != nil { - return c, fmt.Errorf("Could not set up etcd container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - address := fmt.Sprintf("%s:%d", ip, port) - if connector(address) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up etcd container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/glide.lock b/vendor/gopkg.in/ory-am/dockertest.v2/glide.lock deleted file mode 100644 index 89d147bef..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/glide.lock +++ /dev/null @@ -1,149 +0,0 @@ -hash: ea1ce82416f8736cf3fd1f562146f135ee5071c7aed0dcbb4e33b4c18cdeaf6d -updated: 2016-09-03T10:56:05.944984255+08:00 -imports: -- name: github.com/go-errors/errors - version: a41850380601eeb43f4350f7d17c6bbd8944aaf8 -- name: github.com/go-sql-driver/mysql - version: 0b58b37b664c21f3010e836f1b931e1d0b0b0685 -- name: github.com/lib/pq - version: 50761b0867bd1d9d069276790bcd4a3bccf2324a - subpackages: - - oid -- name: github.com/ory-am/common - version: d93c852f2d09c219fd058756caf67bbdf8cf4be4 - subpackages: - - env -- name: github.com/pborman/uuid - version: a97ce2ca70fa5a848076093f05e639a89ca34d06 -testImports: -- name: github.com/araddon/gou - version: 4060436435c0b91885cb45241edb764c632ed8ae -- name: github.com/bitly/go-hostpool - version: d0e59c22a56e8dadfed24f74f452cea5a52722d2 -- name: github.com/cenk/backoff - version: cdf48bbc1eb78d1349cbda326a4a037f7ba565c6 -- name: github.com/cloudfoundry-incubator/candiedyaml - version: 99c3df83b51532e3615f851d8c2dbb638f5313bf -- name: github.com/coreos/etcd - version: 5695120efcfdc05b8ba51be2018d99c2937b41d0 - subpackages: - - auth/authpb - - clientv3 - - etcdserver/api/v3rpc/rpctypes - - etcdserver/etcdserverpb - - mvcc/mvccpb - - pkg/tlsutil -- name: github.com/dancannon/gorethink - version: 27d3045458910e2fc56025a0b52caaaa96414a26 -- name: github.com/davecgh/go-spew - version: 6cf5744a041a0022271cefed95ba843f6d87fd51 - subpackages: - - spew -- name: github.com/garyburd/redigo - version: 8873b2f1995f59d4bcdd2b0dc9858e2cb9bf0c13 - subpackages: - - internal - - redis -- name: github.com/ghodss/yaml - version: aa0c862057666179de291b67d9f093d12b5a8473 -- name: github.com/go-stomp/stomp - version: 364e36fe21291dd5aec3cba10ea15b0e654d9b40 - subpackages: - - frame -- name: github.com/gocql/gocql - version: 3ac1aabebaf2705c6f695d4ef2c25ab6239e88b3 - subpackages: - - internal/lru - - internal/murmur - - internal/streams -- name: github.com/golang/protobuf - version: 1f49d83d9aa00e6ce4fc8258c71cc7786aec968a - subpackages: - - jsonpb - - proto -- name: github.com/golang/snappy - version: d9eb7a3d35ec988b8585d4a0068e462c27d28380 -- name: github.com/grpc-ecosystem/grpc-gateway - version: 331418a167bc76e7e4e7469cf704033eddaba7a5 - subpackages: - - runtime - - runtime/internal - - utilities -- name: github.com/hailocab/go-hostpool - version: e80d13ce29ede4452c43dea11e79b9bc8a15b478 -- name: github.com/hashicorp/consul - version: 0047f09be55fdf790263cbc088bf5ec924ffe644 - subpackages: - - api -- name: github.com/hashicorp/go-cleanhttp - version: ad28ea4487f05916463e2423a55166280e8254b5 -- name: github.com/hashicorp/serf - version: 9432bc08aa8d486e497e27f84878ebbe8c1eab66 - subpackages: - - coordinate -- name: github.com/mattbaird/elastigo - version: 34c4c4d8425cbdcbc8e257943a2044d5e9f7dab5 - subpackages: - - lib -- name: github.com/pmezard/go-difflib - version: 792786c7400a136282c1664665ae0a8db921c6c2 - subpackages: - - difflib -- name: github.com/samuel/go-zookeeper - version: 8c6a1d79a44d2742da3660540d1fd43f4ddcfc8c - subpackages: - - zk -- name: github.com/Sirupsen/logrus - version: 3ec0642a7fb6488f65b06f9040adc67e3990296a -- name: github.com/streadway/amqp - version: 2e25825abdbd7752ff08b270d313b93519a0a232 -- name: github.com/stretchr/testify - version: f390dcf405f7b83c997eac1b06768bb9f44dec18 - subpackages: - - assert - - require -- name: golang.org/x/crypto - version: f160b6bf95857cd862817875dd958be022e587c4 - subpackages: - - pbkdf2 -- name: golang.org/x/net - version: 1358eff22f0dd0c54fc521042cc607f6ff4b531a - subpackages: - - context - - http2 - - http2/hpack - - internal/timeseries - - lex/httplex - - trace -- name: golang.org/x/sys - version: a646d33e2ee3172a661fc09bca23bb4889a41bc8 - subpackages: - - unix -- name: google.golang.org/grpc - version: 52f6504dc290bd928a8139ba94e3ab32ed9a6273 - subpackages: - - codes - - credentials - - grpclog - - internal - - metadata - - naming - - peer - - transport -- name: gopkg.in/dancannon/gorethink.v2 - version: e75f34b0817d1ed1a4b967975ccf5fac9535dbc2 - subpackages: - - encoding - - ql2 - - types -- name: gopkg.in/fatih/pool.v2 - version: 20a0a429c5f93de45c90f5f09ea297c25e0929b3 -- name: gopkg.in/inf.v0 - version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 -- name: gopkg.in/mgo.v2 - version: 3f83fa5005286a7fe593b055f0d7771a7dce4655 - subpackages: - - bson - - internal/json - - internal/sasl - - internal/scram diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/glide.yaml b/vendor/gopkg.in/ory-am/dockertest.v2/glide.yaml deleted file mode 100644 index 7ce277b9a..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/glide.yaml +++ /dev/null @@ -1,39 +0,0 @@ -package: github.com/ory-am/dockertest -import: -- package: github.com/go-errors/errors -- package: github.com/go-sql-driver/mysql - version: 0b58b37b664c21f3010e836f1b931e1d0b0b0685 -- package: github.com/lib/pq -- package: github.com/ory-am/common - subpackages: - - env -- package: github.com/pborman/uuid - version: ~1.0.0 -testImport: -- package: github.com/dancannon/gorethink - version: ~2.1.3 -- package: github.com/garyburd/redigo - version: ~1.0.0 - subpackages: - - redis -- package: github.com/go-stomp/stomp - version: 364e36fe21291dd5aec3cba10ea15b0e654d9b40 -- package: github.com/gocql/gocql -- package: github.com/hashicorp/consul - version: ~0.7.0-test2 - subpackages: - - api -- package: github.com/mattbaird/elastigo - version: 34c4c4d8425cbdcbc8e257943a2044d5e9f7dab5 - subpackages: - - lib -- package: github.com/samuel/go-zookeeper - subpackages: - - zk -- package: github.com/streadway/amqp -- package: github.com/stretchr/testify - version: ~1.1.3 - subpackages: - - assert - - require -- package: gopkg.in/mgo.v2 diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/mockserver.go b/vendor/gopkg.in/ory-am/dockertest.v2/mockserver.go deleted file mode 100644 index 0bdf15396..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/mockserver.go +++ /dev/null @@ -1,66 +0,0 @@ -package dockertest - -import ( - "fmt" - "github.com/go-errors/errors" - "log" - "time" -) - -// SetupMockserverContainer sets up a real Mockserver instance for testing purposes -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupMockserverContainer() (c ContainerID, ip string, mockPort, proxyPort int, err error) { - mockPort = RandomPort() - proxyPort = RandomPort() - - mockForward := fmt.Sprintf("%d:%d", mockPort, 1080) - proxyForward := fmt.Sprintf("%d:%d", proxyPort, 1090) - - if BindDockerToLocalhost != "" { - mockForward = "127.0.0.1:" + mockForward - proxyForward = "127.0.0.1:" + proxyForward - } - - c, ip, err = SetupMultiportContainer(RabbitMQImageName, []int{mockPort, proxyPort}, 10*time.Second, func() (string, error) { - res, err := run("--name", GenerateContainerID(), "-d", "-P", "-p", mockForward, "-p", proxyForward, MockserverImageName) - return res, err - }) - return -} - -// ConnectToMockserver starts a Mockserver image and passes the mock and proxy urls to the connector callback functions. -// The urls will match the http://ip:port pattern (e.g. http://123.123.123.123:4241) -func ConnectToMockserver(tries int, delay time.Duration, mockConnector func(url string) bool, proxyConnector func(url string) bool) (c ContainerID, err error) { - c, ip, mockPort, proxyPort, err := SetupMockserverContainer() - if err != nil { - return c, fmt.Errorf("Could not set up Mockserver container: %v", err) - } - - var mockOk, proxyOk bool - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - - if !mockOk { - if mockConnector(fmt.Sprintf("http://%s:%d", ip, mockPort)) { - mockOk = true - } else { - log.Printf("Try %d failed for mock. Retrying.", try) - } - } - if !proxyOk { - if proxyConnector(fmt.Sprintf("http://%s:%d", ip, proxyPort)) { - proxyOk = true - } else { - log.Printf("Try %d failed for proxy. Retrying.", try) - } - } - } - - if mockOk && proxyOk { - return c, nil - } else { - return c, errors.New("Could not set up Mockserver container.") - } -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/mongodb.go b/vendor/gopkg.in/ory-am/dockertest.v2/mongodb.go deleted file mode 100644 index 72ffbfeeb..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/mongodb.go +++ /dev/null @@ -1,43 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupMongoContainer sets up a real MongoDB instance for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupMongoContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 27017) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(MongoDBImageName, port, 10*time.Second, func() (string, error) { - res, err := run("--name", GenerateContainerID(), "-d", "-P", "-p", forward, MongoDBImageName) - return res, err - }) - return -} - -// ConnectToMongoDB starts a MongoDB image and passes the database url to the connector callback. -// The url will match the ip:port pattern (e.g. 123.123.123.123:4241) -func ConnectToMongoDB(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupMongoContainer() - if err != nil { - return c, fmt.Errorf("Could not set up MongoDB container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%d", ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up MongoDB container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/mysql.go b/vendor/gopkg.in/ory-am/dockertest.v2/mysql.go deleted file mode 100644 index fbbc8b5e0..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/mysql.go +++ /dev/null @@ -1,75 +0,0 @@ -package dockertest - -import ( - "database/sql" - "errors" - "fmt" - "log" - "time" - - mysql "github.com/go-sql-driver/mysql" -) - -const ( - defaultMySQLDBName = "mysql" -) - -// SetupMySQLContainer sets up a real MySQL instance for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupMySQLContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 3306) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(MySQLImageName, port, 10*time.Second, func() (string, error) { - return run("--name", GenerateContainerID(), "-d", "-p", forward, "-e", fmt.Sprintf("MYSQL_ROOT_PASSWORD=%s", MySQLPassword), MySQLImageName) - }) - return -} - -// ConnectToMySQL starts a MySQL image and passes the database url to the connector callback function. -// The url will match the username:password@tcp(ip:port) pattern (e.g. `root:root@tcp(123.123.123.123:3131)`) -func ConnectToMySQL(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupMySQLContainer() - if err != nil { - return c, fmt.Errorf("Could not set up MySQL container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%s@tcp(%s:%d)/mysql?parseTime=true", MySQLUsername, MySQLPassword, ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up MySQL container.") -} - -// SetUpMySQLDatabase connects mysql container with given $connectURL and also creates a new database named $databaseName -// A modified url used to connect the created database will be returned -func SetUpMySQLDatabase(databaseName, connectURL string) (url string, err error) { - if databaseName == defaultMySQLDBName { - return connectURL, nil - } - - db, err := sql.Open("mysql", connectURL) - if err != nil { - return "", err - } - defer db.Close() - _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", databaseName)) - if err != nil { - return "", err - } - - // parse dsn - config, err := mysql.ParseDSN(connectURL) - if err != nil { - return "", err - } - config.DBName = databaseName // overwrite database name - return config.FormatDSN(), nil -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/nsq.go b/vendor/gopkg.in/ory-am/dockertest.v2/nsq.go deleted file mode 100644 index ce3fa7b24..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/nsq.go +++ /dev/null @@ -1,90 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupNSQdContainer sets up a real NSQ instance for testing purposes -// using a Docker container and executing `/nsqd`. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupNSQdContainer() (c ContainerID, ip string, tcpPort int, httpPort int, err error) { - // --name nsqd -p 4150:4150 -p 4151:4151 nsqio/nsq /nsqd --broadcast-address=192.168.99.100 --lookupd-tcp-address=192.168.99.100:4160 - tcpPort = RandomPort() - httpPort = RandomPort() - tcpForward := fmt.Sprintf("%d:%d", tcpPort, 4150) - if BindDockerToLocalhost != "" { - tcpForward = "127.0.0.1:" + tcpForward - } - - httpForward := fmt.Sprintf("%d:%d", httpPort, 4151) - if BindDockerToLocalhost != "" { - httpForward = "127.0.0.1:" + httpForward - } - - c, ip, err = SetupContainer(NSQImageName, tcpPort, 15*time.Second, func() (string, error) { - return run("--name", GenerateContainerID(), "-d", "-P", "-p", tcpForward, "-p", httpForward, NSQImageName, "/nsqd", fmt.Sprintf("--broadcast-address=%s", ip), fmt.Sprintf("--lookupd-tcp-address=%s:4160", ip)) - }) - return -} - -// SetupNSQLookupdContainer sets up a real NSQ instance for testing purposes -// using a Docker container and executing `/nsqlookupd`. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupNSQLookupdContainer() (c ContainerID, ip string, tcpPort int, httpPort int, err error) { - // docker run --name lookupd -p 4160:4160 -p 4161:4161 nsqio/nsq /nsqlookupd - tcpPort = RandomPort() - httpPort = RandomPort() - tcpForward := fmt.Sprintf("%d:%d", tcpPort, 4160) - if BindDockerToLocalhost != "" { - tcpForward = "127.0.0.1:" + tcpForward - } - - httpForward := fmt.Sprintf("%d:%d", httpPort, 4161) - if BindDockerToLocalhost != "" { - httpForward = "127.0.0.1:" + httpForward - } - - c, ip, err = SetupContainer(NSQImageName, tcpPort, 15*time.Second, func() (string, error) { - return run("--name", GenerateContainerID(), "-d", "-P", "-p", tcpForward, "-p", httpForward, NSQImageName, "/nsqlookupd") - }) - return -} - -// ConnectToNSQLookupd starts a NSQ image with `/nsqlookupd` running and passes the IP, HTTP port, and TCP port to the connector callback function. -// The url will match the ip pattern (e.g. 123.123.123.123). -func ConnectToNSQLookupd(tries int, delay time.Duration, connector func(ip string, httpPort int, tcpPort int) bool) (c ContainerID, err error) { - c, ip, tcpPort, httpPort, err := SetupNSQLookupdContainer() - if err != nil { - return c, fmt.Errorf("Could not set up NSQLookupd container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - if connector(ip, httpPort, tcpPort) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up NSQLookupd container.") -} - -// ConnectToNSQd starts a NSQ image with `/nsqd` running and passes the IP, HTTP port, and TCP port to the connector callback function. -// The url will match the ip pattern (e.g. 123.123.123.123). -func ConnectToNSQd(tries int, delay time.Duration, connector func(ip string, httpPort int, tcpPort int) bool) (c ContainerID, err error) { - c, ip, tcpPort, httpPort, err := SetupNSQdContainer() - if err != nil { - return c, fmt.Errorf("Could not set up NSQd container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - if connector(ip, httpPort, tcpPort) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up NSQd container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/postgres.go b/vendor/gopkg.in/ory-am/dockertest.v2/postgres.go deleted file mode 100644 index 22546c290..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/postgres.go +++ /dev/null @@ -1,80 +0,0 @@ -package dockertest - -import ( - "database/sql" - "errors" - "fmt" - "log" - "net/url" - "time" - - _ "github.com/lib/pq" -) - -// SetupPostgreSQLContainer sets up a real PostgreSQL instance for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupPostgreSQLContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 5432) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(PostgresImageName, port, 15*time.Second, func() (string, error) { - return run("--name", GenerateContainerID(), "-d", "-p", forward, "-e", fmt.Sprintf("POSTGRES_PASSWORD=%s", PostgresPassword), PostgresImageName) - }) - return -} - -// ConnectToPostgreSQL starts a PostgreSQL image and passes the database url to the connector callback. -func ConnectToPostgreSQL(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupPostgreSQLContainer() - if err != nil { - return c, fmt.Errorf("Could not set up PostgreSQL container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("postgres://%s:%s@%s:%d/postgres?sslmode=disable", PostgresUsername, PostgresPassword, ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up PostgreSQL container.") -} - -// SetUpPostgreDatabase connects postgre container with given $connectURL and also creates a new database named $databaseName -// A modified url used to connect the created database will be returned -func SetUpPostgreDatabase(databaseName, connectURL string) (modifiedURL string, err error) { - db, err := sql.Open("postgres", connectURL) - if err != nil { - return "", err - } - defer db.Close() - - count := 0 - err = db.QueryRow( - fmt.Sprintf("SELECT COUNT(*) FROM pg_catalog.pg_database WHERE datname = '%s' ;", databaseName)). - Scan(&count) - if err != nil { - return "", err - } - if count == 0 { - // not found for $databaseName, create it - _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", databaseName)) - if err != nil { - return "", err - } - } - - // replace dbname in url - // from: postgres://postgres:docker@192.168.99.100:9071/postgres?sslmode=disable - // to: postgres://postgres:docker@192.168.99.100:9071/$databaseName?sslmode=disable - u, err := url.Parse(connectURL) - if err != nil { - return "", err - } - u.Path = fmt.Sprintf("/%s", databaseName) - return u.String(), nil -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/rabbitmq.go b/vendor/gopkg.in/ory-am/dockertest.v2/rabbitmq.go deleted file mode 100644 index fcc7e8d13..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/rabbitmq.go +++ /dev/null @@ -1,43 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupRabbitMQContainer sets up a real RabbitMQ instance for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupRabbitMQContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 5672) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(RabbitMQImageName, port, 10*time.Second, func() (string, error) { - res, err := run("--name", GenerateContainerID(), "-d", "-P", "-p", forward, RabbitMQImageName) - return res, err - }) - return -} - -// ConnectToRabbitMQ starts a RabbitMQ image and passes the amqp url to the connector callback. -// The url will match the ip:port pattern (e.g. 123.123.123.123:4241) -func ConnectToRabbitMQ(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupRabbitMQContainer() - if err != nil { - return c, fmt.Errorf("Could not set up RabbitMQ container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%d", ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up RabbitMQ container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/redis.go b/vendor/gopkg.in/ory-am/dockertest.v2/redis.go deleted file mode 100644 index 890127586..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/redis.go +++ /dev/null @@ -1,42 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupRedisContainer sets up a real Redis instance for testing purposes -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupRedisContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 6379) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(RedisImageName, port, 15*time.Second, func() (string, error) { - return run("--name", GenerateContainerID(), "-d", "-P", "-p", forward, RedisImageName) - }) - return -} - -// ConnectToRedis starts a Redis image and passes the database url to the connector callback function. -// The url will match the ip:port pattern (e.g. 123.123.123.123:6379) -func ConnectToRedis(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupRedisContainer() - if err != nil { - return c, fmt.Errorf("Could not set up Redis container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%d", ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up Redis container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/rethinkdb.go b/vendor/gopkg.in/ory-am/dockertest.v2/rethinkdb.go deleted file mode 100644 index 94d7d35d0..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/rethinkdb.go +++ /dev/null @@ -1,43 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupRethinkDBContainer sets up a real RethinkDB instance for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupRethinkDBContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 28015) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - c, ip, err = SetupContainer(RethinkDBImageName, port, 10*time.Second, func() (string, error) { - res, err := run("--name", GenerateContainerID(), "-d", "-P", "-p", forward, RethinkDBImageName) - return res, err - }) - return -} - -// ConnectToRethinkDB starts a RethinkDB image and passes the database url to the connector callback. -// The url will match the ip:port pattern (e.g. 123.123.123.123:4241) -func ConnectToRethinkDB(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupRethinkDBContainer() - if err != nil { - return c, fmt.Errorf("Could not set up RethinkDB container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%d", ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not set up RethinkDB container.") -} diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/vars.go b/vendor/gopkg.in/ory-am/dockertest.v2/vars.go deleted file mode 100644 index 619855e01..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/vars.go +++ /dev/null @@ -1,87 +0,0 @@ -package dockertest - -import "github.com/ory-am/common/env" - -// Dockertest configuration -var ( - // Debug if set, prevents any container from being removed. - Debug bool - - // DockerMachineAvailable if true, uses docker-machine to run docker commands (for running tests on Windows and Mac OS) - DockerMachineAvailable bool - - // DockerMachineName is the machine's name. You might want to use a dedicated machine for running your tests. - // You can set this variable either directly or by defining a DOCKERTEST_IMAGE_NAME env variable. - DockerMachineName = env.Getenv("DOCKERTEST_IMAGE_NAME", "default") - - // BindDockerToLocalhost if set, forces docker to bind the image to localhost. This for example is required when running tests on travis-ci. - // You can set this variable either directly or by defining a DOCKERTEST_BIND_LOCALHOST env variable. - // FIXME DOCKER_BIND_LOCALHOST remove legacy support - BindDockerToLocalhost = env.Getenv("DOCKERTEST_BIND_LOCALHOST", env.Getenv("DOCKER_BIND_LOCALHOST", "1")) - - // UseDockerMachine if set, forces docker to use the legacy docker-machine on OSX/Windows. - UseDockerMachine = env.Getenv("DOCKERTEST_LEGACY_DOCKER_MACHINE", "") - - // ContainerPrefix will be prepended to all containers started by dockertest to make identification of these "test images" hassle-free. - ContainerPrefix = env.Getenv("DOCKERTEST_CONTAINER_PREFIX", "dockertest-") -) - -// Image configuration -var ( - // MongoDBImageName is the MongoDB image name on dockerhub. - MongoDBImageName = env.Getenv("DOCKERTEST_MONGODB_IMAGE_NAME", "mongo") - - // MySQLImageName is the MySQL image name on dockerhub. - MySQLImageName = env.Getenv("DOCKERTEST_MYSQL_IMAGE_NAME", "mysql") - - // PostgresImageName is the PostgreSQL image name on dockerhub. - PostgresImageName = env.Getenv("DOCKERTEST_POSTGRES_IMAGE_NAME", "postgres") - - // ElasticSearchImageName is the ElasticSearch image name on dockerhub. - ElasticSearchImageName = env.Getenv("DOCKERTEST_ELASTICSEARCH_IMAGE_NAME", "elasticsearch") - - // RedisImageName is the Redis image name on dockerhub. - RedisImageName = env.Getenv("DOCKERTEST_REDIS_IMAGE_NAME", "redis") - - // NSQImageName is the NSQ image name on dockerhub. - NSQImageName = env.Getenv("DOCKERTEST_NSQ_IMAGE_NAME", "nsqio/nsq") - - // RethinkDBImageName is the RethinkDB image name on dockerhub. - RethinkDBImageName = env.Getenv("DOCKERTEST_RETHINKDB_IMAGE_NAME", "rethinkdb") - - // RabbitMQImage name is the RabbitMQ image name on dockerhub. - RabbitMQImageName = env.Getenv("DOCKERTEST_RABBITMQ_IMAGE_NAME", "rabbitmq") - - // ActiveMQImage name is the ActiveMQ image name on dockerhub. - ActiveMQImageName = env.Getenv("DOCKERTEST_ACTIVEMQ_IMAGE_NAME", "webcenter/activemq") - - // MockserverImageName name is the Mockserver image name on dockerhub. - MockserverImageName = env.Getenv("DOCKERTEST_MOCKSERVER_IMAGE_NAME", "jamesdbloom/mockserver") - - // ConsulImageName is the Consul image name on dockerhub. - ConsulImageName = env.Getenv("DOCKERTEST_CONSUL_IMAGE_NAME", "consul") - - // ZooKeeperImageName is the ZooKeeper image name on dockerhub. - ZooKeeperImageName = env.Getenv("DOCKERTEST_ZOOKEEPER_IMAGE_NAME", "jplock/zookeeper") - - // CassandraImageName is the Cassandra image name on dockerhub. - CassandraImageName = env.Getenv("DOCKERTEST_CASSANDRA_IMAGE_NAME", "cassandra") - - // EtcdImageName is the etcd image name on dockerhub. - EtcdImageName = env.Getenv("DOCKERTEST_ETCD_IMAGE_NAME", "quay.io/coreos/etcd") -) - -// Username and password configuration -var ( - // MySQLUsername must be passed as username when connecting to mysql - MySQLUsername = "root" - - // MySQLPassword must be passed as password when connecting to mysql - MySQLPassword = "root" - - // PostgresUsername must be passed as username when connecting to postgres - PostgresUsername = "postgres" - - // PostgresPassword must be passed as password when connecting to postgres - PostgresPassword = "docker" -) diff --git a/vendor/gopkg.in/ory-am/dockertest.v2/zookeeper.go b/vendor/gopkg.in/ory-am/dockertest.v2/zookeeper.go deleted file mode 100644 index 5f08bcf8c..000000000 --- a/vendor/gopkg.in/ory-am/dockertest.v2/zookeeper.go +++ /dev/null @@ -1,43 +0,0 @@ -package dockertest - -import ( - "errors" - "fmt" - "log" - "time" -) - -// SetupZooKeeperContainer sets up a real ZooKeeper node for testing purposes, -// using a Docker container. It returns the container ID and its IP address, -// or makes the test fail on error. -func SetupZooKeeperContainer() (c ContainerID, ip string, port int, err error) { - port = RandomPort() - forward := fmt.Sprintf("%d:%d", port, 2181) - if BindDockerToLocalhost != "" { - forward = "127.0.0.1:" + forward - } - - c, ip, err = SetupContainer(ZooKeeperImageName, port, 10*time.Second, func() (string, error) { - return run("--name", GenerateContainerID(), "-d", "-p", forward, ZooKeeperImageName) - }) - return -} - -// ConnectToZooKeeper starts a ZooKeeper image and passes the nodes connection string to the connector callback function. -// The connection string will match the ip:port pattern. -func ConnectToZooKeeper(tries int, delay time.Duration, connector func(url string) bool) (c ContainerID, err error) { - c, ip, port, err := SetupZooKeeperContainer() - if err != nil { - return c, fmt.Errorf("Could not setup ZooKeeper container: %v", err) - } - - for try := 0; try <= tries; try++ { - time.Sleep(delay) - url := fmt.Sprintf("%s:%d", ip, port) - if connector(url) { - return c, nil - } - log.Printf("Try %d failed. Retrying.", try) - } - return c, errors.New("Could not setup ZooKeeper container.") -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 3324a1e98..564c91836 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -214,7 +214,7 @@ github.com/go-errors/errors github.com/go-ldap/ldap # github.com/go-sql-driver/mysql v1.4.1 github.com/go-sql-driver/mysql -# github.com/go-test/deep v1.0.1 +# github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31 github.com/go-test/deep # github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df github.com/gocql/gocql @@ -480,8 +480,6 @@ github.com/opencontainers/image-spec/specs-go/v1 github.com/opencontainers/image-spec/specs-go # github.com/opencontainers/runc v0.1.1 github.com/opencontainers/runc/libcontainer/user -# github.com/ory-am/common v0.4.0 -github.com/ory-am/common/env # github.com/ory/dockertest v3.3.4+incompatible github.com/ory/dockertest github.com/ory/dockertest/docker @@ -510,8 +508,6 @@ github.com/ory/dockertest/docker/types/strslice github.com/ory/dockertest/docker/types/versions # github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache -# github.com/pborman/uuid v1.2.0 -github.com/pborman/uuid # github.com/pierrec/lz4 v2.0.5+incompatible github.com/pierrec/lz4 github.com/pierrec/lz4/internal/xxh32 @@ -753,8 +749,6 @@ gopkg.in/mgo.v2/bson gopkg.in/mgo.v2/internal/sasl gopkg.in/mgo.v2/internal/scram gopkg.in/mgo.v2/internal/json -# gopkg.in/ory-am/dockertest.v2 v2.2.3 -gopkg.in/ory-am/dockertest.v2 # gopkg.in/ory-am/dockertest.v3 v3.3.4 gopkg.in/ory-am/dockertest.v3 # gopkg.in/square/go-jose.v2 v2.3.1 diff --git a/website/source/api/libraries.html.md b/website/source/api/libraries.html.md index c30821da3..ba3a1b93a 100644 --- a/website/source/api/libraries.html.md +++ b/website/source/api/libraries.html.md @@ -47,7 +47,7 @@ $ pip install ansible-modules-hashivault ### C# -* [VaultSharp](https://github.com/rajanadar/VaultSharp) (.NET Core >= 1.0.0, .NET 4.5, .NET 4.6, Mono, iOS, Android, Mac, UWP etc.) +* [VaultSharp](https://github.com/rajanadar/VaultSharp) (.NET Standard 2.0 & 1.3, .NET Core >= 1.0.0, .NET 4.5, .NET 4.6, Mono, iOS, Android, Mac, UWP etc.) ```shell $ Install-Package VaultSharp diff --git a/website/source/api/secret/aws/index.html.md b/website/source/api/secret/aws/index.html.md index f790b6e2b..aa5dafecd 100644 --- a/website/source/api/secret/aws/index.html.md +++ b/website/source/api/secret/aws/index.html.md @@ -230,6 +230,9 @@ updated with the new attributes. TTL are capped to `max_sts_ttl`). Valid only when `credential_type` is one of `assumed_role` or `federation_token`. +- `user_path` `(string)` - The path for the user name. Valid only when + `credential_type` is `iam_user`. Default is `/` + Legacy parameters: These parameters are supported for backwards compatibility only. They cannot be diff --git a/website/source/api/secret/gcp/index.html.md b/website/source/api/secret/gcp/index.html.md index 475e81c34..7484719cb 100644 --- a/website/source/api/secret/gcp/index.html.md +++ b/website/source/api/secret/gcp/index.html.md @@ -194,6 +194,10 @@ $ curl \ | :------------------------| :------------------------ | | `GET` | `/gcp/roleset/:name` | +### Parameters + +- `name` (`string:`): Name of the roleset to delete. + ### Sample Request ``` @@ -234,10 +238,6 @@ $ curl \ | `LIST` | `/gcp/rolesets` | -| Method | Path | -| :------------------------| :------------------------ | -| `LIST` | `/gcp/roleset` | - ### Sample Request ``` @@ -260,6 +260,27 @@ $ curl \ } ``` +## Delete Roleset + +This endpoint deletes an existing roleset by the given name. + +| Method | Path | +| :------------------------| :------------------------ | +| `DELETE` | `/gcp/roleset/:name` | + +### Parameters + +- `name` (`string:`): Name of the roleset to delete. + +### Sample Request + +``` +$ curl \ + --header "X-Vault-Token: ..." \ + --request DELETE \ + https://127.0.0.1:8200/v1/gcp/roleset/my-token-roleset +``` + ## Generate Secret (IAM Service Account Creds): OAuth2 Access Token diff --git a/website/source/api/secret/pki/index.html.md b/website/source/api/secret/pki/index.html.md index be4ea4917..63cecd833 100644 --- a/website/source/api/secret/pki/index.html.md +++ b/website/source/api/secret/pki/index.html.md @@ -545,7 +545,8 @@ $ curl \ This endpoint allows submitting the signed CA certificate corresponding to a private key generated via `/pki/intermediate/generate`. The certificate should -be submitted in PEM format; see the documentation for `/pki/config/ca` for some +be submitted in PEM format; see the documentation for +[/pki/config/ca](/api/secret/pki/index.html#submit-ca-information) for some hints on submitting. | Method | Path | diff --git a/website/source/docs/commands/token/create.html.md b/website/source/docs/commands/token/create.html.md index e064f0098..4e96cbb2a 100644 --- a/website/source/docs/commands/token/create.html.md +++ b/website/source/docs/commands/token/create.html.md @@ -117,6 +117,8 @@ flags](/docs/commands/index.html) included on all commands. maximumTTLs. This is specified as a numeric string with suffix like "30s" or "5m". +- `-type` `(string: "service")` - The type of token to create. Can be "service" or "batch". + - `-use-limit` `(int: 0)` - Number of times this token can be used. After the last use, the token is automatically revoked. By default, tokens can be used an unlimited number of times until their expiration. diff --git a/website/source/docs/secrets/gcp/index.html.md b/website/source/docs/secrets/gcp/index.html.md index 4057a87dd..a098de5ea 100644 --- a/website/source/docs/secrets/gcp/index.html.md +++ b/website/source/docs/secrets/gcp/index.html.md @@ -199,7 +199,7 @@ few different formats: include the resource nested in the parent project. ```text - # compute alpha zome + # compute alpha zone https://www.googleapis.com/compute/alpha/projects/my-project/zones/us-central1-c ```