Skip to content

Commit cd29c23

Browse files
authored
Run local KES for S3 integration tests (cortexproject#4547)
Instead of calling out to play.min.io, run the KES service locally in a container. Generate its key and cert instead of downloading them from GitHub. By depending on fewer third-party services we reduce test failures. Extract function to generate PKI certificates. Update to more recent Minio image; not using the very latest KES because it removed `--root` which is useful. Re-enable the SSE tests (see cortexproject#4545) Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
1 parent c7845ae commit cd29c23

File tree

4 files changed

+98
-21
lines changed

4 files changed

+98
-21
lines changed

integration/certs.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//go:build requires_docker
2+
// +build requires_docker
3+
4+
package integration
5+
6+
import (
7+
"crypto/x509"
8+
"crypto/x509/pkix"
9+
"os"
10+
"path/filepath"
11+
12+
"github.com/cortexproject/cortex/integration/ca"
13+
)
14+
15+
func writeCerts(dir string, dnsNames ...string) error {
16+
// set the ca
17+
cert := ca.New("Test")
18+
19+
// Ensure the entire path of directories exist.
20+
if err := os.MkdirAll(filepath.Join(dir, "certs"), os.ModePerm); err != nil {
21+
return err
22+
}
23+
24+
if err := cert.WriteCACertificate(filepath.Join(dir, caCertFile)); err != nil {
25+
return err
26+
}
27+
28+
// server certificate
29+
if err := cert.WriteCertificate(
30+
&x509.Certificate{
31+
Subject: pkix.Name{CommonName: "client"},
32+
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
33+
},
34+
filepath.Join(dir, clientCertFile),
35+
filepath.Join(dir, clientKeyFile),
36+
); err != nil {
37+
return err
38+
}
39+
if err := cert.WriteCertificate(
40+
&x509.Certificate{
41+
Subject: pkix.Name{CommonName: "server"},
42+
DNSNames: dnsNames,
43+
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
44+
},
45+
filepath.Join(dir, serverCertFile),
46+
filepath.Join(dir, serverKeyFile),
47+
); err != nil {
48+
return err
49+
}
50+
return nil
51+
}

integration/e2e/db/db.go

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package e2edb
22

33
import (
44
"fmt"
5+
"path/filepath"
56
"strings"
67

78
"github.com/cortexproject/cortex/integration/e2e"
@@ -15,11 +16,23 @@ const (
1516

1617
// NewMinio returns minio server, used as a local replacement for S3.
1718
func NewMinio(port int, bktNames ...string) *e2e.HTTPService {
18-
minioKESGithubContent := "https://raw.githubusercontent.com/minio/kes/master"
19-
commands := []string{
20-
fmt.Sprintf("curl -sSL --tlsv1.2 -O '%s/root.key' -O '%s/root.cert'", minioKESGithubContent, minioKESGithubContent),
19+
return newMinio(port, map[string]string{}, bktNames...)
20+
}
21+
22+
// NewMinioWithKES returns minio server, configured to talk to a KES service.
23+
func NewMinioWithKES(port int, kesEndpoint, rootKeyFile, rootCertFile, caCertFile string, bktNames ...string) *e2e.HTTPService {
24+
kesEnvVars := map[string]string{
25+
"MINIO_KMS_KES_ENDPOINT": kesEndpoint,
26+
"MINIO_KMS_KES_KEY_FILE": filepath.Join(e2e.ContainerSharedDir, rootKeyFile),
27+
"MINIO_KMS_KES_CERT_FILE": filepath.Join(e2e.ContainerSharedDir, rootCertFile),
28+
"MINIO_KMS_KES_CAPATH": filepath.Join(e2e.ContainerSharedDir, caCertFile),
29+
"MINIO_KMS_KES_KEY_NAME": "my-minio-key",
2130
}
31+
return newMinio(port, kesEnvVars, bktNames...)
32+
}
2233

34+
func newMinio(port int, envVars map[string]string, bktNames ...string) *e2e.HTTPService {
35+
commands := []string{}
2336
for _, bkt := range bktNames {
2437
commands = append(commands, fmt.Sprintf("mkdir -p /data/%s", bkt))
2538
}
@@ -33,17 +46,27 @@ func NewMinio(port int, bktNames ...string) *e2e.HTTPService {
3346
e2e.NewHTTPReadinessProbe(port, "/minio/health/ready", 200, 200),
3447
port,
3548
)
36-
m.SetEnvVars(map[string]string{
37-
"MINIO_ACCESS_KEY": MinioAccessKey,
38-
"MINIO_SECRET_KEY": MinioSecretKey,
39-
"MINIO_BROWSER": "off",
40-
"ENABLE_HTTPS": "0",
41-
// https://docs.min.io/docs/minio-kms-quickstart-guide.html
42-
"MINIO_KMS_KES_ENDPOINT": "https://play.min.io:7373",
43-
"MINIO_KMS_KES_KEY_FILE": "root.key",
44-
"MINIO_KMS_KES_CERT_FILE": "root.cert",
45-
"MINIO_KMS_KES_KEY_NAME": "my-minio-key",
46-
})
49+
envVars["MINIO_ACCESS_KEY"] = MinioAccessKey
50+
envVars["MINIO_SECRET_KEY"] = MinioSecretKey
51+
envVars["MINIO_BROWSER"] = "off"
52+
envVars["ENABLE_HTTPS"] = "0"
53+
m.SetEnvVars(envVars)
54+
return m
55+
}
56+
57+
// NewKES returns KES server, used as a local key management store
58+
func NewKES(port int, serverKeyFile, serverCertFile, rootCertFile string) *e2e.HTTPService {
59+
// Run this as a shell command, so sub-shell can evaluate 'identity' of root user.
60+
command := fmt.Sprintf("/kes server --addr 0.0.0.0:%d --key=%s --cert=%s --root=$(/kes tool identity of %s) --auth=off --quiet",
61+
port, filepath.Join(e2e.ContainerSharedDir, serverKeyFile), filepath.Join(e2e.ContainerSharedDir, serverCertFile), filepath.Join(e2e.ContainerSharedDir, rootCertFile))
62+
63+
m := e2e.NewHTTPService(
64+
"kes",
65+
images.KES,
66+
e2e.NewCommandWithoutEntrypoint("sh", "-c", command),
67+
nil, // KES only supports https calls - TODO make Scenario able to call https or poll plain TCP socket.
68+
port,
69+
)
4770
return m
4871
}
4972

integration/e2e/images/images.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ package images
77

88
var (
99
Memcached = "memcached:1.6.1"
10-
Minio = "minio/minio:RELEASE.2019-12-30T05-45-39Z"
10+
Minio = "minio/minio:RELEASE.2021-10-13T00-23-17Z"
11+
KES = "minio/kes:v0.17.1"
1112
Consul = "consul:1.8.4"
1213
ETCD = "gcr.io/etcd-development/etcd:v3.4.7"
1314
DynamoDB = "amazon/dynamodb-local:1.11.477"

integration/s3_storage_client_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build requires_docker
12
// +build requires_docker
23

34
package integration
@@ -24,7 +25,13 @@ func TestS3Client(t *testing.T) {
2425
defer s.Close()
2526

2627
// Start dependencies.
27-
minio := e2edb.NewMinio(9000, bucketName)
28+
// We use KES to emulate a Key Management Store for use with Minio
29+
kesDNSName := networkName + "-kes"
30+
require.NoError(t, writeCerts(s.SharedDir(), kesDNSName))
31+
// Start dependencies.
32+
kes := e2edb.NewKES(7373, serverKeyFile, serverCertFile, clientCertFile)
33+
require.NoError(t, s.Start(kes)) // TODO: wait for it to be ready, but currently there is no way to probe.
34+
minio := e2edb.NewMinioWithKES(9000, "https://"+kesDNSName+":7373", clientKeyFile, clientCertFile, caCertFile, bucketName)
2835
require.NoError(t, s.StartAndWaitReady(minio))
2936

3037
tests := []struct {
@@ -94,11 +101,6 @@ func TestS3Client(t *testing.T) {
94101

95102
for _, tt := range tests {
96103
t.Run(tt.name, func(t *testing.T) {
97-
switch tt.name {
98-
case "config-with-deprecated-sse", "config-with-sse-s3":
99-
t.Skip("TODO: Issue #4543")
100-
}
101-
102104
client, err := s3.NewS3ObjectClient(tt.cfg)
103105

104106
require.NoError(t, err)

0 commit comments

Comments
 (0)