fix(delivery): address review feedback on idempotency, crash recovery, and security

- Idempotency: verify RequestedBy matches caller to prevent cross-user key reuse
- Crash recovery: persist ExecutionJob (launching) before AWX Launch, update to running after
- Terminal state: finish ExecutionJob on success/cancel/failure; failTask accepts canceling
- Reservation TTL: filter expired reservations in quota aggregation
- Ansible heredoc: use <<'EOF' to prevent shell expansion of secrets; escape single quotes
- Validation: align Go resource ranges with playbook (mem 1024-4096, storage 10-100)
- Version whitelist: only allow 8.0, pass mysql_version to AWX extra_vars; playbook selects package via map

Relates-to: #97
This commit is contained in:
mac
2026-07-23 14:29:32 +08:00
parent b34ebcea83
commit f91df3be3d
3 changed files with 71 additions and 22 deletions
+19 -11
View File
@@ -6,6 +6,10 @@
any_errors_fatal: true
vars:
mysql_instance: "{{ instance_name }}"
mysql_version_value: "{{ mysql_version | default('8.0') }}"
mysql_package_map:
"8.0": "mysql-server=8.0.46-0ubuntu0.24.04.3"
mysql_package_name: "{{ mysql_package_map[mysql_version_value] }}"
mysql_port_value: "{{ mysql_port | default(3307) | int }}"
mysql_memory_mb_value: "{{ memory_mb | default(2048) | int }}"
mysql_storage_gb_value: "{{ storage_gb | default(20) | int }}"
@@ -22,6 +26,7 @@
that:
- topology == 'standalone'
- mysql_instance is match('^[a-z0-9][a-z0-9-]{0,62}$')
- mysql_version_value in mysql_package_map
- (mysql_port_value | int) >= 1024
- (mysql_port_value | int) <= 65535
- (mysql_memory_mb_value | int) >= 1024
@@ -73,7 +78,7 @@
- name: Install Ubuntu MySQL package
ansible.builtin.apt:
name: mysql-server=8.0.46-0ubuntu0.24.04.3
name: "{{ mysql_package_name }}"
state: present
update_cache: true
cache_valid_time: 3600
@@ -191,25 +196,28 @@
ansible.builtin.shell: |
set -euo pipefail
client_file="$(mktemp)"
trap 'rm -f "$client_file"' EXIT
chmod 600 "$client_file"
cat >"$client_file" <<EOF
sql_file="$(mktemp)"
trap 'rm -f "$client_file" "$sql_file"' EXIT
chmod 600 "$client_file" "$sql_file"
cat >"$client_file" <<'EOF'
[client]
user=root
password={{ mysql_root_password_value }}
socket={{ mysql_run_dir }}/mysql.sock
EOF
if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then
/usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <<'SQL'
ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password_value }}';
SQL
cat >"$sql_file" <<'EOF'
ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
EOF
/usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file"
fi
/usr/bin/mysql --defaults-extra-file="$client_file" <<'SQL'
CREATE USER IF NOT EXISTS 'xinfra_admin'@'%' IDENTIFIED BY '{{ mysql_admin_password_value }}';
ALTER USER 'xinfra_admin'@'%' IDENTIFIED BY '{{ mysql_admin_password_value }}';
cat >"$sql_file" <<'EOF'
CREATE USER IF NOT EXISTS 'xinfra_admin'@'%' IDENTIFIED BY '{{ mysql_admin_password_value | replace("'", "''") }}';
ALTER USER 'xinfra_admin'@'%' IDENTIFIED BY '{{ mysql_admin_password_value | replace("'", "''") }}';
GRANT ALL PRIVILEGES ON *.* TO 'xinfra_admin'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
SQL
EOF
/usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file"
args:
executable: /bin/bash
changed_when: false