a lot of changes
diff --git a/wally/discover/__init__.py b/wally/discover/__init__.py
index b02809c..3ac983e 100644
--- a/wally/discover/__init__.py
+++ b/wally/discover/__init__.py
@@ -1,5 +1,5 @@
"this package contains node discovery code"
-from .discover import discover, undiscover
from .node import Node
+from .discover import discover
-__all__ = ["discover", "Node", "undiscover"]
+__all__ = ["discover", "Node"]
diff --git a/wally/discover/discover.py b/wally/discover/discover.py
index 3cab884..5802ac3 100644
--- a/wally/discover/discover.py
+++ b/wally/discover/discover.py
@@ -96,9 +96,4 @@
msg_templ = "Unknown cluster type in 'discover' parameter: {0!r}"
raise ValueError(msg_templ.format(cluster))
- return nodes_to_run, clean_data
-
-
-def undiscover(clean_data):
- if clean_data is not None:
- fuel.clean_fuel_port_forwarding(clean_data)
+ return nodes_to_run
diff --git a/wally/discover/fuel.py b/wally/discover/fuel.py
index a787786..7a14f94 100644
--- a/wally/discover/fuel.py
+++ b/wally/discover/fuel.py
@@ -1,15 +1,18 @@
-import os
import re
-import sys
import socket
import logging
from urlparse import urlparse
-import yaml
+import sshtunnel
+from paramiko import AuthenticationException
+
+
from wally.fuel_rest_api import (KeystoneAuth, get_cluster_id,
reflect_cluster, FuelInfo)
-from wally.utils import parse_creds
-from wally.ssh_utils import run_over_ssh, connect
+from wally.utils import (parse_creds, check_input_param, StopTestError,
+ clean_resource, get_ip_for_target)
+from wally.ssh_utils import (run_over_ssh, connect, set_key_for_node,
+ read_from_remote)
from .node import Node
@@ -26,6 +29,9 @@
conn = KeystoneAuth(fuel_data['url'], creds, headers=None)
+ msg = "openstack_env should be provided in fuel config"
+ check_input_param('openstack_env' in fuel_data, msg)
+
cluster_id = get_cluster_id(conn, fuel_data['openstack_env'])
cluster = reflect_cluster(conn, cluster_id)
@@ -45,55 +51,57 @@
fuel_host = urlparse(fuel_data['url']).hostname
fuel_ip = socket.gethostbyname(fuel_host)
- ssh_conn = connect("{0}@@{1}".format(ssh_creds, fuel_host))
+
+ try:
+ ssh_conn = connect("{0}@{1}".format(ssh_creds, fuel_host))
+ except AuthenticationException:
+ raise StopTestError("Wrong fuel credentials")
+ except Exception:
+ logger.exception("While connection to FUEL")
+ raise StopTestError("Failed to connect to FUEL")
fuel_ext_iface = get_external_interface(ssh_conn, fuel_ip)
- # TODO: keep ssh key in memory
- # http://stackoverflow.com/questions/11994139/how-to-include-the-private-key-in-paramiko-after-fetching-from-string
- fuel_key_file = os.path.join(var_dir, "fuel_master_node_id_rsa")
- download_master_key(ssh_conn, fuel_key_file)
+ logger.debug("Downloading fuel master key")
+ fuel_key = download_master_key(ssh_conn)
nodes = []
- ports = range(BASE_PF_PORT, BASE_PF_PORT + len(fuel_nodes))
ips_ports = []
- for fuel_node, port in zip(fuel_nodes, ports):
- ip = fuel_node.get_ip(network)
- forward_ssh_port(ssh_conn, fuel_ext_iface, port, ip)
+ logger.info("Forwarding ssh ports from FUEL nodes localhost")
+ fuel_usr, fuel_passwd = ssh_creds.split(":", 1)
+ ips = [str(fuel_node.get_ip(network)) for fuel_node in fuel_nodes]
+ port_fw = forward_ssh_ports(fuel_host, fuel_usr, fuel_passwd, ips)
+ listen_ip = get_ip_for_target(fuel_host)
- conn_url = "ssh://root@{0}:{1}:{2}".format(fuel_host,
- port,
- fuel_key_file)
+ for port, fuel_node, ip in zip(port_fw, fuel_nodes, ips):
+ logger.debug(
+ "SSH port forwarding {0} => localhost:{1}".format(ip, port))
+
+ conn_url = "ssh://root@127.0.0.1:{0}".format(port)
+ set_key_for_node(('127.0.0.1', port), fuel_key)
+
node = Node(conn_url, fuel_node['roles'])
- node.monitor_url = None
+ node.monitor_ip = listen_ip
nodes.append(node)
ips_ports.append((ip, port))
logger.debug("Found %s fuel nodes for env %r" %
(len(nodes), fuel_data['openstack_env']))
- # return ([],
- # (ssh_conn, fuel_ext_iface, ips_ports),
- # cluster.get_openrc())
-
return (nodes,
(ssh_conn, fuel_ext_iface, ips_ports),
cluster.get_openrc())
-def download_master_key(conn, dest):
+def download_master_key(conn):
# download master key
- sftp = conn.open_sftp()
- sftp.get('/root/.ssh/id_rsa', dest)
- os.chmod(dest, 0o400)
- sftp.close()
-
- logger.debug("Fuel master key stored in {0}".format(dest))
+ with conn.open_sftp() as sftp:
+ return read_from_remote(sftp, '/root/.ssh/id_rsa')
def get_external_interface(conn, ip):
- data = run_over_ssh(conn, "ip a", node='fuel-master')
+ data = run_over_ssh(conn, "ip a", node='fuel-master', nolog=True)
curr_iface = None
for line in data.split("\n"):
@@ -109,38 +117,14 @@
raise KeyError("Can't found interface for ip {0}".format(ip))
-def forward_ssh_port(conn, iface, new_port, ip, clean=False):
- mode = "-D" if clean is True else "-A"
- cmd = "iptables -t nat {mode} PREROUTING -p tcp " + \
- "-i {iface} --dport {port} -j DNAT --to {ip}:22"
- run_over_ssh(conn,
- cmd.format(iface=iface, port=new_port, ip=ip, mode=mode),
- node='fuel-master')
-
-
-def clean_fuel_port_forwarding(clean_data):
- if clean_data is None:
- return
-
- conn, iface, ips_ports = clean_data
- for ip, port in ips_ports:
- forward_ssh_port(conn, iface, port, ip, clean=True)
-
-
-def main(argv):
- fuel_data = yaml.load(open(sys.argv[1]).read())['clouds']['fuel']
- nodes, to_clean, openrc = discover_fuel_nodes(fuel_data, '/tmp')
-
- print nodes
- print openrc
- print "Ready to test"
-
- sys.stdin.readline()
-
- clean_fuel_port_forwarding(to_clean)
-
- return 0
-
-
-if __name__ == "__main__":
- main(sys.argv[1:])
+def forward_ssh_ports(proxy_ip, proxy_user, proxy_passwd, ips):
+ for ip in ips:
+ tunnel = sshtunnel.open(
+ (proxy_ip, 22),
+ ssh_username=proxy_user,
+ ssh_password=proxy_passwd,
+ threaded=True,
+ remote_bind_address=(ip, 22))
+ tunnel.__enter__()
+ clean_resource(tunnel.__exit__, None, None, None)
+ yield tunnel.local_bind_port
diff --git a/wally/discover/node.py b/wally/discover/node.py
index 9f4356f..9161a21 100644
--- a/wally/discover/node.py
+++ b/wally/discover/node.py
@@ -9,7 +9,7 @@
self.roles = roles
self.conn_url = conn_url
self.connection = None
- self.monitor_url = None
+ self.monitor_ip = None
def get_ip(self):
if self.conn_url == 'local':