Führen Sie Ansible über Python mithilfe der API aus

zunaechst

Ansible ist praktisch, nicht wahr? Wenn ich auf vielen Servern die gleiche Arbeit mache, denke ich, dass es Gott ist.

Es fühlt sich so an, als wäre es vollständig automatisiert, wenn man nur auf das Playbook trifft, aber ich wollte auch die Ausführung des Playbooks auf nette Weise automatisieren. Sie können ein Shell-Skript schreiben, aber das Parsen der Ergebnisse usw. ist problematisch.

Dieses Mal möchte ich Ansible von Python aus auf eine gute Art und Weise treffen. Ich konnte den Artikel nicht unerwartet finden.

Quellcode

Es ist leicht zu verstehen, wenn Sie aus __main__ lesen. Ein Playbook, das ls -la / auf 192.168.0.1 ausführt. Wenn Sie Ansible in Befehlen verwendet haben, sollten Sie es leicht lesen können. Bitte beachten Sie die einfachen Kommentare hier und da.

pip3 install ansible
import json
import shutil
from ansible.module_utils.common.collections import ImmutableDict
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.plugins.callback import CallbackBase
from ansible import context
import ansible.constants as C


class ResultCallback(CallbackBase):
    def __init__(self, *args, **kwargs):
        super(ResultCallback, self).__init__(*args, **kwargs)
        self.host_ok = {}
        self.host_unreachable = {}
        self.host_failed = {}

    def v2_runner_on_unreachable(self, result):
        host = result._host
        self.host_unreachable[host.get_name()] = result

    def v2_runner_on_ok(self, result, *args, **kwargs):
        host = result._host
        self.host_ok[host.get_name()] = result

    def v2_runner_on_failed(self, result, *args, **kwargs):
        host = result._host
        self.host_failed[host.get_name()] = result

def ansible_run(play_source, host_list):
    # ansible-Entspricht dem Argument, das im Playbook angegeben werden kann
    context.CLIARGS = ImmutableDict(
        tags={}, 
        listtags=False, 
        listtasks=False, 
        listhosts=False, 
        syntax=False, 
        connection='ssh',                
        module_path=None, 
        forks=100, 
        private_key_file=None,
        ssh_common_args=None, 
        ssh_extra_args=None, 
        sftp_extra_args=None, 
        scp_extra_args=None, 
        become=False,
        become_method='Sudo', 
        become_user='root', 
        verbosity=True, 
        check=False, 
        start_at_task=None
    )

    #Die Schlüsselauthentifizierung hat Priorität und wird nur verwendet, wenn das Kennwort abgefragt wird. Wenn Sie nicht schreiben möchten, ist es OK
    passwords = dict(vault_pass='secret')

    #Rückrufinstanziierung
    results_callback = ResultCallback()

    #Konvertieren Sie das Inventar in das 1-Liner-Format
    sources = ','.join(host_list)
    if len(host_list) == 1:
        sources += ','
    loader = DataLoader()
    inventory = InventoryManager(loader=loader, sources=sources)

    #Wert einstellen
    variable_manager = VariableManager(loader=loader, inventory=inventory)
    play = Play().load(play_source, variable_manager=variable_manager, loader=loader)

    #Lauf
    tqm = None
    try:
        tqm = TaskQueueManager(
                inventory=inventory,
                variable_manager=variable_manager,
                loader=loader,
                passwords=passwords,
                stdout_callback=results_callback, 
            )
        result = tqm.run(play)
    finally:
        #Temporäre Dateien nach dem Beenden löschen
        if tqm is not None:
            tqm.cleanup()
        # Remove ansible tmpdir
        shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
        return results_callback

if __name__ == "__main__":
    #Geben Sie den Ausführungshost an (auch im Inventar angegeben).
    host_list = [ "[email protected]" ]

    #Spielbuch definieren
    play_source =  dict(
        name = "Ansible Play",
        hosts = host_list,
        gather_facts = 'no',
        tasks = [
            dict(action=dict(module='shell', args='ls -l /'), register='shell_out')
        ]
    )
    
    results = ansible_run(play_source=play_source, host_list=host_list)

    for host, result in results.host_ok.items():
        print(host)
        print(json.dumps(result._result, indent=4))
    
    for host, result in results.host_failed.items():
        print(host)
        print(json.dumps(result._result, indent=4))
    
    for host, result in results.host_unreachable.items():
        print(host)
        print(json.dumps(result._result, indent=4))
    

