From 04299a383d0340ea36f4611ae83d74a20a7adba5 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Thu, 17 Apr 2014 16:54:17 -0500 Subject: [PATCH 01/15] added chefspec testing --- Gemfile | 9 ++ Guardfile | 16 +++ recipes/chroot.rb | 1 + recipes/default.rb | 148 +---------------------- recipes/server.rb | 168 ++++++++++++++++++++++++++ spec/spec_helper.rb | 15 +++ spec/unit/recipes_spec/chroot_spec.rb | 102 ++++++++++++++++ spec/unit/recipes_spec/server_spec.rb | 96 +++++++++++++++ tmp/rspec_guard_result | 1 + 9 files changed, 409 insertions(+), 147 deletions(-) create mode 100644 Guardfile create mode 100644 recipes/server.rb create mode 100644 spec/spec_helper.rb create mode 100644 spec/unit/recipes_spec/chroot_spec.rb create mode 100644 spec/unit/recipes_spec/server_spec.rb create mode 100644 tmp/rspec_guard_result diff --git a/Gemfile b/Gemfile index 3017623..5e19db0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,12 @@ source 'https://rubygems.org' gem 'berkshelf' +gem 'test-kitchen' +gem 'kitchen-vagrant' +gem 'foodcritic' +gem 'chefspec' +gem 'strainer' +gem 'guard' +gem 'guard-foodcritic' +gem 'guard-rspec' +gem 'fakefs' diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..bd01721 --- /dev/null +++ b/Guardfile @@ -0,0 +1,16 @@ +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +guard :rspec do + watch(%r{^spec/.+_spec\.rb$}) + watch(%r{^spec/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } + watch('spec/spec_helper.rb') { "spec" } +end + + +guard "foodcritic", cookbook_paths:"." do + watch(%r{attributes/.+\.rb$}) + watch(%r{providers/.+\.rb$}) + watch(%r{recipes/.+\.rb$}) + watch(%r{resources/.+\.rb$}) +end diff --git a/recipes/chroot.rb b/recipes/chroot.rb index a3df796..03a7747 100644 --- a/recipes/chroot.rb +++ b/recipes/chroot.rb @@ -38,6 +38,7 @@ not_if { ::File.directory?(File.join(node[:bind9][:chroot_dir].to_s, "/var/run/named")) } end + ruby_block "modify_init_script" do block do rc = Chef::Util::FileEdit.new("/etc/init.d/bind9") diff --git a/recipes/default.rb b/recipes/default.rb index c617d41..3acf1a7 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -17,150 +17,4 @@ # limitations under the License. # -package "bind9" do - case node[:platform] - when "centos", "redhat", "suse", "fedora" - package_name "bind" - end - action :install -end - -service "bind9" do - case node[:platform] - when "centos", "redhat" - service_name "named" - end - supports :status => true, :reload => true, :restart => true - action [ :enable ] -end - -directory File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:data_path]) do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0755 - recursive true -end - -directory File.dirname(File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:log_file])) do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0755 - recursive true -end - -directory File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true -end - -if !node[:bind9][:chroot_dir].nil? - include_recipe "bind9-chroot::chroot" -end - -class Chef::Recipe::NameServer - include LeCafeAutomatique::Bind9::NameServer -end - -if node[:bind9][:resolvconf] - include_recipe "resolvconf" - # file "/etc/resolvconf/resolv.conf.d/tail" do - # content NameServer.nameserver_proxy("/etc/resolv.conf", /nameserver.*/) - # only_if { !::File.exists?("/etc/resolvconf/resolv.conf.d/tail") } - # end -end - - -template File.join(node[:bind9][:config_path], node[:bind9][:options_file]) do - source "named.conf.options.erb" - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - notifies :restart, "service[bind9]" -end - -template File.join(node[:bind9][:config_path], node[:bind9][:config_file]) do - source "named.conf.erb" - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - notifies :restart, "service[bind9]" -end - -template File.join(node[:bind9][:config_path], node[:bind9][:local_file]) do - source "named.conf.local.erb" - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - variables({ - :zonefiles => search(:zones) - }) - notifies :restart, "service[bind9]" -end - - -template node[:bind9][:defaults_file] do - source "bind9.erb" - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - notifies :restart, "service[bind9]" - not_if { node[:bind9][:defaults_file].nil? } -end - - -directory node[:bind9][:zones_path] do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true - not_if { ::File.directory?(node[:bind9][:zones_path]) or ::File.symlink?(node[:bind9][:zones_path]) } -end - -search(:zones).each do |zone| - #unless zone['autodomain'].nil? || zone['autodomain'] == '' - # search(:node, "domain:#{zone['autodomain']}").each do |host| - # next if host['ipaddress'] == '' || host['ipaddress'].nil? - # zone['zone_info']['records'].push( { - # "name" => host['hostname'], - # "type" => "A", - # "ip" => host['ipaddress'] - # }) - # end - #end - - template File.join(node[:bind9][:zones_path], zone['domain']) do - source File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") - local true - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - notifies :restart, "service[bind9]" - variables({ - :serial => zone['zone_info']['serial'] || Time.new.strftime("%Y%m%d%H%M%S") - }) - action :nothing - end - - template File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") do - source "zonefile.erb" - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - variables({ - :domain => zone['domain'], - :soa => zone['zone_info']['soa'], - :contact => zone['zone_info']['contact'], - :global_ttl => zone['zone_info']['global_ttl'], - :nameserver => zone['zone_info']['nameserver'], - :mail_exchange => zone['zone_info']['mail_exchange'], - :records => zone['zone_info']['records'] - }) - notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately - end -end - -service "bind9" do - action [ :start ] -end +include_recipe 'bind9-chroot::server' diff --git a/recipes/server.rb b/recipes/server.rb new file mode 100644 index 0000000..b034141 --- /dev/null +++ b/recipes/server.rb @@ -0,0 +1,168 @@ +# Cookbook Name:: bind9-chroot +# Recipe:: server +# +# Copyright 2011, Mike Adolphs +# Copyright 2013, tnarik +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package "bind9" do + case node[:platform] + when "centos", "redhat", "suse", "fedora" + package_name "bind" + end + action :install +end + +service "bind9" do + case node[:platform] + when "centos", "redhat" + service_name "named" + end + supports :status => true, :reload => true, :restart => true + action [ :enable ] +end + +directory File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:data_path]) do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0755 + recursive true +end + +directory File.dirname(File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:log_file])) do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0755 + recursive true +end + +directory File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0744 + recursive true +end + +if !node[:bind9][:chroot_dir].nil? + include_recipe "bind9-chroot::chroot" +end + +class Chef::Recipe::NameServer + include LeCafeAutomatique::Bind9::NameServer +end + +if node[:bind9][:resolvconf] + include_recipe "resolvconf" +# # file "/etc/resolvconf/resolv.conf.d/tail" do +# # content NameServer.nameserver_proxy("/etc/resolv.conf", /nameserver.*/) +# # only_if { !::File.exists?("/etc/resolvconf/resolv.conf.d/tail") } +# # end +end + + +template File.join(node[:bind9][:config_path], node[:bind9][:options_file]) do + source "named.conf.options.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + notifies :restart, "service[bind9]" +end + +template File.join(node[:bind9][:config_path], node[:bind9][:config_file]) do + source "named.conf.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + notifies :restart, "service[bind9]" +end + +p search(:zones) + +template File.join(node[:bind9][:config_path], node[:bind9][:local_file]) do + source "named.conf.local.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + variables({ + :zonefiles => search(:zones) + }) + notifies :restart, "service[bind9]" +end + + +#template node[:bind9][:defaults_file] do +# source "bind9.erb" +# owner node[:bind9][:user] +# group node[:bind9][:user] +# mode 0644 +# notifies :restart, "service[bind9]" +# not_if { node[:bind9][:defaults_file].nil? } +#end + + +#directory node[:bind9][:zones_path] do +# owner node[:bind9][:user] +# group node[:bind9][:user] +# mode 0744 +# recursive true +# not_if { ::File.directory?(node[:bind9][:zones_path]) or ::File.symlink?(node[:bind9][:zones_path]) } +#end + +#search(:zones).each do |zone| + #unless zone['autodomain'].nil? || zone['autodomain'] == '' + # search(:node, "domain:#{zone['autodomain']}").each do |host| + # next if host['ipaddress'] == '' || host['ipaddress'].nil? + # zone['zone_info']['records'].push( { + # "name" => host['hostname'], + # "type" => "A", + # "ip" => host['ipaddress'] + # }) + # end + #end + +# template File.join(node[:bind9][:zones_path], zone['domain']) do +# source File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") +# local true +# owner node[:bind9][:user] +# group node[:bind9][:user] +# mode 0644 +# notifies :restart, "service[bind9]" +# variables({ +# :serial => zone['zone_info']['serial'] || Time.new.strftime("%Y%m%d%H%M%S") +# }) +# action :nothing +# end + +# template File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") do +# source "zonefile.erb" +# owner node[:bind9][:user] +# group node[:bind9][:user] +# mode 0644 +# variables({ +# :domain => zone['domain'], +# :soa => zone['zone_info']['soa'], +# :contact => zone['zone_info']['contact'], +# :global_ttl => zone['zone_info']['global_ttl'], +# :nameserver => zone['zone_info']['nameserver'], +# :mail_exchange => zone['zone_info']['mail_exchange'], +# :records => zone['zone_info']['records'] +# }) +# notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately +# end +#end + +#service "bind9" do +# action [ :start ] +#end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..dfd554a --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,15 @@ +# spec_helper.rb +require 'chefspec' +require 'chefspec/berkshelf' +require 'fakefs/safe' + +ChefSpec::Coverage.start! + +UBUNTU_OPTS = { + platform: 'ubuntu', + version: '12.04' +} + +#RSpec.configure do |config| +# config.include FakeFS::SpecHelpers, fakefs: true +#end diff --git a/spec/unit/recipes_spec/chroot_spec.rb b/spec/unit/recipes_spec/chroot_spec.rb new file mode 100644 index 0000000..c70fa4f --- /dev/null +++ b/spec/unit/recipes_spec/chroot_spec.rb @@ -0,0 +1,102 @@ +require 'spec_helper' + +describe 'bind9-chroot::chroot' do + + context 'Ubuntu 12.04' do + let(:chef_run) do + ChefSpec::Runner.new(UBUNTU_OPTS) do |node| + node.set[:bind9][:chroot_dir] = '/var/run/bind' + end.converge(described_recipe) + end + + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + end + + it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind does not exists' do + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'runs ruby_block copy_openssl_dependencies' do + expect(chef_run).to run_ruby_block('copy_openssl_dependencies') + end + + it 'creates directory /var/run/bind/var/run/named' do + expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block modify_init_script' do + expect(chef_run).to run_ruby_block('modify_init_script') + end + + it 'does not run ruby_block modify_init_script' do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) + expect(chef_run).to_not run_ruby_block('modify_init_script') + end + + it 'creates directory /var/run/bind/etc/bind' do + expect(chef_run).to create_directory('/var/run/bind/etc/bind').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block move_config_to_chroot' do + expect(chef_run).to run_ruby_block('move_config_to_chroot') + end + + it 'links bind config from chroot' do + expect(chef_run).to create_link('/etc/bind').with(to: '/var/run/bind/etc/bind') + end + + it 'does not create directory /var/run/bind/etc/bind/zones' do + expect(chef_run).to_not create_directory('/var/run/bind/etc/bind/zones').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'does not link bind zones from chroot' do + expect(chef_run).to_not create_link('/etc/bind/zones').with(to: '/var/run/bind/etc/bind/zones') + end + + it 'creates directory /var/run/bind/dev' do + expect(chef_run).to create_directory('/var/run/bind/dev').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'creates special device files' do + expect(chef_run).to run_execute('create_special_device_files') + end + + it 'does not create special device files' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) + expect(chef_run).to_not run_execute('create_special_device_files') + end + + end +end diff --git a/spec/unit/recipes_spec/server_spec.rb b/spec/unit/recipes_spec/server_spec.rb new file mode 100644 index 0000000..51d9042 --- /dev/null +++ b/spec/unit/recipes_spec/server_spec.rb @@ -0,0 +1,96 @@ +require 'spec_helper' + +describe 'bind9-chroot::server' do + let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } + + context 'Ubuntu 12.04' do + let(:chef_run) { ChefSpec::Runner.new(UBUNTU_OPTS).converge(described_recipe) } + + before(:each) do + stub_search("zones", "*:*").and_return([ {"id"=>"exampleDOTcom"} ]) + end + + it 'installs bind9' do + expect(chef_run).to install_package('bind9') + end + + it 'enables bind9 service' do + expect(chef_run).to enable_service('bind9') + end + + it 'creates directory /var/cache/bind owned by bind user' do + expect(chef_run).to create_directory('/var/cache/bind').with( + user: 'bind', + group: 'bind', + mode: 0755, + recursive: true + ) + end + + it 'creates directory /var/log/bind owned by bind user' do + expect(chef_run).to create_directory('/var/log/bind').with( + user: 'bind', + group: 'bind', + mode: 0755, + recursive: true + ) + end + + it 'creates directory /etc/bind/zones owned by bind user' do + expect(chef_run).to create_directory('/etc/bind/zones').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'does not include bind9-chroot::chroot recipe' do + expect(chef_run).to_not include_recipe('bind9-chroot::chroot') + end + + it 'does include resolvconf recipe' do + expect(chef_run).to_not include_recipe('resolvconf') + end + + it 'includes resolvconf recipe' do + chef_run.node.set[:bind9][:resolvconf] = true + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('resolvconf') + end + + it 'creates /etc/bind/named.conf.options' do + expect(chef_run).to create_template('/etc/bind/named.conf.options').with( + user: 'bind', + group: 'bind', + mode: 0644, + ) + end + + it 'creates /etc/bind/named.conf' do + expect(chef_run).to create_template('/etc/bind/named.conf').with( + user: 'bind', + group: 'bind', + mode: 0644, + ) + end + + it '/etc/bind/named.conf notifies bind9 to restart' do + expect(chef_run.template('/etc/bind/named.conf')).to notify('service[bind9]').to(:restart) + end + + it 'creates /etc/bind/named.conf.local' do + expect(chef_run).to create_template('/etc/bind/named.conf').with( + user: 'bind', + group: 'bind', + mode: 0644, + variables: { :zonefiles => [{"id"=>"exampleDOTcom"}] } + ) + end + +# it '/etc/bind/named.conf.local notifies bind9 to restart' do +# expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) +# end + + end +end diff --git a/tmp/rspec_guard_result b/tmp/rspec_guard_result new file mode 100644 index 0000000..43ae73c --- /dev/null +++ b/tmp/rspec_guard_result @@ -0,0 +1 @@ +./spec/unit/recipes_spec/server_spec.rb:82 From 2bda973d842ca137860dc7224db0817204aab949 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Fri, 18 Apr 2014 17:07:22 -0500 Subject: [PATCH 02/15] more Chefspec testing --- recipes/chroot.rb | 120 ++++++++-------- recipes/server.rb | 132 +++++++++--------- spec/spec_helper.rb | 2 +- spec/unit/recipes_spec/chroot_spec.rb | 134 +++++++++--------- spec/unit/recipes_spec/server_spec.rb | 188 ++++++++++++++++++++++---- tmp/rspec_guard_result | 3 +- 6 files changed, 359 insertions(+), 220 deletions(-) diff --git a/recipes/chroot.rb b/recipes/chroot.rb index 03a7747..b079caa 100644 --- a/recipes/chroot.rb +++ b/recipes/chroot.rb @@ -19,7 +19,7 @@ case node[:platform] when "ubuntu" if node[:platform_version].to_f >= 12.04 - ruby_block "copy_openssl_dependencies" do + ruby_block "copy_openssl_dependencies" do block do FileUtils.mkdir_p File.dirname(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) FileUtils.cp_r node[:bind9][:openssl], File.dirname(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) @@ -39,72 +39,72 @@ end -ruby_block "modify_init_script" do - block do - rc = Chef::Util::FileEdit.new("/etc/init.d/bind9") - rc.search_file_replace(Regexp.new("/var/run/named"), "${PIDDIR}") - rc.write_file - end - not_if { ::File.readlines('/etc/init.d/bind9').grep(Regexp.new("/var/run/named")).empty? } -end +#ruby_block "modify_init_script" do +# block do +# rc = Chef::Util::FileEdit.new("/etc/init.d/bind9") +# rc.search_file_replace(Regexp.new("/var/run/named"), "${PIDDIR}") +# rc.write_file +# end +# not_if { ::File.readlines('/etc/init.d/bind9').grep(Regexp.new("/var/run/named")).empty? } +#end -chroot_config_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:config_path]) +#chroot_config_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:config_path]) -directory chroot_config_dir do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true -end +#directory chroot_config_dir do +# owner node[:bind9][:user] +# group node[:bind9][:user] +# mode 0744 +# recursive true +#end -ruby_block "move_config_to_chroot" do - block do - FileUtils.rm_rf chroot_config_dir - FileUtils.mv node[:bind9][:config_path], chroot_config_dir - end - not_if { ::File.symlink?(node[:bind9][:config_path]) } -end +#ruby_block "move_config_to_chroot" do +# block do +# FileUtils.rm_rf chroot_config_dir +# FileUtils.mv node[:bind9][:config_path], chroot_config_dir +# end +# not_if { ::File.symlink?(node[:bind9][:config_path]) } +#end -directory chroot_config_dir do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true -end +#directory chroot_config_dir do +# owner node[:bind9][:user] +# group node[:bind9][:user] +# mode 0744 +# recursive true +#end -link "bind_config_from_chroot" do - target_file node[:bind9][:config_path] - to chroot_config_dir - not_if { ::File.symlink?(node[:bind9][:config_path]) } -end +#link "bind_config_from_chroot" do +# target_file node[:bind9][:config_path] +# to chroot_config_dir +# not_if { ::File.symlink?(node[:bind9][:config_path]) } +#end -chroot_zones_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) +#chroot_zones_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) -directory chroot_zones_dir do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true - not_if { chroot_zones_dir.start_with?(chroot_config_dir) } -end +#directory chroot_zones_dir do +# owner node[:bind9][:user] +# group node[:bind9][:user] +# mode 0744 +# recursive true +# not_if { chroot_zones_dir.start_with?(chroot_config_dir) } +#end -link "bind_zones_from_chroot" do - target_file node[:bind9][:zones_path] - to chroot_zones_dir - not_if { ::File.symlink?(node[:bind9][:zones_path]) or chroot_zones_dir.start_with?(chroot_config_dir) } -end +#link "bind_zones_from_chroot" do +# target_file node[:bind9][:zones_path] +# to chroot_zones_dir +# not_if { ::File.symlink?(node[:bind9][:zones_path]) or chroot_zones_dir.start_with?(chroot_config_dir) } +#end -directory File.join(node[:bind9][:chroot_dir].to_s, "/dev") do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true -end +#directory File.join(node[:bind9][:chroot_dir].to_s, "/dev") do +# owner node[:bind9][:user] +# group node[:bind9][:user] +# mode 0744 +# recursive true +#end -execute "create_special_device_files" do - command "mknod #{node[:bind9][:chroot_dir]}/dev/null c 1 3; - mknod #{node[:bind9][:chroot_dir]}/dev/random c 1 8; - chmod 666 #{node[:bind9][:chroot_dir]}/dev/null; - chmod 666 #{node[:bind9][:chroot_dir]}/dev/random" - not_if { ::File.exists?( File.join(node[:bind9][:chroot_dir].to_s, "/dev/null")) } -end +#execute "create_special_device_files" do +# command "mknod #{node[:bind9][:chroot_dir]}/dev/null c 1 3; +# mknod #{node[:bind9][:chroot_dir]}/dev/random c 1 8; +# chmod 666 #{node[:bind9][:chroot_dir]}/dev/null; +# chmod 666 #{node[:bind9][:chroot_dir]}/dev/random" +# not_if { ::File.exists?( File.join(node[:bind9][:chroot_dir].to_s, "/dev/null")) } +#end diff --git a/recipes/server.rb b/recipes/server.rb index b034141..0193bc7 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -17,6 +17,8 @@ # limitations under the License. # +p node[:bind9][:chroot_dir] + package "bind9" do case node[:platform] when "centos", "redhat", "suse", "fedora" @@ -88,8 +90,6 @@ class Chef::Recipe::NameServer notifies :restart, "service[bind9]" end -p search(:zones) - template File.join(node[:bind9][:config_path], node[:bind9][:local_file]) do source "named.conf.local.erb" owner node[:bind9][:user] @@ -102,67 +102,67 @@ class Chef::Recipe::NameServer end -#template node[:bind9][:defaults_file] do -# source "bind9.erb" -# owner node[:bind9][:user] -# group node[:bind9][:user] -# mode 0644 -# notifies :restart, "service[bind9]" -# not_if { node[:bind9][:defaults_file].nil? } -#end - - -#directory node[:bind9][:zones_path] do -# owner node[:bind9][:user] -# group node[:bind9][:user] -# mode 0744 -# recursive true -# not_if { ::File.directory?(node[:bind9][:zones_path]) or ::File.symlink?(node[:bind9][:zones_path]) } -#end - -#search(:zones).each do |zone| - #unless zone['autodomain'].nil? || zone['autodomain'] == '' - # search(:node, "domain:#{zone['autodomain']}").each do |host| - # next if host['ipaddress'] == '' || host['ipaddress'].nil? - # zone['zone_info']['records'].push( { - # "name" => host['hostname'], - # "type" => "A", - # "ip" => host['ipaddress'] - # }) - # end - #end - -# template File.join(node[:bind9][:zones_path], zone['domain']) do -# source File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") -# local true -# owner node[:bind9][:user] -# group node[:bind9][:user] -# mode 0644 -# notifies :restart, "service[bind9]" -# variables({ -# :serial => zone['zone_info']['serial'] || Time.new.strftime("%Y%m%d%H%M%S") -# }) -# action :nothing -# end - -# template File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") do -# source "zonefile.erb" -# owner node[:bind9][:user] -# group node[:bind9][:user] -# mode 0644 -# variables({ -# :domain => zone['domain'], -# :soa => zone['zone_info']['soa'], -# :contact => zone['zone_info']['contact'], -# :global_ttl => zone['zone_info']['global_ttl'], -# :nameserver => zone['zone_info']['nameserver'], -# :mail_exchange => zone['zone_info']['mail_exchange'], -# :records => zone['zone_info']['records'] -# }) -# notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately -# end -#end - -#service "bind9" do -# action [ :start ] -#end +template node[:bind9][:defaults_file] do + source "bind9.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + notifies :restart, "service[bind9]" + not_if { node[:bind9][:defaults_file].nil? } +end + + +directory node[:bind9][:zones_path] do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0744 + recursive true + not_if { ::File.directory?(node[:bind9][:zones_path]) or ::File.symlink?(node[:bind9][:zones_path]) } +end + +search(:zones).each do |zone| + unless zone['autodomain'].nil? || zone['autodomain'] == '' + search(:node, "domain:#{zone['autodomain']}").each do |host| + next if host['ipaddress'] == '' || host['ipaddress'].nil? + zone['zone_info']['records'].push( { + "name" => host['hostname'], + "type" => "A", + "ip" => host['ipaddress'] + }) + end + end + + template File.join(node[:bind9][:zones_path], zone['domain']) do + source File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") + local true + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + notifies :restart, "service[bind9]" + variables({ + :serial => zone['zone_info']['serial'] || Time.new.strftime("%Y%m%d%H%M%S") + }) + action :nothing + end + + template File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") do + source "zonefile.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + variables({ + :domain => zone['domain'], + :soa => zone['zone_info']['soa'], + :contact => zone['zone_info']['contact'], + :global_ttl => zone['zone_info']['global_ttl'], + :nameserver => zone['zone_info']['nameserver'], + :mail_exchange => zone['zone_info']['mail_exchange'], + :records => zone['zone_info']['records'] + }) + notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately + end +end + +service "bind9" do + action [ :start ] +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dfd554a..ba70ebf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,7 @@ # spec_helper.rb require 'chefspec' require 'chefspec/berkshelf' -require 'fakefs/safe' +#require 'fakefs/safe' ChefSpec::Coverage.start! diff --git a/spec/unit/recipes_spec/chroot_spec.rb b/spec/unit/recipes_spec/chroot_spec.rb index c70fa4f..bfefea7 100644 --- a/spec/unit/recipes_spec/chroot_spec.rb +++ b/spec/unit/recipes_spec/chroot_spec.rb @@ -20,7 +20,7 @@ expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') end - it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind does not exists' do + it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do File.stub(:directory?).with(anything).and_call_original File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') @@ -30,73 +30,73 @@ expect(chef_run).to run_ruby_block('copy_openssl_dependencies') end - it 'creates directory /var/run/bind/var/run/named' do - expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end +# it 'creates directory /var/run/bind/var/run/named' do +# expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( +# user: 'bind', +# group: 'bind', +# mode: 0744, +# recursive: true +# ) +# end - it 'runs ruby_block modify_init_script' do - expect(chef_run).to run_ruby_block('modify_init_script') - end - - it 'does not run ruby_block modify_init_script' do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) - expect(chef_run).to_not run_ruby_block('modify_init_script') - end - - it 'creates directory /var/run/bind/etc/bind' do - expect(chef_run).to create_directory('/var/run/bind/etc/bind').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - - it 'runs ruby_block move_config_to_chroot' do - expect(chef_run).to run_ruby_block('move_config_to_chroot') - end - - it 'links bind config from chroot' do - expect(chef_run).to create_link('/etc/bind').with(to: '/var/run/bind/etc/bind') - end - - it 'does not create directory /var/run/bind/etc/bind/zones' do - expect(chef_run).to_not create_directory('/var/run/bind/etc/bind/zones').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - - it 'does not link bind zones from chroot' do - expect(chef_run).to_not create_link('/etc/bind/zones').with(to: '/var/run/bind/etc/bind/zones') - end - - it 'creates directory /var/run/bind/dev' do - expect(chef_run).to create_directory('/var/run/bind/dev').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - - it 'creates special device files' do - expect(chef_run).to run_execute('create_special_device_files') - end - - it 'does not create special device files' do - File.stub(:exists?).with(anything).and_call_original - File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) - expect(chef_run).to_not run_execute('create_special_device_files') - end +# it 'runs ruby_block modify_init_script' do +# expect(chef_run).to run_ruby_block('modify_init_script') +# end + +# it 'does not run ruby_block modify_init_script' do +# File.stub(:readlines).with(anything).and_call_original +# File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) +# expect(chef_run).to_not run_ruby_block('modify_init_script') +# end + +# it 'creates directory /var/run/bind/etc/bind' do +# expect(chef_run).to create_directory('/var/run/bind/etc/bind').with( +# user: 'bind', +# group: 'bind', +# mode: 0744, +# recursive: true +# ) +# end + +# it 'runs ruby_block move_config_to_chroot' do +# expect(chef_run).to run_ruby_block('move_config_to_chroot') +# end + +# it 'links bind config from chroot' do +# expect(chef_run).to create_link('/etc/bind').with(to: '/var/run/bind/etc/bind') +# end + +# it 'does not create directory /var/run/bind/etc/bind/zones' do +# expect(chef_run).to_not create_directory('/var/run/bind/etc/bind/zones').with( +# user: 'bind', +# group: 'bind', +# mode: 0744, +# recursive: true +# ) +# end + +# it 'does not link bind zones from chroot' do +# expect(chef_run).to_not create_link('/etc/bind/zones').with(to: '/var/run/bind/etc/bind/zones') +# end + +# it 'creates directory /var/run/bind/dev' do +# expect(chef_run).to create_directory('/var/run/bind/dev').with( +# user: 'bind', +# group: 'bind', +# mode: 0744, +# recursive: true +# ) +# end + +# it 'creates special device files' do +# expect(chef_run).to run_execute('create_special_device_files') +# end + +# it 'does not create special device files' do +# File.stub(:exists?).with(anything).and_call_original +# File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) +# expect(chef_run).to_not run_execute('create_special_device_files') +# end end end diff --git a/spec/unit/recipes_spec/server_spec.rb b/spec/unit/recipes_spec/server_spec.rb index 51d9042..e005bf8 100644 --- a/spec/unit/recipes_spec/server_spec.rb +++ b/spec/unit/recipes_spec/server_spec.rb @@ -4,10 +4,43 @@ let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } context 'Ubuntu 12.04' do - let(:chef_run) { ChefSpec::Runner.new(UBUNTU_OPTS).converge(described_recipe) } - + let(:chef_run) { ChefSpec::Runner.new(UBUNTU_OPTS).converge(described_recipe) } + let(:zones) { + [ + { + 'id' => 'exampleDOTcom', + 'domain' => 'example.com', + 'zone_info' => { + 'serial' =>'00000', + 'soa' => 'ns.example.com', + 'contact' => 'root.example.com', + 'global_ttl' => 300, + 'nameserver' => [ + 'ns1.example.com', + 'ns2.example.com' + ], + 'mail_exchange' => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM.', + 'priority' => 10, + } + ], + 'records' => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + } + ] + } + before(:each) do - stub_search("zones", "*:*").and_return([ {"id"=>"exampleDOTcom"} ]) + stub_search("zones", "*:*").and_return(zones) + chef_run.node.set[:bind9][:chroot_dir] = nil + chef_run.converge(described_recipe) end it 'installs bind9' do @@ -27,6 +60,18 @@ ) end + it 'creates directory /var/run/bind/var/cache/bind owned by bind user' do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/var/cache/bind').with( + user: 'bind', + group: 'bind', + mode: 0755, + recursive: true + ) + end + + it 'creates directory /var/log/bind owned by bind user' do expect(chef_run).to create_directory('/var/log/bind').with( user: 'bind', @@ -36,6 +81,17 @@ ) end + it 'creates directory /var/run/bind/var/log/bind owned by bind user' do +# chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' +# chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/var/log/bind').with( + user: 'bind', + group: 'bind', + mode: 0755, + recursive: true + ) + end + it 'creates directory /etc/bind/zones owned by bind user' do expect(chef_run).to create_directory('/etc/bind/zones').with( user: 'bind', @@ -45,12 +101,31 @@ ) end - it 'does not include bind9-chroot::chroot recipe' do - expect(chef_run).to_not include_recipe('bind9-chroot::chroot') + it 'creates directory /var/run/bind/etc/bind/zones owned by bind user' do +# chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' +# chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/etc/bind/zones').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) end + +# it 'includes bind9-chroot::chroot recipe' do +# chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' +# chef_run.converge(described_recipe) +# expect(chef_run).to include_recipe('bind9-chroot::chroot') +# end +# it 'does not include resolvconf recipe' do +# expect(chef_run).to_not include_recipe('resolvconf') +# end + it 'does include resolvconf recipe' do - expect(chef_run).to_not include_recipe('resolvconf') + chef_run.node.set[:bind9][:resolvconf] = true + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('resolvconf') end it 'includes resolvconf recipe' do @@ -59,20 +134,20 @@ expect(chef_run).to include_recipe('resolvconf') end - it 'creates /etc/bind/named.conf.options' do + it 'creates template /etc/bind/named.conf.options' do expect(chef_run).to create_template('/etc/bind/named.conf.options').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) + user: 'bind', + group: 'bind', + mode: 0644, + ) end - it 'creates /etc/bind/named.conf' do + it 'creates template /etc/bind/named.conf' do expect(chef_run).to create_template('/etc/bind/named.conf').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) + user: 'bind', + group: 'bind', + mode: 0644, + ) end it '/etc/bind/named.conf notifies bind9 to restart' do @@ -80,17 +155,80 @@ end it 'creates /etc/bind/named.conf.local' do - expect(chef_run).to create_template('/etc/bind/named.conf').with( - user: 'bind', - group: 'bind', - mode: 0644, - variables: { :zonefiles => [{"id"=>"exampleDOTcom"}] } - ) + expect(chef_run).to create_template('/etc/bind/named.conf.local').with( + user: 'bind', + group: 'bind', + mode: 0644, + variables: { :zonefiles => zones } + ) end -# it '/etc/bind/named.conf.local notifies bind9 to restart' do -# expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) -# end + it '/etc/bind/named.conf.local notifies bind9 to restart' do + expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) + end + + it 'creates /etc/default/bind9' do + expect(chef_run).to create_template('/etc/default/bind9').with( + user: 'bind', + group: 'bind', + mode: 0644, + ) + end + + it '/etc/default/bind9 notifies bind9 to restart' do + expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) + end + + it 'does not create /etc/bind/zones/example.com' do + expect(chef_run).to_not create_template('/etc/bind/zones/example.com').with( + source: '/etc/bind/zones/example.com.erb', + local: true, + user: 'bind', + group: 'bind', + mode: 0644, + variables: { :serial => '00000' } + ) + end + + it 'creates /etc/bind/zones/example.com.erb' do + expect(chef_run).to create_template('/etc/bind/zones/example.com.erb').with( + source: 'zonefile.erb', + user: 'bind', + group: 'bind', + mode: 0644, + variables: { + :domain => 'example.com', + :soa => 'ns.example.com', + :contact => 'root.example.com', + :global_ttl => 300, + :nameserver => [ + 'ns1.example.com', + 'ns2.example.com' + ], + :mail_exchange => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM.', + 'priority' => 10 + } + ], + :records => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + ) + end + + it 'notifies /etc/bind/zones/example.com immediately' do + expect(chef_run.template('/etc/bind/zones/example.com.erb')).to notify('template[/etc/bind/zones/example.com]').to(:create).immediately + end + + it 'starts bind9 service' do + expect(chef_run).to start_service('bind9') + end end end diff --git a/tmp/rspec_guard_result b/tmp/rspec_guard_result index 43ae73c..a11b7b6 100644 --- a/tmp/rspec_guard_result +++ b/tmp/rspec_guard_result @@ -1 +1,2 @@ -./spec/unit/recipes_spec/server_spec.rb:82 +./spec/unit/recipes_spec/server_spec.rb:84 +./spec/unit/recipes_spec/server_spec.rb:104 From 5cbb0565e64ab1b46616297c1915763078b3dbc1 Mon Sep 17 00:00:00 2001 From: Brad Wadsworth Date: Sun, 20 Apr 2014 11:03:15 -0500 Subject: [PATCH 03/15] fixing chefspecs --- .gitignore | 9 +- .kitchen.yml | 16 ++ Berksfile | 3 +- Thorfile | 12 ++ chefignore | 2 - metadata.json | 32 ---- recipes/chroot.rb | 118 ++++++------ recipes/server.rb | 2 - spec/unit/recipes_spec/chroot_spec.rb | 194 +++++++++---------- spec/unit/recipes_spec/server_spec.rb | 265 +++++++++++++------------- tmp/rspec_guard_result | 3 +- 11 files changed, 329 insertions(+), 327 deletions(-) create mode 100644 .kitchen.yml create mode 100644 Thorfile delete mode 100644 metadata.json diff --git a/.gitignore b/.gitignore index 45b891c..cbccf1e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,20 @@ -.vagrant -Berksfile.lock *~ *# .#* \#*# .*.sw[a-z] *.un~ +pkg/ + +# Berkshelf +.vagrant /cookbooks +Berksfile.lock # Bundler Gemfile.lock bin/* .bundle/* +.kitchen/ +.kitchen.local.yml diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 0000000..cbab9da --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,16 @@ +--- +driver: + name: vagrant + +provisioner: + name: chef_solo + +platforms: + - name: ubuntu-12.04 + - name: centos-6.4 + +suites: + - name: default + run_list: + - recipe[bind9-chroot::default] + attributes: diff --git a/Berksfile b/Berksfile index c4bb297..0e89e8b 100644 --- a/Berksfile +++ b/Berksfile @@ -1,3 +1,4 @@ -site :opscode +#site :opscode +source "http://api.berkshelf.com" metadata diff --git a/Thorfile b/Thorfile new file mode 100644 index 0000000..b23ee16 --- /dev/null +++ b/Thorfile @@ -0,0 +1,12 @@ +# encoding: utf-8 + +require 'bundler' +require 'bundler/setup' +require 'berkshelf/thor' + +begin + require 'kitchen/thor_tasks' + Kitchen::ThorTasks.new +rescue LoadError + puts ">>>>> Kitchen gem not loaded, omitting tasks" unless ENV['CI'] +end diff --git a/chefignore b/chefignore index a6de142..138a808 100644 --- a/chefignore +++ b/chefignore @@ -69,8 +69,6 @@ Procfile # Berkshelf # ############# -Berksfile -Berksfile.lock cookbooks/* tmp diff --git a/metadata.json b/metadata.json deleted file mode 100644 index 6b62e35..0000000 --- a/metadata.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "bind9-chroot", - "description": "Installs/Configures bind9 with chroot and hiding CHAOS INFORMATION", - "long_description": "#Description\n\nThis cookbook takes care of the installation and configuration of BIND9. You're able to define some global variables and manage your zonefiles via data bags (json example below).\nIt also supports automatic serial number generation and automatic resource records for chef nodes (see optional json in example below)\nNo DNSSEC, no configurable logging, no rndc shell operations or other safety checks (named-checkconf, etc.).\n\nIf you want to help feel free to contribute (either here or at [Mike Adolphs's cookbook](https://github.com/fooforge/chef-cookbook_bind9), which this is based on)!\n\n**DISCLAIMER**: \nIt works on my setup!\n\n#Requirements\n\nPlatform:\n\n* Debian\n* Ubuntu\n* Centos\n\n#Attributes\n\nIt's so much better if you take a look at the ```attributes/default.rb``` file for the full list, but this is a brief summary:\n\n* **node[:bind9][:enable_ipv6]** - Enables BIND to listen on an IPv6 address. Default is: On\n* **node[:bind9][:allow_query]** - Allow clients to query the nameserver. Default is: none\n* **node[:bind9][:allow_recursion]** - Allow recursive name resolution. Default is: none (to prevent DNS cache poisoning)\n* **node[:bind9][:allow_update]** - Allow dynamic DNS updates. Default is: none\n* **node[:bind9][:allow_transfer]** - Allow zone transfers globally. Default is: none\n* **node[:bind9][:enable_forwarding]** - Enables forwarding of requests. Default is: No forwarding\n* **node[:bind9][:forwarders]** - Array for forwarding DNS. Default is: 8.8.4.4 and 8.8.8.8 (Google DNS)\n* **node[:bind9][:chroot_dir]** - Enables running in a chroot'ed environment. Default is: no chroot'ing\n* **node[:bind9][:disclose]** - Enables disclosing CHAOS information. Default is: false\n\n\n#Usage\n\nAdd ```\"recipe[bind9-chroot]\"``` to your run list. If you want to use BIND9 for serving domains you need add the appropriate data via data bags (example below).\nPlease note that the data bag's structure is mandatory except: \n\n* TTL for DNS records (if you decide to leave it empty, the global TTL will take over).\n* IP for DNS records (if not available, ```node['ipaddress']``` will be used).\n\nIn order to run a a chroot'ed Bind9 server, set the ```node[:bind9][:chroot_dir]``` to the desired chroot path and optionally the ```node[:bind9][:disclose]``` attributes.\n\nTo use this cookbook with Chef Solo, add ```\"recipe[chef-solo-search]\"``` to your run list, and create the data bags either manually or using the ```knife-solo_data_bag``` gem.\n\n#Examples\n\nTo create and view the data bags:\n\n $ knife data bag create zones\n $ knife data bag create zones exampleDOTcom\n $ ... do something ...\n $ knife data bag from file zones exampleDOTcom.json\n\nAn example of a data bag with mail records and specific IPs.\n\n {\n \"id\": \"exampleDOTcom\",\n \"domain\": \"example.com\",\n \"type\": \"master\",\n \"allow_transfer\": [ \"8.8.4.4\",\n \"8.8.8.8\" ],\n \"zone_info\": {\n \"global_ttl\": 300,\n \"soa\": \"ns.example.com.\",\n \"contact\": \"user.example.com.\",\n \"nameserver\": [ \"ns.example.com.\",\n \"ns.example.net.\" ],\n \"mail_exchange\": [{\n \"host\": \"ASPMX.L.GOOGLE.COM.\",\n \"priority\": 10\n },{\n \"host\": \"ALT1.ASPMX.L.GOOGLE.COM.\",\n \"priority\": 20\n },{\n \"host\": \"ALT2.ASPMX.L.GOOGLE.COM.\",\n \"priority\": 20\n },{\n \"host\": \"ASPMX2.GOOGLEMAIL.COM.\",\n \"priority\": 30\n },{\n \"host\": \"ASPMX3.GOOGLEMAIL.COM.\",\n \"priority\": 30\n },{\n \"host\": \"ASPMX4.GOOGLEMAIL.COM.\",\n \"priority\": 30\n },{\n \"host\": \"ASPMX5.GOOGLEMAIL.COM.\",\n \"priority\": 30\n }],\n \"records\": [{\n \"name\": \"www\",\n \"type\": \"A\",\n \"ip\": \"127.0.0.1\"\n },{\n \"name\": \"img\",\n \"ttl\": 30,\n \"type\": \"A\",\n \"ip\": \"127.0.0.1\"\n },{\n \"name\": \"mail\",\n \"type\": \"CNAME\",\n \"ip\": \"ghs.google.com.\"\n }]\n }\n }\n\nAn example of a data bag with mail records and specific IPs.\n\n {\n \"id\": \"exampleDOTcom\",\n \"domain\": \"example.com\",\n \"type\": \"master\",\n \"allow_transfer\": [],\n \"zone_info\": {\n \"global_ttl\": 300,\n \"soa\": \"ns.example.com.\",\n \"contact\": \"user.example.com.\",\n \"nameserver\": [ \"ns.example.com.\",\n \"ns.example.net.\" ],\n \"mail_exchange\": [],\n \"records\": [{\n \"name\": \"www\",\n \"type\": \"A\"\n },{\n \"name\": \"img\",\n \"ttl\": 30,\n \"type\": \"A\"\n },{\n \"name\": \"mail\",\n \"type\": \"CNAME\"\n }]\n }\n }\n \n#Contributions\n\nThis cookbook is derived from [Mike Adolphs's](https://github.com/fooforge/chef-cookbook_bind9), and specific contributions can be tracked via git.", - "maintainer": "Tnarik Innael", - "maintainer_email": "tnarik@lecafeautomatique.co.uk", - "license": "Apache 2.0", - "platforms": { - "ubuntu": ">= 0.0.0", - "debian": ">= 0.0.0", - "centos": ">= 0.0.0" - }, - "dependencies": { - }, - "recommendations": { - }, - "suggestions": { - }, - "conflicting": { - }, - "providing": { - }, - "replacing": { - }, - "attributes": { - }, - "groupings": { - }, - "recipes": { - }, - "version": "0.4.1" -} diff --git a/recipes/chroot.rb b/recipes/chroot.rb index b079caa..835fe0c 100644 --- a/recipes/chroot.rb +++ b/recipes/chroot.rb @@ -39,72 +39,72 @@ end -#ruby_block "modify_init_script" do -# block do -# rc = Chef::Util::FileEdit.new("/etc/init.d/bind9") -# rc.search_file_replace(Regexp.new("/var/run/named"), "${PIDDIR}") -# rc.write_file -# end -# not_if { ::File.readlines('/etc/init.d/bind9').grep(Regexp.new("/var/run/named")).empty? } -#end +ruby_block "modify_init_script" do + block do + rc = Chef::Util::FileEdit.new("/etc/init.d/bind9") + rc.search_file_replace(Regexp.new("/var/run/named"), "${PIDDIR}") + rc.write_file + end + not_if { ::File.readlines('/etc/init.d/bind9').grep(Regexp.new("/var/run/named")).empty? } +end -#chroot_config_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:config_path]) +chroot_config_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:config_path]) -#directory chroot_config_dir do -# owner node[:bind9][:user] -# group node[:bind9][:user] -# mode 0744 -# recursive true -#end +directory chroot_config_dir do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0744 + recursive true +end -#ruby_block "move_config_to_chroot" do -# block do -# FileUtils.rm_rf chroot_config_dir -# FileUtils.mv node[:bind9][:config_path], chroot_config_dir -# end -# not_if { ::File.symlink?(node[:bind9][:config_path]) } -#end +ruby_block "move_config_to_chroot" do + block do + FileUtils.rm_rf chroot_config_dir + FileUtils.mv node[:bind9][:config_path], chroot_config_dir + end + not_if { ::File.symlink?(node[:bind9][:config_path]) } +end -#directory chroot_config_dir do -# owner node[:bind9][:user] -# group node[:bind9][:user] -# mode 0744 -# recursive true -#end +directory chroot_config_dir do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0744 + recursive true +end -#link "bind_config_from_chroot" do -# target_file node[:bind9][:config_path] -# to chroot_config_dir -# not_if { ::File.symlink?(node[:bind9][:config_path]) } -#end +link "bind_config_from_chroot" do + target_file node[:bind9][:config_path] + to chroot_config_dir + not_if { ::File.symlink?(node[:bind9][:config_path]) } +end -#chroot_zones_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) +chroot_zones_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) -#directory chroot_zones_dir do -# owner node[:bind9][:user] -# group node[:bind9][:user] -# mode 0744 -# recursive true -# not_if { chroot_zones_dir.start_with?(chroot_config_dir) } -#end +directory chroot_zones_dir do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0744 + recursive true + not_if { chroot_zones_dir.start_with?(chroot_config_dir) } +end -#link "bind_zones_from_chroot" do -# target_file node[:bind9][:zones_path] -# to chroot_zones_dir -# not_if { ::File.symlink?(node[:bind9][:zones_path]) or chroot_zones_dir.start_with?(chroot_config_dir) } -#end +link "bind_zones_from_chroot" do + target_file node[:bind9][:zones_path] + to chroot_zones_dir + not_if { ::File.symlink?(node[:bind9][:zones_path]) or chroot_zones_dir.start_with?(chroot_config_dir) } +end -#directory File.join(node[:bind9][:chroot_dir].to_s, "/dev") do -# owner node[:bind9][:user] -# group node[:bind9][:user] -# mode 0744 -# recursive true -#end +directory File.join(node[:bind9][:chroot_dir].to_s, "/dev") do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0744 + recursive true +end -#execute "create_special_device_files" do -# command "mknod #{node[:bind9][:chroot_dir]}/dev/null c 1 3; -# mknod #{node[:bind9][:chroot_dir]}/dev/random c 1 8; -# chmod 666 #{node[:bind9][:chroot_dir]}/dev/null; -# chmod 666 #{node[:bind9][:chroot_dir]}/dev/random" -# not_if { ::File.exists?( File.join(node[:bind9][:chroot_dir].to_s, "/dev/null")) } -#end +execute "create_special_device_files" do + command "mknod #{node[:bind9][:chroot_dir]}/dev/null c 1 3; + mknod #{node[:bind9][:chroot_dir]}/dev/random c 1 8; + chmod 666 #{node[:bind9][:chroot_dir]}/dev/null; + chmod 666 #{node[:bind9][:chroot_dir]}/dev/random" + not_if { ::File.exists?( File.join(node[:bind9][:chroot_dir].to_s, "/dev/null")) } +end diff --git a/recipes/server.rb b/recipes/server.rb index 0193bc7..dbd38d8 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -17,8 +17,6 @@ # limitations under the License. # -p node[:bind9][:chroot_dir] - package "bind9" do case node[:platform] when "centos", "redhat", "suse", "fedora" diff --git a/spec/unit/recipes_spec/chroot_spec.rb b/spec/unit/recipes_spec/chroot_spec.rb index bfefea7..ecc36e9 100644 --- a/spec/unit/recipes_spec/chroot_spec.rb +++ b/spec/unit/recipes_spec/chroot_spec.rb @@ -1,102 +1,102 @@ require 'spec_helper' - -describe 'bind9-chroot::chroot' do - - context 'Ubuntu 12.04' do - let(:chef_run) do - ChefSpec::Runner.new(UBUNTU_OPTS) do |node| - node.set[:bind9][:chroot_dir] = '/var/run/bind' - end.converge(described_recipe) - end - - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) - end - - it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do - File.stub(:directory?).with(anything).and_call_original - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) - expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') - end - - it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do - File.stub(:directory?).with(anything).and_call_original - File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) - expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') - end - - it 'runs ruby_block copy_openssl_dependencies' do - expect(chef_run).to run_ruby_block('copy_openssl_dependencies') - end - -# it 'creates directory /var/run/bind/var/run/named' do -# expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( -# user: 'bind', -# group: 'bind', -# mode: 0744, -# recursive: true -# ) -# end +shared_context 'chroot recipe' do + describe 'bind9-chroot::chroot' do + context 'Ubuntu 12.04' do + let(:chef_run) do + ChefSpec::Runner.new(UBUNTU_OPTS) do |node| + node.set[:bind9][:chroot_dir] = '/var/run/bind' + end.converge(described_recipe) + end + + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + end + + it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'runs ruby_block copy_openssl_dependencies' do + expect(chef_run).to run_ruby_block('copy_openssl_dependencies') + end + + it 'creates directory /var/run/bind/var/run/named' do + expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end -# it 'runs ruby_block modify_init_script' do -# expect(chef_run).to run_ruby_block('modify_init_script') -# end - -# it 'does not run ruby_block modify_init_script' do -# File.stub(:readlines).with(anything).and_call_original -# File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) -# expect(chef_run).to_not run_ruby_block('modify_init_script') -# end - -# it 'creates directory /var/run/bind/etc/bind' do -# expect(chef_run).to create_directory('/var/run/bind/etc/bind').with( -# user: 'bind', -# group: 'bind', -# mode: 0744, -# recursive: true -# ) -# end - -# it 'runs ruby_block move_config_to_chroot' do -# expect(chef_run).to run_ruby_block('move_config_to_chroot') -# end - -# it 'links bind config from chroot' do -# expect(chef_run).to create_link('/etc/bind').with(to: '/var/run/bind/etc/bind') -# end - -# it 'does not create directory /var/run/bind/etc/bind/zones' do -# expect(chef_run).to_not create_directory('/var/run/bind/etc/bind/zones').with( -# user: 'bind', -# group: 'bind', -# mode: 0744, -# recursive: true -# ) -# end - -# it 'does not link bind zones from chroot' do -# expect(chef_run).to_not create_link('/etc/bind/zones').with(to: '/var/run/bind/etc/bind/zones') -# end - -# it 'creates directory /var/run/bind/dev' do -# expect(chef_run).to create_directory('/var/run/bind/dev').with( -# user: 'bind', -# group: 'bind', -# mode: 0744, -# recursive: true -# ) -# end - -# it 'creates special device files' do -# expect(chef_run).to run_execute('create_special_device_files') -# end - -# it 'does not create special device files' do -# File.stub(:exists?).with(anything).and_call_original -# File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) -# expect(chef_run).to_not run_execute('create_special_device_files') -# end + it 'runs ruby_block modify_init_script' do + expect(chef_run).to run_ruby_block('modify_init_script') + end + + it 'does not run ruby_block modify_init_script' do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) + expect(chef_run).to_not run_ruby_block('modify_init_script') + end + + it 'creates directory /var/run/bind/etc/bind' do + expect(chef_run).to create_directory('/var/run/bind/etc/bind').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block move_config_to_chroot' do + expect(chef_run).to run_ruby_block('move_config_to_chroot') + end + + it 'links bind config from chroot' do + expect(chef_run).to create_link('/etc/bind').with(to: '/var/run/bind/etc/bind') + end + + it 'does not create directory /var/run/bind/etc/bind/zones' do + expect(chef_run).to_not create_directory('/var/run/bind/etc/bind/zones').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'does not link bind zones from chroot' do + expect(chef_run).to_not create_link('/etc/bind/zones').with(to: '/var/run/bind/etc/bind/zones') + end + + it 'creates directory /var/run/bind/dev' do + expect(chef_run).to create_directory('/var/run/bind/dev').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'creates special device files' do + expect(chef_run).to run_execute('create_special_device_files') + end + + it 'does not create special device files' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) + expect(chef_run).to_not run_execute('create_special_device_files') + end + end end end diff --git a/spec/unit/recipes_spec/server_spec.rb b/spec/unit/recipes_spec/server_spec.rb index e005bf8..5afb9b2 100644 --- a/spec/unit/recipes_spec/server_spec.rb +++ b/spec/unit/recipes_spec/server_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'unit/recipes_spec/chroot_spec.rb' describe 'bind9-chroot::server' do let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } @@ -39,8 +40,6 @@ before(:each) do stub_search("zones", "*:*").and_return(zones) - chef_run.node.set[:bind9][:chroot_dir] = nil - chef_run.converge(described_recipe) end it 'installs bind9' do @@ -60,16 +59,16 @@ ) end - it 'creates directory /var/run/bind/var/cache/bind owned by bind user' do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/var/cache/bind').with( - user: 'bind', - group: 'bind', - mode: 0755, - recursive: true - ) - end +# it 'creates directory /var/run/bind/var/cache/bind owned by bind user' do +# chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' +# chef_run.converge(described_recipe) +# expect(chef_run).to create_directory('/var/run/bind/var/cache/bind').with( +# user: 'bind', +# group: 'bind', +# mode: 0755, +# recursive: true +# ) +# end it 'creates directory /var/log/bind owned by bind user' do @@ -81,16 +80,16 @@ ) end - it 'creates directory /var/run/bind/var/log/bind owned by bind user' do +# it 'creates directory /var/run/bind/var/log/bind owned by bind user' do # chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' # chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/var/log/bind').with( - user: 'bind', - group: 'bind', - mode: 0755, - recursive: true - ) - end +# expect(chef_run).to create_directory('/var/run/bind/var/log/bind').with( +# user: 'bind', +# group: 'bind', +# mode: 0755, +# recursive: true +# ) +# end it 'creates directory /etc/bind/zones owned by bind user' do expect(chef_run).to create_directory('/etc/bind/zones').with( @@ -101,134 +100,140 @@ ) end - it 'creates directory /var/run/bind/etc/bind/zones owned by bind user' do -# chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' -# chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/etc/bind/zones').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - -# it 'includes bind9-chroot::chroot recipe' do +# it 'creates directory /var/run/bind/etc/bind/zones owned by bind user' do # chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' # chef_run.converge(described_recipe) -# expect(chef_run).to include_recipe('bind9-chroot::chroot') +# expect(chef_run).to create_directory('/var/run/bind/etc/bind/zones').with( +# user: 'bind', +# group: 'bind', +# mode: 0744, +# recursive: true +# ) # end + + context 'chroot_dir exists' do + include_context 'chroot recipe' + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + end + + it 'includes bind9-chroot::chroot recipe' do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('bind9-chroot::chroot') + end + end + it 'does not include bind9-chroot::chroot recipe' do + expect(chef_run).to_not include_recipe('resolvconf') + end + # it 'does not include resolvconf recipe' do # expect(chef_run).to_not include_recipe('resolvconf') # end - it 'does include resolvconf recipe' do - chef_run.node.set[:bind9][:resolvconf] = true - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('resolvconf') - end - - it 'includes resolvconf recipe' do - chef_run.node.set[:bind9][:resolvconf] = true - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('resolvconf') - end - - it 'creates template /etc/bind/named.conf.options' do - expect(chef_run).to create_template('/etc/bind/named.conf.options').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) - end +# it 'includes resolvconf recipe' do +# chef_run.node.set[:bind9][:resolvconf] = true +# chef_run.converge(described_recipe) +# expect(chef_run).to include_recipe('resolvconf') +# end - it 'creates template /etc/bind/named.conf' do - expect(chef_run).to create_template('/etc/bind/named.conf').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) - end +# it 'creates template /etc/bind/named.conf.options' do +# expect(chef_run).to create_template('/etc/bind/named.conf.options').with( +# user: 'bind', +# group: 'bind', +# mode: 0644, +# ) +# end - it '/etc/bind/named.conf notifies bind9 to restart' do - expect(chef_run.template('/etc/bind/named.conf')).to notify('service[bind9]').to(:restart) - end +# it 'creates template /etc/bind/named.conf' do +# expect(chef_run).to create_template('/etc/bind/named.conf').with( +# user: 'bind', +# group: 'bind', +# mode: 0644, +# ) +# end - it 'creates /etc/bind/named.conf.local' do - expect(chef_run).to create_template('/etc/bind/named.conf.local').with( - user: 'bind', - group: 'bind', - mode: 0644, - variables: { :zonefiles => zones } - ) - end +# it '/etc/bind/named.conf notifies bind9 to restart' do +# expect(chef_run.template('/etc/bind/named.conf')).to notify('service[bind9]').to(:restart) +# end - it '/etc/bind/named.conf.local notifies bind9 to restart' do - expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) - end +# it 'creates /etc/bind/named.conf.local' do +# expect(chef_run).to create_template('/etc/bind/named.conf.local').with( +# user: 'bind', +# group: 'bind', +# mode: 0644, +# variables: { :zonefiles => zones } +# ) +# end - it 'creates /etc/default/bind9' do - expect(chef_run).to create_template('/etc/default/bind9').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) - end +# it '/etc/bind/named.conf.local notifies bind9 to restart' do +# expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) +# end - it '/etc/default/bind9 notifies bind9 to restart' do - expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) - end +# it 'creates /etc/default/bind9' do +# expect(chef_run).to create_template('/etc/default/bind9').with( +# user: 'bind', +# group: 'bind', +# mode: 0644, +# ) +# end - it 'does not create /etc/bind/zones/example.com' do - expect(chef_run).to_not create_template('/etc/bind/zones/example.com').with( - source: '/etc/bind/zones/example.com.erb', - local: true, - user: 'bind', - group: 'bind', - mode: 0644, - variables: { :serial => '00000' } - ) - end +# it '/etc/default/bind9 notifies bind9 to restart' do +# expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) +# end - it 'creates /etc/bind/zones/example.com.erb' do - expect(chef_run).to create_template('/etc/bind/zones/example.com.erb').with( - source: 'zonefile.erb', - user: 'bind', - group: 'bind', - mode: 0644, - variables: { - :domain => 'example.com', - :soa => 'ns.example.com', - :contact => 'root.example.com', - :global_ttl => 300, - :nameserver => [ - 'ns1.example.com', - 'ns2.example.com' - ], - :mail_exchange => [ - { - 'host' => 'ASPMX.L.GOOGLE.COM.', - 'priority' => 10 - } - ], - :records => [ - { - 'name' => 'www', - 'type' => 'A', - 'ip' => '127.0.0.1' - } - ] - } - ) - end +# it 'does not create /etc/bind/zones/example.com' do +# expect(chef_run).to_not create_template('/etc/bind/zones/example.com').with( +# source: '/etc/bind/zones/example.com.erb', +# local: true, +# user: 'bind', +# group: 'bind', +# mode: 0644, +# variables: { :serial => '00000' } +# ) +# end - it 'notifies /etc/bind/zones/example.com immediately' do - expect(chef_run.template('/etc/bind/zones/example.com.erb')).to notify('template[/etc/bind/zones/example.com]').to(:create).immediately - end + # it 'creates /etc/bind/zones/example.com.erb' do + # expect(chef_run).to create_template('/etc/bind/zones/example.com.erb').with( + # source: 'zonefile.erb', + # user: 'bind', + # group: 'bind', + # mode: 0644, + # variables: { + # :domain => 'example.com', + # :soa => 'ns.example.com', + # :contact => 'root.example.com', + # :global_ttl => 300, + # :nameserver => [ + # 'ns1.example.com', + # 'ns2.example.com' + # ], + # :mail_exchange => [ + # { + # 'host' => 'ASPMX.L.GOOGLE.COM.', + # 'priority' => 10 + # } + # ], + # :records => [ + # { + # 'name' => 'www', + # 'type' => 'A', + # 'ip' => '127.0.0.1' + # } + # ] + # } + # ) + # end + + # it 'notifies /etc/bind/zones/example.com immediately' do + # expect(chef_run.template('/etc/bind/zones/example.com.erb')).to notify('template[/etc/bind/zones/example.com]').to(:create).immediately +# end - it 'starts bind9 service' do - expect(chef_run).to start_service('bind9') - end +# it 'starts bind9 service' do +# expect(chef_run).to start_service('bind9') +# end end end diff --git a/tmp/rspec_guard_result b/tmp/rspec_guard_result index a11b7b6..20225d8 100644 --- a/tmp/rspec_guard_result +++ b/tmp/rspec_guard_result @@ -1,2 +1 @@ -./spec/unit/recipes_spec/server_spec.rb:84 -./spec/unit/recipes_spec/server_spec.rb:104 +./spec/unit/recipes_spec/chroot_spec.rb:68 From 9caea672b88eca618486d91c8e8c7674d7990289 Mon Sep 17 00:00:00 2001 From: Brad Wadsworth Date: Mon, 21 Apr 2014 15:18:59 -0500 Subject: [PATCH 04/15] finished initial chefspec tests --- recipes/server.rb | 8 +- spec/spec_helper.rb | 51 +++- spec/unit/recipes_spec/chroot_spec.rb | 147 ++++++---- spec/unit/recipes_spec/server_spec.rb | 387 +++++++++++++------------- tmp/rspec_guard_result | 22 +- 5 files changed, 352 insertions(+), 263 deletions(-) diff --git a/recipes/server.rb b/recipes/server.rb index dbd38d8..7257b7a 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -65,10 +65,10 @@ class Chef::Recipe::NameServer if node[:bind9][:resolvconf] include_recipe "resolvconf" -# # file "/etc/resolvconf/resolv.conf.d/tail" do -# # content NameServer.nameserver_proxy("/etc/resolv.conf", /nameserver.*/) -# # only_if { !::File.exists?("/etc/resolvconf/resolv.conf.d/tail") } -# # end + # file "/etc/resolvconf/resolv.conf.d/tail" do + # content NameServer.nameserver_proxy("/etc/resolv.conf", /nameserver.*/) + # only_if { !::File.exists?("/etc/resolvconf/resolv.conf.d/tail") } + # end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ba70ebf..536a730 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,15 +1,48 @@ # spec_helper.rb require 'chefspec' require 'chefspec/berkshelf' -#require 'fakefs/safe' -ChefSpec::Coverage.start! +PLATFORMS = [ + { + 'platform' => 'ubuntu', + 'version' => '12.04', + 'package' => 'bind9', + 'service' => 'bind9', + 'user' => 'bind', + 'data_path' => '/var/cache/bind', + 'log_dir' => '/var/log/bind', + 'zone_path' => '/etc/bind/zones', + 'config_path' => '/etc/bind', + 'options_file' => 'named.conf.options', + 'config_file' => 'named.conf', + 'local_file' => 'named.conf.local' + }, + { + 'platform' => 'centos', + 'version' => '6.5', + 'package' => 'bind', + 'service' => 'named', + 'user' => 'named', + 'data_path' => '/var/named', + 'log_dir' => '/var/log/named', + 'zone_path' => '/var/named/zones', + 'config_path' => '/etc/named', + 'options_file' => 'named.conf.options', + 'config_file' => 'named.conf', + 'local_file' => 'named.conf.local' + } +] -UBUNTU_OPTS = { - platform: 'ubuntu', - version: '12.04' -} +RSpec.configure do |config| + config.color_enabled = true + config.tty = true + config.formatter = :documentation + config.treat_symbols_as_metadata_keys_with_true_values = true + config.filter_run :focus => true + config.run_all_when_everything_filtered = true + config.expect_with :rspec do |c| + c.syntax = :expect + end +end -#RSpec.configure do |config| -# config.include FakeFS::SpecHelpers, fakefs: true -#end +#at_exit { ChefSpec::Coverage.report! } diff --git a/spec/unit/recipes_spec/chroot_spec.rb b/spec/unit/recipes_spec/chroot_spec.rb index ecc36e9..32b20cd 100644 --- a/spec/unit/recipes_spec/chroot_spec.rb +++ b/spec/unit/recipes_spec/chroot_spec.rb @@ -1,9 +1,12 @@ require 'spec_helper' -shared_context 'chroot recipe' do - describe 'bind9-chroot::chroot' do - context 'Ubuntu 12.04' do + +ChefSpec::Coverage.start! + +describe 'bind9-chroot::chroot' do + PLATFORMS.each do |p| + context "#{p['platform']} #{p['version']}" do let(:chef_run) do - ChefSpec::Runner.new(UBUNTU_OPTS) do |node| + ChefSpec::Runner.new(:platform=>p['platform'],:version=>p['version']) do |node| node.set[:bind9][:chroot_dir] = '/var/run/bind' end.converge(described_recipe) end @@ -11,92 +14,122 @@ before(:each) do File.stub(:readlines).with(anything).and_call_original File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) end + case p['platform'] + when 'ubuntu' it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do - File.stub(:directory?).with(anything).and_call_original - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') end it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do - File.stub(:directory?).with(anything).and_call_original File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') end it 'runs ruby_block copy_openssl_dependencies' do + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) expect(chef_run).to run_ruby_block('copy_openssl_dependencies') end + end + - it 'creates directory /var/run/bind/var/run/named' do - expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end + it 'creates directory /var/run/bind/var/run/named' do + expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( + user: p['user'], + group: p['user'], + mode: 0744, + recursive: true + ) + end - it 'runs ruby_block modify_init_script' do - expect(chef_run).to run_ruby_block('modify_init_script') - end + it 'runs ruby_block modify_init_script' do + expect(chef_run).to run_ruby_block('modify_init_script') + end - it 'does not run ruby_block modify_init_script' do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) - expect(chef_run).to_not run_ruby_block('modify_init_script') - end + it 'does not run ruby_block modify_init_script' do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) + expect(chef_run).to_not run_ruby_block('modify_init_script') + end - it 'creates directory /var/run/bind/etc/bind' do - expect(chef_run).to create_directory('/var/run/bind/etc/bind').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end + it "creates directory /var/run/bind#{p['config_path']}" do + expect(chef_run).to create_directory("/var/run/bind#{p['config_path']}").with( + user: p['user'], + group: p['user'], + mode: 0744, + recursive: true + ) + end - it 'runs ruby_block move_config_to_chroot' do - expect(chef_run).to run_ruby_block('move_config_to_chroot') - end + it 'runs ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with(p['config_path']).and_return(false) + expect(chef_run).to run_ruby_block('move_config_to_chroot') + end - it 'links bind config from chroot' do - expect(chef_run).to create_link('/etc/bind').with(to: '/var/run/bind/etc/bind') - end + it 'does not run ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with(p['config_path']).and_return(true) + expect(chef_run).to_not run_ruby_block('move_config_to_chroot') + end - it 'does not create directory /var/run/bind/etc/bind/zones' do - expect(chef_run).to_not create_directory('/var/run/bind/etc/bind/zones').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) + it 'links bind config from chroot' do + expect(chef_run).to create_link(p['config_path']).with( + to: "/var/run/bind#{p['config_path']}" + ) + end + + case p['platform'] + when "ubuntu" + it "does not create directory /var/run/bind#{p['zone_path']}" do + expect(chef_run).to_not create_directory("/var/run/bind#{p['zone_path']}") end it 'does not link bind zones from chroot' do - expect(chef_run).to_not create_link('/etc/bind/zones').with(to: '/var/run/bind/etc/bind/zones') + expect(chef_run).to_not create_link("#{p['zone_path']}").with( + to: "/var/run/bind#{p['zone_path']}" + ) end - - it 'creates directory /var/run/bind/dev' do - expect(chef_run).to create_directory('/var/run/bind/dev').with( - user: 'bind', - group: 'bind', + else + it "does not create directory /var/run/bind#{p['zone_path']}" do + expect(chef_run).to create_directory("/var/run/bind#{p['zone_path']}").with( + user: p['user'], + group: p['user'], mode: 0744, recursive: true ) end - it 'creates special device files' do - expect(chef_run).to run_execute('create_special_device_files') + it 'does not link bind zones from chroot' do + expect(chef_run).to create_link("#{p['zone_path']}").with( + to: "/var/run/bind#{p['zone_path']}" + ) end + end - it 'does not create special device files' do - File.stub(:exists?).with(anything).and_call_original - File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) - expect(chef_run).to_not run_execute('create_special_device_files') - end + it 'creates directory /var/run/bind/dev' do + expect(chef_run).to create_directory('/var/run/bind/dev').with( + user: p['user'], + group: p['user'], + mode: 0744, + recursive: true + ) + end + + it 'creates special device files' do + expect(chef_run).to run_execute('create_special_device_files') + end + + it 'does not create special device files' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) + expect(chef_run).to_not run_execute('create_special_device_files') + end end end end + diff --git a/spec/unit/recipes_spec/server_spec.rb b/spec/unit/recipes_spec/server_spec.rb index 5afb9b2..b1dcb49 100644 --- a/spec/unit/recipes_spec/server_spec.rb +++ b/spec/unit/recipes_spec/server_spec.rb @@ -1,12 +1,11 @@ require 'spec_helper' -require 'unit/recipes_spec/chroot_spec.rb' -describe 'bind9-chroot::server' do - let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } +ChefSpec::Coverage.start! do + add_filter '*/bind9-chroot/recipes/chroot.rb' +end - context 'Ubuntu 12.04' do - let(:chef_run) { ChefSpec::Runner.new(UBUNTU_OPTS).converge(described_recipe) } - let(:zones) { +describe 'bind9-chroot::server' do + let(:zones) { [ { 'id' => 'exampleDOTcom', @@ -38,202 +37,206 @@ ] } - before(:each) do - stub_search("zones", "*:*").and_return(zones) - end - - it 'installs bind9' do - expect(chef_run).to install_package('bind9') - end + before(:each) do + stub_search("zones", "*:*").and_return(zones) + end - it 'enables bind9 service' do - expect(chef_run).to enable_service('bind9') - end + PLATFORMS.each do |p| + context "#{p['platform']} #{p['version']}" do + let(:chef_run) { ChefSpec::Runner.new(:platform=>p['platform'],:version=>p['version']).converge(described_recipe) } + + it "installs #{p['package']}" do + expect(chef_run).to install_package(p['package']) + end - it 'creates directory /var/cache/bind owned by bind user' do - expect(chef_run).to create_directory('/var/cache/bind').with( - user: 'bind', - group: 'bind', - mode: 0755, - recursive: true - ) - end + it "enables #{p['service']} service" do + expect(chef_run).to enable_service(p['service']) + end -# it 'creates directory /var/run/bind/var/cache/bind owned by bind user' do -# chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' -# chef_run.converge(described_recipe) -# expect(chef_run).to create_directory('/var/run/bind/var/cache/bind').with( -# user: 'bind', -# group: 'bind', -# mode: 0755, -# recursive: true -# ) -# end - - - it 'creates directory /var/log/bind owned by bind user' do - expect(chef_run).to create_directory('/var/log/bind').with( - user: 'bind', - group: 'bind', - mode: 0755, - recursive: true - ) - end + it "creates directory #{p['data_path']} owned by #{p['user']} user" do + expect(chef_run).to create_directory(p['data_path']).with( + user: p['user'], + group: p['user'], + mode: 0755, + recursive: true + ) + end -# it 'creates directory /var/run/bind/var/log/bind owned by bind user' do -# chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' -# chef_run.converge(described_recipe) -# expect(chef_run).to create_directory('/var/run/bind/var/log/bind').with( -# user: 'bind', -# group: 'bind', -# mode: 0755, -# recursive: true -# ) -# end - - it 'creates directory /etc/bind/zones owned by bind user' do - expect(chef_run).to create_directory('/etc/bind/zones').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end + it "creates directory #{p['log_dir']} owned by bind user" do + expect(chef_run).to create_directory(p['log_dir']).with( + user: p['user'], + group: p['user'], + mode: 0755, + recursive: true + ) + end -# it 'creates directory /var/run/bind/etc/bind/zones owned by bind user' do -# chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' -# chef_run.converge(described_recipe) -# expect(chef_run).to create_directory('/var/run/bind/etc/bind/zones').with( -# user: 'bind', -# group: 'bind', -# mode: 0744, -# recursive: true -# ) -# end - - context 'chroot_dir exists' do - include_context 'chroot recipe' - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + it "creates directory #{p['zone_path']} owned by bind user" do + expect(chef_run).to create_directory(p['zone_path']).with( + user: p['user'], + group: p['user'], + mode: 0744, + recursive: true + ) end + + context 'chroot_dir exists' do + let(:chef_run) do + ChefSpec::Runner.new(:platform=>p['platform'],:version=>p['version']) do |node| + node.set[:bind9][:chroot_dir] = '/var/run/bind' + end.converge(described_recipe) + end + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + end - it 'includes bind9-chroot::chroot recipe' do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('bind9-chroot::chroot') + it 'includes bind9-chroot::chroot recipe' do + expect(chef_run).to include_recipe('bind9-chroot::chroot') + end + + it "creates directory /var/run/bind#{p['data_path']} owned by #{p['user']}" do + expect(chef_run).to create_directory("/var/run/bind#{p['data_path']}").with( + user: p['user'], + group: p['user'], + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/run/bind#{p['log_dir']} owned by #{p['user']}" do + expect(chef_run).to create_directory("/var/run/bind#{p['log_dir']}").with( + user: p['user'], + group: p['user'], + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/run/bind#{p['zone_path']} owned by #{p['user']}" do + expect(chef_run).to create_directory("/var/run/bind#{p['zone_path']}").with( + user: p['user'], + group: p['user'], + mode: 0744, + recursive: true + ) + end + end - end - it 'does not include bind9-chroot::chroot recipe' do - expect(chef_run).to_not include_recipe('resolvconf') - end + it 'does not include bind9-chroot::chroot recipe' do + expect(chef_run).to_not include_recipe('resolvconf') + end -# it 'does not include resolvconf recipe' do -# expect(chef_run).to_not include_recipe('resolvconf') -# end - -# it 'includes resolvconf recipe' do -# chef_run.node.set[:bind9][:resolvconf] = true -# chef_run.converge(described_recipe) -# expect(chef_run).to include_recipe('resolvconf') -# end - -# it 'creates template /etc/bind/named.conf.options' do -# expect(chef_run).to create_template('/etc/bind/named.conf.options').with( -# user: 'bind', -# group: 'bind', -# mode: 0644, -# ) -# end - -# it 'creates template /etc/bind/named.conf' do -# expect(chef_run).to create_template('/etc/bind/named.conf').with( -# user: 'bind', -# group: 'bind', -# mode: 0644, -# ) -# end - -# it '/etc/bind/named.conf notifies bind9 to restart' do -# expect(chef_run.template('/etc/bind/named.conf')).to notify('service[bind9]').to(:restart) -# end - -# it 'creates /etc/bind/named.conf.local' do -# expect(chef_run).to create_template('/etc/bind/named.conf.local').with( -# user: 'bind', -# group: 'bind', -# mode: 0644, -# variables: { :zonefiles => zones } -# ) -# end - -# it '/etc/bind/named.conf.local notifies bind9 to restart' do -# expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) -# end - -# it 'creates /etc/default/bind9' do -# expect(chef_run).to create_template('/etc/default/bind9').with( -# user: 'bind', -# group: 'bind', -# mode: 0644, -# ) -# end - -# it '/etc/default/bind9 notifies bind9 to restart' do -# expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) -# end - -# it 'does not create /etc/bind/zones/example.com' do -# expect(chef_run).to_not create_template('/etc/bind/zones/example.com').with( -# source: '/etc/bind/zones/example.com.erb', -# local: true, -# user: 'bind', -# group: 'bind', -# mode: 0644, -# variables: { :serial => '00000' } -# ) -# end - - # it 'creates /etc/bind/zones/example.com.erb' do - # expect(chef_run).to create_template('/etc/bind/zones/example.com.erb').with( - # source: 'zonefile.erb', - # user: 'bind', - # group: 'bind', - # mode: 0644, - # variables: { - # :domain => 'example.com', - # :soa => 'ns.example.com', - # :contact => 'root.example.com', - # :global_ttl => 300, - # :nameserver => [ - # 'ns1.example.com', - # 'ns2.example.com' - # ], - # :mail_exchange => [ - # { - # 'host' => 'ASPMX.L.GOOGLE.COM.', - # 'priority' => 10 - # } - # ], - # :records => [ - # { - # 'name' => 'www', - # 'type' => 'A', - # 'ip' => '127.0.0.1' - # } - # ] - # } - # ) - # end - - # it 'notifies /etc/bind/zones/example.com immediately' do - # expect(chef_run.template('/etc/bind/zones/example.com.erb')).to notify('template[/etc/bind/zones/example.com]').to(:create).immediately -# end - -# it 'starts bind9 service' do -# expect(chef_run).to start_service('bind9') -# end + it 'does not include resolvconf recipe' do + expect(chef_run).to_not include_recipe('resolvconf') + end + it 'includes resolvconf recipe' do + chef_run.node.set[:bind9][:resolvconf] = true + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('resolvconf') + end + + it "creates template #{p['config_path']}/#{p['options_file']}" do + expect(chef_run).to create_template("#{p['config_path']}/#{p['options_file']}").with( + user: p['user'], + group: p['user'], + mode: 0644, + ) + end + + it "creates template #{p['config_path']}/#{p['config_file']}" do + expect(chef_run).to create_template("#{p['config_path']}/#{p['config_file']}").with( + user: p['user'], + group: p['user'], + mode: 0644, + ) + end + + it "#{p['config_path']}/#{p['config_file']} notifies bind9 to restart" do + expect(chef_run.template("#{p['config_path']}/#{p['config_file']}")).to notify('service[bind9]').to(:restart) + end + + it "creates #{p['config_path']}/#{p['local_file']}" do + expect(chef_run).to create_template("#{p['config_path']}/#{p['local_file']}").with( + user: p['user'], + group: p['user'], + mode: 0644, + variables: { :zonefiles => zones } + ) + end + + it "#{p['config_path']}/#{p['local_file']} notifies bind9 to restart" do + expect(chef_run.template("#{p['config_path']}/#{p['local_file']}")).to notify('service[bind9]').to(:restart) + end + + case p['platform'] + when 'ubuntu' + it 'creates /etc/default/bind9' do + expect(chef_run).to create_template('/etc/default/bind9').with( + user: 'bind', + group: 'bind', + mode: 0644, + ) + end + + it '/etc/default/bind9 notifies bind9 to restart' do + expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) + end + end + + it "does not create #{p['zone_path']}/example.com" do + expect(chef_run).to_not create_template("#{p['zone_path']}/example.com").with( + source: '/etc/bind/zones/example.com.erb', + local: true, + user: p['user'], + group: p['user'], + mode: 0644, + variables: { :serial => '00000' } + ) + end + + it "creates #{p['zone_path']}/example.com.erb" do + expect(chef_run).to create_template("#{p['zone_path']}/example.com.erb").with( + source: 'zonefile.erb', + user: p['user'], + group: p['user'], + mode: 0644, + variables: { + :domain => 'example.com', + :soa => 'ns.example.com', + :contact => 'root.example.com', + :global_ttl => 300, + :nameserver => [ + 'ns1.example.com', + 'ns2.example.com' + ], + :mail_exchange => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM.', + 'priority' => 10 + } + ], + :records => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + ) + end + + it "notifies #{p['zone_path']}/example.com immediately" do + expect(chef_run.template("#{p['zone_path']}/example.com.erb")).to notify("template[#{p['zone_path']}/example.com]").to(:create).immediately + end + + it "starts #{p['service']} service" do + expect(chef_run).to start_service('bind9') + end + + end end end diff --git a/tmp/rspec_guard_result b/tmp/rspec_guard_result index 20225d8..d7c32b9 100644 --- a/tmp/rspec_guard_result +++ b/tmp/rspec_guard_result @@ -1 +1,21 @@ -./spec/unit/recipes_spec/chroot_spec.rb:68 +./spec/unit/recipes_spec/server_spec.rb:48 +./spec/unit/recipes_spec/server_spec.rb:52 +./spec/unit/recipes_spec/server_spec.rb:56 +./spec/unit/recipes_spec/server_spec.rb:65 +./spec/unit/recipes_spec/server_spec.rb:74 +./spec/unit/recipes_spec/server_spec.rb:127 +./spec/unit/recipes_spec/server_spec.rb:131 +./spec/unit/recipes_spec/server_spec.rb:135 +./spec/unit/recipes_spec/server_spec.rb:141 +./spec/unit/recipes_spec/server_spec.rb:149 +./spec/unit/recipes_spec/server_spec.rb:157 +./spec/unit/recipes_spec/server_spec.rb:161 +./spec/unit/recipes_spec/server_spec.rb:170 +./spec/unit/recipes_spec/server_spec.rb:189 +./spec/unit/recipes_spec/server_spec.rb:200 +./spec/unit/recipes_spec/server_spec.rb:232 +./spec/unit/recipes_spec/server_spec.rb:236 +./spec/unit/recipes_spec/server_spec.rb:94 +./spec/unit/recipes_spec/server_spec.rb:98 +./spec/unit/recipes_spec/server_spec.rb:107 +./spec/unit/recipes_spec/server_spec.rb:116 From 898e9d24cf404409c6043d25df3663839c5e943b Mon Sep 17 00:00:00 2001 From: Brad Wadsworth Date: Mon, 21 Apr 2014 17:18:38 -0500 Subject: [PATCH 05/15] added Strainerfile --- .kitchen.yml | 3 ++- Gemfile | 5 ++-- Strainerfile | 5 ++++ .../data_bags/zones/exampleDOTcom.json | 25 +++++++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 Strainerfile create mode 100644 test/integration/default/data_bags/zones/exampleDOTcom.json diff --git a/.kitchen.yml b/.kitchen.yml index cbab9da..034cc76 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -3,7 +3,7 @@ driver: name: vagrant provisioner: - name: chef_solo + name: chef_zero platforms: - name: ubuntu-12.04 @@ -11,6 +11,7 @@ platforms: suites: - name: default + data_bags_path: "test/integration/default/data_bags" run_list: - recipe[bind9-chroot::default] attributes: diff --git a/Gemfile b/Gemfile index 5e19db0..08b465f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,11 @@ source 'https://rubygems.org' -gem 'berkshelf' +gem 'berkshelf', '~>3.0' gem 'test-kitchen' gem 'kitchen-vagrant' gem 'foodcritic' gem 'chefspec' -gem 'strainer' +gem 'strainer', '~>3.3' gem 'guard' gem 'guard-foodcritic' gem 'guard-rspec' -gem 'fakefs' diff --git a/Strainerfile b/Strainerfile new file mode 100644 index 0000000..61d536d --- /dev/null +++ b/Strainerfile @@ -0,0 +1,5 @@ +# Strainerfile +knife test: bundle exec knife cookbook test $COOKBOOK +foodcritic: bundle exec foodcritic -f any $SANDBOX/$COOKBOOK +chefspec: bundle exec rspec --color +kitchen: bundle exec kitchen test -d always diff --git a/test/integration/default/data_bags/zones/exampleDOTcom.json b/test/integration/default/data_bags/zones/exampleDOTcom.json new file mode 100644 index 0000000..6fcaeb9 --- /dev/null +++ b/test/integration/default/data_bags/zones/exampleDOTcom.json @@ -0,0 +1,25 @@ +{ + "id": "exampleDOTcom", + "domain": "example.com", + "type": "master", + "allow_transfer": [], + "zone_info": { + "global_ttl": 300, + "soa": "ns.example.com.", + "contact": "user.example.com.", + "nameserver": [ "ns.example.com.", + "ns.example.net." ], + "mail_exchange": [], + "records": [{ + "name": "www", + "type": "A" + },{ + "name": "img", + "ttl": 30, + "type": "A" + },{ + "name": "mail", + "type": "CNAME" + }] + } + } From 31b723cdbc464d016f561ffd64abe6302e4c2745 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Tue, 22 Apr 2014 11:18:09 -0500 Subject: [PATCH 06/15] edited Gemfile, Bersfile, and chefspec code cleanup --- Berksfile | 4 +- Gemfile | 4 +- spec/spec_helper.rb | 2 - spec/unit/recipes_spec/chroot_spec.rb | 178 +++++++++++++------------- 4 files changed, 93 insertions(+), 95 deletions(-) diff --git a/Berksfile b/Berksfile index 0e89e8b..935460d 100644 --- a/Berksfile +++ b/Berksfile @@ -1,4 +1,4 @@ -#site :opscode -source "http://api.berkshelf.com" +site :opscode +#source "http://api.berkshelf.com" metadata diff --git a/Gemfile b/Gemfile index 08b465f..3b674d7 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,11 @@ source 'https://rubygems.org' -gem 'berkshelf', '~>3.0' +gem 'berkshelf' gem 'test-kitchen' gem 'kitchen-vagrant' gem 'foodcritic' gem 'chefspec' -gem 'strainer', '~>3.3' +gem 'strainer' gem 'guard' gem 'guard-foodcritic' gem 'guard-rspec' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 536a730..45590a2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -44,5 +44,3 @@ c.syntax = :expect end end - -#at_exit { ChefSpec::Coverage.report! } diff --git a/spec/unit/recipes_spec/chroot_spec.rb b/spec/unit/recipes_spec/chroot_spec.rb index 32b20cd..fe3b238 100644 --- a/spec/unit/recipes_spec/chroot_spec.rb +++ b/spec/unit/recipes_spec/chroot_spec.rb @@ -18,84 +18,100 @@ File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) end - case p['platform'] - when 'ubuntu' - it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do - expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + case p['platform'] + when 'ubuntu' + it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do + File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'runs ruby_block copy_openssl_dependencies' do + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + expect(chef_run).to run_ruby_block('copy_openssl_dependencies') + end end - - it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do - File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) - expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') - end - - it 'runs ruby_block copy_openssl_dependencies' do - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) - expect(chef_run).to run_ruby_block('copy_openssl_dependencies') - end - end - it 'creates directory /var/run/bind/var/run/named' do - expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end + it 'creates directory /var/run/bind/var/run/named' do + expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( + user: p['user'], + group: p['user'], + mode: 0744, + recursive: true + ) + end - it 'runs ruby_block modify_init_script' do - expect(chef_run).to run_ruby_block('modify_init_script') - end - - it 'does not run ruby_block modify_init_script' do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) - expect(chef_run).to_not run_ruby_block('modify_init_script') - end - - it "creates directory /var/run/bind#{p['config_path']}" do - expect(chef_run).to create_directory("/var/run/bind#{p['config_path']}").with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end + it 'runs ruby_block modify_init_script' do + expect(chef_run).to run_ruby_block('modify_init_script') + end - it 'runs ruby_block move_config_to_chroot' do - File.stub(:symlink?).with(anything).and_call_original - File.stub(:symlink?).with(p['config_path']).and_return(false) - expect(chef_run).to run_ruby_block('move_config_to_chroot') - end + it 'does not run ruby_block modify_init_script' do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) + expect(chef_run).to_not run_ruby_block('modify_init_script') + end - it 'does not run ruby_block move_config_to_chroot' do - File.stub(:symlink?).with(anything).and_call_original - File.stub(:symlink?).with(p['config_path']).and_return(true) - expect(chef_run).to_not run_ruby_block('move_config_to_chroot') - end + it "creates directory /var/run/bind#{p['config_path']}" do + expect(chef_run).to create_directory("/var/run/bind#{p['config_path']}").with( + user: p['user'], + group: p['user'], + mode: 0744, + recursive: true + ) + end - it 'links bind config from chroot' do - expect(chef_run).to create_link(p['config_path']).with( - to: "/var/run/bind#{p['config_path']}" - ) - end + it 'runs ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with(p['config_path']).and_return(false) + expect(chef_run).to run_ruby_block('move_config_to_chroot') + end - case p['platform'] - when "ubuntu" - it "does not create directory /var/run/bind#{p['zone_path']}" do - expect(chef_run).to_not create_directory("/var/run/bind#{p['zone_path']}") + it 'does not run ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with(p['config_path']).and_return(true) + expect(chef_run).to_not run_ruby_block('move_config_to_chroot') end - it 'does not link bind zones from chroot' do - expect(chef_run).to_not create_link("#{p['zone_path']}").with( - to: "/var/run/bind#{p['zone_path']}" + it 'links bind config from chroot' do + expect(chef_run).to create_link(p['config_path']).with( + to: "/var/run/bind#{p['config_path']}" ) end - else - it "does not create directory /var/run/bind#{p['zone_path']}" do - expect(chef_run).to create_directory("/var/run/bind#{p['zone_path']}").with( + + case p['platform'] + when "ubuntu" + it "does not create directory /var/run/bind#{p['zone_path']}" do + expect(chef_run).to_not create_directory("/var/run/bind#{p['zone_path']}") + end + + it 'does not link bind zones from chroot' do + expect(chef_run).to_not create_link("#{p['zone_path']}").with( + to: "/var/run/bind#{p['zone_path']}" + ) + end + else + it "does not create directory /var/run/bind#{p['zone_path']}" do + expect(chef_run).to create_directory("/var/run/bind#{p['zone_path']}").with( + user: p['user'], + group: p['user'], + mode: 0744, + recursive: true + ) + end + + it 'does not link bind zones from chroot' do + expect(chef_run).to create_link("#{p['zone_path']}").with( + to: "/var/run/bind#{p['zone_path']}" + ) + end + end + + it 'creates directory /var/run/bind/dev' do + expect(chef_run).to create_directory('/var/run/bind/dev').with( user: p['user'], group: p['user'], mode: 0744, @@ -103,31 +119,15 @@ ) end - it 'does not link bind zones from chroot' do - expect(chef_run).to create_link("#{p['zone_path']}").with( - to: "/var/run/bind#{p['zone_path']}" - ) + it 'creates special device files' do + expect(chef_run).to run_execute('create_special_device_files') end - end - - it 'creates directory /var/run/bind/dev' do - expect(chef_run).to create_directory('/var/run/bind/dev').with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end - it 'creates special device files' do - expect(chef_run).to run_execute('create_special_device_files') - end - - it 'does not create special device files' do - File.stub(:exists?).with(anything).and_call_original - File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) - expect(chef_run).to_not run_execute('create_special_device_files') - end + it 'does not create special device files' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) + expect(chef_run).to_not run_execute('create_special_device_files') + end end end From 4eead988776b8dc1d522d2e2271fc11cfaa44705 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Tue, 22 Apr 2014 12:03:54 -0500 Subject: [PATCH 07/15] edited .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 45b891c..351201e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ Gemfile.lock bin/* .bundle/* +.kitchen/ +.kitchen.local.yml From 226e8755935c9060610092e9d6ec77e884756afb Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Tue, 22 Apr 2014 12:22:00 -0500 Subject: [PATCH 08/15] fixed foodcritic errors --- metadata.rb | 2 +- recipes/server.rb | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/metadata.rb b/metadata.rb index e640113..74e5a2d 100644 --- a/metadata.rb +++ b/metadata.rb @@ -11,5 +11,5 @@ end %w{resolvconf}.each do |cookbook| - depends(cookbook) + depends cookbook end diff --git a/recipes/server.rb b/recipes/server.rb index 7257b7a..56ec400 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -93,9 +93,13 @@ class Chef::Recipe::NameServer owner node[:bind9][:user] group node[:bind9][:user] mode 0644 - variables({ - :zonefiles => search(:zones) - }) + if Chef::Config[:solo] + variables() + else + variables({ + :zonefiles => search(:zones) + }) + end notifies :restart, "service[bind9]" end @@ -149,7 +153,6 @@ class Chef::Recipe::NameServer group node[:bind9][:user] mode 0644 variables({ - :domain => zone['domain'], :soa => zone['zone_info']['soa'], :contact => zone['zone_info']['contact'], :global_ttl => zone['zone_info']['global_ttl'], @@ -157,7 +160,7 @@ class Chef::Recipe::NameServer :mail_exchange => zone['zone_info']['mail_exchange'], :records => zone['zone_info']['records'] }) - notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately + notifies :create, "template[File.join(node[:bind9][:zones_path], zone['domain'])]", :immediately end end From 31be60728637c66810fb8bd8be669dd4ad7d1ee1 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Wed, 23 Apr 2014 08:31:38 -0500 Subject: [PATCH 09/15] Readme file now references node attributes instead of data bags --- README.md | 195 +++++++++++++++++++++++++++++------------------------- 1 file changed, 105 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 3737cd9..6a231e2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ #Description -This cookbook takes care of the installation and configuration of BIND9. You're able to define some global variables and manage your zonefiles via data bags (json example below). +This cookbook takes care of the installation and configuration of BIND9. You're able to define some global variables and manage your zonefiles via node attributes (example below). This allows zone creation to be controlled by a wrapper cookbook using any mechanism to fill the attributes such as data bags, searches, or other attributes. It also supports automatic serial number generation and automatic resource records for chef nodes (see optional json in example below) No DNSSEC, no configurable logging, no rndc shell operations or other safety checks (named-checkconf, etc.). @@ -34,106 +34,121 @@ It's so much better if you take a look at the ```attributes/default.rb``` file f #Usage -Add ```"recipe[bind9-chroot]"``` to your run list. If you want to use BIND9 for serving domains you need add the appropriate data via data bags (example below). -Please note that the data bag's structure is mandatory except: +Add ```"recipe[bind9-chroot]"``` to your run list. If you want to use BIND9 for serving domains you need to fill in the appropriate node attributes (example below). +Please note that the node attribute structure is mandatory except: * TTL for DNS records (if you decide to leave it empty, the global TTL will take over). * IP for DNS records (if not available, ```node['ipaddress']``` will be used). In order to run a a chroot'ed Bind9 server, set the ```node[:bind9][:chroot_dir]``` to the desired chroot path and optionally the ```node[:bind9][:disclose]``` attributes. -To use this cookbook with Chef Solo, add ```"recipe[chef-solo-search]"``` to your run list, and create the data bags either manually or using the ```knife-solo_data_bag``` gem. - #Examples -To create and view the data bags: - - $ knife data bag create zones - $ knife data bag create zones exampleDOTcom - $ ... do something ... - $ knife data bag from file zones exampleDOTcom.json - -An example of a data bag with mail records and specific IPs. - - { - "id": "exampleDOTcom", - "domain": "example.com", - "type": "master", - "allow_transfer": [ "8.8.4.4", - "8.8.8.8" ], - "zone_info": { - "global_ttl": 300, - "soa": "ns.example.com.", - "contact": "user.example.com.", - "nameserver": [ "ns.example.com.", - "ns.example.net." ], - "mail_exchange": [{ - "host": "ASPMX.L.GOOGLE.COM.", - "priority": 10 - },{ - "host": "ALT1.ASPMX.L.GOOGLE.COM.", - "priority": 20 - },{ - "host": "ALT2.ASPMX.L.GOOGLE.COM.", - "priority": 20 - },{ - "host": "ASPMX2.GOOGLEMAIL.COM.", - "priority": 30 - },{ - "host": "ASPMX3.GOOGLEMAIL.COM.", - "priority": 30 - },{ - "host": "ASPMX4.GOOGLEMAIL.COM.", - "priority": 30 - },{ - "host": "ASPMX5.GOOGLEMAIL.COM.", - "priority": 30 - }], - "records": [{ - "name": "www", - "type": "A", - "ip": "127.0.0.1" - },{ - "name": "img", - "ttl": 30, - "type": "A", - "ip": "127.0.0.1" - },{ - "name": "mail", - "type": "CNAME", - "ip": "ghs.google.com." - }] - } +An example of node attributes with mail records and specific IPs. + + node[:bind9][:zones] = [ + { + "domain" => "example.com", + "type" => "master", + "allow_transfer" => [ + "8.8.4.4", + "8.8.8.8" + ], + "zone_info" => { + "global_ttl" => 300, + "soa" => "ns.example.com.", + "contact" => "user.example.com.", + "nameserver" => [ + "ns.example.com.", + "ns.example.net." + ], + "mail_exchange" => [ + { + "host" => "ASPMX.L.GOOGLE.COM.", + "priority" => 10 + }, + { + "host" => "ALT1.ASPMX.L.GOOGLE.COM.", + "priority" => 20 + }, + { + "host" => "ALT2.ASPMX.L.GOOGLE.COM.", + "priority" => 20 + }, + { + "host" => "ASPMX2.GOOGLEMAIL.COM.", + "priority" => 30 + }, + { + "host" => "ASPMX3.GOOGLEMAIL.COM.", + "priority" => 30 + }, + { + "host" => "ASPMX4.GOOGLEMAIL.COM.", + "priority" => 30 + }, + { + "host" => "ASPMX5.GOOGLEMAIL.COM.", + "priority" => 30 + } + ], + "records" => [ + { + "name" => "www", + "type" => "A", + "ip" => "127.0.0.1" + }, + { + "name" => "img", + "ttl" => 30, + "type" => "A", + "ip" => "127.0.0.1" + }, + { + "name" => "mail", + "type" => "CNAME", + "ip" => "ghs.google.com." + } + ] + } + ] } -An example of a data bag with mail records and specific IPs. - - { - "id": "exampleDOTcom", - "domain": "example.com", - "type": "master", - "allow_transfer": [], - "zone_info": { - "global_ttl": 300, - "soa": "ns.example.com.", - "contact": "user.example.com.", - "nameserver": [ "ns.example.com.", - "ns.example.net." ], - "mail_exchange": [], - "records": [{ - "name": "www", - "type": "A" - },{ - "name": "img", - "ttl": 30, - "type": "A" - },{ - "name": "mail", - "type": "CNAME" - }] +An example of node attributes with mail records and specific IPs. + + node[:bind9][:zones] = [ + { + "domain" => "example.com", + "type" => "master", + "allow_transfer" => [], + "zone_info" => { + "global_ttl": 300, + "soa": "ns.example.com.", + "contact": "user.example.com.", + "nameserver": [ + "ns.example.com.", + "ns.example.net." + ], + "mail_exchange": [], + "records": [ + { + "name": "www", + "type": "A" + }, + { + "name": "img", + "ttl": 30, + "type": "A" + }, + { + "name": "mail", + "type": "CNAME" + } + ] + } } - } + ] #Contributions -This cookbook is derived from [Mike Adolphs's](https://github.com/fooforge/chef-cookbook_bind9), and specific contributions can be tracked via git. \ No newline at end of file +This cookbook is derived from [Mike Adolphs's](https://github.com/fooforge/chef-cookbook_bind9), and specific contributions can be tracked via git. From 5fc2961efc4c912b0fd6bd4b06a63b710621e9c4 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Wed, 23 Apr 2014 14:07:34 -0500 Subject: [PATCH 10/15] refactored code to use attributes instead of data bags. refactored tests into different platforms --- attributes/default.rb | 1 + recipes/chroot.rb | 21 +- recipes/server.rb | 90 +++---- spec/spec_helper.rb | 4 +- .../recipes_spec/centos/6.5/chroot_spec.rb | 87 +++++++ .../recipes_spec/centos/6.5/server_spec.rb | 228 +++++++++++++++++ spec/unit/recipes_spec/chroot_spec.rb | 135 ---------- spec/unit/recipes_spec/server_spec.rb | 242 ------------------ .../recipes_spec/ubuntu/12.04/chroot_spec.rb | 111 ++++++++ .../recipes_spec/ubuntu/12.04/server_spec.rb | 231 +++++++++++++++++ tmp/rspec_guard_result | 22 +- 11 files changed, 696 insertions(+), 476 deletions(-) create mode 100644 spec/unit/recipes_spec/centos/6.5/chroot_spec.rb create mode 100644 spec/unit/recipes_spec/centos/6.5/server_spec.rb delete mode 100644 spec/unit/recipes_spec/chroot_spec.rb delete mode 100644 spec/unit/recipes_spec/server_spec.rb create mode 100644 spec/unit/recipes_spec/ubuntu/12.04/chroot_spec.rb create mode 100644 spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb diff --git a/attributes/default.rb b/attributes/default.rb index 0fee4c3..bc67f56 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -1,3 +1,4 @@ +default[:bind9][:zones] = [] default[:bind9][:enable_ipv6] = true # Allow all clients to query the nameserver, no recursion diff --git a/recipes/chroot.rb b/recipes/chroot.rb index 835fe0c..e652126 100644 --- a/recipes/chroot.rb +++ b/recipes/chroot.rb @@ -30,12 +30,12 @@ end end -directory File.join(node[:bind9][:chroot_dir].to_s, "/var/run/named") do +directory "#{node[:bind9][:chroot_dir].to_s}/var/run/named" do owner node[:bind9][:user] group node[:bind9][:user] mode 0744 recursive true - not_if { ::File.directory?(File.join(node[:bind9][:chroot_dir].to_s, "/var/run/named")) } + not_if { ::File.directory?("#{node[:bind9][:chroot_dir].to_s}/var/run/named") } end @@ -65,13 +65,6 @@ not_if { ::File.symlink?(node[:bind9][:config_path]) } end -directory chroot_config_dir do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true -end - link "bind_config_from_chroot" do target_file node[:bind9][:config_path] to chroot_config_dir @@ -80,21 +73,13 @@ chroot_zones_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) -directory chroot_zones_dir do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true - not_if { chroot_zones_dir.start_with?(chroot_config_dir) } -end - link "bind_zones_from_chroot" do target_file node[:bind9][:zones_path] to chroot_zones_dir not_if { ::File.symlink?(node[:bind9][:zones_path]) or chroot_zones_dir.start_with?(chroot_config_dir) } end -directory File.join(node[:bind9][:chroot_dir].to_s, "/dev") do +directory "#{node[:bind9][:chroot_dir].to_s}/dev" do owner node[:bind9][:user] group node[:bind9][:user] mode 0744 diff --git a/recipes/server.rb b/recipes/server.rb index 56ec400..8fd6947 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -34,21 +34,22 @@ action [ :enable ] end -directory File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:data_path]) do +directory "#{node[:bind9][:chroot_dir].to_s}#{node[:bind9][:data_path]}" do owner node[:bind9][:user] group node[:bind9][:user] mode 0755 recursive true end -directory File.dirname(File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:log_file])) do +log_dir = File.dirname(node[:bind9][:log_file]) +directory "#{node[:bind9][:chroot_dir].to_s}#{log_dir}" do owner node[:bind9][:user] group node[:bind9][:user] mode 0755 recursive true end -directory File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) do +directory "#{node[:bind9][:chroot_dir].to_s}#{node[:bind9][:zones_path]}" do owner node[:bind9][:user] group node[:bind9][:user] mode 0744 @@ -71,8 +72,7 @@ class Chef::Recipe::NameServer # end end - -template File.join(node[:bind9][:config_path], node[:bind9][:options_file]) do +template "#{node[:bind9][:config_path]}/#{node[:bind9][:options_file]}" do source "named.conf.options.erb" owner node[:bind9][:user] group node[:bind9][:user] @@ -80,7 +80,7 @@ class Chef::Recipe::NameServer notifies :restart, "service[bind9]" end -template File.join(node[:bind9][:config_path], node[:bind9][:config_file]) do +template "#{node[:bind9][:config_path]}/#{node[:bind9][:config_file]}" do source "named.conf.erb" owner node[:bind9][:user] group node[:bind9][:user] @@ -88,82 +88,56 @@ class Chef::Recipe::NameServer notifies :restart, "service[bind9]" end -template File.join(node[:bind9][:config_path], node[:bind9][:local_file]) do +template "#{node[:bind9][:config_path]}/#{node[:bind9][:local_file]}" do source "named.conf.local.erb" owner node[:bind9][:user] group node[:bind9][:user] mode 0644 - if Chef::Config[:solo] - variables() - else - variables({ - :zonefiles => search(:zones) - }) - end + variables( + :zonefiles => node[:bind9][:zones] + ) notifies :restart, "service[bind9]" end - -template node[:bind9][:defaults_file] do - source "bind9.erb" - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - notifies :restart, "service[bind9]" - not_if { node[:bind9][:defaults_file].nil? } -end - - -directory node[:bind9][:zones_path] do - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0744 - recursive true - not_if { ::File.directory?(node[:bind9][:zones_path]) or ::File.symlink?(node[:bind9][:zones_path]) } -end - -search(:zones).each do |zone| - unless zone['autodomain'].nil? || zone['autodomain'] == '' - search(:node, "domain:#{zone['autodomain']}").each do |host| - next if host['ipaddress'] == '' || host['ipaddress'].nil? - zone['zone_info']['records'].push( { - "name" => host['hostname'], - "type" => "A", - "ip" => host['ipaddress'] - }) - end +case node[:platform] +when 'ubuntu' + template node[:bind9][:defaults_file] do + source "bind9.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + notifies :restart, "service[bind9]" + not_if { node[:bind9][:defaults_file].nil? } end +end - template File.join(node[:bind9][:zones_path], zone['domain']) do - source File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") +node[:bind9][:zones].each do |z| + template "#{node[:bind9][:zones_path]}/#{z[:domain]}" do + source "#{node[:bind9][:zones_path]}/#{z[:domain]}.erb" local true owner node[:bind9][:user] group node[:bind9][:user] mode 0644 notifies :restart, "service[bind9]" variables({ - :serial => zone['zone_info']['serial'] || Time.new.strftime("%Y%m%d%H%M%S") + :serial => z[:zone_info][:serial] || Time.new.strftime("%Y%m%d%H%M%S") }) action :nothing end - template File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") do + template "#{node[:bind9][:zones_path]}/#{z[:domain]}.erb" do source "zonefile.erb" owner node[:bind9][:user] group node[:bind9][:user] mode 0644 variables({ - :soa => zone['zone_info']['soa'], - :contact => zone['zone_info']['contact'], - :global_ttl => zone['zone_info']['global_ttl'], - :nameserver => zone['zone_info']['nameserver'], - :mail_exchange => zone['zone_info']['mail_exchange'], - :records => zone['zone_info']['records'] + :soa => z[:zone_info][:soa], + :contact => z[:zone_info][:contact], + :global_ttl => z[:zone_info][:global_ttl], + :nameserver => z[:zone_info][:nameserver], + :mail_exchange => z[:zone_info][:mail_exchange], + :records => z[:zone_info][:records] }) - notifies :create, "template[File.join(node[:bind9][:zones_path], zone['domain'])]", :immediately + notifies :create, "template[#{node[:bind9][:zones_path]}/#{z[:domain]}]", :immediately end end - -service "bind9" do - action [ :start ] -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 45590a2..ce9fabc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -11,7 +11,7 @@ 'user' => 'bind', 'data_path' => '/var/cache/bind', 'log_dir' => '/var/log/bind', - 'zone_path' => '/etc/bind/zones', + 'zones_path' => '/etc/bind/zones', 'config_path' => '/etc/bind', 'options_file' => 'named.conf.options', 'config_file' => 'named.conf', @@ -25,7 +25,7 @@ 'user' => 'named', 'data_path' => '/var/named', 'log_dir' => '/var/log/named', - 'zone_path' => '/var/named/zones', + 'zones_path' => '/var/named/zones', 'config_path' => '/etc/named', 'options_file' => 'named.conf.options', 'config_file' => 'named.conf', diff --git a/spec/unit/recipes_spec/centos/6.5/chroot_spec.rb b/spec/unit/recipes_spec/centos/6.5/chroot_spec.rb new file mode 100644 index 0000000..0a3e331 --- /dev/null +++ b/spec/unit/recipes_spec/centos/6.5/chroot_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' + +ChefSpec::Coverage.start! + +describe 'bind9-chroot::chroot' do + context 'Centos 6.5' do + let(:chef_run) do + ChefSpec::Runner.new(:platform=>'centos',:version=>'6.5') do |node| + node.set[:bind9][:chroot_dir] = '/var/run/bind' + end.converge(described_recipe) + end + + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) + end + + it 'creates directory /var/run/bind/var/run/named' do + expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( + user: 'named', + group: 'named', + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block modify_init_script' do + expect(chef_run).to run_ruby_block('modify_init_script') + end + + it 'does not run ruby_block modify_init_script' do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) + expect(chef_run).to_not run_ruby_block('modify_init_script') + end + + it "creates directory /var/run/bind/etc/named" do + expect(chef_run).to create_directory("/var/run/bind/etc/named").with( + user: 'named', + group: 'named', + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with('/etc/named').and_return(false) + expect(chef_run).to run_ruby_block('move_config_to_chroot') + end + + it 'does not run ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with('/etc/named').and_return(true) + expect(chef_run).to_not run_ruby_block('move_config_to_chroot') + end + + it 'links bind config from chroot' do + expect(chef_run).to create_link('/etc/named').with( + to: "/var/run/bind/etc/named" + ) + end + + it 'creates directory /var/run/bind/dev' do + expect(chef_run).to create_directory('/var/run/bind/dev').with( + user: 'named', + group: 'named', + mode: 0744, + recursive: true + ) + end + + it 'creates special device files' do + expect(chef_run).to run_execute('create_special_device_files') + end + + it 'does not create special device files' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) + expect(chef_run).to_not run_execute('create_special_device_files') + end + + end +end + diff --git a/spec/unit/recipes_spec/centos/6.5/server_spec.rb b/spec/unit/recipes_spec/centos/6.5/server_spec.rb new file mode 100644 index 0000000..e480513 --- /dev/null +++ b/spec/unit/recipes_spec/centos/6.5/server_spec.rb @@ -0,0 +1,228 @@ +require 'spec_helper' + +ChefSpec::Coverage.start! do + add_filter '*/bind9-chroot/recipes/chroot.rb' +end + +describe 'bind9-chroot::server' do + context 'Centos 6.5' do + let(:chef_run) do + ChefSpec::Runner.new(:platform=>'centos',:version=>'6.5') do |node| + node.set[:bind9][:zones] = zones + end.converge(described_recipe) + end + let(:zones) { + [ + { + 'domain' => 'example.com', + 'zone_info' => { + 'serial' =>'00000', + 'soa' => 'ns.example.com', + 'contact' => 'root.example.com', + 'global_ttl' => 300, + 'nameserver' => [ + 'ns1.example.com', + 'ns2.example.com' + ], + 'mail_exchange' => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM.', + 'priority' => 10, + } + ], + 'records' => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + } + ] + } + + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + end + + it "installs bind" do + expect(chef_run).to install_package('bind') + end + + it "enables named service" do + expect(chef_run).to enable_service('named') + end + + it "creates directory /var/named owned by named user" do + expect(chef_run).to create_directory('/var/named').with( + user: 'named', + group: 'named', + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/run/bind/var/named owned by named user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/var/named').with( + user: 'named', + group: 'named', + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/log/named owned by named user" do + expect(chef_run).to create_directory('/var/log/named').with( + user: 'named', + group: 'named', + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/run/bind/var/log/named owned by named user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/var/log/named').with( + user: 'named', + group: 'named', + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/named/zones owned by named user" do + expect(chef_run).to create_directory('/var/named/zones').with( + user: 'named', + group: 'named', + mode: 0744, + recursive: true + ) + end + + it "creates directory /var/run/bind/var/named/zones owned by named user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/var/named/zones').with( + user: 'named', + group: 'named', + mode: 0744, + recursive: true + ) + end + + it 'does not include bind9-chroot::chroot recipe' do + expect(chef_run).to_not include_recipe('bind9-chroot::chroot') + end + + it 'includes bind9-chroot::chroot recipe' do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('bind9-chroot::chroot') + end + + + it 'does not include resolvconf recipe' do + expect(chef_run).to_not include_recipe('resolvconf') + end + + it 'includes resolvconf recipe' do + chef_run.node.set[:bind9][:resolvconf] = true + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('resolvconf') + end + + it "creates template /etc/named/named.conf.options" do + expect(chef_run).to create_template('/etc/named/named.conf.options').with( + user: 'named', + group: 'named', + mode: 0644, + ) + end + + it "creates template /etc/named/named.conf" do + expect(chef_run).to create_template('/etc/named/named.conf').with( + user: 'named', + group: 'named', + mode: 0644, + ) + end + + it "/etc/named/named.conf notifies bind to restart" do + expect(chef_run.template('/etc/named/named.conf')).to notify('service[named]').to(:restart) + end + + it "creates /etc/named/named.conf.local" do + expect(chef_run).to create_template('/etc/named/named.conf.local').with( + user: 'named', + group: 'named', + mode: 0644, + variables: { :zonefiles => zones } + ) + end + + it "/etc/named/named.conf.local notifies bind to restart" do + expect(chef_run.template('/etc/named/named.conf.local')).to notify('service[named]').to(:restart) + end + + it "creates directory /var/named/zones owned by named user" do + expect(chef_run).to create_directory('/var/named/zones').with( + user: 'named', + group: 'named', + mode: 0744, + recursive: true + ) + end + + it "does not create /var/named/zones/example.com" do + expect(chef_run).to_not create_template('/var/named/zones/example.com').with( + source: '/var/named/zones/example.com.erb', + local: true, + user: 'named', + group: 'named', + mode: 0644, + variables: { :serial => '00000' } + ) + end + + it "creates /var/named/zones/example.com.erb" do + expect(chef_run).to create_template('/var/named/zones/example.com.erb').with( + source: 'zonefile.erb', + user: 'named', + group: 'named', + mode: 0644, + variables: { + :soa => 'ns.example.com', + :contact => 'root.example.com', + :global_ttl => 300, + :nameserver => [ + 'ns1.example.com', + 'ns2.example.com' + ], + :mail_exchange => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM.', + 'priority' => 10 + } + ], + :records => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + ) + end + + it "notifies /var/named/zones/example.com immediately" do + expect(chef_run.template('/var/named/zones/example.com.erb')).to notify("template[/var/named/zones/example.com]").to(:create).immediately + end + + end +end diff --git a/spec/unit/recipes_spec/chroot_spec.rb b/spec/unit/recipes_spec/chroot_spec.rb deleted file mode 100644 index fe3b238..0000000 --- a/spec/unit/recipes_spec/chroot_spec.rb +++ /dev/null @@ -1,135 +0,0 @@ -require 'spec_helper' - -ChefSpec::Coverage.start! - -describe 'bind9-chroot::chroot' do - PLATFORMS.each do |p| - context "#{p['platform']} #{p['version']}" do - let(:chef_run) do - ChefSpec::Runner.new(:platform=>p['platform'],:version=>p['version']) do |node| - node.set[:bind9][:chroot_dir] = '/var/run/bind' - end.converge(described_recipe) - end - - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) - File.stub(:directory?).with(anything).and_call_original - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) - end - - case p['platform'] - when 'ubuntu' - it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do - expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') - end - - it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do - File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) - expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') - end - - it 'runs ruby_block copy_openssl_dependencies' do - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) - expect(chef_run).to run_ruby_block('copy_openssl_dependencies') - end - end - - - it 'creates directory /var/run/bind/var/run/named' do - expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end - - it 'runs ruby_block modify_init_script' do - expect(chef_run).to run_ruby_block('modify_init_script') - end - - it 'does not run ruby_block modify_init_script' do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) - expect(chef_run).to_not run_ruby_block('modify_init_script') - end - - it "creates directory /var/run/bind#{p['config_path']}" do - expect(chef_run).to create_directory("/var/run/bind#{p['config_path']}").with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end - - it 'runs ruby_block move_config_to_chroot' do - File.stub(:symlink?).with(anything).and_call_original - File.stub(:symlink?).with(p['config_path']).and_return(false) - expect(chef_run).to run_ruby_block('move_config_to_chroot') - end - - it 'does not run ruby_block move_config_to_chroot' do - File.stub(:symlink?).with(anything).and_call_original - File.stub(:symlink?).with(p['config_path']).and_return(true) - expect(chef_run).to_not run_ruby_block('move_config_to_chroot') - end - - it 'links bind config from chroot' do - expect(chef_run).to create_link(p['config_path']).with( - to: "/var/run/bind#{p['config_path']}" - ) - end - - case p['platform'] - when "ubuntu" - it "does not create directory /var/run/bind#{p['zone_path']}" do - expect(chef_run).to_not create_directory("/var/run/bind#{p['zone_path']}") - end - - it 'does not link bind zones from chroot' do - expect(chef_run).to_not create_link("#{p['zone_path']}").with( - to: "/var/run/bind#{p['zone_path']}" - ) - end - else - it "does not create directory /var/run/bind#{p['zone_path']}" do - expect(chef_run).to create_directory("/var/run/bind#{p['zone_path']}").with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end - - it 'does not link bind zones from chroot' do - expect(chef_run).to create_link("#{p['zone_path']}").with( - to: "/var/run/bind#{p['zone_path']}" - ) - end - end - - it 'creates directory /var/run/bind/dev' do - expect(chef_run).to create_directory('/var/run/bind/dev').with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end - - it 'creates special device files' do - expect(chef_run).to run_execute('create_special_device_files') - end - - it 'does not create special device files' do - File.stub(:exists?).with(anything).and_call_original - File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) - expect(chef_run).to_not run_execute('create_special_device_files') - end - - end - end -end - diff --git a/spec/unit/recipes_spec/server_spec.rb b/spec/unit/recipes_spec/server_spec.rb deleted file mode 100644 index b1dcb49..0000000 --- a/spec/unit/recipes_spec/server_spec.rb +++ /dev/null @@ -1,242 +0,0 @@ -require 'spec_helper' - -ChefSpec::Coverage.start! do - add_filter '*/bind9-chroot/recipes/chroot.rb' -end - -describe 'bind9-chroot::server' do - let(:zones) { - [ - { - 'id' => 'exampleDOTcom', - 'domain' => 'example.com', - 'zone_info' => { - 'serial' =>'00000', - 'soa' => 'ns.example.com', - 'contact' => 'root.example.com', - 'global_ttl' => 300, - 'nameserver' => [ - 'ns1.example.com', - 'ns2.example.com' - ], - 'mail_exchange' => [ - { - 'host' => 'ASPMX.L.GOOGLE.COM.', - 'priority' => 10, - } - ], - 'records' => [ - { - 'name' => 'www', - 'type' => 'A', - 'ip' => '127.0.0.1' - } - ] - } - } - ] - } - - before(:each) do - stub_search("zones", "*:*").and_return(zones) - end - - PLATFORMS.each do |p| - context "#{p['platform']} #{p['version']}" do - let(:chef_run) { ChefSpec::Runner.new(:platform=>p['platform'],:version=>p['version']).converge(described_recipe) } - - it "installs #{p['package']}" do - expect(chef_run).to install_package(p['package']) - end - - it "enables #{p['service']} service" do - expect(chef_run).to enable_service(p['service']) - end - - it "creates directory #{p['data_path']} owned by #{p['user']} user" do - expect(chef_run).to create_directory(p['data_path']).with( - user: p['user'], - group: p['user'], - mode: 0755, - recursive: true - ) - end - - it "creates directory #{p['log_dir']} owned by bind user" do - expect(chef_run).to create_directory(p['log_dir']).with( - user: p['user'], - group: p['user'], - mode: 0755, - recursive: true - ) - end - - it "creates directory #{p['zone_path']} owned by bind user" do - expect(chef_run).to create_directory(p['zone_path']).with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end - - context 'chroot_dir exists' do - let(:chef_run) do - ChefSpec::Runner.new(:platform=>p['platform'],:version=>p['version']) do |node| - node.set[:bind9][:chroot_dir] = '/var/run/bind' - end.converge(described_recipe) - end - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) - end - - it 'includes bind9-chroot::chroot recipe' do - expect(chef_run).to include_recipe('bind9-chroot::chroot') - end - - it "creates directory /var/run/bind#{p['data_path']} owned by #{p['user']}" do - expect(chef_run).to create_directory("/var/run/bind#{p['data_path']}").with( - user: p['user'], - group: p['user'], - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/run/bind#{p['log_dir']} owned by #{p['user']}" do - expect(chef_run).to create_directory("/var/run/bind#{p['log_dir']}").with( - user: p['user'], - group: p['user'], - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/run/bind#{p['zone_path']} owned by #{p['user']}" do - expect(chef_run).to create_directory("/var/run/bind#{p['zone_path']}").with( - user: p['user'], - group: p['user'], - mode: 0744, - recursive: true - ) - end - - end - - it 'does not include bind9-chroot::chroot recipe' do - expect(chef_run).to_not include_recipe('resolvconf') - end - - it 'does not include resolvconf recipe' do - expect(chef_run).to_not include_recipe('resolvconf') - end - - it 'includes resolvconf recipe' do - chef_run.node.set[:bind9][:resolvconf] = true - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('resolvconf') - end - - it "creates template #{p['config_path']}/#{p['options_file']}" do - expect(chef_run).to create_template("#{p['config_path']}/#{p['options_file']}").with( - user: p['user'], - group: p['user'], - mode: 0644, - ) - end - - it "creates template #{p['config_path']}/#{p['config_file']}" do - expect(chef_run).to create_template("#{p['config_path']}/#{p['config_file']}").with( - user: p['user'], - group: p['user'], - mode: 0644, - ) - end - - it "#{p['config_path']}/#{p['config_file']} notifies bind9 to restart" do - expect(chef_run.template("#{p['config_path']}/#{p['config_file']}")).to notify('service[bind9]').to(:restart) - end - - it "creates #{p['config_path']}/#{p['local_file']}" do - expect(chef_run).to create_template("#{p['config_path']}/#{p['local_file']}").with( - user: p['user'], - group: p['user'], - mode: 0644, - variables: { :zonefiles => zones } - ) - end - - it "#{p['config_path']}/#{p['local_file']} notifies bind9 to restart" do - expect(chef_run.template("#{p['config_path']}/#{p['local_file']}")).to notify('service[bind9]').to(:restart) - end - - case p['platform'] - when 'ubuntu' - it 'creates /etc/default/bind9' do - expect(chef_run).to create_template('/etc/default/bind9').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) - end - - it '/etc/default/bind9 notifies bind9 to restart' do - expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) - end - end - - it "does not create #{p['zone_path']}/example.com" do - expect(chef_run).to_not create_template("#{p['zone_path']}/example.com").with( - source: '/etc/bind/zones/example.com.erb', - local: true, - user: p['user'], - group: p['user'], - mode: 0644, - variables: { :serial => '00000' } - ) - end - - it "creates #{p['zone_path']}/example.com.erb" do - expect(chef_run).to create_template("#{p['zone_path']}/example.com.erb").with( - source: 'zonefile.erb', - user: p['user'], - group: p['user'], - mode: 0644, - variables: { - :domain => 'example.com', - :soa => 'ns.example.com', - :contact => 'root.example.com', - :global_ttl => 300, - :nameserver => [ - 'ns1.example.com', - 'ns2.example.com' - ], - :mail_exchange => [ - { - 'host' => 'ASPMX.L.GOOGLE.COM.', - 'priority' => 10 - } - ], - :records => [ - { - 'name' => 'www', - 'type' => 'A', - 'ip' => '127.0.0.1' - } - ] - } - ) - end - - it "notifies #{p['zone_path']}/example.com immediately" do - expect(chef_run.template("#{p['zone_path']}/example.com.erb")).to notify("template[#{p['zone_path']}/example.com]").to(:create).immediately - end - - it "starts #{p['service']} service" do - expect(chef_run).to start_service('bind9') - end - - end - end -end diff --git a/spec/unit/recipes_spec/ubuntu/12.04/chroot_spec.rb b/spec/unit/recipes_spec/ubuntu/12.04/chroot_spec.rb new file mode 100644 index 0000000..3bdbf6c --- /dev/null +++ b/spec/unit/recipes_spec/ubuntu/12.04/chroot_spec.rb @@ -0,0 +1,111 @@ +require 'spec_helper' + +ChefSpec::Coverage.start! + +describe 'bind9-chroot::chroot' do + context 'Ubuntu 12.04' do + let(:chef_run) do + ChefSpec::Runner.new(:platform=>'ubuntu',:version=>'12.04') do |node| + node.set[:bind9][:chroot_dir] = '/var/run/bind' + end.converge(described_recipe) + end + + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) + end + + it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do + File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'runs ruby_block copy_openssl_dependencies' do + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + expect(chef_run).to run_ruby_block('copy_openssl_dependencies') + end + + it 'creates directory /var/run/bind/var/run/named' do + expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block modify_init_script' do + expect(chef_run).to run_ruby_block('modify_init_script') + end + + it 'does not run ruby_block modify_init_script' do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) + expect(chef_run).to_not run_ruby_block('modify_init_script') + end + + it "creates directory /var/run/bind/etc/bind" do + expect(chef_run).to create_directory("/var/run/bind/etc/bind").with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with('/etc/bind').and_return(false) + expect(chef_run).to run_ruby_block('move_config_to_chroot') + end + + it 'does not run ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with('/etc/bind').and_return(true) + expect(chef_run).to_not run_ruby_block('move_config_to_chroot') + end + + it 'links bind config from chroot' do + expect(chef_run).to create_link('/etc/bind').with( + to: "/var/run/bind/etc/bind" + ) + end + + it "does not create directory /var/run/bind/etc/bind/zones" do + expect(chef_run).to_not create_directory("/var/run/bind/etc/bind/zones") + end + + it 'does not link bind zones from chroot' do + expect(chef_run).to_not create_link('/etc/bind/zones').with( + to: "/var/run/bind/etc/bind/zones" + ) + end + + it 'creates directory /var/run/bind/dev' do + expect(chef_run).to create_directory('/var/run/bind/dev').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'creates special device files' do + expect(chef_run).to run_execute('create_special_device_files') + end + + it 'does not create special device files' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) + expect(chef_run).to_not run_execute('create_special_device_files') + end + + end +end + diff --git a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb new file mode 100644 index 0000000..e72e9cd --- /dev/null +++ b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb @@ -0,0 +1,231 @@ +require 'spec_helper' + +ChefSpec::Coverage.start! do + add_filter '*/bind9-chroot/recipes/chroot.rb' +end + +describe 'bind9-chroot::server' do + context 'Ubuntu 12.04' do + let(:chef_run) do + ChefSpec::Runner.new(:platform=>'ubuntu',:version=>'12.04') do |node| + node.set[:bind9][:zones] = zones + end.converge(described_recipe) + end + let(:zones) { + [ + { + 'domain' => 'example.com', + 'zone_info' => { + 'serial' =>'00000', + 'soa' => 'ns.example.com', + 'contact' => 'root.example.com', + 'global_ttl' => 300, + 'nameserver' => [ + 'ns1.example.com', + 'ns2.example.com' + ], + 'mail_exchange' => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM.', + 'priority' => 10, + } + ], + 'records' => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + } + ] + } + + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + end + + it "installs bind9" do + expect(chef_run).to install_package('bind9') + end + + it "enables bind9 service" do + expect(chef_run).to enable_service('bind9') + end + + it "creates directory /var/cache/bind owned by bind user" do + expect(chef_run).to create_directory('/var/cache/bind').with( + user: 'bind', + group: 'bind', + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/run/bind/var/cache/bind owned by bind user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/var/cache/bind').with( + user: 'bind', + group: 'bind', + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/log/bind owned by bind user" do + expect(chef_run).to create_directory('/var/log/bind').with( + user: 'bind', + group: 'bind', + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/run/bind/var/log/bind owned by bind user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/var/log/bind').with( + user: 'bind', + group: 'bind', + mode: 0755, + recursive: true + ) + end + + it "creates directory /etc/bind/zones owned by bind user" do + expect(chef_run).to create_directory('/etc/bind/zones').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it "creates directory /var/run/bind/etc/bind/zones owned by bind user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory('/var/run/bind/etc/bind/zones').with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'does not include bind9-chroot::chroot recipe' do + expect(chef_run).to_not include_recipe('bind9-chroot::chroot') + end + + it 'includes bind9-chroot::chroot recipe' do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('bind9-chroot::chroot') + end + + + it 'does not include resolvconf recipe' do + expect(chef_run).to_not include_recipe('resolvconf') + end + + it 'includes resolvconf recipe' do + chef_run.node.set[:bind9][:resolvconf] = true + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('resolvconf') + end + + it "creates template /etc/bind/named.conf.options" do + expect(chef_run).to create_template('/etc/bind/named.conf.options').with( + user: 'bind', + group: 'bind', + mode: 0644, + ) + end + + it "creates template /etc/bind/named.conf" do + expect(chef_run).to create_template('/etc/bind/named.conf').with( + user: 'bind', + group: 'bind', + mode: 0644, + ) + end + + it "/etc/bind/named.conf notifies bind9 to restart" do + expect(chef_run.template('/etc/bind/named.conf')).to notify('service[bind9]').to(:restart) + end + + it "creates /etc/bind/named.conf.local" do + expect(chef_run).to create_template('/etc/bind/named.conf.local').with( + user: 'bind', + group: 'bind', + mode: 0644, + variables: { :zonefiles => zones } + ) + end + + it "/etc/bind/named.conf.local notifies bind9 to restart" do + expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) + end + + it 'creates /etc/default/bind9' do + expect(chef_run).to create_template('/etc/default/bind9').with( + user: 'bind', + group: 'bind', + mode: 0644, + ) + end + + it '/etc/default/bind9 notifies bind9 to restart' do + expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) + end + + it "does not create /etc/bind/zones/example.com" do + expect(chef_run).to_not create_template('/etc/bind/zones/example.com').with( + source: '/etc/bind/zones/example.com.erb', + local: true, + user: 'bind', + group: 'bind', + mode: 0644, + variables: { :serial => '00000' } + ) + end + + it "creates /etc/bind/zones/example.com.erb" do + expect(chef_run).to create_template('/etc/bind/zones/example.com.erb').with( + source: 'zonefile.erb', + user: 'bind', + group: 'bind', + mode: 0644, + variables: { + :soa => 'ns.example.com', + :contact => 'root.example.com', + :global_ttl => 300, + :nameserver => [ + 'ns1.example.com', + 'ns2.example.com' + ], + :mail_exchange => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM.', + 'priority' => 10 + } + ], + :records => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + ) + end + + it "notifies /etc/bind/zones/example.com immediately" do + expect(chef_run.template('/etc/bind/zones/example.com.erb')).to notify("template[/etc/bind/zones/example.com]").to(:create).immediately + end + + end +end diff --git a/tmp/rspec_guard_result b/tmp/rspec_guard_result index d7c32b9..8b13789 100644 --- a/tmp/rspec_guard_result +++ b/tmp/rspec_guard_result @@ -1,21 +1 @@ -./spec/unit/recipes_spec/server_spec.rb:48 -./spec/unit/recipes_spec/server_spec.rb:52 -./spec/unit/recipes_spec/server_spec.rb:56 -./spec/unit/recipes_spec/server_spec.rb:65 -./spec/unit/recipes_spec/server_spec.rb:74 -./spec/unit/recipes_spec/server_spec.rb:127 -./spec/unit/recipes_spec/server_spec.rb:131 -./spec/unit/recipes_spec/server_spec.rb:135 -./spec/unit/recipes_spec/server_spec.rb:141 -./spec/unit/recipes_spec/server_spec.rb:149 -./spec/unit/recipes_spec/server_spec.rb:157 -./spec/unit/recipes_spec/server_spec.rb:161 -./spec/unit/recipes_spec/server_spec.rb:170 -./spec/unit/recipes_spec/server_spec.rb:189 -./spec/unit/recipes_spec/server_spec.rb:200 -./spec/unit/recipes_spec/server_spec.rb:232 -./spec/unit/recipes_spec/server_spec.rb:236 -./spec/unit/recipes_spec/server_spec.rb:94 -./spec/unit/recipes_spec/server_spec.rb:98 -./spec/unit/recipes_spec/server_spec.rb:107 -./spec/unit/recipes_spec/server_spec.rb:116 + From a6c5c3afaaabb131ed548dc2ad837f3c670e5da7 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Wed, 23 Apr 2014 17:09:09 -0500 Subject: [PATCH 11/15] started creating serverspec tests and fixed warnings. made more chefspec tests --- .kitchen.yml | 33 ++++++- Gemfile | 1 + attributes/default.rb | 2 +- recipes/server.rb | 56 ++++++------ spec/spec_helper.rb | 72 +++++++++------ .../recipes_spec/centos/6.5/server_spec.rb | 88 ++++++++++--------- .../recipes_spec/ubuntu/12.04/server_spec.rb | 58 ++++-------- templates/default/named.conf.local.erb | 28 ++++-- .../default/serverspec/spec_helper.rb | 11 +++ .../ubuntu/12.04/bind9_service_spec.rb | 19 ++++ 10 files changed, 224 insertions(+), 144 deletions(-) create mode 100644 test/integration/default/serverspec/spec_helper.rb create mode 100644 test/integration/default/serverspec/ubuntu/12.04/bind9_service_spec.rb diff --git a/.kitchen.yml b/.kitchen.yml index 034cc76..566d3c6 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -14,4 +14,35 @@ suites: data_bags_path: "test/integration/default/data_bags" run_list: - recipe[bind9-chroot::default] - attributes: + attributes: { + 'bind9': { + 'zones': [ + { + 'domain':'example.com', + 'zone_info': { + 'serial': '00000', + 'soa': 'ns.example.com', + 'contact': 'root.example.com', + 'global_ttl': 300, + 'nameserver': [ + 'ns1.example.com', + 'ns2.example.com' + ], + 'mail_exchange': [ + { + 'host': 'ASPMX.L.GOOGLE.COM.', + 'priority': 10, + } + ], + 'records': [ + { + 'name': 'www', + 'type': 'A', + 'ip': '127.0.0.1' + } + ] + } + } + ] + } + } diff --git a/Gemfile b/Gemfile index 3b674d7..0122ab8 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,7 @@ source 'https://rubygems.org' gem 'berkshelf' gem 'test-kitchen' +gem 'busser' gem 'kitchen-vagrant' gem 'foodcritic' gem 'chefspec' diff --git a/attributes/default.rb b/attributes/default.rb index bc67f56..9eca6c4 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -35,7 +35,7 @@ default[:bind9][:defaults_file] = "/etc/default/bind9" default[:bind9][:data_path] = "/var/cache/bind" default[:bind9][:zones_path] = "/etc/bind/zones" - default[:bind9][:log_file] = "/var/log/bind/bind.log" + default[:bind9][:log_file] = "/var/log/named/bind.log" default[:bind9][:user] = "bind" default[:bind9][:openssl] = "/usr/lib/x86_64-linux-gnu/openssl-1.0.0" diff --git a/recipes/server.rb b/recipes/server.rb index 8fd6947..fdd64b9 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -112,32 +112,36 @@ class Chef::Recipe::NameServer end node[:bind9][:zones].each do |z| - template "#{node[:bind9][:zones_path]}/#{z[:domain]}" do - source "#{node[:bind9][:zones_path]}/#{z[:domain]}.erb" - local true - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - notifies :restart, "service[bind9]" - variables({ - :serial => z[:zone_info][:serial] || Time.new.strftime("%Y%m%d%H%M%S") - }) - action :nothing - end + case z['type'] + when 'master' - template "#{node[:bind9][:zones_path]}/#{z[:domain]}.erb" do - source "zonefile.erb" - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - variables({ - :soa => z[:zone_info][:soa], - :contact => z[:zone_info][:contact], - :global_ttl => z[:zone_info][:global_ttl], - :nameserver => z[:zone_info][:nameserver], - :mail_exchange => z[:zone_info][:mail_exchange], - :records => z[:zone_info][:records] - }) - notifies :create, "template[#{node[:bind9][:zones_path]}/#{z[:domain]}]", :immediately + template "#{node[:bind9][:zones_path]}/db.#{z[:domain]}" do + source "#{node[:bind9][:zones_path]}/db.#{z[:domain]}.erb" + local true + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + notifies :restart, "service[bind9]" + variables( + :serial => z[:zone_info][:serial] || Time.new.strftime("%Y%m%d%H%M%S") + ) + action :nothing + end + + template "#{node[:bind9][:zones_path]}/db.#{z[:domain]}.erb" do + source "zonefile.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + variables( + :soa => z[:zone_info][:soa], + :contact => z[:zone_info][:contact], + :global_ttl => z[:zone_info][:global_ttl], + :nameserver => z[:zone_info][:nameserver], + :mail_exchange => z[:zone_info][:mail_exchange], + :records => z[:zone_info][:records] + ) + notifies :create, "template[#{node[:bind9][:zones_path]}/db.#{z[:domain]}]", :immediately + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ce9fabc..16be0e1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,36 +2,50 @@ require 'chefspec' require 'chefspec/berkshelf' -PLATFORMS = [ +Zones = [ { - 'platform' => 'ubuntu', - 'version' => '12.04', - 'package' => 'bind9', - 'service' => 'bind9', - 'user' => 'bind', - 'data_path' => '/var/cache/bind', - 'log_dir' => '/var/log/bind', - 'zones_path' => '/etc/bind/zones', - 'config_path' => '/etc/bind', - 'options_file' => 'named.conf.options', - 'config_file' => 'named.conf', - 'local_file' => 'named.conf.local' - }, - { - 'platform' => 'centos', - 'version' => '6.5', - 'package' => 'bind', - 'service' => 'named', - 'user' => 'named', - 'data_path' => '/var/named', - 'log_dir' => '/var/log/named', - 'zones_path' => '/var/named/zones', - 'config_path' => '/etc/named', - 'options_file' => 'named.conf.options', - 'config_file' => 'named.conf', - 'local_file' => 'named.conf.local' - } -] + 'domain' => 'example.com', + 'type' => 'master', + 'allow_transfer' => [ + '192.168.1.2', + '192.168.1.3' + ], + 'also_notify' => [ + '192.168.1.2', + '192.168.1.3' + ], + 'zone_info' => { + 'serial' =>'00000', + 'soa' => 'ns.example.com', + 'contact' => 'root.example.com', + 'global_ttl' => 300, + 'nameserver' => [ + 'ns1.example.com', + 'ns2.example.com' + ], + 'mail_exchange' => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM.', + 'priority' => 10, + } + ], + 'records' => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + }, + { + 'domain' => 'example.net', + 'type' => 'slave', + 'masters' => [ + '192.168.1.1' + ] + } + ] RSpec.configure do |config| config.color_enabled = true diff --git a/spec/unit/recipes_spec/centos/6.5/server_spec.rb b/spec/unit/recipes_spec/centos/6.5/server_spec.rb index e480513..57109a7 100644 --- a/spec/unit/recipes_spec/centos/6.5/server_spec.rb +++ b/spec/unit/recipes_spec/centos/6.5/server_spec.rb @@ -8,39 +8,10 @@ context 'Centos 6.5' do let(:chef_run) do ChefSpec::Runner.new(:platform=>'centos',:version=>'6.5') do |node| - node.set[:bind9][:zones] = zones + node.set[:bind9][:zones] = Zones end.converge(described_recipe) end - let(:zones) { - [ - { - 'domain' => 'example.com', - 'zone_info' => { - 'serial' =>'00000', - 'soa' => 'ns.example.com', - 'contact' => 'root.example.com', - 'global_ttl' => 300, - 'nameserver' => [ - 'ns1.example.com', - 'ns2.example.com' - ], - 'mail_exchange' => [ - { - 'host' => 'ASPMX.L.GOOGLE.COM.', - 'priority' => 10, - } - ], - 'records' => [ - { - 'name' => 'www', - 'type' => 'A', - 'ip' => '127.0.0.1' - } - ] - } - } - ] - } + before(:each) do File.stub(:readlines).with(anything).and_call_original @@ -156,12 +127,45 @@ expect(chef_run.template('/etc/named/named.conf')).to notify('service[named]').to(:restart) end - it "creates /etc/named/named.conf.local" do + it "creates /etc/named/named.conf.local owned by named user" do expect(chef_run).to create_template('/etc/named/named.conf.local').with( user: 'named', group: 'named', mode: 0644, - variables: { :zonefiles => zones } + variables: { :zonefiles => Zones } + ) + end + + it 'fills /etc/named/named.conf.local with correct content' do + expect(chef_run).to render_file('/etc/named/named.conf.local').with_content( +'// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; + +zone "example.com" { + type master; + file "/var/named/zones/db.example.com"; + allow-transfer { + 192.168.1.2; + 192.168.1.3; + }; + also-notify { + 192.168.1.2; + 192.168.1.3; + }; +}; + +zone "example.net" { + type slave; + file "db.example.net"; + masters { + 192.168.1.1; + }; +};' ) end @@ -178,8 +182,8 @@ ) end - it "does not create /var/named/zones/example.com" do - expect(chef_run).to_not create_template('/var/named/zones/example.com').with( + it "does not create /var/named/zones/db.example.com" do + expect(chef_run).to_not create_template('/var/named/zones/db.example.com').with( source: '/var/named/zones/example.com.erb', local: true, user: 'named', @@ -189,8 +193,8 @@ ) end - it "creates /var/named/zones/example.com.erb" do - expect(chef_run).to create_template('/var/named/zones/example.com.erb').with( + it "creates /var/named/zones/db.example.com.erb" do + expect(chef_run).to create_template('/var/named/zones/db.example.com.erb').with( source: 'zonefile.erb', user: 'named', group: 'named', @@ -202,7 +206,7 @@ :nameserver => [ 'ns1.example.com', 'ns2.example.com' - ], + ], :mail_exchange => [ { 'host' => 'ASPMX.L.GOOGLE.COM.', @@ -220,8 +224,12 @@ ) end - it "notifies /var/named/zones/example.com immediately" do - expect(chef_run.template('/var/named/zones/example.com.erb')).to notify("template[/var/named/zones/example.com]").to(:create).immediately + it "notifies /var/named/zones/db.example.com immediately" do + expect(chef_run.template('/var/named/zones/db.example.com.erb')).to notify("template[/var/named/zones/db.example.com]").to(:create).immediately + end + + it "does not create /var/named/zones/db.example.net.erb" do + expect(chef_run).to_not create_template('/var/named/zones/db.example.net.erb') end end diff --git a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb index e72e9cd..7ad7469 100644 --- a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb +++ b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb @@ -8,39 +8,9 @@ context 'Ubuntu 12.04' do let(:chef_run) do ChefSpec::Runner.new(:platform=>'ubuntu',:version=>'12.04') do |node| - node.set[:bind9][:zones] = zones + node.set[:bind9][:zones] = Zones end.converge(described_recipe) end - let(:zones) { - [ - { - 'domain' => 'example.com', - 'zone_info' => { - 'serial' =>'00000', - 'soa' => 'ns.example.com', - 'contact' => 'root.example.com', - 'global_ttl' => 300, - 'nameserver' => [ - 'ns1.example.com', - 'ns2.example.com' - ], - 'mail_exchange' => [ - { - 'host' => 'ASPMX.L.GOOGLE.COM.', - 'priority' => 10, - } - ], - 'records' => [ - { - 'name' => 'www', - 'type' => 'A', - 'ip' => '127.0.0.1' - } - ] - } - } - ] - } before(:each) do File.stub(:readlines).with(anything).and_call_original @@ -75,8 +45,8 @@ ) end - it "creates directory /var/log/bind owned by bind user" do - expect(chef_run).to create_directory('/var/log/bind').with( + it "creates directory /var/log/named owned by bind user" do + expect(chef_run).to create_directory('/var/log/named').with( user: 'bind', group: 'bind', mode: 0755, @@ -84,10 +54,10 @@ ) end - it "creates directory /var/run/bind/var/log/bind owned by bind user" do + it "creates directory /var/run/bind/var/log/named owned by bind user" do chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/var/log/bind').with( + expect(chef_run).to create_directory('/var/run/bind/var/log/named').with( user: 'bind', group: 'bind', mode: 0755, @@ -161,7 +131,7 @@ user: 'bind', group: 'bind', mode: 0644, - variables: { :zonefiles => zones } + variables: { :zonefiles => Zones } ) end @@ -181,8 +151,8 @@ expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) end - it "does not create /etc/bind/zones/example.com" do - expect(chef_run).to_not create_template('/etc/bind/zones/example.com').with( + it "does not create /etc/bind/zones/db.example.com" do + expect(chef_run).to_not create_template('/etc/bind/zones/db.example.com').with( source: '/etc/bind/zones/example.com.erb', local: true, user: 'bind', @@ -192,8 +162,8 @@ ) end - it "creates /etc/bind/zones/example.com.erb" do - expect(chef_run).to create_template('/etc/bind/zones/example.com.erb').with( + it "creates /etc/bind/zones/db.example.com.erb" do + expect(chef_run).to create_template('/etc/bind/zones/db.example.com.erb').with( source: 'zonefile.erb', user: 'bind', group: 'bind', @@ -223,8 +193,12 @@ ) end - it "notifies /etc/bind/zones/example.com immediately" do - expect(chef_run.template('/etc/bind/zones/example.com.erb')).to notify("template[/etc/bind/zones/example.com]").to(:create).immediately + it "notifies /etc/bind/zones/db.example.com immediately" do + expect(chef_run.template('/etc/bind/zones/db.example.com.erb')).to notify("template[/etc/bind/zones/db.example.com]").to(:create).immediately + end + + it "does not create /etc/bind/zones/db.example.net.erb" do + expect(chef_run).to_not create_template('/etc/bind/zones/db.example.net.erb') end end diff --git a/templates/default/named.conf.local.erb b/templates/default/named.conf.local.erb index 082faa0..67b7363 100644 --- a/templates/default/named.conf.local.erb +++ b/templates/default/named.conf.local.erb @@ -7,14 +7,32 @@ //include "/etc/bind/zones.rfc1918"; <% @zonefiles.each do |conf| -%> -zone "<%= conf["domain"] %>" IN { - type <%= conf["type"] %>; - file "<%= node[:bind9][:zones_path] %>/<%= conf["domain"] %>"; +zone "<%= conf['domain'] %>" { + type <%= conf['type'] %>; + <% if conf['type'] == "master" %> + file "<%= node[:bind9][:zones_path] %>/db.<%= conf["domain"] %>"; + <% if conf['allow_transfer'].is_a?(Array) %> allow-transfer { - <% conf["allow_transfer"].each do |ip| -%> + <% conf['allow_transfer'].each do |ip| -%> <%= ip %>; - <% end %> + <% end %> + }; + <% end %> + <% if conf['also_notify'].is_a?(Array) -%> + also-notify { + <% conf['also_notify'].each do |ip| -%> + <%= ip %>; + <% end %> }; + <% end %> + <% elsif conf['type'] == "slave" -%> + file "db.<%= conf["domain"] %>"; + masters { + <% conf['masters'].each do |ip| -%> + <%= ip %>; + <% end %> + }; + <% end %> }; <% end %> diff --git a/test/integration/default/serverspec/spec_helper.rb b/test/integration/default/serverspec/spec_helper.rb new file mode 100644 index 0000000..541a08f --- /dev/null +++ b/test/integration/default/serverspec/spec_helper.rb @@ -0,0 +1,11 @@ +require 'serverspec' + +include Serverspec::Helper::Exec +include Serverspec::Helper::DetectOS + +RSpec.configure do |c| + c.before :all do + c.path = '/sbin:/usr/sbin' + c.os = backend(Serverspec::Commands::Base).check_os + end +end diff --git a/test/integration/default/serverspec/ubuntu/12.04/bind9_service_spec.rb b/test/integration/default/serverspec/ubuntu/12.04/bind9_service_spec.rb new file mode 100644 index 0000000..427002a --- /dev/null +++ b/test/integration/default/serverspec/ubuntu/12.04/bind9_service_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe 'Bind9 Server' do + + it 'is listening on port 53' do + expect(port(53)).to be_listening + end + + it 'has bind9 service enabled and started' do + case RSpec.configuration.os[:family] + when 'Ubuntu' + expect(service('bind9')).to be_enabled + expect(service('bind9')).to be_running + else + expect(service('named')).to be_enabled + expect(service('named')).to be_running + end + end +end From 2432e08798aeba2395f9b0a143b70c80391daf29 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Thu, 24 Apr 2014 17:17:08 -0500 Subject: [PATCH 12/15] created serverspecs and fixed code to pass tests --- .kitchen.yml | 17 +++- .../recipes_spec/centos/6.5/server_spec.rb | 22 +++++ .../recipes_spec/ubuntu/12.04/server_spec.rb | 55 +++++++++++ templates/default/named.conf.local.erb | 28 +++--- .../data_bags/zones/exampleDOTcom.json | 25 ----- .../default/serverspec/bind9_service_spec.rb | 96 +++++++++++++++++++ .../ubuntu/12.04/bind9_service_spec.rb | 19 ---- 7 files changed, 204 insertions(+), 58 deletions(-) delete mode 100644 test/integration/default/data_bags/zones/exampleDOTcom.json create mode 100644 test/integration/default/serverspec/bind9_service_spec.rb delete mode 100644 test/integration/default/serverspec/ubuntu/12.04/bind9_service_spec.rb diff --git a/.kitchen.yml b/.kitchen.yml index 566d3c6..8809049 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -11,7 +11,6 @@ platforms: suites: - name: default - data_bags_path: "test/integration/default/data_bags" run_list: - recipe[bind9-chroot::default] attributes: { @@ -19,6 +18,15 @@ suites: 'zones': [ { 'domain':'example.com', + 'type':'master', + 'allow_transfer': [ + '192.168.1.2', + '192.168.1.3' + ], + 'also_notify': [ + '192.168.1.2', + '192.168.1.3' + ], 'zone_info': { 'serial': '00000', 'soa': 'ns.example.com', @@ -42,6 +50,13 @@ suites: } ] } + }, + { + 'domain':'example.net', + 'type':'slave', + 'masters': [ + '192.168.1.1' + ] } ] } diff --git a/spec/unit/recipes_spec/centos/6.5/server_spec.rb b/spec/unit/recipes_spec/centos/6.5/server_spec.rb index 57109a7..e5cf6a6 100644 --- a/spec/unit/recipes_spec/centos/6.5/server_spec.rb +++ b/spec/unit/recipes_spec/centos/6.5/server_spec.rb @@ -224,6 +224,28 @@ ) end + it 'fills /var/named/zones/db.example.com.erb with correct content' do + expect(chef_run).to render_file('/var/named/zones/db.example.com.erb').with_content( +'$TTL 300 +@ IN SOA ns.example.com root.example.com ( + <%= @serial %> ; serial [yyyyMMddNN] + 4H ; refresh + 30M ; retry + 1W ; expiry + 1D ; minimum +) + + IN NS ns.example.com + IN NS ns1.example.com + IN NS ns2.example.com + + IN MX 10 ASPMX.L.GOOGLE.COM. + +www IN A 127.0.0.1 +' + ) + end + it "notifies /var/named/zones/db.example.com immediately" do expect(chef_run.template('/var/named/zones/db.example.com.erb')).to notify("template[/var/named/zones/db.example.com]").to(:create).immediately end diff --git a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb index 7ad7469..b42bc3a 100644 --- a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb +++ b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb @@ -135,6 +135,39 @@ ) end + it 'fills /etc/bind/named.conf.local with correct content' do + expect(chef_run).to render_file('/etc/bind/named.conf.local').with_content( +'// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; + +zone "example.com" { + type master; + file "/etc/bind/zones/db.example.com"; + allow-transfer { + 192.168.1.2; + 192.168.1.3; + }; + also-notify { + 192.168.1.2; + 192.168.1.3; + }; +}; + +zone "example.net" { + type slave; + file "db.example.net"; + masters { + 192.168.1.1; + }; +};' + ) + end + it "/etc/bind/named.conf.local notifies bind9 to restart" do expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) end @@ -193,6 +226,28 @@ ) end + it 'fills /etc/bind/zones/db.example.com.erb with correct content' do + expect(chef_run).to render_file('/etc/bind/zones/db.example.com.erb').with_content( +'$TTL 300 +@ IN SOA ns.example.com root.example.com ( + <%= @serial %> ; serial [yyyyMMddNN] + 4H ; refresh + 30M ; retry + 1W ; expiry + 1D ; minimum +) + + IN NS ns.example.com + IN NS ns1.example.com + IN NS ns2.example.com + + IN MX 10 ASPMX.L.GOOGLE.COM. + +www IN A 127.0.0.1 +' + ) + end + it "notifies /etc/bind/zones/db.example.com immediately" do expect(chef_run.template('/etc/bind/zones/db.example.com.erb')).to notify("template[/etc/bind/zones/db.example.com]").to(:create).immediately end diff --git a/templates/default/named.conf.local.erb b/templates/default/named.conf.local.erb index 67b7363..07f4177 100644 --- a/templates/default/named.conf.local.erb +++ b/templates/default/named.conf.local.erb @@ -7,32 +7,34 @@ //include "/etc/bind/zones.rfc1918"; <% @zonefiles.each do |conf| -%> + <% if conf['type'] %> zone "<%= conf['domain'] %>" { type <%= conf['type'] %>; - <% if conf['type'] == "master" %> + <% if conf['type'] == "master" %> file "<%= node[:bind9][:zones_path] %>/db.<%= conf["domain"] %>"; - <% if conf['allow_transfer'].is_a?(Array) %> + <% if conf['allow_transfer'].is_a?(Array) %> allow-transfer { - <% conf['allow_transfer'].each do |ip| -%> + <% conf['allow_transfer'].each do |ip| -%> <%= ip %>; - <% end %> + <% end %> }; - <% end %> - <% if conf['also_notify'].is_a?(Array) -%> + <% end %> + <% if conf['also_notify'].is_a?(Array) -%> also-notify { - <% conf['also_notify'].each do |ip| -%> + <% conf['also_notify'].each do |ip| -%> <%= ip %>; - <% end %> + <% end %> }; - <% end %> - <% elsif conf['type'] == "slave" -%> + <% end %> + <% elsif conf['type'] == "slave" -%> file "db.<%= conf["domain"] %>"; masters { - <% conf['masters'].each do |ip| -%> + <% conf['masters'].each do |ip| -%> <%= ip %>; - <% end %> + <% end %> }; - <% end %> + <% end %> }; + <% end %> <% end %> diff --git a/test/integration/default/data_bags/zones/exampleDOTcom.json b/test/integration/default/data_bags/zones/exampleDOTcom.json deleted file mode 100644 index 6fcaeb9..0000000 --- a/test/integration/default/data_bags/zones/exampleDOTcom.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "id": "exampleDOTcom", - "domain": "example.com", - "type": "master", - "allow_transfer": [], - "zone_info": { - "global_ttl": 300, - "soa": "ns.example.com.", - "contact": "user.example.com.", - "nameserver": [ "ns.example.com.", - "ns.example.net." ], - "mail_exchange": [], - "records": [{ - "name": "www", - "type": "A" - },{ - "name": "img", - "ttl": 30, - "type": "A" - },{ - "name": "mail", - "type": "CNAME" - }] - } - } diff --git a/test/integration/default/serverspec/bind9_service_spec.rb b/test/integration/default/serverspec/bind9_service_spec.rb new file mode 100644 index 0000000..a65982b --- /dev/null +++ b/test/integration/default/serverspec/bind9_service_spec.rb @@ -0,0 +1,96 @@ +require 'spec_helper' + +describe port(53) do + it { should be_listening } +end + +describe 'check Bind sevice' do + it 'should enable and run service' do + case RSpec.configuration.os[:family] + when 'Ubuntu' + expect(service('bind9')).to be_enabled + expect(service('bind9')).to be_running + else + expect(service('named')).to be_enabled + expect(service('named')).to be_running + end + end +end + +describe 'named.conf.local' do + it 'should exist' do + case RSpec.configuration.os[:family] + when 'Ubuntu' + expect(file('/etc/bind/named.conf.local')).to be_file + else + expect(file('/etc/named/named.conf.local')).to be_file + end + end + + it 'should contain' do + case RSpec.configuration.os[:family] + when 'Ubuntu' + expect(file('/etc/bind/named.conf.local').content).to match( +'// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; + +zone "example.com" { + type master; + file "/etc/bind/zones/db.example.com"; + allow-transfer { + 192.168.1.2; + 192.168.1.3; + }; + also-notify { + 192.168.1.2; + 192.168.1.3; + }; +}; + +zone "example.net" { + type slave; + file "db.example.net"; + masters { + 192.168.1.1; + }; +};' + ) + else + expect(file('/etc/named/named.conf.local').content).to match( +'// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; + +zone "example.com" { + type master; + file "/var/named/zones/db.example.com"; + allow-transfer { + 192.168.1.2; + 192.168.1.3; + }; + also-notify { + 192.168.1.2; + 192.168.1.3; + }; +}; + +zone "example.net" { + type slave; + file "db.example.net"; + masters { + 192.168.1.1; + }; +};' + ) + end + end +end diff --git a/test/integration/default/serverspec/ubuntu/12.04/bind9_service_spec.rb b/test/integration/default/serverspec/ubuntu/12.04/bind9_service_spec.rb deleted file mode 100644 index 427002a..0000000 --- a/test/integration/default/serverspec/ubuntu/12.04/bind9_service_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'spec_helper' - -describe 'Bind9 Server' do - - it 'is listening on port 53' do - expect(port(53)).to be_listening - end - - it 'has bind9 service enabled and started' do - case RSpec.configuration.os[:family] - when 'Ubuntu' - expect(service('bind9')).to be_enabled - expect(service('bind9')).to be_running - else - expect(service('named')).to be_enabled - expect(service('named')).to be_running - end - end -end From f29d8f253ec1329e3ad8a1ca147fef53496ee58a Mon Sep 17 00:00:00 2001 From: Brad Wadsworth Date: Wed, 30 Apr 2014 22:37:22 -0500 Subject: [PATCH 13/15] edited chefspecs and serverspecs --- .kitchen.yml | 54 ++++++++++++++++++- recipes/server.rb | 3 +- spec/spec_helper.rb | 2 +- .../recipes_spec/centos/6.5/server_spec.rb | 12 ++--- .../recipes_spec/ubuntu/12.04/server_spec.rb | 10 ++-- templates/default/zonefile.erb | 8 +-- .../default/serverspec/bind9_service_spec.rb | 38 ++++++++++++- tmp/rspec_guard_result | 1 - 8 files changed, 107 insertions(+), 21 deletions(-) delete mode 100644 tmp/rspec_guard_result diff --git a/.kitchen.yml b/.kitchen.yml index 8809049..a009168 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -38,7 +38,7 @@ suites: ], 'mail_exchange': [ { - 'host': 'ASPMX.L.GOOGLE.COM.', + 'host': 'ASPMX.L.GOOGLE.COM', 'priority': 10, } ], @@ -61,3 +61,55 @@ suites: ] } } + - name: chroot + run_list: + - recipe[bind9-chroot::default] + attributes: { + 'bind9': { + 'chroot_dir' => true, + 'zones': [ + { + 'domain':'example.com', + 'type':'master', + 'allow_transfer': [ + '192.168.1.2', + '192.168.1.3' + ], + 'also_notify': [ + '192.168.1.2', + '192.168.1.3' + ], + 'zone_info': { + 'serial': '00000', + 'soa': 'ns.example.com', + 'contact': 'root.example.com', + 'global_ttl': 300, + 'nameserver': [ + 'ns1.example.com', + 'ns2.example.com' + ], + 'mail_exchange': [ + { + 'host': 'ASPMX.L.GOOGLE.COM', + 'priority': 10, + } + ], + 'records': [ + { + 'name': 'www', + 'type': 'A', + 'ip': '127.0.0.1' + } + ] + } + }, + { + 'domain':'example.net', + 'type':'slave', + 'masters': [ + '192.168.1.1' + ] + } + ] + } + } diff --git a/recipes/server.rb b/recipes/server.rb index fdd64b9..29609bb 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -112,9 +112,8 @@ class Chef::Recipe::NameServer end node[:bind9][:zones].each do |z| - case z['type'] - when 'master' + if z[:type] == "master" and z[:zone_info].is_a?(Hash) template "#{node[:bind9][:zones_path]}/db.#{z[:domain]}" do source "#{node[:bind9][:zones_path]}/db.#{z[:domain]}.erb" local true diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 16be0e1..113437f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,7 +25,7 @@ ], 'mail_exchange' => [ { - 'host' => 'ASPMX.L.GOOGLE.COM.', + 'host' => 'ASPMX.L.GOOGLE.COM', 'priority' => 10, } ], diff --git a/spec/unit/recipes_spec/centos/6.5/server_spec.rb b/spec/unit/recipes_spec/centos/6.5/server_spec.rb index e5cf6a6..42d76b9 100644 --- a/spec/unit/recipes_spec/centos/6.5/server_spec.rb +++ b/spec/unit/recipes_spec/centos/6.5/server_spec.rb @@ -209,7 +209,7 @@ ], :mail_exchange => [ { - 'host' => 'ASPMX.L.GOOGLE.COM.', + 'host' => 'ASPMX.L.GOOGLE.COM', 'priority' => 10 } ], @@ -227,7 +227,7 @@ it 'fills /var/named/zones/db.example.com.erb with correct content' do expect(chef_run).to render_file('/var/named/zones/db.example.com.erb').with_content( '$TTL 300 -@ IN SOA ns.example.com root.example.com ( +@ IN SOA ns.example.com. root.example.com. ( <%= @serial %> ; serial [yyyyMMddNN] 4H ; refresh 30M ; retry @@ -235,9 +235,9 @@ 1D ; minimum ) - IN NS ns.example.com - IN NS ns1.example.com - IN NS ns2.example.com + IN NS ns.example.com. + IN NS ns1.example.com. + IN NS ns2.example.com. IN MX 10 ASPMX.L.GOOGLE.COM. @@ -246,7 +246,7 @@ ) end - it "notifies /var/named/zones/db.example.com immediately" do + it "notifies/var/named/zones/db.example.com immediately" do expect(chef_run.template('/var/named/zones/db.example.com.erb')).to notify("template[/var/named/zones/db.example.com]").to(:create).immediately end diff --git a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb index b42bc3a..851d809 100644 --- a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb +++ b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb @@ -211,7 +211,7 @@ ], :mail_exchange => [ { - 'host' => 'ASPMX.L.GOOGLE.COM.', + 'host' => 'ASPMX.L.GOOGLE.COM', 'priority' => 10 } ], @@ -229,7 +229,7 @@ it 'fills /etc/bind/zones/db.example.com.erb with correct content' do expect(chef_run).to render_file('/etc/bind/zones/db.example.com.erb').with_content( '$TTL 300 -@ IN SOA ns.example.com root.example.com ( +@ IN SOA ns.example.com. root.example.com. ( <%= @serial %> ; serial [yyyyMMddNN] 4H ; refresh 30M ; retry @@ -237,9 +237,9 @@ 1D ; minimum ) - IN NS ns.example.com - IN NS ns1.example.com - IN NS ns2.example.com + IN NS ns.example.com. + IN NS ns1.example.com. + IN NS ns2.example.com. IN MX 10 ASPMX.L.GOOGLE.COM. diff --git a/templates/default/zonefile.erb b/templates/default/zonefile.erb index 511c071..4b85064 100644 --- a/templates/default/zonefile.erb +++ b/templates/default/zonefile.erb @@ -1,5 +1,5 @@ $TTL <%= @global_ttl %> -@ IN SOA <%= @soa %> <%= @contact %> ( +@ IN SOA <%= @soa %>. <%= @contact %>. ( <%%= @serial %> ; serial [yyyyMMddNN] 4H ; refresh 30M ; retry @@ -7,13 +7,13 @@ $TTL <%= @global_ttl %> 1D ; minimum ) - IN NS <%= @soa %> + IN NS <%= @soa %>. <% @nameserver.each do |ns| -%> - IN NS <%= ns %> + IN NS <%= ns %>. <% end %> <% @mail_exchange.each do |mx| -%> - IN MX <%= mx['priority'] %> <%= mx['host'] %> + IN MX <%= mx['priority'] %> <%= mx['host'] %>. <% end %> <% @records.each do |record| -%> diff --git a/test/integration/default/serverspec/bind9_service_spec.rb b/test/integration/default/serverspec/bind9_service_spec.rb index a65982b..b83c82b 100644 --- a/test/integration/default/serverspec/bind9_service_spec.rb +++ b/test/integration/default/serverspec/bind9_service_spec.rb @@ -27,7 +27,7 @@ end end - it 'should contain' do + it 'should contain correct content' do case RSpec.configuration.os[:family] when 'Ubuntu' expect(file('/etc/bind/named.conf.local').content).to match( @@ -94,3 +94,39 @@ end end end + +describe 'db.example.com' do + it 'should exist' do + case RSpec.configuration.os[:family] + when 'Ubuntu' + expect(file('/etc/bind/zones/db.example.com')).to be_file + else + expect(file('/var/named/zones/db.example.com')).to be_file + end + end + + it 'should contain correct content' do + case RSpec.configuration.os[:family] + when 'Ubuntu' + expect(file('/etc/bind/zones/db.example.com').content).to match( +'$TTL 300 +@ IN SOA ns.example.com. root.example.com. ( + 0000 ; serial [yyyyMMddNN] + 4H ; refresh + 30M ; retry + 1W ; expiry + 1D ; minimum +) + + IN NS ns.example.com. + IN NS ns1.example.com. + IN NS ns2.example.com. + + IN MX 10 ASPMX.L.GOOGLE.COM. + +www IN A 127.0.0.1' + ) +# else + end + end +end diff --git a/tmp/rspec_guard_result b/tmp/rspec_guard_result deleted file mode 100644 index 8b13789..0000000 --- a/tmp/rspec_guard_result +++ /dev/null @@ -1 +0,0 @@ - From c2cc2175e7dbc0748a8dd1cfa5f79b54e9eb039c Mon Sep 17 00:00:00 2001 From: Brad Wadsworth Date: Mon, 12 May 2014 09:52:30 -0500 Subject: [PATCH 14/15] modified chefspec tests --- recipes/chroot.rb | 2 +- .../recipes_spec/centos/6.5/chroot_spec.rb | 87 ----- .../recipes_spec/centos/6.5/server_spec.rb | 258 ------------- spec/unit/recipes_spec/chroot_spec.rb | 126 +++++++ spec/unit/recipes_spec/server_spec.rb | 341 ++++++++++++++++++ .../recipes_spec/ubuntu/12.04/chroot_spec.rb | 111 ------ .../recipes_spec/ubuntu/12.04/server_spec.rb | 260 ------------- 7 files changed, 468 insertions(+), 717 deletions(-) delete mode 100644 spec/unit/recipes_spec/centos/6.5/chroot_spec.rb delete mode 100644 spec/unit/recipes_spec/centos/6.5/server_spec.rb create mode 100644 spec/unit/recipes_spec/chroot_spec.rb create mode 100644 spec/unit/recipes_spec/server_spec.rb delete mode 100644 spec/unit/recipes_spec/ubuntu/12.04/chroot_spec.rb delete mode 100644 spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb diff --git a/recipes/chroot.rb b/recipes/chroot.rb index e652126..e13d9a0 100644 --- a/recipes/chroot.rb +++ b/recipes/chroot.rb @@ -19,7 +19,7 @@ case node[:platform] when "ubuntu" if node[:platform_version].to_f >= 12.04 - ruby_block "copy_openssl_dependencies" do + ruby_block "copy_openssl_dependencies" do block do FileUtils.mkdir_p File.dirname(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) FileUtils.cp_r node[:bind9][:openssl], File.dirname(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) diff --git a/spec/unit/recipes_spec/centos/6.5/chroot_spec.rb b/spec/unit/recipes_spec/centos/6.5/chroot_spec.rb deleted file mode 100644 index 0a3e331..0000000 --- a/spec/unit/recipes_spec/centos/6.5/chroot_spec.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'spec_helper' - -ChefSpec::Coverage.start! - -describe 'bind9-chroot::chroot' do - context 'Centos 6.5' do - let(:chef_run) do - ChefSpec::Runner.new(:platform=>'centos',:version=>'6.5') do |node| - node.set[:bind9][:chroot_dir] = '/var/run/bind' - end.converge(described_recipe) - end - - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) - File.stub(:directory?).with(anything).and_call_original - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) - end - - it 'creates directory /var/run/bind/var/run/named' do - expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( - user: 'named', - group: 'named', - mode: 0744, - recursive: true - ) - end - - it 'runs ruby_block modify_init_script' do - expect(chef_run).to run_ruby_block('modify_init_script') - end - - it 'does not run ruby_block modify_init_script' do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) - expect(chef_run).to_not run_ruby_block('modify_init_script') - end - - it "creates directory /var/run/bind/etc/named" do - expect(chef_run).to create_directory("/var/run/bind/etc/named").with( - user: 'named', - group: 'named', - mode: 0744, - recursive: true - ) - end - - it 'runs ruby_block move_config_to_chroot' do - File.stub(:symlink?).with(anything).and_call_original - File.stub(:symlink?).with('/etc/named').and_return(false) - expect(chef_run).to run_ruby_block('move_config_to_chroot') - end - - it 'does not run ruby_block move_config_to_chroot' do - File.stub(:symlink?).with(anything).and_call_original - File.stub(:symlink?).with('/etc/named').and_return(true) - expect(chef_run).to_not run_ruby_block('move_config_to_chroot') - end - - it 'links bind config from chroot' do - expect(chef_run).to create_link('/etc/named').with( - to: "/var/run/bind/etc/named" - ) - end - - it 'creates directory /var/run/bind/dev' do - expect(chef_run).to create_directory('/var/run/bind/dev').with( - user: 'named', - group: 'named', - mode: 0744, - recursive: true - ) - end - - it 'creates special device files' do - expect(chef_run).to run_execute('create_special_device_files') - end - - it 'does not create special device files' do - File.stub(:exists?).with(anything).and_call_original - File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) - expect(chef_run).to_not run_execute('create_special_device_files') - end - - end -end - diff --git a/spec/unit/recipes_spec/centos/6.5/server_spec.rb b/spec/unit/recipes_spec/centos/6.5/server_spec.rb deleted file mode 100644 index 42d76b9..0000000 --- a/spec/unit/recipes_spec/centos/6.5/server_spec.rb +++ /dev/null @@ -1,258 +0,0 @@ -require 'spec_helper' - -ChefSpec::Coverage.start! do - add_filter '*/bind9-chroot/recipes/chroot.rb' -end - -describe 'bind9-chroot::server' do - context 'Centos 6.5' do - let(:chef_run) do - ChefSpec::Runner.new(:platform=>'centos',:version=>'6.5') do |node| - node.set[:bind9][:zones] = Zones - end.converge(described_recipe) - end - - - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) - end - - it "installs bind" do - expect(chef_run).to install_package('bind') - end - - it "enables named service" do - expect(chef_run).to enable_service('named') - end - - it "creates directory /var/named owned by named user" do - expect(chef_run).to create_directory('/var/named').with( - user: 'named', - group: 'named', - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/run/bind/var/named owned by named user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/var/named').with( - user: 'named', - group: 'named', - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/log/named owned by named user" do - expect(chef_run).to create_directory('/var/log/named').with( - user: 'named', - group: 'named', - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/run/bind/var/log/named owned by named user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/var/log/named').with( - user: 'named', - group: 'named', - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/named/zones owned by named user" do - expect(chef_run).to create_directory('/var/named/zones').with( - user: 'named', - group: 'named', - mode: 0744, - recursive: true - ) - end - - it "creates directory /var/run/bind/var/named/zones owned by named user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/var/named/zones').with( - user: 'named', - group: 'named', - mode: 0744, - recursive: true - ) - end - - it 'does not include bind9-chroot::chroot recipe' do - expect(chef_run).to_not include_recipe('bind9-chroot::chroot') - end - - it 'includes bind9-chroot::chroot recipe' do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('bind9-chroot::chroot') - end - - - it 'does not include resolvconf recipe' do - expect(chef_run).to_not include_recipe('resolvconf') - end - - it 'includes resolvconf recipe' do - chef_run.node.set[:bind9][:resolvconf] = true - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('resolvconf') - end - - it "creates template /etc/named/named.conf.options" do - expect(chef_run).to create_template('/etc/named/named.conf.options').with( - user: 'named', - group: 'named', - mode: 0644, - ) - end - - it "creates template /etc/named/named.conf" do - expect(chef_run).to create_template('/etc/named/named.conf').with( - user: 'named', - group: 'named', - mode: 0644, - ) - end - - it "/etc/named/named.conf notifies bind to restart" do - expect(chef_run.template('/etc/named/named.conf')).to notify('service[named]').to(:restart) - end - - it "creates /etc/named/named.conf.local owned by named user" do - expect(chef_run).to create_template('/etc/named/named.conf.local').with( - user: 'named', - group: 'named', - mode: 0644, - variables: { :zonefiles => Zones } - ) - end - - it 'fills /etc/named/named.conf.local with correct content' do - expect(chef_run).to render_file('/etc/named/named.conf.local').with_content( -'// -// Do any local configuration here -// - -// Consider adding the 1918 zones here, if they are not used in your -// organization -//include "/etc/bind/zones.rfc1918"; - -zone "example.com" { - type master; - file "/var/named/zones/db.example.com"; - allow-transfer { - 192.168.1.2; - 192.168.1.3; - }; - also-notify { - 192.168.1.2; - 192.168.1.3; - }; -}; - -zone "example.net" { - type slave; - file "db.example.net"; - masters { - 192.168.1.1; - }; -};' - ) - end - - it "/etc/named/named.conf.local notifies bind to restart" do - expect(chef_run.template('/etc/named/named.conf.local')).to notify('service[named]').to(:restart) - end - - it "creates directory /var/named/zones owned by named user" do - expect(chef_run).to create_directory('/var/named/zones').with( - user: 'named', - group: 'named', - mode: 0744, - recursive: true - ) - end - - it "does not create /var/named/zones/db.example.com" do - expect(chef_run).to_not create_template('/var/named/zones/db.example.com').with( - source: '/var/named/zones/example.com.erb', - local: true, - user: 'named', - group: 'named', - mode: 0644, - variables: { :serial => '00000' } - ) - end - - it "creates /var/named/zones/db.example.com.erb" do - expect(chef_run).to create_template('/var/named/zones/db.example.com.erb').with( - source: 'zonefile.erb', - user: 'named', - group: 'named', - mode: 0644, - variables: { - :soa => 'ns.example.com', - :contact => 'root.example.com', - :global_ttl => 300, - :nameserver => [ - 'ns1.example.com', - 'ns2.example.com' - ], - :mail_exchange => [ - { - 'host' => 'ASPMX.L.GOOGLE.COM', - 'priority' => 10 - } - ], - :records => [ - { - 'name' => 'www', - 'type' => 'A', - 'ip' => '127.0.0.1' - } - ] - } - ) - end - - it 'fills /var/named/zones/db.example.com.erb with correct content' do - expect(chef_run).to render_file('/var/named/zones/db.example.com.erb').with_content( -'$TTL 300 -@ IN SOA ns.example.com. root.example.com. ( - <%= @serial %> ; serial [yyyyMMddNN] - 4H ; refresh - 30M ; retry - 1W ; expiry - 1D ; minimum -) - - IN NS ns.example.com. - IN NS ns1.example.com. - IN NS ns2.example.com. - - IN MX 10 ASPMX.L.GOOGLE.COM. - -www IN A 127.0.0.1 -' - ) - end - - it "notifies/var/named/zones/db.example.com immediately" do - expect(chef_run.template('/var/named/zones/db.example.com.erb')).to notify("template[/var/named/zones/db.example.com]").to(:create).immediately - end - - it "does not create /var/named/zones/db.example.net.erb" do - expect(chef_run).to_not create_template('/var/named/zones/db.example.net.erb') - end - - end -end diff --git a/spec/unit/recipes_spec/chroot_spec.rb b/spec/unit/recipes_spec/chroot_spec.rb new file mode 100644 index 0000000..e1fe370 --- /dev/null +++ b/spec/unit/recipes_spec/chroot_spec.rb @@ -0,0 +1,126 @@ +require 'spec_helper' + +ChefSpec::Coverage.start! + +describe 'bind9-chroot::chroot' do + platforms = { + 'ubuntu' => { + 'versions' => ['12.04'], + 'user' => 'bind', + 'group' => 'bind', + 'config_dir' => '/etc/bind', + 'zones_dir' => '/etc/bind/zones' + } + } + platforms.each do |platform,vals| + vals['versions'].each do |version| + context "On #{platform} #{version}" do + let(:chef_run) do + ChefSpec::Runner.new(:platform=>platform,:version=>version) do |node| + node.set[:bind9][:chroot_dir] = '/var/run/bind' + end.converge(described_recipe) + end + + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) + end + + if platform == 'ubuntu' + it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do + File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') + end + + it 'runs ruby_block copy_openssl_dependencies' do + File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + expect(chef_run).to run_ruby_block('copy_openssl_dependencies') + end + end + + it 'creates directory /var/run/bind/var/run/named' do + expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( + user: vals['user'], + group: vals['group'], + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block modify_init_script' do + expect(chef_run).to run_ruby_block('modify_init_script') + end + + it 'does not run ruby_block modify_init_script' do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) + expect(chef_run).to_not run_ruby_block('modify_init_script') + end + + it "creates directory /var/run/bind#{vals['config_dir']}" do + expect(chef_run).to create_directory("/var/run/bind#{vals['config_dir']}").with( + user: 'bind', + group: 'bind', + mode: 0744, + recursive: true + ) + end + + it 'runs ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with(vals['config_dir']).and_return(false) + expect(chef_run).to run_ruby_block('move_config_to_chroot') + end + + it 'does not run ruby_block move_config_to_chroot' do + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with(vals['config_dir']).and_return(true) + expect(chef_run).to_not run_ruby_block('move_config_to_chroot') + end + + it 'links bind config from chroot' do + expect(chef_run).to create_link(vals['config_dir']).with( + to: "/var/run/bind#{vals['config_dir']}" + ) + end + + it "does not create directory /var/run/bind#{vals['zones_dir']}" do + expect(chef_run).to_not create_directory("/var/run/bind#{vals['zones_dir']}") + end + + it 'does not link bind zones from chroot' do + expect(chef_run).to_not create_link(vals['zones_dir']).with( + to: "/var/run/bind#{vals['zones_dir']}" + ) + end + + it 'creates directory /var/run/bind/dev' do + expect(chef_run).to create_directory('/var/run/bind/dev').with( + user: vals['user'], + group: vals['group'], + mode: 0744, + recursive: true + ) + end + + it 'creates special device files' do + expect(chef_run).to run_execute('create_special_device_files') + end + + it 'does not create special device files' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) + expect(chef_run).to_not run_execute('create_special_device_files') + end + + end + end + end +end + diff --git a/spec/unit/recipes_spec/server_spec.rb b/spec/unit/recipes_spec/server_spec.rb new file mode 100644 index 0000000..ae3cfbf --- /dev/null +++ b/spec/unit/recipes_spec/server_spec.rb @@ -0,0 +1,341 @@ +require 'spec_helper' + +ChefSpec::Coverage.start! do + add_filter '*/bind9-chroot/recipes/chroot.rb' +end + +describe 'bind9-chroot::server' do + platforms = { + 'ubuntu' => { + 'versions' => ['12.04'], + 'package' => 'bind9', + 'service' => 'bind9', + 'user' => 'bind', + 'group' => 'bind', + 'data_dir' => '/var/cache/bind', + 'log_dir' => '/var/log/named', + 'zones_dir' => '/etc/bind/zones', + 'named_options' => '/etc/bind/named.conf.options', + 'named_conf' => '/etc/bind/named.conf', + 'named_local' => '/etc/bind/named.conf.local' + + }, + 'centos' => { + 'versions' => ['6.5'], + 'package' => 'bind', + 'service' => 'named', + 'user' => 'named', + 'group' => 'named', + 'data_dir' => '/var/named', + 'log_dir' => '/var/log/named', + 'zones_dir' => '/var/named/zones', + 'named_options' => '/etc/named/named.conf.options', + 'named_conf' => '/etc/named/named.conf', + 'named_local' => '/etc/named/named.conf.local' + + } + } + let(:zones) { [ + { + 'domain' => 'example.com', + 'type' => 'master', + 'allow_transfer' => [ + '192.168.1.2', + '192.168.1.3' + ], + 'also_notify' => [ + '192.168.1.2', + '192.168.1.3' + ], + 'zone_info' => { + 'serial' =>'00000', + 'soa' => 'ns.example.com', + 'contact' => 'root.example.com', + 'global_ttl' => 300, + 'nameserver' => [ + 'ns1.example.com', + 'ns2.example.com' + ], + 'mail_exchange' => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM', + 'priority' => 10, + } + ], + 'records' => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + }, + { + 'domain' => 'example.net', + 'type' => 'slave', + 'masters' => [ + '192.168.1.1' + ] + } + ] + } + let(:zone_file) { '$TTL 300 +@ IN SOA ns.example.com. root.example.com. ( + <%= @serial %> ; serial [yyyyMMddNN] + 4H ; refresh + 30M ; retry + 1W ; expiry + 1D ; minimum +) + + IN NS ns.example.com. + IN NS ns1.example.com. + IN NS ns2.example.com. + + IN MX 10 ASPMX.L.GOOGLE.COM. + +www IN A 127.0.0.1 +' + } + + platforms.each do |platform,vals| + vals['versions'].each do |version| + context "On #{platform} #{version}" do + let(:chef_run) do + ChefSpec::Runner.new(:platform=>platform,:version=>version) do |node| + node.set[:bind9][:zones] = zones + end.converge(described_recipe) + end + + let(:named_conf_local) { "// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include \"/etc/bind/zones.rfc1918\"; + +zone \"example.com\" { + type master; + file \"#{vals['zones_dir']}/db.example.com\"; + allow-transfer { + 192.168.1.2; + 192.168.1.3; + }; + also-notify { + 192.168.1.2; + 192.168.1.3; + }; +}; + +zone \"example.net\" { + type slave; + file \"db.example.net\"; + masters { + 192.168.1.1; + }; +};" + } + + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + end + + it "installs #{vals['package']}" do + expect(chef_run).to install_package(vals['package']) + end + + it "enables #{vals['service']} service" do + expect(chef_run).to enable_service(vals['service']) + end + + it "creates directory #{vals['data_dir']} owned by #{vals['user']} user" do + expect(chef_run).to create_directory(vals['data_dir']).with( + user: vals['user'], + group: vals['group'], + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/run/bind#{vals['data_dir']} owned by #{vals['user']} user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory("/var/run/bind#{vals['data_dir']}").with( + user: vals['user'], + group: vals['group'], + mode: 0755, + recursive: true + ) + end + + it "creates directory #{vals['log_dir']} owned by #{vals['user']} user" do + expect(chef_run).to create_directory(vals['log_dir']).with( + user: vals['user'], + group: vals['group'], + mode: 0755, + recursive: true + ) + end + + it "creates directory /var/run/bind#{vals['log_dir']} owned by #{vals['user']} user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory("/var/run/bind#{vals['log_dir']}").with( + user: vals['user'], + group: vals['group'], + mode: 0755, + recursive: true + ) + end + + it "creates directory #{vals['zones_dir']} owned by #{vals['user']} user" do + expect(chef_run).to create_directory(vals['zones_dir']).with( + user: vals['user'], + group: vals['group'], + mode: 0744, + recursive: true + ) + end + + it "creates directory /var/run/bind#{vals['zones_dir']} owned by #{vals['user']} user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory("/var/run/bind#{vals['zones_dir']}").with( + user: vals['user'], + group: vals['group'], + mode: 0744, + recursive: true + ) + end + + it 'does not include bind9-chroot::chroot recipe' do + expect(chef_run).to_not include_recipe('bind9-chroot::chroot') + end + + it 'includes bind9-chroot::chroot recipe' do + chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('bind9-chroot::chroot') + end + + it 'does not include resolvconf recipe' do + expect(chef_run).to_not include_recipe('resolvconf') + end + + it 'includes resolvconf recipe' do + chef_run.node.set[:bind9][:resolvconf] = true + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('resolvconf') + end + + it "creates template #{vals['named_options']}" do + expect(chef_run).to create_template(vals['named_options']).with( + user: vals['user'], + group: vals['group'], + mode: 0644, + ) + end + + it "creates template #{vals['named_conf']}" do + expect(chef_run).to create_template(vals['named_conf']).with( + user: vals['user'], + group: vals['group'], + mode: 0644, + ) + end + + it "#{vals['named_conf']} notifies #{vals['service']} to restart" do + expect(chef_run.template(vals['named_conf'])).to notify("service[#{vals['service']}]").to(:restart) + end + + it "creates #{vals['named_local']}" do + expect(chef_run).to create_template(vals['named_local']).with( + user: vals['user'], + group: vals['group'], + mode: 0644, + variables: { :zonefiles => Zones } + ) + end + + it "fills #{vals['named_local']} with correct content" do + expect(chef_run).to render_file(vals['named_local']).with_content(named_conf_local) + end + + it "#{vals['named_local']} notifies bind9 to restart" do + expect(chef_run.template(vals['named_local'])).to notify("service[#{vals['service']}]").to(:restart) + end + + if platform == 'ubuntu' + it 'creates /etc/default/bind9' do + expect(chef_run).to create_template('/etc/default/bind9').with( + user: vals['user'], + group: vals['group'], + mode: 0644, + ) + end + + it '/etc/default/bind9 notifies bind9 to restart' do + expect(chef_run.template('/etc/default/bind9')).to notify("service[#{vals['service']}]").to(:restart) + end + end + + it "does not create #{vals['zones_dir']}/db.example.com" do + expect(chef_run).to_not create_template("#{vals['zones_dir']}/db.example.com").with( + source: '/etc/bind/zones/example.com.erb', + local: true, + user: vals['user'], + group: vals['group'], + mode: 0644, + variables: { :serial => '00000' } + ) + end + + it "creates #{vals['zones_dir']}/db.example.com.erb" do + expect(chef_run).to create_template("#{vals['zones_dir']}/db.example.com.erb").with( + source: 'zonefile.erb', + user: vals['user'], + group: vals['group'], + mode: 0644, + variables: { + :soa => 'ns.example.com', + :contact => 'root.example.com', + :global_ttl => 300, + :nameserver => [ + 'ns1.example.com', + 'ns2.example.com' + ], + :mail_exchange => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM', + 'priority' => 10 + } + ], + :records => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] + } + ) + end + + it "fills #{vals['zones_dir']}/db.example.com.erb with correct content" do + expect(chef_run).to render_file("#{vals['zones_dir']}/db.example.com.erb").with_content(zone_file) + end + + it "notifies #{vals['zones_dir']}/db.example.com immediately" do + expect(chef_run.template("#{vals['zones_dir']}/db.example.com.erb")).to notify("template[#{vals['zones_dir']}/db.example.com]").to(:create).immediately + end + + it "does not create #{vals['zones_dir']}/db.example.net.erb" do + expect(chef_run).to_not create_template("#{vals['zones_dir']}/db.example.net.erb") + end + end + end + end +end diff --git a/spec/unit/recipes_spec/ubuntu/12.04/chroot_spec.rb b/spec/unit/recipes_spec/ubuntu/12.04/chroot_spec.rb deleted file mode 100644 index 3bdbf6c..0000000 --- a/spec/unit/recipes_spec/ubuntu/12.04/chroot_spec.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'spec_helper' - -ChefSpec::Coverage.start! - -describe 'bind9-chroot::chroot' do - context 'Ubuntu 12.04' do - let(:chef_run) do - ChefSpec::Runner.new(:platform=>'ubuntu',:version=>'12.04') do |node| - node.set[:bind9][:chroot_dir] = '/var/run/bind' - end.converge(described_recipe) - end - - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) - File.stub(:directory?).with(anything).and_call_original - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) - end - - it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do - expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') - end - - it 'does not run ruby_block copy_openssl_dependencies when /usr/lib/x86_64-linux-gnu/openssl-1.0.0 does not exist' do - File.stub(:directory?).with('/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) - expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') - end - - it 'runs ruby_block copy_openssl_dependencies' do - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) - expect(chef_run).to run_ruby_block('copy_openssl_dependencies') - end - - it 'creates directory /var/run/bind/var/run/named' do - expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - - it 'runs ruby_block modify_init_script' do - expect(chef_run).to run_ruby_block('modify_init_script') - end - - it 'does not run ruby_block modify_init_script' do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) - expect(chef_run).to_not run_ruby_block('modify_init_script') - end - - it "creates directory /var/run/bind/etc/bind" do - expect(chef_run).to create_directory("/var/run/bind/etc/bind").with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - - it 'runs ruby_block move_config_to_chroot' do - File.stub(:symlink?).with(anything).and_call_original - File.stub(:symlink?).with('/etc/bind').and_return(false) - expect(chef_run).to run_ruby_block('move_config_to_chroot') - end - - it 'does not run ruby_block move_config_to_chroot' do - File.stub(:symlink?).with(anything).and_call_original - File.stub(:symlink?).with('/etc/bind').and_return(true) - expect(chef_run).to_not run_ruby_block('move_config_to_chroot') - end - - it 'links bind config from chroot' do - expect(chef_run).to create_link('/etc/bind').with( - to: "/var/run/bind/etc/bind" - ) - end - - it "does not create directory /var/run/bind/etc/bind/zones" do - expect(chef_run).to_not create_directory("/var/run/bind/etc/bind/zones") - end - - it 'does not link bind zones from chroot' do - expect(chef_run).to_not create_link('/etc/bind/zones').with( - to: "/var/run/bind/etc/bind/zones" - ) - end - - it 'creates directory /var/run/bind/dev' do - expect(chef_run).to create_directory('/var/run/bind/dev').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - - it 'creates special device files' do - expect(chef_run).to run_execute('create_special_device_files') - end - - it 'does not create special device files' do - File.stub(:exists?).with(anything).and_call_original - File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) - expect(chef_run).to_not run_execute('create_special_device_files') - end - - end -end - diff --git a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb b/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb deleted file mode 100644 index 851d809..0000000 --- a/spec/unit/recipes_spec/ubuntu/12.04/server_spec.rb +++ /dev/null @@ -1,260 +0,0 @@ -require 'spec_helper' - -ChefSpec::Coverage.start! do - add_filter '*/bind9-chroot/recipes/chroot.rb' -end - -describe 'bind9-chroot::server' do - context 'Ubuntu 12.04' do - let(:chef_run) do - ChefSpec::Runner.new(:platform=>'ubuntu',:version=>'12.04') do |node| - node.set[:bind9][:zones] = Zones - end.converge(described_recipe) - end - - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) - end - - it "installs bind9" do - expect(chef_run).to install_package('bind9') - end - - it "enables bind9 service" do - expect(chef_run).to enable_service('bind9') - end - - it "creates directory /var/cache/bind owned by bind user" do - expect(chef_run).to create_directory('/var/cache/bind').with( - user: 'bind', - group: 'bind', - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/run/bind/var/cache/bind owned by bind user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/var/cache/bind').with( - user: 'bind', - group: 'bind', - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/log/named owned by bind user" do - expect(chef_run).to create_directory('/var/log/named').with( - user: 'bind', - group: 'bind', - mode: 0755, - recursive: true - ) - end - - it "creates directory /var/run/bind/var/log/named owned by bind user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/var/log/named').with( - user: 'bind', - group: 'bind', - mode: 0755, - recursive: true - ) - end - - it "creates directory /etc/bind/zones owned by bind user" do - expect(chef_run).to create_directory('/etc/bind/zones').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - - it "creates directory /var/run/bind/etc/bind/zones owned by bind user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory('/var/run/bind/etc/bind/zones').with( - user: 'bind', - group: 'bind', - mode: 0744, - recursive: true - ) - end - - it 'does not include bind9-chroot::chroot recipe' do - expect(chef_run).to_not include_recipe('bind9-chroot::chroot') - end - - it 'includes bind9-chroot::chroot recipe' do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('bind9-chroot::chroot') - end - - - it 'does not include resolvconf recipe' do - expect(chef_run).to_not include_recipe('resolvconf') - end - - it 'includes resolvconf recipe' do - chef_run.node.set[:bind9][:resolvconf] = true - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('resolvconf') - end - - it "creates template /etc/bind/named.conf.options" do - expect(chef_run).to create_template('/etc/bind/named.conf.options').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) - end - - it "creates template /etc/bind/named.conf" do - expect(chef_run).to create_template('/etc/bind/named.conf').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) - end - - it "/etc/bind/named.conf notifies bind9 to restart" do - expect(chef_run.template('/etc/bind/named.conf')).to notify('service[bind9]').to(:restart) - end - - it "creates /etc/bind/named.conf.local" do - expect(chef_run).to create_template('/etc/bind/named.conf.local').with( - user: 'bind', - group: 'bind', - mode: 0644, - variables: { :zonefiles => Zones } - ) - end - - it 'fills /etc/bind/named.conf.local with correct content' do - expect(chef_run).to render_file('/etc/bind/named.conf.local').with_content( -'// -// Do any local configuration here -// - -// Consider adding the 1918 zones here, if they are not used in your -// organization -//include "/etc/bind/zones.rfc1918"; - -zone "example.com" { - type master; - file "/etc/bind/zones/db.example.com"; - allow-transfer { - 192.168.1.2; - 192.168.1.3; - }; - also-notify { - 192.168.1.2; - 192.168.1.3; - }; -}; - -zone "example.net" { - type slave; - file "db.example.net"; - masters { - 192.168.1.1; - }; -};' - ) - end - - it "/etc/bind/named.conf.local notifies bind9 to restart" do - expect(chef_run.template('/etc/bind/named.conf.local')).to notify('service[bind9]').to(:restart) - end - - it 'creates /etc/default/bind9' do - expect(chef_run).to create_template('/etc/default/bind9').with( - user: 'bind', - group: 'bind', - mode: 0644, - ) - end - - it '/etc/default/bind9 notifies bind9 to restart' do - expect(chef_run.template('/etc/default/bind9')).to notify('service[bind9]').to(:restart) - end - - it "does not create /etc/bind/zones/db.example.com" do - expect(chef_run).to_not create_template('/etc/bind/zones/db.example.com').with( - source: '/etc/bind/zones/example.com.erb', - local: true, - user: 'bind', - group: 'bind', - mode: 0644, - variables: { :serial => '00000' } - ) - end - - it "creates /etc/bind/zones/db.example.com.erb" do - expect(chef_run).to create_template('/etc/bind/zones/db.example.com.erb').with( - source: 'zonefile.erb', - user: 'bind', - group: 'bind', - mode: 0644, - variables: { - :soa => 'ns.example.com', - :contact => 'root.example.com', - :global_ttl => 300, - :nameserver => [ - 'ns1.example.com', - 'ns2.example.com' - ], - :mail_exchange => [ - { - 'host' => 'ASPMX.L.GOOGLE.COM', - 'priority' => 10 - } - ], - :records => [ - { - 'name' => 'www', - 'type' => 'A', - 'ip' => '127.0.0.1' - } - ] - } - ) - end - - it 'fills /etc/bind/zones/db.example.com.erb with correct content' do - expect(chef_run).to render_file('/etc/bind/zones/db.example.com.erb').with_content( -'$TTL 300 -@ IN SOA ns.example.com. root.example.com. ( - <%= @serial %> ; serial [yyyyMMddNN] - 4H ; refresh - 30M ; retry - 1W ; expiry - 1D ; minimum -) - - IN NS ns.example.com. - IN NS ns1.example.com. - IN NS ns2.example.com. - - IN MX 10 ASPMX.L.GOOGLE.COM. - -www IN A 127.0.0.1 -' - ) - end - - it "notifies /etc/bind/zones/db.example.com immediately" do - expect(chef_run.template('/etc/bind/zones/db.example.com.erb')).to notify("template[/etc/bind/zones/db.example.com]").to(:create).immediately - end - - it "does not create /etc/bind/zones/db.example.net.erb" do - expect(chef_run).to_not create_template('/etc/bind/zones/db.example.net.erb') - end - - end -end From b51e5a19b578095b3b79ff7f656ff3c1c8b90b75 Mon Sep 17 00:00:00 2001 From: bradkwadsworth Date: Tue, 13 May 2014 12:21:43 -0500 Subject: [PATCH 15/15] edited chefspec tests, created serverspec tests, modified recipes and templates to fixes errors from tests --- .kitchen.yml | 2 +- recipes/chroot.rb | 53 ++- recipes/server.rb | 66 +-- spec/unit/recipes_spec/chroot_spec.rb | 76 ++-- spec/unit/recipes_spec/server_spec.rb | 400 ++++++++++-------- templates/default/local.usr.sbin.named.erb | 16 + templates/default/named.conf.local.erb | 4 +- templates/default/zonefile.erb | 3 +- .../chroot/serverspec/bind9_service_spec.rb | 139 ++++++ .../chroot/serverspec/spec_helper.rb | 11 + .../default/serverspec/bind9_service_spec.rb | 131 +++--- .../default/serverspec/spec_helper.rb | 2 +- 12 files changed, 584 insertions(+), 319 deletions(-) create mode 100644 templates/default/local.usr.sbin.named.erb create mode 100644 test/integration/chroot/serverspec/bind9_service_spec.rb create mode 100644 test/integration/chroot/serverspec/spec_helper.rb diff --git a/.kitchen.yml b/.kitchen.yml index a009168..76df55f 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -66,7 +66,7 @@ suites: - recipe[bind9-chroot::default] attributes: { 'bind9': { - 'chroot_dir' => true, + 'chroot_dir': '/var/chroot/named', 'zones': [ { 'domain':'example.com', diff --git a/recipes/chroot.rb b/recipes/chroot.rb index e13d9a0..1d99d2c 100644 --- a/recipes/chroot.rb +++ b/recipes/chroot.rb @@ -17,17 +17,42 @@ # case node[:platform] - when "ubuntu" - if node[:platform_version].to_f >= 12.04 - ruby_block "copy_openssl_dependencies" do - block do - FileUtils.mkdir_p File.dirname(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) - FileUtils.cp_r node[:bind9][:openssl], File.dirname(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) - end - not_if { ::File.directory?(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) or - !::File.directory?(node[:bind9][:openssl]) } +when "ubuntu" + if node[:platform_version].to_f >= 12.04 + ruby_block "copy_openssl_dependencies" do + block do + FileUtils.mkdir_p File.dirname(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) + FileUtils.cp_r node[:bind9][:openssl], File.dirname(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) end + not_if { ::File.directory?(File.join(node[:bind9][:chroot_dir], node[:bind9][:openssl])) or + !::File.directory?(node[:bind9][:openssl]) } end + end + + ruby_block "modify_init_script" do + block do + rc = Chef::Util::FileEdit.new("/etc/init.d/bind9") + rc.search_file_replace(Regexp.new("/var/run/named"), "${PIDDIR}") + rc.write_file + end + not_if { ::File.readlines('/etc/init.d/bind9').grep(Regexp.new("/var/run/named")).empty? } + end + + service 'apparmor' do + supports :status => true, :restart => true, :reload => true + action [:enable] + only_if { ::File.exists?("/etc/init.d/apparmor") } + end + + template "/etc/apparmor.d/local/usr.sbin.named" do + source "local.usr.sbin.named.erb" + owner 'root' + group 'root' + mode '0644' + notifies :restart, "service[apparmor]", :immediately + only_if { ::File.exists?("/etc/apparmor.d/local/usr.sbin.named") } + end + end directory "#{node[:bind9][:chroot_dir].to_s}/var/run/named" do @@ -38,16 +63,6 @@ not_if { ::File.directory?("#{node[:bind9][:chroot_dir].to_s}/var/run/named") } end - -ruby_block "modify_init_script" do - block do - rc = Chef::Util::FileEdit.new("/etc/init.d/bind9") - rc.search_file_replace(Regexp.new("/var/run/named"), "${PIDDIR}") - rc.write_file - end - not_if { ::File.readlines('/etc/init.d/bind9').grep(Regexp.new("/var/run/named")).empty? } -end - chroot_config_dir = File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:config_path]) directory chroot_config_dir do diff --git a/recipes/server.rb b/recipes/server.rb index 29609bb..4edc796 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -34,22 +34,21 @@ action [ :enable ] end -directory "#{node[:bind9][:chroot_dir].to_s}#{node[:bind9][:data_path]}" do +directory File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:data_path]) do owner node[:bind9][:user] group node[:bind9][:user] mode 0755 recursive true end -log_dir = File.dirname(node[:bind9][:log_file]) -directory "#{node[:bind9][:chroot_dir].to_s}#{log_dir}" do +directory File.dirname(File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:log_file])) do owner node[:bind9][:user] group node[:bind9][:user] mode 0755 recursive true end -directory "#{node[:bind9][:chroot_dir].to_s}#{node[:bind9][:zones_path]}" do +directory File.join(node[:bind9][:chroot_dir].to_s, node[:bind9][:zones_path]) do owner node[:bind9][:user] group node[:bind9][:user] mode 0744 @@ -72,7 +71,7 @@ class Chef::Recipe::NameServer # end end -template "#{node[:bind9][:config_path]}/#{node[:bind9][:options_file]}" do +template File.join(node[:bind9][:config_path], node[:bind9][:options_file]) do source "named.conf.options.erb" owner node[:bind9][:user] group node[:bind9][:user] @@ -80,7 +79,7 @@ class Chef::Recipe::NameServer notifies :restart, "service[bind9]" end -template "#{node[:bind9][:config_path]}/#{node[:bind9][:config_file]}" do +template File.join(node[:bind9][:config_path], node[:bind9][:config_file]) do source "named.conf.erb" owner node[:bind9][:user] group node[:bind9][:user] @@ -88,7 +87,7 @@ class Chef::Recipe::NameServer notifies :restart, "service[bind9]" end -template "#{node[:bind9][:config_path]}/#{node[:bind9][:local_file]}" do +template File.join(node[:bind9][:config_path], node[:bind9][:local_file]) do source "named.conf.local.erb" owner node[:bind9][:user] group node[:bind9][:user] @@ -99,48 +98,55 @@ class Chef::Recipe::NameServer notifies :restart, "service[bind9]" end -case node[:platform] -when 'ubuntu' - template node[:bind9][:defaults_file] do - source "bind9.erb" - owner node[:bind9][:user] - group node[:bind9][:user] - mode 0644 - notifies :restart, "service[bind9]" - not_if { node[:bind9][:defaults_file].nil? } - end +template 'defaults_file' do + path node[:bind9][:defaults_file] + source "bind9.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + notifies :restart, "service[bind9]" + not_if { node[:bind9][:defaults_file].nil? } +end + +directory 'recreate zones path' do + path node[:bind9][:zones_path] + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0744 + recursive true + not_if { ::File.directory?(node[:bind9][:zones_path]) or ::File.symlink?(node[:bind9][:zones_path]) } end -node[:bind9][:zones].each do |z| +node[:bind9][:zones].each do |zone| - if z[:type] == "master" and z[:zone_info].is_a?(Hash) - template "#{node[:bind9][:zones_path]}/db.#{z[:domain]}" do - source "#{node[:bind9][:zones_path]}/db.#{z[:domain]}.erb" + if zone[:type] == "master" and zone[:zone_info].is_a?(Hash) + template File.join(node[:bind9][:zones_path], zone[:domain]) do + source File.join(node[:bind9][:zones_path], "#{zone[:domain]}.erb") local true owner node[:bind9][:user] group node[:bind9][:user] mode 0644 notifies :restart, "service[bind9]" variables( - :serial => z[:zone_info][:serial] || Time.new.strftime("%Y%m%d%H%M%S") + :serial => zone[:zone_info][:serial] || Time.new.strftime("%Y%m%d%H%M%S") ) action :nothing end - template "#{node[:bind9][:zones_path]}/db.#{z[:domain]}.erb" do + template File.join(node[:bind9][:zones_path], "#{zone[:domain]}.erb") do source "zonefile.erb" owner node[:bind9][:user] group node[:bind9][:user] mode 0644 variables( - :soa => z[:zone_info][:soa], - :contact => z[:zone_info][:contact], - :global_ttl => z[:zone_info][:global_ttl], - :nameserver => z[:zone_info][:nameserver], - :mail_exchange => z[:zone_info][:mail_exchange], - :records => z[:zone_info][:records] + :soa => zone[:zone_info][:soa], + :contact => zone[:zone_info][:contact], + :global_ttl => zone[:zone_info][:global_ttl], + :nameserver => zone[:zone_info][:nameserver], + :mail_exchange => zone[:zone_info][:mail_exchange], + :records => zone[:zone_info][:records] ) - notifies :create, "template[#{node[:bind9][:zones_path]}/db.#{z[:domain]}]", :immediately + notifies :create, "template[#{node[:bind9][:zones_path]}/#{zone[:domain]}]", :immediately end end end diff --git a/spec/unit/recipes_spec/chroot_spec.rb b/spec/unit/recipes_spec/chroot_spec.rb index e1fe370..2316a96 100644 --- a/spec/unit/recipes_spec/chroot_spec.rb +++ b/spec/unit/recipes_spec/chroot_spec.rb @@ -17,7 +17,7 @@ context "On #{platform} #{version}" do let(:chef_run) do ChefSpec::Runner.new(:platform=>platform,:version=>version) do |node| - node.set[:bind9][:chroot_dir] = '/var/run/bind' + node.set[:bind9][:chroot_dir] = '/var/chroot/named' end.converge(described_recipe) end @@ -25,11 +25,11 @@ File.stub(:readlines).with(anything).and_call_original File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) File.stub(:directory?).with(anything).and_call_original - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) + File.stub(:directory?).with('/var/chroot/named/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(true) end if platform == 'ubuntu' - it 'does not run ruby_block copy_openssl_dependencies when /var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do + it 'does not run ruby_block copy_openssl_dependencies when /var/chroot/named/usr/lib/x86_64-linux-gnu/openssl-1.0.0 exists' do expect(chef_run).to_not run_ruby_block('copy_openssl_dependencies') end @@ -39,32 +39,56 @@ end it 'runs ruby_block copy_openssl_dependencies' do - File.stub(:directory?).with('/var/run/bind/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) + File.stub(:directory?).with('/var/chroot/named/usr/lib/x86_64-linux-gnu/openssl-1.0.0').and_return(false) expect(chef_run).to run_ruby_block('copy_openssl_dependencies') end - end - it 'creates directory /var/run/bind/var/run/named' do - expect(chef_run).to create_directory('/var/run/bind/var/run/named').with( + it 'runs ruby_block modify_init_script' do + expect(chef_run).to run_ruby_block('modify_init_script') + end + + it 'does not run ruby_block modify_init_script' do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) + expect(chef_run).to_not run_ruby_block('modify_init_script') + end + + it 'enables apparmor service' do + expect(chef_run).to enable_service('apparmor') + end + + it 'creates /etc/apparmor.d/local/usr.sbin.named' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/etc/apparmor.d/local/usr.sbin.named').and_return(true) + expect(chef_run).to create_template('/etc/apparmor.d/local/usr.sbin.named').with( + user: 'root', + group: 'root', + mode: '0644' + ) + end + + it 'does not create /etc/apparmor.d/local/usr.sbin.named' do + File.stub(:exists?).with(anything).and_call_original + File.stub(:exists?).with('/etc/apparmor.d/local/usr.sbin.named').and_return(false) + expect(chef_run).to_not create_template('/etc/apparmor.d/local/usr.sbin.named') + end + + it '/etc/apparmor.d/local/usr.sbin.named restarts apparmor service' do + expect(chef_run.template('/etc/apparmor.d/local/usr.sbin.named')).to notify('service[apparmor]').immediately + end + end + + it 'creates directory /var/chroot/named/var/run/named' do + expect(chef_run).to create_directory('/var/chroot/named/var/run/named').with( user: vals['user'], group: vals['group'], mode: 0744, recursive: true ) end - - it 'runs ruby_block modify_init_script' do - expect(chef_run).to run_ruby_block('modify_init_script') - end - it 'does not run ruby_block modify_init_script' do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['']) - expect(chef_run).to_not run_ruby_block('modify_init_script') - end - - it "creates directory /var/run/bind#{vals['config_dir']}" do - expect(chef_run).to create_directory("/var/run/bind#{vals['config_dir']}").with( + it "creates directory /var/chroot/named#{vals['config_dir']}" do + expect(chef_run).to create_directory("/var/chroot/named#{vals['config_dir']}").with( user: 'bind', group: 'bind', mode: 0744, @@ -86,22 +110,18 @@ it 'links bind config from chroot' do expect(chef_run).to create_link(vals['config_dir']).with( - to: "/var/run/bind#{vals['config_dir']}" + to: "/var/chroot/named#{vals['config_dir']}" ) end - it "does not create directory /var/run/bind#{vals['zones_dir']}" do - expect(chef_run).to_not create_directory("/var/run/bind#{vals['zones_dir']}") - end - it 'does not link bind zones from chroot' do expect(chef_run).to_not create_link(vals['zones_dir']).with( - to: "/var/run/bind#{vals['zones_dir']}" + to: "/var/chroot/named#{vals['zones_dir']}" ) end - it 'creates directory /var/run/bind/dev' do - expect(chef_run).to create_directory('/var/run/bind/dev').with( + it 'creates directory /var/chroot/named/dev' do + expect(chef_run).to create_directory('/var/chroot/named/dev').with( user: vals['user'], group: vals['group'], mode: 0744, @@ -115,7 +135,7 @@ it 'does not create special device files' do File.stub(:exists?).with(anything).and_call_original - File.stub(:exists?).with('/var/run/bind/dev/null').and_return(true) + File.stub(:exists?).with('/var/chroot/named/dev/null').and_return(true) expect(chef_run).to_not run_execute('create_special_device_files') end diff --git a/spec/unit/recipes_spec/server_spec.rb b/spec/unit/recipes_spec/server_spec.rb index ae3cfbf..a4b9a93 100644 --- a/spec/unit/recipes_spec/server_spec.rb +++ b/spec/unit/recipes_spec/server_spec.rb @@ -107,8 +107,9 @@ node.set[:bind9][:zones] = zones end.converge(described_recipe) end + let(:node) { chef_run } - let(:named_conf_local) { "// + let(:named_conf_local) { "// // Do any local configuration here // @@ -118,7 +119,7 @@ zone \"example.com\" { type master; - file \"#{vals['zones_dir']}/db.example.com\"; + file \"#{vals['zones_dir']}/example.com\"; allow-transfer { 192.168.1.2; 192.168.1.3; @@ -131,210 +132,261 @@ zone \"example.net\" { type slave; - file \"db.example.net\"; + file \"example.net\"; masters { 192.168.1.1; }; };" } - before(:each) do - File.stub(:readlines).with(anything).and_call_original - File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) - end + before(:each) do + File.stub(:readlines).with(anything).and_call_original + File.stub(:readlines).with('/etc/init.d/bind9').and_return(['/var/run/named']) + end - it "installs #{vals['package']}" do - expect(chef_run).to install_package(vals['package']) - end + it "installs #{vals['package']}" do + expect(chef_run).to install_package(vals['package']) + end - it "enables #{vals['service']} service" do - expect(chef_run).to enable_service(vals['service']) - end + it "enables #{vals['service']} service" do + expect(chef_run).to enable_service(vals['service']) + end - it "creates directory #{vals['data_dir']} owned by #{vals['user']} user" do - expect(chef_run).to create_directory(vals['data_dir']).with( - user: vals['user'], - group: vals['group'], - mode: 0755, - recursive: true - ) - end + it "creates directory #{vals['data_dir']} owned by #{vals['user']} user" do + expect(chef_run).to create_directory(vals['data_dir']).with( + user: vals['user'], + group: vals['group'], + mode: 0755, + recursive: true + ) + end - it "creates directory /var/run/bind#{vals['data_dir']} owned by #{vals['user']} user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory("/var/run/bind#{vals['data_dir']}").with( - user: vals['user'], - group: vals['group'], - mode: 0755, - recursive: true - ) - end + it "creates directory /var/chroot/named#{vals['data_dir']} owned by #{vals['user']} user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/chroot/named' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory("/var/chroot/named#{vals['data_dir']}").with( + user: vals['user'], + group: vals['group'], + mode: 0755, + recursive: true + ) + end - it "creates directory #{vals['log_dir']} owned by #{vals['user']} user" do - expect(chef_run).to create_directory(vals['log_dir']).with( - user: vals['user'], - group: vals['group'], - mode: 0755, - recursive: true - ) - end + it "creates directory #{vals['log_dir']} owned by #{vals['user']} user" do + expect(chef_run).to create_directory(vals['log_dir']).with( + user: vals['user'], + group: vals['group'], + mode: 0755, + recursive: true + ) + end - it "creates directory /var/run/bind#{vals['log_dir']} owned by #{vals['user']} user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory("/var/run/bind#{vals['log_dir']}").with( - user: vals['user'], - group: vals['group'], - mode: 0755, - recursive: true - ) - end + it "creates directory /var/chroot/named#{vals['log_dir']} owned by #{vals['user']} user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/chroot/named' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory("/var/chroot/named#{vals['log_dir']}").with( + user: vals['user'], + group: vals['group'], + mode: 0755, + recursive: true + ) + end - it "creates directory #{vals['zones_dir']} owned by #{vals['user']} user" do - expect(chef_run).to create_directory(vals['zones_dir']).with( - user: vals['user'], - group: vals['group'], - mode: 0744, - recursive: true - ) - end + it "creates directory #{vals['zones_dir']} owned by #{vals['user']} user" do + expect(chef_run).to create_directory(vals['zones_dir']).with( + user: vals['user'], + group: vals['group'], + mode: 0744, + recursive: true + ) + end - it "creates directory /var/run/bind#{vals['zones_dir']} owned by #{vals['user']} user" do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to create_directory("/var/run/bind#{vals['zones_dir']}").with( - user: vals['user'], - group: vals['group'], - mode: 0744, - recursive: true - ) - end + it "creates directory /var/chroot/named#{vals['zones_dir']} owned by #{vals['user']} user" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/chroot/named' + chef_run.converge(described_recipe) + expect(chef_run).to create_directory("/var/chroot/named#{vals['zones_dir']}").with( + user: vals['user'], + group: vals['group'], + mode: 0744, + recursive: true + ) + end - it 'does not include bind9-chroot::chroot recipe' do - expect(chef_run).to_not include_recipe('bind9-chroot::chroot') - end + it 'does not include bind9-chroot::chroot recipe' do + expect(chef_run).to_not include_recipe('bind9-chroot::chroot') + end - it 'includes bind9-chroot::chroot recipe' do - chef_run.node.set[:bind9][:chroot_dir] = '/var/run/bind' - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('bind9-chroot::chroot') - end + it 'includes bind9-chroot::chroot recipe' do + chef_run.node.set[:bind9][:chroot_dir] = '/var/chroot/named' + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('bind9-chroot::chroot') + end - it 'does not include resolvconf recipe' do - expect(chef_run).to_not include_recipe('resolvconf') - end + it 'does not include resolvconf recipe' do + expect(chef_run).to_not include_recipe('resolvconf') + end - it 'includes resolvconf recipe' do - chef_run.node.set[:bind9][:resolvconf] = true - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('resolvconf') - end + it 'includes resolvconf recipe' do + chef_run.node.set[:bind9][:resolvconf] = true + chef_run.converge(described_recipe) + expect(chef_run).to include_recipe('resolvconf') + end - it "creates template #{vals['named_options']}" do - expect(chef_run).to create_template(vals['named_options']).with( - user: vals['user'], - group: vals['group'], - mode: 0644, - ) - end + it "creates template #{vals['named_options']}" do + expect(chef_run).to create_template(vals['named_options']).with( + user: vals['user'], + group: vals['group'], + mode: 0644, + ) + end - it "creates template #{vals['named_conf']}" do - expect(chef_run).to create_template(vals['named_conf']).with( - user: vals['user'], - group: vals['group'], - mode: 0644, - ) - end + it "creates template #{vals['named_conf']}" do + expect(chef_run).to create_template(vals['named_conf']).with( + user: vals['user'], + group: vals['group'], + mode: 0644, + ) + end - it "#{vals['named_conf']} notifies #{vals['service']} to restart" do - expect(chef_run.template(vals['named_conf'])).to notify("service[#{vals['service']}]").to(:restart) - end + it "#{vals['named_conf']} notifies #{vals['service']} to restart" do + expect(chef_run.template(vals['named_conf'])).to notify("service[#{vals['service']}]").to(:restart) + end - it "creates #{vals['named_local']}" do - expect(chef_run).to create_template(vals['named_local']).with( - user: vals['user'], - group: vals['group'], - mode: 0644, - variables: { :zonefiles => Zones } - ) - end + it "creates #{vals['named_local']}" do + expect(chef_run).to create_template(vals['named_local']).with( + user: vals['user'], + group: vals['group'], + mode: 0644, + variables: { :zonefiles => Zones } + ) + end - it "fills #{vals['named_local']} with correct content" do - expect(chef_run).to render_file(vals['named_local']).with_content(named_conf_local) - end + it "fills #{vals['named_local']} with correct content" do + expect(chef_run).to render_file(vals['named_local']).with_content(named_conf_local) + end - it "#{vals['named_local']} notifies bind9 to restart" do - expect(chef_run.template(vals['named_local'])).to notify("service[#{vals['service']}]").to(:restart) - end + it "#{vals['named_local']} notifies bind9 to restart" do + expect(chef_run.template(vals['named_local'])).to notify("service[#{vals['service']}]").to(:restart) + end - if platform == 'ubuntu' - it 'creates /etc/default/bind9' do - expect(chef_run).to create_template('/etc/default/bind9').with( - user: vals['user'], - group: vals['group'], - mode: 0644, - ) - end + it 'creates /etc/default/bind9' do + if chef_run.node[:bind9][:defaults_file] + expect(chef_run).to create_template('defaults_file').with( + user: vals['user'], + group: vals['group'], + mode: 0644, + ) + end + end - it '/etc/default/bind9 notifies bind9 to restart' do - expect(chef_run.template('/etc/default/bind9')).to notify("service[#{vals['service']}]").to(:restart) - end - end + it '/etc/default/bind9 notifies bind9 to restart' do + expect(chef_run.template('defaults_file')).to notify("service[#{vals['service']}]").to(:restart) + end - it "does not create #{vals['zones_dir']}/db.example.com" do - expect(chef_run).to_not create_template("#{vals['zones_dir']}/db.example.com").with( - source: '/etc/bind/zones/example.com.erb', - local: true, - user: vals['user'], - group: vals['group'], - mode: 0644, - variables: { :serial => '00000' } - ) - end + it 'does not create /etc/default/bind9' do + if chef_run.node[:bind9][:defaults_file].nil? + expect(chef_run).to_not create_template('defaults_file').with( + user: vals['user'], + group: vals['group'], + mode: 0644, + ) + end + end - it "creates #{vals['zones_dir']}/db.example.com.erb" do - expect(chef_run).to create_template("#{vals['zones_dir']}/db.example.com.erb").with( - source: 'zonefile.erb', - user: vals['user'], - group: vals['group'], - mode: 0644, - variables: { - :soa => 'ns.example.com', - :contact => 'root.example.com', - :global_ttl => 300, - :nameserver => [ - 'ns1.example.com', - 'ns2.example.com' - ], - :mail_exchange => [ - { - 'host' => 'ASPMX.L.GOOGLE.COM', - 'priority' => 10 - } - ], - :records => [ - { - 'name' => 'www', - 'type' => 'A', - 'ip' => '127.0.0.1' + it "recreates directory #{vals['data_dir']} owned by #{vals['user']} user" do + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with(vals['zones_dir']).and_return(false) + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with(vals['zones_dir']).and_return(false) + expect(chef_run).to create_directory('recreate zones path').with( + user: vals['user'], + group: vals['group'], + mode: 0744, + recursive: true + ) + end + + it "does not recreate directory #{vals['data_dir']} owned by #{vals['user']} user" do + File.stub(:directory?).with(anything).and_call_original + File.stub(:directory?).with(vals['zones_dir']).and_return(true) + File.stub(:symlink?).with(anything).and_call_original + File.stub(:symlink?).with(vals['zones_dir']).and_return(true) + expect(chef_run).to_not create_directory('recreate zones path').with( + user: vals['user'], + group: vals['group'], + mode: 0744, + recursive: true + ) + end + + it "does not create #{vals['zones_dir']}/example.com" do + expect(chef_run).to_not create_template("#{vals['zones_dir']}/example.com").with( + source: "#{vals['zones_dir']}/example.com.erb", + local: true, + user: vals['user'], + group: vals['group'], + mode: 0644, + variables: { :serial => '00000' } + ) + end + + it "does not create /var/chroot/named#{vals['zones_dir']}/example.com" do + chef_run.node.set[:bind9][:chroot_dir] = '/var/chroot/named' + chef_run.converge(described_recipe) + expect(chef_run).to_not create_template("/var/chroot/named#{vals['zones_dir']}/example.com").with( + source: "/var/chroot/named#{vals['zones_dir']}/example.com.erb", + local: true, + user: vals['user'], + group: vals['group'], + mode: 0644, + variables: { :serial => '00000' } + ) + end + + it "creates #{vals['zones_dir']}/example.com.erb" do + expect(chef_run).to create_template("#{vals['zones_dir']}/example.com.erb").with( + source: 'zonefile.erb', + user: vals['user'], + group: vals['group'], + mode: 0644, + variables: { + :soa => 'ns.example.com', + :contact => 'root.example.com', + :global_ttl => 300, + :nameserver => [ + 'ns1.example.com', + 'ns2.example.com' + ], + :mail_exchange => [ + { + 'host' => 'ASPMX.L.GOOGLE.COM', + 'priority' => 10 + } + ], + :records => [ + { + 'name' => 'www', + 'type' => 'A', + 'ip' => '127.0.0.1' + } + ] } - ] - } - ) - end + ) + end - it "fills #{vals['zones_dir']}/db.example.com.erb with correct content" do - expect(chef_run).to render_file("#{vals['zones_dir']}/db.example.com.erb").with_content(zone_file) - end - it "notifies #{vals['zones_dir']}/db.example.com immediately" do - expect(chef_run.template("#{vals['zones_dir']}/db.example.com.erb")).to notify("template[#{vals['zones_dir']}/db.example.com]").to(:create).immediately - end + it "fills #{vals['zones_dir']}/example.com.erb with correct content" do + expect(chef_run).to render_file("#{vals['zones_dir']}/example.com.erb").with_content(zone_file) + end + + it "notifies #{vals['zones_dir']}/example.com immediately" do + expect(chef_run.template("#{vals['zones_dir']}/example.com.erb")).to notify("template[#{vals['zones_dir']}/example.com]").to(:create).immediately + end + + it "does not create #{vals['zones_dir']}/example.net.erb" do + expect(chef_run).to_not create_template("#{vals['zones_dir']}/example.net.erb") + end - it "does not create #{vals['zones_dir']}/db.example.net.erb" do - expect(chef_run).to_not create_template("#{vals['zones_dir']}/db.example.net.erb") - end end end end diff --git a/templates/default/local.usr.sbin.named.erb b/templates/default/local.usr.sbin.named.erb new file mode 100644 index 0000000..f9856bb --- /dev/null +++ b/templates/default/local.usr.sbin.named.erb @@ -0,0 +1,16 @@ +# Site-specific additions and overrides for usr.sbin.named. +# For more details, please see /etc/apparmor.d/local/README. + +# named chroot +/var/chroot/named/** r, +/var/chroot/named/etc/bind/** r, +/var/chroot/named/var/lib/bind/ rw, +/var/chroot/named/var/lib/bind/** rw, +/var/chroot/named/var/cache/bind/ rw, +/var/chroot/named/var/cache/bind/** rw, +/var/chroot/named/var/log/named/** rw, + +/var/chroot/named/var/run/named/named.pid w, +/var/chroot/named/var/run/named/session.key w, + +/var/chroot/named/usr/lib/x86_64-linux-gnu/openssl-1.0.0/engines/libgost.so rm, diff --git a/templates/default/named.conf.local.erb b/templates/default/named.conf.local.erb index 07f4177..2b06f98 100644 --- a/templates/default/named.conf.local.erb +++ b/templates/default/named.conf.local.erb @@ -11,7 +11,7 @@ zone "<%= conf['domain'] %>" { type <%= conf['type'] %>; <% if conf['type'] == "master" %> - file "<%= node[:bind9][:zones_path] %>/db.<%= conf["domain"] %>"; + file "<%= node[:bind9][:chroot_dir] %><%= node[:bind9][:zones_path] %>/<%= conf["domain"] %>"; <% if conf['allow_transfer'].is_a?(Array) %> allow-transfer { <% conf['allow_transfer'].each do |ip| -%> @@ -27,7 +27,7 @@ zone "<%= conf['domain'] %>" { }; <% end %> <% elsif conf['type'] == "slave" -%> - file "db.<%= conf["domain"] %>"; + file "<%= conf["domain"] %>"; masters { <% conf['masters'].each do |ip| -%> <%= ip %>; diff --git a/templates/default/zonefile.erb b/templates/default/zonefile.erb index 4b85064..1f6469a 100644 --- a/templates/default/zonefile.erb +++ b/templates/default/zonefile.erb @@ -17,6 +17,5 @@ $TTL <%= @global_ttl %> <% end %> <% @records.each do |record| -%> -<%= "%-20s %5s IN %5s %s" % [record['name'],record['ttl'],record['type'], - (record['ip'].nil? || record['ip'].empty?)? node['ipaddress']: record['ip'] ] %> +<%= "%-20s %5s IN %5s %s" % [record['name'],record['ttl'],record['type'],(record['ip'].nil? || record['ip'].empty?)? node['ipaddress']: record['ip'] ] %> <% end %> diff --git a/test/integration/chroot/serverspec/bind9_service_spec.rb b/test/integration/chroot/serverspec/bind9_service_spec.rb new file mode 100644 index 0000000..30a7fc6 --- /dev/null +++ b/test/integration/chroot/serverspec/bind9_service_spec.rb @@ -0,0 +1,139 @@ +require 'spec_helper' + +describe port(53) do + it { should be_listening } +end + +case RSpec.configure.os[:family] +when 'Ubuntu' + + describe package('bind9') do + it { should be_installed } + end + + describe service('bind9') do + it { should be_enabled } + it { should be_running } + end + + describe file('/var/chroot/named/etc/bind/named.conf.local') do + contents = '// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; + +zone "example.com" { + type master; + file "/var/chroot/named/etc/bind/zones/example.com"; + allow-transfer { + 192.168.1.2; + 192.168.1.3; + }; + also-notify { + 192.168.1.2; + 192.168.1.3; + }; +}; + +zone "example.net" { + type slave; + file "example.net"; + masters { + 192.168.1.1; + }; +};' + it { should be_file } + its(:content) {should match contents } + end + + describe file('/var/chroot/named/etc/bind/zones/example.com') do + contents = '\$TTL 300 +@ IN SOA ns.example.com. root.example.com. \( + 00000 \; serial \[yyyyMMddNN\] + 4H \; refresh + 30M \; retry + 1W \; expiry + 1D \; minimum +\) + + IN NS ns.example.com. + IN NS ns1.example.com. + IN NS ns2.example.com. + + IN MX 10 ASPMX.L.GOOGLE.COM. + +www IN A 127.0.0.1' + + it { should be_file } + its(:content) { should match contents } + end + +else + + describe package('bind') do + it { should be_installed } + end + + describe service('named') do + it { should be_enabled } + it { should be_running } + end + + describe file('/var/chroot/named/etc/named/named.conf.local') do + contents = '// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; + +zone "example.com" { + type master; + file "/var/chroot/named/var/named/zones/example.com"; + allow-transfer { + 192.168.1.2; + 192.168.1.3; + }; + also-notify { + 192.168.1.2; + 192.168.1.3; + }; +}; + +zone "example.net" { + type slave; + file "example.net"; + masters { + 192.168.1.1; + }; +};' + it { should be_file } + its(:content) {should match contents } + end + + describe file('/var/chroot/named/var/named/zones/example.com') do + content = '\$TTL 300 +@ IN SOA ns.example.com. root.example.com. \( + 00000 \; serial \[yyyyMMddNN\] + 4H \; refresh + 30M \; retry + 1W \; expiry + 1D \; minimum +\) + + IN NS ns.example.com. + IN NS ns1.example.com. + IN NS ns2.example.com. + + IN MX 10 ASPMX.L.GOOGLE.COM. + +www IN A 127.0.0.1' + it { should be_file } + its(:content) { should match content } + end + +end diff --git a/test/integration/chroot/serverspec/spec_helper.rb b/test/integration/chroot/serverspec/spec_helper.rb new file mode 100644 index 0000000..6b0a55d --- /dev/null +++ b/test/integration/chroot/serverspec/spec_helper.rb @@ -0,0 +1,11 @@ +require 'serverspec' + +include Serverspec::Helper::Exec +include Serverspec::Helper::DetectOS + +RSpec.configure do |c| + c.before :all do + c.path = '/sbin:/usr/sbin' + c.os = backend.check_os + end +end diff --git a/test/integration/default/serverspec/bind9_service_spec.rb b/test/integration/default/serverspec/bind9_service_spec.rb index b83c82b..79ce154 100644 --- a/test/integration/default/serverspec/bind9_service_spec.rb +++ b/test/integration/default/serverspec/bind9_service_spec.rb @@ -4,34 +4,20 @@ it { should be_listening } end -describe 'check Bind sevice' do - it 'should enable and run service' do - case RSpec.configuration.os[:family] - when 'Ubuntu' - expect(service('bind9')).to be_enabled - expect(service('bind9')).to be_running - else - expect(service('named')).to be_enabled - expect(service('named')).to be_running - end +case RSpec.configure.os[:family] +when 'Ubuntu' + + describe package('bind9') do + it { should be_installed } end -end -describe 'named.conf.local' do - it 'should exist' do - case RSpec.configuration.os[:family] - when 'Ubuntu' - expect(file('/etc/bind/named.conf.local')).to be_file - else - expect(file('/etc/named/named.conf.local')).to be_file - end + describe service('bind9') do + it { should be_enabled } + it { should be_running } end - it 'should contain correct content' do - case RSpec.configuration.os[:family] - when 'Ubuntu' - expect(file('/etc/bind/named.conf.local').content).to match( -'// + describe file('/etc/bind/named.conf.local') do + contents = '// // Do any local configuration here // @@ -41,7 +27,7 @@ zone "example.com" { type master; - file "/etc/bind/zones/db.example.com"; + file "/etc/bind/zones/example.com"; allow-transfer { 192.168.1.2; 192.168.1.3; @@ -54,15 +40,50 @@ zone "example.net" { type slave; - file "db.example.net"; + file "example.net"; masters { 192.168.1.1; }; };' - ) - else - expect(file('/etc/named/named.conf.local').content).to match( -'// + it { should be_file } + its(:content) {should match contents } + end + + describe file('/etc/bind/zones/example.com') do + contents = '\$TTL 300 +@ IN SOA ns.example.com. root.example.com. \( + 00000 \; serial \[yyyyMMddNN\] + 4H \; refresh + 30M \; retry + 1W \; expiry + 1D \; minimum +\) + + IN NS ns.example.com. + IN NS ns1.example.com. + IN NS ns2.example.com. + + IN MX 10 ASPMX.L.GOOGLE.COM. + +www IN A 127.0.0.1' + + it { should be_file } + its(:content) { should match contents } + end + +else + + describe package('bind') do + it { should be_installed } + end + + describe service('named') do + it { should be_enabled } + it { should be_running } + end + + describe file('/etc/named/named.conf.local') do + contents = '// // Do any local configuration here // @@ -72,7 +93,7 @@ zone "example.com" { type master; - file "/var/named/zones/db.example.com"; + file "/var/named/zones/example.com"; allow-transfer { 192.168.1.2; 192.168.1.3; @@ -85,48 +106,34 @@ zone "example.net" { type slave; - file "db.example.net"; + file "example.net"; masters { 192.168.1.1; }; };' - ) - end - end -end - -describe 'db.example.com' do - it 'should exist' do - case RSpec.configuration.os[:family] - when 'Ubuntu' - expect(file('/etc/bind/zones/db.example.com')).to be_file - else - expect(file('/var/named/zones/db.example.com')).to be_file - end + it { should be_file } + its(:content) {should match contents } end - it 'should contain correct content' do - case RSpec.configuration.os[:family] - when 'Ubuntu' - expect(file('/etc/bind/zones/db.example.com').content).to match( -'$TTL 300 -@ IN SOA ns.example.com. root.example.com. ( - 0000 ; serial [yyyyMMddNN] - 4H ; refresh - 30M ; retry - 1W ; expiry - 1D ; minimum -) + describe file('/var/named/zones/example.com') do + content = '\$TTL 300 +@ IN SOA ns.example.com. root.example.com. \( + 00000 \; serial \[yyyyMMddNN\] + 4H \; refresh + 30M \; retry + 1W \; expiry + 1D \; minimum +\) IN NS ns.example.com. IN NS ns1.example.com. - IN NS ns2.example.com. + IN NS ns2.example.com. IN MX 10 ASPMX.L.GOOGLE.COM. www IN A 127.0.0.1' - ) -# else - end - end + it { should be_file } + its(:content) { should match content } + end + end diff --git a/test/integration/default/serverspec/spec_helper.rb b/test/integration/default/serverspec/spec_helper.rb index 541a08f..6b0a55d 100644 --- a/test/integration/default/serverspec/spec_helper.rb +++ b/test/integration/default/serverspec/spec_helper.rb @@ -6,6 +6,6 @@ RSpec.configure do |c| c.before :all do c.path = '/sbin:/usr/sbin' - c.os = backend(Serverspec::Commands::Base).check_os + c.os = backend.check_os end end