m/node: implement Port type for node ports
This allows us to use %v/%s to get a pretty port name where needed.
We also drive-by remove MasterServicePort which is a leftover from
a pre-curator cluster service implementation.
Change-Id: Id8feddf87269b13dd1dad2460a015c1a7ecbc6d7
Reviewed-on: https://review.monogon.dev/c/monogon/+/418
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/node/core/consensus/consensus.go b/metropolis/node/core/consensus/consensus.go
index 8e74000..d0fe83f 100644
--- a/metropolis/node/core/consensus/consensus.go
+++ b/metropolis/node/core/consensus/consensus.go
@@ -124,7 +124,7 @@
}
port := s.config.Port
if port == 0 {
- port = node.ConsensusPort
+ port = int(node.ConsensusPort)
}
cfg := embed.NewConfig()
diff --git a/metropolis/node/kubernetes/apiserver.go b/metropolis/node/kubernetes/apiserver.go
index e3f0d98..39105b2 100644
--- a/metropolis/node/kubernetes/apiserver.go
+++ b/metropolis/node/kubernetes/apiserver.go
@@ -98,7 +98,7 @@
"--enable-admission-plugins=NodeRestriction,PodSecurityPolicy",
"--enable-aggregator-routing=true",
"--insecure-port=0",
- fmt.Sprintf("--secure-port=%v", common.KubernetesAPIPort),
+ fmt.Sprintf("--secure-port=%d", common.KubernetesAPIPort),
fmt.Sprintf("--etcd-servers=unix:///%s:0", s.EphemeralConsensusDirectory.ClientSocket.FullPath()),
args.FileOpt("--kubelet-client-certificate", "kubelet-client-cert.pem",
pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: s.kubeletClientCert})),
diff --git a/metropolis/node/kubernetes/clusternet/clusternet.go b/metropolis/node/kubernetes/clusternet/clusternet.go
index 85a78a1..3cf2535 100644
--- a/metropolis/node/kubernetes/clusternet/clusternet.go
+++ b/metropolis/node/kubernetes/clusternet/clusternet.go
@@ -120,7 +120,7 @@
err = s.wgClient.ConfigureDevice(clusterNetDeviceName, wgtypes.Config{
Peers: []wgtypes.PeerConfig{{
PublicKey: pubKey,
- Endpoint: &net.UDPAddr{Port: common.WireGuardPort, IP: internalIP},
+ Endpoint: &net.UDPAddr{Port: int(common.WireGuardPort), IP: internalIP},
ReplaceAllowedIPs: true,
AllowedIPs: allowedIPs,
}},
@@ -227,7 +227,7 @@
}
defer netlink.LinkDel(wgInterface)
- listenPort := common.WireGuardPort
+ listenPort := int(common.WireGuardPort)
if err := wgClient.ConfigureDevice(clusterNetDeviceName, wgtypes.Config{
PrivateKey: &s.privKey,
ListenPort: &listenPort,
diff --git a/metropolis/node/kubernetes/pki/kubernetes.go b/metropolis/node/kubernetes/pki/kubernetes.go
index a59ab98..0c795f2 100644
--- a/metropolis/node/kubernetes/pki/kubernetes.go
+++ b/metropolis/node/kubernetes/pki/kubernetes.go
@@ -213,7 +213,7 @@
kubeconfig := configapi.NewConfig()
cluster := configapi.NewCluster()
- cluster.Server = fmt.Sprintf("https://127.0.0.1:%v", common.KubernetesAPIPort)
+ cluster.Server = fmt.Sprintf("https://127.0.0.1:%d", common.KubernetesAPIPort)
ca, err := c.Issuer.CACertificate(ctx, kv)
if err != nil {
diff --git a/metropolis/node/ports.go b/metropolis/node/ports.go
index 3449f07..05cbd9e 100644
--- a/metropolis/node/ports.go
+++ b/metropolis/node/ports.go
@@ -16,12 +16,44 @@
package node
+// Port is a TCP and/or UDP port number reserved for and used by Metropolis
+// node code.
+type Port uint16
+
const (
- CuratorServicePort = 7835
- ConsensusPort = 7834
- MasterServicePort = 7833
- DebugServicePort = 7837
- WireGuardPort = 7838
- KubernetesAPIPort = 6443
- DebuggerPort = 2345
+ // CuratorServicePort is the TCP port on which the Curator listens for gRPC
+ // calls and services Management/AAA/Curator RPCs.
+ CuratorServicePort Port = 7835
+ // ConsensusPort is the TCP port on which etcd listens for peer traffic.
+ ConsensusPort Port = 7834
+ // DebugServicePort is the TCP port on which the debug service serves gRPC
+ // traffic. This is only available in debug builds.
+ DebugServicePort Port = 7837
+ // WireGuardPort is the UDP port on which the Wireguard Kubernetes network
+ // overlay listens for incoming peer traffic.
+ WireGuardPort Port = 7838
+ // KubernetesAPIPort is the TCP port on which the Kubernetes API is
+ // exposed.
+ KubernetesAPIPort Port = 6443
+ // DebuggerPort is the port on which the delve debugger runs (on debug
+ // builds only). Not to be confused with DebugServicePort.
+ DebuggerPort Port = 2345
)
+
+func (p Port) String() string {
+ switch p {
+ case CuratorServicePort:
+ return "curator"
+ case ConsensusPort:
+ return "consensus"
+ case DebugServicePort:
+ return "debug"
+ case WireGuardPort:
+ return "wireguard"
+ case KubernetesAPIPort:
+ return "kubernetes-api"
+ case DebuggerPort:
+ return "delve"
+ }
+ return "unknown"
+}
diff --git a/metropolis/test/launch/BUILD.bazel b/metropolis/test/launch/BUILD.bazel
index 22590fe..1cb6b24 100644
--- a/metropolis/test/launch/BUILD.bazel
+++ b/metropolis/test/launch/BUILD.bazel
@@ -6,6 +6,7 @@
importpath = "source.monogon.dev/metropolis/test/launch",
visibility = ["//metropolis:__subpackages__"],
deps = [
+ "//metropolis/node:go_default_library",
"//metropolis/pkg/freeport:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_x_sys//unix:go_default_library",
diff --git a/metropolis/test/launch/cluster/cluster.go b/metropolis/test/launch/cluster/cluster.go
index 6be0efe..a4f11a2 100644
--- a/metropolis/test/launch/cluster/cluster.go
+++ b/metropolis/test/launch/cluster/cluster.go
@@ -62,14 +62,13 @@
}
// NodePorts is the list of ports a fully operational Metropolis node listens on
-var NodePorts = []uint16{
+var NodePorts = []node.Port{
node.ConsensusPort,
node.CuratorServicePort,
node.DebugServicePort,
node.KubernetesAPIPort,
- node.MasterServicePort,
node.CuratorServicePort,
node.DebuggerPort,
}
@@ -252,7 +251,7 @@
// ClusterPorts contains all ports forwarded by Nanoswitch to the first VM in a
// launched Metropolis cluster.
-var ClusterPorts = []uint16{
+var ClusterPorts = []node.Port{
node.CuratorServicePort,
node.DebugServicePort,
diff --git a/metropolis/test/launch/launch.go b/metropolis/test/launch/launch.go
index 0b15a58..4a4c803 100644
--- a/metropolis/test/launch/launch.go
+++ b/metropolis/test/launch/launch.go
@@ -32,6 +32,7 @@
"golang.org/x/sys/unix"
"google.golang.org/grpc"
+ "source.monogon.dev/metropolis/node"
"source.monogon.dev/metropolis/pkg/freeport"
)
@@ -57,28 +58,28 @@
// PortMap represents where VM ports are mapped to on the host. It maps from the VM
// port number to the host port number.
-type PortMap map[uint16]uint16
+type PortMap map[node.Port]uint16
// ToQemuForwards generates QEMU hostfwd values (https://qemu.weilnetz.de/doc/qemu-
// doc.html#:~:text=hostfwd=) for all mapped ports.
func (p PortMap) ToQemuForwards() []string {
var hostfwdOptions []string
for vmPort, hostPort := range p {
- hostfwdOptions = append(hostfwdOptions, fmt.Sprintf("tcp::%v-:%v", hostPort, vmPort))
+ hostfwdOptions = append(hostfwdOptions, fmt.Sprintf("tcp::%d-:%d", hostPort, vmPort))
}
return hostfwdOptions
}
// DialGRPC creates a gRPC client for a VM port that's forwarded/mapped to the
// host. The given port is automatically resolved to the host-mapped port.
-func (p PortMap) DialGRPC(port uint16, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
+func (p PortMap) DialGRPC(port node.Port, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
mappedPort, ok := p[port]
if !ok {
- return nil, fmt.Errorf("cannot dial port: port %v is not mapped/forwarded", port)
+ return nil, fmt.Errorf("cannot dial port: port %d is not mapped/forwarded", port)
}
- grpcClient, err := grpc.Dial(fmt.Sprintf("localhost:%v", mappedPort), opts...)
+ grpcClient, err := grpc.Dial(fmt.Sprintf("localhost:%d", mappedPort), opts...)
if err != nil {
- return nil, fmt.Errorf("failed to dial port %v: %w", port, err)
+ return nil, fmt.Errorf("failed to dial port %d: %w", port, err)
}
return grpcClient, nil
}
@@ -86,10 +87,10 @@
// IdentityPortMap returns a port map where each given port is mapped onto itself
// on the host. This is mainly useful for development against Metropolis. The dbg
// command requires this mapping.
-func IdentityPortMap(ports []uint16) PortMap {
+func IdentityPortMap(ports []node.Port) PortMap {
portMap := make(PortMap)
for _, port := range ports {
- portMap[port] = port
+ portMap[port] = uint16(port)
}
return portMap
}
@@ -99,7 +100,7 @@
// multiple instances of Metropolis nodes might be running. Please call this
// function for each Launch command separately and as close to it as possible since
// it cannot guarantee that the ports will remain free.
-func ConflictFreePortMap(ports []uint16) (PortMap, error) {
+func ConflictFreePortMap(ports []node.Port) (PortMap, error) {
portMap := make(PortMap)
for _, port := range ports {
mappedPort, listenCloser, err := freeport.AllocateTCPPort()
diff --git a/metropolis/test/nanoswitch/nanoswitch.go b/metropolis/test/nanoswitch/nanoswitch.go
index 5c674f5..212696d 100644
--- a/metropolis/test/nanoswitch/nanoswitch.go
+++ b/metropolis/test/nanoswitch/nanoswitch.go
@@ -122,7 +122,7 @@
// userspaceProxy listens on port and proxies all TCP connections to the same
// port on targetIP
-func userspaceProxy(targetIP net.IP, port uint16) supervisor.Runnable {
+func userspaceProxy(targetIP net.IP, port common.Port) supervisor.Runnable {
return func(ctx context.Context) error {
logger := supervisor.Logger(ctx)
tcpListener, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv4(0, 0, 0, 0), Port: int(port)})