Skip to content

Commit

Permalink
IPv6: dhcp/provisioner: make ipv6 aware
Browse files Browse the repository at this point in the history
If the admin network is IPv6 setup the ISC DHCPD server to configure
and use the IPv6 daemon. For this use a seperate set of ipv6 files
to list hosts and subnets as ipv6 hosts and subnets will fail if
v4 dhcp tries to load them.

Also make sure tftp is listening on both IPv4 and v6.

To make this all happen the Network class in the Barclamp::Inventory
library now tracks the ip_version of the network. Which is used to
make decisions through the DHCP and provisioner cookbooks.

To support backwards compatibilty with ipv4 config naming in the
DHCP barclamp a DhcpHelper was added to return config names in
an IPv4 or IPv6 way. The same pattern was used throughout the
barclamp in the early versions of this patch so it's been
refectered to the helper.

Finally, when dealing with some IPv6 addresses in URIs the address
needs to be wrapped. As such the network barclamp has grown a
NetworkHelper module to start gathering network related helper
method's, it's first is a wrap_ip function. Which will wrap an
address if it happens to an IPv6 address. This makes this available
to us anywhere in crowbar, so long as the network barclamp has been
applied, and as a core barclamp to crowbar, should be always.
  • Loading branch information
matthewoliver committed Mar 28, 2019
1 parent 30f1733 commit b5904df
Show file tree
Hide file tree
Showing 20 changed files with 215 additions and 58 deletions.
8 changes: 8 additions & 0 deletions chef/cookbooks/barclamp/libraries/barclamp_library.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class Network
attr_reader :vlan, :use_vlan
attr_reader :add_bridge, :add_ovs_bridge, :bridge_name
attr_reader :conduit
attr_reader :ip_version

def initialize(node, net, data)
@node = node
Expand All @@ -112,6 +113,13 @@ def initialize(node, net, data)
# let's resolve this only if needed
@interface = nil
@interface_list = nil

require "ipaddr"
@ip_version = if IPAddr.new(@subnet).ipv6?
"6"
else
"4"
end
end

def interface
Expand Down
14 changes: 13 additions & 1 deletion chef/cookbooks/dhcp/attributes/default.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

default[:dhcp][:interfaces] = ["eth0"]
default[:dhcp][:options] = [
default[:dhcp][:options][:v4] = [
"ddns-update-style none",
"allow booting",
"option option-128 code 128 = string",
Expand All @@ -10,4 +10,16 @@
"option dhcp-client-debug code 226 = unsigned integer 16",
"option dhcp-client-debug 0"
]
default[:dhcp][:options][:v6] = [
"ddns-update-style none",
"allow booting",
"option option-128 code 128 = string",
"option option-129 code 129 = text",
"option dhcp-client-state code 225 = unsigned integer 16",
"option dhcp-client-state 0",
"option dhcp-client-debug code 226 = unsigned integer 16",
"option dhcp-client-debug 0",
"option dhcp6.bootfile-url code 59 = string",
"option dhcp6.client-arch-type code 61 = array of unsigned integer 16"
]

10 changes: 10 additions & 0 deletions chef/cookbooks/dhcp/libraries/helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module DhcpHelper
def self.config_filename(base, ip_version, extension = ".conf")
if ip_version == "4"
extra = ""
else
extra = ip_version
end
"#{base}#{extra}#{extension}"
end
end
18 changes: 11 additions & 7 deletions chef/cookbooks/dhcp/providers/host.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
hostname: new_resource.hostname,
macaddress: new_resource.macaddress,
ipaddress: new_resource.ipaddress,
options: new_resource.options
options: new_resource.options,
prefix: new_resource.prefix,
ip_version: new_resource.ip_version
)
owner "root"
group "root"
Expand All @@ -35,7 +37,7 @@
end
utils_line "include \"#{filename}\";" do
action :add
file "/etc/dhcp3/hosts.d/host_list.conf"
file "/etc/dhcp3/hosts.d/#{DhcpHelper.config_filename("host_list", new_resource.ip_version)}"
if node[:provisioner][:enable_pxe]
notifies :restart, resources(service: "dhcp3-server"), :delayed
end
Expand All @@ -54,11 +56,13 @@
end
new_resource.updated_by_last_action(true)
end
utils_line "include \"#{filename}\";" do
action :remove
file "/etc/dhcp3/hosts.d/host_list.conf"
if node[:provisioner][:enable_pxe]
notifies :restart, resources(service: "dhcp3-server"), :delayed
["host_list.conf", "host_list6.conf"].each do |host_list|
utils_line "include \"#{filename}\";" do
action :remove
file "/etc/dhcp3/hosts.d/#{host_list}"
if node[:provisioner][:enable_pxe]
notifies :restart, resources(service: "dhcp3-server"), :delayed
end
end
end
end
Expand Down
18 changes: 11 additions & 7 deletions chef/cookbooks/dhcp/providers/subnet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
#

