From 48e992dd4170ef655296edb6b3c7aea92d6ebf36 Mon Sep 17 00:00:00 2001 From: oval Date: Tue, 7 Jul 2026 16:57:36 +0000 Subject: [PATCH] Add Dockerfile --- Dockerfile | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..447e9c5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,233 @@ +# ─────────────────────────────────────────────────────────── +# Ansible Control Node — Alpine-based, QEMU-bootable +# +# Dual-purpose image: +# 1. Run directly: docker run --rm -it ansible-node ansible-playbook ... +# 2. Convert to QEMU disk: scripts/build-qemu.sh extracts this rootfs +# into a bootable qcow2 for pc-q35-10.0 +# +# Integrations: +# • Windows — pywinrm + kerberos → WinRM +# • Cisco ASA — cisco.asa + paramiko → SSH/CLI +# • Cisco Catalyst— cisco.ios + paramiko → SSH/CLI +# • Cisco NX-OS — cisco.nxos + paramiko → SSH/NX-API +# • Linux — native SSH (built-in ansible) +# • VMware — pyvmomi → vCenter/ESXi SOAP API +# • MSSQL — pymssql → SQL Server TDS +# ─────────────────────────────────────────────────────────── + +FROM alpine:3.20 + +# ── System labels ────────────────────────────────────────── +LABEL org.opencontainers.image.title="Ansible Control Node" +LABEL org.opencontainers.image.description="Minimal Ansible control node for Windows, Cisco, VMware, MSSQL, and Linux targets. QEMU-bootable via build-qemu.sh." +LABEL org.opencontainers.image.authors="ansible_testing" + +# ── Kernel + base system ────────────────────────────── +# alpine-base = openrc + busybox + mdev + init scripts (no systemd) +# linux-virt = kernel optimized for VMs (virtio, no firmware) +# docker = container runtime for nested workloads +RUN apk add --no-cache \ + alpine-base \ + linux-virt \ + e2fsprogs \ + docker \ + docker-openrc \ + # ── Networking ──────────────────────────────────────── + dhcpcd \ + openssh-client \ + openssh-server \ + curl \ + wget \ + ca-certificates \ + bind-tools \ + # ── Kerberos (WinRM Kerberos auth to Windows) ──────── + krb5 \ + krb5-server \ + # ── FreeTDS (pymssql → MSSQL TDS protocol) ─────────── + freetds \ + freetds-dev \ + # ── Ansible + Python + SSH pw provider ─────────────── + ansible \ + sshpass \ + py3-pip \ + python3 \ + python3-dev \ + # ── Build deps for pip packages (purged after) ─────── + gcc \ + musl-dev \ + openssl-dev \ + krb5-dev \ + libffi-dev \ + # ── Quality-of-life ────────────────────────────────── + bash \ + bash-completion \ + vim \ + tmux \ + git \ + jq \ + less \ + sudo + +# ── Python packages for target integrations ────────────── +RUN pip3 install --no-cache-dir --break-system-packages \ + # Windows: WinRM + Kerberos + 'pywinrm[kerberos]>=0.4' \ + requests-kerberos \ + requests-ntlm \ + # Cisco: SSH/NETCONF/RESTCONF + paramiko>=2.7 \ + ncclient>=0.6 \ + netmiko>=4.0 \ + scp \ + # VMware: vCenter/ESXi SOAP API + pyvmomi>=8.0 \ + requests \ + # MSSQL: TDS protocol + pymssql>=2.2 \ + # General utilities (required by many Ansible modules) + jmespath>=1.0 \ + xmltodict>=0.13 \ + pyyaml>=6.0 \ + cryptography>=41.0 \ + packaging + +# ── Ansible collections for all target types ────────────── +RUN ansible-galaxy collection install \ + # Windows management + ansible.windows \ + # Network common (required by Cisco collections) + ansible.netcommon \ + ansible.utils \ + # Cisco ASA firewalls + cisco.asa \ + # Cisco Catalyst / IOS / IOS-XE switches & routers + cisco.ios \ + # Cisco Nexus / NX-OS data center switches + cisco.nxos \ + # VMware vCenter / ESXi + community.vmware \ + # MSSQL Server + community.general \ + community.mysql \ + microsoft.sql \ + # Crypto/certificates (needed for various modules) + community.crypto \ + # Generic collection with many useful modules + community.general + +# ── OpenRC: enable boot services ────────────────────────── +# sysinit — devices, logging, hardware +RUN rc-update add devfs sysinit && \ + rc-update add dmesg sysinit && \ + rc-update add mdev sysinit && \ + rc-update add hwdrivers sysinit +# boot — modules, networking, hostname (urandom handled by bootmisc) +RUN rc-update add modules boot && \ + rc-update add sysctl boot && \ + rc-update add bootmisc boot && \ + rc-update add hostname boot && \ + rc-update add networking boot +# default — SSH, DHCP, Docker daemon +RUN rc-update add sshd default && \ + rc-update add dhcpcd default && \ + rc-update add docker default + +# ── Serial console (ttyS0) for QEMU -nographic ──────────── +RUN echo 'ttyS0::respawn:/sbin/agetty -L 115200 ttyS0 xterm-256color' \ + >> /etc/inittab + +# ── Hostname (hosts managed by init/dhcpcd at boot) ──────── +RUN echo 'ansible-node' > /etc/hostname + +# ── SSH: allow root + ansible user ──────────────────────── +RUN ssh-keygen -A && \ + sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' \ + /etc/ssh/sshd_config && \ + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' \ + /etc/ssh/sshd_config && \ + echo 'UseDNS no' >> /etc/ssh/sshd_config + +# ── Users ───────────────────────────────────────────────── +# Root password (change on first boot!) +RUN echo 'root:ansible' | chpasswd + +# Ansible service user +RUN adduser -D ansible && \ + echo 'ansible:ansible' | chpasswd && \ + addgroup ansible wheel && \ + echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers + +# ── Docker: enable ansible user to run docker ───────────── +RUN addgroup ansible docker + +# ── Working directory ───────────────────────────────────── +RUN mkdir -p /ansible/playbooks /ansible/inventory && \ + chown -R ansible:ansible /ansible + +# ── Ansible config ──────────────────────────────────────── +RUN mkdir -p /etc/ansible && \ + printf '[defaults]\n\ +host_key_checking = False\n\ +stdout_callback = yaml\n\ +callback_whitelist = profile_tasks\n\ +retry_files_enabled = False\n\ +\n\ +[ssh_connection]\n\ +pipelining = True\n\ +control_path = /tmp/ansible-%%h-%%p-%%r' \ + > /etc/ansible/ansible.cfg + +# ── Default inventory (placeholder) ─────────────────────── +RUN printf '[windows]\n\ +# win-host.example.com\n\ +\n\ +[cisco_asa]\n\ +# asa-firewall.example.com\n\ +\n\ +[cisco_ios]\n\ +# catalyst-switch.example.com\n\ +\n\ +[cisco_nxos]\n\ +# nexus-switch.example.com\n\ +\n\ +[vmware]\n\ +# vcenter.example.com\n\ +\n\ +[mssql]\n\ +# sql-server.example.com\n\ +\n\ +[linux]\n\ +# debian-host.example.com\n\ +\n\ +[all:vars]\n\ +ansible_user=ansible\n' \ + > /etc/ansible/hosts + +# ── MOTD (friendly boot message) ────────────────────────── +RUN printf '\n\ +\e[1;32m╔════════════════════════════════════════════════╗\e[0m\n\ +\e[1;32m║ Ansible Control Node — Alpine Linux ║\e[0m\n\ +\e[1;32m╠════════════════════════════════════════════════╣\e[0m\n\ +\e[1;32m║ Windows • Cisco • VMware • MSSQL • Linux ║\e[0m\n\ +\e[1;32m╠════════════════════════════════════════════════╣\e[0m\n\ +\e[1;32m║ SSH: ssh ansible@ -p 22 ║\e[0m\n\ +\e[1;32m║ Dir: /ansible ║\e[0m\n\ +\e[1;32m╚════════════════════════════════════════════════╝\e[0m\n\ +' > /etc/motd + +# ── First-boot: expand rootfs to fill disk, gen SSH keys ─ +RUN printf '#!/bin/sh\n\ +# Expand root filesystem to fill the underlying disk\n\ +ROOTDEV=$(findmnt -n -o SOURCE / 2>/dev/null || echo /dev/vda)\n\ +resize2fs "$ROOTDEV" 2>/dev/null || true\n\ +# Re-generate SSH host keys if running from a cloned image\n\ +if [ ! -f /etc/ssh/.host-keys-generated ]; then\n\ + ssh-keygen -A && touch /etc/ssh/.host-keys-generated\n\ +fi\n' \ + > /etc/local.d/00-first-boot.start && \ + chmod +x /etc/local.d/00-first-boot.start && \ + rc-update add local default + +WORKDIR /ansible +CMD ["/sbin/init"]