salt.schedule.highstate_interval_hours could not express a sub-hour
cadence, so an operator who disables salt.auto_apply had no way back to
the legacy 15-minute highstate. Rename the setting to
highstate_interval_minutes (default 120, behavior unchanged) and enforce
a 15-minute floor in SOC.
Non-manager splay is now a quarter of the interval clamped to [5, 30]
minutes, so a short interval no longer gets jitter larger than itself; at
the 120-minute default it stays 1800s. The so-salt-minion-check restart
threshold keeps its interval-plus-one-hour grace, now in minute math.
Previously salt/vars/elasticsearch.map.jinja read the elasticsearch heap
size via a raw pillar access (INIT.PILLAR.elasticsearch.esheap). If the
esheap key was missing from a minion pillar, building GLOBALS raised
'dict object has no attribute esheap', cascading into every state that
imports GLOBALS (elasticsearch.enabled, logstash.config, telegraf.config,
etc.) and blocking highstate entirely.
Add an esheap default ('600m', matching the es_heapsize() floor) to
elasticsearch/defaults.yaml and fall back to it via dict .get() so a
missing pillar value degrades gracefully. The per-node pillar value still
wins when present.
The agent name is also the agentMapping config key and a SOC setting id
segment, so the space made it awkward to target. Matches the rename in
securityonion-soc.
agentMapping values are model displayNames (the canonical selector); the
stock config used the model id, which only resolved via the legacy
id@adapter fallback. Use the Claude Sonnet displayName so agent-to-model
resolution matches the documented contract.
init-db.sh only runs on a fresh PGDATA (docker-entrypoint-initdb.d), so a
cluster left partially initialized -- e.g. the container restarted mid first-init
by a watch trigger -- never recovered: the so_postgres role existed but its
schema grants and the so_telegraf database were missing, breaking SOC with
"permission denied for schema public".
- init-db.sh: make the role upsert race-safe. Try CREATE ROLE and fall back to
ALTER on duplicate_object/unique_violation instead of IF NOT EXISTS, so a
concurrent creator no longer aborts the script (set -e + ON_ERROR_STOP=1)
before the grants and so_telegraf creation run. The whole script is now
idempotent and safe to re-run.
- postgres/enabled.sls: move postgres_wait_ready here (was telegraf-gated in
telegraf_users.sls) and add postgres_bootstrap_soc_db, which re-runs init-db.sh
every highstate so a partially-initialized cluster self-heals.
- telegraf_users.sls: drop its now-duplicate postgres_wait_ready definition; it
resolves from postgres.enabled via the existing include.
- soup: remove bootstrap_so_soc_database and its post_to_3.2.0 call. The
highstates soup runs before postupgrade now reconcile the SOC DB, making the
one-shot bootstrap redundant.