Dynamic dnsmasq config for admin network ranges
In order to successfully PXE/boot nodes from new racks we need to update cobbler's dnsmasq configuration on changes in admin networks of any nodegroup in any Fuel environment. Such changes should survive cobbler container restarts and rebuilds. In order to do so we need to execute the following on every change in admin netwoks configuration of any nodegroup we have in Fuel: - dump list of admin networks into /etc/hiera/networks.yaml file in mcollective container - run 'puppet apply nailgin/examples/dhcp-ranges.pp' inside mcollective container to update config files in shared /etc/dnsmasq.d/ dir - run 'cobbler sync' inside cobbler container to reload dnsmasq Co-Authored-By: Aleksandr Didenko <adidenko@mirantis.com> Blueprint: dynamic-dnsmasq Partial-bug: #1495593 Change-Id: I9d7428c9fc21c705a1aee7fbca8003829a81e1d0
This commit is contained in:
parent
cf54da03b1
commit
4343f1ab8b
|
@ -6,6 +6,7 @@ read-ethers
|
|||
log-queries
|
||||
log-facility=/var/log/dnsmasq.log
|
||||
addn-hosts = /var/lib/cobbler/cobbler_hosts
|
||||
conf-dir=/etc/dnsmasq.d
|
||||
domain=<%= @domain_name %>
|
||||
dhcp-lease-max=<%= @dhcp_lease_max %>
|
||||
<% if @domain_name != 'local' %>
|
||||
|
@ -33,9 +34,4 @@ dhcp-no-override
|
|||
dhcp-sequential-ip
|
||||
|
||||
dhcp-option=6,<%= @name_server %>
|
||||
|
||||
dhcp-range=internal,<%= @dhcp_start_address %>,<%= @dhcp_end_address %>,<%= @dhcp_netmask %>,<%= @lease_time %>
|
||||
dhcp-option=net:internal,option:router,<%= @dhcp_gateway %>
|
||||
dhcp-boot=net:internal,pxelinux.0,boothost,<%= @next_server %>
|
||||
|
||||
$insert_cobbler_system_definitions
|
||||
|
|
|
@ -80,6 +80,8 @@ HOST_VOL['ibp']="-v /var/lib/fuel/ibp:/var/lib/fuel/ibp:rw"
|
|||
HOST_VOL['astute_data']="-v /var/lib/fuel/container_data/$VERSION/astute:/var/lib/astute"
|
||||
HOST_VOL['cobbler_data']="-v /var/lib/fuel/container_data/$VERSION/cobbler:/var/lib/cobbler"
|
||||
HOST_VOL['postgres_data']="-v /var/lib/fuel/container_data/$VERSION/postgres:/var/lib/pgsql"
|
||||
HOST_VOL['dnsmasq']="-v /var/lib/fuel/container_data/$VERSION/dnsmasq:/etc/dnsmasq.d"
|
||||
HOST_VOL['mcollective_data']="-v /var/lib/fuel/container_data/$VERSION/mcollective:/etc/hiera"
|
||||
|
||||
#Storage container volume mounts
|
||||
declare -A CONTAINER_VOLUMES
|
||||
|
@ -113,7 +115,9 @@ REQS["${HOST_VOL['puppet']}"]="rsync"
|
|||
#REQS["${HOST_VOL['puppet']}"]="cobbler postgres rabbitmq rsync astute nailgun ostf nginx rsyslog mcollective keystone"
|
||||
REQS["${HOST_VOL['astute_data']}"]="astute"
|
||||
REQS["${HOST_VOL['cobbler_data']}"]="cobbler"
|
||||
REQS["${HOST_VOL['dnsmasq']}"]="cobbler mcollective"
|
||||
REQS["${HOST_VOL['postgres_data']}"]="postgres"
|
||||
REQS["${HOST_VOL['mcollective_data']}"]="mcollective"
|
||||
REQS["${HOST_VOL['sshkey']}"]="nailgun cobbler astute mcollective ostf"
|
||||
REQS["${HOST_VOL['ibp']}"]="mcollective"
|
||||
REQS["$NAILGUN_VOL"]="nginx"
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
fixtures:
|
||||
symlinks:
|
||||
'nailgun': "#{source_dir}"
|
|
@ -0,0 +1,16 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
group :development, :test do
|
||||
gem 'rake', :require => false
|
||||
gem 'rspec', '~>3.3', :require => false
|
||||
gem 'rspec-puppet', '~>2.1.0', :require => false
|
||||
gem 'puppetlabs_spec_helper', :require => false
|
||||
end
|
||||
|
||||
if puppetversion = ENV['PUPPET_GEM_VERSION']
|
||||
gem 'puppet', puppetversion, :require => false
|
||||
else
|
||||
gem 'puppet', '<4.0', :require => false
|
||||
end
|
||||
|
||||
# vim:ft=ruby
|
|
@ -0,0 +1 @@
|
|||
require 'puppetlabs_spec_helper/rake_tasks'
|
|
@ -0,0 +1,10 @@
|
|||
$fuel_settings = parseyaml($astute_settings_yaml)
|
||||
$admin_network = $::fuel_settings['ADMIN_NETWORK']
|
||||
|
||||
nailgun::dnsmasq::dhcp_range {'default':
|
||||
dhcp_start_address => $admin_network['dhcp_pool_start'],
|
||||
dhcp_end_address => $admin_network['dhcp_pool_end'],
|
||||
dhcp_netmask => $admin_network['netmask'],
|
||||
dhcp_gateway => $admin_network['dhcp_gateway'],
|
||||
next_server => $admin_network['ipaddress'],
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
$admin_networks = hiera('admin_networks')
|
||||
$admin_network = hiera('ADMIN_NETWORK')
|
||||
|
||||
Nailgun::Dnsmasq::Dhcp_range <||> {
|
||||
next_server => $admin_network['ipaddress'],
|
||||
}
|
||||
|
||||
# Ensure dir with purge and recurse to remove configs for
|
||||
# non-existing (removed) nodegroups and ip ranges
|
||||
file { '/etc/dnsmasq.d':
|
||||
ensure => 'directory',
|
||||
recurse => true,
|
||||
purge => true,
|
||||
}
|
||||
|
||||
# Create admin networks dhcp-range files except for 'default' nodegroup
|
||||
# by creating Nailgun::Dnsmasq::Dhcp_range puppet resources
|
||||
create_dnsmasq_dhcp_ranges($admin_networks)
|
|
@ -0,0 +1,61 @@
|
|||
$data_dir = '/etc/hiera'
|
||||
$data = [
|
||||
'override/common',
|
||||
'class/%{calling_class}',
|
||||
'module/%{calling_module}',
|
||||
'nodes',
|
||||
'networks',
|
||||
'astute',
|
||||
'common',
|
||||
]
|
||||
$astute_data_file = '/etc/fuel/astute.yaml'
|
||||
$hiera_main_config = '/etc/hiera.yaml'
|
||||
$hiera_puppet_config = '/etc/puppet/hiera.yaml'
|
||||
$hiera_data_file = "${data_dir}/astute.yaml"
|
||||
|
||||
File {
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
}
|
||||
|
||||
$hiera_config_content = inline_template('
|
||||
---
|
||||
:backends:
|
||||
- yaml
|
||||
|
||||
:hierarchy:
|
||||
<% @data.each do |name| -%>
|
||||
- <%= name %>
|
||||
<% end -%>
|
||||
|
||||
:yaml:
|
||||
:datadir: <%= @data_dir %>
|
||||
|
||||
:merge_behavior: deeper
|
||||
|
||||
:logger: noop
|
||||
')
|
||||
|
||||
file { 'hiera_data_dir' :
|
||||
ensure => 'directory',
|
||||
path => $data_dir,
|
||||
}
|
||||
|
||||
file { 'hiera_config' :
|
||||
ensure => 'present',
|
||||
path => $hiera_main_config,
|
||||
content => $hiera_config_content,
|
||||
}
|
||||
|
||||
file { 'hiera_data_astute' :
|
||||
ensure => 'symlink',
|
||||
path => $hiera_data_file,
|
||||
target => $astute_data_file,
|
||||
}
|
||||
|
||||
file { 'hiera_puppet_config' :
|
||||
ensure => 'symlink',
|
||||
path => $hiera_puppet_config,
|
||||
target => $hiera_main_config,
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
require 'ipaddr'
|
||||
require 'zlib'
|
||||
|
||||
module Puppet::Parser::Functions
|
||||
newfunction(:create_dnsmasq_dhcp_ranges, :doc => <<-EOS
|
||||
Creates nailgun::dnsmasq::dhcp_range puppet resources from list of admin networks.
|
||||
EOS
|
||||
) do |args|
|
||||
admin_nets = args[0]
|
||||
unless admin_nets.is_a?(Array) and admin_nets[0].is_a?(Hash)
|
||||
raise(Puppet::ParseError, 'Should pass list of hashes as a parameter')
|
||||
end
|
||||
admin_nets.each do |net|
|
||||
net['ip_ranges'].each do |ip_range|
|
||||
netmask = IPAddr.new('255.255.255.255').mask(net['cidr'].split('/')[1]).to_s
|
||||
print_range = ip_range.join('_')
|
||||
resource_name = sprintf("range_%08x", Zlib::crc32("#{print_range}_#{net['cidr']}").to_i)
|
||||
range_comment = "# Environment: #{net['cluster_name']}\n# Nodegroup: #{net['node_group_name']}\n# IP range: #{ip_range}"
|
||||
dhcp_range_resource = {
|
||||
resource_name => {
|
||||
'file_header' => "# Generated automatically by puppet\n#{range_comment}",
|
||||
'dhcp_start_address' => ip_range[0],
|
||||
'dhcp_end_address' => ip_range[1],
|
||||
'dhcp_netmask' => netmask,
|
||||
'dhcp_gateway' => net['gateway'],
|
||||
}
|
||||
}
|
||||
debug("Trying to create nailgun::dnsmasq::dhcp_range resource #{dhcp_range_resource}")
|
||||
function_create_resources(['nailgun::dnsmasq::dhcp_range', dhcp_range_resource])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# nailgun::dnsmasq::dhcp_range creates config files in /etc/dnsmasq.d/
|
||||
#
|
||||
# [next_server] IP address that will be used as PXE tftp server
|
||||
# [dhcp_start_address] First address of dhcp range
|
||||
# [dhcp_end_address] Last address of dhcp range
|
||||
# [dhcp_netmask] Netmask of the network
|
||||
# [dhcp_gateway] Gateway address for installed nodes
|
||||
# [lease_time] DHCP lease time
|
||||
# [file_header] File header for comments
|
||||
|
||||
define nailgun::dnsmasq::dhcp_range(
|
||||
$dhcp_start_address = '10.0.0.201',
|
||||
$dhcp_end_address = '10.0.0.254',
|
||||
$dhcp_netmask = '255.255.255.0',
|
||||
$dhcp_gateway = $::ipaddress,
|
||||
$file_header = undef,
|
||||
$lease_time = '120m',
|
||||
$next_server = $::ipaddress,
|
||||
){
|
||||
$range_name = $name
|
||||
file { "/etc/dnsmasq.d/${name}.conf":
|
||||
content => template('nailgun/dnsmasq.dhcp-range.erb'),
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
node 'default' {
|
||||
$admin_networks = [
|
||||
{"id"=>1,
|
||||
"node_group_name"=>nil,
|
||||
"node_group_id"=>nil,
|
||||
"cluster_name"=>nil,
|
||||
"cluster_id"=>nil,
|
||||
"cidr"=>"10.145.0.0/24",
|
||||
"gateway"=>"10.145.0.2",
|
||||
"ip_ranges"=>[["10.145.0.3", "10.145.0.250"]]},
|
||||
{"id"=>2,
|
||||
"node_group_name"=>"default2",
|
||||
"node_group_id"=>22,
|
||||
"cluster_name"=>"default2",
|
||||
"cluster_id"=>2,
|
||||
"cidr"=>"10.144.0.0/24",
|
||||
"gateway"=>"10.144.0.5",
|
||||
"ip_ranges"=>[["10.144.0.10", "10.144.0.254"]]}]
|
||||
$admin_network = {"interface"=>"eth0",
|
||||
"ipaddress"=>"10.145.0.2",
|
||||
"netmask"=>"255.255.255.0",
|
||||
"cidr"=>"10.20.0.0/24",
|
||||
"size"=>"256",
|
||||
"dhcp_pool_start"=>"10.145.0.3",
|
||||
"dhcp_pool_end"=>"10.145.0.254",
|
||||
"mac"=>"64:42:d3:10:64:68",
|
||||
"dhcp_gateway"=>"10.145.0.1"}
|
||||
|
||||
Nailgun::Dnsmasq::Dhcp_range <||> {
|
||||
next_server => $admin_network['ipaddress'],
|
||||
}
|
||||
|
||||
file { '/etc/dnsmasq.d':
|
||||
ensure => 'directory',
|
||||
recurse => true,
|
||||
purge => true,
|
||||
}
|
||||
|
||||
create_dnsmasq_dhcp_ranges($admin_networks, ['default'])
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'create_dnsmasq_dhcp_ranges' do
|
||||
|
||||
it 'refuses String' do
|
||||
is_expected.to run.with_params('foo').\
|
||||
and_raise_error(Puppet::ParseError, /Should pass list of hashes as a parameter/)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,44 @@
|
|||
require 'spec_helper'
|
||||
require 'zlib'
|
||||
require 'ipaddr'
|
||||
|
||||
describe 'default' do
|
||||
admin_nets = [
|
||||
{"id"=>1,
|
||||
"node_group_name"=>nil,
|
||||
"node_group_id"=>nil,
|
||||
"cluster_name"=>nil,
|
||||
"cluster_id"=>nil,
|
||||
"cidr"=>"10.145.0.0/24",
|
||||
"gateway"=>"10.145.0.2",
|
||||
"ip_ranges"=>[["10.145.0.3", "10.145.0.250"]]},
|
||||
{"id"=>2,
|
||||
"node_group_name"=>"default2",
|
||||
"node_group_id"=>22,
|
||||
"cluster_name"=>"default2",
|
||||
"cluster_id"=>2,
|
||||
"cidr"=>"10.144.0.0/24",
|
||||
"gateway"=>"10.144.0.5",
|
||||
"ip_ranges"=>[["10.144.0.10", "10.144.0.254"]]}
|
||||
]
|
||||
admin_network = {"interface"=>"eth0",
|
||||
"ipaddress"=>"10.145.0.2",
|
||||
"netmask"=>"255.255.255.0",
|
||||
"cidr"=>"10.20.0.0/24",
|
||||
"size"=>"256",
|
||||
"dhcp_pool_start"=>"10.145.0.3",
|
||||
"dhcp_pool_end"=>"10.145.0.254",
|
||||
"mac"=>"64:42:d3:10:64:68",
|
||||
"dhcp_gateway"=>"10.145.0.1"}
|
||||
admin_nets.each do |net|
|
||||
net['ip_ranges'].each do |ip_range|
|
||||
netmask = IPAddr.new('255.255.255.255').mask(net['cidr'].split('/')[1]).to_s
|
||||
print_range = ip_range.join('_')
|
||||
resource_name = sprintf("range_%08x", Zlib::crc32("#{print_range}_#{net['cidr']}").to_i)
|
||||
it { should contain_file("/etc/dnsmasq.d/#{resource_name}.conf") \
|
||||
.with_content(/^dhcp-range=#{resource_name}.*#{netmask},120m\n|,boothost,#{admin_network['ipaddress']}\n/)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
require 'rspec-puppet'
|
||||
|
||||
fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures'))
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.module_path = File.join(fixture_path, 'modules')
|
||||
c.manifest_dir = File.join(fixture_path, 'manifests')
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
<% if @file_header %><%= @file_header %><% end %>
|
||||
dhcp-range=<%= @range_name %>,<%= @dhcp_start_address %>,<%= @dhcp_end_address %>,<%= @dhcp_netmask %>,<%= @lease_time %>
|
||||
dhcp-option=net:<%= @range_name %>,option:router,<%= @dhcp_gateway %>
|
||||
dhcp-boot=net:<%= @range_name %>,pxelinux.0,boothost,<%= @next_server %>
|
|
@ -81,6 +81,8 @@ HOST_VOL['ibp']="-v /var/lib/fuel/ibp:/var/lib/fuel/ibp:rw"
|
|||
HOST_VOL['astute_data']="-v /var/lib/fuel/container_data/$VERSION/astute:/var/lib/astute"
|
||||
HOST_VOL['cobbler_data']="-v /var/lib/fuel/container_data/$VERSION/cobbler:/var/lib/cobbler"
|
||||
HOST_VOL['postgres_data']="-v /var/lib/fuel/container_data/$VERSION/postgres:/var/lib/pgsql"
|
||||
HOST_VOL['dnsmasq']="-v /var/lib/fuel/container_data/$VERSION/dnsmasq:/etc/dnsmasq.d"
|
||||
HOST_VOL['mcollective_data']="-v /var/lib/fuel/container_data/$VERSION/mcollective:/etc/hiera"
|
||||
|
||||
#Storage container volume mounts
|
||||
declare -A CONTAINER_VOLUMES
|
||||
|
@ -114,7 +116,9 @@ REQS["${HOST_VOL['puppet']}"]="rsync"
|
|||
#REQS["${HOST_VOL['puppet']}"]="cobbler postgres rabbitmq rsync astute nailgun ostf nginx rsyslog mcollective keystone"
|
||||
REQS["${HOST_VOL['astute_data']}"]="astute"
|
||||
REQS["${HOST_VOL['cobbler_data']}"]="cobbler"
|
||||
REQS["${HOST_VOL['dnsmasq']}"]="cobbler mcollective"
|
||||
REQS["${HOST_VOL['postgres_data']}"]="postgres"
|
||||
REQS["${HOST_VOL['mcollective_data']}"]="mcollective"
|
||||
REQS["${HOST_VOL['sshkey']}"]="nailgun cobbler astute mcollective ostf"
|
||||
REQS["${HOST_VOL['ibp']}"]="mcollective"
|
||||
REQS["$NAILGUN_VOL"]="nginx"
|
||||
|
|
|
@ -18,7 +18,6 @@ memcached
|
|||
mongodb
|
||||
monit
|
||||
mysql
|
||||
nailgun
|
||||
neutron
|
||||
nova
|
||||
ntp
|
||||
|
|
Loading…
Reference in New Issue