metropolis/test/util: move in NewEphemeralClusterCredentials from rpc
Change-Id: I41603b19a76ea91c2191b0118183957973fc9ccd
Reviewed-on: https://review.monogon.dev/c/monogon/+/1960
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
Tested-by: Jenkins CI
diff --git a/metropolis/test/util/BUILD.bazel b/metropolis/test/util/BUILD.bazel
index 16ed382..d431dbe 100644
--- a/metropolis/test/util/BUILD.bazel
+++ b/metropolis/test/util/BUILD.bazel
@@ -2,8 +2,15 @@
go_library(
name = "util",
- srcs = ["runners.go"],
+ srcs = [
+ "rpc.go",
+ "runners.go",
+ ],
importpath = "source.monogon.dev/metropolis/test/util",
visibility = ["//metropolis:__subpackages__"],
- deps = ["//metropolis/test/launch"],
+ deps = [
+ "//metropolis/node/core/identity",
+ "//metropolis/pkg/pki",
+ "//metropolis/test/launch",
+ ],
)
diff --git a/metropolis/test/util/rpc.go b/metropolis/test/util/rpc.go
new file mode 100644
index 0000000..e4caece
--- /dev/null
+++ b/metropolis/test/util/rpc.go
@@ -0,0 +1,100 @@
+package util
+
+import (
+ "context"
+ "crypto/ed25519"
+ "crypto/rand"
+ "crypto/tls"
+ "crypto/x509"
+ "testing"
+
+ "source.monogon.dev/metropolis/node/core/identity"
+ "source.monogon.dev/metropolis/pkg/pki"
+)
+
+// NewEphemeralClusterCredentials creates a set of TLS certificates for use in a
+// test Metropolis cluster. These are a CA certificate, a Manager certificate
+// and an arbitrary amount of Node certificates (per the nodes argument).
+//
+// All of these are ephemeral, ie. not stored anywhere - including the CA
+// certificate. This function is for use by tests which want to bring up a
+// minimum set of PKI credentials for a fake Metropolis cluster.
+func NewEphemeralClusterCredentials(t *testing.T, nodes int) *EphemeralClusterCredentials {
+ ctx := context.Background()
+ t.Helper()
+
+ ns := pki.Namespaced("unused")
+ caCert := pki.Certificate{
+ Namespace: &ns,
+ Issuer: pki.SelfSigned,
+ Template: identity.CACertificate("test cluster ca"),
+ Mode: pki.CertificateEphemeral,
+ }
+ caBytes, err := caCert.Ensure(ctx, nil)
+ if err != nil {
+ t.Fatalf("Could not ensure CA certificate: %v", err)
+ }
+ ca, err := x509.ParseCertificate(caBytes)
+ if err != nil {
+ t.Fatalf("Could not parse new CA certificate: %v", err)
+ }
+
+ managerCert := pki.Certificate{
+ Namespace: &ns,
+ Issuer: &caCert,
+ Template: identity.UserCertificate("owner"),
+ Mode: pki.CertificateEphemeral,
+ }
+ managerBytes, err := managerCert.Ensure(ctx, nil)
+ if err != nil {
+ t.Fatalf("Could not ensure manager certificate: %v", err)
+ }
+ res := &EphemeralClusterCredentials{
+ Nodes: make([]*identity.NodeCredentials, nodes),
+ Manager: tls.Certificate{
+ Certificate: [][]byte{managerBytes},
+ PrivateKey: managerCert.PrivateKey,
+ },
+ CA: ca,
+ }
+
+ for i := 0; i < nodes; i++ {
+ npk, npr, err := ed25519.GenerateKey(rand.Reader)
+ if err != nil {
+ t.Fatalf("Could not generate node keypair: %v", err)
+ }
+ nodeCert := pki.Certificate{
+ Namespace: &ns,
+ Issuer: &caCert,
+ Template: identity.NodeCertificate(npk),
+ Mode: pki.CertificateEphemeral,
+ PublicKey: npk,
+ Name: "",
+ }
+ nodeBytes, err := nodeCert.Ensure(ctx, nil)
+ if err != nil {
+ t.Fatalf("Could not ensure node certificate: %v", err)
+ }
+ node, err := identity.NewNodeCredentials(npr, nodeBytes, caBytes)
+ if err != nil {
+ t.Fatalf("Could not build node credentials: %v", err)
+ }
+ res.Nodes[i] = node
+ }
+
+ return res
+}
+
+// EphemeralClusterCredentials are TLS/PKI credentials for use in a Metropolis
+// test cluster.
+type EphemeralClusterCredentials struct {
+ // Nodes are the node credentials for the cluster. Each contains a private
+ // key and x509 certificate authenticating the bearer as a Metropolis node.
+ Nodes []*identity.NodeCredentials
+ // Manager TLS certificate for the cluster. Contains a private key and x509
+ // certificate authenticating the bearer as a Metropolis manager.
+ Manager tls.Certificate
+ // CA is the x509 certificate of the CA certificate for the cluster. Manager and
+ // Node certificates are signed by this CA.
+ CA *x509.Certificate
+}