連載
» 2016年08月12日 05時00分 公開

実際に検証済み!OSS徹底比較(5)サーバテスト自動化【前編】:OSSのサーバテスト自動化ツール徹底検証 2016年版 〜Serverspec編〜 (4/8)

[森元敏雄,TIS]

テストスクリプトの作成

1.対話的コンソールを有効に設定

 spec_helper.rbに対話的コンソール=有効(set :request_pty, true)の設定行を追加する。

※本設定はroot以外のユーザーでテストスクリプトを利用(sudoコマンドが実行される)場合にのみ必要

$ vi ~/serverspec/spec/spec_helper.rb
require 'Serverspec'
require 'net/ssh'
set :backend, :ssh
set :request_pty, true
if ENV['ASK_SUDO_PASSWORD']
  begin
    require 'highline/import'
  rescue LoadError
    fail "highline is not available. Try installing it."
  end
  set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false }
else
  set :sudo_password, ENV['SUDO_PASSWORD']
end
host = ENV['TARGET_HOST']
options = Net::SSH::Config.for(host)
options[:user] ||= Etc.getlogin
set :host,        options[:host_name] || host
set :ssh_options, options
# Disable sudo
# set :disable_sudo, true
# Set environment variables
# set :env, :LANG => 'C', :LC_MESSAGES => 'C' 
# Set PATH
# set :path, '/sbin:/usr/local/sbin:$PATH'

2.テストスクリプトを作成

 作成したテストスクリプトは以下となる。各処理のTIPSは後ほど、機能ごとに説明する。

テストスクリプトの構成と方針

 テストスクリプトは検証対象のプロダクトごとに1ファイルを作成している。Serverspecは~/spec/[テスト対象ホスト名]以下の*.specファイルを全て実行対象として判定する。処理もファイル名でソートされた順番に行われるため、処理してほしい順番になるよう、ファイル名の先頭に0付加2桁の連番を付与している。

 作成したテストスクリプトは以下の通り。

ファイル名 機能
1 01.packages_spec.rb パッケージの最新化と単体パッケージのインストール確認
2 02.mariadb_spec.rb mariadb-serverのインストールと設定の確認
3 03.wordpress_spec.rb WordPressのインストールと設定の確認
4 04.httpd_spec.rb httpd(Apace2) のインストールと設定の確認
5 05.firewall_spec.rb ファイアウォールの設定の確認
6 06.web_site_spec.rb WorsPressサイトへのアクセス確認

(1)パッケージチェック用のテストスクリプト(01.packages_spec.rb)

$ vi ~/serverspec/spec/tissvv096/01.packages_spec.rb
#
# packages test
#
require 'spec_helper'
# yum update check
describe command("yum check-update") do
  its(:exit_status) { should eq 0 }
end
# php/php-mysql insall check
%w{ php php-mysql }.each do |pkg|
  describe package(pkg) do
    it { should be_installed }
  end
end

(2)mariadb-server用のテストスクリプト(02.mariadb_spec.rb)

$ vi ~/serverspec/spec/tissvv096/02.mariadb_spec.rb
#
# mariadb-serer test
#
require 'spec_helper'
mysql_root_pass='FM11AD2+'
# install check
describe package('mariadb-server') do
#  it { should be_installed }
  it { should be_installed.with_version '5.5' }
end
# service check
describe service('mariadb') do
  it { should be_enabled }
  it { should be_running }
end
# Listen port check
describe port(3306) do
  it { should be_listening }
end
# root password login check
describe command("mysqlshow -u root -p#{mysql_root_pass} mysql") do
  its(:stdout) { should contain('Database') }
end
# root no password login check
describe command("mysqlshow") do
  its(:stdout) { should contain('Database') }
end
# mysqladmin ping execute check
describe command( "mysqladmin ping" ) do
  its(:stdout) { should contain('mysqld is alive') }
end
# mariadb logrotate test
already_rotate = Specinfra.backend.run_command( "sudo find /var/log/mariadb -name '*.gz' | wc -l" ).stdout.to_i
if already_rotate == 0  then
  describe command("logrotate -vf /etc/logrotate.d/mariadb") do
    its(:stdout) { should contain('running postrotate script') }
  end
else
  describe command("logrotate -vd /etc/logrotate.d/mariadb") do
    its(:stdout) { should contain('log does not need rotating') }
  end
end

(3)WordPress用のテストスクリプト(03.wordpress_spec.rb)

$ vi ~/serverspec/spec/tissvv096/03.wordpress_spec.rb
#
# WordPress test
#
require 'spec_helper'
wp_dir='/var/www/wordpress'
wp_os_user='root'
wp_os_group='root'
wp_db_name='WordPress'
wp_db_user='wp_admin'
wp_db_pass='HB-F1XDJ'
wp_uniqe_phrse='FX702PFX801PPB100FX860PPB700PB500PB750PAI1000'
wp_version='4.5.2'
hostname=host_inventory['hostname']
# WordPress version check
describe file("#{wp_dir}/readme.html") do
  it { should contain("Version #{wp_version}")  }
