m/node: allow specifying node labels during cluster bootstrap
We also drive-by refactor ProvideBootstrapData to take a structure
instead of a bunch of unnamed arguments.
Change-Id: I8d876fd726fa87420789513540b20f523994d801
Reviewed-on: https://review.monogon.dev/c/monogon/+/3103
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/node/core/cluster/BUILD.bazel b/metropolis/node/core/cluster/BUILD.bazel
index e002a31..4da6c76 100644
--- a/metropolis/node/core/cluster/BUILD.bazel
+++ b/metropolis/node/core/cluster/BUILD.bazel
@@ -11,6 +11,7 @@
importpath = "source.monogon.dev/metropolis/node/core/cluster",
visibility = ["//metropolis/node/core:__subpackages__"],
deps = [
+ "//metropolis/node",
"//metropolis/node/core/curator",
"//metropolis/node/core/curator/proto/api",
"//metropolis/node/core/identity",
diff --git a/metropolis/node/core/cluster/cluster_bootstrap.go b/metropolis/node/core/cluster/cluster_bootstrap.go
index f328815..3e5f745 100644
--- a/metropolis/node/core/cluster/cluster_bootstrap.go
+++ b/metropolis/node/core/cluster/cluster_bootstrap.go
@@ -26,8 +26,10 @@
"google.golang.org/protobuf/proto"
+ common "source.monogon.dev/metropolis/node"
"source.monogon.dev/metropolis/node/core/curator"
"source.monogon.dev/metropolis/node/core/identity"
+ "source.monogon.dev/metropolis/node/core/roleserve"
"source.monogon.dev/metropolis/pkg/supervisor"
apb "source.monogon.dev/metropolis/proto/api"
@@ -132,7 +134,38 @@
}
supervisor.Logger(ctx).Infof("Saved bootstrapped node's credentials.")
- m.roleServer.ProvideBootstrapData(priv, ownerKey, cuk, nuk, jpriv, cc, tpmUsage)
+ labels := make(map[string]string)
+ if l := bootstrap.Labels; l != nil {
+ if nlabels := len(l.Pairs); nlabels > common.MaxLabelsPerNode {
+ supervisor.Logger(ctx).Warningf("Too many labels (%d, limit %d), truncating...", nlabels, common.MaxLabelsPerNode)
+ l.Pairs = l.Pairs[:common.MaxLabelsPerNode]
+ }
+ for _, pair := range l.Pairs {
+ if err := common.ValidateLabel(pair.Key); err != nil {
+ supervisor.Logger(ctx).Warningf("Skipping label %q/%q: key invalid: %v", pair.Key, pair.Value, err)
+ continue
+ }
+ if err := common.ValidateLabel(pair.Value); err != nil {
+ supervisor.Logger(ctx).Warningf("Skipping label %q/%q: value invalid: %v", pair.Key, pair.Value, err)
+ continue
+ }
+ if _, ok := labels[pair.Key]; ok {
+ supervisor.Logger(ctx).Warningf("Label %q/%q: repeated key, overwriting previous value", pair.Key, pair.Value)
+ }
+ labels[pair.Key] = pair.Value
+ }
+ }
+
+ bd := roleserve.BootstrapData{}
+ bd.Node.PrivateKey = priv
+ bd.Node.ClusterUnlockKey = cuk
+ bd.Node.NodeUnlockKey = nuk
+ bd.Node.JoinKey = jpriv
+ bd.Node.TPMUsage = tpmUsage
+ bd.Node.Labels = labels
+ bd.Cluster.InitialOwnerKey = ownerKey
+ bd.Cluster.Configuration = cc
+ m.roleServer.ProvideBootstrapData(&bd)
supervisor.Signal(ctx, supervisor.SignalHealthy)
supervisor.Signal(ctx, supervisor.SignalDone)