Skip to content

Commit

Permalink
Bind9 can manage DNS entries.
Browse files Browse the repository at this point in the history
  • Loading branch information
c-buisson committed Nov 30, 2014
1 parent f81f81d commit 7147978
Show file tree
Hide file tree
Showing 22 changed files with 294 additions and 95 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
CHANGELOG
=========

2.3: 2014-11-29
---------------
New Feature:
- Bind9 can be installed to manage DNS entries dynamically for the KVM guests.

Updates:
- KVM guest will now have a FQDN name. (.local)
- Added new DB field "mac_address".
- Improved vnc_port generation by using the backend database instead of XMLs.
- Same as above but for mac_addresses.
- Small updates for the installer.

2.2: 2014-11-21
---------------
New Feature:
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ You can choose to start a new virtual machine with an ISO or an Ubuntu Cloud ima
When an Ubuntu Cloud image is used to launch a new instance, the vm will get a static IP. ISO's on the other hand, will get a DHCP ip.

###Network types:
*Netmask*: Mission_Control is setup to work on with Class C IPs, therefore the netmask is hard coded to: 255.255.255.0
*Netmask*: kvm-control was designed to work with Class C IPs, therefore the netmask is hard coded to: 255.255.255.0

*Fqdn*: kvm-control will launch the KVM guests with a fully qualified domain name `.local`. Bind9 will be installed by default to dynamically manage the DNS A and PTR records. See `vars` file.

####Floating IPs

Expand Down
2 changes: 1 addition & 1 deletion kvm/chef_generate_scripts-floating.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/ruby
require 'erb'

def chef_generate_scripts(backend, kvm_folder, floating)
def chef_generate_scripts(backend, kvm_folder, floating, bind9)
dir=File.expand_path(File.dirname(__FILE__))

#Generate Rundeck xml
Expand Down
2 changes: 1 addition & 1 deletion kvm/chef_generate_scripts.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/ruby
require 'erb'

def chef_generate_scripts(backend, kvm_folder, floating)
def chef_generate_scripts(backend, kvm_folder, floating, bind9)
dir=File.expand_path(File.dirname(__FILE__))

#Generate Rundeck xml
Expand Down
3 changes: 2 additions & 1 deletion kvm/generate_scripts-floating.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/ruby
require 'erb'

def generate_scripts(backend, database_name, db_kvm_table, mysql_password, kvm_folder, start_ip, end_ip, gateway_ip, ssh_keys, floating, rundeck_key)
def generate_scripts(backend, database_name, db_kvm_table, mysql_password, kvm_folder, start_ip, end_ip, gateway_ip, ssh_keys, floating, rundeck_key, bind9, ip_host)
dir=File.expand_path(File.dirname(__FILE__))

