metropolis/node/kubernetes: update labels based on node roles

This implements the labelmaker, a reconciling loop running on Kubernetes
controller nodes which updates Kubernetes node labels based on cluster
data.

Currently it only updates role labels based on cluster roles, but this
can be extended in the future to also replicate Metropolis node labels
into Kubernetes node labels.

Change-Id: I9c5ba92bb46f064aa03836720d4a80adc6061ab9
Reviewed-on: https://review.monogon.dev/c/monogon/+/3464
Tested-by: Jenkins CI
Reviewed-by: Jan Schär <jan@monogon.tech>
diff --git a/metropolis/node/kubernetes/service_controller.go b/metropolis/node/kubernetes/service_controller.go
index 7aa91e8..71b133c 100644
--- a/metropolis/node/kubernetes/service_controller.go
+++ b/metropolis/node/kubernetes/service_controller.go
@@ -34,8 +34,10 @@
 	"source.monogon.dev/metropolis/node/kubernetes/metricsproxy"
 	"source.monogon.dev/metropolis/node/kubernetes/pki"
 	"source.monogon.dev/metropolis/node/kubernetes/reconciler"
-	apb "source.monogon.dev/metropolis/proto/api"
 	"source.monogon.dev/osbase/supervisor"
+
+	ipb "source.monogon.dev/metropolis/node/core/curator/proto/api"
+	apb "source.monogon.dev/metropolis/proto/api"
 )
 
 type ConfigController struct {
@@ -47,6 +49,7 @@
 	Consensus consensus.ServiceHandle
 	Network   *network.Service
 	Node      *identity.NodeCredentials
+	Curator   ipb.CuratorClient
 }
 
 type Controller struct {
@@ -157,6 +160,14 @@
 		return fmt.Errorf("could not run sub-service reconciler: %w", err)
 	}
 
+	lm := labelmaker{
+		clientSet: clientSet,
+		curator:   s.c.Curator,
+	}
+	if err := supervisor.Run(ctx, "labelmaker", lm.run); err != nil {
+		return err
+	}
+
 	// Before we start anything else, make sure reconciliation passes at least once.
 	// This makes the initial startup of a cluster much cleaner as we don't end up
 	// starting the scheduler/controller-manager/etc just to get them to immediately