Source code for ucsschool.lib.models.network

#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# UCS@school python lib: models
#
# Copyright 2014-2025 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.

from ipaddress import AddressValueError, IPv4Interface, NetmaskValueError

from ldap.dn import escape_dn_chars

from univention.admin.uexceptions import noObject

from .attributes import Netmask, NetworkAttribute, NetworkBroadcastAddress, SubnetName
from .base import UCSSchoolHelperAbstractClass
from .dhcp import DHCPSubnet
from .utils import _, ucr


[docs] class Network(UCSSchoolHelperAbstractClass): netmask = Netmask(_("Netmask")) network = NetworkAttribute(_("Network")) broadcast = NetworkBroadcastAddress(_("Broadcast")) _netmask_cache = {}
[docs] @classmethod def get_container(cls, school): return cls.get_search_base(school).networks
[docs] def get_subnet(self): # WORKAROUND for Bug #14795 subnetbytes = 0 netmask_parts = self.netmask.split(".") for part in netmask_parts: if part == "255": subnetbytes += 1 else: break return ".".join(self.network.split(".")[:subnetbytes])
[docs] def create_without_hooks(self, lo, validate): dns_reverse_zone = DNSReverseZone.cache(self.get_subnet()) dns_reverse_zone.create(lo) dhcp_service = self.get_school_obj(lo).get_dhcp_service() dhcp_subnet = DHCPSubnet( name=self.network, school=self.school, subnet_mask=self.netmask, broadcast=self.broadcast, dhcp_service=dhcp_service, ) dhcp_subnet.create(lo) # TODO: # set netbios and router for dhcp subnet # if defaultrouter: # print 'setting default router' # set_router_for_subnet (network, defaultrouter, schoolNr) # if netbiosserver: # print 'setting netbios server' # set_netbiosserver_for_subnet (network, netbiosserver, schoolNr) # set default value for nameserver # if nameserver: # print 'setting nameserver' # set_nameserver_for_subnet (network, nameserver, schoolNr) return super(Network, self).create_without_hooks(lo, validate)
[docs] def do_create(self, udm_obj, lo): from ucsschool.lib.models.school import School # TODO: # if iprange: # object['ipRange']=[[str(iprange[0]), str(iprange[1])]] # TODO: this is a DHCPServer created when school is created (not implemented yet) udm_obj["dhcpEntryZone"] = "cn=%s,cn=dhcp,%s" % ( escape_dn_chars(self.school), School.cache(self.school).dn, ) udm_obj["dnsEntryZoneForward"] = "zoneName=%s,cn=dns,%s" % ( escape_dn_chars(ucr.get("domainname")), ucr.get("ldap/base"), ) reversed_subnet = ".".join(reversed(self.get_subnet().split("."))) udm_obj["dnsEntryZoneReverse"] = "zoneName=%s.in-addr.arpa,cn=dns,%s" % ( escape_dn_chars(reversed_subnet), ucr.get("ldap/base"), ) return super(Network, self).do_create(udm_obj, lo)
[docs] @classmethod def invalidate_cache(cls): super(Network, cls).invalidate_cache() cls._netmask_cache.clear()
[docs] @classmethod def get_netmask(cls, dn, school, lo): if dn not in cls._netmask_cache: try: network = cls.from_dn(dn, school, lo) except noObject: return netmask = network.netmask # e.g. '24' network_str = u"0.0.0.0/%s" % netmask try: ipv4_network = IPv4Interface(network_str) except (AddressValueError, NetmaskValueError, ValueError): cls.logger.warning("Unparsable network: %r", network_str) else: netmask = str(ipv4_network.netmask) # e.g. '255.255.255.0' cls.logger.debug("Network mask: %r is %r", dn, netmask) cls._netmask_cache[dn] = netmask return cls._netmask_cache[dn]
[docs] class Meta: udm_module = "networks/network"
[docs] class DNSReverseZone(UCSSchoolHelperAbstractClass): name = SubnetName(_("Subnet")) school = None
[docs] @classmethod def get_container(cls, school=None): return "cn=dns,%s" % ucr.get("ldap/base")
[docs] def do_create(self, udm_obj, lo): udm_obj["nameserver"] = ucr.get("ldap/master") udm_obj["contact"] = "root@%s" % ucr.get("domainname") return super(DNSReverseZone, self).do_create(udm_obj, lo)
[docs] class Meta: udm_module = "dns/reverse_zone"