#!/usr/share/ucs-test/runner python3
## desc: Test creating DHCP entries for some computer roles
## tags: [udm-computers]
## roles: [domaincontroller_master]
## exposure: careful
## bugs: [16923]

from __future__ import print_function
import ldap.dn

import univention.testing.udm as udm_test
import univention.testing.strings as uts
import univention.testing.utils as utils

NET = '192.0.2'
MAC = '00:00:5e:00:53'
NAME = uts.random_name()
UNIQUE = range(2, 254).__iter__()


def main():
	for role in udm_test.UCSTestUDM.COMPUTER_MODULES:
		with udm_test.UCSTestUDM() as udm:
			service = udm.create_object('dhcp/service', service=uts.random_name())
			network = udm.create_object(
				'networks/network',
				name=uts.random_name(),
				network='%s.0' % (NET,),
				netmask='24',
				dhcpEntryZone=service,
				ipRange='%s.2 %s.253' % (NET, NET))

			print('Let Network choose the IP')
			computerName, mac, ip = create(udm, role, network=network)
			verify(computerName, service, mac)

			print('Give explicit IP, but DHCP from Network')
			computerName, mac, ip = create(udm, role, ip=True, network=network)
			verify(computerName, service, mac, ip=[ip])

			print('Manual DHCP with dynamic IP from known-hosts-pool')
			computerName, mac, ip = create(udm, role, dhcp=service)
			verify(computerName, service, mac, ip=[''])

			print('Manual DHCP with fixed IP')
			computerName, mac, ip = create(udm, role, ip=True, dhcp=service)
			verify(computerName, service, mac, ip=[ip])


def create(udm, role, ip=False, network=None, dhcp=None):
	unique = next(UNIQUE)
	computerName = "%s%d" % (NAME, unique)
	mac = '%s:%02x' % (MAC, unique)
	ip = '%s.%d' % (NET, unique) if ip else None
	dhcp = ' '.join(filter(None, [dhcp, ip, mac])) if dhcp else None
	udm.create_object(
		role,
		name=computerName,
		mac=mac,
		ip=ip,
		network=network,
		dhcpEntryZone=dhcp,
	)
	return computerName, mac, ip


def verify(computerName, service, mac, ip=None):
	dn = 'cn=%s,%s' % (ldap.dn.escape_dn_chars(computerName), service)
	expected = {
		'dhcpHWAddress': ['ethernet %s' % (mac,)],
		'univentionObjectType': ['dhcp/host'],
	}
	if ip is not None and ip != ['']:
		expected['univentionDhcpFixedAddress'] = ip
	utils.verify_ldap_object(dn, expected)
	if ip is None:
		lo = utils.get_ldap_connection()
		ip = lo.getAttr(dn, 'univentionDhcpFixedAddress')[0].decode('ASCII')
		assert ip.startswith('%s.' % (NET,))


if __name__ == '__main__':
	main()
