import random
from enum import Enum
from ipaddress import IPv4Interface, IPv4Network
from typing import TYPE_CHECKING, Optional # noqa: F401
import univention.testing.strings as uts
from ucsschool.lib.models.computer import (
IPComputer as IPComputerLib,
LinuxComputer as LinuxComputerLib,
MacComputer as MacComputerLib,
UbuntuComputer as UbuntuComputerLib,
WindowsComputer as WindowsComputerLib,
)
from univention.testing import utils
from univention.testing.ucsschool.importou import get_school_base
if TYPE_CHECKING:
from univention.admin.uldap import access as LoType # noqa: F401
[docs]
class SupportedComputer(Enum):
windows = 1
macos = 2
ipmanagedclient = 3
linux = 4
ubuntu = 5
[docs]
class IpIter(object):
# Hot fix for bug #38191
# Generate 110 different ip addresses in the range 11.x.x.x-120.x.x.x
# so each lie in a different network prefix >= 8
netmasks = ["/255.255.255.0", "/255.255.248.0", "/255.255.0.0"]
def __init__(self):
self.max_range = 120
self.index = 11
self.network_index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < self.max_range:
ip_list = [
self.index,
random.randint(1, 254),
random.randint(1, 254),
random.randint(1, 254),
]
ip = ".".join(map(str, ip_list))
self.index += 1
return ip
raise StopIteration()
[docs]
def next_network(self): # type: () -> str
# get network address from random IP address and next netmask
temp_address = self.next()
netmask = self.netmasks[self.network_index % len(self.netmasks)]
self.network_index += 1
address = IPv4Interface("{}{}".format(temp_address, netmask))
return "{}/{}".format(address.network.network_address, address.netmask)
next = __next__
[docs]
def random_ip(ip_iter=IpIter()): # type: (IpIter) -> str
return next(ip_iter)
[docs]
def random_network(ip_iter=IpIter()): # type: (IpIter) -> str
return ip_iter.next_network()
[docs]
def random_mac(): # type: () -> str
mac = [
random.randint(0x00, 0x7F),
random.randint(0x00, 0x7F),
random.randint(0x00, 0x7F),
random.randint(0x00, 0x7F),
random.randint(0x00, 0xFF),
random.randint(0x00, 0xFF),
]
return ":".join("%02x" % x for x in mac)
[docs]
class Computer(object):
def __init__(self, school, ctype): # type: (str, str) -> None
self.name = uts.random_name()
self.mac = [random_mac()]
self.ip = [random_ip()]
self.network = None
self.school = school
self.ctype = ctype
self.inventory_numbers = []
self.custom_secondary_mac_address = random_mac()
self.school_base = get_school_base(self.school)
self.dn = "cn=%s,cn=computers,%s" % (self.name, self.school_base)
[docs]
def get_args(self):
return {
"school": self.school,
"name": self.name,
"ip_address": self.ip,
"mac_address": self.mac,
"type_name": self.ctype,
"inventory_number": self.inventory_numbers,
}
[docs]
def set_network_address(self):
self.ip = []
self.network = [random_network()]
[docs]
def set_inventory_numbers(self):
self.inventory_numbers.append(uts.random_name())
self.inventory_numbers.append(uts.random_name())
def __str__(self):
_ip = self.ip[0] if self.ip else self.network[0]
_inventory_numbers = ",".join(self.inventory_numbers)
return "\t".join(
(
self.ctype,
self.name,
self.mac[0],
self.school,
_ip,
_inventory_numbers,
self.custom_secondary_mac_address,
)
)
[docs]
def expected_attributes(self):
attr = {
"cn": [self.name],
"macAddress": self.mac,
"univentionObjectType": ["computers/%s" % self.ctype],
}
if self.ip:
attr["aRecord"] = self.ip
if self.inventory_numbers:
attr["univentionInventoryNumber"] = self.inventory_numbers
if self.custom_secondary_mac_address:
attr["macAddress"].append(self.custom_secondary_mac_address)
return attr
[docs]
def verify(self):
print("verify computer: %s" % self.name)
utils.verify_ldap_object(self.dn, expected_attr=self.expected_attributes(), should_exist=True)
if self.network:
lo = utils.get_ldap_connection()
values = lo.get(self.dn, attr=["aRecord"])
network = IPv4Network(self.network[0])
assert "aRecord" in values
aRecord = IPv4Interface(values["aRecord"][0].decode("utf-8"))
assert aRecord in network, (self.name, aRecord, network)
[docs]
def create_test_computers(
lo,
school=None,
nr_windows=1,
nr_macos=0,
nr_ip_managed_clients=0,
nr_linux=0,
nr_ubuntu=0,
): # type: (LoType, Optional[str], int, int, int, int, int) -> list[Computer]
"""Utility function to create test computers (~ python import)"""
created_computers = []
school = school or uts.random_name()
for _i in range(nr_windows):
computer = Computer(school=school, ctype="windows")
WindowsComputerLib(**computer.get_args()).create(lo)
created_computers.append(computer)
for _i in range(nr_macos):
computer = Computer(school=school, ctype="macos")
MacComputerLib(**computer.get_args()).create(lo)
created_computers.append(computer)
for _i in range(nr_ip_managed_clients):
computer = Computer(school=school, ctype="ipmanagedclient")
IPComputerLib(**computer.get_args()).create(lo)
created_computers.append(computer)
for _i in range(nr_linux):
computer = Computer(school=school, ctype="linux")
LinuxComputerLib(**computer.get_args()).create(lo)
created_computers.append(computer)
for _i in range(nr_ubuntu):
computer = Computer(school=school, ctype="ubuntu")
UbuntuComputerLib(**computer.get_args()).create(lo)
created_computers.append(computer)
return sorted(created_computers, key=lambda x: x.name)
[docs]
class Computers(object):
# Utility class to create test computers (~ python import)
def __init__(
self,
lo,
school,
nr_windows=1,
nr_macos=0,
nr_ipmanagedclient=0,
nr_linux=0,
nr_ubuntu=0,
): # type: (LoType, str, int, int, int, int, int) -> None
self.lo = lo
self.school = school
self.nr_windows = nr_windows
self.nr_macos = nr_macos
self.nr_ip_managed_clients = nr_ipmanagedclient
self.nr_linux = nr_linux
self.nr_ubuntu = nr_ubuntu
[docs]
def create(self): # type: () -> list[Computer]
print("********** Create computers")
created_computers = []
school = self.school or uts.random_name()
for _i in range(self.nr_windows):
computer = Computer(school=school, ctype="windows")
WindowsComputerLib(**computer.get_args()).create(self.lo)
created_computers.append(computer)
for _i in range(self.nr_macos):
computer = Computer(school=school, ctype="macos")
MacComputerLib(**computer.get_args()).create(self.lo)
created_computers.append(computer)
for _i in range(self.nr_ip_managed_clients):
computer = Computer(school=school, ctype="ipmanagedclient")
IPComputerLib(**computer.get_args()).create(self.lo)
created_computers.append(computer)
for _i in range(self.nr_linux):
computer = Computer(school=school, ctype="linux")
LinuxComputerLib(**computer.get_args()).create(self.lo)
created_computers.append(computer)
for _i in range(self.nr_ubuntu):
computer = Computer(school=school, ctype="ubuntu")
UbuntuComputerLib(**computer.get_args()).create(self.lo)
created_computers.append(computer)
return sorted(created_computers, key=lambda x: x.name)
[docs]
@staticmethod
def get_dns(computers): # type: (list[Computer]) -> list[str]
return [x.dn for x in computers]
[docs]
@staticmethod
def get_hostnames(computers): # type: (list[Computer]) -> list[str]
return ["%s$" % x.name for x in computers]