211 lines
5.4 KiB
Python
211 lines
5.4 KiB
Python
#!/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()
|