#Generate ENV file
Expand Down Expand Up @@ -37,6 +37,7 @@ def generate_scripts(backend, database_name, db_kvm_table, mysql_password, kvm_f
#Generate user-data template files
user_data_templates=["TEMPLATE-user-data", "TEMPLATE-user-data-nat"].each do |ud|
var = "<%= ip %>"
hostname = "<%= name %>"
template = ERB.new(File.read("#{dir}/templates/#{ud}.erb"))
xml_content = template.result(binding)
File.open("#{kvm_folder}/templates/#{ud}.erb", "w") do |file|
Expand Down
3 changes: 2 additions & 1 deletion kvm/generate_scripts.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/ruby
require 'erb'

def generate_scripts(backend, database_name, db_kvm_table, mysql_password, kvm_folder, ssh_keys, floating, rundeck_key)
def generate_scripts(backend, database_name, db_kvm_table, mysql_password, kvm_folder, ssh_keys, floating, rundeck_key, bind9, ip_host)
dir=File.expand_path(File.dirname(__FILE__))

#Generate ENV file
Expand Down Expand Up @@ -36,6 +36,7 @@ def generate_scripts(backend, database_name, db_kvm_table, mysql_password, kvm_f

#Generate user-data template file
var = "<%= ip %>"
hostname = "<%= name %>"
template = ERB.new(File.read("#{dir}/templates/TEMPLATE-user-data-nat.erb"))
xml_content = template.result(binding)
File.open("#{kvm_folder}/templates/TEMPLATE-user-data-nat.erb", "w") do |file|
Expand Down
20 changes: 0 additions & 20 deletions kvm/lib/def.rb

This file was deleted.

4 changes: 2 additions & 2 deletions kvm/setup_db.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def setup_kvm_db(backend, database_name, db_kvm_table, mysql_password)
client = Mysql2::Client.new(:host => "localhost", :username => "root", :password => mysql_password)
client.query "CREATE DATABASE IF NOT EXISTS #{database_name} CHARACTER SET utf8 COLLATE utf8_general_ci"
client.query "CREATE TABLE IF NOT EXISTS #{database_name}.#{db_kvm_table} \
(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(25), ip VARCHAR(17), vnc_port INT, network_type VARCHAR(8), chef_installed VARCHAR(3))"
(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(25), ip VARCHAR(17), vnc_port INT, mac_address VARCHAR(17), network_type VARCHAR(8), chef_installed VARCHAR(3))"
rescue Mysql2::Error => e
puts e.error
end
Expand All @@ -21,7 +21,7 @@ def setup_kvm_db(backend, database_name, db_kvm_table, mysql_password)
require 'pg'
conn = PG::Connection.open(:dbname => "#{database_name}", :user => "pguser")
conn.exec_params("CREATE TABLE IF NOT EXISTS #{db_kvm_table} (
id serial PRIMARY KEY, name varchar(25) NOT NULL, ip varchar(17) NOT NULL, vnc_port int, network_type varchar(8), chef_installed VARCHAR(3))")
id serial PRIMARY KEY, name varchar(25) NOT NULL, ip varchar(17) NOT NULL, vnc_port int, mac_address(17), network_type varchar(8), chef_installed VARCHAR(3))")
rescue PG::Error => e
puts e.error
end
Expand Down
5 changes: 4 additions & 1 deletion kvm/templates/TEMPLATE-user-data-nat.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#cloud-config
password: ubuntu
password: changeme
fqdn: <%= hostname %>.local
manage_etc_hosts: true
chpasswd: { expire: False }
ssh_pwauth: True
package_update: true
Expand All @@ -25,6 +27,7 @@ write_files:
owner: root:root
- content: |
nameserver 192.168.122.1
search local
path: /home/ubuntu/resolv
permissions: '0644'
owner: root:root
Expand Down
7 changes: 5 additions & 2 deletions kvm/templates/TEMPLATE-user-data.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#cloud-config
password: ubuntu
password: changeme
fqdn: <%= hostname %>.local
manage_etc_hosts: true
chpasswd: { expire: False }
ssh_pwauth: True
package_update: true
Expand All @@ -24,7 +26,8 @@ write_files:
permissions: '0644'
owner: root:root
- content: |
nameserver <%= gateway_ip %>
nameserver <%= ip_host %>
search local
path: /home/ubuntu/resolv
permissions: '0644'
owner: root:root
Expand Down
80 changes: 62 additions & 18 deletions kvm/templates/chef-rundeck_jobs.xml.erb
Original file line number Diff line number Diff line change
Expand Up @@ -74,25 +74,35 @@ echo \"#{guest} is ready, you can now SSH in with: ubuntu@$IP\"")]]></script>
guest=ENV['RD_OPTION_NAME']
eval File.read("<%= kvm_folder %>/ENV")

#Access def.rb library file
require_relative "#{LIB}/def.rb"
<% if backend == "mysql" %>require_relative "#{LIB}/mysql_backend.rb"<% elsif backend == "postgres" %>require_relative "#{LIB}/postgres_backend.rb"<% end %>
list=list_all_guests

#Checking if there is at least one guest on the system
xml = Dir["#{GUESTS_DIR}/*/*.xml"]
if xml[0].nil?
if list[0].nil?
new_vnc_port="5901"
new_mac_address="52:54:aa:" + (1..3).map{"%0.2X"%rand(256)}.join(":").downcase
puts "First guest on that server!\n Assigning VNC port: #{new_vnc_port} and mac_address: #{new_mac_address}".bold
else
#Calling the method generate_value for a new vnc_port and a new mac_address
vnc_ports_use = generate_value "vnc", 59, "'", "vnc_ports_use"
mac_address_use = generate_value "mac address", ":", "'/>", "mac_address_use"
vnc_port_use=[]
list.each_with_index do |l, index|
vnc_port_use << list[index]["vnc_port"]
end
vnc_available=[]
vnc_port_use.each_with_index do |x, index|
idx=vnc_port_use[index+=1]
z=x+=1
unless z == idx.to_i
unless vnc_port_use.include?(z)
vnc_available << z
end
end
end
new_vnc_port=vnc_available[0]

