Source code for cobbler.modules.managers.isc

"""
This is some of the code behind 'cobbler sync'.
"""

from builtins import str
from builtins import object
import time
import copy

import cobbler.templar as templar
import cobbler.utils as utils

from cobbler.cexceptions import CX
from cobbler.utils import _


[docs]def register(): """ The mandatory cobbler module registration hook. """ return "manage"
[docs]class IscManager(object):
[docs] def what(self): return "isc"
def __init__(self, collection_mgr, logger): """ Constructor """ self.logger = logger self.collection_mgr = collection_mgr self.api = collection_mgr.api self.distros = collection_mgr.distros() self.profiles = collection_mgr.profiles() self.systems = collection_mgr.systems() self.settings = collection_mgr.settings() self.repos = collection_mgr.repos() self.templar = templar.Templar(collection_mgr) self.settings_file = utils.dhcpconf_location(self.api)
[docs] def write_dhcp_file(self): """ DHCP files are written when manage_dhcp is set in /etc/cobbler/settings. """ template_file = "/etc/cobbler/dhcp.template" blender_cache = {} try: f2 = open(template_file, "r") except: raise CX(_("error reading template: %s") % template_file) template_data = "" template_data = f2.read() f2.close() # use a simple counter for generating generic names where a hostname # is not available counter = 0 # we used to just loop through each system, but now we must loop # through each network interface of each system. dhcp_tags = {"default": {}} yaboot = "/yaboot" # FIXME: ding should evolve into the new dhcp_tags dict ding = {} ignore_macs = [] for system in self.systems: if not system.is_management_supported(cidr_ok=False): continue profile = system.get_conceptual_parent() distro = profile.get_conceptual_parent() # if distro is None then the profile is really an image record for (name, system_interface) in list(system.interfaces.items()): # We make a copy because we may modify it before adding it to the dhcp_tags # and we don't want to affect the master copy. interface = copy.deepcopy(system_interface) if interface["if_gateway"]: interface["gateway"] = interface["if_gateway"] else: interface["gateway"] = system.gateway mac = interface["mac_address"] if interface["interface_type"] in ("bond_slave", "bridge_slave", "bonded_bridge_slave"): if interface["interface_master"] not in system.interfaces: # Can't write DHCP entry; master interface does not exist continue # We may have multiple bonded interfaces, so we need a composite index into ding. name_master = "%s-%s" % (system.name, interface["interface_master"]) if name_master not in ding: ding[name_master] = {interface["interface_master"]: []} if len(ding[name_master][interface["interface_master"]]) == 0: ding[name_master][interface["interface_master"]].append(mac) else: ignore_macs.append(mac) ip = system.interfaces[interface["interface_master"]]["ip_address"] netmask = system.interfaces[interface["interface_master"]]["netmask"] dhcp_tag = system.interfaces[interface["interface_master"]]["dhcp_tag"] host = system.interfaces[interface["interface_master"]]["dns_name"] if ip is None or ip == "": for (nam2, int2) in list(system.interfaces.items()): if (nam2.startswith(interface["interface_master"] + ".") and int2["ip_address"] is not None and int2["ip_address"] != ""): ip = int2["ip_address"] break interface["ip_address"] = ip interface["netmask"] = netmask else: ip = interface["ip_address"] netmask = interface["netmask"] dhcp_tag = interface["dhcp_tag"] host = interface["dns_name"] if distro is not None: interface["distro"] = distro.to_dict() if mac is None or mac == "": # can't write a DHCP entry for this system continue counter = counter + 1 # the label the entry after the hostname if possible if host is not None and host != "": if name != "eth0": interface["name"] = "%s-%s" % (host, name) else: interface["name"] = "%s" % (host) else: interface["name"] = "generic%d" % counter # add references to the system, profile, and distro # for use in the template if system.name in blender_cache: blended_system = blender_cache[system.name] else: blended_system = utils.blender(self.api, False, system) blender_cache[system.name] = blended_system interface["next_server"] = blended_system["next_server"] interface["netboot_enabled"] = blended_system["netboot_enabled"] interface["hostname"] = blended_system["hostname"] interface["owner"] = blended_system["name"] interface["enable_gpxe"] = blended_system["enable_gpxe"] interface["name_servers"] = blended_system["name_servers"] interface["mgmt_parameters"] = blended_system["mgmt_parameters"] # Explicitly declare filename for other (non x86) archs as in DHCP discover # package mostly the architecture cannot be differed due to missing bits... if distro is not None and not interface.get("filename"): if distro.arch == "ppc" or distro.arch == "ppc64": interface["filename"] = yaboot elif distro.arch == "ppc64le": interface["filename"] = "grub/grub.ppc64le" elif distro.arch == "aarch64": interface["filename"] = "grub/grubaa64.efi" if not self.settings.always_write_dhcp_entries: if not interface["netboot_enabled"] and interface['static']: continue if dhcp_tag == "": dhcp_tag = blended_system.get("dhcp_tag", "") if dhcp_tag == "": dhcp_tag = "default" if dhcp_tag not in dhcp_tags: dhcp_tags[dhcp_tag] = { mac: interface } else: dhcp_tags[dhcp_tag][mac] = interface # remove macs from redundant slave interfaces from dhcp_tags # otherwise you get duplicate ip's in the installer for dt in list(dhcp_tags.keys()): for m in list(dhcp_tags[dt].keys()): if m in ignore_macs: del dhcp_tags[dt][m] # we are now done with the looping through each interface of each system metadata = { "date": time.asctime(time.gmtime()), "cobbler_server": "%s:%s" % (self.settings.server, self.settings.http_port), "next_server": self.settings.next_server, "yaboot": yaboot, "dhcp_tags": dhcp_tags } if self.logger is not None: self.logger.info("generating %s" % self.settings_file) self.templar.render(template_data, metadata, self.settings_file, None)
[docs] def regen_ethers(self): pass # ISC/BIND do not use this
[docs] def sync_dhcp(self): restart_dhcp = str(self.settings.restart_dhcp).lower() service_name = utils.dhcp_service_name(self.api) if restart_dhcp != "0": rc = utils.subprocess_call(self.logger, "dhcpd -t -q", shell=True) if rc != 0: error_msg = "dhcpd -t failed" self.logger.error(error_msg) raise CX(error_msg) service_restart = "service %s restart" % service_name rc = utils.subprocess_call(self.logger, service_restart, shell=True) if rc != 0: error_msg = "%s failed" % service_name self.logger.error(error_msg) raise CX(error_msg)
[docs]def get_manager(collection_mgr, logger): return IscManager(collection_mgr, logger)