Skip to content

Commit 2b0ac08

Browse files
committed
IPv6: dhcp/provisioner: make ipv6 aware
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.
1 parent 0a5369b commit 2b0ac08

File tree

20 files changed

+252
-70
lines changed

20 files changed

+252
-70
lines changed

chef/cookbooks/barclamp/libraries/barclamp_library.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class Network
9292
attr_reader :vlan, :use_vlan
9393
attr_reader :add_bridge, :add_ovs_bridge, :bridge_name
9494
attr_reader :conduit
95+
attr_reader :ip_version
9596

9697
def initialize(node, net, data)
9798
@node = node
@@ -112,6 +113,13 @@ def initialize(node, net, data)
112113
# let's resolve this only if needed
113114
@interface = nil
114115
@interface_list = nil
116+
117+
require "ipaddr"
118+
@ip_version = if IPAddr.new(@subnet).ipv6?
119+
"6"
120+
else
121+
"4"
122+
end
115123
end
116124

117125
def interface

chef/cookbooks/dhcp/attributes/default.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
default[:dhcp][:interfaces] = ["eth0"]
3-
default[:dhcp][:options] = [
3+
default[:dhcp][:options][:v4] = [
44
"ddns-update-style none",
55
"allow booting",
66
"option option-128 code 128 = string",
@@ -10,4 +10,17 @@
1010
"option dhcp-client-debug code 226 = unsigned integer 16",
1111
"option dhcp-client-debug 0"
1212
]
13+
default[:dhcp][:options][:v6] = [
14+
"ddns-update-style none",
15+
"allow booting",
16+
"option option-128 code 128 = string",
17+
"option option-129 code 129 = text",
18+
"option dhcp-client-state code 225 = unsigned integer 16",
19+
"option dhcp-client-state 0",
20+
"option dhcp-client-debug code 226 = unsigned integer 16",
21+
"option dhcp-client-debug 0",
22+
"option dhcp6.bootfile-url code 59 = string",
23+
"option dhcp6.client-arch-type code 61 = array of unsigned integer 16",
24+
"option dhcp6.vendor-class code 16 = {integer 32, integer 16, string}"
25+
]
1326

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module DhcpHelper
2+
def self.config_filename(base, ip_version, extension = ".conf")
3+
if ip_version == "4"
4+
extra = ""
5+
else
6+
extra = ip_version
7+
end
8+
"#{base}#{extra}#{extension}"
9+
end
10+
end

chef/cookbooks/dhcp/providers/host.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
hostname: new_resource.hostname,
2525
macaddress: new_resource.macaddress,
2626
ipaddress: new_resource.ipaddress,
27-
options: new_resource.options
27+
options: new_resource.options,
28+
prefix: new_resource.prefix,
29+
ip_version: new_resource.ip_version
2830
)
2931
owner "root"
3032
group "root"
@@ -35,7 +37,7 @@
3537
end
3638
utils_line "include \"#{filename}\";" do
3739
action :add
38-
file "/etc/dhcp3/hosts.d/host_list.conf"
40+
file "/etc/dhcp3/hosts.d/#{DhcpHelper.config_filename("host_list", new_resource.ip_version)}"
3941
if node[:provisioner][:enable_pxe]
4042
notifies :restart, resources(service: "dhcp3-server"), :delayed
4143
end
@@ -54,11 +56,13 @@
5456
end
5557
new_resource.updated_by_last_action(true)
5658
end
57-
utils_line "include \"#{filename}\";" do
58-
action :remove
59-
file "/etc/dhcp3/hosts.d/host_list.conf"
60-
if node[:provisioner][:enable_pxe]
61-
notifies :restart, resources(service: "dhcp3-server"), :delayed
59+
["host_list.conf", "host_list6.conf"].each do |host_list|
60+
utils_line "include \"#{filename}\";" do
61+
action :remove
62+
file "/etc/dhcp3/hosts.d/#{host_list}"
63+
if node[:provisioner][:enable_pxe]
64+
notifies :restart, resources(service: "dhcp3-server"), :delayed
65+
end
6266
end
6367
end
6468
end

chef/cookbooks/dhcp/providers/subnet.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
#
1515