#Found the higher VNC port number and add 1 to it.
new_vnc_port=vnc_ports_use.sort.last.to_i+1
#Generates a random MAC address
new_mac_address="52:54:aa:" + (1..3).map{"%0.2X"%rand(256)}.join(":").downcase
#Test is the generated mac is already in use by a guest.
mac_address_use=[]
list.each_with_index do |l, index|
mac_address_use << list[index]["mac_address"]
end
mac_address_use.each do |mac|
if mac == new_mac_address
puts "The generated mac_address is already assigned to another KVM guest...".red.bold
Expand Down Expand Up @@ -123,11 +133,11 @@ if ENV['RD_OPTION_SOURCE'].end_with? "iso"
ip="DHCP"
<% if backend == "mysql" %>
require_relative "#{LIB}/mysql_backend.rb"
add_guest guest, ip, new_vnc_port, ENV['RD_OPTION_NETWORK_TYPE'], "yes"
add_guest guest, ip, new_vnc_port, new_mac_address, ENV['RD_OPTION_NETWORK_TYPE'], "yes"
require_relative "#{LIB}/lists.rb"
add_to_list "vm", guest, ip<% elsif backend == "postgres" %>
require_relative "#{LIB}/postgres_backend.rb"
add_guest guest, ip, new_vnc_port, ENV['RD_OPTION_NETWORK_TYPE'], "yes"
add_guest guest, ip, new_vnc_port, new_mac_address, ENV['RD_OPTION_NETWORK_TYPE'], "yes"
require_relative "#{LIB}/lists.rb"
add_to_list "vm", guest, ip<% end %>

Expand All @@ -140,11 +150,11 @@ elsif ENV['RD_OPTION_SOURCE'].end_with? "img"
require_relative "#{LIB}/generate_static_ip.rb"
ip = generate_ip ENV['RD_OPTION_NAME'], ENV['RD_OPTION_NETWORK_TYPE']<% if backend == "mysql" %>
require_relative "#{LIB}/mysql_backend.rb"
add_guest guest, ip, new_vnc_port, ENV['RD_OPTION_NETWORK_TYPE'], "yes"
add_guest guest, ip, new_vnc_port, new_mac_address, ENV['RD_OPTION_NETWORK_TYPE'], "yes"
require_relative "#{LIB}/lists.rb"
add_to_list "vm", guest, ip<% elsif backend == "postgres" %>
require_relative "#{LIB}/postgres_backend.rb"
add_guest guest, ip, new_vnc_port, ENV['RD_OPTION_NETWORK_TYPE'], "yes"
add_guest guest, ip, new_vnc_port, new_mac_address, ENV['RD_OPTION_NETWORK_TYPE'], "yes"
require_relative "#{LIB}/lists.rb"
add_to_list "vm", guest, ip<% end %>

Expand Down Expand Up @@ -180,7 +190,24 @@ File.open(XML, "w") do |file|
file.puts xml_content
end

puts "New XML file created at: " + XML.underline]]></script>
<% if bind9 == "yes" %>#Update Bind
list=list_all_guests
serial=Time.now.to_i
require 'erb'
template = ERB.new(File.read("<%= kvm_folder %>/templates/db.local.erb"))
xml_content = template.result(binding)
File.open("/etc/bind/db.local", "w") do |file|
file.puts xml_content
end
template = ERB.new(File.read("<%= kvm_folder %>/templates/db.1XX.erb"))
xml_content = template.result(binding)
File.open("/etc/bind/db.1XX", "w") do |file|
file.puts xml_content
end
puts "Reloading Bind9..."
system("service bind9 reload")<% end %>

