Seite 1 von 1

Bitte um Hilfe bei while loop / dictionary

Verfasst: Sonntag 14. Juni 2020, 12:56
von jakob83
Hallo,

ich möchte eine script erstellen, mit welchem ich automasierte Befehle vie paramiko mit ssh an diverse clients sendne möchte (später so ca. 20).

Mein Problem ist das ich den Code nicht zu lang werden lassen will, daher die Idee für den Schlüssel die Variable "x" zu nehmen (ansonsten müsste man für
jeden host eine einzelne Zeile ergänzen...

Code: Alles auswählen

ssh.connect(z, port=HOSTS["1"]["ssh_port"], username=HOSTS["1"]["username"], password=HOSTS["1"]["pwd"], allow_agent = False)
    stdin, stdout, stderr = ssh.exec_command(updatehost, get_pty=True)
    stdin.write(HOSTS["1"]["su_pwd"])
    stdin.flush()
Was kann man hier ändern dass es funktioniert?:

Code: Alles auswählen


import paramiko

HOSTS = {
    "1": {"name": "PC1", "ip": "192.168.1.10", "host_name": "Computer1", "ssh_port": "22", "username": "user1", "pwd": "pw1", "su_pwd": "supwd1\n"},
    "2": {"name": "PC2", "ip": "192.168.1.11", "host_name": "Computer2", "ssh_port": "22", "username": "user2", "pwd": "p2w", "su_pwd": "supwd2\n"},
    }


# Counter for Nested  Hosts Dictonary
x = 0

# TH = TotalHosts
TH=len(HOSTS.keys())

updatehost="sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get clean && sudo apt-get autoremove"

ssh = paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

while x <= TH:
    x = x+1
    ssh.connect(HOSTS[x]["ip"], port=HOSTS[x]["ssh_port"], username=HOSTS[x]["username"], password=HOSTS[x]["pwd"], allow_agent = False)
    stdin, stdout, stderr = ssh.exec_command(updatehost, get_pty=True)
    stdin.write(HOSTS[x]["su_pwd"])
    stdin.flush()
    for line in iter(stdout.readline, ""):
         print(line, end="")
         
gibt folgende Ausnahme zurück:

Code: Alles auswählen

Traceback (most recent call last):
  File "Z:\Python\ssh_paramiko.py", line 30, in <module>
    ssh.connect(HOSTS[x]["ip"], port=HOSTS[x]["ssh_port"], username=HOSTS[x]["username"], password=HOSTS[x]["pwd"], allow_agent = False)
KeyError: 0
Vielen Dank im Voraus für die Mühe!

Re: Bitte um Hilfe bei while loop / dictionary

Verfasst: Montag 15. Juni 2020, 06:47
von Jankie
Du hast in deinem Dictionary als Key einen String und versuchst nun über einen Int an den Value zu kommen. Das funktioniert so nicht. Ich würde auch die while Schleife durch eine for-Schleife ersetzen.

Re: Bitte um Hilfe bei while loop / dictionary

Verfasst: Montag 15. Juni 2020, 07:21
von __blackjack__
Da die Schlüssel auch keinerlei Bedeutung zu haben scheinen würde man auch kein Wörterbuch für `HOSTS` verwenden, sondern eine Liste.

Warum das `iter()` in der ``for``-Schleife und nicht einfach eine Schleife über `stdout`?

Re: Bitte um Hilfe bei while loop / dictionary

Verfasst: Montag 15. Juni 2020, 07:50
von Sirius3
Wenn man Variablen mit Kommentaren versehen muß, dann ist klar, dass der Name schlecht ist: TH -> TOTAL_HOSTS
Die while-Schleife ist eigentlich eine for-Schleife. Über einen Index iteriert man in Python auch nicht, sondern direkt über die Objekte.
Eingerückt wird immer mit 4 Leerzeichen pro Eben, nicht mal 4 und mal 5.

Code: Alles auswählen

import paramiko

HOSTS = [
    {"name": "PC1", "ip": "192.168.1.10", "host_name": "Computer1", "ssh_port": "22", "username": "user1", "pwd": "pw1", "su_pwd": "supwd1"},
    {"name": "PC2", "ip": "192.168.1.11", "host_name": "Computer2", "ssh_port": "22", "username": "user2", "pwd": "p2w", "su_pwd": "supwd2"},
]

UPDATEHOST = "sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get clean && sudo apt-get autoremove"

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for host in HOST:
    ssh.connect(host["ip"], port=host["ssh_port"], username=host["username"], password=host["pwd"], allow_agent=False)
    stdin, stdout, stderr = ssh.exec_command(updatehost, get_pty=True)
    stdin.write(host["su_pwd"] + "\n")
    stdin.flush()
    for line in stdout:
        print(line, end="")

Re: Bitte um Hilfe bei while loop / dictionary

Verfasst: Montag 15. Juni 2020, 08:04
von __blackjack__
Ich verwende bei solchen Sachen noch ganz gerne ein `addict.Dict` um per Punktoperator auf die Werte im Wörterbuch zugreifen zu können.

Und auch bei den Schlüsseln sollte man keine Abkürzungen verwenden, genau wie bei Namen nicht. `su_pwd` ist zum Beispiel irritierend, weil es ja nicht nur ``sudo`` gibt, sondern tatsächlich auch ein ``su``-Kommando was auch nach einem Passwort fragt. Diese Verwirrung sollte man sich ersparen.

Das Programm enthält eine potentielle Verklemmung wenn ``apt-get`` Ausgaben auf der Standardfehlerausgabe macht!

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import paramiko
from addict import Dict

HOSTS = [
    {
        "name": "PC1",
        "ip": "192.168.1.10",
        "host_name": "Computer1",
        "ssh_port": "22",
        "username": "user1",
        "password": "pw1",
        "sudo_password": "supwd1",
    },
    {
        "name": "PC2",
        "ip": "192.168.1.11",
        "host_name": "Computer2",
        "ssh_port": "22",
        "username": "user2",
        "password": "p2w",
        "sudo_password": "supwd2",
    },
]

UPDATEHOST = (
    "sudo apt-get update"
    " && sudo apt-get upgrade -y"
    " && sudo apt-get clean"
    " && sudo apt-get autoremove"
)


def main():
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    for host in map(Dict, HOSTS):
        ssh.connect(
            host.ip,
            port=host.ssh_port,
            username=host.username,
            password=host.password,
            allow_agent=False,
        )
        stdin, stdout, _stderr = ssh.exec_command(UPDATEHOST, get_pty=True)
        stdin.write(host.sudo_password + "\n")
        stdin.flush()
        #
        # FIXME When ``apt-get`` prints stuff to its ``stderr`` this will
        # eventually hang in a deadlock!
        #
        for line in stdout:
            print(line, end="")


if __name__ == "__main__":
    main()

Re: Bitte um Hilfe bei while loop / dictionary

Verfasst: Dienstag 16. Juni 2020, 13:05
von jakob83
Vielen Dank an alle für die rasche Hilfe und die guten Ratschläge!

Ich schreibe es um und probiere es aus!


LG