Merge branch 'master' into fix-6579
This commit is contained in:
commit
ed722d8013
|
@ -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=
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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,
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
))
|
||||
}
|
||||
|
||||
|
|
12
go.mod
12
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
|
||||
|
|
31
go.sum
31
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=
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, "<nil pointer>")
|
||||
c.saveDiff("<nil pointer>", b)
|
||||
} else if a != nil && b == nil {
|
||||
c.saveDiff(a, "<nil pointer>")
|
||||
}
|
||||
|
@ -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}
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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.
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -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
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- "1.9"
|
||||
- "1.10"
|
||||
- "1.11"
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v ./...
|
|
@ -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.
|
|
@ -1 +0,0 @@
|
|||
Paul Borman <borman@google.com>
|
|
@ -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.
|
|
@ -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
|
|
@ -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))
|
||||
}
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
module github.com/pborman/uuid
|
||||
|
||||
require github.com/google/uuid v1.0.0
|
|
@ -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=
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
.idea/
|
||||
node_modules/
|
||||
*.iml
|
||||
*.exe
|
||||
.cover/
|
||||
vendor/
|
|
@ -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"
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
**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)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
## 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)
|
||||
}
|
||||
```
|
|
@ -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.")
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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
|
|
@ -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())
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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.")
|
||||
}
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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.")
|
||||
}
|
|
@ -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"
|
||||
)
|
|
@ -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.")
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -194,6 +194,10 @@ $ curl \
|
|||
| :------------------------| :------------------------ |
|
||||
| `GET` | `/gcp/roleset/:name` |
|
||||
|
||||
### Parameters
|
||||
|
||||
- `name` (`string:<required>`): 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:<required>`): 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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in New Issue