mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-30 18:17:55 +00:00 
			
		
		
		
	Store Cluster Name in Physical Storage (#26878)
* Store Cluster Name in Physical Storage * Add changelog
This commit is contained in:
		 Luis (LT) Carbonell
					Luis (LT) Carbonell
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							1fa8b1f4cf
						
					
				
				
					commit
					33d93652d5
				
			
							
								
								
									
										3
									
								
								changelog/26878.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/26878.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| ```release-note:bug | ||||
| core/metrics: store cluster name in unencrypted storage to prevent blank cluster name | ||||
| ``` | ||||
| @@ -1182,20 +1182,6 @@ func (c *ServerCommand) Run(args []string) int { | ||||
| 				"in a Docker container, provide the IPC_LOCK cap to the container.")) | ||||
| 	} | ||||
|  | ||||
| 	inmemMetrics, metricSink, prometheusEnabled, err := configutil.SetupTelemetry(&configutil.SetupTelemetryOpts{ | ||||
| 		Config:      config.Telemetry, | ||||
| 		Ui:          c.UI, | ||||
| 		ServiceName: "vault", | ||||
| 		DisplayName: "Vault", | ||||
| 		UserAgent:   useragent.String(), | ||||
| 		ClusterName: config.ClusterName, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		c.UI.Error(fmt.Sprintf("Error initializing telemetry: %s", err)) | ||||
| 		return 1 | ||||
| 	} | ||||
| 	metricsHelper := metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled) | ||||
|  | ||||
| 	// Initialize the storage backend | ||||
| 	var backend physical.Backend | ||||
| 	if !c.flagDev || config.Storage != nil { | ||||
| @@ -1211,6 +1197,27 @@ func (c *ServerCommand) Run(args []string) int { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	clusterName := config.ClusterName | ||||
|  | ||||
| 	// Attempt to retrieve cluster name from insecure storage | ||||
| 	if clusterName == "" { | ||||
| 		clusterName, err = c.readClusterNameFromInsecureStorage(backend) | ||||
| 	} | ||||
|  | ||||
| 	inmemMetrics, metricSink, prometheusEnabled, err := configutil.SetupTelemetry(&configutil.SetupTelemetryOpts{ | ||||
| 		Config:      config.Telemetry, | ||||
| 		Ui:          c.UI, | ||||
| 		ServiceName: "vault", | ||||
| 		DisplayName: "Vault", | ||||
| 		UserAgent:   useragent.String(), | ||||
| 		ClusterName: clusterName, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		c.UI.Error(fmt.Sprintf("Error initializing telemetry: %s", err)) | ||||
| 		return 1 | ||||
| 	} | ||||
| 	metricsHelper := metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled) | ||||
|  | ||||
| 	// Initialize the Service Discovery, if there is one | ||||
| 	var configSR sr.ServiceRegistration | ||||
| 	if config.ServiceRegistration != nil { | ||||
| @@ -3530,6 +3537,32 @@ func (c *ServerCommand) reloadSeals(ctx context.Context, grabStateLock bool, cor | ||||
| 	return true, nil | ||||
| } | ||||
|  | ||||
| // Attempt to read the cluster name from the insecure storage. | ||||
| func (c *ServerCommand) readClusterNameFromInsecureStorage(b physical.Backend) (string, error) { | ||||
| 	ctx := context.Background() | ||||
| 	entry, err := b.Get(ctx, "core/cluster/local/name") | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	var result map[string]interface{} | ||||
| 	// Decode JSON data into the map | ||||
|  | ||||
| 	if entry != nil { | ||||
| 		if err := jsonutil.DecodeJSON(entry.Value, &result); err != nil { | ||||
| 			return "", fmt.Errorf("failed to decode JSON data: %w", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Retrieve the value of the "name" field from the map | ||||
| 	name, ok := result["name"].(string) | ||||
| 	if !ok { | ||||
| 		return "", fmt.Errorf("failed to extract name field from decoded JSON") | ||||
| 	} | ||||
|  | ||||
| 	return name, nil | ||||
| } | ||||
|  | ||||
| func SetStorageMigration(b physical.Backend, active bool) error { | ||||
| 	if !active { | ||||
| 		return b.Delete(context.Background(), storageMigrationLock) | ||||
|   | ||||
| @@ -23,12 +23,14 @@ import ( | ||||
| 	uuid "github.com/hashicorp/go-uuid" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | ||||
| 	"github.com/hashicorp/vault/sdk/logical" | ||||
| 	"github.com/hashicorp/vault/sdk/physical" | ||||
| 	"github.com/hashicorp/vault/vault/cluster" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// Storage path where the local cluster name and identifier are stored | ||||
| 	coreLocalClusterInfoPath = "core/cluster/local/info" | ||||
| 	coreLocalClusterNamePath = "core/cluster/local/name" | ||||
|  | ||||
| 	corePrivateKeyTypeP521    = "p521" | ||||
| 	corePrivateKeyTypeED25519 = "ed25519" | ||||
| @@ -61,18 +63,30 @@ type Cluster struct { | ||||
| // when Vault is sealed. | ||||
| func (c *Core) Cluster(ctx context.Context) (*Cluster, error) { | ||||
| 	var cluster Cluster | ||||
| 	var logicalEntry *logical.StorageEntry | ||||
| 	var physicalEntry *physical.Entry | ||||
|  | ||||
| 	// Fetch the storage entry. This call fails when Vault is sealed. | ||||
| 	entry, err := c.barrier.Get(ctx, coreLocalClusterInfoPath) | ||||
| 	logicalEntry, err := c.barrier.Get(ctx, coreLocalClusterInfoPath) | ||||
| 	if err != nil { | ||||
| 		// Vault is sealed, pull cluster name from unencrypted storage | ||||
| 		physicalEntry, err = c.physical.Get(ctx, coreLocalClusterNamePath) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	if entry == nil { | ||||
| 	} | ||||
| 	if logicalEntry == nil && physicalEntry == nil { | ||||
| 		return &cluster, nil | ||||
| 	} | ||||
|  | ||||
| 	// Decode the cluster information | ||||
| 	if err = jsonutil.DecodeJSON(entry.Value, &cluster); err != nil { | ||||
| 	var value []byte | ||||
| 	if logicalEntry != nil { | ||||
| 		value = logicalEntry.Value | ||||
| 	} else { | ||||
| 		value = physicalEntry.Value | ||||
| 	} | ||||
| 	if err = jsonutil.DecodeJSON(value, &cluster); err != nil { | ||||
| 		return nil, fmt.Errorf("failed to decode cluster details: %w", err) | ||||
| 	} | ||||
|  | ||||
| @@ -162,6 +176,7 @@ func (c *Core) setupCluster(ctx context.Context) error { | ||||
| 	} | ||||
|  | ||||
| 	var modified bool | ||||
| 	var generatedClusterName bool | ||||
|  | ||||
| 	if cluster == nil { | ||||
| 		cluster = &Cluster{} | ||||
| @@ -178,6 +193,7 @@ func (c *Core) setupCluster(ctx context.Context) error { | ||||
| 			} | ||||
|  | ||||
| 			c.clusterName = fmt.Sprintf("vault-cluster-%08x", clusterNameBytes) | ||||
| 			generatedClusterName = true | ||||
| 		} | ||||
|  | ||||
| 		cluster.Name = c.clusterName | ||||
| @@ -270,7 +286,7 @@ func (c *Core) setupCluster(ctx context.Context) error { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		// Store it | ||||
| 		// Store cluster information in logical storage | ||||
| 		err = c.barrier.Put(ctx, &logical.StorageEntry{ | ||||
| 			Key:   coreLocalClusterInfoPath, | ||||
| 			Value: rawCluster, | ||||
| @@ -279,6 +295,32 @@ func (c *Core) setupCluster(ctx context.Context) error { | ||||
| 			c.logger.Error("failed to store cluster details", "error", err) | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		// Store only cluster name in physical storage, but only if name isn't provided in config | ||||
| 		if generatedClusterName { | ||||
| 			rawCluster, err = json.Marshal(&Cluster{Name: cluster.Name}) | ||||
| 			if err != nil { | ||||
| 				c.logger.Error("failed to marshal cluster name", "error", err) | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			err = c.physical.Put(ctx, &physical.Entry{ | ||||
| 				Key:   coreLocalClusterNamePath, | ||||
| 				Value: rawCluster, | ||||
| 			}) | ||||
| 			if err != nil { | ||||
| 				c.logger.Error("failed to store cluster name", "error", err) | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			// check to ensure there is no entry at coreLocalClusterNamePath | ||||
| 			err = c.physical.Delete(ctx, coreLocalClusterNamePath) | ||||
| 			if err != nil { | ||||
| 				c.logger.Error("failed to clear cluster name", "error", err) | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	c.clusterID.Store(cluster.ID) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user