action :add do
subnet_template = DhcpHelper.config_filename("subnet", new_resource.ip_version, ".conf.erb")
filename = "/etc/dhcp3/subnets.d/#{new_resource.subnet}.conf"
template filename do
cookbook "dhcp"
source "subnet.conf.erb"
source subnet_template
variables(
network: new_resource.network,
options: new_resource.options,
Expand All @@ -31,9 +32,10 @@
notifies :restart, resources(service: "dhcp3-server"), :delayed
end
end
subnet_file = DhcpHelper.config_filename("subnet_list", new_resource.ip_version)
utils_line "include \"#{filename}\";" do
action :add
file "/etc/dhcp3/subnets.d/subnet_list.conf"
file "/etc/dhcp3/subnets.d/#{subnet_file}"
if node[:provisioner][:enable_pxe]
notifies :restart, resources(service: "dhcp3-server"), :delayed
end
Expand All @@ -52,11 +54,13 @@
end
new_resource.updated_by_last_action(true)
end
utils_line "include \"#{filename}\";" do
action :remove
file "/etc/dhcp3/subnets.d/subnet_list.conf"
if node[:provisioner][:enable_pxe]
notifies :restart, resources(service: "dhcp3-server"), :delayed
["subnet_list.conf", "subnet_list6.conf"].each do |subnet_list|
utils_line "include \"#{filename}\";" do
action :remove
file "/etc/dhcp3/subnets.d/#{subnet_list}"
if node[:provisioner][:enable_pxe]
notifies :restart, resources(service: "dhcp3-server"), :delayed
end
end
end
end
Expand Down
40 changes: 23 additions & 17 deletions chef/cookbooks/dhcp/recipes/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,25 @@
directory "/etc/dhcp3/subnets.d"
directory "/etc/dhcp3/hosts.d"

file "/etc/dhcp3/groups.d/group_list.conf" do
# This needs to be evaled.
admin_network = Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin")
address = admin_network.address
intfs = [admin_network.interface]

group_list = DhcpHelper.config_filename("group_list", admin_network.ip_version)
file "/etc/dhcp3/groups.d/#{group_list}" do
owner "root"
group "root"
mode 0644
end
file "/etc/dhcp3/subnets.d/subnet_list.conf" do
subnet_list = DhcpHelper.config_filename("subnet_list", admin_network.ip_version)
file "/etc/dhcp3/subnets.d/#{subnet_list}" do
owner "root"
group "root"
mode 0644
end
file "/etc/dhcp3/hosts.d/host_list.conf" do
host_list = DhcpHelper.config_filename("host_list", admin_network.ip_version)
file "/etc/dhcp3/hosts.d/#{host_list}" do
owner "root"
group "root"
mode 0644
Expand All @@ -59,22 +67,20 @@
not_if "test -f /etc/dhcp3/omapi.key"
end

# This needs to be evaled.
intfs = [Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin").interface]
address = Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin").address

d_opts = node[:dhcp][:options]
d_opts = node[:dhcp][:options]["v#{admin_network.ip_version}"]
dhcpd_conf = DhcpHelper.config_filename("dhcpd", admin_network.ip_version)

case node[:platform_family]
when "debian"
case node[:lsb][:codename]
when "natty","oneiric","precise"
template "/etc/dhcp/dhcpd.conf" do
template "/etc/dhcp/#{dhcpd_conf}" do
owner "root"
group "root"
mode 0644
source "dhcpd.conf.erb"
variables(options: d_opts)
variables(options: d_opts, ip_version: admin_network.ip_version)
if node[:provisioner][:enable_pxe]
notifies :restart, "service[dhcp3-server]"
end
Expand All @@ -90,12 +96,12 @@
end
end
else
template "/etc/dhcp3/dhcpd.conf" do
template "/etc/dhcp3/#{dhcpd_conf}" do
owner "root"
group "root"
mode 0644
source "dhcpd.conf.erb"
variables(options: d_opts)
variables(options: d_opts, ip_version: admin_network.ip_version)
if node[:provisioner][:enable_pxe]
notifies :restart, "service[dhcp3-server]"
end
Expand All @@ -115,17 +121,17 @@

dhcp_config_file = case
when node[:platform_version].to_f >= 6
"/etc/dhcp/dhcpd.conf"
"/etc/dhcp/#{dhcpd_conf}"
else
"/etc/dhcpd.conf"
"/etc/#{dhcpd_conf}"
end

template dhcp_config_file do
owner "root"
group "root"
mode 0644
source "dhcpd.conf.erb"
variables(options: d_opts)
variables(options: d_opts, ip_version: admin_network.ip_version)
if node[:provisioner][:enable_pxe]
notifies :restart, "service[dhcp3-server]"
end
Expand All @@ -143,12 +149,12 @@
end

when "suse"
template "/etc/dhcpd.conf" do
template "/etc/#{dhcpd_conf}" do
owner "root"
group "root"
mode 0644
source "dhcpd.conf.erb"
variables(options: d_opts)
variables(options: d_opts, ip_version: admin_network.ip_version)
if node[:provisioner][:enable_pxe]
notifies :restart, "service[dhcp3-server]"
end
Expand All @@ -168,7 +174,7 @@

service "dhcp3-server" do
if %w(suse rhel).include?(node[:platform_family])
service_name "dhcpd"
service_name DhcpHelper.config_filename("dhcpd", admin_network.ip_version, "")
elsif node[:platform] == "ubuntu"
case node[:lsb][:codename]
when "maverick"
Expand Down
2 changes: 2 additions & 0 deletions chef/cookbooks/dhcp/resources/host.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
attribute :hostname, kind_of: String
attribute :macaddress, kind_of: String
attribute :ipaddress, kind_of: String
attribute :prefix, kind_of: String
attribute :ip_version, kind_of: String, default: "4"
attribute :group, kind_of: String
attribute :options, kind_of: Array, default: []

1 change: 1 addition & 0 deletions chef/cookbooks/dhcp/resources/subnet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@
attribute :pools, kind_of: Array, default: ["dhcp"]
attribute :pool_options, kind_of: Hash, default: { "dhcp" => ["allow unknown-hosts"] }
attribute :options, kind_of: Array, default: []
attribute :ip_version, kind_of: String, default: "4"

6 changes: 6 additions & 0 deletions chef/cookbooks/dhcp/templates/default/dhcpd.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ log-facility local7;
# Fix for https://bugzilla.opensuse.org/show_bug.cgi?id=961536
always-reply-rfc1048 true;

<% if @ip_version == "6" -%>
include "/etc/dhcp3/groups.d/group_list6.conf";
include "/etc/dhcp3/subnets.d/subnet_list6.conf";
include "/etc/dhcp3/hosts.d/host_list6.conf";
<% else -%>
include "/etc/dhcp3/groups.d/group_list.conf";
include "/etc/dhcp3/subnets.d/subnet_list.conf";
include "/etc/dhcp3/hosts.d/host_list.conf";
<% end -%>
5 changes: 5 additions & 0 deletions chef/cookbooks/dhcp/templates/default/host.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ host <%= @name %> {
option host-name "<%= @hostname %>";
hardware ethernet <%= @macaddress %>;
<% if @ipaddress -%>
<% if @ip_version == "6" -%>
fixed-address6 <%= @ipaddress %>;
fixed-prefix6 <%= @prefix %>;
<% else -%>
fixed-address <%= @ipaddress %>;
<% end -%>
<% else -%>
deny booting;
<% end -%>
Expand Down
19 changes: 19 additions & 0 deletions chef/cookbooks/dhcp/templates/default/subnet6.conf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# File managed by Crowbar
<% if node[:provisioner][:enable_pxe] -%>

subnet6 <%= @network["subnet"] %>/<%= @network["netmask"]%> {
option subnet-mask <%= @network["netmask"] %>;
<% @options.each do |option| -%>
<%= option %>;
<% end -%>
<% @pools.each do |pool| -%>
pool6 {
range6 <%=@network["ranges"][pool]["start"]%> <%=@network["ranges"][pool]["end"]%>;
<% @pool_options[pool].each do |opt| -%>
<%=opt%><%=if opt[-1,1] != '}' then ';' else '' end%>
<% end if @pool_options[pool] -%>
}
<% end -%>
}

<% end -%>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Do not edit.
<% unless @interfaces.empty? -%>
DHCPD_INTERFACE="<%= @interfaces.collect! {|i| "#{i}" }.join(" ") %>"
DHCPD6_INTERFACE="<%= @interfaces.collect! {|i| "#{i}" }.join(" ") %>"
<% end -%>
DHCPD_IFUP_RESTART=""
DHCPD_RUN_CHROOTED="no"
Expand Down
12 changes: 12 additions & 0 deletions chef/cookbooks/network/libraries/helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module NetworkHelper
def self.wrap_ip(address)
require "ipaddr"
if IPAddr.new(address).ipv6?
"[#{address}]"
else
address.to_s
end
rescue
address.to_s
end
end
2 changes: 1 addition & 1 deletion chef/cookbooks/provisioner/recipes/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@
crowbar_node = node_search_with_cache("roles:crowbar").first
address = crowbar_node["crowbar"]["network"]["admin"]["address"]
protocol = crowbar_node["crowbar"]["apache"]["ssl"] ? "https" : "http"
server = "#{protocol}://#{address}"
server = "#{protocol}://#{NetworkHelper.wrap_ip(address)}"
password = crowbar_node["crowbar"]["users"]["crowbar"]["password"]
verify_ssl = !crowbar_node["crowbar"]["apache"]["insecure"]

Expand Down
Loading

0 comments on commit b5904df

Please sign in to comment.