koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 1 | import socket |
| 2 | import logging |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 3 | from typing import Dict, Any, List, Optional, cast |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 4 | |
koder aka kdanilov | 7308462 | 2016-11-16 21:51:08 +0200 | [diff] [blame] | 5 | from ..node_interfaces import NodeInfo |
| 6 | from ..config import ConfigBlock |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 7 | from ..ssh_utils import ConnCreds |
| 8 | from ..start_vms import OSConnection, NovaClient |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 9 | |
| 10 | |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 11 | logger = logging.getLogger("wally.discover") |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 12 | |
| 13 | |
koder aka kdanilov | 7308462 | 2016-11-16 21:51:08 +0200 | [diff] [blame] | 14 | def get_floating_ip(vm: Any) -> str: |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 15 | """Get VM floating IP address""" |
| 16 | |
| 17 | for net_name, ifaces in vm.addresses.items(): |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 18 | for iface in ifaces: |
| 19 | if iface.get('OS-EXT-IPS:type') == "floating": |
| 20 | return iface['addr'] |
| 21 | |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 22 | raise ValueError("VM {} has no floating ip".format(vm)) |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 23 | |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 24 | |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 25 | def discover_vms(client: NovaClient, search_data: str) -> List[NodeInfo]: |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 26 | """Discover virtual machines""" |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 27 | name, user, key_file = search_data.split(",") |
| 28 | servers = client.servers.list(search_opts={"name": name}) |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 29 | logger.debug("Found %s openstack vms" % len(servers)) |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 30 | |
koder aka kdanilov | 7308462 | 2016-11-16 21:51:08 +0200 | [diff] [blame] | 31 | nodes = [] # type: List[NodeInfo] |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 32 | for server in servers: |
| 33 | ip = get_floating_ip(server) |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 34 | creds = ConnCreds(host=ip, user=user, key_file=key_file) |
| 35 | nodes.append(NodeInfo(creds, roles={"test_vm"})) |
| 36 | |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 37 | return nodes |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 38 | |
| 39 | |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 40 | def discover_openstack_nodes(conn: OSConnection, conf: ConfigBlock) -> List[NodeInfo]: |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 41 | """Discover openstack services for given cluster""" |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 42 | os_nodes_auth = conf['auth'] # type: str |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 43 | |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 44 | if os_nodes_auth.count(":") == 2: |
| 45 | user, password, key_file = os_nodes_auth.split(":") # type: str, Optional[str], Optional[str] |
| 46 | if not password: |
| 47 | password = None |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 48 | else: |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 49 | user, password = os_nodes_auth.split(":") |
| 50 | key_file = None |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 51 | |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 52 | services = conn.nova.services.list() # type: List[Any] |
| 53 | host_services_mapping = {} # type: Dict[str, List[str]] |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 54 | |
| 55 | for service in services: |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 56 | ip = cast(str, socket.gethostbyname(service.host)) |
koder aka kdanilov | 7308462 | 2016-11-16 21:51:08 +0200 | [diff] [blame] | 57 | host_services_mapping.get(ip, []).append(service.binary) |
koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 58 | |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 59 | logger.debug("Found %s openstack service nodes" % len(host_services_mapping)) |
koder aka kdanilov | 7308462 | 2016-11-16 21:51:08 +0200 | [diff] [blame] | 60 | |
| 61 | nodes = [] # type: List[NodeInfo] |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 62 | for host, services in host_services_mapping.items(): |
koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame^] | 63 | creds = ConnCreds(host=host, user=user, passwd=password, key_file=key_file) |
| 64 | nodes.append(NodeInfo(creds, set(services))) |
koder aka kdanilov | 3b4da8b | 2016-10-17 00:17:53 +0300 | [diff] [blame] | 65 | |
| 66 | return nodes |