Joker integration and some joker fixes

This commit is contained in:
Maxim Kulkin 2013-10-22 20:19:25 +04:00
parent ae752109dd
commit 12e6ad74e0
3 changed files with 83 additions and 52 deletions

View File

@ -1,6 +1,5 @@
from nodes import NodesDict,Node
from nodes import NodesDict, Node
#from os import remove
import os
PETYA_ENV_KEY = "-----BEGIN RSA PRIVATE KEY-----\n\
MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI\n\
@ -32,46 +31,59 @@ NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s=\n\
#TMP_PATH="/tmp/%s"
class Joker():
def __init__(self, key = PETYA_ENV_KEY, *args, **kwargs):
def __init__(self, key=PETYA_ENV_KEY, *args, **kwargs):
self.default_key = key
self.nodes = NodesDict()
self.keyPath = None
self.name = "EntryPoint"
#self.setKey()
#self.setKey()
# def __del__(self):
# if (self.keyPath):
# if (self.keyPath):
# # look at this.
# # epic security hole oneliner
# print "os.remove(self.keyPath)"
def addNode(self, name, host, port, user):
self.entryPoint = Node(name, host, port);
self.entryPoint.assignCredential(user, self.default_key, None)
self.entryPoint = Node(name, host, port)
self.entryPoint.assignCredential(user, self.default_key, None)
return
def genStub(self, hostname, ip, port, user, key, proxycommand):
return {"name": hostname, "ip": ip, "user": user,
"key": key, "port": port,
"key": key, "port": port,
"proxy_command": proxycommand
}
}
def discover(self):
result = []
discoveryData = self.entryPoint.discovery()
ep = self.entryPoint
discoveryData = ep.discovery()
for node in discoveryData:
result.append(self.genStub(discoveryData[node], discoveryData[node], self.default_key , "vagrant", None, "ssh -i " + "%%PATH_TO_KEY%%" + " -p " + str(self.entryPoint.accessPort) + " -q " + self.entryPoint.user + "@" + self.entryPoint.hostName + " nc -q0 " + discoveryData[node] + " 22"))
proxy_command = ("ssh" +
" -i %%PATH_TO_KEY%%" +
" -p {0}".format(ep.accessPort) +
" -q {0}@{1}".format(ep.user, ep.hostName) +
" nc -q0 {0} 22".format(discoveryData[node]))
result.append(
self.genStub(hostname=discoveryData[node],
ip=discoveryData[node],
port=ep.accessPort,
user="vagrant",
key=self.default_key,
proxycommand=proxy_command))
return result
joker = Joker(PETYA_ENV_KEY)
joker.addNode("controller1", "172.18.66.112", 2301, "vagrant");
print joker.discover()
if __name__ == '__main__':
joker = Joker(PETYA_ENV_KEY)
joker.addNode("controller1", "172.18.66.112", 2301, "vagrant")
print joker.discover()

View File

