26c42f84c297ce6e349e4392212c78ee21c3d923
[pharos-tools.git] / pharos-validator / src / validation_tool / src / dhcp.py
1 ##############################################################################
2 # Copyright (c) 2015 Todd Gaunt and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 import yaml
11 import netifaces
12 import subprocess
13 import copy
14 import re
15 import os
16 import logging
17
18 from pharosvalidator.specification import *
19 from pharosvalidator import util
20
21 init_cmd = ["systemctl", "start", "dhcpd.service"]
22
23 def gen_dhcpd_file(dhcpdfile, nodes, network):
24     """Generates and associates incremental ip addresses to
25     MAC addresses according to restrictions placed by network
26     configuration file. Writes all of this out in dhcpd.conf format"""
27     logger = logging.getLogger(__name__)
28     logger.info("Generating dhcpfile...")
29
30     header = "default-lease-time 86400;\n\
31             max-lease-time 604800;\n\
32             max-lease-time 604800;\n\
33             \n\
34             allow booting;\n\
35             authoritative;\n\
36             \n"
37
38     # Skip this network if it is disabled
39     if network.enabled == False:
40         logger.info("Admin network is disabled, please change the configuration to \"enabled\" if you would like this test to run")
41         quit()
42
43     # Not explicitly in the cofiguration file
44     broadcastaddr = "0.0.0.0"
45     next_server = "0.0.0.0"
46
47     ip_range = util.gen_ip_range(network.cidr, [network.installer_ip], network.usable_ip_range.minimum, \
48             network.usable_ip_range.maximum)
49
50     tab = '    '
51     subnetconf = "subnet {} netmask {} {{\n".format(network.subnet, network.netmask)\
52             + tab+"range {} {};\n".format(network.usable_ip_range.minimum, network.usable_ip_range.maximum)\
53             + tab+"option broadcast-address {};\n".format(broadcastaddr)\
54             + tab+'filename "pxelinux.0";\n'\
55             + tab+"next-server {};\n".format(next_server)
56
57     # For now no static addresses are assigned
58     """
59     static_addrs = []
60     for node in nodes:
61         # Skip the node if it doesn't have a name or mac address specified
62         if not node.name or not node.mac_address:
63             continue
64
65         if node.ipmi_addr in ip_range:
66             ip_range.remove(node.ipmi_addr)
67
68         static_line = "host {node}  {{ hardware ethernet {ipmi_mac}; fixed-address {ip_addr}; }}\n".format\
69                 (node=node.name, ipmi_mac=node.mac_address, ip_addr=ip_range[0])
70         ip_range = ip_range[1::] # Remove the assigned ip address
71         static_addrs.append(static_line)
72
73     # Now add all statically assigned ip addresses
74     for addr in static_addrs:
75         subnetconf += tab+addr
76     """
77
78     subnetconf += "}\n" # Just the closing bracket
79
80     # The final text to be written out to a file
81     dhcpdtext = header + subnetconf
82
83     with open(dhcpdfile, "w+") as fd:
84         logger.info("Writing out dhcpd file to {}".format(dhcpdfile))
85         fd.write(dhcpdtext)
86
87     return dhcpdtext
88
89 def start_server():
90     logger = logging.getLogger(__name__)
91     global init_cmd
92     cmd = init_cmd
93     with open(os.devnull, 'w') as fn:
94         status = subprocess.Popen(cmd, stdout=fn, stderr=fn).wait()
95     if int(status) != 0:
96         logger.error("Could not bring up dhcpd server")
97     else:
98         logger.info("Dhcp server brought up")
99     return status
100
101 if __name__ == "__main__":
102     split("inventory.yaml", "eth0")