metropolis: implement Metrics Service

This is the first pass at a Metrics Service. It currently consists of an
HTTP reverse proxy which authenticates incoming connections using the
Cluster CA and certificates, and passes these connections over to a
locally running node_exporter.

In the future more exporters will be added, and we will likely also run
our own exporter for Metropolis-specific metrics.

Change-Id: Ibab52aa303965dd7d975f5035f411d1c56ad73e6
Reviewed-on: https://review.monogon.dev/c/monogon/+/1816
Tested-by: Jenkins CI
Reviewed-by: Leopold Schabel <leo@monogon.tech>
diff --git a/metropolis/test/launch/cluster/cluster.go b/metropolis/test/launch/cluster/cluster.go
index 0efd08b..615a9cc 100644
--- a/metropolis/test/launch/cluster/cluster.go
+++ b/metropolis/test/launch/cluster/cluster.go
@@ -10,6 +10,7 @@
 	"crypto/ed25519"
 	"crypto/rand"
 	"crypto/tls"
+	"crypto/x509"
 	"errors"
 	"fmt"
 	"io"
@@ -504,6 +505,9 @@
 	// creation.
 	NodeIDs []string
 
+	// CACertificate is the cluster's CA certificate.
+	CACertificate *x509.Certificate
+
 	// nodesDone is a list of channels populated with the return codes from all the
 	// nodes' qemu instances. It's used by Close to ensure all nodes have
 	// successfully been stopped.
@@ -829,6 +833,12 @@
 		ctxC()
 		return nil, fmt.Errorf("GetClusterInfo: %w", err)
 	}
+	caCert, err := x509.ParseCertificate(resI.CaCertificate)
+	if err != nil {
+		ctxC()
+		return nil, fmt.Errorf("ParseCertificate: %w", err)
+	}
+	cluster.CACertificate = caCert
 
 	// Use the retrieved information to configure the rest of the node options.
 	for i := 1; i < opts.NumNodes; i++ {