Форум сайта python.su
Добрый день, Коллеги.
Прошу помощи.
Хочу нарисовать модуль, который подключается к 5 сервера по ssh и выполняет определенные команды + sftp команды (копировать - удалять файлы/директории).
Команды буду скармливать через txredisapi.
У меня сложность с conch.
Нарисовал для себя такой пример:
[code python]#!/usr/bin/env python
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
if __name__ == '__main__':
import sys
import p3
from twisted.internet.task import react
react(p3.main)
import os, getpass
from twisted.python.filepath import FilePath
from twisted.python.usage import Options
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Factory, Protocol, ReconnectingClientFactory
from twisted.internet.endpoints import UNIXClientEndpoint
from twisted.conch.ssh.keys import EncryptedKeyError, Key
from twisted.conch.client.knownhosts import KnownHostsFile
from twisted.conch.endpoints import SSHCommandClientEndpoint
class NoiseProtocol(Protocol):
def connectionMade(self):
print "Connected to SSH"
self.finished = Deferred()
def dataReceived(self, data):
print "Server says:\n", data
class ConnectionParameters(object):
def __init__(self, reactor):
self.reactor = reactor
self.host = "192.168.87.100"
self.port = 22
self.username = "root"
self.password = None
self.keys = None
self.knownHosts = None
self.agent = None
self.keys = []
self.keys.append(Key.fromFile(os.path.expanduser("~/.ssh/id_rsa")))
knownHostsPath = FilePath(os.path.expanduser("~/.ssh/known_hosts"))
if knownHostsPath.exists():
self.knownHosts = KnownHostsFile.fromPath(knownHostsPath)
else:
self.knownHosts = None
def endpointForCommand(self, command):
return SSHCommandClientEndpoint.newConnection(
self.reactor, command, self.username, self.host,
port=self.port, keys=self.keys,
knownHosts=self.knownHosts)
def main(reactor):
parameters = ConnectionParameters(reactor)
endpoint = parameters.endpointForCommand(b"")
factory = ReconnectingClientFactory()
factory.protocol = NoiseProtocol
d = endpoint.connect(factory)
d.addCallback(lambda proto: proto.finished)
r = endpoint.existingConnection(factory.protocol.transport, b"/bin/ls")
d = endpoint.connect(factory)
d.addCallback(lambda proto: proto.finished)
r.addCallback(lambda proto: proto.finished)
return d[/code]
<twisted.conch.endpoints.SSHCommandClientEndpoint object at 0x104fc4790> Connected to SSH Connected to SSH
Офлайн
отвечаю себе)))
пока такой вариант
from twisted.conch.ssh import transport, connection, userauth, channel, common, keys from twisted.internet import defer, protocol, reactor import sys, struct USER = 'root' CMD = b'/bin/ls' from twisted.python import log import sys, os log.startLogging(sys.stdout) class ClientCommandTransport(transport.SSHClientTransport): def __init__(self, username, command, factory): self.username = username self.command = command self.factory = factory def verifyHostKey(self, pubKey, fingerprint): print fingerprint return defer.succeed(True) def connectionSecure(self): self.requestService( SSHKeyAuth(self.username, ClientConnection(self.command, self.factory))) class SSHKeyAuth(userauth.SSHUserAuthClient): def getPublicKey(self): path = os.path.expanduser('~/.ssh/id_rsa') if not os.path.exists(path) or self.lastPublicKey: return return keys.Key.fromFile(filename=path+'.pub').blob() def getPrivateKey(self): path = os.path.expanduser('~/.ssh/id_rsa') return defer.succeed(keys.Key.fromFile(path).keyObject) class ClientConnection(connection.SSHConnection): def __init__(self, cmd, *args, **kwargs): connection.SSHConnection.__init__(self) self.command = cmd self.factory = factory def serviceStarted(self): self.openChannel(CommandChannel(self.command, self.factory, conn=self)) self.openChannel(CommandChannel(b"/bin/ls /var/log/", self.factory, conn=self)) # self.openChannel(CommandChannel(self.command, self.factory, conn=self)) # self.openChannel(CommandChannel(self.command, self.factory, conn=self)) class CommandChannel(channel.SSHChannel): name = 'session' def __init__(self, command, factory, *args, **kwargs): channel.SSHChannel.__init__(self, *args, **kwargs) self.command = command self.data = '' self.factory = factory self.factory.num_connections += 1 self.factory.connections.append(self) def channelOpen(self, data): print ">>>>>>> Try send exec" self.conn.sendRequest(self, 'exec', common.NS(self.command), wantReply=True).addCallback(self._gotResponse) def _gotResponse(self, _): pass self.conn.sendEOF(self) self.loseConnection() # self.factory.num_connections -= 1 # self.factory.connections.remove(self) # if self.factory.num_connections == 0: # reactor.stop() def dataReceived(self, data): self.data += data # print ">>>>>>>>>>>>>>", data print "|", self.data, "|" # def request_exit_status(self, data): # (status,) = struct.unpack('>L', data) # print 'exit status = ', status class ClientCommandFactory(protocol.ClientFactory): def __init__(self, command=CMD): self.username = USER self.command = command self.connections = [] self.num_connections = 0 def buildProtocol(self, addr): protocol = ClientCommandTransport(self.username, self.command, self) return protocol def test1(self): pass masters = ['192.168.87.100', '10.30.50.27', '10.30.50.110'] factory = ClientCommandFactory() for server in masters: print server reactor.connectTCP(server, 22, factory) reactor.run()
Офлайн