Files
docker-elk/setup/lib.sh
Antoine Cotten 2dc9e53ec2 fix(setup): Set curl --resolve flag conditionally
curl 8.x no longer treats CURLOPT_RESOLVE parse failures as a warning.
Because 'elasticsearch' is not an IP address, using it as the ADDR
segment in the --resolve flag is illegal.

In 7.x, curl would print a warning but fall back to the hostname in the
URL, as if --resolve had not been set.

This issue went under the radar because:

1. curl 8.x is used in Elastic v8 images (Ubuntu base[1]), whereas our
   default Elastic v9 images still ship with curl 7.x (RHEL base[2]).
2. The warning was not printed due to the usage of the -s flag.

Fixes #1137

[1]: https://github.com/elastic/elasticsearch/blob/v8.19.8/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java#L16
[2]: https://github.com/elastic/elasticsearch/blob/v9.2.2/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java#L17
2025-12-21 10:54:53 +01:00

235 lines
4.7 KiB
Bash

#!/usr/bin/env bash
es_ca_cert="${BASH_SOURCE[0]%/*}"/ca.crt
# Log a message.
function log {
echo "[+] $1"
}
# Log a message at a sub-level.
function sublog {
echo "$1"
}
# Log an error.
function err {
echo "[x] $1" >&2
}
# Log an error at a sub-level.
function suberr {
echo "$1" >&2
}
# Inject common arguments to curl commands based on the environment.
function augment_curl_args {
local args_var_name=$1
local -n args_ref="${args_var_name}"
if [[ -n "${ELASTIC_PASSWORD:-}" ]]; then
args_ref+=( '-u' "elastic:${ELASTIC_PASSWORD}" )
fi
if [[ -n "${ELASTICSEARCH_ADDR:-}" ]]; then
args_ref+=( '--resolve' "elasticsearch:9200:${ELASTICSEARCH_ADDR}" )
fi
}
# Poll the 'elasticsearch' service until it responds with HTTP code 200.
function wait_for_elasticsearch {
local -a args=( '-s' '-D-' '-m15' '-w' '%{http_code}' 'https://elasticsearch:9200/' '--cacert' "$es_ca_cert" )
augment_curl_args args
local -i result=1
local output
# retry for max 300s (60*5s)
for _ in $(seq 1 60); do
local -i exit_code=0
output="$(curl "${args[@]}")" || exit_code=$?
if ((exit_code)); then
result=$exit_code
fi
if [[ "${output: -3}" -eq 200 ]]; then
result=0
break
fi
sleep 5
done
if ((result)) && [[ "${output: -3}" -ne 000 ]]; then
echo -e "\n${output::-3}"
fi
return $result
}
# Poll the Elasticsearch users API until it returns users.
function wait_for_builtin_users {
local -a args=( '-s' '-D-' '-m15' 'https://elasticsearch:9200/_security/user?pretty' '--cacert' "$es_ca_cert" )
augment_curl_args args
local -i result=1
local line
local -i exit_code
local -i num_users
# retry for max 30s (30*1s)
for _ in $(seq 1 30); do
num_users=0
# read exits with a non-zero code if the last read input doesn't end
# with a newline character. The printf without newline that follows the
# curl command ensures that the final input not only contains curl's
# exit code, but causes read to fail so we can capture the return value.
# Ref. https://unix.stackexchange.com/a/176703/152409
while IFS= read -r line || ! exit_code="$line"; do
if [[ "$line" =~ _reserved.+true ]]; then
(( num_users++ ))
fi
done < <(curl "${args[@]}"; printf '%s' "$?")
if ((exit_code)); then
result=$exit_code
fi
# we expect more than just the 'elastic' user in the result
if (( num_users > 1 )); then
result=0
break
fi
sleep 1
done
return $result
}
# Verify that the given Elasticsearch user exists.
function check_user_exists {
local username=$1
local -a args=( '-s' '-D-' '-m15' '-w' '%{http_code}'
"https://elasticsearch:9200/_security/user/${username}"
'--cacert' "$es_ca_cert"
)
augment_curl_args args
local -i result=1
local -i exists=0
local output
output="$(curl "${args[@]}")"
if [[ "${output: -3}" -eq 200 || "${output: -3}" -eq 404 ]]; then
result=0
fi
if [[ "${output: -3}" -eq 200 ]]; then
exists=1
fi
if ((result)); then
echo -e "\n${output::-3}"
else
echo "$exists"
fi
return $result
}
# Set password of a given Elasticsearch user.
function set_user_password {
local username=$1
local password=$2
local -a args=( '-s' '-D-' '-m15' '-w' '%{http_code}'
"https://elasticsearch:9200/_security/user/${username}/_password"
'--cacert' "$es_ca_cert"
'-X' 'POST'
'-H' 'Content-Type: application/json'
'-d' "{\"password\" : \"${password}\"}"
)
augment_curl_args args
local -i result=1
local output
output="$(curl "${args[@]}")"
if [[ "${output: -3}" -eq 200 ]]; then
result=0
fi
if ((result)); then
echo -e "\n${output::-3}\n"
fi
return $result
}
# Create the given Elasticsearch user.
function create_user {
local username=$1
local password=$2
local role=$3
local -a args=( '-s' '-D-' '-m15' '-w' '%{http_code}'
"https://elasticsearch:9200/_security/user/${username}"
'--cacert' "$es_ca_cert"
'-X' 'POST'
'-H' 'Content-Type: application/json'
'-d' "{\"password\":\"${password}\",\"roles\":[\"${role}\"]}"
)
augment_curl_args args
local -i result=1
local output
output="$(curl "${args[@]}")"
if [[ "${output: -3}" -eq 200 ]]; then
result=0
fi
if ((result)); then
echo -e "\n${output::-3}\n"
fi
return $result
}
# Ensure that the given Elasticsearch role is up-to-date, create it if required.
function ensure_role {
local name=$1
local body=$2
local -a args=( '-s' '-D-' '-m15' '-w' '%{http_code}'
"https://elasticsearch:9200/_security/role/${name}"
'--cacert' "$es_ca_cert"
'-X' 'POST'
'-H' 'Content-Type: application/json'
'-d' "$body"
)
augment_curl_args args
local -i result=1
local output
output="$(curl "${args[@]}")"
if [[ "${output: -3}" -eq 200 ]]; then
result=0
fi
if ((result)); then
echo -e "\n${output::-3}\n"
fi
return $result
}