puts "\nNew XML file created at: " + XML.underline]]></script>
</command>
</sequence>
<description>This will generate a guest XML.</description>
Expand Down Expand Up @@ -322,7 +349,24 @@ end
puts "removing folder: " + "#{GUEST}/\n".red
FileUtils.rm_rf(GUEST)

puts "Instance destroyed and files removed"
<% if bind9 == "yes" %>#Update Bind
list=list_all_guests
serial=Time.now.to_i
require 'erb'
template = ERB.new(File.read("<%= kvm_folder %>/templates/db.local.erb"))
xml_content = template.result(binding)
File.open("/etc/bind/db.local", "w") do |file|
file.puts xml_content
end
template = ERB.new(File.read("<%= kvm_folder %>/templates/db.1XX.erb"))
xml_content = template.result(binding)
File.open("/etc/bind/db.1XX", "w") do |file|
file.puts xml_content
end
puts "Reloading Bind9..."
system("service bind9 reload")<% end %>

puts "\nInstance destroyed and files removed"
puts "Carry on..."]]></script>
</command>
</sequence>
Expand Down
15 changes: 15 additions & 0 deletions kvm/templates/db.1XX.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
;
; BIND reverse data file for local loopback interface
;
$TTL 604800
@ IN SOA localhost. root.localhost. (
<%= serial %> ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
1.0.0 IN PTR localhost.
<% list.each_with_index do |n, index| %>
<%= list[index]["ip"].split(".")[3] %> IN PTR <%= list[index]["name"] %>.local.<% end %>
14 changes: 14 additions & 0 deletions kvm/templates/db.local.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
;
; BIND reverse data file for broadcast zone
;
$TTL 604800
@ IN SOA localhost. root.localhost. (
<%= serial %> ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
<% list.each_with_index do |n, index| %>
<%= list[index]["name"] %> IN A <%= list[index]["ip"] %><% end %>
4 changes: 2 additions & 2 deletions kvm/templates/mysql_backend.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/ruby

def add_guest(name, ip, vnc_port, network_type, chef)
def add_guest(name, ip, vnc_port, mac_address, network_type, chef)
begin
client = Mysql2::Client.new(:host => "localhost", :username => "root", :password => MYSQL_PASSWORD)
client.query "INSERT INTO <%= database_name %>.<%= db_kvm_table %> (name, ip, vnc_port, network_type, chef_installed) VALUES ('#{name}', '#{ip}', '#{vnc_port}', '#{network_type}', '#{chef}')"
client.query "INSERT INTO <%= database_name %>.<%= db_kvm_table %> (name, ip, vnc_port, mac_address, network_type, chef_installed) VALUES ('#{name}', '#{ip}', '#{vnc_port}', '#{mac_address}', '#{network_type}', '#{chef}')"
rescue Mysql2::Error => e
puts e.error
end
Expand Down
16 changes: 16 additions & 0 deletions kvm/templates/named.conf.local.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
zone "local" {
type master;
file "/etc/bind/db.local";
};

zone "122.168.192.in-addr.arpa" {
type master;
notify no;
file "/etc/bind/db.1XX";
};

<% unless floating == "no" %>zone "<%= third_octet %>.168.192.in-addr.arpa" {
type master;
notify no;
file "/etc/bind/db.1XX";
};<% end %>
4 changes: 2 additions & 2 deletions kvm/templates/postgres_backend.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/ruby

def add_guest(name, ip, vnc_port, network_type, chef)
def add_guest(name, ip, vnc_port, mac_address, network_type, chef)
begin
conn = PG::Connection.open(:dbname => "<%= database_name %>", :user => "pguser")
conn.exec_params "INSERT INTO <%= db_kvm_table %> (name, ip, vnc_port, network_type, chef_installed) VALUES ('#{name}', '#{ip}', '#{vnc_port}', '#{network_type}', '#{chef}')"
conn.exec_params "INSERT INTO <%= db_kvm_table %> (name, ip, vnc_port, mac_address, network_type, chef_installed) VALUES ('#{name}', '#{ip}', '#{vnc_port}', '#{mac_address}', '#{network_type}', '#{chef}')"
rescue PG::Error => e
puts e.error
end
Expand Down
Loading

0 comments on commit 7147978

Please sign in to comment.