Skip to content

Commit

Permalink
Merge branch 'main' into thyton/VAULT-33084/add-system-view-stubs
Browse files Browse the repository at this point in the history
  • Loading branch information
thyton authored Jan 10, 2025
2 parents e460f9c + 896532e commit 1e9c68b
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 14 deletions.
71 changes: 58 additions & 13 deletions helper/activationflags/activation_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,39 +61,84 @@ func (f *FeatureActivationFlags) Initialize(ctx context.Context, storage logical
// actual values from storage, then updates the in-memory cache of the activation-flags. It
// returns a slice of the feature names which have already been activated.
func (f *FeatureActivationFlags) Get(ctx context.Context) ([]string, error) {
// Don't use nil slice declaration, we want the JSON to show "[]" instead of null
activated := []string{}

_, err := f.ReloadFlagsFromStorage(ctx)
if err != nil {
return activated, err
}

f.activationFlagsLock.Lock()
defer f.activationFlagsLock.Unlock()

// Don't use nil slice declaration, we want the JSON to show "[]" instead of null
activated := []string{}
for flag, set := range f.activationFlags {
if set {
activated = append(activated, flag)
}
}

return activated, nil
}

func (f *FeatureActivationFlags) ReloadFlagsFromStorage(ctx context.Context) (map[string]bool, error) {
f.activationFlagsLock.Lock()
defer f.activationFlagsLock.Unlock()

if f.storage == nil {
return activated, nil
return map[string]bool{}, nil
}

entry, err := f.storage.Get(ctx, storagePathActivationFlags)
if err != nil {
return nil, fmt.Errorf("failed to get activation flags from storage: %w", err)
}
if entry == nil {
return activated, nil
return map[string]bool{}, nil
}

var activationFlags map[string]bool
if err := entry.DecodeJSON(&activationFlags); err != nil {
var storageActivationFlags map[string]bool
if err := entry.DecodeJSON(&storageActivationFlags); err != nil {
return nil, fmt.Errorf("failed to decode activation flags from storage: %w", err)
}

// Update the in-memory flags after loading the latest values from storage
f.activationFlags = activationFlags

for flag, set := range activationFlags {
if set {
activated = append(activated, flag)
// State Change Logic for Flags
//
// This logic determines changes to flags, but it does NOT account for flags that have been deleted.
// As of this writing, flag removal is not supported for activation flags.
//
// Valid State Transitions:
// 1. Unset (new flag) -> Active
// 2. Active -> Inactive
// 3. Inactive -> Active
//
// Behavior notes:
// - If a flag does not exist in-memory (`!ok`), it is treated as a new flag.
// Nodes should only react to the new flag if its state is being set to "Active".
// - If a flag exists in-memory, any change in its value (e.g., Active -> Inactive) is considered valid
// and is marked as a state change.
//
// The resulting `changedFlags` map will store the flags with their new values if they meet the above criteria.
changedFlags := map[string]bool{}
for flg, v := range storageActivationFlags {
oldValue, ok := f.activationFlags[flg]

switch {
// New flag: handle only if transitioning to "Active (true)"
case !ok && v:
changedFlags[flg] = v
default:
// Existing flag: detect state change
if oldValue != v {
changedFlags[flg] = v
}
}
}

return activated, nil
// Update the in-memory flags after loading the latest values from storage
f.activationFlags = storageActivationFlags

return changedFlags, nil
}

// Write is the helper function called by the activation-flags API write endpoint. This stores
Expand Down
2 changes: 1 addition & 1 deletion website/content/docs/platform/k8s/injector/annotations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ them, optional commands to run, etc.

- `vault.hashicorp.com/agent-image` - name of the Vault docker image to use. This
value overrides the default image configured in the injector and is usually
not needed. Defaults to `hashicorp/vault:1.18.1`.
not needed. Defaults to `hashicorp/vault:1.18.2`.

- `vault.hashicorp.com/agent-init-first` - configures the pod to run the Vault Agent
init container first if `true` (last if `false`). This is useful when other init
Expand Down
27 changes: 27 additions & 0 deletions website/content/docs/platform/k8s/injector/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,33 @@ The configuration map must contain either one or both of the following files:

An example of mounting a Vault Agent configmap [can be found here](/vault/docs/platform/k8s/injector/examples#configmap-example).

### Injector telemetry

<Tip>

Set [`injector.metrics.enabled`](/vault/docs/platform/k8s/helm/configuration#metrics)
to `true` in the Helm chart to start collecting injector metrics.

</Tip>

Vault Agent injector collects the following Prometheus metrics in addition to
the default set of `golang` metrics:

- `vault_agent_injector_request_queue_length` - The number of pending webhook requests for the injector.

- `vault_agent_injector_request_processing_duration_ms` - A histogram of webhook
request processing times in milliseconds.

- `vault_agent_injector_injections_by_namespace_total` - The total count of
Agent container injections, grouped by Kubernetes `namespace` and `injection_type`.
Vault Agent injector counts the following injection types:
- `init_only`
- `sidecar_only`
- `init_and_sidecar`

- `vault_agent_injector_failed_injections_by_namespace_total` - The total count
of failed Agent sidecar injections, grouped by Kubernetes `namespace`.

## Tutorial

Refer to the [Injecting Secrets into Kubernetes Pods via Vault Helm
Expand Down

0 comments on commit 1e9c68b

Please sign in to comment.