131 lines
3.8 KiB
Bash
Executable File
131 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
YQ_IMAGE="mikefarah/yq:latest"
|
|
|
|
template_source=""
|
|
values_args=()
|
|
|
|
# --- Parse command line arguments ---
|
|
while [[ $# -gt 0 ]]; do
|
|
key="$1"
|
|
case $key in
|
|
--template)
|
|
template_source="$2"
|
|
shift # past argument
|
|
shift # past value
|
|
;;
|
|
--values)
|
|
# Collect all arguments after --values until next -- argument or end
|
|
shift # past --values
|
|
while [[ $# -gt 0 ]] && [[ ! "$1" =~ ^-- ]]; do
|
|
values_args+=("$1")
|
|
shift # past value argument
|
|
done
|
|
;;
|
|
*) # Unknown option
|
|
echo "Error: Unknown option $1" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# --- Get template content ---
|
|
current_yaml=""
|
|
if [[ -z "$template_source" ]]; then
|
|
# If no template provided, start with empty YAML
|
|
current_yaml="{}"
|
|
elif [[ "$template_source" =~ ^https?:// ]]; then
|
|
# Download from URL
|
|
# Use curl, exit if fails
|
|
if ! command -v curl &> /dev/null; then
|
|
echo "Error: curl command required to download URL template." >&2
|
|
exit 1
|
|
fi
|
|
template_content=$(curl -sfL "$template_source")
|
|
if [[ $? -ne 0 ]]; then
|
|
echo "Error: Failed to download template from URL: $template_source" >&2
|
|
exit 1
|
|
fi
|
|
# Check if downloaded content is empty
|
|
if [[ -z "$template_content" ]]; then
|
|
current_yaml="{}"
|
|
else
|
|
current_yaml="$template_content"
|
|
fi
|
|
|
|
elif [[ -f "$template_source" ]]; then
|
|
# Read from local file
|
|
current_yaml=$(cat "$template_source")
|
|
# Check if file content is empty
|
|
if [[ -z "$current_yaml" ]]; then
|
|
current_yaml="{}"
|
|
fi
|
|
else
|
|
# Invalid template source
|
|
echo "Error: Invalid template source '$template_source'. Please provide valid file path or HTTP/HTTPS URL." >&2
|
|
exit 1
|
|
fi
|
|
|
|
|
|
# --- Check if Docker is available ---
|
|
if ! command -v docker &> /dev/null; then
|
|
echo "Error: docker command required to run yq." >&2
|
|
exit 1
|
|
fi
|
|
# Try pulling or verifying yq image (helps catch issues early)
|
|
docker pull $YQ_IMAGE > /dev/null
|
|
|
|
# --- Apply values ---
|
|
if [[ ${#values_args[@]} -gt 0 ]]; then
|
|
for val_arg in "${values_args[@]}"; do
|
|
# Parse key=value
|
|
if [[ ! "$val_arg" =~ ^([^=]+)=(.*)$ ]]; then
|
|
continue
|
|
fi
|
|
|
|
# BASH_REMATCH is result array from =~ operator
|
|
yaml_path="${BASH_REMATCH[1]}"
|
|
raw_value="${BASH_REMATCH[2]}"
|
|
|
|
# Prepare yq value (try handling basic types, otherwise treat as string)
|
|
yq_value=""
|
|
if [[ "$raw_value" == "true" || "$raw_value" == "false" || "$raw_value" == "null" ]]; then
|
|
yq_value="$raw_value"
|
|
# Check if integer or float (simple regex)
|
|
elif [[ "$raw_value" =~ ^-?[0-9]+(\.[0-9]+)?$ ]]; then
|
|
# If value starts with 0 but isn't 0 itself and has no decimal point, force string to prevent octal interpretation
|
|
if [[ "$raw_value" =~ ^0[0-9]+$ ]]; then
|
|
# Need to escape internal double quotes
|
|
escaped_value=$(echo "$raw_value" | sed 's/"/\\"/g')
|
|
yq_value="\"$escaped_value\""
|
|
else
|
|
yq_value="$raw_value"
|
|
fi
|
|
else
|
|
# Treat as string, need to escape internal double quotes
|
|
escaped_value=$(echo "$raw_value" | sed 's/"/\\"/g')
|
|
yq_value="\"$escaped_value\""
|
|
fi
|
|
|
|
# Build yq expression
|
|
yq_expression=".$yaml_path = $yq_value"
|
|
|
|
# Apply update via docker run yq
|
|
# Pass current YAML via stdin to yq, get stdout as new YAML
|
|
# Use <<< for here-string input to avoid temp files
|
|
new_yaml=$(docker run --rm -i "$YQ_IMAGE" "$yq_expression" <<< "$current_yaml")
|
|
yq_exit_code=$?
|
|
|
|
if [[ $yq_exit_code -ne 0 ]]; then
|
|
echo "Error: yq execution failed (exit code: $yq_exit_code). Expression: '$yq_expression'" >&2
|
|
# Could output yq error message, but requires more complex docker run call to capture stderr
|
|
exit 1
|
|
fi
|
|
current_yaml="$new_yaml"
|
|
done
|
|
fi
|
|
|
|
# --- Output final result ---
|
|
printf "%s\n" "$current_yaml"
|
|
|
|
exit 0 |