modules: dhcp: Add an mgmt module for managing dhcpd
This is not perfect, but it's a good start, and it shows how a module might be structured.
This commit is contained in:
55
modules/dhcp/files/dhcpd.conf.tmpl
Normal file
55
modules/dhcp/files/dhcpd.conf.tmpl
Normal file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# This file has been generated by mgmt config. Do not edit.
|
||||
#
|
||||
|
||||
# DHCP Server Configuration file.
|
||||
# see /usr/share/doc/dhcp-server/dhcpd.conf.example
|
||||
# see dhcpd.conf(5) man page
|
||||
#
|
||||
|
||||
#
|
||||
# global option definitions
|
||||
#
|
||||
{{ if .domain -}}
|
||||
option domain-name "{{ .domain }}";
|
||||
{{ end -}}
|
||||
{{ if .dns -}}
|
||||
option domain-name-servers {{ .dns }};
|
||||
{{ end -}}
|
||||
|
||||
#
|
||||
# dhcpd settings
|
||||
#
|
||||
{{ if .omapiport -}}
|
||||
#omapi-port {{ .omapiport }}; # FIXME !
|
||||
{{ end -}}
|
||||
{{ if .serveridentifier -}}
|
||||
#server-identifier {{ .serveridentifier }}; # FIXME !
|
||||
{{ end -}}
|
||||
default-lease-time {{ .defaultleasetime }};
|
||||
max-lease-time {{ .maxleasetime }};
|
||||
|
||||
# Use this to enable / disable dynamic dns updates globally.
|
||||
#ddns-update-style none;
|
||||
|
||||
# If this DHCP server is the official DHCP server for the local
|
||||
# network, the authoritative directive should be uncommented.
|
||||
{{ if .authoritative -}}
|
||||
authoritative;
|
||||
{{ else -}}
|
||||
#authoritative; # not authoritative!
|
||||
{{ end -}}
|
||||
|
||||
# Use this to send dhcp log messages to a different log file (you also
|
||||
# have to hack syslog.conf to complete the redirection).
|
||||
log-facility local7;
|
||||
|
||||
#
|
||||
# include all the subnet definitions
|
||||
#
|
||||
include "/etc/dhcp/subnets.conf";
|
||||
|
||||
#
|
||||
# include all the hosts
|
||||
#
|
||||
include "/etc/dhcp/hosts.conf";
|
||||
19
modules/dhcp/files/host.frag.tmpl
Normal file
19
modules/dhcp/files/host.frag.tmpl
Normal file
@@ -0,0 +1,19 @@
|
||||
{{/* newline for host spacing */}}
|
||||
# host: {{ .name }}
|
||||
host {{ .name }} {
|
||||
hardware ethernet {{ .macaddress }};
|
||||
fixed-address {{ .valid_fixedaddress }};
|
||||
{{- if .hostname }}
|
||||
option host-name "{{ .hostname }}";
|
||||
{{ end -}}
|
||||
{{- if .nextserver }}
|
||||
next-server {{ .nextserver }};
|
||||
{{ end -}}
|
||||
{{- if .filename }}
|
||||
filename "{{ .filename }}";
|
||||
{{ end -}}
|
||||
{{- if .veo }}
|
||||
filename "{{ .filename }}";
|
||||
option vendor-encapsulated-options {{ .veo }};
|
||||
{{ end -}}
|
||||
}
|
||||
3
modules/dhcp/files/hosts.header
Normal file
3
modules/dhcp/files/hosts.header
Normal file
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# This has been generated by mgmt config. Do not edit.
|
||||
#
|
||||
34
modules/dhcp/files/subnet.frag.tmpl
Normal file
34
modules/dhcp/files/subnet.frag.tmpl
Normal file
@@ -0,0 +1,34 @@
|
||||
{{/* newline for subnet spacing */}}
|
||||
#
|
||||
# {{ .name }} subnet
|
||||
#
|
||||
subnet {{ .network }} netmask {{ .netmask }} {
|
||||
option subnet-mask {{ .netmask }};
|
||||
{{- if .broadcast }}
|
||||
option broadcast-address {{ .broadcast }};
|
||||
{{ end -}}
|
||||
{{- if .router }}
|
||||
option routers {{ .router }};
|
||||
{{ end -}}
|
||||
{{- if .dns }}
|
||||
option domain-name-servers {{ .dns }};
|
||||
{{ end -}}
|
||||
{{- if .nextserver }}
|
||||
next-server {{ .nextserver }};
|
||||
{{ end -}}
|
||||
{{- if .filename }}
|
||||
filename "{{ .filename }}";
|
||||
{{ end -}}
|
||||
{{- if .serveridentifier }}
|
||||
server-identifier {{ .serveridentifier }};
|
||||
{{ end -}}
|
||||
{{- if .defaultleasetime }}
|
||||
default-lease-time {{ .defaultleasetime }};
|
||||
{{ end -}}
|
||||
{{- if .maxleasetime }}
|
||||
max-lease-time {{ .maxleasetime }};
|
||||
{{ end -}}
|
||||
{{- if .range }}
|
||||
range {{ .range }};
|
||||
{{ end -}}
|
||||
}
|
||||
3
modules/dhcp/files/subnets.header
Normal file
3
modules/dhcp/files/subnets.header
Normal file
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# This has been generated by mgmt config. Do not edit.
|
||||
#
|
||||
213
modules/dhcp/main.mcl
Normal file
213
modules/dhcp/main.mcl
Normal file
@@ -0,0 +1,213 @@
|
||||
# Mgmt
|
||||
# Copyright (C) 2013-2024+ James Shubin and the project contributors
|
||||
# Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Additional permission under GNU GPL version 3 section 7
|
||||
#
|
||||
# If you modify this program, or any covered work, by linking or combining it
|
||||
# with embedded mcl code and modules (and that the embedded mcl code and
|
||||
# modules which link with this program, contain a copy of their source code in
|
||||
# the authoritative form) containing parts covered by the terms of any other
|
||||
# license, the licensors of this program grant you additional permission to
|
||||
# convey the resulting work. Furthermore, the licensors of this program grant
|
||||
# the original author, James Shubin, additional permission to update this
|
||||
# additional permission if he deems it necessary to achieve the goals of this
|
||||
# additional permission.
|
||||
|
||||
import "deploy"
|
||||
import "fmt"
|
||||
import "golang"
|
||||
import "local"
|
||||
import "golang/strings"
|
||||
|
||||
class server($st) {
|
||||
$defaultleasetime = $st->defaultleasetime || 600
|
||||
$maxleasetime = $st->maxleasetime || 7200
|
||||
|
||||
$tmpl = struct{
|
||||
defaultleasetime => $defaultleasetime,
|
||||
maxleasetime => $maxleasetime,
|
||||
}
|
||||
|
||||
pkg "dhcp-server" {
|
||||
state => "installed",
|
||||
|
||||
Before => File["/etc/dhcp/"],
|
||||
}
|
||||
|
||||
file "/etc/dhcp/" {
|
||||
state => $const.res.file.state.exists,
|
||||
recurse => true,
|
||||
purge => true,
|
||||
owner => "root",
|
||||
group => "root",
|
||||
mode => "u=rwx,g=rx,o=", # dir
|
||||
}
|
||||
|
||||
file "/etc/dhcp/dhcpd.conf" {
|
||||
state => $const.res.file.state.exists,
|
||||
content => golang.template(deploy.readfile("/files/dhcpd.conf.tmpl"), $tmpl),
|
||||
owner => "root",
|
||||
group => "root",
|
||||
mode => "u=rw,go=",
|
||||
|
||||
Notify => Svc["dhcpd"],
|
||||
}
|
||||
|
||||
svc "dhcpd" {
|
||||
state => "running",
|
||||
startup => "enabled",
|
||||
}
|
||||
|
||||
$vardir = local.vardir("dhcp/")
|
||||
}
|
||||
|
||||
class server:subnet_base() {
|
||||
file "${vardir}subnets.d/" {
|
||||
state => $const.res.file.state.exists,
|
||||
recurse => true,
|
||||
purge => true,
|
||||
owner => "root",
|
||||
group => "root",
|
||||
mode => "u=rwx,g=rx,o=", # dir
|
||||
}
|
||||
|
||||
file "${vardir}subnets.header" {
|
||||
state => $const.res.file.state.exists,
|
||||
content => deploy.readfile("/files/subnets.header"), # static, no template!
|
||||
owner => "root",
|
||||
group => "root",
|
||||
mode => "u=rw,go=",
|
||||
}
|
||||
|
||||
|
||||
file "/etc/dhcp/subnets.conf" {
|
||||
state => $const.res.file.state.exists,
|
||||
fragments => [
|
||||
"${vardir}subnets.header",
|
||||
"${vardir}subnets.d/",
|
||||
],
|
||||
|
||||
Notify => Svc["dhcpd"],
|
||||
}
|
||||
}
|
||||
|
||||
class server:subnet($name, $st) {
|
||||
print "subnet: ${name}" {}
|
||||
include subnet_base
|
||||
|
||||
# TODO: We could compute many defaults from a single network CIDR.
|
||||
|
||||
$network str = $st->network # TODO: improve type unification
|
||||
$netmask = $st->netmask || "255.255.255.0"
|
||||
$broadcast = $st->broadcast || ""
|
||||
$router = $st->router || "" # TODO: eventually this could be a list
|
||||
$dns = $st->dns || [] # []str, local 'option domain-name-servers'
|
||||
$range = $st->range || struct{start => "", end => "",} # struct with start, end fields
|
||||
$range_start = $range->start || ""
|
||||
$range_end = $range->end || ""
|
||||
|
||||
$comment = $st->comment || ""
|
||||
|
||||
$valid_range = if $range_start != "" and $range_end != "" {
|
||||
"${range_start} ${range_end}"
|
||||
} else {
|
||||
"" # invalid
|
||||
}
|
||||
|
||||
$tmpl = struct{
|
||||
name => "${name}",
|
||||
network => "${network}", # the subnet
|
||||
netmask => "${netmask}",
|
||||
broadcast => "${broadcast}",
|
||||
router => "${router}", # TODO: support multiple
|
||||
dns => strings.join($dns, ", "),
|
||||
range => $valid_range,
|
||||
#nextserver => "${nextserver}",
|
||||
#filename => "${filename}",
|
||||
comment => "${comment}",
|
||||
}
|
||||
|
||||
file "${vardir}subnets.d/${name}.subnet" {
|
||||
state => $const.res.file.state.exists,
|
||||
content => golang.template(deploy.readfile("/files/subnet.frag.tmpl"), $tmpl),
|
||||
owner => "root",
|
||||
group => "root",
|
||||
mode => "u=rwx,g=rx,o=",
|
||||
}
|
||||
}
|
||||
|
||||
class server:host_base() {
|
||||
file "${vardir}hosts.d/" {
|
||||
state => $const.res.file.state.exists,
|
||||
recurse => true,
|
||||
purge => true,
|
||||
owner => "root",
|
||||
group => "root",
|
||||
mode => "u=rwx,g=rx,o=", # dir
|
||||
}
|
||||
|
||||
file "${vardir}hosts.header" {
|
||||
state => $const.res.file.state.exists,
|
||||
content => deploy.readfile("/files/hosts.header"), # static, no template!
|
||||
owner => "root",
|
||||
group => "root",
|
||||
mode => "u=rw,go=",
|
||||
}
|
||||
|
||||
|
||||
file "/etc/dhcp/hosts.conf" {
|
||||
state => $const.res.file.state.exists,
|
||||
fragments => [
|
||||
"${vardir}hosts.header",
|
||||
"${vardir}hosts.d/",
|
||||
],
|
||||
|
||||
Notify => Svc["dhcpd"],
|
||||
}
|
||||
}
|
||||
|
||||
class server:host($name, $st) {
|
||||
print "host: ${name}" {}
|
||||
include host_base
|
||||
|
||||
$macaddress = $st->macaddress
|
||||
$fixedaddress = $st->fixedaddress # []str
|
||||
$hostname = $st->hostname || ""
|
||||
$nextserver = $st->nextserver || ""
|
||||
$filename = $st->filename || ""
|
||||
$comment = $st->comment || ""
|
||||
|
||||
$tmpl = struct{
|
||||
name => "${name}",
|
||||
macaddress => "${macaddress}",
|
||||
valid_fixedaddress => strings.join($fixedaddress, ","),
|
||||
#fixedaddress => $fixedaddress, # TODO: when it's a list
|
||||
hostname => "${hostname}",
|
||||
nextserver => "${nextserver}",
|
||||
filename => "${filename}",
|
||||
veo => false, # TODO
|
||||
comment => "${comment}",
|
||||
}
|
||||
|
||||
file "${vardir}hosts.d/${name}.host" {
|
||||
state => $const.res.file.state.exists,
|
||||
content => golang.template(deploy.readfile("/files/host.frag.tmpl"), $tmpl),
|
||||
owner => "root",
|
||||
group => "root",
|
||||
mode => "u=rwx,g=rx,o=",
|
||||
}
|
||||
}
|
||||
0
modules/dhcp/metadata.yaml
Normal file
0
modules/dhcp/metadata.yaml
Normal file
Reference in New Issue
Block a user