Serverspecを使ってみた（１）

Resource Typeの追加について追記しました。（2018/09/09追記）

# 前書き 
今更ながら感がありますが、Serverspecを使ってみました。

# 目的
- サーバ構築にて標準的に必要な単体テストにおいて、Serverspecがどれだけ使えるものかを確認する。（ここで言う標準的とは、あくまで私個人の業務にて標準的という意味です。）

# Serverspecを使う上での方針
最初に決めた方針ではなく、使っているうちにこれが良いじゃないかと思った方針です。
- できるだけ標準のリソースタイプだけを使う
  [Resource Types](https://serverspec.org/resource_types.html)
- 逆に言うと、どこでカスタマイズしたリソースタイプが必要かを見定める
- その上で、必要であればリソースのカスタマイズを行う
- マッチャーについても同様

# 環境
近い将来SolarisやWindowsもテスト対象として試したいが、今回はとりあえず下記の環境。
- CentOS 7.4（ゲストOS、今回のテスト対象）
- Virtualbox 5.2.18
- Vagrant 2.1.2
- macOS 10.12.6（ホストマシン、Ruby環境とServerspecを導入）
- 業務的にエビデンス取得が必須のため、下記のフォーマッタを使用
 [Serverspec でコマンド実行のエビデンスを取得](https://qiita.com/ohtsuka1317/items/984041a1b94131547a21)

# テストファイル
テスト内容を記載したspecファイルです。どんなテストをしているかは読めば分かると思います。
- 01hard_spec.rb
- 02install_spec.rb
- 03selinux_spec.rb
- 04interface_spec.rb
- 05group_spec.rb
- 06user_spec.rb

```01hard_spec.rb
require 'spec_helper'

describe command('hostname') do
  its(:stdout) { should match 'centOS7' }
end

describe command("cat /proc/cpuinfo | grep 'cpu cores' ") do
  its(:stdout) { should match '1' }
end

describe command("cat /proc/meminfo | grep 'MemTotal'") do
  its(:stdout) { should match /500152/ }
end

describe command('cat /etc/redhat-release') do
  its(:stdout) { should match 'CentOS Linux release 7.4.1708 \(Core\)' }
end

describe command('uname -a') do
  its(:stdout) { should match 'Linux centOS7 3.10.0-693.2.1.el7.x86_64' }
end
```


"Locale" と "Timezone" の Resource Typeを追加しています。
詳しくは[こちら](
https://qiita.com/ttjhykw2/items/0fa3e44222405ddf0b66) を参照してください。

```02install_spec.rb
require 'spec_helper'

describe locale('System Locale') do
  its(:value) { should eq 'LANG=ja_JP.utf8' }
end

# Keyboard layout mapping
describe locale('VC Keymap') do
  its(:value) { should eq 'jp106' }
end

# Time Zone
describe timezone do
  its(:value) { should eq "Asia\/Tokyo" }
end

# Swap device
describe command('swapon -s') do
  its(:stdout) { should match /\/dev\/dm-1/ }
end
```

```03selinux_spec.rb
require 'spec_helper'

# SELinux should be disabled
describe selinux do
  it { should be_disabled }
end
```

```04interface_spec.rb
require 'spec_helper'

# Network settings

describe interface('eth0') do
  it { should exist }
end

describe interface('eth0') do
  it { should be_up }
end

describe interface('eth0') do
  its(:speed) { should eq 1000 }
end

describe interface('eth0') do
  it { should have_ipv4_address("10.0.2.15/24") }
end

describe interface('eth1') do
  it { should exist }
end

describe interface('eth1') do
  it { should be_up }
end

describe interface('eth1') do
  its(:speed) { should eq 1000 }
end

describe interface('eth1') do
  it { should have_ipv4_address("192.168.56.10/24") }
end
```

```05group_spec.rb
require 'spec_helper'

describe group('oinstall') do
  it { should exist }
end

describe group('dba') do
  it { should exist }
end

describe group('oper') do
  it { should exist }
end


describe group('oinstall') do
  it { should have_gid 1002 }
end

describe group('dba') do
  it { should have_gid 1003 }
end

describe group('oper') do
  it { should have_gid 1004 }
end

```

```06user_spec.rb
require 'spec_helper'

describe user('itadm') do
  it { should exist }
end

describe user('oracle') do
  it { should exist }
end

describe user('jobadm') do
  it { should exist }
end

describe user('webadm') do
  it { should exist }
end


describe user('itadm') do
  it { should have_uid 1002 }
end

describe user('oracle') do
  it { should have_uid 1003 }
end

describe user('jobadm') do
  it { should have_uid 1004 }
end

describe user('webadm') do
  it { should have_uid 1005 }
end


describe user('itadm') do
  it { should belong_to_primary_group 'oper' }
end

describe user('oracle') do
  it { should belong_to_primary_group 'oinstall' }
end

describe user('jobadm') do
  it { should belong_to_primary_group 'oper' }
end

describe user('webadm') do
  it { should belong_to_primary_group 'oper' }
end


describe user('itadm') do
  it { should belong_to_group 'dba' }
end

describe user('itadm') do
  it { should belong_to_group 'oinstall' }
end

describe user('oracle') do
  it { should belong_to_group 'dba' }
end

describe user('oracle') do
  it { should belong_to_group 'oper' }
end

describe user('jobadm') do
  it { should belong_to_group 'dba' }
end


describe user('root') do
  it { should have_home_directory '/root' }
end

describe user('oracle') do
  it { should have_home_directory '/home/oracle' }
end

describe user('itadm') do
  it { should have_home_directory '/home/itadm' }
end

describe user('jobadm') do
  it { should have_home_directory '/home/jobadm' }
end

describe user('webadm') do
  it { should have_home_directory '/home/webadm' }
end


describe user('root') do
  it { should have_login_shell '/bin/bash' }
end

describe user('itadm') do
  it { should have_login_shell '/bin/bash' }
end

describe user('oracle') do
  it { should have_login_shell '/bin/bash' }
end

describe user('jobadm') do
  it { should have_login_shell '/bin/bash' }
end

describe user('webadm') do
  it { should have_login_shell '/bin/bash' }
end
```

テスト実行時の画面出力

```result.txt
$ bundle exec rake spec
（略）

Command "hostname"
  stdout
    should match "centOS7"

Command "cat /proc/cpuinfo | grep 'cpu cores' "
  stdout
    should match "1"

Command "cat /proc/meminfo | grep 'MemTotal'"
  stdout
    should match /500152/

Command "cat /etc/redhat-release"
  stdout
    should match "CentOS Linux release 7.4.1708 \\(Core\\)"

Command "uname -a"
  stdout
    should match "Linux centOS7 3.10.0-693.2.1.el7.x86_64"

Locale "System Locale"
  value
    should eq "LANG=ja_JP.utf8"

Locale "VC Keymap"
  value
    should eq "jp106"

Timezone ""
  value
    should eq "Asia/Tokyo"

Command "swapon -s"
  stdout
    should match /\/dev\/dm-1/

SELinux
  should be disabled

Interface "eth0"
  should exist

Interface "eth0"
  should be up

Interface "eth0"
  speed
    should eq 1000

Interface "eth0"
  should have ipv4 address "10.0.2.15/24"

Interface "eth1"
  should exist

Interface "eth1"
  should be up

Interface "eth1"
  speed
    should eq 1000

Interface "eth1"
  should have ipv4 address "192.168.56.10/24"

Group "oinstall"
  should exist

Group "dba"
  should exist

Group "oper"
  should exist

Group "oinstall"
  should have gid 1002

Group "dba"
  should have gid 1003

Group "oper"
  should have gid 1004

User "itadm"
  should exist

User "oracle"
  should exist

User "jobadm"
  should exist

User "webadm"
  should exist

User "itadm"
  should have uid 1002

User "oracle"
  should have uid 1003

User "jobadm"
  should have uid 1004

User "webadm"
  should have uid 1005

User "itadm"
  should belong to primary group "oper"

User "oracle"
  should belong to primary group "oinstall"

User "jobadm"
  should belong to primary group "oper"

User "webadm"
  should belong to primary group "oper"

User "itadm"
  should belong to group "dba"

User "itadm"
  should belong to group "oinstall"

User "oracle"
  should belong to group "dba"

User "oracle"
  should belong to group "oper"

User "jobadm"
  should belong to group "dba"

User "root"
  should have home directory "/root"

User "oracle"
  should have home directory "/home/oracle"

User "itadm"
  should have home directory "/home/itadm"

User "jobadm"
  should have home directory "/home/jobadm"

User "webadm"
  should have home directory "/home/webadm"

User "root"
  should have login shell "/bin/bash"

User "itadm"
  should have login shell "/bin/bash"

User "oracle"
  should have login shell "/bin/bash"

User "jobadm"
  should have login shell "/bin/bash"

User "webadm"
  should have login shell "/bin/bash"

Finished in 3.73 seconds (files took 0.5301 seconds to load)
51 examples, 0 failures

$ 
```


続きはまた書きます。