end
# WordPress db exists and db user login check
describe command("mysqlshow -u #{wp_db_user} -p#{wp_db_pass} #{wp_db_name}") do
  its(:stdout) { should contain("#{wp_db_name}") }
end
# wp-config.php file exits check
describe file("#{wp_dir}/wp-config.php") do
  it { should exist }
end
# wp-config.php paramaters check
describe file("#{wp_dir}/wp-config.php") do
  it { should contain("define('DB_NAME',.*'#{wp_db_name}');") }
  it { should contain("define\('DB_USER',.*'#{wp_db_user}'\);")  }
  it { should contain("define\('DB_PASSWORD',.*'#{wp_db_pass}'\);")  }
  it { should contain("define\('AUTH_KEY',.*'#{wp_uniqe_phrse}'\);")  }
  it { should contain("define\('SECURE_AUTH_KEY',.*'#{wp_uniqe_phrse}'\);")  }
  it { should contain("define\('LOGGED_IN_KEY',.*'#{wp_uniqe_phrse}'\);")  }
  it { should contain("define\('NONCE_KEY',.*'#{wp_uniqe_phrse}'\);")  }
  it { should contain("define\('AUTH_SALT',.*'#{wp_uniqe_phrse}'\);")  }
  it { should contain("define\('SECURE_AUTH_SALT',.*'#{wp_uniqe_phrse}'\);")  }
  it { should contain("define\('LOGGED_IN_SALT',.*'#{wp_uniqe_phrse}'\);")  }
  it { should contain("define\('NONCE_SALT',.*'#{wp_uniqe_phrse}'\);")  }
end
# wordpress file user/group check (each file/reject)
#wp_files = Specinfra.backend.run_command( "find #{wp_dir}" ).stdout.chop
#
#wp_files.each_line { |wp_file| 
#  describe file(wp_file.chomp) do
#    it { should be_owned_by('root') }
#    it { should be_grouped_into('root') }
#  end
#}
# wordpress file user/group check
describe command( "find #{wp_dir} -not -user #{wp_os_user} -or -not -group #{wp_os_group} | wc -l | tr -d '\n'" ) do
  its(:stdout) { should contain('^0$') }
end
# wordpress.conf exists check
describe file("/etc/httpd/conf.d/wordpress.conf") do
  it { should exist }
end
# wordpress.conf check
wordpress_conf = <<"EOT"
<VirtualHost *:80>
  ServerName #{hostname}
  DocumentRoot #{wp_dir}
  <Directory "#{wp_dir}">
    AllowOverride All
    Options -Indexes
  </Directory>
  <Files wp-config.php>
    order allow,deny
    deny from all
  </Files>
</VirtualHost>
EOT
describe file("/etc/httpd/conf.d/wordpress.conf") do
  it { should contain wordpress_conf }
end

(4)httpd用のテストスクリプト(04.httpd_spec.rb)

$ vi ~/serverspec/spec/tissvv096/04.httpd_spec.rb
#
# httpd test
#
require 'spec_helper'
hostname=host_inventory['hostname']
# httpd install check
describe package('httpd') do
  it { should be_installed }
end
# httpd.conf backup check
describe file("/etc/httpd/conf/httpd.conf.bak") do
  it { should exist }
end
# httpd.conf ServerName check
describe file("/etc/httpd/conf/httpd.conf") do
  it { should contain("ServerName #{hostname}") }
end
# httpd service check
describe service('httpd') do
  it { should be_enabled }
  it { should be_running }
end
# httpd listen port check
describe port(80) do
  it { should be_listening }
end

(5)firewall用のテストスクリプト(05.firewall_spec.rb)

$ vi ~/serverspec/spec/tissvv096/05.firewall_spec.rb
#
# firewall test
#
require 'spec_helper'
# httpd port open check
describe command("firewall-cmd --list-all --zone=public") do
  its(:stdout) { should contain('services:.*ssh') }
  its(:stdout) { should contain('services:.*http') }
  its(:stdout) { should contain('services:.*mysql') }
  its(:stdout) { should contain('ports: ') }
end

(6)WordPressサイトアクセス確認用のテストスクリプト(06.web_site_spec.rb)

$ vi ~/serverspec/spec/tissvv096/06.web_site_spec.rb
#
# wordpres web site test
#
require 'spec_helper'
hostname=host_inventory['hostname']
# httpd port open check
describe command("curl http://#{hostname}/wp-admin/install.php") do
  its(:stdout) { should contain('WordPress') }
end

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。