def ping_hosts(hosts, **params): reachable = tobiko.Selection() unreachable = tobiko.Selection() for host in hosts: try: result = ping(host, count=1, **params) except _exception.PingError: LOG.exception('Error pinging host: %r', host) unreachable.append(host) else: if result.received: reachable.append(host) else: unreachable.append(host) return reachable, unreachable
def list_podman_containers(client=None, **kwargs): try: containers = podman_client(client).containers.list(**kwargs) except _exception.DockerUrlNotFoundError: return tobiko.Selection() else: return tobiko.select(containers)
def list_ip_addresses(ip_version=None, **execute_params): inets = INETS.get(ip_version) if inets is None: error = "invalid IP version: {!r}".format(ip_version) raise IfconfigError(error=error) output = execute_ifconfig(**execute_params) ips = tobiko.Selection() for line in output.splitlines(): if line.startswith(' '): try: fields = line.strip().split() if fields[0] in inets: address = fields[1] if address.startswith('addr:'): address = address[len('addr:'):] if not address: address = fields[2] if '/' in address: address, _ = address.split('/', 1) ips.append(netaddr.IPAddress(address)) except IndexError: pass return ips
def list_server_ip_addresses(server, network_name=None, ip_version=None, address_type=None, check_connectivity=False, ssh_client=None, count=None): ips = tobiko.Selection() for _network_name, addresses in server.addresses.items(): if count and len(ips) == count: break # check network name if network_name and network_name != _network_name: continue for address in addresses: if check_server_ip_address(address, ip_version=ip_version, address_type=address_type): ips.append( netaddr.IPAddress(address['addr'], version=address['version'])) # check ICMP connectivity if check_connectivity: ips = ping.list_reachable_hosts(ips, ssh_client=ssh_client) return ips
def list_ip_addresses(ip_version: int = None, device: str = None, scope: str = None, **execute_params) -> \ tobiko.Selection[netaddr.IPAddress]: inets = INETS.get(ip_version) if inets is None: error = "invalid IP version: {!r}".format(ip_version) raise IpError(error=error) command = ['-o', 'address', 'list'] if device is not None: tobiko.check_valid_type(device, str) command.append(device) output = execute_ip(command, **execute_params) ips: tobiko.Selection[netaddr.IPAddress] = tobiko.Selection() if output: for line in output.splitlines(): fields = line.strip().split() inet = fields[2] if inet not in inets: continue # List only address of selected IP version if scope: try: scope_index = fields.index('scope') if fields[scope_index + 1] != scope: continue except (IndexError, ValueError): continue address, _ = parse_ip_address(fields[3]) ips.append(address) return ips
def list_ip_addresses(ip_version=None, scope=None, **execute_params): inets = INETS.get(ip_version) if inets is None: error = "invalid IP version: {!r}".format(ip_version) raise IpError(error=error) output = execute_ip(['-o', 'address', 'list'], **execute_params) ips = tobiko.Selection() if output: for line in output.splitlines(): fields = line.strip().split() inet = fields[2] if inet not in inets: continue # List only address of selected IP version if scope: try: scope_index = fields.index('scope') if fields[scope_index + 1] != scope: continue except (IndexError, ValueError): continue address = fields[3] if '/' in address: # Remove netmask prefix length address, _ = address.split('/', 1) ips.append(netaddr.IPAddress(address)) return ips
def get_group(self, group: str) \ -> tobiko.Selection[OpenStackTopologyNode]: tobiko.check_valid_type(group, str) try: return tobiko.Selection(self._groups[group]) except KeyError as ex: raise _exception.NoSuchOpenStackTopologyNodeGroup( group=group) from ex
def get_container_states_list(containers_list, include_container_objects=False): container_states_list = tobiko.Selection() container_states_list.extend([ comparable_container_keys( container, include_container_objects=include_container_objects) for container in containers_list ]) return container_states_list
def list_network_namespaces(**execute_params): output = execute_ip(['-o', 'netns', 'list'], **execute_params) namespaces = tobiko.Selection() if output: for line in output.splitlines(): fields = line.strip().split() namespace = fields[0] namespaces.append(namespace) return namespaces
def list_docker_containers(client=None, **kwargs): try: containers = docker_client(client).containers.list(all=True, sparse=True, **kwargs) except _exception.DockerUrlNotFoundError: return tobiko.Selection() else: return tobiko.select(containers)
def list_port_ip_addresses(port, subnet_id=None, ip_version=None, check_connectivity=False, ssh_client=None): selected_addresses = [] for fixed_ip in port['fixed_ips']: if subnet_id and subnet_id != fixed_ip['subnet_id']: continue ip_address = netaddr.IPAddress(fixed_ip['ip_address']) if ip_version and ip_version != ip_address.version: continue if check_connectivity and not ping.ping( host=ip_address, ssh_client=ssh_client).received: continue selected_addresses.append(ip_address) return tobiko.Selection(selected_addresses)
def list_port_ip_addresses(port: NeutronPortType, subnet_id: typing.Optional[str] = None, ip_version: typing.Optional[int] = None, check_connectivity: bool = False, ssh_client: ssh.SSHClientFixture = None) -> \ tobiko.Selection[netaddr.IPAddress]: addresses = tobiko.Selection[netaddr.IPAddress]( netaddr.IPAddress(fixed_ip['ip_address']) for fixed_ip in port['fixed_ips'] if subnet_id is None or subnet_id == fixed_ip['subnet_id']) if ip_version: addresses = addresses.with_attributes(version=ip_version) if addresses and check_connectivity: hosts = ping.list_reachable_hosts(addresses, ssh_client=ssh_client) addresses = tobiko.Selection(netaddr.IPAddress(host) for host in hosts) return addresses
def list_nameservers(ssh_client: typing.Optional[ssh.SSHClientFixture] = None, filenames: typing.Optional[typing.Iterable[str]] = None, ip_version: typing.Optional[int] = None, **execute_params) -> \ tobiko.Selection[netaddr.IPAddress]: if filenames is None: filenames = ['/etc/resolv.conf'] nameservers: tobiko.Selection[netaddr.IPAddress] = tobiko.Selection() for filename in filenames: nameservers.extend( parse_resolv_conf_file(ssh_client=ssh_client, filename=filename, **execute_params)) if ip_version: nameservers = nameservers.with_attributes(version=ip_version) return nameservers
def wait_for_systemd_units_state( match_unit: typing.Callable[[SystemdUnit], bool], *pattern: str, state: str = None, type: str = None, ssh_client: ssh.SSHClientType = None, sudo: bool = None, check: bool = True, timeout: tobiko.Seconds = None, interval: tobiko.Seconds = None) \ -> tobiko.Selection[SystemdUnit]: all_units: typing.Dict[str, SystemdUnit] = collections.OrderedDict() bad_units = tobiko.Selection[SystemdUnit]() for attempt in tobiko.retry(timeout=timeout, interval=interval, default_timeout=30., default_interval=5.): units = list_systemd_units(*pattern, all=True, state=state, type=type, ssh_client=ssh_client, sudo=sudo) assert units all_units.update((unit.unit, unit) for unit in units) bad_units = units.select(match_unit, expect=False) if not bad_units: break LOG.info('Systemd unit(s) still on unexpected state:' f' expected: ({match_unit})...:\n' ' actual: \n' '\n'.join(f' - {u}' for u in bad_units)) if attempt.is_last: break pattern = tuple(u.unit for u in bad_units) if check: if bad_units: raise UnexpectedSystemctlUnitState(matcher=match_unit, units=bad_units) return tobiko.Selection(all_units.values())
def resolve_host_ips(host, port=0): tobiko.check_valid_type(host, six.string_types) LOG.debug('Calling getaddrinfo with host %r', host) ips = tobiko.Selection() try: addrinfo = socket.getaddrinfo(host, port, 0, 0, socket.AI_CANONNAME | socket.IPPROTO_TCP) except socket.gaierror: LOG.exception('Error calling getaddrinfo for host %r', host) else: for _, _, _, canonical_name, sockaddr in addrinfo: try: ips.append(netaddr.IPAddress(sockaddr[0])) except netaddr.AddrFormatError as ex: LOG.error("Invalid sockaddr for host %r: %r -> %r (%s)", host, canonical_name, sockaddr, ex) else: LOG.debug("IP address for host %r: %r -> %r", host, canonical_name, sockaddr) return ips
def list_containers(group=None): """get list of containers in running state from specified node group returns : a list of overcloud_node's running containers""" # moved here from topology # reason : Workaround for : # AttributeError: module 'tobiko.openstack.topology' has no # attribute 'container_runtime' if group is None: group = 'overcloud' containers_list = tobiko.Selection() openstack_nodes = topology.list_openstack_nodes(group=group) for node in openstack_nodes: LOG.debug(f"List containers for node {node.name}") node_containers_list = list_node_containers(ssh_client=node.ssh_client) containers_list.extend(node_containers_list) return containers_list
def list_device_ip_addresses(device_id: str, network_id: typing.Optional[str] = None, ip_version: typing.Optional[int] = None, check_connectivity: bool = False, ssh_client: ssh.SSHClientFixture = None, need_dhcp: typing.Optional[bool] = None, **subnet_params) -> \ tobiko.Selection[netaddr.IPAddress]: ports = _client.list_ports(device_id=device_id, network_id=network_id) if need_dhcp is not None: subnet_params['enable_dhcp'] = bool(need_dhcp) subnets = _client.list_subnets(network_id=network_id, ip_version=ip_version, **subnet_params) addresses = tobiko.Selection[netaddr.IPAddress]( port_ip for subnet in subnets for port in ports for port_ip in list_port_ip_addresses( port=port, subnet_id=subnet['id'], ip_version=ip_version)) if addresses and check_connectivity: hosts = ping.list_reachable_hosts(addresses, ssh_client=ssh_client) addresses = tobiko.Selection(netaddr.IPAddress(host) for host in hosts) return addresses
def list_addresses(obj, ip_version: typing.Optional[int] = None, port: typing.Union[int, str, None] = None, ssh_config: bool = False) -> \ tobiko.Selection[netaddr.IPAddress]: if isinstance(obj, tobiko.Selection): addresses = obj elif isinstance(obj, netaddr.IPAddress): addresses = tobiko.select([obj]) elif isinstance(obj, str): addresses = tobiko.select( list_host_addresses(obj, ip_version=ip_version, port=port, ssh_config=ssh_config)) elif isinstance(obj, abc.Sequence): addresses = tobiko.Selection() for item in iter(obj): addresses.extend(list_addresses(item)) if addresses and ip_version is not None: addresses = addresses.with_attributes(version=ip_version) return addresses
def list_host_addresses(host: str, ip_version: typing.Optional[int] = None, port: typing.Union[int, str, None] = None, ssh_config: bool = False) -> \ tobiko.Selection[netaddr.IPAddress]: if not port: if ssh_config: port = 22 # use the default port for SSH protocol else: port = 0 addresses: tobiko.Selection[netaddr.IPAddress] = tobiko.Selection() hosts = [host] resolved = set() while hosts: host = hosts.pop() if host in resolved: LOG.debug(f"Cyclic address resolution detected for host {host}") continue # already resolved resolved.add(host) # avoid resolving it again address = parse_ip_address(host) if address: addresses.append(address) continue # use socket host address resolution to get IP addresses addresses.extend( resolv_host_addresses(host=host, port=port, ip_version=ip_version)) if ssh_config: # get additional socket addresses from SSH configuration hosts.extend(list_ssh_hostconfig_hostnames(host)) if [host] != [str(address) for address in addresses]: LOG.debug(f"Host '{host}' addresses resolved as: {addresses}") return addresses
def create_selection(*args, **kwargs): return tobiko.Selection(*args, **kwargs)
def create_group() -> tobiko.Selection[OpenStackTopologyNode]: return tobiko.Selection()
def external_gateway_addresses(self): ips = tobiko.Selection() for port in self.external_geteway_ports: ips.extend(neutron.list_port_ip_addresses(port)) return ips
def create_group(self): return tobiko.Selection()