--- - 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