blob: 040dcf489653be522d0d829f4319965aee1371aa [file] [log] [blame]
koder aka kdanilov39e449e2016-12-17 15:15:26 +02001import logging
2from typing import Dict, List, NamedTuple, Union, cast
3
4from paramiko.ssh_exception import AuthenticationException
5
6from .fuel_rest_api import get_cluster_id, reflect_cluster, FuelInfo, KeystoneAuth
7from .node_interfaces import NodeInfo
8from .ssh_utils import ConnCreds, parse_ssh_uri
9from .utils import check_input_param, StopTestError, parse_creds
10from .stage import Stage, StepOrder
11from .test_run_class import TestRun
12from .node import connect, setup_rpc
13from .config import ConfigBlock
14from .openstack_api import OSCreds
15
16
17logger = logging.getLogger("wally.discover")
18
19
20FuelNodeInfo = NamedTuple("FuelNodeInfo",
21 [("version", List[int]),
22 ("fuel_ext_iface", str),
23 ("openrc", Dict[str, Union[str, bool]])])
24
25
26
27class DiscoverFuelStage(Stage):
28 """"Fuel nodes discovery, also can get openstack openrc"""
29
30 priority = StepOrder.DISCOVER
31 config_block = 'fuel'
32
33 @classmethod
34 def validate(cls, cfg: ConfigBlock) -> None:
35 # msg = "openstack_env should be provided in fuel config"
36 # check_input_param('openstack_env' in fuel_data, msg)
37 # fuel.openstack_env
38 pass
39
40 def run(self, ctx: TestRun) -> None:
41 if 'fuel' in ctx.storage:
42 ctx.nodes_info.extend(ctx.storage.load_list(NodeInfo, 'fuel/nodes'))
43 ctx.fuel_openstack_creds = ctx.storage['fuel/os_creds'] # type: ignore
44 ctx.fuel_version = ctx.storage['fuel/version'] # type: ignore
45 else:
46 fuel = ctx.config.fuel
47 discover_nodes = (fuel.discover != "fuel_openrc_only")
48 fuel_node_info = NodeInfo(parse_ssh_uri(fuel.ssh_creds), {'fuel_master'})
49 fuel_nodes = [fuel_node_info]
50
51 creds = dict(zip(("user", "passwd", "tenant"), parse_creds(fuel.creds)))
52 fuel_conn = KeystoneAuth(fuel.url, creds)
53
54 # get cluster information from REST API
55 cluster_id = get_cluster_id(fuel_conn, fuel.openstack_env)
56 cluster = reflect_cluster(fuel_conn, cluster_id)
57 ctx.fuel_version = FuelInfo(fuel_conn).get_version()
58 logger.info("Found fuel {0}".format(".".join(map(str, ctx.fuel_version))))
59 openrc = cluster.get_openrc()
60
61 if openrc:
62 auth_url = cast(str, openrc['os_auth_url'])
63 if ctx.fuel_version >= [8, 0] and auth_url.startswith("https://"):
64 logger.warning("Fixing FUEL 8.0 AUTH url - replace https://->http://")
65 auth_url = auth_url.replace("https", "http", 1)
66
67 os_creds = OSCreds(name=cast(str, openrc['username']),
68 passwd=cast(str, openrc['password']),
69 tenant=cast(str, openrc['tenant_name']),
70 auth_url=cast(str, auth_url),
71 insecure=cast(bool, openrc['insecure']))
72
73 ctx.fuel_openstack_creds = os_creds
74 else:
75 ctx.fuel_openstack_creds = None
76
77 if discover_nodes:
78
79 try:
80 fuel_rpc = setup_rpc(connect(fuel_node_info), ctx.rpc_code)
81 except AuthenticationException:
82 raise StopTestError("Wrong fuel credentials")
83 except Exception:
84 logger.exception("While connection to FUEL")
85 raise StopTestError("Failed to connect to FUEL")
86
87 logger.debug("Downloading FUEL node ssh master key")
88 fuel_key = fuel_rpc.get_file_content('/root/.ssh/id_rsa')
89 network = 'fuelweb_admin' if ctx.fuel_version >= [6, 0] else 'admin'
90
91 for fuel_node in list(cluster.get_nodes()):
92 ip = str(fuel_node.get_ip(network))
93 fuel_nodes.append(NodeInfo(ConnCreds(ip, "root", key=fuel_key),
94 roles=set(fuel_node.get_roles())))
95
96 ctx.storage['fuel_nodes'] = fuel_nodes
97 ctx.nodes_info.extend(fuel_nodes)
98 ctx.nodes_info.append(fuel_node_info)
99 logger.debug("Found {} FUEL nodes for env {}".format(len(fuel_nodes) - 1, fuel.openstack_env))
100 else:
101 logger.debug("Skip FUEL nodes discovery, as 'fuel_openrc_only' is set to fuel.discover option")
102
103 ctx.storage["fuel/nodes"] = fuel_nodes
104 ctx.storage["fuel/os_creds"] = ctx.fuel_openstack_creds
105 ctx.storage["fuel/version"] = ctx.fuel_version