diff --git a/sdk/helper/consts/replication.go b/sdk/helper/consts/replication.go index 55cfc4ae34b6d5010caac2e239ce3e75b0840aa8..546f533ee393fc2dda0d9f74f0d731e1771f2401 100644 --- a/sdk/helper/consts/replication.go +++ b/sdk/helper/consts/replication.go @@ -18,6 +18,7 @@ const ( // manager. It should contain a character that is not allowed in secondary // ids to ensure it doesn't collide. CurrentReplicatedSecondaryIdentifier = ".current" + CoreFeatureFlagPath = "core/cluster/feature-flags" ) type ReplicationState uint32 diff --git a/vault/core.go b/vault/core.go index 263ef00305f76e739214cf794c399316c651ffce..b7180bae204ed258210b06ec8922b3c8d9df202a 100644 --- a/vault/core.go +++ b/vault/core.go @@ -1825,6 +1825,14 @@ func (s standardUnsealStrategy) unseal(ctx context.Context, logger log.Logger, c if err := enterprisePostUnseal(c); err != nil { return err } + if !c.ReplicationState().HasState(consts.ReplicationPerformanceSecondary | consts.ReplicationDRPrimary | consts.ReplicationDRSecondary) { + // Only perf primarys should write feature flags, but we do it by + // excluding other states so that we don't have to change it when + // a non-replicated cluster becomes a primary. + if err := c.persistFeatureFlags(ctx); err != nil { + return err + } + } if !c.IsDRSecondary() { if err := c.ensureWrappingKey(ctx); err != nil { @@ -2330,3 +2338,34 @@ type BuiltinRegistry interface { func (c *Core) AuditLogger() AuditLogger { return &basicAuditor{c: c} } + +type FeatureFlags struct { + NamespacesCubbyholesLocal bool `json:"namespace_cubbyholes_local"` +} + +func (c *Core) persistFeatureFlags(ctx context.Context) error { + c.logger.Debug("persisting feature flags") + json, err := jsonutil.EncodeJSON(&FeatureFlags{NamespacesCubbyholesLocal: !c.PR1103disabled}) + if err != nil { + return err + } + return c.barrier.Put(ctx, &logical.StorageEntry{ + Key: consts.CoreFeatureFlagPath, + Value: json, + }) +} + +func (c *Core) readFeatureFlags(ctx context.Context) (*FeatureFlags, error) { + entry, err := c.barrier.Get(ctx, consts.CoreFeatureFlagPath) + if err != nil { + return nil, err + } + var flags FeatureFlags + if entry != nil { + err = jsonutil.DecodeJSON(entry.Value, &flags) + if err != nil { + return nil, err + } + } + return &flags, nil +} diff --git a/vendor/github.com/hashicorp/vault/sdk/framework/path.go b/vendor/github.com/hashicorp/vault/sdk/framework/path.go index 8f5dd5bee107d858c94e8076159df925d6fe4b06..87ba5d43e041c386f37fa4b9b40398def85197c3 100644 --- a/vendor/github.com/hashicorp/vault/sdk/framework/path.go +++ b/vendor/github.com/hashicorp/vault/sdk/framework/path.go @@ -190,8 +190,8 @@ type DisplayAttributes struct { // Action is the verb to use for the operation. Action string `json:"action,omitempty"` - // EditType is the type of form field needed for a property - // e.g. "textarea" or "file" + // EditType is the optional type of form field needed for a property + // This is only necessary for a "textarea" or "file" EditType string `json:"editType,omitempty"` } diff --git a/vendor/github.com/hashicorp/vault/sdk/helper/consts/replication.go b/vendor/github.com/hashicorp/vault/sdk/helper/consts/replication.go index 55cfc4ae34b6d5010caac2e239ce3e75b0840aa8..546f533ee393fc2dda0d9f74f0d731e1771f2401 100644 --- a/vendor/github.com/hashicorp/vault/sdk/helper/consts/replication.go +++ b/vendor/github.com/hashicorp/vault/sdk/helper/consts/replication.go @@ -18,6 +18,7 @@ const ( // manager. It should contain a character that is not allowed in secondary // ids to ensure it doesn't collide. CurrentReplicatedSecondaryIdentifier = ".current" + CoreFeatureFlagPath = "core/cluster/feature-flags" ) type ReplicationState uint32