Sie können das Ausführungsergebniswörterbuch wie folgt abrufen. Das Folgende ist ein Auszug dessen, was von Json ausgegeben wurde.

{
    "cmd": "ls -l /",
    "stdout": "total 28\nlrwxrwxrwx.    1 root root    7 May 11  2019 bin -> usr/bin\ndr-xr-xr-x.    6 root root 4096 Nov 12 18:17 boot\ndrwxr-xr-x.    7 root root   65 Nov 17 00:41 data\ndrwxr-xr-x.   21 root root 3580 Nov 23 12:10 dev\ndrwxr-xr-x.  104 root root 8192 Nov 22 14:11 etc\ndrwxr-xr-x.    6 root root 4096 Nov 20 13:06 gvolume0\ndrwxr-xr-x.    3 root root 4096 Nov 17 00:47 gvolume1\ndrwxr-xr-x.    3 root root   19 Nov 10 01:24 home\nlrwxrwxrwx.    1 root root    7 May 11  2019 lib -> usr/lib\nlrwxrwxrwx.    1 root root    9 May 11  2019 lib64 -> usr/lib64\ndrwxr-xr-x.    2 root root    6 May 11  2019 media\ndrwxr-xr-x.    2 root root    6 May 11  2019 mnt\ndrwxr-xr-x.    2 root root    6 May 11  2019 opt\ndr-xr-xr-x. 1056 root root    0 Nov 22 14:04 proc\ndr-xr-x---.    4 root root  192 Nov 23 11:27 root\ndrwxr-xr-x.   32 root root 1100 Nov 22 14:46 run\nlrwxrwxrwx.    1 root root    8 May 11  2019 sbin -> usr/sbin\ndrwxr-xr-x.    2 root root    6 May 11  2019 srv\ndr-xr-xr-x.   13 root root    0 Nov 22 14:04 sys\ndrwxrwxrwt.    9 root root  212 Nov 23 22:51 tmp\ndrwxr-xr-x.   12 root root  144 Nov 10 01:22 usr\ndrwxr-xr-x.   21 root root 4096 Nov 10 01:28 var",
    "stderr": "",
    "rc": 0,
    "start": "2020-11-23 22:51:11.787866",
    "end": "2020-11-23 22:51:11.793951",
    "delta": "0:00:00.006085",
    "changed": true,
    "invocation": {
        "module_args": {
            "_raw_params": "ls -l /",
            "_uses_shell": true,
            "warn": true,
            "stdin_add_newline": true,
            "strip_empty_ends": true,
            "argv": null,
            "chdir": null,
            "executable": null,
            "creates": null,
            "removes": null,
            "stdin": null
        }
    },
    "stdout_lines": [
        "total 28",
        "lrwxrwxrwx.    1 root root    7 May 11  2019 bin -> usr/bin",
        "dr-xr-xr-x.    6 root root 4096 Nov 12 18:17 boot",
        "drwxr-xr-x.    7 root root   65 Nov 17 00:41 data",
        "drwxr-xr-x.   21 root root 3580 Nov 23 12:10 dev",
        "drwxr-xr-x.  104 root root 8192 Nov 22 14:11 etc",
        "drwxr-xr-x.    6 root root 4096 Nov 20 13:06 gvolume0",
        "drwxr-xr-x.    3 root root 4096 Nov 17 00:47 gvolume1",
        "drwxr-xr-x.    3 root root   19 Nov 10 01:24 home",
        "lrwxrwxrwx.    1 root root    7 May 11  2019 lib -> usr/lib",
        "lrwxrwxrwx.    1 root root    9 May 11  2019 lib64 -> usr/lib64",
        "drwxr-xr-x.    2 root root    6 May 11  2019 media",
        "drwxr-xr-x.    2 root root    6 May 11  2019 mnt",
        "drwxr-xr-x.    2 root root    6 May 11  2019 opt",
        "dr-xr-xr-x. 1056 root root    0 Nov 22 14:04 proc",
        "dr-xr-x---.    4 root root  192 Nov 23 11:27 root",
        "drwxr-xr-x.   32 root root 1100 Nov 22 14:46 run",
        "lrwxrwxrwx.    1 root root    8 May 11  2019 sbin -> usr/sbin",
        "drwxr-xr-x.    2 root root    6 May 11  2019 srv",
        "dr-xr-xr-x.   13 root root    0 Nov 22 14:04 sys",
        "drwxrwxrwt.    9 root root  212 Nov 23 22:51 tmp",
        "drwxr-xr-x.   12 root root  144 Nov 10 01:22 usr",
        "drwxr-xr-x.   21 root root 4096 Nov 10 01:28 var"
    ],
    "stderr_lines": [],
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "_ansible_no_log": false
}

