mirror of
https://github.com/Security-Onion-Solutions/securityonion.git
synced 2026-06-12 21:29:16 +02:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 80c39d612c | |||
| f03f0155f4 | |||
| 4741cc92bd | |||
| 46655860e9 | |||
| 289ddda5e8 | |||
| f905afbc6f | |||
| bd5e77afc5 | |||
| 944e773759 |
@@ -130,6 +130,17 @@ common_sbin:
|
|||||||
- so-pcap-import
|
- so-pcap-import
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
# Pin physical NIC names by MAC (run-once) so a kernel upgrade can't renumber the
|
||||||
|
# interfaces SO binds by name. The marker keeps it a one-time setup; an admin can
|
||||||
|
# pre-create the marker to opt out.
|
||||||
|
pin_nic_names:
|
||||||
|
cmd.run:
|
||||||
|
- name: /usr/sbin/so-nic-pin
|
||||||
|
- unless: 'test -e /opt/so/state/nic_names_pinned'
|
||||||
|
- require:
|
||||||
|
- file: common_sbin
|
||||||
|
- file: statedir
|
||||||
|
|
||||||
common_sbin_jinja:
|
common_sbin_jinja:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# so-nic-pin — pin physical NIC names by permanent MAC via classic by-MAC udev
|
||||||
|
# rules, so a kernel upgrade can't renumber them.
|
||||||
|
#
|
||||||
|
# Security Onion binds its management and monitor interfaces BY NAME in pillar
|
||||||
|
# (host:mainint, sensor:mainint, and bond0 is built on a specific physical NIC).
|
||||||
|
# A kernel upgrade can change the kernel/systemd-udevd predictable-naming output
|
||||||
|
# and renumber those NICs (e.g. enp1s0 -> enp2s0), which breaks the grid: the
|
||||||
|
# pillar references a name that no longer exists and bond/bridge bring-up fails.
|
||||||
|
#
|
||||||
|
# This writes /etc/udev/rules.d/70-persistent-net.rules pinning each PHYSICAL NIC
|
||||||
|
# to its CURRENT name by its PERMANENT MAC, freezing the names across future kernel
|
||||||
|
# changes. It only writes the rules file; it does NOT live-trigger a rename (the
|
||||||
|
# rules apply on the next boot/kernel, and a live rename would be disruptive).
|
||||||
|
#
|
||||||
|
# Run-once: gated by the drop file /opt/so/state/nic_names_pinned. If the marker is
|
||||||
|
# present the script does nothing, so an admin can pre-create it to opt out. Invoked
|
||||||
|
# from the common state on every highstate; the marker keeps it a one-time setup.
|
||||||
|
|
||||||
|
NET_RULES_FILE="/etc/udev/rules.d/70-persistent-net.rules"
|
||||||
|
MARKER="/opt/so/state/nic_names_pinned"
|
||||||
|
|
||||||
|
log() { echo -e "[so-nic-pin] $*"; }
|
||||||
|
|
||||||
|
# Echo "<name> <permanent-mac>" for every PHYSICAL NIC. A physical NIC is backed by a
|
||||||
|
# real device (has device/driver), which excludes bond0/sobridge/docker0/veth*/lo whose
|
||||||
|
# MACs are dynamic and must never be pinned. The PERMANENT MAC is used (ethtool -P, with
|
||||||
|
# fallbacks), not the current one: an enslaved bond member's current MAC is rewritten to
|
||||||
|
# the bond's, so matching on it would be wrong/ambiguous.
|
||||||
|
physical_nics() {
|
||||||
|
local path n mac
|
||||||
|
for path in /sys/class/net/*; do
|
||||||
|
n="${path##*/}"
|
||||||
|
[ "$n" = "lo" ] && continue
|
||||||
|
[ -e "${path}/device/driver" ] || continue # real device only
|
||||||
|
mac="$(ethtool -P "$n" 2>/dev/null | awk '/Permanent address/{print $NF}')"
|
||||||
|
case "$mac" in ""|00:00:00:00:00:00) mac="$(cat "${path}/bonding_slave/perm_hwaddr" 2>/dev/null)" ;; esac
|
||||||
|
case "$mac" in ""|00:00:00:00:00:00) mac="$(cat "${path}/address" 2>/dev/null)" ;; esac
|
||||||
|
case "$mac" in ""|00:00:00:00:00:00) continue ;; esac
|
||||||
|
echo "$n $mac"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Turn "<name> <mac>" lines on stdin into classic by-MAC persistent-net udev rules.
|
||||||
|
render_net_rules() {
|
||||||
|
echo "# Generated by so-nic-pin: pin NIC names by MAC so kernel upgrades can't renumber them."
|
||||||
|
echo "# Security Onion binds its management/monitor interfaces by name; do not hand-edit."
|
||||||
|
local n mac
|
||||||
|
while read -r n mac; do
|
||||||
|
[ -n "$n" ] || continue
|
||||||
|
printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", NAME="%s"\n' \
|
||||||
|
"$mac" "$n"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$(id -u)" -eq 0 ] || exit 0 # salt runs us as root; bail quietly otherwise
|
||||||
|
[ -e "${MARKER}" ] && exit 0 # run-once guard (mirrors the state's unless)
|
||||||
|
|
||||||
|
nics="$(physical_nics)"
|
||||||
|
if [ -z "${nics}" ]; then
|
||||||
|
log "no physical NICs detected — nothing to pin (will retry on next highstate)"
|
||||||
|
exit 0 # do NOT drop the marker; let it retry later
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "pinning physical NICs by permanent MAC:"
|
||||||
|
echo "${nics}" | sed 's/^/ /'
|
||||||
|
|
||||||
|
[ -f "${NET_RULES_FILE}" ] && cp -f "${NET_RULES_FILE}" "${NET_RULES_FILE}.bak"
|
||||||
|
echo "${nics}" | render_net_rules > "${NET_RULES_FILE}" || {
|
||||||
|
log "ERROR: failed to write ${NET_RULES_FILE}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "${MARKER}")" && touch "${MARKER}"
|
||||||
|
log "wrote ${NET_RULES_FILE} ($(grep -c '^SUBSYSTEM' "${NET_RULES_FILE}") NIC(s) pinned); dropped ${MARKER}"
|
||||||
@@ -101,6 +101,17 @@ so-elastic-fleet:
|
|||||||
- file: trusttheca
|
- file: trusttheca
|
||||||
- x509: etc_elasticfleet_key
|
- x509: etc_elasticfleet_key
|
||||||
- x509: etc_elasticfleet_crt
|
- x509: etc_elasticfleet_crt
|
||||||
|
|
||||||
|
wait_for_so-elastic-fleet:
|
||||||
|
http.wait_for_successful_query:
|
||||||
|
- name: "https://localhost:8220/api/status"
|
||||||
|
- ssl: True
|
||||||
|
- verify_ssl: False
|
||||||
|
- status: 200
|
||||||
|
- wait_for: 300
|
||||||
|
- request_interval: 15
|
||||||
|
- require:
|
||||||
|
- docker_container: so-elastic-fleet
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
delete_so-elastic-fleet_so-status.disabled:
|
delete_so-elastic-fleet_so-status.disabled:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
include:
|
include:
|
||||||
- elasticfleet.config
|
- elasticfleet.config
|
||||||
|
- kibana.enabled
|
||||||
|
|
||||||
# If enabled, automatically update Fleet Logstash Outputs
|
# If enabled, automatically update Fleet Logstash Outputs
|
||||||
{% if ELASTICFLEETMERGED.config.server.enable_auto_configuration %}
|
{% if ELASTICFLEETMERGED.config.server.enable_auto_configuration %}
|
||||||
@@ -19,6 +20,8 @@ so-elastic-fleet-auto-configure-logstash-outputs:
|
|||||||
- retry:
|
- retry:
|
||||||
attempts: 4
|
attempts: 4
|
||||||
interval: 30
|
interval: 30
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# If enabled, automatically update Fleet Server URLs & ES Connection
|
# If enabled, automatically update Fleet Server URLs & ES Connection
|
||||||
@@ -28,6 +31,8 @@ so-elastic-fleet-auto-configure-server-urls:
|
|||||||
- retry:
|
- retry:
|
||||||
attempts: 4
|
attempts: 4
|
||||||
interval: 30
|
interval: 30
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# Automatically update Fleet Server Elasticsearch URLs & Agent Artifact URLs
|
# Automatically update Fleet Server Elasticsearch URLs & Agent Artifact URLs
|
||||||
@@ -37,6 +42,8 @@ so-elastic-fleet-auto-configure-elasticsearch-urls:
|
|||||||
- retry:
|
- retry:
|
||||||
attempts: 4
|
attempts: 4
|
||||||
interval: 30
|
interval: 30
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
|
|
||||||
so-elastic-fleet-auto-configure-artifact-urls:
|
so-elastic-fleet-auto-configure-artifact-urls:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
@@ -44,6 +51,8 @@ so-elastic-fleet-auto-configure-artifact-urls:
|
|||||||
- retry:
|
- retry:
|
||||||
attempts: 4
|
attempts: 4
|
||||||
interval: 30
|
interval: 30
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
|
|
||||||
so-elastic-fleet-package-statefile:
|
so-elastic-fleet-package-statefile:
|
||||||
file.managed:
|
file.managed:
|
||||||
@@ -55,7 +64,9 @@ so-elastic-fleet-package-upgrade:
|
|||||||
- name: /usr/sbin/so-elastic-fleet-package-upgrade
|
- name: /usr/sbin/so-elastic-fleet-package-upgrade
|
||||||
- retry:
|
- retry:
|
||||||
attempts: 3
|
attempts: 3
|
||||||
interval: 10
|
interval: 30
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
- onchanges:
|
- onchanges:
|
||||||
- file: /opt/so/state/elastic_fleet_packages.txt
|
- file: /opt/so/state/elastic_fleet_packages.txt
|
||||||
|
|
||||||
@@ -65,6 +76,8 @@ so-elastic-fleet-integrations:
|
|||||||
- retry:
|
- retry:
|
||||||
attempts: 3
|
attempts: 3
|
||||||
interval: 10
|
interval: 10
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
|
|
||||||
so-elastic-agent-grid-upgrade:
|
so-elastic-agent-grid-upgrade:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
@@ -72,6 +85,8 @@ so-elastic-agent-grid-upgrade:
|
|||||||
- retry:
|
- retry:
|
||||||
attempts: 12
|
attempts: 12
|
||||||
interval: 5
|
interval: 5
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
|
|
||||||
so-elastic-fleet-integration-upgrade:
|
so-elastic-fleet-integration-upgrade:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
@@ -79,16 +94,22 @@ so-elastic-fleet-integration-upgrade:
|
|||||||
- retry:
|
- retry:
|
||||||
attempts: 3
|
attempts: 3
|
||||||
interval: 10
|
interval: 10
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
|
|
||||||
{# Optional integrations script doesn't need the retries like so-elastic-fleet-integration-upgrade which loads the default integrations #}
|
{# Optional integrations script doesn't need the retries like so-elastic-fleet-integration-upgrade which loads the default integrations #}
|
||||||
so-elastic-fleet-addon-integrations:
|
so-elastic-fleet-addon-integrations:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
- name: /usr/sbin/so-elastic-fleet-optional-integrations-load
|
- name: /usr/sbin/so-elastic-fleet-optional-integrations-load
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
|
|
||||||
{% if ELASTICFLEETMERGED.config.defend_filters.enable_auto_configuration %}
|
{% if ELASTICFLEETMERGED.config.defend_filters.enable_auto_configuration %}
|
||||||
so-elastic-defend-manage-filters-file-watch:
|
so-elastic-defend-manage-filters-file-watch:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
- name: python3 /sbin/so-elastic-defend-manage-filters.py -c /opt/so/conf/elasticsearch/curl.config -d /opt/so/conf/elastic-fleet/defend-exclusions/disabled-filters.yaml -i /nsm/securityonion-resources/event_filters/ -i /opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters/ &>> /opt/so/log/elasticfleet/elastic-defend-manage-filters.log
|
- name: python3 /sbin/so-elastic-defend-manage-filters.py -c /opt/so/conf/elasticsearch/curl.config -d /opt/so/conf/elastic-fleet/defend-exclusions/disabled-filters.yaml -i /nsm/securityonion-resources/event_filters/ -i /opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters/ &>> /opt/so/log/elasticfleet/elastic-defend-manage-filters.log
|
||||||
|
- require:
|
||||||
|
- http: wait_for_so-kibana
|
||||||
- onchanges:
|
- onchanges:
|
||||||
- file: elasticdefendcustom
|
- file: elasticdefendcustom
|
||||||
- file: elasticdefenddisabled
|
- file: elasticdefenddisabled
|
||||||
|
|||||||
@@ -30,70 +30,6 @@ fleet_api() {
|
|||||||
curl -sK /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/${QUERYPATH}" "$@" --retry 3 --retry-delay 10 --fail 2>/dev/null
|
curl -sK /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/${QUERYPATH}" "$@" --retry 3 --retry-delay 10 --fail 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Max number of concurrent Fleet write jobs (create/update). Override via env if needed.
|
|
||||||
MAX_FLEET_JOBS=${MAX_FLEET_JOBS:-10}
|
|
||||||
|
|
||||||
# Block until fewer than MAX_FLEET_JOBS background jobs are running.
|
|
||||||
elastic_fleet_throttle() {
|
|
||||||
while (( $(jobs -rp | wc -l) >= MAX_FLEET_JOBS )); do
|
|
||||||
wait -n
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Load every integration JSON in a directory into a single agent policy.
|
|
||||||
# The agent policy is fetched ONCE (not per file), and the create/update writes
|
|
||||||
# are dispatched as throttled background jobs.
|
|
||||||
# $1 AGENT_POLICY - the agent policy id/name to load integrations into
|
|
||||||
# $2 DIR - directory of integration *.json files
|
|
||||||
# $3 LABEL - human-readable label for log output
|
|
||||||
# $4 SKIP_CREATE_NAME - (optional) integration name to skip when creating (still updated if present)
|
|
||||||
# Returns 1 if any integration failed to create/update.
|
|
||||||
elastic_fleet_load_integrations_dir() {
|
|
||||||
local AGENT_POLICY=$1
|
|
||||||
local DIR=$2
|
|
||||||
local LABEL=$3
|
|
||||||
local SKIP_CREATE_NAME=$4
|
|
||||||
local POLICY_JSON FAIL_FILE INTEGRATION NAME ID
|
|
||||||
|
|
||||||
FAIL_FILE=$(mktemp)
|
|
||||||
|
|
||||||
# Fetch the agent policy a single time; we look up integration ids locally below.
|
|
||||||
POLICY_JSON=$(fleet_api "agent_policies/$AGENT_POLICY")
|
|
||||||
|
|
||||||
for INTEGRATION in "$DIR"/*.json; do
|
|
||||||
[ -e "$INTEGRATION" ] || continue
|
|
||||||
NAME=$(jq -r .name "$INTEGRATION")
|
|
||||||
ID=$(jq -r --arg n "$NAME" '.item.package_policies[]? | select(.name==$n) | .id' <<<"$POLICY_JSON")
|
|
||||||
|
|
||||||
elastic_fleet_throttle
|
|
||||||
{
|
|
||||||
if [ -n "$ID" ]; then
|
|
||||||
printf "\n\n%s - Updating integration %s\n" "$LABEL" "$NAME"
|
|
||||||
if ! elastic_fleet_integration_update "$ID" "@$INTEGRATION"; then
|
|
||||||
flock 9; echo "update ${INTEGRATION##*/}" >&9
|
|
||||||
fi
|
|
||||||
elif [ -n "$SKIP_CREATE_NAME" ] && [ "$NAME" == "$SKIP_CREATE_NAME" ]; then
|
|
||||||
printf "\n\n%s - Skipping creation of %s\n" "$LABEL" "$NAME"
|
|
||||||
else
|
|
||||||
printf "\n\n%s - Creating integration %s\n" "$LABEL" "$NAME"
|
|
||||||
if ! elastic_fleet_integration_create "@$INTEGRATION"; then
|
|
||||||
flock 9; echo "create ${INTEGRATION##*/}" >&9
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
} 9>>"$FAIL_FILE" &
|
|
||||||
done
|
|
||||||
wait
|
|
||||||
|
|
||||||
local rc=0
|
|
||||||
if [ -s "$FAIL_FILE" ]; then
|
|
||||||
printf "\n%s: failed integrations:\n" "$LABEL"
|
|
||||||
cat "$FAIL_FILE"
|
|
||||||
rc=1
|
|
||||||
fi
|
|
||||||
rm -f "$FAIL_FILE"
|
|
||||||
return $rc
|
|
||||||
}
|
|
||||||
|
|
||||||
elastic_fleet_integration_check() {
|
elastic_fleet_integration_check() {
|
||||||
|
|
||||||
AGENT_POLICY=$1
|
AGENT_POLICY=$1
|
||||||
|
|||||||
@@ -18,32 +18,102 @@ if [ ! -f /opt/so/state/eaintegrations.txt ]; then
|
|||||||
# Third, configure Elastic Defend Integration seperately
|
# Third, configure Elastic Defend Integration seperately
|
||||||
/usr/sbin/so-elastic-fleet-integration-policy-elastic-defend
|
/usr/sbin/so-elastic-fleet-integration-policy-elastic-defend
|
||||||
|
|
||||||
# Each group fetches its agent policy once and dispatches create/update writes concurrently.
|
|
||||||
|
|
||||||
# Initial Endpoints
|
# Initial Endpoints
|
||||||
elastic_fleet_load_integrations_dir "endpoints-initial" \
|
for INTEGRATION in /opt/so/conf/elastic-fleet/integrations/endpoints-initial/*.json; do
|
||||||
/opt/so/conf/elastic-fleet/integrations/endpoints-initial "Initial Endpoints Policy" || RETURN_CODE=1
|
printf "\n\nInitial Endpoints Policy - Loading $INTEGRATION\n"
|
||||||
|
elastic_fleet_integration_check "endpoints-initial" "$INTEGRATION"
|
||||||
|
if [ -n "$INTEGRATION_ID" ]; then
|
||||||
|
printf "\n\nIntegration $NAME exists - Updating integration\n"
|
||||||
|
if ! elastic_fleet_integration_update "$INTEGRATION_ID" "@$INTEGRATION"; then
|
||||||
|
echo -e "\nFailed to update integration for ${INTEGRATION##*/}"
|
||||||
|
RETURN_CODE=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "\n\nIntegration does not exist - Creating integration\n"
|
||||||
|
if ! elastic_fleet_integration_create "@$INTEGRATION"; then
|
||||||
|
echo -e "\nFailed to create integration for ${INTEGRATION##*/}"
|
||||||
|
RETURN_CODE=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# Grid Nodes - General
|
# Grid Nodes - General
|
||||||
elastic_fleet_load_integrations_dir "so-grid-nodes_general" \
|
for INTEGRATION in /opt/so/conf/elastic-fleet/integrations/grid-nodes_general/*.json; do
|
||||||
/opt/so/conf/elastic-fleet/integrations/grid-nodes_general "Grid Nodes Policy_General" || RETURN_CODE=1
|
printf "\n\nGrid Nodes Policy_General - Loading $INTEGRATION\n"
|
||||||
|
elastic_fleet_integration_check "so-grid-nodes_general" "$INTEGRATION"
|
||||||
|
if [ -n "$INTEGRATION_ID" ]; then
|
||||||
|
printf "\n\nIntegration $NAME exists - Updating integration\n"
|
||||||
|
if ! elastic_fleet_integration_update "$INTEGRATION_ID" "@$INTEGRATION"; then
|
||||||
|
echo -e "\nFailed to update integration for ${INTEGRATION##*/}"
|
||||||
|
RETURN_CODE=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "\n\nIntegration does not exist - Creating integration\n"
|
||||||
|
if ! elastic_fleet_integration_create "@$INTEGRATION"; then
|
||||||
|
echo -e "\nFailed to create integration for ${INTEGRATION##*/}"
|
||||||
|
RETURN_CODE=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# Grid Nodes - Heavy
|
# Grid Nodes - Heavy
|
||||||
elastic_fleet_load_integrations_dir "so-grid-nodes_heavy" \
|
for INTEGRATION in /opt/so/conf/elastic-fleet/integrations/grid-nodes_heavy/*.json; do
|
||||||
/opt/so/conf/elastic-fleet/integrations/grid-nodes_heavy "Grid Nodes Policy_Heavy" || RETURN_CODE=1
|
printf "\n\nGrid Nodes Policy_Heavy - Loading $INTEGRATION\n"
|
||||||
|
elastic_fleet_integration_check "so-grid-nodes_heavy" "$INTEGRATION"
|
||||||
|
if [ -n "$INTEGRATION_ID" ]; then
|
||||||
|
printf "\n\nIntegration $NAME exists - Updating integration\n"
|
||||||
|
if ! elastic_fleet_integration_update "$INTEGRATION_ID" "@$INTEGRATION"; then
|
||||||
|
echo -e "\nFailed to update integration for ${INTEGRATION##*/}"
|
||||||
|
RETURN_CODE=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "\n\nIntegration does not exist - Creating integration\n"
|
||||||
|
if ! elastic_fleet_integration_create "@$INTEGRATION"; then
|
||||||
|
echo -e "\nFailed to create integration for ${INTEGRATION##*/}"
|
||||||
|
RETURN_CODE=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# Fleet Server - Optional integrations (one agent policy per FleetServer_* directory)
|
# Fleet Server - Optional integrations
|
||||||
for FLEET_DIR in /opt/so/conf/elastic-fleet/integrations-optional/FleetServer*/; do
|
for INTEGRATION in /opt/so/conf/elastic-fleet/integrations-optional/FleetServer*/*.json; do
|
||||||
[ -d "$FLEET_DIR" ] || continue
|
if ! [ "$INTEGRATION" == "/opt/so/conf/elastic-fleet/integrations-optional/FleetServer*/*.json" ]; then
|
||||||
FLEET_POLICY=$(basename "$FLEET_DIR")
|
FLEET_POLICY=`echo "$INTEGRATION"| cut -d'/' -f7`
|
||||||
elastic_fleet_load_integrations_dir "$FLEET_POLICY" \
|
printf "\n\nFleet Server Policy - Loading $INTEGRATION\n"
|
||||||
"${FLEET_DIR%/}" "Fleet Server Policy" "elasticsearch-logs" || RETURN_CODE=1
|
elastic_fleet_integration_check "$FLEET_POLICY" "$INTEGRATION"
|
||||||
|
if [ -n "$INTEGRATION_ID" ]; then
|
||||||
|
printf "\n\nIntegration $NAME exists - Updating integration\n"
|
||||||
|
if ! elastic_fleet_integration_update "$INTEGRATION_ID" "@$INTEGRATION"; then
|
||||||
|
echo -e "\nFailed to update integration for ${INTEGRATION##*/}"
|
||||||
|
RETURN_CODE=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "\n\nIntegration does not exist - Creating integration\n"
|
||||||
|
if [ "$NAME" != "elasticsearch-logs" ]; then
|
||||||
|
if ! elastic_fleet_integration_create "@$INTEGRATION"; then
|
||||||
|
echo -e "\nFailed to create integration for ${INTEGRATION##*/}"
|
||||||
|
RETURN_CODE=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Only create the state file if all policies were created/updated successfully
|
# Only create the state file if all policies were created/updated successfully
|
||||||
if [[ "$RETURN_CODE" != "1" ]]; then
|
if [[ $RETURN_CODE -eq 0 ]]; then
|
||||||
touch /opt/so/state/eaintegrations.txt
|
touch /opt/so/state/eaintegrations.txt
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit $RETURN_CODE
|
echo "Fleet integration policies already loaded."
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -23,90 +23,73 @@ if [ $? -ne 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
default_packages=({% for pkg in SUPPORTED_PACKAGES %}"{{ pkg }}"{% if not loop.last %} {% endif %}{% endfor %})
|
default_packages=({% for pkg in SUPPORTED_PACKAGES %}"{{ pkg }}"{% if not loop.last %} {% endif %}{% endfor %})
|
||||||
# JSON array of the default packages, used by the jq filter below.
|
|
||||||
default_packages_json=$(printf '%s\n' "${default_packages[@]}" | jq -R . | jq -s '.')
|
|
||||||
|
|
||||||
# Output lock (serializes concurrent job output) and failure file (one marker line per
|
|
||||||
# failed integration). Mirrors the pattern used by elastic_fleet_load_integrations_dir.
|
|
||||||
OUTPUT_LOCK=$(mktemp)
|
|
||||||
FAIL_FILE=$(mktemp)
|
|
||||||
trap 'rm -f "$OUTPUT_LOCK" "$FAIL_FILE"' EXIT
|
|
||||||
|
|
||||||
# Cache of package name -> latest available version, so the same package is only looked up
|
|
||||||
# once instead of once per (policy, integration).
|
|
||||||
declare -A LATEST_VERSION_CACHE
|
|
||||||
|
|
||||||
|
ERROR=false
|
||||||
for AGENT_POLICY in $agent_policies; do
|
for AGENT_POLICY in $agent_policies; do
|
||||||
# Fetch the agent policy a single time; package name/version and integration id are all
|
if ! integrations=$(elastic_fleet_integration_policy_names "$AGENT_POLICY"); then
|
||||||
# extracted locally below instead of re-fetching the same policy per integration.
|
|
||||||
if ! POLICY_JSON=$(fleet_api "agent_policies/$AGENT_POLICY"); then
|
|
||||||
# this script upgrades default integration packages, exit 1 and let salt handle retrying
|
# this script upgrades default integration packages, exit 1 and let salt handle retrying
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
for INTEGRATION in $integrations; do
|
||||||
# One jq pass emits name/package.name/package.version/id for every eligible integration.
|
if ! [[ "$INTEGRATION" == "elastic-defend-endpoints" ]] && ! [[ "$INTEGRATION" == "fleet_server-"* ]]; then
|
||||||
# The endpoint/fleet_server skips and the default-package gate are applied here in jq.
|
# Get package name so we know what package to look for when checking the current and latest available version
|
||||||
# $defaults (not $def, a jq reserved keyword) holds the default package list.
|
if ! PACKAGE_NAME=$(elastic_fleet_integration_policy_package_name "$AGENT_POLICY" "$INTEGRATION"); then
|
||||||
while IFS=$'\t' read -r INTEGRATION PACKAGE_NAME PACKAGE_VERSION INTEGRATION_ID; do
|
|
||||||
[ -n "$INTEGRATION" ] || continue
|
|
||||||
|
|
||||||
# Look up the latest available version once per package, then memoize it.
|
|
||||||
if [[ -z "${LATEST_VERSION_CACHE[$PACKAGE_NAME]+set}" ]]; then
|
|
||||||
if ! AVAILABLE_VERSION=$(elastic_fleet_package_latest_version_check "$PACKAGE_NAME"); then
|
|
||||||
echo "Error: Failed getting latest version for $PACKAGE_NAME"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
LATEST_VERSION_CACHE[$PACKAGE_NAME]=$AVAILABLE_VERSION
|
{%- if not AUTO_UPGRADE_INTEGRATIONS %}
|
||||||
|
if [[ " ${default_packages[@]} " =~ " $PACKAGE_NAME " ]]; then
|
||||||
|
{%- endif %}
|
||||||
|
# Get currently installed version of package
|
||||||
|
attempt=0
|
||||||
|
max_attempts=3
|
||||||
|
while [ $attempt -lt $max_attempts ]; do
|
||||||
|
if PACKAGE_VERSION=$(elastic_fleet_integration_policy_package_version "$AGENT_POLICY" "$INTEGRATION") && AVAILABLE_VERSION=$(elastic_fleet_package_latest_version_check "$PACKAGE_NAME"); then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
done
|
||||||
|
if [ $attempt -eq $max_attempts ]; then
|
||||||
|
echo "Error: Failed getting $PACKAGE_VERSION or $AVAILABLE_VERSION"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get integration ID
|
||||||
|
if ! INTEGRATION_ID=$(elastic_fleet_integration_id "$AGENT_POLICY" "$INTEGRATION"); then
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
AVAILABLE_VERSION=${LATEST_VERSION_CACHE[$PACKAGE_NAME]}
|
|
||||||
|
|
||||||
if [[ "$PACKAGE_VERSION" != "$AVAILABLE_VERSION" ]]; then
|
if [[ "$PACKAGE_VERSION" != "$AVAILABLE_VERSION" ]]; then
|
||||||
# Dry run, then (if clean) the actual upgrade, dispatched as a throttled background
|
# Dry run of the upgrade
|
||||||
# job. Each job builds its full log into one block, then flushes it under a single
|
echo ""
|
||||||
# shared lock (OUTPUT_LOCK) so concurrent jobs never interleave on stdout; a failed
|
echo "Current $PACKAGE_NAME package version ($PACKAGE_VERSION) is not the same as the latest available package ($AVAILABLE_VERSION)..."
|
||||||
# job also appends a marker line to FAIL_FILE while holding that same lock.
|
echo "Upgrading $INTEGRATION..."
|
||||||
elastic_fleet_throttle
|
echo "Starting dry run..."
|
||||||
{
|
|
||||||
block=$'\n'"Current $PACKAGE_NAME package version ($PACKAGE_VERSION) is not the same as the latest available package ($AVAILABLE_VERSION)..."$'\n'
|
|
||||||
block+="Upgrading $INTEGRATION..."$'\n'"Starting dry run..."$'\n'
|
|
||||||
fail=""
|
|
||||||
if ! DRYRUN_OUTPUT=$(elastic_fleet_integration_policy_dryrun_upgrade "$INTEGRATION_ID"); then
|
if ! DRYRUN_OUTPUT=$(elastic_fleet_integration_policy_dryrun_upgrade "$INTEGRATION_ID"); then
|
||||||
block+="Error: Failed to complete dry run for '$INTEGRATION_ID'."$'\n'
|
exit 1
|
||||||
fail="dryrun $INTEGRATION"
|
fi
|
||||||
elif [[ "$(jq .[].hasErrors <<<"$DRYRUN_OUTPUT")" == "false" ]]; then
|
DRYRUN_ERRORS=$(echo "$DRYRUN_OUTPUT" | jq .[].hasErrors)
|
||||||
block+="No errors detected. Proceeding with upgrade..."$'\n'
|
|
||||||
|
# If no errors with dry run, proceed with actual upgrade
|
||||||
|
if [[ "$DRYRUN_ERRORS" == "false" ]]; then
|
||||||
|
echo "No errors detected. Proceeding with upgrade..."
|
||||||
if ! elastic_fleet_integration_policy_upgrade "$INTEGRATION_ID"; then
|
if ! elastic_fleet_integration_policy_upgrade "$INTEGRATION_ID"; then
|
||||||
block+="Error: Upgrade failed for $PACKAGE_NAME with integration ID '$INTEGRATION_ID'."$'\n'
|
echo "Error: Upgrade failed for $PACKAGE_NAME with integration ID '$INTEGRATION_ID'."
|
||||||
fail="upgrade $INTEGRATION"
|
ERROR=true
|
||||||
|
continue
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
block+="Errors detected during dry run for $PACKAGE_NAME policy upgrade..."$'\n'
|
echo "Errors detected during dry run for $PACKAGE_NAME policy upgrade..."
|
||||||
fail="dryrun-errors $INTEGRATION"
|
ERROR=true
|
||||||
|
continue
|
||||||
fi
|
fi
|
||||||
{
|
|
||||||
flock 9
|
|
||||||
printf '%s' "$block"
|
|
||||||
[ -n "$fail" ] && printf '%s\n' "$fail" >>"$FAIL_FILE"
|
|
||||||
} 9>>"$OUTPUT_LOCK"
|
|
||||||
} &
|
|
||||||
fi
|
fi
|
||||||
done < <(jq -r --argjson defaults "$default_packages_json" '
|
|
||||||
.item.package_policies[]
|
|
||||||
| select(.name != "elastic-defend-endpoints")
|
|
||||||
| select(.name | startswith("fleet_server-") | not)
|
|
||||||
{%- if not AUTO_UPGRADE_INTEGRATIONS %}
|
{%- if not AUTO_UPGRADE_INTEGRATIONS %}
|
||||||
| select(.package.name | IN($defaults[]))
|
fi
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
| [.name, .package.name, .package.version, .id] | @tsv
|
fi
|
||||||
' <<<"$POLICY_JSON")
|
|
||||||
done
|
done
|
||||||
|
done
|
||||||
# Barrier: wait for every dispatched dry-run/upgrade job to finish.
|
if [[ "$ERROR" == "true" ]]; then
|
||||||
wait
|
|
||||||
|
|
||||||
if [ -s "$FAIL_FILE" ]; then
|
|
||||||
printf '\nFailed integration upgrades:\n'
|
|
||||||
cat "$FAIL_FILE"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
STATE_FILE_SUCCESS=/opt/so/state/estemplates.txt
|
STATE_FILE_SUCCESS=/opt/so/state/estemplates.txt
|
||||||
INSTALLED_PACKAGE_LIST=/tmp/esfleet_installed_packages.json
|
INSTALLED_PACKAGE_LIST=/tmp/esfleet_installed_packages.json
|
||||||
BULK_INSTALL_PACKAGE_LIST=/tmp/esfleet_bulk_install.json
|
BULK_INSTALL_PACKAGE_LIST=/tmp/esfleet_bulk_install.json
|
||||||
|
BULK_INSTALL_PACKAGE_TMP=/tmp/esfleet_bulk_install_tmp.json
|
||||||
BULK_INSTALL_OUTPUT=/opt/so/state/esfleet_bulk_install_results.json
|
BULK_INSTALL_OUTPUT=/opt/so/state/esfleet_bulk_install_results.json
|
||||||
INTEGRATION_PACKAGE_COMPONENTS=/opt/so/state/esfleet_package_components.json
|
INTEGRATION_PACKAGE_COMPONENTS=/opt/so/state/esfleet_package_components.json
|
||||||
INPUT_PACKAGE_COMPONENTS=/opt/so/state/esfleet_input_package_components.json
|
INPUT_PACKAGE_COMPONENTS=/opt/so/state/esfleet_input_package_components.json
|
||||||
@@ -28,6 +29,29 @@ PENDING_UPDATE=false
|
|||||||
# Requiring some level of manual Elastic Stack configuration before installation
|
# Requiring some level of manual Elastic Stack configuration before installation
|
||||||
EXCLUDED_INTEGRATIONS=('apm')
|
EXCLUDED_INTEGRATIONS=('apm')
|
||||||
|
|
||||||
|
version_conversion(){
|
||||||
|
version=$1
|
||||||
|
echo "$version" | awk -F '.' '{ printf("%d%03d%03d\n", $1, $2, $3); }'
|
||||||
|
}
|
||||||
|
|
||||||
|
compare_versions() {
|
||||||
|
version1=$1
|
||||||
|
version2=$2
|
||||||
|
|
||||||
|
# Convert versions to numbers
|
||||||
|
num1=$(version_conversion "$version1")
|
||||||
|
num2=$(version_conversion "$version2")
|
||||||
|
|
||||||
|
# Compare using bc
|
||||||
|
if (( $(echo "$num1 < $num2" | bc -l) )); then
|
||||||
|
echo "less"
|
||||||
|
elif (( $(echo "$num1 > $num2" | bc -l) )); then
|
||||||
|
echo "greater"
|
||||||
|
else
|
||||||
|
echo "equal"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
IFS=$'\n'
|
IFS=$'\n'
|
||||||
agent_policies=$(elastic_fleet_agent_policy_ids)
|
agent_policies=$(elastic_fleet_agent_policy_ids)
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
@@ -39,23 +63,23 @@ default_packages=({% for pkg in SUPPORTED_PACKAGES %}"{{ pkg }}"{% if not loop.l
|
|||||||
|
|
||||||
in_use_integrations=()
|
in_use_integrations=()
|
||||||
|
|
||||||
# Fetch each agent policy once; its package_policies[] already contain both the integration name
|
|
||||||
# and the .package.name, so extract all non-default package names locally in a single jq instead
|
|
||||||
# of re-fetching the same policy per integration.
|
|
||||||
default_packages_json=$(printf '%s\n' "${default_packages[@]}" | jq -R . | jq -s '.')
|
|
||||||
for AGENT_POLICY in $agent_policies; do
|
for AGENT_POLICY in $agent_policies; do
|
||||||
|
|
||||||
if ! policy_json=$(fleet_api "agent_policies/$AGENT_POLICY"); then
|
if ! integrations=$(elastic_fleet_integration_policy_names "$AGENT_POLICY"); then
|
||||||
# skip the agent policy if we can't get required info, let salt retry. Integrations loaded by this script are non-default integrations.
|
# skip the agent policy if we can't get required info, let salt retry. Integrations loaded by this script are non-default integrations.
|
||||||
echo "Skipping $AGENT_POLICY.. "
|
echo "Skipping $AGENT_POLICY.. "
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
for INTEGRATION in $integrations; do
|
||||||
|
if ! PACKAGE_NAME=$(elastic_fleet_integration_policy_package_name "$AGENT_POLICY" "$INTEGRATION"); then
|
||||||
|
echo "Not adding $INTEGRATION, couldn't get package name"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
# non-default integrations that are in-use in any policy
|
# non-default integrations that are in-use in any policy
|
||||||
while IFS= read -r PACKAGE_NAME; do
|
if ! [[ " ${default_packages[@]} " =~ " $PACKAGE_NAME " ]]; then
|
||||||
[ -n "$PACKAGE_NAME" ] && in_use_integrations+=("$PACKAGE_NAME")
|
in_use_integrations+=("$PACKAGE_NAME")
|
||||||
done < <(jq -r --argjson defaults "$default_packages_json" \
|
fi
|
||||||
'.item.package_policies[].package.name | select(. as $n | ($defaults | index($n)) | not)' \
|
done
|
||||||
<<<"$policy_json")
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ -f $STATE_FILE_SUCCESS ]]; then
|
if [[ -f $STATE_FILE_SUCCESS ]]; then
|
||||||
@@ -66,55 +90,72 @@ if [[ -f $STATE_FILE_SUCCESS ]]; then
|
|||||||
rm -f $INSTALLED_PACKAGE_LIST
|
rm -f $INSTALLED_PACKAGE_LIST
|
||||||
echo $latest_package_list | jq '{packages: [.items[] | {name: .name, latest_version: .version, installed_version: .installationInfo.version, subscription: .conditions.elastic.subscription }]}' >> $INSTALLED_PACKAGE_LIST
|
echo $latest_package_list | jq '{packages: [.items[] | {name: .name, latest_version: .version, installed_version: .installationInfo.version, subscription: .conditions.elastic.subscription }]}' >> $INSTALLED_PACKAGE_LIST
|
||||||
|
|
||||||
# Build the bulk install list and the per-package status messages with two jq passes
|
while read -r package; do
|
||||||
# instead of a per-package bash loop. The old loop forked ~10 processes per package
|
# get package details
|
||||||
# (5 jq + awk/bc for the version compare) and re-parsed/rewrote a growing JSON file on
|
package_name=$(echo "$package" | jq -r '.name')
|
||||||
# every add (O(n^2)). Selection and messages below are identical to that logic.
|
latest_version=$(echo "$package" | jq -r '.latest_version')
|
||||||
SUB={% if SUB %}true{% else %}false{% endif %}
|
installed_version=$(echo "$package" | jq -r '.installed_version')
|
||||||
AUTOUP={% if AUTO_UPGRADE_INTEGRATIONS %}true{% else %}false{% endif %}
|
subscription=$(echo "$package" | jq -r '.subscription')
|
||||||
EXCLUDED_JSON=$(printf '%s\n' "${EXCLUDED_INTEGRATIONS[@]}" | jq -R 'select(length>0)' | jq -s '.')
|
bulk_package=$(echo "$package" | jq '{name: .name, version: .latest_version}' )
|
||||||
INUSE_JSON=$(printf '%s\n' "${in_use_integrations[@]}" | jq -R 'select(length>0)' | jq -s 'unique')
|
|
||||||
|
|
||||||
# vnum replicates the previous version_conversion (%d%03d%03d of the first three dotted
|
if [[ ! "${EXCLUDED_INTEGRATIONS[@]}" =~ "$package_name" ]]; then
|
||||||
# fields); needs() replicates the excluded/subscription/installed/upgrade/in-use logic.
|
{% if not SUB %}
|
||||||
JQ_DECISION='
|
if [[ "$subscription" != "basic" && "$subscription" != "null" && -n "$subscription" ]]; then
|
||||||
def vnum:
|
# pass over integrations that require non-basic elastic license
|
||||||
[ (split(".")|.[0:3][] | gsub("[^0-9].*";"") | (if .=="" then "0" else . end) | tonumber) ]
|
echo "$package_name integration requires an Elastic license of $subscription or greater... skipping"
|
||||||
| (.[0]//0)*1000000 + (.[1]//0)*1000 + (.[2]//0);
|
continue
|
||||||
def needs($sub;$autoup;$excluded;$inuse):
|
else
|
||||||
.name as $n
|
if [[ "$installed_version" == "null" || -z "$installed_version" ]]; then
|
||||||
| ($n | IN($excluded[]) | not)
|
echo "$package_name is not installed... Adding to next update."
|
||||||
and ( $sub or (.subscription==null or .subscription=="basic" or .subscription=="") )
|
jq --argjson package "$bulk_package" '.packages += [$package]' $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_PACKAGE_TMP && mv $BULK_INSTALL_PACKAGE_TMP $BULK_INSTALL_PACKAGE_LIST
|
||||||
and ( (.installed_version==null or .installed_version=="")
|
|
||||||
or ( ((.latest_version|vnum) > (.installed_version|vnum))
|
|
||||||
and ( $autoup or ($n | IN($inuse[]) | not) ) ) );'
|
|
||||||
|
|
||||||
JQ_ARGS=(--argjson sub "$SUB" --argjson autoup "$AUTOUP" --argjson excluded "$EXCLUDED_JSON" --argjson inuse "$INUSE_JSON")
|
|
||||||
|
|
||||||
# (a) Per-package status messages (parity with the previous echo output).
|
|
||||||
jq -r "${JQ_ARGS[@]}" "$JQ_DECISION"'
|
|
||||||
.packages[]
|
|
||||||
| .name as $n
|
|
||||||
| if ($n|IN($excluded[])) then "Skipping \($n)..."
|
|
||||||
elif (($sub|not) and (.subscription!=null and .subscription!="basic" and .subscription!="")) then
|
|
||||||
"\($n) integration requires an Elastic license of \(.subscription) or greater... skipping"
|
|
||||||
elif (.installed_version==null or .installed_version=="") then
|
|
||||||
"\($n) is not installed... Adding to next update."
|
|
||||||
elif ((.latest_version|vnum) > (.installed_version|vnum)) then
|
|
||||||
(if ($autoup or ($n|IN($inuse[])|not))
|
|
||||||
then "\($n) is at version \(.installed_version) latest version is \(.latest_version)... Adding to next update."
|
|
||||||
else "skipping available upgrade for in use integration - \($n)." end)
|
|
||||||
else empty end
|
|
||||||
' "$INSTALLED_PACKAGE_LIST"
|
|
||||||
|
|
||||||
# (b) The bulk install list, built in a single pass.
|
|
||||||
jq "${JQ_ARGS[@]}" "$JQ_DECISION"'
|
|
||||||
{packages: [ .packages[] | select(needs($sub;$autoup;$excluded;$inuse)) | {name, version: .latest_version} ]}
|
|
||||||
' "$INSTALLED_PACKAGE_LIST" > "$BULK_INSTALL_PACKAGE_LIST"
|
|
||||||
|
|
||||||
if jq -e '.packages | length > 0' "$BULK_INSTALL_PACKAGE_LIST" >/dev/null; then
|
|
||||||
PENDING_UPDATE=true
|
PENDING_UPDATE=true
|
||||||
|
else
|
||||||
|
results=$(compare_versions "$latest_version" "$installed_version")
|
||||||
|
if [ $results == "greater" ]; then
|
||||||
|
{#- When auto_upgrade_integrations is false, skip upgrading in_use_integrations #}
|
||||||
|
{%- if not AUTO_UPGRADE_INTEGRATIONS %}
|
||||||
|
if ! [[ " ${in_use_integrations[@]} " =~ " $package_name " ]]; then
|
||||||
|
{%- endif %}
|
||||||
|
echo "$package_name is at version $installed_version latest version is $latest_version... Adding to next update."
|
||||||
|
jq --argjson package "$bulk_package" '.packages += [$package]' $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_PACKAGE_TMP && mv $BULK_INSTALL_PACKAGE_TMP $BULK_INSTALL_PACKAGE_LIST
|
||||||
|
|
||||||
|
PENDING_UPDATE=true
|
||||||
|
{%- if not AUTO_UPGRADE_INTEGRATIONS %}
|
||||||
|
else
|
||||||
|
echo "skipping available upgrade for in use integration - $package_name."
|
||||||
fi
|
fi
|
||||||
|
{%- endif %}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
{% else %}
|
||||||
|
if [[ "$installed_version" == "null" || -z "$installed_version" ]]; then
|
||||||
|
echo "$package_name is not installed... Adding to next update."
|
||||||
|
jq --argjson package "$bulk_package" '.packages += [$package]' $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_PACKAGE_TMP && mv $BULK_INSTALL_PACKAGE_TMP $BULK_INSTALL_PACKAGE_LIST
|
||||||
|
PENDING_UPDATE=true
|
||||||
|
else
|
||||||
|
results=$(compare_versions "$latest_version" "$installed_version")
|
||||||
|
if [ $results == "greater" ]; then
|
||||||
|
{#- When auto_upgrade_integrations is false, skip upgrading in_use_integrations #}
|
||||||
|
{%- if not AUTO_UPGRADE_INTEGRATIONS %}
|
||||||
|
if ! [[ " ${in_use_integrations[@]} " =~ " $package_name " ]]; then
|
||||||
|
{%- endif %}
|
||||||
|
echo "$package_name is at version $installed_version latest version is $latest_version... Adding to next update."
|
||||||
|
jq --argjson package "$bulk_package" '.packages += [$package]' $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_PACKAGE_TMP && mv $BULK_INSTALL_PACKAGE_TMP $BULK_INSTALL_PACKAGE_LIST
|
||||||
|
PENDING_UPDATE=true
|
||||||
|
{%- if not AUTO_UPGRADE_INTEGRATIONS %}
|
||||||
|
else
|
||||||
|
echo "skipping available upgrade for in use integration - $package_name."
|
||||||
|
fi
|
||||||
|
{%- endif %}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
{% endif %}
|
||||||
|
else
|
||||||
|
echo "Skipping $package_name..."
|
||||||
|
fi
|
||||||
|
done <<< "$(jq -c '.packages[]' "$INSTALLED_PACKAGE_LIST")"
|
||||||
|
|
||||||
if [ "$PENDING_UPDATE" = true ]; then
|
if [ "$PENDING_UPDATE" = true ]; then
|
||||||
# Run chunked install of packages
|
# Run chunked install of packages
|
||||||
|
|||||||
@@ -8,18 +8,33 @@
|
|||||||
|
|
||||||
. /usr/sbin/so-elastic-fleet-common
|
. /usr/sbin/so-elastic-fleet-common
|
||||||
|
|
||||||
|
PKG_LOAD_FAILURES=0
|
||||||
|
PKG_LOAD_FAILURES_NAMES=()
|
||||||
|
|
||||||
{%- for PACKAGE in SUPPORTED_PACKAGES %}
|
{%- for PACKAGE in SUPPORTED_PACKAGES %}
|
||||||
echo "Upgrading {{ PACKAGE }} package..."
|
echo "Upgrading {{ PACKAGE }} package..."
|
||||||
if VERSION=$(elastic_fleet_package_latest_version_check "{{ PACKAGE }}"); then
|
if VERSION=$(elastic_fleet_package_latest_version_check "{{ PACKAGE }}"); then
|
||||||
if ! elastic_fleet_package_install "{{ PACKAGE }}" "$VERSION"; then
|
if ! elastic_fleet_package_install "{{ PACKAGE }}" "$VERSION"; then
|
||||||
# exit 1 on failure to upgrade a default package, allow salt to handle retries
|
PKG_LOAD_FAILURES=$((PKG_LOAD_FAILURES + 1))
|
||||||
echo -e "\nERROR: Failed to upgrade $PACKAGE to version: $VERSION"
|
PKG_LOAD_FAILURES_NAMES+=("{{ PACKAGE }}")
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -e "\nERROR: Failed to get version information for integration $PACKAGE"
|
PKG_LOAD_FAILURES=$((PKG_LOAD_FAILURES + 1))
|
||||||
|
PKG_LOAD_FAILURES_NAMES+=("{{ PACKAGE }}")
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
|
if [ $PKG_LOAD_FAILURES -gt 0 ]; then
|
||||||
|
echo "ERROR: Failed to upgrade $PKG_LOAD_FAILURES package(s):"
|
||||||
|
for PKG in "${PKG_LOAD_FAILURES_NAMES[@]}"; do
|
||||||
|
echo " - $PKG"
|
||||||
|
done
|
||||||
|
# exit 1 on failure to upgrade a default package, allow salt to handle retries
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Successfully upgraded all packages."
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
/usr/sbin/so-elasticsearch-templates-load
|
/usr/sbin/so-elasticsearch-templates-load
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ ADDON_STATEFILE_SUCCESS=/opt/so/state/addon_estemplates.txt
|
|||||||
ELASTICSEARCH_TEMPLATES_DIR="/opt/so/conf/elasticsearch/templates"
|
ELASTICSEARCH_TEMPLATES_DIR="/opt/so/conf/elasticsearch/templates"
|
||||||
SO_TEMPLATES_DIR="${ELASTICSEARCH_TEMPLATES_DIR}/index"
|
SO_TEMPLATES_DIR="${ELASTICSEARCH_TEMPLATES_DIR}/index"
|
||||||
ADDON_TEMPLATES_DIR="${ELASTICSEARCH_TEMPLATES_DIR}/addon-index"
|
ADDON_TEMPLATES_DIR="${ELASTICSEARCH_TEMPLATES_DIR}/addon-index"
|
||||||
FAILED_NAMES=()
|
SO_LOAD_FAILURES=0
|
||||||
FAILED_COUNT=0
|
ADDON_LOAD_FAILURES=0
|
||||||
|
SO_LOAD_FAILURES_NAMES=()
|
||||||
|
ADDON_LOAD_FAILURES_NAMES=()
|
||||||
IS_HEAVYNODE="false"
|
IS_HEAVYNODE="false"
|
||||||
FORCE="false"
|
FORCE="false"
|
||||||
VERBOSE="false"
|
VERBOSE="false"
|
||||||
@@ -44,86 +46,20 @@ while [[ $# -gt 0 ]]; do
|
|||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
# Max number of concurrent template PUT jobs. Override via env if needed.
|
|
||||||
MAX_TEMPLATE_JOBS=${MAX_TEMPLATE_JOBS:-10}
|
|
||||||
|
|
||||||
# Block until fewer than MAX_TEMPLATE_JOBS background jobs are running.
|
|
||||||
template_throttle() {
|
|
||||||
while (( $(jobs -rp | wc -l) >= MAX_TEMPLATE_JOBS )); do
|
|
||||||
wait -n
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Per-job failure markers and an output lock for serializing parallel job output.
|
|
||||||
# Each failed load drops one file (named after the template) into FAIL_DIR; the
|
|
||||||
# output of each job is flushed as a single block under flock so concurrent jobs
|
|
||||||
# never interleave their (chatty) retry output.
|
|
||||||
FAIL_DIR=$(mktemp -d)
|
|
||||||
OUTPUT_LOCK="${FAIL_DIR}/.output.lock"
|
|
||||||
: > "$OUTPUT_LOCK"
|
|
||||||
trap 'rm -rf "$FAIL_DIR"' EXIT
|
|
||||||
|
|
||||||
# Record a failure: $1 = the template name/path to report later. Slashes are
|
|
||||||
# encoded so the path becomes a safe single filename.
|
|
||||||
record_failure() {
|
|
||||||
local marker="${1//\//__}"
|
|
||||||
: > "${FAIL_DIR}/fail.${marker}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Populate FAILED_NAMES and FAILED_COUNT from the current phase's markers.
|
|
||||||
# Must run in the current shell (not a command substitution) so the array sticks.
|
|
||||||
collect_failures() {
|
|
||||||
FAILED_NAMES=()
|
|
||||||
FAILED_COUNT=0
|
|
||||||
local f name
|
|
||||||
shopt -s nullglob
|
|
||||||
for f in "${FAIL_DIR}"/fail.*; do
|
|
||||||
name="${f##*/fail.}"
|
|
||||||
name="${name//__//}"
|
|
||||||
FAILED_NAMES+=("$name")
|
|
||||||
FAILED_COUNT=$((FAILED_COUNT + 1))
|
|
||||||
done
|
|
||||||
shopt -u nullglob
|
|
||||||
}
|
|
||||||
|
|
||||||
# Clear markers and names between phases so SO and addon counts stay independent.
|
|
||||||
reset_failures() {
|
|
||||||
shopt -s nullglob
|
|
||||||
rm -f "${FAIL_DIR}"/fail.*
|
|
||||||
shopt -u nullglob
|
|
||||||
FAILED_NAMES=()
|
|
||||||
FAILED_COUNT=0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print a block of text atomically (under the shared output lock) so the output
|
|
||||||
# of concurrent background jobs is not interleaved.
|
|
||||||
locked_echo() {
|
|
||||||
{ flock 9; printf '%s\n' "$1"; } 9>>"$OUTPUT_LOCK"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Loads one template file via PUT. Intended to be dispatched as a background job.
|
|
||||||
# $1 uri - e.g. _component_template/foo or _index_template/foo
|
|
||||||
# $2 file - path to the template JSON
|
|
||||||
# $3 report_name - name/path to record if this load fails
|
|
||||||
load_template() {
|
load_template() {
|
||||||
local uri="$1"
|
local uri="$1"
|
||||||
local file="$2"
|
local file="$2"
|
||||||
local report_name="$3"
|
|
||||||
local out rc=0 block
|
|
||||||
|
|
||||||
# Capture everything (including retry's diagnostic chatter) into one block so
|
echo "Loading template file $file"
|
||||||
# concurrent jobs never interleave; the whole block is flushed under one flock.
|
if ! output=$(retry 3 3 "so-elasticsearch-query $uri -d@$file -XPUT" "{\"acknowledged\":true}"); then
|
||||||
block="Loading template file $file"$'\n'
|
echo "$output"
|
||||||
if ! out=$(retry 3 3 "so-elasticsearch-query $uri -d@$file -XPUT" "{\"acknowledged\":true}" 2>&1); then
|
|
||||||
block+="$out"$'\n'
|
return 1
|
||||||
rc=1
|
|
||||||
elif [[ "$VERBOSE" == "true" ]]; then
|
elif [[ "$VERBOSE" == "true" ]]; then
|
||||||
block+="$out"$'\n'
|
echo "$output"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
{ flock 9; printf '%s' "$block"; } 9>>"$OUTPUT_LOCK"
|
|
||||||
|
|
||||||
(( rc != 0 )) && record_failure "$report_name"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check_required_component_template_exists() {
|
check_required_component_template_exists() {
|
||||||
@@ -174,9 +110,6 @@ load_component_templates() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Dispatch loads as throttled background jobs. The barrier (wait) happens in
|
|
||||||
# the caller after all component groups have been dispatched, since index
|
|
||||||
# templates must not load until every component template is in place.
|
|
||||||
for component in "$pattern"/*.json; do
|
for component in "$pattern"/*.json; do
|
||||||
tmpl_name=$(basename "${component%.json}")
|
tmpl_name=$(basename "${component%.json}")
|
||||||
|
|
||||||
@@ -185,8 +118,10 @@ load_component_templates() {
|
|||||||
tmpl_name="${tmpl_name%-mappings}-mappings"
|
tmpl_name="${tmpl_name%-mappings}-mappings"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
template_throttle
|
if ! load_template "_component_template/${tmpl_name}" "$component"; then
|
||||||
load_template "_component_template/${tmpl_name}" "$component" "$component" &
|
SO_LOAD_FAILURES=$((SO_LOAD_FAILURES + 1))
|
||||||
|
SO_LOAD_FAILURES_NAMES+=("$component")
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,9 +180,6 @@ if [[ "$FORCE" == "true" || ! -f "$SO_STATEFILE_SUCCESS" ]] && index_templates_e
|
|||||||
load_component_templates "Elastic Agent" "elastic-agent"
|
load_component_templates "Elastic Agent" "elastic-agent"
|
||||||
load_component_templates "Security Onion" "so"
|
load_component_templates "Security Onion" "so"
|
||||||
|
|
||||||
# Barrier: every component template PUT must complete before we snapshot the
|
|
||||||
# component template list and start loading index templates that depend on them.
|
|
||||||
wait
|
|
||||||
component_templates=$(so-elasticsearch-component-templates-list)
|
component_templates=$(so-elasticsearch-component-templates-list)
|
||||||
echo -e "Loading Security Onion index templates...\n"
|
echo -e "Loading Security Onion index templates...\n"
|
||||||
for so_idx_tmpl in "${SO_TEMPLATES_DIR}"/*.json; do
|
for so_idx_tmpl in "${SO_TEMPLATES_DIR}"/*.json; do
|
||||||
@@ -257,7 +189,7 @@ if [[ "$FORCE" == "true" || ! -f "$SO_STATEFILE_SUCCESS" ]] && index_templates_e
|
|||||||
# TODO: Better way to load only heavynode specific templates
|
# TODO: Better way to load only heavynode specific templates
|
||||||
if ! check_heavynode_compatiable_index_template "$tmpl_name"; then
|
if ! check_heavynode_compatiable_index_template "$tmpl_name"; then
|
||||||
if [[ "$VERBOSE" == "true" ]]; then
|
if [[ "$VERBOSE" == "true" ]]; then
|
||||||
locked_echo "Skipping over $so_idx_tmpl, template is not a heavynode specific index template."
|
echo "Skipping over $so_idx_tmpl, template is not a heavynode specific index template."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
continue
|
continue
|
||||||
@@ -265,34 +197,32 @@ if [[ "$FORCE" == "true" || ! -f "$SO_STATEFILE_SUCCESS" ]] && index_templates_e
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if check_required_component_template_exists "$so_idx_tmpl"; then
|
if check_required_component_template_exists "$so_idx_tmpl"; then
|
||||||
template_throttle
|
if ! load_template "_index_template/$tmpl_name" "$so_idx_tmpl"; then
|
||||||
load_template "_index_template/$tmpl_name" "$so_idx_tmpl" "$so_idx_tmpl" &
|
SO_LOAD_FAILURES=$((SO_LOAD_FAILURES + 1))
|
||||||
|
SO_LOAD_FAILURES_NAMES+=("$so_idx_tmpl")
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
locked_echo "Skipping over $so_idx_tmpl due to missing required component template(s)."
|
echo "Skipping over $so_idx_tmpl due to missing required component template(s)."
|
||||||
record_failure "$so_idx_tmpl"
|
SO_LOAD_FAILURES=$((SO_LOAD_FAILURES + 1))
|
||||||
|
SO_LOAD_FAILURES_NAMES+=("$so_idx_tmpl")
|
||||||
|
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Barrier: all SO index template PUTs must finish before tallying failures.
|
if [[ $SO_LOAD_FAILURES -eq 0 ]]; then
|
||||||
wait
|
|
||||||
|
|
||||||
collect_failures
|
|
||||||
if [[ $FAILED_COUNT -eq 0 ]]; then
|
|
||||||
echo "All Security Onion core templates loaded successfully."
|
echo "All Security Onion core templates loaded successfully."
|
||||||
|
|
||||||
touch "$SO_STATEFILE_SUCCESS"
|
touch "$SO_STATEFILE_SUCCESS"
|
||||||
else
|
else
|
||||||
echo "Encountered $FAILED_COUNT failure(s) loading templates:"
|
echo "Encountered $SO_LOAD_FAILURES failure(s) loading templates:"
|
||||||
for failed_template in "${FAILED_NAMES[@]}"; do
|
for failed_template in "${SO_LOAD_FAILURES_NAMES[@]}"; do
|
||||||
echo " - $failed_template"
|
echo " - $failed_template"
|
||||||
done
|
done
|
||||||
if [[ "$SHOULD_EXIT_ON_FAILURE" == "true" ]]; then
|
if [[ "$SHOULD_EXIT_ON_FAILURE" == "true" ]]; then
|
||||||
fail "Failed to load all Security Onion core templates successfully."
|
fail "Failed to load all Security Onion core templates successfully."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
reset_failures
|
|
||||||
elif ! index_templates_exist "$SO_TEMPLATES_DIR"; then
|
elif ! index_templates_exist "$SO_TEMPLATES_DIR"; then
|
||||||
echo "No Security Onion core index templates found in ${SO_TEMPLATES_DIR}, skipping."
|
echo "No Security Onion core index templates found in ${SO_TEMPLATES_DIR}, skipping."
|
||||||
elif [[ -f "$SO_STATEFILE_SUCCESS" ]]; then
|
elif [[ -f "$SO_STATEFILE_SUCCESS" ]]; then
|
||||||
@@ -311,27 +241,26 @@ if should_load_addon_templates; then
|
|||||||
tmpl_name=$(basename "${addon_idx_tmpl%-template.json}")
|
tmpl_name=$(basename "${addon_idx_tmpl%-template.json}")
|
||||||
|
|
||||||
if check_required_component_template_exists "$addon_idx_tmpl"; then
|
if check_required_component_template_exists "$addon_idx_tmpl"; then
|
||||||
template_throttle
|
if ! load_template "_index_template/${tmpl_name}" "$addon_idx_tmpl"; then
|
||||||
load_template "_index_template/${tmpl_name}" "$addon_idx_tmpl" "$addon_idx_tmpl" &
|
ADDON_LOAD_FAILURES=$((ADDON_LOAD_FAILURES + 1))
|
||||||
|
ADDON_LOAD_FAILURES_NAMES+=("$addon_idx_tmpl")
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
locked_echo "Skipping over $addon_idx_tmpl due to missing required component template(s)."
|
echo "Skipping over $addon_idx_tmpl due to missing required component template(s)."
|
||||||
record_failure "$addon_idx_tmpl"
|
ADDON_LOAD_FAILURES=$((ADDON_LOAD_FAILURES + 1))
|
||||||
|
ADDON_LOAD_FAILURES_NAMES+=("$addon_idx_tmpl")
|
||||||
|
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Barrier: all addon index template PUTs must finish before tallying failures.
|
if [[ $ADDON_LOAD_FAILURES -eq 0 ]]; then
|
||||||
wait
|
|
||||||
|
|
||||||
collect_failures
|
|
||||||
if [[ $FAILED_COUNT -eq 0 ]]; then
|
|
||||||
echo "All addon integration templates loaded successfully."
|
echo "All addon integration templates loaded successfully."
|
||||||
|
|
||||||
touch "$ADDON_STATEFILE_SUCCESS"
|
touch "$ADDON_STATEFILE_SUCCESS"
|
||||||
else
|
else
|
||||||
echo "Encountered $FAILED_COUNT failure(s) loading addon integration templates:"
|
echo "Encountered $ADDON_LOAD_FAILURES failure(s) loading addon integration templates:"
|
||||||
for failed_template in "${FAILED_NAMES[@]}"; do
|
for failed_template in "${ADDON_LOAD_FAILURES_NAMES[@]}"; do
|
||||||
echo " - $failed_template"
|
echo " - $failed_template"
|
||||||
done
|
done
|
||||||
if [[ "$SHOULD_EXIT_ON_FAILURE" == "true" ]]; then
|
if [[ "$SHOULD_EXIT_ON_FAILURE" == "true" ]]; then
|
||||||
|
|||||||
@@ -6,37 +6,6 @@
|
|||||||
|
|
||||||
. /usr/sbin/so-common
|
. /usr/sbin/so-common
|
||||||
|
|
||||||
MAX_JOBS=10
|
|
||||||
|
|
||||||
# Lock used to serialize block writes so concurrent jobs never interleave their output.
|
|
||||||
ILM_OUTPUT_LOCK=$(mktemp)
|
|
||||||
trap 'rm -f "$ILM_OUTPUT_LOCK"' EXIT
|
|
||||||
|
|
||||||
# Policies are loaded concurrently (up to MAX_JOBS at a time) for speed. Each policy's block is
|
|
||||||
# printed the moment its curl returns, so output appears in COMPLETION ORDER, not the order
|
|
||||||
# policies are defined in configuration.
|
|
||||||
echo "Loading ILM policies concurrently; output below appears in completion order, not configuration order."
|
|
||||||
echo
|
|
||||||
|
|
||||||
put_policy() {
|
|
||||||
local desc="$1" policyname="$2" data="$3" result
|
|
||||||
result=$(curl -K /opt/so/conf/elasticsearch/curl.config -s -k -L \
|
|
||||||
-X PUT "https://localhost:9200/_ilm/policy/${policyname}" \
|
|
||||||
-H 'Content-Type: application/json' -d"${data}")
|
|
||||||
# curl above ran in parallel; serialize just this block write so concurrent jobs never interleave.
|
|
||||||
{
|
|
||||||
flock 200
|
|
||||||
printf 'Setting up %s policy...\n%s\n\n' "${desc}" "${result}"
|
|
||||||
} 200>>"${ILM_OUTPUT_LOCK}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Block until fewer than MAX_JOBS background curls are running.
|
|
||||||
throttle() {
|
|
||||||
while (( $(jobs -rp | wc -l) >= MAX_JOBS )); do
|
|
||||||
wait -n
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
{%- from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS %}
|
{%- from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS %}
|
||||||
{%- if GLOBALS.role != "so-heavynode" %}
|
{%- if GLOBALS.role != "so-heavynode" %}
|
||||||
{%- from 'elasticsearch/template.map.jinja' import ALL_ADDON_SETTINGS %}
|
{%- from 'elasticsearch/template.map.jinja' import ALL_ADDON_SETTINGS %}
|
||||||
@@ -45,26 +14,35 @@ throttle() {
|
|||||||
{%- for index, settings in ES_INDEX_SETTINGS.items() %}
|
{%- for index, settings in ES_INDEX_SETTINGS.items() %}
|
||||||
{%- if settings.policy is defined %}
|
{%- if settings.policy is defined %}
|
||||||
{%- if index == 'so-logs-detections.alerts' %}
|
{%- if index == 'so-logs-detections.alerts' %}
|
||||||
throttle
|
echo
|
||||||
put_policy "so-logs-detections.alerts-so" "{{ index }}-so" '{ "policy": {{ settings.policy | tojson(true) }} }' &
|
echo "Setting up so-logs-detections.alerts-so policy..."
|
||||||
|
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-so" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }'
|
||||||
|
echo
|
||||||
{%- elif index == 'so-logs-soc' %}
|
{%- elif index == 'so-logs-soc' %}
|
||||||
throttle
|
echo
|
||||||
put_policy "so-soc-logs" "so-soc-logs" '{ "policy": {{ settings.policy | tojson(true) }} }' &
|
echo "Setting up so-soc-logs policy..."
|
||||||
throttle
|
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/so-soc-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }'
|
||||||
put_policy "{{ index }}-logs" "{{ index }}-logs" '{ "policy": {{ settings.policy | tojson(true) }} }' &
|
echo
|
||||||
|
echo
|
||||||
|
echo "Setting up {{ index }}-logs policy..."
|
||||||
|
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }'
|
||||||
|
echo
|
||||||
{%- else %}
|
{%- else %}
|
||||||
throttle
|
echo
|
||||||
put_policy "{{ index }}-logs" "{{ index }}-logs" '{ "policy": {{ settings.policy | tojson(true) }} }' &
|
echo "Setting up {{ index }}-logs policy..."
|
||||||
|
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }'
|
||||||
|
echo
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
echo
|
||||||
{%- if GLOBALS.role != "so-heavynode" %}
|
{%- if GLOBALS.role != "so-heavynode" %}
|
||||||
{%- for index, settings in ALL_ADDON_SETTINGS.items() %}
|
{%- for index, settings in ALL_ADDON_SETTINGS.items() %}
|
||||||
{%- if settings.policy is defined %}
|
{%- if settings.policy is defined %}
|
||||||
throttle
|
echo
|
||||||
put_policy "{{ index }}-logs" "{{ index }}-logs" '{ "policy": {{ settings.policy | tojson(true) }} }' &
|
echo "Setting up {{ index }}-logs policy..."
|
||||||
|
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }'
|
||||||
|
echo
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
wait
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||||
{% if sls.split('.')[0] in allowed_states %}
|
{% if sls.split('.')[0] in allowed_states %}
|
||||||
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
|
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
|
||||||
|
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %}
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
@@ -60,6 +61,19 @@ so-kibana:
|
|||||||
- watch:
|
- watch:
|
||||||
- file: kibanaconfig
|
- file: kibanaconfig
|
||||||
|
|
||||||
|
wait_for_so-kibana:
|
||||||
|
http.wait_for_successful_query:
|
||||||
|
- name: "http://localhost:5601/api/status"
|
||||||
|
- username: 'so_elastic'
|
||||||
|
- password: '{{ ELASTICSEARCHMERGED.auth.users.so_elastic_user.pass }}'
|
||||||
|
- ssl: True
|
||||||
|
- verify_ssl: False
|
||||||
|
- status: 200
|
||||||
|
- wait_for: 300
|
||||||
|
- request_interval: 15
|
||||||
|
- require:
|
||||||
|
- docker_container: so-kibana
|
||||||
|
|
||||||
delete_so-kibana_so-status.disabled:
|
delete_so-kibana_so-status.disabled:
|
||||||
file.uncomment:
|
file.uncomment:
|
||||||
- name: /opt/so/conf/so-status/so-status.conf
|
- name: /opt/so/conf/so-status/so-status.conf
|
||||||
|
|||||||
@@ -343,11 +343,10 @@ highstate() {
|
|||||||
masterlock() {
|
masterlock() {
|
||||||
echo "Locking Salt Master"
|
echo "Locking Salt Master"
|
||||||
mv -v $TOPFILE $BACKUPTOPFILE
|
mv -v $TOPFILE $BACKUPTOPFILE
|
||||||
# Render the real top file only for the host running soup; every other
|
echo "base:" > $TOPFILE
|
||||||
# minion gets an empty top (no states) while the master is upgrading.
|
echo " $MINIONID:" >> $TOPFILE
|
||||||
echo "{% if grains['id'] == '$MINIONID' %}" > $TOPFILE
|
echo " - ca" >> $TOPFILE
|
||||||
cat $BACKUPTOPFILE >> $TOPFILE
|
echo " - elasticsearch" >> $TOPFILE
|
||||||
echo "{% endif %}" >> $TOPFILE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
masterunlock() {
|
masterunlock() {
|
||||||
|
|||||||
Reference in New Issue
Block a user