@ -53,39 +53,38 @@ class Node():
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.setHostName(ip)
self.setName(name)
self.setAccessPort(port)
self.setAccessPort(port)
self.connected = False
#self.neighbours = NodesDict()
self.neighbours = {}
self.debug = True
#self.neighbours = NodesDict()
self.neighbours = {}
self.debug = True
self.hwAddr = None
def discoveryHwAddr(self):
def discoveryHwAddr(self):
try:
(stdout, stderr) = self.runCommand("ip link | grep -m1 -A1 BROADCAST,MULTICAST,UP,LOWER_UP | awk -F\" \" '/link/ {print $2}'");
(stdout, stderr) = self.runCommand("ip link | grep -m1 -A1 BROADCAST,MULTICAST,UP,LOWER_UP | awk -F\" \" '/link/ {print $2}'");
except:
raise()
return stdout[0].strip()
raise()
return stdout[0].strip()
def setUniqData(self):
self.hwAddr = self.discoveryHwAddr()
self.hwAddr = self.discoveryHwAddr()
def getUniqData(self):
return self.hwAddr
def debugLog(self, debugData):
def debugLog(self, debugData):
if self.debug is True:
print debugData
def prepare(self):
# install arp-scan on node
self.runCommand(
"[ ! -x arp-scan ] && sudo apt-get --force-yes -y install arp-scan")
self.setUniqData()
self.debugLog("Unit data is " + self.getUniqData());
"which arp-scan || sudo apt-get --force-yes -y install arp-scan")
self.setUniqData()
self.debugLog("Unit data is " + self.getUniqData())
return True
def infect(self):
@ -105,7 +104,7 @@ class Node():
self.user = user
self.password = password
# from paramiko?
# from paramiko?
self.origKey = key
self._pkey = RSAKey.from_private_key(StringIO(self.origKey))
@ -118,15 +117,14 @@ class Node():
# except SSHException:
# raise "Unknown private key format"
def setProxyCommand(self, proxyCommand):
self.proxyCommand = proxyCommand
def connect(self):
if self.connected is True:
raise assertionError(self.connected is True)
raise AssertionError(self.connected is True)
try:
print self.hostName, " ", self.accessPort, " ", self.user, " "
print self.hostName, " ", self.accessPort, " ", self.user, " "
self.ssh.connect(self.hostName, self.accessPort, self.user,
pkey=self._pkey)
self.connected = True
@ -143,32 +141,32 @@ class Node():
def runCommand(self, command):
if (command == ""):
assertionError(command == "")
AssertionError(command == "")
if (self.connected is False):
self.connect()
self.debugLog("---> " + self.hostName + " " + command)
self.debugLog("---> " + self.hostName + " " + command)
stdin, stdout, stderr = self.ssh.exec_command(command)
self.debugLog("OK " + self.hostName + " " + command)
self.debugLog("OK " + self.hostName + " " + command)
return (stdout.readlines(), stderr.readlines())
return (stdout.readlines(), stderr.readlines())
def __discovery__(self):
def __discovery__(self):
# tuesday discovery
(self.discovery_data, _) = self.runCommand(
"ip link | awk -F: '/^[0-9]+?: eth/ {print $2}' |\
sudo xargs -I% arp-scan -l -I % 2>&1 | grep -E '^[0-9]+?\.' | grep -E '192.168.(28|30)'.101")
def discovery(self):
self.prepare()
node = {}
node = {}
self.__discovery__()
self.__discovery__()
for n in self.discovery_data:
( node['ip'], node['hwaddr'], _) = n.split("\t")
(node['ip'], node['hwaddr'], _) = n.split("\t")
self.neighbours[node['hwaddr']] = node['ip']
self.neighbours[self.getUniqData()] = self.hostName
return self.neighbours

View File

@ -1,6 +1,7 @@
import os.path
import re
import traceback
import tempfile
from StringIO import StringIO
import logging
@ -71,6 +72,15 @@ class NodeClient(object):
private_key=None, proxy_command=None):
super(NodeClient, self).__init__()
self.use_sudo = (username != 'root')
if proxy_command and proxy_command.find('%%PATH_TO_KEY%%') != -1:
self._pkey_file = tempfile.NamedTemporaryFile(suffix='.key')
self._pkey_file.write(private_key)
self._pkey_file.flush()
proxy_command = proxy_command.replace('%%PATH_TO_KEY%%',
self._pkey_file.name)
sock = paramiko.ProxyCommand(proxy_command) if proxy_command else None
self.shell = SshShell(
@ -80,6 +90,7 @@ class NodeClient(object):
password=password,
private_key=private_key,
missing_host_key=spur.ssh.MissingHostKey.accept,
connect_timeout=5,
sock=sock)
def run(self, command, *args, **kwargs):
@ -148,12 +159,22 @@ class JokerNodeDiscovery(object):
j = joker.Joker(default_key=private_key)
count = 0
for node in parse_nodes_info(initial_nodes):
j.add_node('node%d' % count,
node['host'],
node['port'],
node['username'])
j.addNode('node%d' % count,
node['host'],
node['port'],
node['username'])
nodes = j.discover()
nodes = []
for j_node_info in j.discover():
node = dict(
name=j_node_info['name'],
host=j_node_info['ip'],
port=j_node_info['port'],
username=j_node_info['user'],
private_key=j_node_info['key'],)
# proxy_command=j_node_info['proxy_command'])
node = dict((k, v) for k, v in node.iteritems() if v)
nodes.append(node)
return nodes
@ -164,7 +185,7 @@ python_re = re.compile('(/?([^/]*/)*)python[0-9.]*')
class OpenstackDiscovery(object):
logger = logging.getLogger('rubick.discovery')
node_discovery_klass = SimpleNodeDiscovery
node_discovery_klass = JokerNodeDiscovery
def test_connection(self, initial_nodes, private_key):
d = self.node_discovery_klass()