Am Ende

Die Ergebnisse sind auch in Python einfach zu verwenden, sodass sie leicht mit anderen Systemen kombiniert werden können. Ich habe nach dieser Methode gesucht, weil ich Ansible aus My Hobby Writing Python System aufrufen wollte. Es wäre großartig, wenn es für andere Menschen nützlich sein könnte.

Referenz

Recommended Posts

Führen Sie Ansible über Python mithilfe der API aus
Ich habe versucht, die UnityCloudBuild-API von Python zu verwenden
Führen Sie Python aus Excel aus
Führen Sie Python-Dateien mit Django aus HTML aus
Führen Sie Python-Skripte in Excel aus (mit xlwings).
Mit Python abflachen
Führen Sie das Illustrator-Skript von Python aus
Verwenden Sie die e-Stat-API von Python
PUSH-Benachrichtigung von Python an Android mithilfe der Google-API
Datenerfassung mit Python Googlemap API
Verwenden von Rstan aus Python mit PypeR
Installieren Sie Python von der Quelle mit Ansible
[Python3] Google übersetzt Google Übersetzung ohne Verwendung von API
Hinweise zur Verwendung von MeCab aus Python
Versuchen Sie es mit der Pleasant-API (Python / FastAPI).
Verwenden von Cloud-Speicher aus Python3 (Einführung)
Führen Sie Aprili von Python auf Orange aus
Verwenden Sie die kabu Station® API von Python
Verwenden Sie die Flickr-API von Python
Python-Fehlererkennung von Powershell ausgeführt
Python Holen Sie sich das kommende Wetter von der Wetter-API
Versuchen Sie es mit der Aktions-API von Python argparse
Führen Sie Python-Skripte synchron von C # aus
Prognostizieren Sie das Geschlecht anhand des Namens mithilfe der Gender-API und von Pykakasi in Python
Vorsichtsmaßnahmen bei der Verwendung von Phantomjs aus Python
Greifen Sie mit OAuth 2.0 von Python aus auf Tabellenkalkulationen zu
Verwenden Sie die Google Analytics-API von Python
Behandeln Sie die SOAP-API von Python (Zeep)
Führen Sie das Python-Skript in Cisco Memorandum_EEM aus
Versuchen Sie es mit Amazon DynamoDB von Python
So erhalten Sie mithilfe der Mastodon-API Follower und Follower von Python
Sammeln von Informationen von Twitter mit Python (Twitter API)
Mausbedienung mit Windows-API in Python
[Python] Webanwendung von 0! Hands-on (3) -API-Implementierung-
Führen Sie Cloud Dataflow (Python) über AppEngine aus
Versuchen Sie es mit der Wunderlist-API in Python
Von Python bis zur Verwendung von MeCab (und CaboCha)
Versuchen Sie, die Kraken-API mit Python zu verwenden
Tweet mit der Twitter-API in Python
Holen Sie sich Youtube-Daten in Python mithilfe der Youtube-Daten-API
Lassen Sie einen Servomotor mit Python auf Raspberry Pi 3 laufen
Erstellen einer Google-Tabelle mit der Python / Google Data-API
API-Erklärung zum Berühren von Mastodon aus Python
Stellen Sie von Python aus eine Verbindung zur Websocket-API von coincheck her
Starten Sie Python
SQL zu SQL
Erkennen Sie japanische Zeichen anhand von Bildern mithilfe der Cloud Vision-API von Google mit Python
Scraping mit Python
Führen Sie Python-Skripte in C # -GUI-Anwendungen aus
Vorgehensweise zur Verwendung der WEG-API von TeamGant (mit Python)
Ich möchte mit Python eine E-Mail von Google Mail senden.
Führen Sie die Google Analytics-API (Core v3) in Python aus
Holen Sie sich die Bild-URL mithilfe der Flickr-API in Python
Lassen Sie uns Emotionen mithilfe der Emotions-API in Python beurteilen
Letzte Ranglistenerstellung mit der Qiita-API mit Python
Bearbeiten Sie Objekte mit der einfachen Python-API von Blender 2.8
Führen Sie die vSphere-API von VMware vSphere 6 mit dem Python-Skript (pyvmomi) aus.
Laden Sie Bilder von der URL mit Pillow in Python 3
Anonymer Upload von Bildern mit der Imgur-API (mit Python)