1616
action :add do
17+
subnet_template = DhcpHelper.config_filename("subnet", new_resource.ip_version, ".conf.erb")
1718
filename = "/etc/dhcp3/subnets.d/#{new_resource.subnet}.conf"
1819
template filename do
1920
cookbook "dhcp"
20-
source "subnet.conf.erb"
21+
source subnet_template
2122
variables(
2223
network: new_resource.network,
2324
options: new_resource.options,
@@ -31,9 +32,10 @@
3132
notifies :restart, resources(service: "dhcp3-server"), :delayed
3233
end
3334
end
35+
subnet_file = DhcpHelper.config_filename("subnet_list", new_resource.ip_version)
3436
utils_line "include \"#{filename}\";" do
3537
action :add
36-
file "/etc/dhcp3/subnets.d/subnet_list.conf"
38+
file "/etc/dhcp3/subnets.d/#{subnet_file}"
3739
if node[:provisioner][:enable_pxe]
3840
notifies :restart, resources(service: "dhcp3-server"), :delayed
3941
end
@@ -52,11 +54,13 @@
5254
end
5355
new_resource.updated_by_last_action(true)
5456
end
55-
utils_line "include \"#{filename}\";" do
56-
action :remove
57-
file "/etc/dhcp3/subnets.d/subnet_list.conf"
58-
if node[:provisioner][:enable_pxe]
59-
notifies :restart, resources(service: "dhcp3-server"), :delayed
57+
["subnet_list.conf", "subnet_list6.conf"].each do |subnet_list|
58+
utils_line "include \"#{filename}\";" do
59+
action :remove
60+
file "/etc/dhcp3/subnets.d/#{subnet_list}"
61+
if node[:provisioner][:enable_pxe]
62+
notifies :restart, resources(service: "dhcp3-server"), :delayed
63+
end
6064
end
6165
end
6266
end

chef/cookbooks/dhcp/recipes/default.rb

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,25 @@
3333
directory "/etc/dhcp3/subnets.d"
3434
directory "/etc/dhcp3/hosts.d"
3535

36-
file "/etc/dhcp3/groups.d/group_list.conf" do
36+
# This needs to be evaled.
37+
admin_network = Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin")
38+
address = admin_network.address
39+
intfs = [admin_network.interface]
40+
41+
group_list = DhcpHelper.config_filename("group_list", admin_network.ip_version)
42+
file "/etc/dhcp3/groups.d/#{group_list}" do
3743
owner "root"
3844
group "root"
3945
mode 0644
4046
end
41-
file "/etc/dhcp3/subnets.d/subnet_list.conf" do
47+
subnet_list = DhcpHelper.config_filename("subnet_list", admin_network.ip_version)
48+
file "/etc/dhcp3/subnets.d/#{subnet_list}" do
4249
owner "root"
4350
group "root"
4451
mode 0644
4552
end
46-
file "/etc/dhcp3/hosts.d/host_list.conf" do
53+
host_list = DhcpHelper.config_filename("host_list", admin_network.ip_version)
54+
file "/etc/dhcp3/hosts.d/#{host_list}" do
4755
owner "root"
4856
group "root"
4957
mode 0644
@@ -59,22 +67,20 @@
5967
not_if "test -f /etc/dhcp3/omapi.key"
6068
end
6169

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

66-
d_opts = node[:dhcp][:options]
71+
d_opts = node[:dhcp][:options]["v#{admin_network.ip_version}"]
72+
dhcpd_conf = DhcpHelper.config_filename("dhcpd", admin_network.ip_version)
6773

6874
case node[:platform_family]
6975
when "debian"
7076
case node[:lsb][:codename]
7177
when "natty","oneiric","precise"
72-
template "/etc/dhcp/dhcpd.conf" do
78+
template "/etc/dhcp/#{dhcpd_conf}" do
7379
owner "root"
7480
group "root"
7581
mode 0644
7682
source "dhcpd.conf.erb"
77-
variables(options: d_opts)
83+
variables(options: d_opts, ip_version: admin_network.ip_version)
7884
if node[:provisioner][:enable_pxe]
7985
notifies :restart, "service[dhcp3-server]"
8086
end
@@ -90,12 +96,12 @@
9096
end
9197
end
9298
else
93-
template "/etc/dhcp3/dhcpd.conf" do
99+
template "/etc/dhcp3/#{dhcpd_conf}" do
94100
owner "root"
95101
group "root"
96102
mode 0644
97103
source "dhcpd.conf.erb"
98-
variables(options: d_opts)
104+
variables(options: d_opts, ip_version: admin_network.ip_version)
99105
if node[:provisioner][:enable_pxe]
100106
notifies :restart, "service[dhcp3-server]"
101107
end
@@ -115,17 +121,17 @@
115121

116122
dhcp_config_file = case
117123
when node[:platform_version].to_f >= 6
118-
"/etc/dhcp/dhcpd.conf"
124+
"/etc/dhcp/#{dhcpd_conf}"
119125
else
120-
"/etc/dhcpd.conf"
126+
"/etc/#{dhcpd_conf}"
121127
end
122128

123129
template dhcp_config_file do
124130
owner "root"
125131
group "root"
126132
mode 0644
127133
source "dhcpd.conf.erb"
128-
variables(options: d_opts)
134+
variables(options: d_opts, ip_version: admin_network.ip_version)
129135
if node[:provisioner][:enable_pxe]
130136
notifies :restart, "service[dhcp3-server]"
131137
end
@@ -143,12 +149,12 @@
143149
end
144150

145151
when "suse"
146-
template "/etc/dhcpd.conf" do
152+
template "/etc/#{dhcpd_conf}" do
147153
owner "root"
148154
group "root"
149155
mode 0644
150156
source "dhcpd.conf.erb"
151-
variables(options: d_opts)
157+
variables(options: d_opts, ip_version: admin_network.ip_version)
152158
if node[:provisioner][:enable_pxe]
153159
notifies :restart, "service[dhcp3-server]"
154160
end
@@ -168,7 +174,7 @@
168174

169175
service "dhcp3-server" do
170176
if %w(suse rhel).include?(node[:platform_family])
171-
service_name "dhcpd"
177+
service_name DhcpHelper.config_filename("dhcpd", admin_network.ip_version, "")
172178
elsif node[:platform] == "ubuntu"
173179
case node[:lsb][:codename]
174180
when "maverick"

chef/cookbooks/dhcp/resources/host.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
attribute :hostname, kind_of: String
2020
attribute :macaddress, kind_of: String
2121
attribute :ipaddress, kind_of: String
22+
attribute :prefix, kind_of: String
23+
attribute :ip_version, kind_of: String, default: "4"
2224
attribute :group, kind_of: String
2325
attribute :options, kind_of: Array, default: []
2426

chef/cookbooks/dhcp/resources/subnet.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@
2020
attribute :pools, kind_of: Array, default: ["dhcp"]
2121
attribute :pool_options, kind_of: Hash, default: { "dhcp" => ["allow unknown-hosts"] }
2222
attribute :options, kind_of: Array, default: []
23+
attribute :ip_version, kind_of: String, default: "4"
2324

chef/cookbooks/dhcp/templates/default/dhcpd.conf.erb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ log-facility local7;
2121
# Fix for https://bugzilla.opensuse.org/show_bug.cgi?id=961536
2222
always-reply-rfc1048 true;
2323

24+
<% if @ip_version == "6" -%>
25+
include "/etc/dhcp3/groups.d/group_list6.conf";
26+
include "/etc/dhcp3/subnets.d/subnet_list6.conf";
27+
include "/etc/dhcp3/hosts.d/host_list6.conf";
28+
<% else -%>
2429
include "/etc/dhcp3/groups.d/group_list.conf";
2530
include "/etc/dhcp3/subnets.d/subnet_list.conf";
2631
include "/etc/dhcp3/hosts.d/host_list.conf";
32+
<% end -%>

chef/cookbooks/dhcp/templates/default/host.conf.erb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ host <%= @name %> {
22
option host-name "<%= @hostname %>";
33
hardware ethernet <%= @macaddress %>;
44
<% if @ipaddress -%>
5+
<% if @ip_version == "6" -%>
6+
fixed-address6 <%= @ipaddress %>;
7+
fixed-prefix6 <%= @prefix %>;
8+
<% else -%>
59
fixed-address <%= @ipaddress %>;
10+
<% end -%>
611
<% else -%>
712
deny booting;
813
<% end -%>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# File managed by Crowbar
2+
<% if node[:provisioner][:enable_pxe] -%>
3+
4+
subnet6 <%= @network["subnet"] %>/<%= @network["netmask"]%> {
5+
option subnet-mask <%= @network["netmask"] %>;
6+
<% @options.each do |option| -%>
7+
<%= option %>;
8+
<% end -%>
9+
<% @pools.each do |pool| -%>
10+
pool6 {
11+
range6 <%=@network["ranges"][pool]["start"]%> <%=@network["ranges"][pool]["end"]%>;
12+
<% @pool_options[pool].each do |opt| -%>
13+
<%=opt%><%=if opt[-1,1] != '}' then ';' else '' end%>
14+
<% end if @pool_options[pool] -%>
15+
}
16+
<% end -%>
17+
}
18+
19+
<% end -%>

chef/cookbooks/dhcp/templates/default/suse-sysconfig-dhcpd.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Do not edit.
33
<% unless @interfaces.empty? -%>
44
DHCPD_INTERFACE="<%= @interfaces.collect! {|i| "#{i}" }.join(" ") %>"
5+
DHCPD6_INTERFACE="<%= @interfaces.collect! {|i| "#{i}" }.join(" ") %>"
56
<% end -%>
67
DHCPD_IFUP_RESTART=""
78
DHCPD_RUN_CHROOTED="no"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module NetworkHelper
2+
def self.wrap_ip(address)
3+
require "ipaddr"
4+
if IPAddr.new(address).ipv6?
5+
"[#{address}]"
6+
else
7+
address.to_s
8+
end
9+
rescue
10+
address.to_s
11+
end
12+
end

chef/cookbooks/provisioner/recipes/base.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@
350350
crowbar_node = node_search_with_cache("roles:crowbar").first
351351
address = crowbar_node["crowbar"]["network"]["admin"]["address"]
352352
protocol = crowbar_node["crowbar"]["apache"]["ssl"] ? "https" : "http"
353-
server = "#{protocol}://#{address}"
353+
server = "#{protocol}://#{NetworkHelper.wrap_ip(address)}"
354354
verify_ssl = !crowbar_node["crowbar"]["apache"]["insecure"]
355355

356356
package "ruby2.1-rubygem-crowbar-client"

0 commit comments

Comments
 (0)