#!/usr/bin/env python3 """ Setup Ansible roles for Asustor NAS Creates all necessary files for node_exporter and SSH key exchange """ import os from pathlib import Path BASE_DIR = Path.home() / "git.repos/myansible" STRUCTURE = { # Inventory update "inventory/host_vars/asustor-lan1.yml": """--- ansible_python_interpreter: /usr/bin/python3 ansible_ssh_common_args: '-o StrictHostKeyChecking=no' node_exporter_version: "1.7.0" node_exporter_port: 9100 """, # Role: asustor.ssh_keys "roles/asustor.ssh_keys/defaults/main.yml": """--- ssh_key_file: ~/.ssh/id_rsa_ansible.pub """, "roles/asustor.ssh_keys/tasks/main.yml": """--- - name: Ensure .ssh directory exists file: path: "~/.ssh" state: directory mode: '0700' - name: Copy SSH public key authorized_key: user: "{{ ansible_user }}" key: "{{ lookup('file', ssh_key_file) }}" state: present """, # Role: asustor.node_exporter "roles/asustor.node_exporter/defaults/main.yml": """--- node_exporter_version: "1.7.0" node_exporter_port: 9100 node_exporter_install_dir: /usr/local/bin node_exporter_arch: "amd64" """, "roles/asustor.node_exporter/tasks/main.yml": """--- - name: Check if node_exporter exists stat: path: "{{ node_exporter_install_dir }}/node_exporter" register: node_exporter_bin - name: Download node_exporter get_url: url: "https://github.com/prometheus/node_exporter/releases/download/v{{ node_exporter_version }}/node_exporter-{{ node_exporter_version }}.linux-{{ node_exporter_arch }}.tar.gz" dest: /tmp/node_exporter.tar.gz when: not node_exporter_bin.stat.exists - name: Extract node_exporter unarchive: src: /tmp/node_exporter.tar.gz dest: /tmp/ remote_src: yes when: not node_exporter_bin.stat.exists - name: Copy node_exporter binary copy: src: "/tmp/node_exporter-{{ node_exporter_version }}.linux-{{ node_exporter_arch }}/node_exporter" dest: "{{ node_exporter_install_dir }}/node_exporter" mode: '0755' remote_src: yes when: not node_exporter_bin.stat.exists - name: Create startup script template: src: node_exporter_start.sh.j2 dest: /usr/local/etc/init.d/node_exporter.sh mode: '0755' ignore_errors: yes - name: Kill existing node_exporter shell: pkill -f node_exporter || true ignore_errors: yes - name: Start node_exporter shell: | nohup {{ node_exporter_install_dir }}/node_exporter --web.listen-address=":{{ node_exporter_port }}" > /var/log/node_exporter.log 2>&1 & async: 10 poll: 0 - name: Wait for node_exporter to start wait_for: port: "{{ node_exporter_port }}" timeout: 30 """, "roles/asustor.node_exporter/templates/node_exporter_start.sh.j2": """#!/bin/sh # Node Exporter startup script for Asustor NAS case "$1" in start) echo "Starting node_exporter..." nohup {{ node_exporter_install_dir }}/node_exporter --web.listen-address=":{{ node_exporter_port }}" > /var/log/node_exporter.log 2>&1 & ;; stop) echo "Stopping node_exporter..." pkill -f node_exporter ;; restart) $0 stop sleep 2 $0 start ;; status) pgrep -f node_exporter && echo "Running" || echo "Stopped" ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 esac """, # Playbook "playbooks/asustor.yml": """--- - name: Configure Asustor NAS hosts: asustor gather_facts: no pre_tasks: - name: Test connection ping: roles: - asustor.ssh_keys - asustor.node_exporter post_tasks: - name: Verify node_exporter uri: url: "http://{{ inventory_hostname }}:{{ node_exporter_port }}/metrics" return_content: no delegate_to: localhost register: result failed_when: false - name: Report status debug: msg: "node_exporter is {{ 'running' if result.status == 200 else 'NOT running' }}" """, } # Update hosts.yml - dodaj sekcję asustor jeśli nie istnieje HOSTS_ADDITION = """ asustor: hosts: asustor-lan1: ansible_host: 192.168.1.10 ansible_port: 8883 ansible_user: admin ansible_ssh_private_key_file: ~/.ssh/id_rsa_ansible """ def main(): print(f"Creating Ansible structure in: {BASE_DIR}\n") # Create all files for filepath, content in STRUCTURE.items(): full_path = BASE_DIR / filepath full_path.parent.mkdir(parents=True, exist_ok=True) if full_path.exists(): print(f" [SKIP] {filepath} (already exists)") else: full_path.write_text(content.lstrip()) print(f" [CREATE] {filepath}") # Check hosts.yml for asustor section hosts_file = BASE_DIR / "inventory/hosts.yml" if hosts_file.exists(): content = hosts_file.read_text() if "asustor:" not in content or "ansible_port: 8883" not in content: print(f"\n [INFO] Add this to {hosts_file} under 'all:children:':") print(HOSTS_ADDITION) print("\n" + "="*60) print("DONE! Next steps:") print("="*60) print(""" 1. First, fix SSH connection to Asustor: ssh -vvv -p 8883 admin@asustor-lan1 2. If SSH works, copy the key manually: ssh-copy-id -p 8883 -i ~/.ssh/id_rsa_ansible.pub admin@asustor-lan1 3. Test Ansible connection: cd ~/git.repos/myansible ansible asustor -m ping 4. Run the playbook: ansible-playbook playbooks/asustor.yml -v 5. Verify node_exporter: curl http://asustor-lan1:9100/metrics | head """) if __name__ == "__main__": main()