diff --git a/salt/elasticfleet/enabled.sls b/salt/elasticfleet/enabled.sls index af5e552eb..26738b688 100644 --- a/salt/elasticfleet/enabled.sls +++ b/salt/elasticfleet/enabled.sls @@ -142,6 +142,10 @@ so-elastic-agent-grid-upgrade: cmd.run: - name: /usr/sbin/so-elastic-agent-grid-upgrade - retry: True + +so-elastic-fleet-integration-upgrade: + cmd.run: + - name: /usr/sbin/so-elastic-fleet-integration-upgrade {% endif %} delete_so-elastic-fleet_so-status.disabled: diff --git a/salt/elasticfleet/tools/sbin/so-elastic-fleet-common b/salt/elasticfleet/tools/sbin/so-elastic-fleet-common index 48ff3518a..fadf18b5f 100644 --- a/salt/elasticfleet/tools/sbin/so-elastic-fleet-common +++ b/salt/elasticfleet/tools/sbin/so-elastic-fleet-common @@ -102,6 +102,62 @@ elastic_fleet_package_is_installed() { curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET -H 'kbn-xsrf: true' "localhost:5601/api/fleet/epm/packages/$PACKAGE" | jq -r '.item.status' } +elastic_fleet_agent_policy_names() { + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies" | jq -r .items[].name + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve agent policies." + exit 1 + fi +} + +elastic_fleet_integration_policy_names() { + AGENT_POLICY=$1 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies/$AGENT_POLICY" | jq -r .item.package_policies[].name + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve integrations for '$AGENT_POLICY'." + exit 1 + fi +} + +elastic_fleet_integration_policy_package_name() { + AGENT_POLICY=$1 + INTEGRATION=$2 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies/$AGENT_POLICY" | jq -r --arg INTEGRATION "$INTEGRATION" '.item.package_policies[] | select(.name==$INTEGRATION)| .package.name' + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve package name for '$INTEGRATION' in '$AGENT_POLICY'." + exit 1 + fi +} + +elastic_fleet_integration_policy_package_version() { + AGENT_POLICY=$1 + INTEGRATION=$2 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies/$AGENT_POLICY" | jq -r --arg INTEGRATION "$INTEGRATION" '.item.package_policies[] | select(.name==$INTEGRATION)| .package.version' + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve package version for '$INTEGRATION' in '$AGENT_POLICY'." + exit 1 + fi +} + +elastic_fleet_integration_id() { + AGENT_POLICY=$1 + INTEGRATION=$2 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies/$AGENT_POLICY" | jq -r --arg INTEGRATION "$INTEGRATION" '.item.package_policies[] | select(.name==$INTEGRATION)| .id' + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve integration ID for '$INTEGRATION' in '$AGENT_POLICY'." + exit 1 + fi +} + +elastic_fleet_integration_policy_dryrun_upgrade() { + INTEGRATION_ID=$1 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -H "Content-Type: application/json" -H 'kbn-xsrf: true' -L -X POST "localhost:5601/api/fleet/package_policies/upgrade/dryrun" -d "{\"packagePolicyIds\":[\"$INTEGRATION_ID\"]}" + if [ $? -ne 0 ]; then + echo "Error: Failed to complete dry run for '$INTEGRATION_ID'." + exit 1 + fi +} + elastic_fleet_policy_create() { NAME=$1 diff --git a/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-upgrade b/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-upgrade new file mode 100644 index 000000000..bdf93bad3 --- /dev/null +++ b/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-upgrade @@ -0,0 +1,62 @@ +#!/bin/bash +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +. /usr/sbin/so-elastic-fleet-common + +curl_output=$(curl -s -K /opt/so/conf/elasticsearch/curl.config -c - -X GET http://localhost:5601/) +if [ $? -ne 0 ]; then + echo "Error: Failed to connect to Kibana." + exit 1 +fi + +IFS=$'\n' +agent_policies=$(elastic_fleet_agent_policy_names) +if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve agent policies." + exit 1 +fi + +for AGENT_POLICY in $agent_policies; do + integrations=$(elastic_fleet_integration_policy_names "$AGENT_POLICY") + for INTEGRATION in $integrations; do + if ! [[ "$INTEGRATION" == "elastic-defend-endpoints" ]] && ! [[ "$INTEGRATION" == "fleet_server-"* ]]; then + # Get package name so we know what package to look for when checking the current and latest available version + PACKAGE_NAME=$(elastic_fleet_integration_policy_package_name "$AGENT_POLICY" "$INTEGRATION") + + # Get currently installed version of package + PACKAGE_VERSION=$(elastic_fleet_integration_policy_package_version "$AGENT_POLICY" "$INTEGRATION") + + # Get latest available version of package + AVAILABLE_VERSION=$(elastic_fleet_package_latest_version_check "$PACKAGE_NAME") + + # Get integration ID + INTEGRATION_ID=$(elastic_fleet_integration_id "$AGENT_POLICY" "$INTEGRATION") + + if [[ "$PACKAGE_VERSION" != "$AVAILABLE_VERSION" ]]; then + # Dry run of the upgrade + echo "Current $PACKAGE_NAME package version ($PACKAGE_VERSION) is not the same as the latest available package ($AVAILABLE_VERSION)..." + echo "Upgrading $INTEGRATION..." + echo "Starting dry run..." + DRYRUN_OUTPUT=$(elastic_fleet_integration_policy_dryrun_upgrade "$INTEGRATION_ID") + DRYRUN_ERRORS=$(echo "$DRYRUN_OUTPUT" | jq .[].hasErrors) + + # If no errors with dry run, proceed with actual upgrade + if [[ "$DRYRUN_ERRORS" == "false" ]]; then + echo "No errors detected. Proceeding with upgrade..." + elastic_fleet_integration_policy_upgrade "$INTEGRATION_ID" + if [ $? -ne 0 ]; then + echo "Error: Upgrade failed for integration ID '$INTEGRATION_ID'." + exit 1 + fi + else + echo "Errors detected during dry run. Stopping upgrade..." + exit 1 + fi + fi + fi + done +done +echo