|
3 | 3 | import logging
|
4 | 4 | from base64 import b32decode, b16encode
|
5 | 5 | from dataclasses import is_dataclass, asdict as dataclass_as_dict
|
6 |
| -from typing import Any, Optional, Coroutine |
| 6 | +from typing import Any, Optional, Coroutine, Tuple, Iterable |
7 | 7 |
|
8 | 8 | import aiodns
|
9 | 9 |
|
@@ -51,3 +51,53 @@ async def run_and_log_exception(coro: Coroutine):
|
51 | 51 | def create_task_log_exceptions(coro: Coroutine, *, name=None):
|
52 | 52 | """Ensure that exceptions running in coroutines are logged."""
|
53 | 53 | return asyncio.create_task(run_and_log_exception(coro), name=name)
|
| 54 | + |
| 55 | + |
| 56 | +def ipstr_to_int(ip_string: str) -> Tuple[int, int]: |
| 57 | + """Convert an IP address string with subnet mask to an integer |
| 58 | + representation of the IP and the mask separately. |
| 59 | + """ |
| 60 | + ip, mask = ip_string.split("/") |
| 61 | + ip_int = sum( |
| 62 | + int(octet) * 256**idx for idx, octet in enumerate(reversed(ip.split("."))) |
| 63 | + ) |
| 64 | + return ip_int, int(mask) |
| 65 | + |
| 66 | + |
| 67 | +def int_to_ipstr(ip_int: int, mask: int) -> str: |
| 68 | + """Converts an integer representation of an IP address and a subnetmask |
| 69 | + and turns it into a string representation |
| 70 | + """ |
| 71 | + ip_integers: Iterable[int] = ( |
| 72 | + (ip_int >> (8 * i)) & 0xFF for i in reversed(range(4)) |
| 73 | + ) |
| 74 | + ip_string: str = ".".join(str(i) for i in ip_integers) |
| 75 | + return f"{ip_string}/{mask}" |
| 76 | + |
| 77 | + |
| 78 | +def get_ip_addresses( |
| 79 | + vm_id: int, address_pool: str, ip_network_size: int |
| 80 | +) -> Tuple[str, str]: |
| 81 | + """Calculates the host and guest ip from vm_id and returns it as their string representations with subnetmask""" |
| 82 | + network_pool, pool_size = ipstr_to_int(address_pool) |
| 83 | + pool_netmask = 0xFFFFFFFF << 32 - pool_size |
| 84 | + network_part = vm_id << 32 - ip_network_size |
| 85 | + network_part_mask = 2 ** (ip_network_size - pool_size) - 1 << 32 - ip_network_size |
| 86 | + host = 1 |
| 87 | + guest = 2 |
| 88 | + hosts_mask = 2 ** (32 - ip_network_size) - 1 |
| 89 | + |
| 90 | + host_ip = ( |
| 91 | + (network_pool & pool_netmask) |
| 92 | + | (network_part & network_part_mask) |
| 93 | + | (host & hosts_mask) |
| 94 | + ) |
| 95 | + guest_ip = ( |
| 96 | + (network_pool & pool_netmask) |
| 97 | + | (network_part & network_part_mask) |
| 98 | + | (guest & hosts_mask) |
| 99 | + ) |
| 100 | + |
| 101 | + return int_to_ipstr(host_ip, ip_network_size), int_to_ipstr( |
| 102 | + guest_ip, ip_network_size |
| 103 | + ) |
0 commit comments