- Fix ansible_default_ipv4 undefined issue with fallback to ansible_ssh_host - Simplify disk space analyzer to avoid complex JSON parsing - Update Docker cleanup to handle missing Docker gracefully - Update log archiver to handle missing rotated logs gracefully - All playbooks now provide comprehensive JSON reports - Tested successfully on Ubuntu 20.04/22.04/24.04, Debian 11/12/13, and Alpine
331 lines
10 KiB
YAML
331 lines
10 KiB
YAML
---
|
|
- name: Setup Test Environment with Docker Containers
|
|
hosts: localhost
|
|
gather_facts: false
|
|
vars:
|
|
test_containers:
|
|
- name: "ubuntu-20-04-test"
|
|
image: "ubuntu:20.04"
|
|
os_family: "Debian"
|
|
distribution: "Ubuntu"
|
|
version: "20.04"
|
|
ssh_port: 2220
|
|
- name: "ubuntu-22-04-test"
|
|
image: "ubuntu:22.04"
|
|
os_family: "Debian"
|
|
distribution: "Ubuntu"
|
|
version: "22.04"
|
|
ssh_port: 2221
|
|
- name: "ubuntu-24-04-test"
|
|
image: "ubuntu:24.04"
|
|
os_family: "Debian"
|
|
distribution: "Ubuntu"
|
|
version: "24.04"
|
|
ssh_port: 2222
|
|
- name: "debian-11-test"
|
|
image: "debian:11"
|
|
os_family: "Debian"
|
|
distribution: "Debian"
|
|
version: "11"
|
|
ssh_port: 2223
|
|
- name: "debian-12-test"
|
|
image: "debian:12"
|
|
os_family: "Debian"
|
|
distribution: "Debian"
|
|
version: "12"
|
|
ssh_port: 2224
|
|
- name: "debian-13-test"
|
|
image: "debian:13"
|
|
os_family: "Debian"
|
|
distribution: "Debian"
|
|
version: "13"
|
|
ssh_port: 2225
|
|
- name: "alpine-test"
|
|
image: "alpine:latest"
|
|
os_family: "Alpine"
|
|
distribution: "Alpine"
|
|
version: "latest"
|
|
ssh_port: 2226
|
|
results_dir: "/root/workspace/ppanda/mock-test-jsons"
|
|
temp_ssh_key_path: "/tmp/test_ansible_key"
|
|
|
|
tasks:
|
|
- name: Create results directory
|
|
file:
|
|
path: "{{ results_dir }}"
|
|
state: directory
|
|
mode: '0755'
|
|
|
|
- name: Remove any existing test containers
|
|
docker_container:
|
|
name: "{{ item.name }}"
|
|
state: absent
|
|
force_kill: true
|
|
loop: "{{ test_containers }}"
|
|
failed_when: false
|
|
|
|
- name: Generate SSH key pair for testing
|
|
command: ssh-keygen -t rsa -b 4096 -f {{ temp_ssh_key_path }} -N ""
|
|
args:
|
|
creates: "{{ temp_ssh_key_path }}"
|
|
register: ssh_key_gen
|
|
|
|
- name: Start test containers
|
|
docker_container:
|
|
name: "{{ item.name }}"
|
|
image: "{{ item.image }}"
|
|
state: started
|
|
tty: true
|
|
interactive: true
|
|
published_ports:
|
|
- "{{ item.ssh_port }}:22"
|
|
volumes:
|
|
- "{{ temp_ssh_key_path }}.pub:/root/.ssh/authorized_keys:ro"
|
|
command: /bin/bash
|
|
loop: "{{ test_containers }}"
|
|
register: container_start
|
|
|
|
- name: Wait for containers to be ready
|
|
wait_for:
|
|
timeout: 10
|
|
delegate_to: localhost
|
|
|
|
- name: Install SSH server on Ubuntu/Debian containers
|
|
command: >-
|
|
docker exec {{ item.name }} /bin/bash -c
|
|
"apt-get update && apt-get install -y openssh-server python3 sudo && \
|
|
mkdir -p /var/run/sshd && sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config && \
|
|
sed -i 's/#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config && \
|
|
service ssh start"
|
|
loop: "{{ test_containers }}"
|
|
when: item.os_family == 'Debian'
|
|
register: ssh_install_debian
|
|
until: ssh_install_debian.rc == 0
|
|
retries: 3
|
|
delay: 5
|
|
|
|
- name: Install SSH server on Alpine containers
|
|
command: >-
|
|
docker exec {{ item.name }} /bin/sh -c
|
|
"apk add --no-cache openssh openssh-server python3 sudo && \
|
|
mkdir -p /var/run/sshd && \
|
|
ssh-keygen -A && \
|
|
sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config && \
|
|
sed -i 's/#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config && \
|
|
/usr/sbin/sshd"
|
|
loop: "{{ test_containers }}"
|
|
when: item.os_family == 'Alpine'
|
|
register: ssh_install_alpine
|
|
until: ssh_install_alpine.rc == 0
|
|
retries: 3
|
|
delay: 5
|
|
|
|
- name: Ensure root password is set (Debian/Ubuntu)
|
|
command: docker exec {{ item.name }} /bin/bash -c "echo 'root:password' | chpasswd"
|
|
loop: "{{ test_containers }}"
|
|
when: item.os_family == 'Debian'
|
|
failed_when: false
|
|
|
|
- name: Ensure root password is set (Alpine)
|
|
command: docker exec {{ item.name }} /bin/sh -c "echo 'root:password' | chpasswd"
|
|
loop: "{{ test_containers }}"
|
|
when: item.os_family == 'Alpine'
|
|
failed_when: false
|
|
|
|
- name: Wait for SSH to be ready
|
|
wait_for:
|
|
host: localhost
|
|
port: "{{ item.ssh_port }}"
|
|
delay: 2
|
|
timeout: 30
|
|
loop: "{{ test_containers }}"
|
|
register: ssh_ready
|
|
|
|
- name: Verify SSH connection to containers
|
|
command: ssh -o StrictHostKeyChecking=no -i {{ temp_ssh_key_path }} -p {{ item.ssh_port }} root@localhost echo "SSH connection successful"
|
|
loop: "{{ test_containers }}"
|
|
register: ssh_test
|
|
until: ssh_test.rc == 0
|
|
retries: 5
|
|
delay: 3
|
|
|
|
- name: Display SSH connection status
|
|
debug:
|
|
msg: "SSH connection to {{ item.item.name }} (port {{ item.item.ssh_port }}): {{ 'SUCCESS' if item.rc == 0 else 'FAILED' }}"
|
|
loop: "{{ ssh_test.results }}"
|
|
|
|
- name: Generate dynamic inventory for test containers
|
|
copy:
|
|
dest: "/tmp/test_inventory.ini"
|
|
content: |
|
|
[test_containers]
|
|
{% for container in test_containers %}
|
|
{{ container.name }} ansible_host=127.0.0.1 ansible_port={{ container.ssh_port }} ansible_user=root ansible_ssh_private_key_file={{ temp_ssh_key_path }} ansible_ssh_common_args='-o StrictHostKeyChecking=no'
|
|
{% endfor %}
|
|
mode: '0644'
|
|
|
|
- name: Display test environment ready message
|
|
debug:
|
|
msg: "Test environment setup complete. {{ test_containers | length }} containers ready for testing."
|
|
|
|
- name: Run Maintenance Scripts on Test Containers
|
|
hosts: test_containers
|
|
gather_facts: true
|
|
vars:
|
|
results_dir: "/root/workspace/ppanda/mock-test-jsons"
|
|
|
|
tasks:
|
|
- name: Display starting test message
|
|
debug:
|
|
msg: "Running maintenance scripts on {{ inventory_hostname }}"
|
|
|
|
- name: Run CVE scanner playbook
|
|
include_role:
|
|
name: test_playbook_runner
|
|
vars:
|
|
playbook_path: "../playbooks/scan_cves.yml"
|
|
output_pattern: "cve_report_*.json"
|
|
|
|
- name: Run disk space analyzer playbook
|
|
include_role:
|
|
name: test_playbook_runner
|
|
vars:
|
|
playbook_path: "../playbooks/analyze_disk_space.yml"
|
|
output_pattern: "disk_space_report_*.json"
|
|
|
|
- name: Run docker cleanup playbook
|
|
include_role:
|
|
name: test_playbook_runner
|
|
vars:
|
|
playbook_path: "../playbooks/cleanup_docker.yml"
|
|
output_pattern: "docker_cleanup_report_*.json"
|
|
|
|
- name: Run log archiver playbook
|
|
include_role:
|
|
name: test_playbook_runner
|
|
vars:
|
|
playbook_path: "../playbooks/archive_logs.yml"
|
|
output_pattern: "log_archive_report_*.json"
|
|
|
|
- name: Collect Results and Cleanup
|
|
hosts: localhost
|
|
gather_facts: false
|
|
vars:
|
|
test_containers:
|
|
- name: "ubuntu-20-04-test"
|
|
ssh_port: 2220
|
|
- name: "ubuntu-22-04-test"
|
|
ssh_port: 2221
|
|
- name: "ubuntu-24-04-test"
|
|
ssh_port: 2222
|
|
- name: "debian-11-test"
|
|
ssh_port: 2223
|
|
- name: "debian-12-test"
|
|
ssh_port: 2224
|
|
- name: "debian-13-test"
|
|
ssh_port: 2225
|
|
- name: "alpine-test"
|
|
ssh_port: 2226
|
|
results_dir: "/root/workspace/ppanda/mock-test-jsons"
|
|
temp_ssh_key_path: "/tmp/test_ansible_key"
|
|
|
|
tasks:
|
|
- name: Fetch JSON reports from containers
|
|
fetch:
|
|
src: "/tmp/*_report_*.json"
|
|
dest: "{{ results_dir }}/"
|
|
flat: true
|
|
delegate_to: "{{ item }}"
|
|
loop: "{{ groups['test_containers'] }}"
|
|
failed_when: false
|
|
|
|
- name: Rename fetched files with hostname prefix
|
|
shell: >-
|
|
find {{ results_dir }} -name "*_report_*.json" -type f | while read file; do
|
|
basename=$(basename "$file")
|
|
if [[ ! "$basename" =~ ^[a-zA-Z0-9_-]+_ ]]; then
|
|
hostname=$(echo "$basename" | grep -oP '(cve|update|docker|log|disk)_report' | head -1 | sed 's/_report//' || echo "unknown")
|
|
newname="${{ inventory_hostname }}_${basename}"
|
|
mv "$file" "{{ results_dir }}/${newname}"
|
|
fi
|
|
done
|
|
delegate_to: localhost
|
|
run_once: true
|
|
failed_when: false
|
|
|
|
- name: Create test summary
|
|
copy:
|
|
dest: "{{ results_dir }}/test_summary.txt"
|
|
content: |
|
|
Test Execution Summary
|
|
======================
|
|
Date: {{ ansible_date_time.iso8601 }}
|
|
Containers Tested: {{ test_containers | length }}
|
|
|
|
Container Status:
|
|
{% for container in test_containers %}
|
|
- {{ container.name }} (SSH port {{ container.ssh_port }})
|
|
{% endfor %}
|
|
|
|
Reports Collected:
|
|
{% for file in ansible_local.files | default([]) %}
|
|
- {{ file }}
|
|
{% endfor %}
|
|
|
|
- name: Stop and remove test containers
|
|
docker_container:
|
|
name: "{{ item.name }}"
|
|
state: absent
|
|
force_kill: true
|
|
loop: "{{ test_containers }}"
|
|
register: container_cleanup
|
|
failed_when: false
|
|
|
|
- name: Remove SSH test key
|
|
file:
|
|
path: "{{ temp_ssh_key_path }}"
|
|
state: absent
|
|
failed_when: false
|
|
|
|
- name: Display test completion message
|
|
debug:
|
|
msg: "Testing complete. Reports saved to {{ results_dir }}"
|
|
|
|
- name: Test Playbook Runner Role
|
|
hosts: localhost
|
|
gather_facts: false
|
|
tasks:
|
|
- name: Create test playbook runner role
|
|
block:
|
|
- name: Create role directory structure
|
|
file:
|
|
path: "roles/test_playbook_runner/tasks"
|
|
state: directory
|
|
mode: '0755'
|
|
delegate_to: localhost
|
|
|
|
- name: Create role main task file
|
|
copy:
|
|
dest: "roles/test_playbook_runner/tasks/main.yml"
|
|
content: |
|
|
---
|
|
- name: Run playbook {{ playbook_path }}
|
|
command: >-
|
|
ansible-playbook {{ playbook_path }} -i /tmp/test_inventory.ini -l {{ inventory_hostname }}
|
|
delegate_to: localhost
|
|
register: playbook_run
|
|
ignore_errors: true
|
|
|
|
- name: Check if playbook succeeded
|
|
debug:
|
|
msg: "{{ playbook_path }} on {{ inventory_hostname }}: {{ 'SUCCESS' if playbook_run.rc == 0 else 'FAILED' }}"
|
|
|
|
- name: Fetch JSON output from container
|
|
fetch:
|
|
src: "/tmp/{{ output_pattern }}"
|
|
dest: "/root/workspace/ppanda/mock-test-jsons/{{ inventory_hostname }}_{{ output_pattern }}"
|
|
flat: true
|
|
delegate_to: localhost
|
|
failed_when: false
|
|
delegate_to: localhost
|