37
41
maaslog = get_maas_logger("dhcp")
43
# Location of the DHCPv4 configuration file.
44
DHCPv4_CONFIG_FILE = '/etc/maas/dhcpd.conf'
46
# Location of the DHCPv4 interfaces file.
47
DHCPv4_INTERFACES_FILE = '/var/lib/maas/dhcpd-interfaces'
39
49
# Location of the DHCPv6 configuration file.
40
50
DHCPv6_CONFIG_FILE = '/etc/maas/dhcpd6.conf'
42
52
# Location of the DHCPv6 interfaces file.
43
53
DHCPv6_INTERFACES_FILE = '/var/lib/maas/dhcpd6-interfaces'
46
def configure_dhcpv6(omapi_key, subnet_configs):
47
"""Configure the DHCPv6 server, and restart it as appropriate.
49
:param omapi_key: OMAPI secret key.
50
:param subnet_configs: List of dicts with subnet parameters for each
51
subnet for which the DHCP server should serve DHCPv6. If no subnets
52
are defined, the DHCP server will be stopped.
55
# Message to put in the DHCP config file when the DHCP server gets stopped.
56
DISABLED_DHCP_SERVER = "# DHCP server stopped and disabled."
60
"""Represents the settings and controls for a DHCP server.
62
:cvar descriptive_name: A name to use for this server in human-readable
64
:cvar template_basename: The base filename for the template to use when
65
generating configuration for this server.
66
:cvar interfaces_filename: The full path and filename for the server's
68
:cvar config_filename: The full path and filename for the server's
70
:ivar omapi_key: The OMAPI secret key for the server.
55
interfaces = ' '.join(
56
sorted({subnet['interface'] for subnet in subnet_configs}))
57
dhcpd_config = get_config(
58
'dhcpd6.conf.template',
59
omapi_key=omapi_key, dhcp_subnets=subnet_configs)
61
sudo_write_file(DHCPv6_CONFIG_FILE, dhcpd_config)
62
sudo_write_file(DHCPv6_INTERFACES_FILE, interfaces)
63
except ExternalProcessError as e:
64
# ExternalProcessError.__unicode__ contains a generic failure message
65
# as well as the command and its error output. On the other hand,
66
# ExternalProcessError.output_as_unicode contains just the error
67
# output which is probably the best information on what went wrong.
68
# Log the full error information, but keep the exception message short
71
"Could not rewrite DHCPv6 server configuration "
72
"(for network interfaces %s): %s",
73
', '.join(interfaces), unicode(e))
74
raise CannotConfigureDHCP(
75
"Could not rewrite DHCPv6 server configuration: %s"
76
% e.output_as_unicode)
78
if len(subnet_configs) == 0:
81
except ExternalProcessError as e:
82
maaslog.error("DHCPv6 server failed to stop: %s", unicode(e))
83
raise CannotConfigureDHCP(
84
"DHCPv6 server failed to stop: %s" % e.output_as_unicode)
88
except ExternalProcessError as e:
73
__metaclass__ = ABCMeta
75
descriptive_name = abstractproperty()
76
template_basename = abstractproperty()
77
interfaces_filename = abstractproperty()
78
config_filename = abstractproperty()
80
def __init__(self, omapi_key):
81
super(DHCPServer, self).__init__()
82
self.omapi_key = omapi_key
86
"""Stop the DHCP server."""
90
"""Restart the DHCP server."""
92
def configure(self, subnet_configs):
93
"""Configure the DHCPv6/DHCPv4 server, and restart it as appropriate.
95
:param subnet_configs: List of dicts with subnet parameters for each
96
subnet for which the DHCP server should serve DHCP. If no subnets
97
are defined, the DHCP server will be stopped.
99
stopping = len(subnet_configs) == 0
102
dhcpd_config = DISABLED_DHCP_SERVER
104
dhcpd_config = get_config(
105
self.template_basename, omapi_key=self.omapi_key,
106
dhcp_subnets=subnet_configs)
108
interfaces = {subnet['interface'] for subnet in subnet_configs}
109
interfaces_config = ' '.join(sorted(interfaces))
112
sudo_write_file(self.config_filename, dhcpd_config)
113
sudo_write_file(self.interfaces_filename, interfaces_config)
114
except ExternalProcessError as e:
115
# ExternalProcessError.__unicode__ contains a generic failure
116
# message as well as the command and its error output. On the
117
# other hand, ExternalProcessError.output_as_unicode contains just
118
# the error output which is probably the best information on what
119
# went wrong. Log the full error information, but keep the
120
# exception message short and to the point.
90
"DHCPv6 server failed to restart "
91
"(for network interfaces %s): %s",
92
', '.join(interfaces), unicode(e))
122
"Could not rewrite %s server configuration (for network "
123
"interfaces %s): %s", self.descriptive_name,
124
interfaces_config, unicode(e))
93
125
raise CannotConfigureDHCP(
94
"DHCPv6 server failed to restart: %s" % e.output_as_unicode)
126
"Could not rewrite %s server configuration: %s" % (
127
self.descriptive_name, e.output_as_unicode))
132
except ExternalProcessError as e:
134
"%s server failed to stop: %s", self.descriptive_name,
136
raise CannotConfigureDHCP(
137
"%s server failed to stop: %s" % (
138
self.descriptive_name, e.output_as_unicode))
142
except ExternalProcessError as e:
144
"%s server failed to restart (for network interfaces "
145
"%s): %s", self.descriptive_name, interfaces_config,
147
raise CannotConfigureDHCP(
148
"%s server failed to restart: %s" % (
149
self.descriptive_name, e.output_as_unicode))
152
class DHCPv4Server(DHCPServer):
153
"""Represents the settings and controls for a DHCPv4 server.
158
descriptive_name = "DHCPv4"
159
template_basename = 'dhcpd.conf.template'
160
interfaces_filename = DHCPv4_INTERFACES_FILE
161
config_filename = DHCPv4_CONFIG_FILE
164
"""Stop the DHCPv4 server."""
165
control.stop_dhcpv4()
168
"""Restart the DHCPv4 server."""
169
control.restart_dhcpv4()
172
class DHCPv6Server(DHCPServer):
173
"""Represents the settings and controls for a DHCPv6 server.
178
descriptive_name = "DHCPv6"
179
template_basename = 'dhcpd6.conf.template'
180
interfaces_filename = DHCPv6_INTERFACES_FILE
181
config_filename = DHCPv6_CONFIG_FILE
184
"""Stop the DHCPv6 server."""
185
control.stop_dhcpv6()
188
"""Restart the DHCPv6 server."""
189
control.restart_dhcpv6()
97
192
def create_host_maps(mappings, shared_key):