metropolis: finish implementing TPMMode

This wraps up the implementation of TPMMode in ClusterConfiguration,
allowing operators to select whether nodes should or should not use
their TPM, based on local availability.

We keep the default behaviour to require a TPM, as we'd like to be
secure by default.

Change-Id: Ic8ac76d88ecc9de51f58ca99c92daede79d78ad7
Reviewed-on: https://review.monogon.dev/c/monogon/+/1495
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/node/core/cluster/cluster.go b/metropolis/node/core/cluster/cluster.go
index 8a1a3ae..529120b 100644
--- a/metropolis/node/core/cluster/cluster.go
+++ b/metropolis/node/core/cluster/cluster.go
@@ -73,6 +73,7 @@
 	}
 	close(m.oneway)
 
+	// Try sealed configuration first.
 	configuration, err := m.storageRoot.ESP.Metropolis.SealedConfiguration.Unseal()
 	if err == nil {
 		supervisor.Logger(ctx).Info("Sealed configuration present. attempting to join cluster")
@@ -84,13 +85,27 @@
 		if err != nil {
 			return fmt.Errorf("while reading cluster directory: %w", err)
 		}
-		return m.join(ctx, configuration, cd)
+		return m.join(ctx, configuration, cd, true)
 	}
 
 	if !errors.Is(err, localstorage.ErrNoSealed) {
 		return fmt.Errorf("unexpected sealed config error: %w", err)
 	}
 
+	configuration, err = m.storageRoot.ESP.Metropolis.SealedConfiguration.ReadUnsafe()
+	if err == nil {
+		supervisor.Logger(ctx).Info("Non-sealed configuration present. attempting to join cluster")
+
+		// Read Cluster Directory and unmarshal it. Since the node is already
+		// registered with the cluster, the directory won't be bootstrapped from
+		// Node Parameters.
+		cd, err := m.storageRoot.ESP.Metropolis.ClusterDirectory.Unmarshal()
+		if err != nil {
+			return fmt.Errorf("while reading cluster directory: %w", err)
+		}
+		return m.join(ctx, configuration, cd, false)
+	}
+
 	supervisor.Logger(ctx).Info("No sealed configuration, looking for node parameters")
 
 	switch inner := m.nodeParams.Cluster.(type) {