Skip to content

Commit 33d9365

Browse files
authored
Store Cluster Name in Physical Storage (#26878)
* Store Cluster Name in Physical Storage * Add changelog
1 parent 1fa8b1f commit 33d9365

File tree

3 files changed

+97
-19
lines changed

3 files changed

+97
-19
lines changed

changelog/26878.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
core/metrics: store cluster name in unencrypted storage to prevent blank cluster name
3+
```

command/server.go

+47-14
Original file line numberDiff line numberDiff line change
@@ -1182,20 +1182,6 @@ func (c *ServerCommand) Run(args []string) int {
11821182
"in a Docker container, provide the IPC_LOCK cap to the container."))
11831183
}
11841184

1185-
inmemMetrics, metricSink, prometheusEnabled, err := configutil.SetupTelemetry(&configutil.SetupTelemetryOpts{
1186-
Config: config.Telemetry,
1187-
Ui: c.UI,
1188-
ServiceName: "vault",
1189-
DisplayName: "Vault",
1190-
UserAgent: useragent.String(),
1191-
ClusterName: config.ClusterName,
1192-
})
1193-
if err != nil {
1194-
c.UI.Error(fmt.Sprintf("Error initializing telemetry: %s", err))
1195-
return 1
1196-
}
1197-
metricsHelper := metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled)
1198-
11991185
// Initialize the storage backend
12001186
var backend physical.Backend
12011187
if !c.flagDev || config.Storage != nil {
@@ -1211,6 +1197,27 @@ func (c *ServerCommand) Run(args []string) int {
12111197
}
12121198
}
12131199

1200+
clusterName := config.ClusterName
1201+
1202+
// Attempt to retrieve cluster name from insecure storage
1203+
if clusterName == "" {
1204+
clusterName, err = c.readClusterNameFromInsecureStorage(backend)
1205+
}
1206+
1207+
inmemMetrics, metricSink, prometheusEnabled, err := configutil.SetupTelemetry(&configutil.SetupTelemetryOpts{
1208+
Config: config.Telemetry,
1209+
Ui: c.UI,
1210+
ServiceName: "vault",
1211+
DisplayName: "Vault",
1212+
UserAgent: useragent.String(),
1213+
ClusterName: clusterName,
1214+
})
1215+
if err != nil {
1216+
c.UI.Error(fmt.Sprintf("Error initializing telemetry: %s", err))
1217+
return 1
1218+
}
1219+
metricsHelper := metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled)
1220+
12141221
// Initialize the Service Discovery, if there is one
12151222
var configSR sr.ServiceRegistration
12161223
if config.ServiceRegistration != nil {
@@ -3530,6 +3537,32 @@ func (c *ServerCommand) reloadSeals(ctx context.Context, grabStateLock bool, cor
35303537
return true, nil
35313538
}
35323539

3540+
// Attempt to read the cluster name from the insecure storage.
3541+
func (c *ServerCommand) readClusterNameFromInsecureStorage(b physical.Backend) (string, error) {
3542+
ctx := context.Background()
3543+
entry, err := b.Get(ctx, "core/cluster/local/name")
3544+
if err != nil {
3545+
return "", err
3546+
}
3547+
3548+
var result map[string]interface{}
3549+
// Decode JSON data into the map
3550+
3551+
if entry != nil {
3552+
if err := jsonutil.DecodeJSON(entry.Value, &result); err != nil {
3553+
return "", fmt.Errorf("failed to decode JSON data: %w", err)
3554+
}
3555+
}
3556+
3557+
// Retrieve the value of the "name" field from the map
3558+
name, ok := result["name"].(string)
3559+
if !ok {
3560+
return "", fmt.Errorf("failed to extract name field from decoded JSON")
3561+
}
3562+
3563+
return name, nil
3564+
}
3565+
35333566
func SetStorageMigration(b physical.Backend, active bool) error {
35343567
if !active {
35353568
return b.Delete(context.Background(), storageMigrationLock)

vault/cluster.go

+47-5
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ import (
2323
uuid "github.com/hashicorp/go-uuid"
2424
"github.com/hashicorp/vault/sdk/helper/jsonutil"
2525
"github.com/hashicorp/vault/sdk/logical"
26+
"github.com/hashicorp/vault/sdk/physical"
2627
"github.com/hashicorp/vault/vault/cluster"
2728
)
2829

2930
const (
3031
// Storage path where the local cluster name and identifier are stored
3132
coreLocalClusterInfoPath = "core/cluster/local/info"
33+
coreLocalClusterNamePath = "core/cluster/local/name"
3234

3335
corePrivateKeyTypeP521 = "p521"
3436
corePrivateKeyTypeED25519 = "ed25519"
@@ -61,18 +63,30 @@ type Cluster struct {
6163
// when Vault is sealed.
6264
func (c *Core) Cluster(ctx context.Context) (*Cluster, error) {
6365
var cluster Cluster
66+
var logicalEntry *logical.StorageEntry
67+
var physicalEntry *physical.Entry
6468

6569
// Fetch the storage entry. This call fails when Vault is sealed.
66-
entry, err := c.barrier.Get(ctx, coreLocalClusterInfoPath)
70+
logicalEntry, err := c.barrier.Get(ctx, coreLocalClusterInfoPath)
6771
if err != nil {
68-
return nil, err
72+
// Vault is sealed, pull cluster name from unencrypted storage
73+
physicalEntry, err = c.physical.Get(ctx, coreLocalClusterNamePath)
74+
if err != nil {
75+
return nil, err
76+
}
6977
}
70-
if entry == nil {
78+
if logicalEntry == nil && physicalEntry == nil {
7179
return &cluster, nil
7280
}
7381

7482
// Decode the cluster information
75-
if err = jsonutil.DecodeJSON(entry.Value, &cluster); err != nil {
83+
var value []byte
84+
if logicalEntry != nil {
85+
value = logicalEntry.Value
86+
} else {
87+
value = physicalEntry.Value
88+
}
89+
if err = jsonutil.DecodeJSON(value, &cluster); err != nil {
7690
return nil, fmt.Errorf("failed to decode cluster details: %w", err)
7791
}
7892

@@ -162,6 +176,7 @@ func (c *Core) setupCluster(ctx context.Context) error {
162176
}
163177

164178
var modified bool
179+
var generatedClusterName bool
165180

166181
if cluster == nil {
167182
cluster = &Cluster{}
@@ -178,6 +193,7 @@ func (c *Core) setupCluster(ctx context.Context) error {
178193
}
179194

180195
c.clusterName = fmt.Sprintf("vault-cluster-%08x", clusterNameBytes)
196+
generatedClusterName = true
181197
}
182198

183199
cluster.Name = c.clusterName
@@ -270,7 +286,7 @@ func (c *Core) setupCluster(ctx context.Context) error {
270286
return err
271287
}
272288

273-
// Store it
289+
// Store cluster information in logical storage
274290
err = c.barrier.Put(ctx, &logical.StorageEntry{
275291
Key: coreLocalClusterInfoPath,
276292
Value: rawCluster,
@@ -279,6 +295,32 @@ func (c *Core) setupCluster(ctx context.Context) error {
279295
c.logger.Error("failed to store cluster details", "error", err)
280296
return err
281297
}
298+
299+
// Store only cluster name in physical storage, but only if name isn't provided in config
300+
if generatedClusterName {
301+
rawCluster, err = json.Marshal(&Cluster{Name: cluster.Name})
302+
if err != nil {
303+
c.logger.Error("failed to marshal cluster name", "error", err)
304+
return err
305+
}
306+
307+
err = c.physical.Put(ctx, &physical.Entry{
308+
Key: coreLocalClusterNamePath,
309+
Value: rawCluster,
310+
})
311+
if err != nil {
312+
c.logger.Error("failed to store cluster name", "error", err)
313+
return err
314+
}
315+
} else {
316+
// check to ensure there is no entry at coreLocalClusterNamePath
317+
err = c.physical.Delete(ctx, coreLocalClusterNamePath)
318+
if err != nil {
319+
c.logger.Error("failed to clear cluster name", "error", err)
320+
return err
321+
}
322+
323+
}
282324
}
283325

284326
c.clusterID.Store(cluster.ID)

0 commit comments

Comments
 (0)