├── .github ├── stale.yml └── workflows │ ├── ci.yml │ └── stale.yaml ├── .gitignore ├── .gitmodules ├── .travis.yml ├── Gemfile ├── Guardfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── WINDOWS_SUPPORT.md ├── appveyor.yml ├── bin └── serverspec-init ├── lib ├── serverspec.rb └── serverspec │ ├── commands │ └── base.rb │ ├── helper.rb │ ├── helper │ └── type.rb │ ├── matcher.rb │ ├── matcher │ ├── be_enabled.rb │ ├── be_enforcing.rb │ ├── be_executable.rb │ ├── be_installed.rb │ ├── be_listening.rb │ ├── be_monitored_by.rb │ ├── be_mounted.rb │ ├── be_permissive.rb │ ├── be_reachable.rb │ ├── be_readable.rb │ ├── be_resolvable.rb │ ├── be_running.rb │ ├── be_writable.rb │ ├── belong_to_group.rb │ ├── belong_to_primary_group.rb │ ├── contain.rb │ ├── have_entry.rb │ ├── have_rule.rb │ ├── have_site_application.rb │ ├── have_site_bindings.rb │ └── have_virtual_dir.rb │ ├── power_assert.rb │ ├── setup.rb │ ├── subject.rb │ ├── type │ ├── base.rb │ ├── bond.rb │ ├── bridge.rb │ ├── cgroup.rb │ ├── command.rb │ ├── cron.rb │ ├── default_gateway.rb │ ├── docker_base.rb │ ├── docker_container.rb │ ├── docker_image.rb │ ├── file.rb │ ├── fstab.rb │ ├── group.rb │ ├── hadoop_config.rb │ ├── host.rb │ ├── iis_app_pool.rb │ ├── iis_website.rb │ ├── interface.rb │ ├── ip6tables.rb │ ├── ipfilter.rb │ ├── ipnat.rb │ ├── iptables.rb │ ├── json_file.rb │ ├── kernel_module.rb │ ├── kvm.rb │ ├── linux_audit_system.rb │ ├── linux_kernel_parameter.rb │ ├── lxc.rb │ ├── mail_alias.rb │ ├── mysql_config.rb │ ├── package.rb │ ├── php_config.rb │ ├── php_extension.rb │ ├── port.rb │ ├── ppa.rb │ ├── process.rb │ ├── routing_table.rb │ ├── selinux.rb │ ├── selinux_module.rb │ ├── service.rb │ ├── user.rb │ ├── windows_feature.rb │ ├── windows_firewall.rb │ ├── windows_hot_fix.rb │ ├── windows_registry_key.rb │ ├── windows_scheduled_task.rb │ ├── x509_certificate.rb │ ├── x509_private_key.rb │ ├── yumrepo.rb │ └── zfs.rb │ └── version.rb ├── serverspec.gemspec ├── spec ├── helper │ └── type_spec.rb ├── spec_helper.rb └── type │ ├── aix │ ├── file_spec.rb │ ├── group_spec.rb │ ├── package_spec.rb │ ├── port_spec.rb │ ├── service_spec.rb │ └── user_spec.rb │ ├── arch │ ├── file_spec.rb │ ├── package_spec.rb │ └── service_spec.rb │ ├── base │ ├── command_spec.rb │ ├── cron_spec.rb │ ├── default_gateway_spec.rb │ ├── file_spec.rb │ ├── group_spec.rb │ ├── host_spec.rb │ ├── json_file_spec.rb │ ├── mail_alias_spec.rb │ ├── mysql_config_spec.rb │ ├── package_spec.rb │ ├── php_config_spec.rb │ ├── php_extension_spec.rb │ ├── port_spec.rb │ ├── process_spec.rb │ ├── routing_table_spec.rb │ ├── service_spec.rb │ └── user_spec.rb │ ├── darwin │ ├── file_spec.rb │ ├── package_spec.rb │ ├── port_spec.rb │ └── service_spec.rb │ ├── debian │ ├── package_spec.rb │ └── service_spec.rb │ ├── fedora │ └── service_spec.rb │ ├── fedora15 │ └── service_spec.rb │ ├── fedora20 │ └── service_spec.rb │ ├── freebsd │ ├── file_spec.rb │ ├── package_spec.rb │ ├── port_spec.rb │ └── service_spec.rb │ ├── freebsd10 │ └── package_spec.rb │ ├── gentoo │ ├── package_spec.rb │ └── service_spec.rb │ ├── linux │ ├── bond_spec.rb │ ├── bridge_spec.rb │ ├── cgroup_spec.rb │ ├── docker_container_pre_1_8_spec.rb │ ├── docker_container_spec.rb │ ├── docker_image_spec.rb │ ├── file_spec.rb │ ├── fstab_spec.rb │ ├── interface_spec.rb │ ├── ip6tables_spec.rb │ ├── iptables_spec.rb │ ├── kernel_module_spec.rb │ ├── kvm_guest_spec.rb │ ├── linux_audit_system_spec.rb │ ├── linux_kernel_parameter_spec.rb │ ├── lxc_container_spec.rb │ ├── selinux_module_spec.rb │ ├── selinux_spec.rb │ ├── x509_certificate_spec.rb │ ├── x509_private_key_spec.rb │ └── zfs_spec.rb │ ├── nixos │ ├── package_spec.rb │ └── service_spec.rb │ ├── openbsd │ ├── file_spec.rb │ ├── interface_spec.rb │ ├── mail_alias_spec.rb │ ├── package_spec.rb │ ├── port_spec.rb │ ├── service_spec.rb │ └── user_spec.rb │ ├── opensuse │ └── service_spec.rb │ ├── plamo │ ├── package_spec.rb │ └── service_spec.rb │ ├── redhat │ ├── file_spec.rb │ ├── package_spec.rb │ ├── service_spec.rb │ └── yumrepo_spec.rb │ ├── redhat5 │ └── iptables_spec.rb │ ├── redhat7 │ └── service_spec.rb │ ├── smartos │ ├── package_spec.rb │ └── service_spec.rb │ ├── solaris │ ├── cron_spec.rb │ ├── file_spec.rb │ ├── group_spec.rb │ ├── host_spec.rb │ ├── ipfilter_spec.rb │ ├── ipnat_spec.rb │ ├── package_spec.rb │ ├── port_spec.rb │ ├── service_spec.rb │ ├── user_spec.rb │ └── zfs_spec.rb │ ├── solaris10 │ ├── file_spec.rb │ ├── group_spec.rb │ ├── host_spec.rb │ ├── package_spec.rb │ └── user_spec.rb │ ├── suse │ ├── package_spec.rb │ └── service_spec.rb │ ├── ubuntu │ ├── ppa_spec.rb │ └── service_spec.rb │ └── windows │ ├── command_spec.rb │ ├── feature_spec.rb │ ├── file_spec.rb │ ├── group_spec.rb │ ├── host_spec.rb │ ├── hot_fix_spec.rb │ ├── iis_app_pool_spec.rb │ ├── iis_webisite_spec.rb │ ├── package_spec.rb │ ├── port_spec.rb │ ├── registry_key_spec.rb │ ├── scheduled_task_spec.rb │ ├── service_spec.rb │ └── user_spec.rb └── wercker.yml /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | 19 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ci 3 | 4 | on: 5 | push: 6 | pull_request: 7 | types: 8 | - opened 9 | - synchronize 10 | - reopened 11 | 12 | permissions: {} 13 | 14 | jobs: 15 | ci: 16 | runs-on: ubuntu-latest 17 | strategy: 18 | fail-fast: false 19 | 20 | matrix: 21 | ruby-version: 22 | - "2.2" 23 | - "2.3" 24 | - "2.4" 25 | - "2.5" 26 | - "2.6" 27 | - "2.7" 28 | - "3.0" 29 | - "3.1" 30 | - "3.2" 31 | - "3.3" 32 | - "3.4" 33 | 34 | steps: 35 | - uses: actions/checkout@v4 36 | with: 37 | persist-credentials: false 38 | 39 | - uses: ruby/setup-ruby@v1 40 | with: 41 | ruby-version: ${{ matrix.ruby-version }} 42 | bundler-cache: true 43 | 44 | - run: bundle exec rake 45 | -------------------------------------------------------------------------------- /.github/workflows/stale.yaml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PR' 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '30 1 * * *' 6 | 7 | permissions: 8 | contents: write 9 | issues: write 10 | pull-requests: write 11 | 12 | jobs: 13 | stale: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/stale@v8 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | *.swp 4 | .bundle 5 | .rvmrc 6 | .versions.conf 7 | .config 8 | .yardoc 9 | .rspec 10 | .idea/ 11 | Gemfile.lock 12 | InstalledFiles 13 | _yardoc 14 | coverage 15 | doc/ 16 | lib/bundler/man 17 | pkg 18 | rdoc 19 | spec/reports 20 | test/tmp 21 | test/version_tmp 22 | tmp 23 | Vagrantfile 24 | vendor/ 25 | .DS_Store 26 | Gemfile.local 27 | upstream.sh 28 | 29 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "integration-test"] 2 | path = integration-test 3 | url = https://github.com/serverspec/serverspec-integration-test.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | 3 | rvm: 4 | - 1.9.3 5 | - 2.0.0 6 | - 2.1.1 7 | - 2.2.4 8 | - 2.3.6 9 | - 2.4.3 10 | - 2.5.0 11 | 12 | before_install: 13 | - travis_retry gem update --system 2.7.8 14 | - travis_retry gem install bundler -v 1.17.3 15 | - travis_retry gem uninstall -i /home/travis/.rvm/gems/ruby-2.3.7@global bundler || echo 16 | 17 | script: 18 | - bundle exec rake spec 19 | 20 | dist: trusty 21 | sudo: false 22 | cache: bundler 23 | notifications: 24 | slack: 25 | secure: X1umGErES0zd+LXX1EqZZxrPZv2YOzbCNxiLLiSGmJLlZAEtlSkMPyr+M00Lrs2DFhn4blwKPm+5YCBvU7f9F4K5GthSl0qZYNpNX/lGNn6EGeBnzJ8rFVgwXPUv1rvrJq0NjeSGni3yAK69K/uX6QohGojAI3iI28/EbJ+uYQM= 26 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in serverspec.gemspec 4 | gemspec 5 | 6 | if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') 7 | # net-ssh 3.x dropped Ruby 1.8 and 1.9 support. 8 | gem 'net-ssh', '~> 2.7' 9 | end 10 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | guard :rspec do 2 | watch(%r{^spec/.+/.+_spec\.rb$}) 3 | watch('spec/spec_helper.rb') { "spec" } 4 | end 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Gosuke Miyashita 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serverspec [![Gem Version](https://badge.fury.io/rb/serverspec.svg)](http://badge.fury.io/rb/serverspec) [![BuildStatus](https://secure.travis-ci.org/mizzy/serverspec.svg)](http://travis-ci.org/mizzy/serverspec) [![wercker status](https://app.wercker.com/status/526d1ff4df6eadaa793dca1affcaed35/s/ "wercker status")](https://app.wercker.com/project/bykey/526d1ff4df6eadaa793dca1affcaed35) 2 | 3 | RSpec tests for your servers configured by Puppet, Chef or anything else 4 | 5 | You can see the details of serverspec on [serverspec.org](http://serverspec.org/). 6 | 7 | ---- 8 | 9 | ## Running the gem's tests 10 | 11 | Use 12 | 13 | ```bundle exec rake``` 14 | 15 | (Using ```rspec``` alone will not work). 16 | 17 | 18 | 19 | ## Maintenance policy of Serverspec/Specinfra 20 | 21 | * The person who found a bug should fix the bug by themself. 22 | * If you find a bug and cannot fix it by yourself, send a pull request and attach test code to reproduce the bug, please. 23 | * The person who want a new feature should implement it by themself. 24 | * For above reasons, I accept pull requests only and disable issues. 25 | * If you'd like to discuss about a new feature before implement it, make an empty commit and send [a WIP pull request](http://ben.straub.cc/2015/04/02/wip-pull-request/). But It is better that the WIP PR has some code than an empty commit. 26 | 27 | 28 | ---- 29 | 30 | ## Contributing 31 | 32 | 1. Fork it 33 | 2. Create your feature branch (`git checkout -b my-new-feature`) 34 | 3. Commit your changes (`git commit -am 'Add some feature'`) 35 | 4. Push to the branch (`git push origin my-new-feature`) 36 | 5. Create new Pull Request 37 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | begin 3 | require "rspec/core/rake_task" 4 | require "octorelease" 5 | rescue LoadError 6 | end 7 | 8 | if defined?(RSpec) 9 | task :default => 'spec:all' 10 | task :spec => 'spec:all' 11 | 12 | namespace :spec do 13 | task :all => [ 'spec:type:all', 'spec:helper' ] 14 | 15 | namespace :type do 16 | oses = Dir.glob('spec/type/*').map {|d| File.basename(d)} 17 | 18 | task :all => oses.map {|os| "spec:type:#{os}" } 19 | 20 | oses.each do |os| 21 | RSpec::Core::RakeTask.new(os.to_sym) do |t| 22 | t.pattern = "spec/type/#{os}/*_spec.rb" 23 | end 24 | end 25 | end 26 | 27 | RSpec::Core::RakeTask.new(:helper) do |t| 28 | t.pattern = "spec/helper/*_spec.rb" 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /WINDOWS_SUPPORT.md: -------------------------------------------------------------------------------- 1 | ## Windows support 2 | 3 | Serverspec is now providing a limited support for Microsoft Windows. 4 | 5 | If you want to test Windows based machines you need to set the target host's OS explicitly in your `spec/spec_helper.rb` 6 | 7 | For local testing (equivalent to the Exec option in Linux/Unix systems) simply do: 8 | 9 | ```ruby 10 | require 'serverspec' 11 | 12 | set :backend, :cmd 13 | set :os, :family => 'windows' 14 | ``` 15 | 16 | For remote testing you have to configure Windows Remote Management in order to communicate to the target host: 17 | 18 | ```ruby 19 | require 'serverspec' 20 | require 'winrm' 21 | 22 | set :backend, :winrm 23 | set :os, :family => 'windows' 24 | 25 | user = 26 | pass = 27 | endpoint = "http://#{ENV['TARGET_HOST']}:5985/wsman" 28 | 29 | if Gem::Version.new(WinRM::VERSION) < Gem::Version.new('2') 30 | winrm = ::WinRM::WinRMWebService.new(endpoint, :ssl, :user => user, :pass => pass, :basic_auth_only => true) 31 | winrm.set_timeout 300 # 5 minutes max timeout for any operation 32 | else 33 | opts = { 34 | user: user, 35 | password: pass, 36 | endpoint: endpoint, 37 | operation_timeout: 300, 38 | no_ssl_peer_verification: false, 39 | } 40 | 41 | winrm = ::WinRM::Connection.new(opts) 42 | end 43 | 44 | Specinfra.configuration.winrm = winrm 45 | ``` 46 | 47 | For how to configure the guest to accept WinRM connections and the different authentication mechanisms check the Microsoft WinRM documentation and verify the ones that are supported by [WinRb/WinRM](https://github.com/WinRb/WinRM). 48 | 49 | 50 | ###RSpec Examples for windows target hosts 51 | ```ruby 52 | describe file('c:/windows') do 53 | it { should be_directory } 54 | it { should be_readable } 55 | it { should_not be_writable.by('Everyone') } 56 | end 57 | 58 | describe file('c:/temp/test.txt') do 59 | it { should be_file } 60 | it { should contain "some text" } 61 | end 62 | 63 | describe package('Adobe AIR') do 64 | it { should be_installed} 65 | end 66 | 67 | describe service('DNS Client') do 68 | it { should be_installed } 69 | it { should be_enabled } 70 | it { should be_running } 71 | it { should have_start_mode("Manual") } 72 | end 73 | 74 | describe port(139) do 75 | it { should be_listening } 76 | end 77 | 78 | describe user('some.admin') do 79 | it { should exist } 80 | it { should belong_to_group('Administrators')} 81 | end 82 | 83 | describe group('Guests') do 84 | it { should exist } 85 | end 86 | 87 | describe group('MYDOMAIN\Domain Users') do 88 | it { should exist } 89 | end 90 | 91 | describe command('& "ipconfig"') do 92 | its(:stdout) { should match /IPv4 Address(\.| )*: 192\.168\.1\.100/ } 93 | end 94 | 95 | describe windows_registry_key('HKEY_USERS\S-1-5-21-1319311448-2088773778-316617838-32407\Test MyKey') do 96 | it { should exist } 97 | it { should have_property('string value') } 98 | it { should have_property('binary value', :type_binary) } 99 | it { should have_property('dword value', :type_dword) } 100 | it { should have_value('test default data') } 101 | it { should have_property_value('multistring value', :type_multistring, "test\nmulti\nstring\ndata") } 102 | it { should have_property_value('qword value', :type_qword, 'adff32') } 103 | it { should have_property_value('binary value', :type_binary, 'dfa0f066') } 104 | end 105 | 106 | describe windows_feature('Minesweeper') do 107 | it{ should be_installed } 108 | it{ should be_installed.by("dism") } 109 | it{ should be_installed.by("powershell") } 110 | end 111 | 112 | describe iis_website("Default Website") do 113 | it { should exist } 114 | it { should be_enabled } 115 | it { should be_running } 116 | it { should be_in_app_pool "DefaultAppPool" } 117 | it { should have_physical_path "c:/inetpub/wwwroot" } 118 | end 119 | 120 | describe iis_app_pool("DefaultAppPool") do 121 | it { should exist } 122 | it { should have_dotnet_version "2.0" } 123 | end 124 | 125 | ``` 126 | 127 | ###Notes: 128 | * Not all the matchers you are used to in Linux-like OS are supported in Windows, some because of differences between the operating systems (e.g. users and permissions model), some because they haven't been yet implemented. 129 | * All commands in the windows backend are run via powershell, so the output in case of stderr is a pretty ugly xml-like thing. Still it should contain some information to help troubleshooting. 130 | * The *command* type is executed again through powershell, so bear that in mind if you mean to run old CMD windows batch or programs. (i.e run the command using the **Invoke-Expression** Cmdlet, or the **&** Call Operator) 131 | * You may have to change Exectution Policy on the machine at both, machine and user level in order for tests to run: Get-ExecutionPolicy -list|%{set-executionpolicy bypass -scope $_.scope} 132 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{build}" 2 | image: Previous Visual Studio 2015 3 | 4 | platform: 5 | - x64 6 | 7 | environment: 8 | bundle_gemfile: integration-test/Gemfile.winrm 9 | bundler_url: https://rubygems.org/downloads/bundler-1.9.9.gem 10 | 11 | matrix: 12 | - ruby_version: "193" 13 | - ruby_version: "200" 14 | - ruby_version: "21" 15 | - ruby_version: "22" 16 | - ruby_version: "23" 17 | - ruby_version: "24" 18 | - ruby_version: "25" 19 | - ruby_version: "26" 20 | 21 | matrix: 22 | allow_failures: 23 | - ruby_version: "193" 24 | 25 | clone_depth: 5 26 | 27 | cache: 28 | - C:\Ruby193\lib\ruby\gems\1.9.1 -> appveyor.yml 29 | - C:\Ruby193\bin -> appveyor.yml 30 | - C:\Ruby200\lib\ruby\gems\2.0.0 -> appveyor.yml 31 | - C:\Ruby200\bin -> appveyor.yml 32 | - C:\Ruby21\lib\ruby\gems\2.1.0 -> appveyor.yml 33 | - C:\Ruby21\bin -> appveyor.yml 34 | - C:\Ruby22\lib\ruby\gems\2.2.0 -> appveyor.yml 35 | - C:\Ruby22\bin -> appveyor.yml 36 | - C:\Ruby23\lib\ruby\gems\2.2.0 -> appveyor.yml 37 | - C:\Ruby23\bin -> appveyor.yml 38 | - C:\Ruby24\lib\ruby\gems\2.4.0 -> appveyor.yml 39 | - C:\Ruby24\bin -> appveyor.yml 40 | - C:\Ruby25\lib\ruby\gems\2.5.0 -> appveyor.yml 41 | - C:\Ruby25\bin -> appveyor.yml 42 | - C:\Ruby26\lib\ruby\gems\2.6.0 -> appveyor.yml 43 | - C:\Ruby26\bin 44 | 45 | install: 46 | - git submodule update --init --recursive 47 | - ps: Enable-PSRemoting -Force 48 | - winrm quickconfig -q 49 | - winrm set winrm/config/client @{TrustedHosts="*"} 50 | - winrm set winrm/config/client/auth @{Basic="true"} 51 | - winrm set winrm/config/service/auth @{Basic="true"} 52 | - winrm set winrm/config/service @{AllowUnencrypted="true"} 53 | - SET PATH=C:\Ruby%ruby_version%\bin;%PATH% 54 | - echo %PATH% 55 | - ruby --version 56 | - gem --version 57 | - appveyor DownloadFile -Url %bundler_url% -FileName bundler.gem 58 | - gem install --local bundler.gem --no-document --force ## appveyor often stops `gem install bundler`..? 59 | - ps: $PSVersionTable 60 | 61 | build_script: 62 | - set SSL_CERT_FILE=C:/ruby24-x64/ssl/cert.pem 63 | - ruby -rfileutils -e 'FileUtils.rm_r(File.join(Gem.dir, "cache", "bundler")) if Dir.exist?(File.join(Gem.dir, "cache", "bundler"))' 64 | - bundle install --jobs 3 --retry 3 65 | - net user 66 | - net localgroup 67 | 68 | test_script: 69 | - net user appveyor %WINDOWS_PASSWORD% # set by webui 70 | - bundle exec rspec -fd --backtrace -r .\integration-test\winrm\spec_helper.rb .\integration-test\winrm 71 | -------------------------------------------------------------------------------- /bin/serverspec-init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. lib]) 4 | 5 | require 'serverspec' 6 | 7 | Serverspec::Setup.run 8 | -------------------------------------------------------------------------------- /lib/serverspec.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'rspec' 3 | require 'rspec/its' 4 | require 'specinfra' 5 | require 'serverspec/version' 6 | require 'serverspec/matcher' 7 | require 'serverspec/helper' 8 | require 'serverspec/setup' 9 | require 'serverspec/subject' 10 | require 'serverspec/commands/base' 11 | require 'rspec/core/formatters/base_formatter' 12 | require 'specinfra/helper/set' 13 | include Specinfra::Helper::Set 14 | 15 | module RSpec::Core::Notifications 16 | class FailedExampleNotification < ExampleNotification 17 | def failure_lines 18 | host = ENV['TARGET_HOST'] || Specinfra.configuration.host 19 | @failure_lines ||= 20 | begin 21 | lines = [] 22 | lines << "On host `#{host}'" if host 23 | lines << "Failure/Error: #{read_failed_line.strip}" 24 | lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/ 25 | exception.message.to_s.split("\n").each do |line| 26 | lines << " #{line}" if exception.message 27 | end 28 | lines << " #{example.metadata[:command]}" 29 | lines << " #{example.metadata[:stdout]}" if example.metadata[:stdout] 30 | lines << " #{example.metadata[:stderr]}" if example.metadata[:stderr] 31 | lines 32 | end 33 | end 34 | end 35 | end 36 | 37 | # For RSpec 3.3.x 38 | if defined?(RSpec::Core::Formatters::ExceptionPresenter) 39 | class RSpec::Core::Formatters::ExceptionPresenter 40 | def failure_lines 41 | host = ENV['TARGET_HOST'] || Specinfra.configuration.host 42 | @failure_lines ||= 43 | begin 44 | lines = [] 45 | lines << "On host `#{host}'" if host 46 | error_lines = [] 47 | error_lines = [failure_slash_error_line] if defined?(failure_slash_error_line) 48 | error_lines = failure_slash_error_lines if defined?(failure_slash_error_lines) 49 | lines += error_lines unless (description == error_lines.join('')) 50 | lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/ 51 | encoded_string(exception.message.to_s).split("\n").each do |line| 52 | lines << " #{line}" 53 | end 54 | lines << " #{example.metadata[:command]}" 55 | lines << " #{example.metadata[:stdout]}" if example.metadata[:stdout] 56 | lines << " #{example.metadata[:stderr]}" if example.metadata[:stderr] 57 | lines 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /lib/serverspec/commands/base.rb: -------------------------------------------------------------------------------- 1 | module Serverspec 2 | module Commands 3 | class Base < Specinfra::Command::Base 4 | end 5 | end 6 | end 7 | 8 | -------------------------------------------------------------------------------- /lib/serverspec/helper.rb: -------------------------------------------------------------------------------- 1 | # Subject type helper 2 | require 'serverspec/helper/type' 3 | extend Serverspec::Helper::Type 4 | class RSpec::Core::ExampleGroup 5 | extend Serverspec::Helper::Type 6 | include Serverspec::Helper::Type 7 | end 8 | 9 | -------------------------------------------------------------------------------- /lib/serverspec/helper/type.rb: -------------------------------------------------------------------------------- 1 | module Serverspec 2 | module Helper 3 | module Type 4 | types = %w( 5 | base bridge bond cgroup command cron default_gateway file fstab 6 | group host iis_website iis_app_pool interface ipfilter ipnat 7 | iptables ip6tables json_file kernel_module kvm linux_kernel_parameter lxc 8 | mail_alias mysql_config package php_config port ppa process 9 | routing_table selinux selinux_module service user yumrepo 10 | windows_feature windows_hot_fix windows_registry_key 11 | windows_scheduled_task zfs docker_base docker_image 12 | docker_container x509_certificate x509_private_key 13 | linux_audit_system hadoop_config php_extension windows_firewall 14 | ) 15 | 16 | types.each {|type| require "serverspec/type/#{type}" } 17 | 18 | types.each do |type| 19 | define_method type do |*args| 20 | eval "Serverspec::Type::#{type.to_camel_case}.new(*args)" 21 | end 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/serverspec/matcher.rb: -------------------------------------------------------------------------------- 1 | # file 2 | require 'serverspec/matcher/be_mounted' 3 | require 'serverspec/matcher/contain' 4 | require 'serverspec/matcher/be_readable' 5 | require 'serverspec/matcher/be_writable' 6 | require 'serverspec/matcher/be_executable' 7 | 8 | # port 9 | require 'serverspec/matcher/be_listening' 10 | 11 | # host 12 | require 'serverspec/matcher/be_resolvable' 13 | require 'serverspec/matcher/be_reachable' 14 | 15 | # package 16 | require 'serverspec/matcher/be_installed' 17 | 18 | # selinux 19 | require 'serverspec/matcher/be_enforcing' 20 | require 'serverspec/matcher/be_permissive' 21 | 22 | # service 23 | require 'serverspec/matcher/be_enabled' 24 | require 'serverspec/matcher/be_running' 25 | require 'serverspec/matcher/be_monitored_by' 26 | 27 | # user 28 | require 'serverspec/matcher/belong_to_group' 29 | require 'serverspec/matcher/belong_to_primary_group' 30 | 31 | # ipfiter, ipnat, iptables, ip6tables 32 | require 'serverspec/matcher/have_rule' 33 | 34 | # cron, fstab, routing_table 35 | require 'serverspec/matcher/have_entry' 36 | 37 | # iis_website 38 | require 'serverspec/matcher/have_site_application' 39 | require 'serverspec/matcher/have_site_bindings' 40 | require 'serverspec/matcher/have_virtual_dir' 41 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_enabled.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_enabled do 2 | match do |subject| 3 | if subject.class.name == 'Serverspec::Type::Service' 4 | subject.enabled?(@level, @under) 5 | else 6 | subject.enabled? 7 | end 8 | end 9 | 10 | description do 11 | message = 'be enabled' 12 | message << " under #{@under}" if @under 13 | message << " with level #{@level}" if @level 14 | message 15 | end 16 | 17 | chain :with_level do |level| 18 | @level = level 19 | end 20 | 21 | chain :under do |under| 22 | @under = under 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_enforcing.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_enforcing do 2 | match do |selinux| 3 | selinux.enforcing?(@with_policy) 4 | end 5 | 6 | chain :with_policy do |with_policy| 7 | @with_policy = with_policy 8 | end 9 | 10 | end 11 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_executable.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_executable do 2 | match do |file| 3 | file.executable?(@by_whom, @by_user) 4 | end 5 | 6 | chain :by do |by_whom| 7 | @by_whom = by_whom 8 | end 9 | 10 | chain :by_user do |by_user| 11 | @by_user = by_user 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_installed.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_installed do 2 | match do |subject| 3 | if subject.class.name == 'Serverspec::Type::SelinuxModule' 4 | subject.installed?(@version) 5 | else 6 | subject.installed?(@provider, @version) 7 | end 8 | end 9 | 10 | description do 11 | message = 'be installed' 12 | message << %( by "#{@provider}") if @provider 13 | message << %( with version "#{@version}") if @version 14 | message 15 | end 16 | 17 | chain :by do |provider| 18 | @provider = provider 19 | end 20 | 21 | chain :with_version do |version| 22 | @version = version 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_listening.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_listening do 2 | match do |port| 3 | port.listening? @with, @local_address 4 | end 5 | 6 | description do 7 | message = 'be listening' 8 | message << " on #{@local_address}" if @local_address 9 | message << " with #{@with}" if @with 10 | message 11 | end 12 | 13 | chain :with do |with| 14 | @with = with 15 | end 16 | 17 | chain :on do |local_address| 18 | @local_address = local_address 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_monitored_by.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_monitored_by do |monitor| 2 | match do |service| 3 | service.monitored_by?(monitor, @monitor_name) 4 | end 5 | description do 6 | if @monitor_name 7 | "be monitored by #{monitor} with name #{@monitor_name}" 8 | else 9 | "be monitored by #{monitor}" 10 | end 11 | end 12 | 13 | chain :with_name do |name| 14 | @monitor_name = (name ? name : nil) 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_mounted.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_mounted do 2 | match do |path| 3 | path.mounted?(@attr, @only_with) 4 | end 5 | 6 | chain :with do |attr| 7 | @attr = attr 8 | @only_with = false 9 | end 10 | 11 | chain :only_with do |attr| 12 | @attr = attr 13 | @only_with = true 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_permissive.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_permissive do 2 | match do |selinux| 3 | selinux.permissive?(@with_policy) 4 | end 5 | 6 | chain :with_policy do |with_policy| 7 | @with_policy = with_policy 8 | end 9 | 10 | end 11 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_reachable.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_reachable do 2 | match do |host| 3 | proto = 'tcp' 4 | timeout = 5 5 | if @attr 6 | port = @attr[:port] 7 | proto = @attr[:proto] if @attr[:proto] 8 | timeout = @attr[:timeout] if @attr[:timeout] 9 | end 10 | 11 | host.reachable?(port, proto, timeout) 12 | end 13 | 14 | chain :with do |attr| 15 | @attr = attr 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_readable.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_readable do 2 | match do |file| 3 | file.readable?(@by_whom, @by_user) 4 | end 5 | 6 | chain :by do |by_whom| 7 | @by_whom = by_whom 8 | end 9 | 10 | chain :by_user do |by_user| 11 | @by_user = by_user 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_resolvable.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_resolvable do 2 | match do |name| 3 | name.resolvable?(@type) 4 | end 5 | 6 | chain :by do |type| 7 | @type = type 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_running.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_running do 2 | match do |subject| 3 | if subject.class.name == 'Serverspec::Type::Service' 4 | subject.running?(@under) 5 | else 6 | subject.running? 7 | end 8 | end 9 | 10 | description do 11 | message = 'be running' 12 | message << " under #{@under}" if @under 13 | message 14 | end 15 | 16 | chain :under do |under| 17 | @under = under 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/be_writable.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_writable do 2 | match do |file| 3 | file.writable?(@by_whom, @by_user) 4 | end 5 | 6 | chain :by do |by_whom| 7 | @by_whom = by_whom 8 | end 9 | 10 | chain :by_user do |by_user| 11 | @by_user = by_user 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/belong_to_group.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :belong_to_group do |group| 2 | match do |user| 3 | user.belongs_to_group?(group) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/belong_to_primary_group.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :belong_to_primary_group do |group| 2 | match do |user| 3 | user.belongs_to_primary_group?(group) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/contain.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :contain do |pattern| 2 | match do |resource| 3 | if resource.is_a?(String) 4 | resource.match(Regexp.new([@from, pattern, @to].compact.join.gsub('/', '.*'), Regexp::MULTILINE)) 5 | else 6 | resource.contain(pattern, @from, @to) 7 | end 8 | end 9 | 10 | # for contain(pattern).from(/A/).to(/B/) 11 | chain :from do |from| 12 | @from = Regexp.new(from).inspect 13 | end 14 | 15 | chain :to do |to| 16 | @to = Regexp.new(to).inspect 17 | end 18 | 19 | # for contain(pattern).after(/A/) 20 | chain :after do |after| 21 | @from = Regexp.new(after).inspect 22 | end 23 | 24 | # for contain(pattern).before(/B/) 25 | chain :before do |before| 26 | @to = Regexp.new(before).inspect 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/have_entry.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :have_entry do |entry| 2 | match do |subject| 3 | if subject.class.name == 'Serverspec::Type::Cron' 4 | subject.has_entry?(@user, entry) 5 | elsif subject.respond_to?(:has_entry?) 6 | subject.has_entry?(entry) 7 | end 8 | end 9 | 10 | # For cron type 11 | chain :with_user do |user| 12 | @user = user 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/have_rule.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :have_rule do |rule| 2 | match do |subject| 3 | if subject.class.name == 'Serverspec::Type::Iptables' || subject.class.name == 'Serverspec::Type::Ip6tables' 4 | subject.has_rule?(rule, @table, @chain) 5 | else 6 | subject.has_rule?(rule) 7 | end 8 | end 9 | 10 | description do 11 | message = %Q{have rule "#{rule}"} 12 | message << " with table #{@table}" if @table 13 | message << ' and' if @table && @chain 14 | message << " with chain #{@chain}" if @chain 15 | message 16 | end 17 | 18 | chain :with_table do |table| 19 | @table = table 20 | end 21 | 22 | chain :with_chain do |chain| 23 | @chain = chain 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/have_site_application.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :have_site_application do |app| 2 | match do |subject| 3 | if subject.class.name == 'Serverspec::Type::IisWebsite' 4 | subject.has_site_application?(app, @pool, @physical_path) 5 | else 6 | className = subject.class.name 7 | raise "not supported class #{className}" 8 | end 9 | end 10 | 11 | chain :with_pool do |pool| 12 | @pool = pool 13 | end 14 | 15 | chain :with_physical_path do |physical_path| 16 | @physical_path = physical_path 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/have_site_bindings.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :have_site_bindings do |port| 2 | match do |subject| 3 | if subject.class.name == 'Serverspec::Type::IisWebsite' 4 | subject.has_site_bindings?(port, @protocol, @ipaddress, @host_header) 5 | else 6 | className = subject.class.name 7 | raise "not supported class #{className}" 8 | end 9 | end 10 | 11 | chain :with_protocol do |protocol| 12 | @protocol = protocol 13 | end 14 | 15 | chain :with_ipaddress do |ipaddress| 16 | @ipaddress = ipaddress 17 | end 18 | 19 | chain :with_host_header do |host_header| 20 | @host_header = host_header 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/serverspec/matcher/have_virtual_dir.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :have_virtual_dir do |vdir| 2 | match do |subject| 3 | if subject.class.name == 'Serverspec::Type::IisWebsite' 4 | subject.has_virtual_dir?(vdir, @path) 5 | else 6 | className = subject.class.name 7 | raise "not supported class #{className}" 8 | end 9 | end 10 | 11 | chain :with_path do |path| 12 | @path = path 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/serverspec/power_assert.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require 'specinfra' 3 | 4 | require 'serverspec/helper/type' 5 | 6 | PowerAssert.configure do |c| 7 | c.lazy_inspection = true 8 | end 9 | 10 | class Serverspec::TestCase < Test::Unit::TestCase 11 | extend Serverspec::Helper::Type 12 | include Serverspec::Helper::Type 13 | end 14 | 15 | -------------------------------------------------------------------------------- /lib/serverspec/setup.rb: -------------------------------------------------------------------------------- 1 | require 'pathname' 2 | require 'fileutils' 3 | require 'erb' 4 | 5 | module Serverspec 6 | class Setup 7 | def self.run 8 | 9 | ask_os_type 10 | 11 | if @os_type == 'UN*X' 12 | ask_unix_backend 13 | else 14 | ask_windows_backend 15 | end 16 | 17 | if @backend_type == 'ssh' 18 | print 'Vagrant instance y/n: ' 19 | @vagrant = $stdin.gets.chomp 20 | if @vagrant =~ (/(true|t|yes|y|1)$/i) 21 | @vagrant = true 22 | print 'Auto-configure Vagrant from Vagrantfile? y/n: ' 23 | auto_config = $stdin.gets.chomp 24 | if auto_config =~ (/(true|t|yes|y|1)$/i) 25 | auto_vagrant_configuration 26 | else 27 | print('Input vagrant instance name: ') 28 | @hostname = $stdin.gets.chomp 29 | end 30 | else 31 | @vagrant = false 32 | print('Input target host name: ') 33 | @hostname = $stdin.gets.chomp 34 | end 35 | elsif @backend_type == 'winrm' 36 | print('Input target host name: ') 37 | @hostname = $stdin.gets.chomp 38 | else 39 | @hostname = 'localhost' 40 | end 41 | 42 | ['spec', "spec/#{@hostname}"].each { |dir| safe_mkdir(dir) } 43 | safe_create_spec 44 | safe_create_spec_helper 45 | safe_create_rakefile 46 | safe_create_dotrspec 47 | end 48 | 49 | def self.ask_os_type 50 | prompt = <<-EOF 51 | Select OS type: 52 | 53 | 1) UN*X 54 | 2) Windows 55 | 56 | Select number: 57 | EOF 58 | 59 | print prompt.chop 60 | num = $stdin.gets.to_i - 1 61 | puts 62 | 63 | @os_type = ['UN*X', 'Windows'][num] || 'UN*X' 64 | end 65 | 66 | def self.ask_unix_backend 67 | prompt = <<-EOF 68 | Select a backend type: 69 | 70 | 1) SSH 71 | 2) Exec (local) 72 | 73 | Select number: 74 | EOF 75 | print prompt.chop 76 | num = $stdin.gets.to_i - 1 77 | puts 78 | 79 | @backend_type = ['ssh', 'exec'][num] || 'exec' 80 | end 81 | 82 | def self.ask_windows_backend 83 | prompt = <<-EOF 84 | Select a backend type: 85 | 86 | 1) WinRM 87 | 2) Cmd (local) 88 | 89 | Select number: 90 | EOF 91 | print prompt.chop 92 | num = $stdin.gets.to_i - 1 93 | puts 94 | 95 | @backend_type = ['winrm', 'cmd'][num] || 'exec' 96 | end 97 | 98 | def self.safe_create_spec 99 | content = <<-EOF 100 | require 'spec_helper' 101 | 102 | describe package('httpd'), :if => os[:family] == 'redhat' do 103 | it { should be_installed } 104 | end 105 | 106 | describe package('apache2'), :if => os[:family] == 'ubuntu' do 107 | it { should be_installed } 108 | end 109 | 110 | describe service('httpd'), :if => os[:family] == 'redhat' do 111 | it { should be_enabled } 112 | it { should be_running } 113 | end 114 | 115 | describe service('apache2'), :if => os[:family] == 'ubuntu' do 116 | it { should be_enabled } 117 | it { should be_running } 118 | end 119 | 120 | describe service('org.apache.httpd'), :if => os[:family] == 'darwin' do 121 | it { should be_enabled } 122 | it { should be_running } 123 | end 124 | 125 | describe port(80) do 126 | it { should be_listening } 127 | end 128 | EOF 129 | 130 | if File.exist? "spec/#{@hostname}/sample_spec.rb" 131 | old_content = File.read("spec/#{@hostname}/sample_spec.rb") 132 | if old_content != content 133 | $stderr.puts "!! spec/#{@hostname}/sample_spec.rb already exists and differs from template" 134 | end 135 | else 136 | File.open("spec/#{@hostname}/sample_spec.rb", 'w') do |f| 137 | f.puts content 138 | end 139 | puts " + spec/#{@hostname}/sample_spec.rb" 140 | end 141 | end 142 | 143 | def self.safe_mkdir(dir) 144 | if File.exist? dir 145 | unless File.directory? dir 146 | $stderr.puts "!! #{dir} already exists and is not a directory" 147 | end 148 | else 149 | FileUtils.mkdir dir 150 | puts " + #{dir}/" 151 | end 152 | end 153 | 154 | def self.safe_create_spec_helper 155 | erb = if RUBY_VERSION >= "2.6" 156 | ERB.new(spec_helper_template, :trim_mode => '-') 157 | else 158 | ERB.new(spec_helper_template, nil, '-') 159 | end 160 | content = erb.result(binding) 161 | if File.exist? 'spec/spec_helper.rb' 162 | old_content = File.read('spec/spec_helper.rb') 163 | if old_content != content 164 | $stderr.puts "!! spec/spec_helper.rb already exists and differs from template" 165 | end 166 | else 167 | File.open('spec/spec_helper.rb', 'w') do |f| 168 | f.puts content 169 | end 170 | puts ' + spec/spec_helper.rb' 171 | end 172 | end 173 | 174 | def self.safe_create_rakefile 175 | content = <<-'EOF' 176 | require 'rake' 177 | require 'rspec/core/rake_task' 178 | 179 | task :spec => 'spec:all' 180 | task :default => :spec 181 | 182 | namespace :spec do 183 | targets = [] 184 | Dir.glob('./spec/*').each do |dir| 185 | next unless File.directory?(dir) 186 | target = File.basename(dir) 187 | target = "_#{target}" if target == "default" 188 | targets << target 189 | end 190 | 191 | task :all => targets 192 | task :default => :all 193 | 194 | targets.each do |target| 195 | original_target = target == "_default" ? target[1..-1] : target 196 | desc "Run serverspec tests to #{original_target}" 197 | RSpec::Core::RakeTask.new(target.to_sym) do |t| 198 | ENV['TARGET_HOST'] = original_target 199 | t.pattern = "spec/#{original_target}/*_spec.rb" 200 | end 201 | end 202 | end 203 | EOF 204 | if File.exist? 'Rakefile' 205 | old_content = File.read('Rakefile') 206 | if old_content != content 207 | $stderr.puts '!! Rakefile already exists and differs from template' 208 | end 209 | else 210 | File.open('Rakefile', 'w') do |f| 211 | f.puts content 212 | end 213 | puts ' + Rakefile' 214 | end 215 | end 216 | 217 | def self.find_vagrantfile 218 | Pathname.new(Dir.pwd).ascend do |dir| 219 | path = File.expand_path('Vagrantfile', dir) 220 | return path if File.exist?(path) 221 | end 222 | nil 223 | end 224 | 225 | def self.auto_vagrant_configuration 226 | if find_vagrantfile 227 | vagrant_list = `vagrant status` 228 | list_of_vms = [] 229 | if vagrant_list != '' 230 | vagrant_list.each_line do |line| 231 | if match = /([\w-]+[\s]+)(created|aborted|not created|poweroff|running|saved)[\s](\(virtualbox\)|\(vmware\)|\(vmware_fusion\)|\(libvirt\))/.match(line) 232 | list_of_vms << match[1].strip! 233 | end 234 | end 235 | if list_of_vms.length == 1 236 | @hostname = list_of_vms[0] 237 | else 238 | list_of_vms.each_with_index { |vm, index | puts "#{index}) #{vm}\n" } 239 | print 'Choose a VM from the Vagrantfile: ' 240 | chosen_vm = $stdin.gets.chomp 241 | @hostname = list_of_vms[chosen_vm.to_i] 242 | end 243 | else 244 | $stderr.puts 'Vagrant status error - Check your Vagrantfile or .vagrant' 245 | exit 1 246 | end 247 | else 248 | $stderr.puts 'Vagrantfile not found in directory!' 249 | exit 1 250 | end 251 | end 252 | 253 | def self.spec_helper_template 254 | template = <<-'EOF' 255 | require 'serverspec' 256 | <% if @backend_type == 'ssh' -%> 257 | require 'net/ssh' 258 | <% end -%> 259 | <%- if @vagrant -%> 260 | require 'tempfile' 261 | <% end -%> 262 | <% if @backend_type == 'winrm' -%> 263 | require 'winrm' 264 | <% end -%> 265 | 266 | set :backend, :<%= @backend_type %> 267 | 268 | <% if @os_type == 'UN*X' && @backend_type == 'ssh' -%> 269 | if ENV['ASK_SUDO_PASSWORD'] 270 | begin 271 | require 'highline/import' 272 | rescue LoadError 273 | fail "highline is not available. Try installing it." 274 | end 275 | set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false } 276 | else 277 | set :sudo_password, ENV['SUDO_PASSWORD'] 278 | end 279 | 280 | <%- if @backend_type == 'ssh' -%> 281 | host = ENV['TARGET_HOST'] 282 | 283 | <%- if @vagrant -%> 284 | `vagrant up #{host}` 285 | 286 | config = Tempfile.new('', Dir.tmpdir) 287 | config.write(`vagrant ssh-config #{host}`) 288 | config.close 289 | 290 | options = Net::SSH::Config.for(host, [config.path]) 291 | <%- else -%> 292 | options = Net::SSH::Config.for(host) 293 | <%- end -%> 294 | 295 | options[:user] ||= Etc.getlogin 296 | 297 | set :host, options[:host_name] || host 298 | set :ssh_options, options 299 | 300 | # Disable sudo 301 | # set :disable_sudo, true 302 | <%- end -%> 303 | 304 | 305 | # Set environment variables 306 | # set :env, :LANG => 'C', :LC_MESSAGES => 'C' 307 | 308 | # Set PATH 309 | # set :path, '/sbin:/usr/local/sbin:$PATH' 310 | <%- end -%> 311 | <% if @backend_type == 'winrm'-%> 312 | user = 313 | pass = 314 | endpoint = "http://#{ENV['TARGET_HOST']}:5985/wsman" 315 | 316 | if Gem::Version.new(WinRM::VERSION) < Gem::Version.new('2') 317 | winrm = ::WinRM::WinRMWebService.new(endpoint, :ssl, :user => user, :pass => pass, :basic_auth_only => true) 318 | winrm.set_timeout 300 # 5 minutes max timeout for any operation 319 | else 320 | opts = { 321 | user: user, 322 | password: pass, 323 | endpoint: endpoint, 324 | operation_timeout: 300, 325 | no_ssl_peer_verification: false, 326 | } 327 | 328 | winrm = ::WinRM::Connection.new(opts) 329 | end 330 | 331 | Specinfra.configuration.winrm = winrm 332 | <% end -%> 333 | EOF 334 | template 335 | end 336 | 337 | def self.safe_create_dotrspec 338 | content = <<-'EOF' 339 | --color 340 | --format documentation 341 | EOF 342 | if File.exist? '.rspec' 343 | old_content = File.read('.rspec') 344 | if old_content != content 345 | $stderr.puts '!! .rspec already exists and differs from template' 346 | end 347 | else 348 | File.open('.rspec', 'w') do |f| 349 | f.puts content 350 | end 351 | puts ' + .rspec' 352 | end 353 | end 354 | 355 | end 356 | end 357 | -------------------------------------------------------------------------------- /lib/serverspec/subject.rb: -------------------------------------------------------------------------------- 1 | module Serverspec 2 | class Subject 3 | def value(v=nil) 4 | if v.nil? 5 | @value 6 | else 7 | @value = v 8 | self 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/serverspec/type/base.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Base 3 | 4 | attr_reader :name 5 | 6 | def initialize(name=nil, options = {}) 7 | @name = name 8 | @options = options 9 | @runner = Specinfra::Runner 10 | end 11 | 12 | def to_s 13 | type = self.class.name.split(':')[-1] 14 | type.gsub!(/([a-z\d])([A-Z])/, '\1 \2') 15 | type.capitalize! 16 | %Q!#{type} "#{@name}"! 17 | end 18 | 19 | def inspect 20 | if defined?(PowerAssert) 21 | @inspection 22 | else 23 | to_s 24 | end 25 | end 26 | 27 | def to_ary 28 | to_s.split(" ") 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/serverspec/type/bond.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Bond < Base 3 | def exists? 4 | @runner.check_bond_exists(@name) 5 | end 6 | 7 | def has_interface?(interface) 8 | @runner.check_bond_has_interface(@name, interface) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/bridge.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Bridge < Base 3 | def exists? 4 | @runner.check_bridge_exists(@name) 5 | end 6 | 7 | def has_interface?(interface) 8 | @runner.check_bridge_has_interface(@name, interface) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/cgroup.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Cgroup < Base 3 | attr_accessor :subsystem 4 | def method_missing(meth) 5 | if @subsystem.nil? 6 | @subsystem = meth.to_s 7 | self 8 | else 9 | param = "#{@subsystem}.#{meth.to_s}" 10 | ret = @runner.run_command("cgget -n -r #{param} #{@name} | awk '{print $2}'") 11 | val = ret.stdout.strip 12 | val = val.to_i if val.match(/^\d+$/) 13 | val 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/serverspec/type/command.rb: -------------------------------------------------------------------------------- 1 | require 'multi_json' 2 | 3 | module Serverspec::Type 4 | class Command < Base 5 | def stdout 6 | command_result.stdout 7 | end 8 | 9 | def stdout_as_json 10 | MultiJson.load(command_result.stdout) 11 | end 12 | 13 | def stderr 14 | command_result.stderr 15 | end 16 | 17 | def exit_status 18 | command_result.exit_status.to_i 19 | end 20 | 21 | protected 22 | def command 23 | @name 24 | end 25 | 26 | private 27 | def command_result() 28 | @command_result ||= @runner.run_command(command) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/serverspec/type/cron.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Cron < Base 3 | def has_entry?(user, entry) 4 | @runner.check_cron_has_entry(user, entry) 5 | end 6 | 7 | def table 8 | @runner.get_cron_table.stdout 9 | end 10 | 11 | def to_s 12 | 'Cron' 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/serverspec/type/default_gateway.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class DefaultGateway < Base 3 | def ipaddress 4 | @runner.get_default_gateway(:gateway) 5 | end 6 | 7 | def interface 8 | @runner.get_default_gateway(:interface) 9 | end 10 | 11 | def to_s 12 | 'Default Gateway' 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/serverspec/type/docker_base.rb: -------------------------------------------------------------------------------- 1 | require 'multi_json' 2 | 3 | module Serverspec::Type 4 | class DockerBase < Base 5 | def exist? 6 | get_inspection.success? 7 | end 8 | 9 | def [](key) 10 | value = inspection 11 | key.split('.').each do |k| 12 | is_index = k.start_with?('[') && k.end_with?(']') 13 | value = value[is_index ? k[1..-2].to_i : k] 14 | end 15 | value 16 | end 17 | 18 | def inspection 19 | @inspection ||= ::MultiJson.load(get_inspection.stdout)[0] 20 | end 21 | 22 | private 23 | def get_inspection 24 | @get_inspection ||= @runner.run_command("docker inspect #{@name}") 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/serverspec/type/docker_container.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class DockerContainer < DockerBase 3 | def running? 4 | inspection['State']['Running'] && !inspection['State']['Restarting'] 5 | end 6 | 7 | def has_volume?(container_path, host_path) 8 | if (inspection['Mounts']) 9 | check_volume(container_path, host_path) 10 | else 11 | check_volume_pre_1_8(container_path, host_path) 12 | end 13 | end 14 | 15 | private 16 | def check_volume(container_path, host_path) 17 | inspection['Mounts'].find {|mount| 18 | mount['Destination'] == container_path && 19 | mount['Source'] == host_path 20 | } 21 | end 22 | 23 | def check_volume_pre_1_8(container_path, host_path) 24 | inspection['Volumes'][container_path] == host_path 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/serverspec/type/docker_image.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class DockerImage < DockerBase 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /lib/serverspec/type/file.rb: -------------------------------------------------------------------------------- 1 | require 'date' 2 | require 'multi_json' 3 | require 'yaml' 4 | 5 | module Serverspec::Type 6 | class File < Base 7 | attr_accessor :content 8 | 9 | def file? 10 | cmd = Specinfra.command.get(:check_file_is_file, @name) 11 | @inspection = Specinfra.backend.build_command(cmd.to_s) 12 | @runner.check_file_is_file(@name) 13 | end 14 | 15 | def block_device? 16 | @runner.check_file_is_block_device(@name) 17 | end 18 | 19 | def character_device? 20 | @runner.check_file_is_character_device(@name) 21 | end 22 | 23 | def socket? 24 | @runner.check_file_is_socket(@name) 25 | end 26 | 27 | def directory? 28 | @runner.check_file_is_directory(@name) 29 | end 30 | 31 | def symlink? 32 | @runner.check_file_is_symlink(@name) 33 | end 34 | 35 | def pipe? 36 | @runner.check_file_is_pipe(@name) 37 | end 38 | 39 | def contain(pattern, from, to) 40 | if pattern.is_a?(Array) 41 | @runner.check_file_contains_lines(@name, pattern, from, to) 42 | else 43 | if (from || to).nil? 44 | @runner.check_file_contains(@name, pattern) 45 | else 46 | @runner.check_file_contains_within(@name, pattern, from, to) 47 | end 48 | end 49 | end 50 | 51 | def mode?(mode) 52 | @runner.check_file_has_mode(@name, mode) 53 | end 54 | 55 | def owned_by?(owner) 56 | @runner.check_file_is_owned_by(@name, owner) 57 | end 58 | 59 | def grouped_into?(group) 60 | @runner.check_file_is_grouped(@name, group) 61 | end 62 | 63 | def linked_to?(target) 64 | @runner.check_file_is_linked_to(@name, target) 65 | end 66 | 67 | def readable?(by_whom, by_user) 68 | if by_user != nil 69 | @runner.check_file_is_accessible_by_user(@name, by_user, 'r') 70 | else 71 | @runner.check_file_is_readable(@name, by_whom) 72 | end 73 | end 74 | 75 | def writable?(by_whom, by_user) 76 | if by_user != nil 77 | @runner.check_file_is_accessible_by_user(@name, by_user, 'w') 78 | else 79 | @runner.check_file_is_writable(@name, by_whom) 80 | end 81 | end 82 | 83 | def executable?(by_whom, by_user) 84 | if by_user != nil 85 | @runner.check_file_is_accessible_by_user(@name, by_user, 'x') 86 | else 87 | @runner.check_file_is_executable(@name, by_whom) 88 | end 89 | end 90 | 91 | def mounted?(attr, only_with) 92 | @runner.check_file_is_mounted(@name, attr, only_with) 93 | end 94 | 95 | def immutable? 96 | @runner.check_file_is_immutable(@name) 97 | end 98 | 99 | def exists? 100 | @runner.check_file_exists(@name) 101 | end 102 | 103 | def md5sum 104 | @runner.get_file_md5sum(@name).stdout.strip 105 | end 106 | 107 | def sha256sum 108 | @runner.get_file_sha256sum(@name).stdout.strip 109 | end 110 | 111 | def content 112 | if @content.nil? 113 | @content = @runner.get_file_content(@name).stdout 114 | end 115 | @content 116 | end 117 | 118 | def content_as_json 119 | @content_as_json = MultiJson.load(content) if @content_as_json.nil? 120 | @content_as_json 121 | end 122 | 123 | def content_as_yaml 124 | if @content_as_yaml.nil? 125 | @content_as_yaml = if YAML.respond_to?(:unsafe_load) 126 | YAML.unsafe_load(content) 127 | else 128 | YAML.load(content) 129 | end 130 | end 131 | @content_as_yaml 132 | end 133 | 134 | def group 135 | @runner.get_file_owner_group(@name).stdout.strip 136 | end 137 | 138 | def version?(version) 139 | @runner.check_file_has_version(@name, version) 140 | end 141 | 142 | def link_target 143 | @runner.get_file_link_target(@name).stdout.strip 144 | end 145 | 146 | def mode 147 | @runner.get_file_mode(@name).stdout.strip 148 | end 149 | 150 | def mtime 151 | d = @runner.get_file_mtime(@name).stdout.strip 152 | DateTime.strptime(d, '%s').new_offset(DateTime.now.offset) 153 | end 154 | 155 | def owner 156 | @runner.get_file_owner_user(@name).stdout.strip 157 | end 158 | 159 | def size 160 | @runner.get_file_size(@name).stdout.strip.to_i 161 | end 162 | 163 | def selinux_label 164 | @runner.get_file_selinuxlabel(@name).stdout.strip 165 | end 166 | end 167 | end 168 | -------------------------------------------------------------------------------- /lib/serverspec/type/fstab.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Fstab < Base 3 | def has_entry?(entry) 4 | @runner.check_fstab_has_entry(entry) 5 | end 6 | 7 | def to_s 8 | 'Fstab' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/group.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Group < Base 3 | def exists? 4 | @runner.check_group_exists(@name) 5 | end 6 | 7 | def gid 8 | @runner.get_group_gid(@name).stdout.to_i 9 | end 10 | 11 | def has_gid?(gid) 12 | @runner.check_group_has_gid(@name, gid) 13 | end 14 | 15 | def is_system_group? 16 | @runner.check_group_is_system_group(@name) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/serverspec/type/hadoop_config.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class HadoopConfig < Base 3 | def initialize(name=nil, options={}) 4 | super 5 | 6 | begin 7 | require 'nokogiri' 8 | rescue LoadError 9 | fail "nokogiri is not available. Try installing it." 10 | end 11 | end 12 | 13 | def value 14 | @runner.run_command("find /etc/hadoop/conf/ -type f -name \"*.xml\" ").stdout.split(/\n/).each do |file| 15 | @doc = ::Nokogiri::XML( @runner.get_file_content("#{file}").stdout.strip ) 16 | @doc.xpath('/configuration/property').each do |property| 17 | case property.xpath('name').text 18 | when /#{@name}/ 19 | ret = property.xpath('value').text 20 | val = ret.to_s 21 | return val 22 | end 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/serverspec/type/host.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Host < Base 3 | def resolvable?(type) 4 | @runner.check_host_is_resolvable(@name, type) 5 | end 6 | 7 | def reachable?(port, proto, timeout) 8 | @runner.check_host_is_reachable(@name, port, proto, timeout) 9 | end 10 | 11 | def ipaddress 12 | @runner.get_host_ipaddress(@name).stdout.strip 13 | end 14 | def ipv4_address 15 | @runner.get_host_ipv4_address(@name).stdout.strip 16 | end 17 | def ipv6_address 18 | @runner.get_host_ipv6_address(@name).stdout.strip 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/serverspec/type/iis_app_pool.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class IisAppPool < Base 3 | def exists?() 4 | @runner.check_iis_app_pool_exists(@name) 5 | end 6 | 7 | def has_dotnet_version?(dotnet) 8 | @runner.check_iis_app_pool_has_dotnet_version(@name, dotnet) 9 | end 10 | 11 | def has_32bit_enabled?() 12 | @runner.check_iis_app_pool_has_32bit_enabled(@name) 13 | end 14 | 15 | def has_idle_timeout?(minutes) 16 | @runner.check_iis_app_pool_has_idle_timeout(@name, minutes) 17 | end 18 | 19 | def has_identity_type?(identity_type) 20 | @runner.check_iis_app_pool_has_identity_type(@name, identity_type) 21 | end 22 | 23 | def has_periodic_restart?(minutes) 24 | @runner.check_iis_app_pool_has_periodic_restart(@name, minutes) 25 | end 26 | 27 | def has_user_profile_enabled?() 28 | @runner.check_iis_app_pool_has_user_profile(@name) 29 | end 30 | 31 | def has_username?(username) 32 | @runner.check_iis_app_pool_has_username(@name, username) 33 | end 34 | 35 | def has_managed_pipeline_mode?(mode) 36 | @runner.check_iis_app_pool_has_managed_pipeline_mode(@name, mode) 37 | end 38 | 39 | def to_s 40 | %Q[IIS Application Pool "#{@name}"] 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/serverspec/type/iis_website.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class IisWebsite < Base 3 | 4 | def exists?() 5 | @runner.check_iis_website_is_installed(@name) 6 | end 7 | 8 | def enabled?() 9 | @runner.check_iis_website_is_enabled(@name) 10 | end 11 | 12 | def running?() 13 | @runner.check_iis_website_is_running(@name) 14 | end 15 | 16 | def in_app_pool?(app_pool) 17 | @runner.check_iis_website_is_in_app_pool(@name, app_pool) 18 | end 19 | 20 | def has_physical_path?(path) 21 | @runner.check_iis_website_has_physical_path(@name, path) 22 | end 23 | 24 | def has_site_bindings?(port, protocol, ipaddress, host_header) 25 | @runner.check_iis_website_has_site_bindings(@name, port, protocol, ipaddress, host_header) 26 | end 27 | 28 | def has_virtual_dir?(vdir, path) 29 | @runner.check_iis_website_has_virtual_dir(@name, vdir, path) 30 | end 31 | 32 | def has_site_application?(app, pool, physical_path) 33 | @runner.check_iis_website_has_site_application(@name, app, pool, physical_path) 34 | end 35 | 36 | def to_s 37 | %Q[IIS Website "#{@name}"] 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/serverspec/type/interface.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Interface < Base 3 | def exists? 4 | @runner.check_interface_exists(@name) 5 | end 6 | 7 | def speed 8 | ret = @runner.get_interface_speed_of(@name) 9 | val_to_integer(ret) 10 | end 11 | 12 | def mtu 13 | ret = @runner.get_interface_mtu_of(@name) 14 | val_to_integer(ret) 15 | end 16 | 17 | def has_ipv4_address?(ip_address) 18 | @runner.check_interface_has_ipv4_address(@name, ip_address) 19 | end 20 | 21 | def has_ipv6_address?(ip_address) 22 | @runner.check_interface_has_ipv6_address(@name, ip_address) 23 | end 24 | 25 | def ipv4_address 26 | @runner.get_interface_ipv4_address(@name).stdout.strip 27 | end 28 | 29 | def ipv6_address 30 | @runner.get_interface_ipv6_address(@name).stdout.strip 31 | end 32 | 33 | def up? 34 | ret = @runner.get_interface_link_state(@name) 35 | ret.stdout.strip == 'up' 36 | end 37 | 38 | private 39 | 40 | def val_to_integer(ret) 41 | val = ret.stdout.strip 42 | val = val.to_i if val.match(/^\d+$/) 43 | val 44 | end 45 | 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/serverspec/type/ip6tables.rb: -------------------------------------------------------------------------------- 1 | module Serverspec 2 | module Type 3 | class Ip6tables < Base 4 | def has_rule?(rule, table, chain) 5 | @runner.check_ip6tables_has_rule(rule, table, chain) 6 | end 7 | 8 | def to_s 9 | 'ip6tables' 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/serverspec/type/ipfilter.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Ipfilter < Base 3 | def has_rule?(rule) 4 | @runner.check_ipfilter_has_rule(rule) 5 | end 6 | 7 | def to_s 8 | 'ipfilter' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/ipnat.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Ipnat < Base 3 | def has_rule?(rule) 4 | @runner.check_ipnat_has_rule(rule) 5 | end 6 | 7 | def to_s 8 | 'ipnat' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/iptables.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Iptables < Base 3 | def has_rule?(rule, table, chain) 4 | @runner.check_iptables_has_rule(rule, table, chain) 5 | end 6 | 7 | def to_s 8 | 'iptables' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/json_file.rb: -------------------------------------------------------------------------------- 1 | require 'multi_json' 2 | 3 | module Serverspec::Type 4 | class JsonFile < File 5 | def content 6 | MultiJson.load(super) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/serverspec/type/kernel_module.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class KernelModule < Base 3 | def loaded? 4 | @runner.check_kernel_module_is_loaded(@name) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/serverspec/type/kvm.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Kvm < Base 3 | def exists? 4 | @runner.check_kvm_guest_exists(@name) 5 | end 6 | 7 | def running? 8 | @runner.check_kvm_guest_is_running(@name) 9 | end 10 | 11 | def enabled? 12 | @runner.check_kvm_guest_is_enabled(@name) 13 | end 14 | 15 | def to_s 16 | 'KVM' 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/serverspec/type/linux_audit_system.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class LinuxAuditSystem < Base 3 | def initialize(name=nil) 4 | @name = 'linux_audit_system' 5 | @runner = Specinfra::Runner 6 | @rules_content = nil 7 | end 8 | 9 | def enabled? 10 | status_of('enabled') == '1' 11 | end 12 | 13 | def running? 14 | pid = status_of('pid') 15 | (!pid.nil? && pid.size > 0 && pid != '0') 16 | end 17 | 18 | def rules 19 | if @rules_content.nil? 20 | @rules_content = @runner.run_command('/sbin/auditctl -l').stdout || '' 21 | end 22 | @rules_content 23 | end 24 | 25 | private 26 | 27 | def status_of(part) 28 | cmd = "/sbin/auditctl -s" 29 | status_str = @runner.run_command(cmd).stdout.chomp 30 | status_map = parse_status(status_str) 31 | status_map[part] || '' 32 | end 33 | 34 | def parse_status(status_str) 35 | map = nil 36 | if status_str =~ /^AUDIT_STATUS/ then 37 | map = status_str.split(' ')[1..-1].inject({}) { |res,elem| a = elem.split('='); res.store(a[0],a[1] || ''); res } 38 | else 39 | map = status_str.split("\n").inject({}) { |res,elem| a = elem.split(' '); res.store(a[0],a[1] || ''); res } 40 | end 41 | map 42 | end 43 | 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/serverspec/type/linux_kernel_parameter.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class LinuxKernelParameter < Base 3 | def value 4 | ret = @runner.run_command("/sbin/sysctl -q -n #{@name}") 5 | val = ret.stdout.strip 6 | val = val.to_i if val.match(/^\d+$/) 7 | val 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/serverspec/type/lxc.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Lxc < Base 3 | def exists? 4 | @runner.check_lxc_container_exists(@name) 5 | end 6 | 7 | def running? 8 | @runner.check_lxc_container_is_running(@name) 9 | end 10 | 11 | def to_s 12 | 'LXC' 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/serverspec/type/mail_alias.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class MailAlias < Base 3 | def aliased_to?(target) 4 | @runner.check_mail_alias_is_aliased_to(@name, target) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/serverspec/type/mysql_config.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class MysqlConfig < Base 3 | def value 4 | ret = @runner.run_command("mysqld --verbose --help 2> /dev/null | grep '^#{@name}'") 5 | val = ret.stdout.match(/#{@name}\s+(.+)$/)[1] 6 | val = val.to_i if val.match(/^\d+$/) 7 | val 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/serverspec/type/package.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Package < Base 3 | def installed?(provider=nil, version=nil) 4 | if provider.nil? 5 | @inspection = Specinfra.command.get(:check_package_is_installed, @name, version) 6 | @runner.check_package_is_installed(@name, version) 7 | else 8 | check_method = "check_package_is_installed_by_#{provider}".to_sym 9 | @runner.send(check_method, @name, version) 10 | end 11 | end 12 | 13 | def version 14 | ret = @runner.get_package_version(@name).stdout.strip 15 | if ret.empty? 16 | nil 17 | else 18 | Version.new(ret) 19 | end 20 | end 21 | 22 | class Version 23 | include Comparable 24 | 25 | attr_reader :epoch, :version 26 | 27 | def initialize(val) 28 | matches = val.match(/^(?:(\d+):)?(\d[0-9a-zA-Z.+:~_-]*)$/) 29 | if matches.nil? 30 | raise ArgumentError, "Malformed version number string #{val}" 31 | end 32 | @epoch = matches[1].to_i 33 | @version = matches[2].to_s 34 | end 35 | 36 | def <=>(other) 37 | other = Version.new(other) if other.is_a?(String) 38 | rv = @epoch <=> other.epoch 39 | return rv if rv != 0 40 | 41 | self.ver_array <=> other.ver_array 42 | end 43 | 44 | def ver_array 45 | val = @version 46 | re = /^(?:(\d+)|(\D+))(.*)$/ 47 | res = [] 48 | until val.empty? 49 | matches = val.match(re) 50 | if matches[1].nil? 51 | # String 52 | matches[2].to_s.each_byte do |b| 53 | code_point = defined?("~".ord) ? "~".ord : ?~ 54 | res << ((b == code_point) ? -2 : b) 55 | end 56 | else 57 | # Digits 58 | res << matches[1].to_i 59 | end 60 | val = matches[3].to_s 61 | end 62 | res << -1 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /lib/serverspec/type/php_config.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class PhpConfig < Base 3 | def value 4 | extra = ''; 5 | extra = extra + "-c #{@options[:ini]}" if @options.has_key?(:ini) 6 | ret = @runner.run_command("php #{extra} -r 'echo get_cfg_var( \"#{@name}\" );'") 7 | val = ret.stdout 8 | val = val.to_i if val.match(/^\d+$/) 9 | val 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/serverspec/type/php_extension.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class PhpExtension < Base 3 | def loaded? 4 | ret = @runner.run_command("php --ri '#{@name}'") 5 | 6 | return false if ret.exit_status.to_i > 0 7 | 8 | true 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/port.rb: -------------------------------------------------------------------------------- 1 | require 'resolv' 2 | 3 | module Serverspec::Type 4 | class Port < Base 5 | def protocols 6 | %w(udp tcp tcp6 udp6) 7 | end 8 | 9 | def options 10 | @options ||= {} 11 | end 12 | 13 | def protocol_matcher(protocol) 14 | protocol = protocol.to_s.downcase 15 | if protocols.include?(protocol) 16 | options[:protocol] = protocol 17 | else 18 | raise ArgumentError.new("`be_listening` matcher doesn't support #{protocol}") 19 | end 20 | end 21 | 22 | def local_address_matcher(local_address) 23 | if valid_ip_address?(local_address) 24 | options[:local_address] = local_address 25 | else 26 | raise ArgumentError.new("`be_listening` matcher requires valid IPv4 or IPv6 address") 27 | end 28 | end 29 | 30 | def listening?(protocol, local_address) 31 | protocol_matcher(protocol) if protocol 32 | local_address_matcher(local_address) if local_address 33 | @runner.check_port_is_listening(@name, options) 34 | end 35 | 36 | def valid_ip_address?(ip_address) 37 | !!(ip_address =~ Resolv::IPv4::Regex) || !!(ip_address =~ Resolv::IPv6::Regex) 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/serverspec/type/ppa.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Ppa < Base 3 | def exists? 4 | @runner.check_ppa_exists(@name) 5 | end 6 | 7 | def enabled? 8 | @runner.check_ppa_is_enabled(@name) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/process.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Process < Base 3 | def running? 4 | pid = @runner.get_process(@name, :format => "pid=").stdout 5 | not pid.empty? 6 | end 7 | 8 | def user 9 | get_column("user") 10 | end 11 | 12 | def group 13 | get_column("group") 14 | end 15 | 16 | def count 17 | @runner.count_process(@name).stdout.strip.to_i 18 | end 19 | 20 | def method_missing(meth) 21 | get_column(meth.to_s) 22 | end 23 | 24 | def get_column(keyword) 25 | ret = @runner.get_process(@name, :format => "#{keyword}=") 26 | val = ret.stdout.strip 27 | val = val.to_i if val.match(/^\d+$/) 28 | val 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/serverspec/type/routing_table.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class RoutingTable < Base 3 | def has_entry?(entry) 4 | @runner.check_routing_table_has_entry(entry) 5 | end 6 | 7 | def to_s 8 | 'Routing Table' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/selinux.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Selinux < Base 3 | def disabled? 4 | @runner.check_selinux_has_mode('disabled') 5 | end 6 | 7 | def enforcing?(with_policy) 8 | @runner.check_selinux_has_mode('enforcing', with_policy) 9 | end 10 | 11 | def permissive?(with_policy) 12 | @runner.check_selinux_has_mode('permissive', with_policy) 13 | end 14 | 15 | def to_s 16 | 'SELinux' 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/serverspec/type/selinux_module.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class SelinuxModule < Base 3 | def enabled? 4 | @runner.check_selinux_module_is_enabled(@name) 5 | end 6 | 7 | def installed?(version = nil) 8 | @runner.check_selinux_module_is_installed(@name, version) 9 | end 10 | 11 | def to_s 12 | %(SELinux module "#{@name}") 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/serverspec/type/service.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Service < Base 3 | def enabled?(level, under=nil) 4 | under = under ? "_under_#{under.gsub(/^under_/, '')}" : '' 5 | check_method = "check_service_is_enabled#{under}" 6 | 7 | if level 8 | @runner.send(check_method.to_sym, @name, level) 9 | else 10 | @runner.send(check_method.to_sym, @name) 11 | end 12 | end 13 | 14 | def installed?(name, version) 15 | @runner.check_service_is_installed(@name) 16 | end 17 | 18 | def has_start_mode?(mode) 19 | @runner.check_service_has_start_mode(@name, mode) 20 | end 21 | 22 | def running?(under) 23 | if under 24 | check_method = "check_service_is_running_under_#{under}".to_sym 25 | @runner.send(check_method, @name) 26 | else 27 | @runner.check_service_is_running(@name) 28 | end 29 | end 30 | 31 | def monitored_by?(monitor, monitor_name) 32 | check_method = "check_service_is_monitored_by_#{monitor}".to_sym 33 | # use the with_name value if set instead of the service name 34 | monitor_name = (monitor_name ? monitor_name : @name) 35 | res = @runner.send(check_method, monitor_name) 36 | end 37 | 38 | def has_property?(property) 39 | @runner.check_service_has_property(@name, property) 40 | end 41 | 42 | def property 43 | get_property if @property.nil? 44 | @property 45 | end 46 | 47 | private 48 | def get_property 49 | @property = {} 50 | props = @runner.get_service_property(@name).stdout 51 | props.split(/\n/).each do |line| 52 | property, _type, *value = line.split(/\s+/) 53 | @property[property] = value.join(' ') 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/serverspec/type/user.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class User < Base 3 | def exists? 4 | @runner.check_user_exists(@name) 5 | end 6 | 7 | def belongs_to_group?(group) 8 | @runner.check_user_belongs_to_group(@name, group) 9 | end 10 | 11 | def belongs_to_primary_group?(group) 12 | @runner.check_user_belongs_to_primary_group(@name, group) 13 | end 14 | 15 | def uid 16 | @runner.get_user_uid(@name).stdout.to_i 17 | end 18 | 19 | def has_uid?(uid) 20 | @runner.check_user_has_uid(@name, uid) 21 | end 22 | 23 | def has_home_directory?(path) 24 | @runner.check_user_has_home_directory(@name, path) 25 | end 26 | 27 | def has_login_shell?(shell) 28 | @runner.check_user_has_login_shell(@name, shell) 29 | end 30 | 31 | def has_authorized_key?(key) 32 | @runner.check_user_has_authorized_key(@name, key) 33 | end 34 | 35 | def minimum_days_between_password_change 36 | @runner.get_user_minimum_days_between_password_change(@name).stdout.to_i 37 | end 38 | 39 | def maximum_days_between_password_change 40 | @runner.get_user_maximum_days_between_password_change(@name).stdout.to_i 41 | end 42 | 43 | def encrypted_password 44 | @runner.get_user_encrypted_password(@name).stdout.strip 45 | end 46 | 47 | def is_system_user? 48 | @runner.check_user_is_system_user(@name) 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /lib/serverspec/type/windows_feature.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class WindowsFeature < Base 3 | def installed?(provider, version) 4 | @runner.check_feature_is_enabled(@name, provider) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/serverspec/type/windows_firewall.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class WindowsFirewall < Base 3 | def exists? 4 | @runner.check_firewall_exists(@name) 5 | end 6 | 7 | def tcp? 8 | @runner.check_firewall_has_protocol(@name, 'TCP') 9 | end 10 | 11 | def has_localport?(port) 12 | @runner.check_firewall_has_localport(@name, port) 13 | end 14 | 15 | def inbound? 16 | @runner.check_firewall_has_direction(@name, 'Inbound') 17 | end 18 | 19 | def enabled? 20 | @runner.check_firewall_is_enabled(@name) 21 | end 22 | 23 | def allowed? 24 | @runner.check_firewall_has_action(@name, 'Allow') 25 | end 26 | 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/serverspec/type/windows_hot_fix.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class WindowsHotFix < Base 3 | def installed?(provider, version) 4 | @runner.check_hot_fix_is_installed(@name, version) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/serverspec/type/windows_registry_key.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class WindowsRegistryKey < Base 3 | def exists? 4 | @runner.check_registry_key_exists(@name) 5 | end 6 | 7 | def has_property?(property_name, property_type = :type_string) 8 | @runner.check_registry_key_has_property(@name, {:name => property_name, :type => property_type}) 9 | end 10 | 11 | def has_value?(value) 12 | @runner.check_registry_key_has_value(@name, {:name => '', :type => :type_string, :value => value}) 13 | end 14 | 15 | def has_property_value?(property_name, property_type, value) 16 | @runner.check_registry_key_has_value(@name, {:name => property_name, :type => property_type, :value => value}) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/serverspec/type/windows_scheduled_task.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class WindowsScheduledTask < Base 3 | def exists? 4 | @runner.check_scheduled_task_exists(@name) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/serverspec/type/x509_certificate.rb: -------------------------------------------------------------------------------- 1 | require 'time' 2 | 3 | module Serverspec::Type 4 | class X509Certificate < Base 5 | def certificate? 6 | (run_openssl_command_with("-noout").exit_status == 0) 7 | end 8 | 9 | def subject 10 | normalize_dn(run_openssl_command_with("-subject -noout").stdout.chomp.gsub(/^subject= */,'')) 11 | end 12 | 13 | def issuer 14 | normalize_dn(run_openssl_command_with("-issuer -noout").stdout.chomp.gsub(/^issuer= */,'')) 15 | end 16 | 17 | def email 18 | run_openssl_command_with("-email -noout").stdout.chomp 19 | end 20 | 21 | def fingerprint 22 | run_openssl_command_with("-fingerprint -noout").stdout.chomp 23 | end 24 | 25 | def alias 26 | run_openssl_command_with("-alias -noout").stdout.chomp 27 | end 28 | 29 | # Modern openssl use following output format for key length: 30 | # Public-Key: (4096 bit) 31 | # while ancient (0.9.8 for example) use 32 | # RSA Public Key: (2048 bit) 33 | def keylength 34 | len_str = run_openssl_command_with("-text -noout | grep -E 'Public(-| )Key: \\([[:digit:]]+ bit\\)'").stdout.chomp 35 | len_str.gsub(/^.*\(/,'').gsub(/ bit\)$/,'').to_i 36 | end 37 | 38 | def has_purpose?(p) 39 | grep_str = "#{p} : Yes" 40 | ( run_openssl_command_with("-purpose -noout | grep -wq \"#{grep_str}\""). 41 | exit_status == 0 ) 42 | end 43 | 44 | def valid? 45 | runner_res = run_openssl_command_with("-startdate -enddate -noout") 46 | return false if runner_res.exit_status != 0 47 | 48 | date_map = parse_dates_str_to_map(runner_res.stdout) 49 | 50 | now = Time.now 51 | ( now >= date_map[:notBefore] && now <= date_map[:notAfter]) 52 | end 53 | 54 | def validity_in_days 55 | runner_res = run_openssl_command_with("-enddate -noout") 56 | return 0 if runner_res.exit_status != 0 57 | 58 | date_map = parse_dates_str_to_map(runner_res.stdout) 59 | diff = date_map[:notAfter] - Time.now 60 | ( diff/(60*60*24) ) 61 | end 62 | 63 | def subject_alt_names 64 | text = run_openssl_command_with('-text -noout').stdout 65 | # X509v3 Subject Alternative Name: 66 | # DNS:*.example.com, DNS:www.example.net, IP:192.0.2.10 67 | if text =~ /^ *X509v3 Subject Alternative Name:.*\n *(.*)$/ 68 | $1.split(/, +/) 69 | end 70 | end 71 | 72 | private 73 | def run_openssl_command_with(param_str) 74 | @runner.run_command("openssl x509 -in #{name} #{param_str}") 75 | end 76 | 77 | def parse_dates_str_to_map(dates_str) 78 | dates_str.split("\n").inject({}) do |res,line| 79 | kv_arr = line.split '=' 80 | time = Time.strptime(kv_arr[1],'%b %e %T %Y %Z') rescue Time.parse(kv_arr[1] || '') 81 | res.merge({ kv_arr[0].to_sym => time }) 82 | end 83 | end 84 | 85 | # Normalize output between openssl versions. 86 | def normalize_dn(dn) 87 | return dn unless dn.start_with?('/') 88 | # normalize openssl < 1.1 to >= 1.1 output 89 | dn[1..-1].split('/').join(', ').gsub('=', ' = ') 90 | end 91 | end 92 | end 93 | -------------------------------------------------------------------------------- /lib/serverspec/type/x509_private_key.rb: -------------------------------------------------------------------------------- 1 | require 'time' 2 | 3 | module Serverspec::Type 4 | class X509PrivateKey < Base 5 | def valid? 6 | runner_res = @runner.run_command("echo | openssl rsa -in #{name} -check -noout -passin #{@options[:passin] || "stdin"}") 7 | ( runner_res.exit_status == 0 && runner_res.stdout.chomp == 'RSA key ok' ) && (!@options.has_key?(:passin) || encrypted?) 8 | end 9 | 10 | def encrypted? 11 | @runner.run_command("grep -Ewq \"^(Proc-Type.*ENCRYPTED|-----BEGIN ENCRYPTED PRIVATE KEY-----)$\" #{name}").exit_status == 0 12 | end 13 | 14 | def has_matching_certificate?(cert_file) 15 | h1 = @runner.run_command("openssl x509 -noout -modulus -in #{cert_file}") 16 | h2 = @runner.run_command("echo | openssl rsa -noout -modulus -in #{name} -passin #{@options[:passin] || "stdin"}") 17 | (h1.stdout == h2.stdout) && (h1.exit_status == 0) && (h2.exit_status == 0) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/serverspec/type/yumrepo.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Yumrepo < Base 3 | def exists? 4 | @runner.check_yumrepo_exists(@name) 5 | end 6 | 7 | def enabled? 8 | @runner.check_yumrepo_is_enabled(@name) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/serverspec/type/zfs.rb: -------------------------------------------------------------------------------- 1 | module Serverspec::Type 2 | class Zfs < Base 3 | def exists? 4 | @runner.check_zfs_exists(@name) 5 | end 6 | 7 | def has_property?(property) 8 | @runner.check_zfs_has_property(@name, property) 9 | end 10 | 11 | def to_s 12 | 'ZFS' 13 | end 14 | 15 | def property 16 | get_property if @property.nil? 17 | @property 18 | end 19 | 20 | private 21 | def get_property 22 | @property = Hash.new 23 | @runner.get_zfs_property(@name).stdout.split(/\n/).each do |line| 24 | property, value = line.split(/\s+/) 25 | @property[property] = value 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/serverspec/version.rb: -------------------------------------------------------------------------------- 1 | module Serverspec 2 | VERSION = "2.43.0" 3 | end 4 | -------------------------------------------------------------------------------- /serverspec.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'serverspec/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "serverspec" 8 | spec.version = Serverspec::VERSION 9 | spec.authors = ["Gosuke Miyashita"] 10 | spec.email = ["gosukenator@gmail.com"] 11 | spec.description = %q{RSpec tests for your servers configured by Puppet, Chef, Itamae or anything else} 12 | spec.summary = %q{RSpec tests for your servers configured by Puppet, Chef, Itamae or anything else} 13 | spec.homepage = "http://serverspec.org/" 14 | spec.license = "MIT" 15 | 16 | spec.files = `git ls-files`.split($/) 17 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 18 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 19 | spec.require_paths = ["lib"] 20 | 21 | spec.add_runtime_dependency "rspec", "~> 3.0" 22 | spec.add_runtime_dependency "rspec-its" 23 | spec.add_runtime_dependency "multi_json" 24 | spec.add_runtime_dependency "specinfra", "~> 2.72" 25 | 26 | if RUBY_VERSION < "1.9" 27 | spec.add_development_dependency "json", "~> 1.8" 28 | spec.add_development_dependency "rake", "~> 10.1.1" 29 | else 30 | spec.add_development_dependency "rake" 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /spec/helper/type_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe String do 4 | subject { String.new } 5 | it { should_not respond_to :host } 6 | end 7 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'serverspec' 2 | 3 | set :backend, :exec 4 | 5 | module Specinfra 6 | module Backend 7 | class Exec < Base 8 | def run_command cmd 9 | CommandResult.new({ 10 | :stdout => ::Specinfra.configuration.stdout, 11 | :stderr => ::Specinfra.configuration.stderr, 12 | :exit_status => ::Specinfra.configuration.exit_status, 13 | :exit_signal => nil, 14 | }) 15 | end 16 | end 17 | class Cmd < Base 18 | def run_command cmd 19 | CommandResult.new({ 20 | :stdout => ::Specinfra.configuration.stdout, 21 | :stderr => ::Specinfra.configuration.stderr, 22 | :exit_status => ::Specinfra.configuration.exit_status, 23 | :exit_signal => nil, 24 | }) 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/type/aix/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, {:family => 'aix'} 4 | 5 | describe file('/tmp') do 6 | it { should be_readable.by_user('mail') } 7 | end 8 | 9 | describe file('/tmp') do 10 | it { should be_writable.by_user('mail') } 11 | end 12 | 13 | describe file('/tmp') do 14 | it { should be_executable.by_user('mail') } 15 | end 16 | 17 | describe file('/etc/passwd') do 18 | it { should be_mode 644 } 19 | end 20 | 21 | describe file('/etc/passwd') do 22 | it { should be_owned_by 'root' } 23 | end 24 | 25 | describe file('/etc/passwd') do 26 | it { should be_grouped_into 'root' } 27 | end 28 | -------------------------------------------------------------------------------- /spec/type/aix/group_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'aix' 4 | 5 | describe group('root') do 6 | it { should have_gid 0 } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/aix/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'aix' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/aix/port_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'aix' 4 | 5 | describe port(80) do 6 | it { should be_listening } 7 | end 8 | 9 | describe port(80) do 10 | it { should be_listening.with('tcp') } 11 | end 12 | 13 | describe port(80) do 14 | it { should be_listening.on('127.0.0.1') } 15 | end 16 | 17 | describe port(53) do 18 | it { should be_listening.with('udp') } 19 | end 20 | 21 | -------------------------------------------------------------------------------- /spec/type/aix/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'aix' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | 13 | -------------------------------------------------------------------------------- /spec/type/aix/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'aix' 4 | 5 | describe user('root') do 6 | it { should belong_to_group 'root' } 7 | end 8 | 9 | describe user('root') do 10 | it { should have_login_shell '/bin/bash' } 11 | end 12 | 13 | describe user('root') do 14 | it { should have_home_directory '/root' } 15 | end 16 | 17 | -------------------------------------------------------------------------------- /spec/type/arch/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'arch' 4 | 5 | describe file('/tmp') do 6 | it { should be_readable.by_user('mail') } 7 | end 8 | 9 | describe file('/tmp') do 10 | it { should be_writable.by_user('mail') } 11 | end 12 | 13 | describe file('/tmp') do 14 | it { should be_executable.by_user('mail') } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/arch/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'arch' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | let(:stdout) { "2.2.15\n" } 15 | its(:version) { should eq '2.2.15' } 16 | its(:version) { should > '2.2.14' } 17 | its(:version) { should < '2.2.16' } 18 | its(:version) { should > '2.2.9' } 19 | end 20 | -------------------------------------------------------------------------------- /spec/type/arch/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'arch' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | it { should be_running } 8 | end 9 | 10 | -------------------------------------------------------------------------------- /spec/type/base/command_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe command('cat /etc/resolv.conf') do 6 | let(:stdout) { "nameserver 127.0.0.1\r\n" } 7 | its(:stdout) { should match /nameserver 127.0.0.1/ } 8 | end 9 | 10 | describe 'complete matching of stdout' do 11 | context command('cat /etc/resolv.conf') do 12 | let(:stdout) { "foocontent-should-be-includedbar\r\n" } 13 | its(:stdout) { should_not eq 'content-should-be-included' } 14 | end 15 | end 16 | 17 | describe 'regexp matching of stdout' do 18 | context command('cat /etc/resolv.conf') do 19 | let(:stdout) { "nameserver 127.0.0.1\r\n" } 20 | its(:stdout) { should match /127\.0\.0\.1/ } 21 | end 22 | end 23 | 24 | describe command('cat /etc/resolv.conf') do 25 | let(:stderr) { "No such file or directory\r\n" } 26 | its(:stderr) { should match /No such file or directory/ } 27 | end 28 | 29 | describe 'complete matching of stderr' do 30 | context command('cat /etc/resolv.conf') do 31 | let(:stderr) { "No such file or directory\r\n" } 32 | its(:stdout) { should_not eq 'file' } 33 | end 34 | end 35 | 36 | describe 'regexp matching of stderr' do 37 | context command('cat /etc/resolv.conf') do 38 | let(:stderr) { "No such file or directory\r\n" } 39 | its(:stderr) { should match /file/ } 40 | end 41 | end 42 | 43 | describe command('cat /etc/resolv.conf') do 44 | its(:exit_status) { should eq 0 } 45 | end 46 | 47 | describe command('ls -al /') do 48 | let(:stdout) { < include('version' => '0.26.5')) } 103 | its(:stdout_as_json) { should include('transport' => include('keepalives' => include('consumers' => 1))) } 104 | its(:stdout_as_json) { should include('transport' => include('connected' => true)) } 105 | its(:stdout_as_json) { should include('array' => include('title' => 'array 2')) } 106 | end 107 | -------------------------------------------------------------------------------- /spec/type/base/cron_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe cron do 6 | it { should have_entry '* * * * * /usr/local/bin/batch.sh' } 7 | end 8 | 9 | describe cron do 10 | it { should have_entry('* * * * * /usr/local/bin/batch.sh').with_user('root') } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/base/default_gateway_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe default_gateway do 6 | let(:stdout) { "default via 192.168.1.1 dev eth1 \r\n" } 7 | its(:ipaddress) { should eq '192.168.1.1' } 8 | its(:interface) { should eq 'eth1' } 9 | its(:ipaddress) { should_not eq '192.168.1.2' } 10 | its(:interface) { should_not eq 'eth0' } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/base/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, {:family => 'base'} 4 | 5 | describe file('/etc/ssh/sshd_config') do 6 | it { should be_file } 7 | end 8 | 9 | describe file('/etc/ssh') do 10 | it { should be_directory } 11 | end 12 | 13 | describe file('/var/run/unicorn.sock') do 14 | it { should be_socket } 15 | end 16 | 17 | describe file('/dev/disk0') do 18 | it { should be_block_device } 19 | end 20 | 21 | describe file('/dev/ttys0') do 22 | it { should be_character_device } 23 | end 24 | 25 | describe file('/var/run/pure-ftpd/pure-ftpd.upload.pipe') do 26 | it { should be_pipe } 27 | end 28 | 29 | describe file('/bin/sh') do 30 | it { should be_symlink } 31 | end 32 | 33 | describe file('/bin/sh') do 34 | it { should exist } 35 | end 36 | 37 | describe file('/etc/ssh/sshd_config') do 38 | it { should contain 'This is the sshd server system-wide configuration file' } 39 | end 40 | 41 | describe file('/etc/ssh/sshd_config') do 42 | it { should contain /^This is the sshd server system-wide configuration file/ } 43 | end 44 | 45 | describe file('Gemfile') do 46 | it { should contain('rspec').from(/^group :test do/).to(/^end/) } 47 | end 48 | 49 | describe file('Gemfile') do 50 | it { should contain('rspec').after(/^group :test do/) } 51 | end 52 | 53 | describe file('Gemfile') do 54 | it { should contain('rspec').before(/^end/) } 55 | end 56 | 57 | describe file('/etc/passwd') do 58 | it { should be_mode 644 } 59 | end 60 | 61 | describe file('/etc/passwd') do 62 | it { should be_owned_by 'root' } 63 | end 64 | 65 | describe file('/etc/passwd') do 66 | it { should be_grouped_into 'root' } 67 | end 68 | 69 | describe file('/etc/pam.d/system-auth') do 70 | it { should be_linked_to '/etc/pam.d/system-auth-ac' } 71 | end 72 | 73 | describe file('/dev') do 74 | let(:stdout) { "755\r\n" } 75 | it { should be_readable } 76 | end 77 | 78 | describe file('/dev') do 79 | let(:stdout) { "333\r\n" } 80 | it { should_not be_readable } 81 | end 82 | 83 | describe file('/dev') do 84 | let(:stdout) { "400\r\n" } 85 | it { should be_readable.by('owner') } 86 | end 87 | 88 | describe file('/dev') do 89 | let(:stdout) { "044\r\n" } 90 | it { should_not be_readable.by('owner') } 91 | end 92 | 93 | describe file('/dev') do 94 | let(:stdout) { "040\r\n" } 95 | it { should be_readable.by('group') } 96 | end 97 | 98 | describe file('/dev') do 99 | let(:stdout) { "404\r\n" } 100 | it { should_not be_readable.by('group') } 101 | end 102 | 103 | describe file('/dev') do 104 | let(:stdout) { "044\r\n" } 105 | it { should be_readable.by('others') } 106 | end 107 | 108 | describe file('/dev') do 109 | let(:stdout) { "443\r\n" } 110 | it { should_not be_readable.by('others') } 111 | end 112 | 113 | describe file('/dev') do 114 | let(:stdout) { "755\r\n" } 115 | it { should be_writable } 116 | end 117 | 118 | describe file('/dev') do 119 | let(:stdout) { "555\r\n" } 120 | it { should_not be_writable } 121 | end 122 | 123 | describe file('/dev') do 124 | let(:stdout) { "200\r\n" } 125 | it { should be_writable.by('owner') } 126 | end 127 | 128 | describe file('/dev') do 129 | let(:stdout) { "555\r\n" } 130 | it { should_not be_writable.by('owner') } 131 | end 132 | 133 | describe file('/dev') do 134 | let(:stdout) { "030\r\n" } 135 | it { should be_writable.by('group') } 136 | end 137 | 138 | describe file('/dev') do 139 | let(:stdout) { "555\r\n" } 140 | it { should_not be_writable.by('group') } 141 | end 142 | 143 | describe file('/dev') do 144 | let(:stdout) { "666\r\n" } 145 | it { should be_writable.by('others') } 146 | end 147 | 148 | describe file('/dev') do 149 | let(:stdout) { "555\r\n" } 150 | it { should_not be_writable.by('others') } 151 | end 152 | 153 | 154 | describe file('/dev') do 155 | let(:stdout) { "755\r\n" } 156 | it { should be_executable } 157 | end 158 | 159 | describe file('/dev') do 160 | let(:stdout) { "666\r\n" } 161 | it { should_not be_executable } 162 | end 163 | 164 | describe file('/dev') do 165 | let(:stdout) { "100\r\n" } 166 | it { should be_executable.by('owner') } 167 | end 168 | 169 | describe file('/dev') do 170 | let(:stdout) { "666\r\n" } 171 | it { should_not be_executable.by('owner') } 172 | end 173 | 174 | describe file('/dev') do 175 | let(:stdout) { "070\r\n" } 176 | it { should be_executable.by('group') } 177 | end 178 | 179 | describe file('/dev') do 180 | let(:stdout) { "666\r\n" } 181 | it { should_not be_executable.by('group') } 182 | end 183 | 184 | describe file('/dev') do 185 | let(:stdout) { "001\r\n" } 186 | it { should be_executable.by('others') } 187 | end 188 | 189 | describe file('/dev') do 190 | let(:stdout) { "666\r\n" } 191 | it { should_not be_executable.by('others') } 192 | end 193 | 194 | describe file('/') do 195 | it { should be_mounted } 196 | end 197 | 198 | describe file('/') do 199 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 200 | it { should be_mounted.with( :type => 'ext4' ) } 201 | end 202 | 203 | describe file('/') do 204 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 205 | it { should be_mounted.with( :type => 'ext4', :options => { :rw => true } ) } 206 | end 207 | 208 | describe file('/') do 209 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 210 | it { should be_mounted.with( :type => 'ext4', :options => { :mode => 620 } ) } 211 | end 212 | 213 | describe file('/') do 214 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 215 | it { should be_mounted.with( :type => 'ext4', :device => '/dev/mapper/VolGroup-lv_root' ) } 216 | end 217 | 218 | describe file('/') do 219 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 220 | it { should_not be_mounted.with( :type => 'xfs' ) } 221 | end 222 | 223 | describe file('/') do 224 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 225 | it { should_not be_mounted.with( :type => 'ext4', :options => { :rw => false } ) } 226 | end 227 | 228 | describe file('/') do 229 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 230 | it { should_not be_mounted.with( :type => 'ext4', :options => { :mode => 600 } ) } 231 | end 232 | 233 | describe file('/') do 234 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 235 | it { should_not be_mounted.with( :type => 'xfs', :device => '/dev/mapper/VolGroup-lv_root' ) } 236 | end 237 | 238 | describe file('/') do 239 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 240 | it { should_not be_mounted.with( :type => 'ext4', :device => '/dev/mapper/VolGroup-lv_r00t' ) } 241 | end 242 | 243 | describe file('/') do 244 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 245 | it do 246 | should be_mounted.only_with( 247 | :device => '/dev/mapper/VolGroup-lv_root', 248 | :type => 'ext4', 249 | :options => { 250 | :rw => true, 251 | :mode => 620, 252 | } 253 | ) 254 | end 255 | end 256 | 257 | describe file('/') do 258 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 259 | it do 260 | should_not be_mounted.only_with( 261 | :device => '/dev/mapper/VolGroup-lv_root', 262 | :type => 'ext4', 263 | :options => { 264 | :rw => true, 265 | :mode => 620, 266 | :bind => true, 267 | } 268 | ) 269 | end 270 | end 271 | 272 | describe file('/') do 273 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 274 | it do 275 | should_not be_mounted.only_with( 276 | :device => '/dev/mapper/VolGroup-lv_root', 277 | :type => 'ext4', 278 | :options => { 279 | :rw => true, 280 | } 281 | ) 282 | end 283 | end 284 | 285 | describe file('/') do 286 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 287 | it do 288 | should_not be_mounted.only_with( 289 | :device => '/dev/mapper/VolGroup-lv_roooooooooot', 290 | :type => 'ext4', 291 | :options => { 292 | :rw => true, 293 | :mode => 620, 294 | } 295 | ) 296 | end 297 | end 298 | 299 | describe file('/etc/invalid-mount') do 300 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 301 | it { should_not be_mounted.only_with( :type => 'ext4' ) } 302 | end 303 | 304 | describe file('/etc/services') do 305 | let(:stdout) { "35435ea447c19f0ea5ef971837ab9ced\n" } 306 | its(:md5sum) { should eq '35435ea447c19f0ea5ef971837ab9ced' } 307 | end 308 | 309 | describe file('invalid-file') do 310 | its(:md5sum) { should_not eq 'INVALIDMD5CHECKSUM' } 311 | end 312 | 313 | describe file('/etc/services') do 314 | let(:stdout) {"0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a" } 315 | its(:sha256sum) { should eq '0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a' } 316 | end 317 | 318 | describe file('invalid-file') do 319 | its(:sha256sum) { should_not eq 'INVALIDSHA256CHECKSUM' } 320 | end 321 | 322 | describe file('/etc/passwd') do 323 | let(:stdout) { "root\r\n" } 324 | its(:group) { should eq 'root' } 325 | end 326 | 327 | describe file('/etc/passwd') do 328 | let(:stdout) {< include('title' => 'this is a json')) } 365 | its(:content_as_json) { should include('json' => include('array' => include('title' => 'array 2'))) } 366 | end 367 | 368 | describe file('example.yml') do 369 | let(:stdout) {< include('title' => 'this is a yaml')) } 385 | its(:content_as_yaml) { should include('yaml' => include('array' => include('title' => 'array 2'))) } 386 | its(:content_as_yaml) { should include('yaml' => include('date' => Date.new(2023, 2, 3))) } 387 | its(:content_as_yaml) { should include('yaml' => include('Reuse anchor' => 'this is a yaml')) } 388 | end 389 | 390 | 391 | describe file('/etc/pam.d/system-auth') do 392 | let(:stdout) { "/etc/pam.dsystem-auth-ac\r\n" } 393 | its(:link_target) { should eq '/etc/pam.dsystem-auth-ac' } 394 | end 395 | 396 | describe file('/etc/passwd') do 397 | let(:stdout) { "644\r\n" } 398 | its(:mode) { should eq '644' } 399 | end 400 | 401 | describe file('/etc/passwd') do 402 | let(:stdout) { Time.now.to_i.to_s } 403 | its(:mtime) { should > DateTime.now - 1 } 404 | end 405 | 406 | describe file('/etc/passwd') do 407 | let(:stdout) { "root\r\n" } 408 | its(:owner) { should eq 'root' } 409 | end 410 | 411 | describe file('/etc/passwod') do 412 | let(:stdout) { 100.to_s } 413 | its(:size) { should > 0 } 414 | end 415 | 416 | describe file('/etc/passwd') do 417 | it 'be_immutable is not implemented in base class' do 418 | expect { 419 | should be_immutable 420 | }.to raise_error(/is not implemented in Specinfra/) 421 | end 422 | end 423 | -------------------------------------------------------------------------------- /spec/type/base/group_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe group('root') do 6 | it { should exist } 7 | end 8 | 9 | describe group('root') do 10 | it { should have_gid 0 } 11 | end 12 | 13 | describe group('root') do 14 | its(:gid) { should == 0 } 15 | its(:gid) { should < 10 } 16 | end 17 | 18 | describe group('root') do 19 | it { should be_is_system_group } 20 | end 21 | -------------------------------------------------------------------------------- /spec/type/base/host_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe host('127.0.0.1') do 6 | it { should be_resolvable } 7 | end 8 | 9 | describe host('127.0.0.1') do 10 | it { should be_resolvable.by('hosts') } 11 | end 12 | 13 | describe host('127.0.0.1') do 14 | it { should be_resolvable.by('dns') } 15 | end 16 | 17 | describe host('127.0.0.1') do 18 | it { should be_reachable } 19 | end 20 | 21 | describe host('127.0.0.1') do 22 | it { should be_reachable.with(:proto => "icmp", :timeout=> 1) } 23 | end 24 | 25 | describe host('127.0.0.1') do 26 | it { should be_reachable.with(:proto => "tcp", :port => 22, :timeout=> 1) } 27 | end 28 | 29 | describe host('127.0.0.1') do 30 | it { should be_reachable.with(:proto => "udp", :port => 53, :timeout=> 1) } 31 | end 32 | 33 | describe host('example.jp') do 34 | let(:stdout) { "1.2.3.4\r\n" } 35 | its(:ipaddress) { should eq '1.2.3.4' } 36 | end 37 | 38 | describe host('example.jp') do 39 | let(:stdout) { "1.2.3.4\r\n" } 40 | its(:ipv4_address) { should match(/^[\d.]+$/) } 41 | end 42 | 43 | describe host('example.jp') do 44 | let(:stdout) { "2001:db8::1234\r\n" } 45 | its(:ipv6_address) { should match(/^[a-f\d:]+$/i) } 46 | end 47 | 48 | -------------------------------------------------------------------------------- /spec/type/base/json_file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, {:family => 'base'} 4 | 5 | describe json_file('example.json') do 6 | let(:stdout) {< include('title' => 'this is a json')) } 25 | its(:content) { should include('json' => include('array' => include('title' => 'array 2'))) } 26 | end 27 | 28 | -------------------------------------------------------------------------------- /spec/type/base/mail_alias_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe mail_alias('daemon') do 6 | it { should be_aliased_to "root" } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/base/mysql_config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe mysql_config('innodb-buffer-pool-size') do 6 | let(:stdout) { 'innodb-buffer-pool-size 134217728' } 7 | its(:value) { should eq 134217728 } 8 | end 9 | 10 | describe mysql_config('socket') do 11 | let(:stdout) { 'socket /tmp/mysql.sock' } 12 | its(:value) { should eq '/tmp/mysql.sock' } 13 | end 14 | -------------------------------------------------------------------------------- /spec/type/base/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe package('jekyll') do 6 | it { should be_installed.by(:gem) } 7 | end 8 | 9 | describe package('jekyll') do 10 | it { should be_installed.by(:gem).with_version('1.1.1') } 11 | end 12 | 13 | describe package('ruby') do 14 | it { should be_installed.by(:rvm) } 15 | end 16 | 17 | describe package('ruby') do 18 | it { should be_installed.by(:rvm).with_version('2.2.0') } 19 | end 20 | 21 | describe package('bower') do 22 | it { should be_installed.by(:npm) } 23 | end 24 | 25 | describe package('bower') do 26 | it { should be_installed.by(:npm).with_version('0.9.2') } 27 | end 28 | 29 | describe package('mongo') do 30 | it { should be_installed.by(:pecl) } 31 | end 32 | 33 | describe package('mongo') do 34 | it { should be_installed.by(:pecl).with_version('1.4.1') } 35 | end 36 | 37 | describe package('XML_Util') do 38 | it { should be_installed.by(:pear).with_version('1.2.1') } 39 | end 40 | 41 | describe package('supervisor') do 42 | it { should be_installed.by(:pip).with_version('3.0') } 43 | end 44 | 45 | describe package('App::Ack') do 46 | it { should be_installed.by(:cpan) } 47 | end 48 | 49 | describe package('App::Ack') do 50 | it { should be_installed.by(:cpan).with_version('2.04') } 51 | end 52 | -------------------------------------------------------------------------------- /spec/type/base/php_config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe php_config('default_mimetype') do 6 | let(:stdout) { 'text/html' } 7 | its(:value) { should eq 'text/html' } 8 | end 9 | 10 | describe php_config('default_mimetype') do 11 | let(:stdout) { 'text/html' } 12 | its(:value) { should_not eq 'text/plain' } 13 | end 14 | 15 | describe php_config('session.cache_expire') do 16 | let(:stdout) { '180' } 17 | its(:value) { should eq 180 } 18 | end 19 | 20 | describe php_config('session.cache_expire') do 21 | let(:stdout) { '180' } 22 | its(:value) { should_not eq 360 } 23 | end 24 | 25 | describe php_config('mbstring.http_output_conv_mimetypes') do 26 | let(:stdout) { 'application' } 27 | its(:value) { should match /application/ } 28 | end 29 | 30 | describe php_config('mbstring.http_output_conv_mimetypes') do 31 | let(:stdout) { 'application' } 32 | its(:value) { should_not match /html/ } 33 | end 34 | describe php_config('default_mimetype', :ini => '/etc/php5/php.ini') do 35 | let(:stdout) { 'text/html' } 36 | its(:value) { should eq 'text/html' } 37 | end 38 | -------------------------------------------------------------------------------- /spec/type/base/php_extension_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe php_extension('tillext') do 6 | let(:exit_status) { 1 } 7 | it { should_not be_loaded } 8 | end 9 | 10 | describe php_extension('session') do 11 | let(:exit_status) { 0 } 12 | it { should be_loaded } 13 | end 14 | -------------------------------------------------------------------------------- /spec/type/base/port_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe port(80) do 6 | it { should be_listening } 7 | end 8 | 9 | describe port(80) do 10 | it { should be_listening.with('tcp') } 11 | end 12 | 13 | describe port(80) do 14 | it do 15 | expect { 16 | should be_listening.with('not implemented') 17 | }.to raise_error(ArgumentError, %r/\A`be_listening` matcher doesn\'t support/) 18 | end 19 | end 20 | 21 | describe port(80) do 22 | it { should be_listening.on('127.0.0.1') } 23 | end 24 | 25 | describe port(80) do 26 | it do 27 | expect{ should be_listening.on('') }.to raise_error(ArgumentError) 28 | end 29 | end 30 | 31 | describe port(53) do 32 | it { should be_listening.with('udp') } 33 | end 34 | 35 | -------------------------------------------------------------------------------- /spec/type/base/process_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe process("memcached") do 6 | let(:stdout) { " 1407\n" } 7 | its(:pid) { should eq 1407 } 8 | end 9 | 10 | describe process("memcached") do 11 | let(:stdout) { "/usr/bin/memcached -m 14386 -p 11211 -u nobody -l 10.11.1.53 -c 30000\n" } 12 | its(:args) { should match /-c 30000\b/ } 13 | end 14 | 15 | describe process("memcached") do 16 | let(:stdout) { "nobody\n" } 17 | its(:user) { should eq "nobody" } 18 | end 19 | 20 | describe process("memcached") do 21 | let(:stdout) { "nobody\n" } 22 | its(:group) { should eq "nobody" } 23 | end 24 | 25 | describe process("memcached") do 26 | context "when running" do 27 | let(:stdout) { " 1407\n" } 28 | it { should be_running } 29 | end 30 | 31 | context "when not running" do 32 | let(:stdout) { " 1407\n" } 33 | it { should be_running } 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/type/base/routing_table_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe routing_table do 6 | let(:stdout) { "192.168.100.0/24 dev eth1 proto kernel scope link src 192.168.100.10 \r\n" } 7 | it { should have_entry( :destination => '192.168.100.0/24' ) } 8 | end 9 | 10 | describe routing_table do 11 | let(:exit_status) { 1 } 12 | it { should_not have_entry( :destination => '192.168.100.100/24' ) } 13 | end 14 | 15 | describe routing_table do 16 | let(:stdout) { "192.168.100.0/24 dev eth1 proto kernel scope link src 192.168.100.10 \r\n" } 17 | it do 18 | should have_entry( 19 | :destination => '192.168.100.0/24', 20 | :interface => 'eth1' 21 | ) 22 | end 23 | end 24 | 25 | describe routing_table do 26 | let(:stdout) { "192.168.200.0/24 via 192.168.200.1 dev eth0 \r\n" } 27 | it { should have_entry( :destination => '192.168.200.0/24' ) } 28 | 29 | it do 30 | should have_entry( 31 | :destination => '192.168.200.0/24', 32 | :gateway => '192.168.200.1' 33 | ) 34 | end 35 | 36 | it do 37 | should have_entry( 38 | :destination => '192.168.200.0/24', 39 | :gateway => '192.168.200.1', 40 | :interface => 'eth0' 41 | ) 42 | end 43 | end 44 | 45 | describe routing_table do 46 | let(:stdout) { "default via 10.0.2.2 dev eth0 \r\n" } 47 | it { should have_entry( :destination => 'default' ) } 48 | 49 | it do 50 | should have_entry( 51 | :destination => 'default', 52 | :gateway => '10.0.2.2' 53 | ) 54 | end 55 | 56 | it do 57 | should have_entry( 58 | :destination => 'default', 59 | :gateway => '10.0.2.2', 60 | :interface => 'eth0' 61 | ) 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /spec/type/base/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe service('sshd') do 6 | it { should be_running } 7 | end 8 | 9 | describe service('sshd') do 10 | let(:stdout) { "sshd is stopped\r\n" } 11 | it { should be_running } 12 | end 13 | 14 | describe service('sshd') do 15 | it { should be_running.under(:supervisor) } 16 | end 17 | 18 | describe service('sshd') do 19 | it { should be_running.under(:upstart) } 20 | end 21 | 22 | describe service('sshd') do 23 | it { should be_running.under(:daemontools) } 24 | end 25 | 26 | describe service('sshd') do 27 | it { 28 | expect { 29 | should be_running.under('not implemented') 30 | }.to raise_error(/is not implemented in Specinfra/) 31 | } 32 | end 33 | 34 | describe service('sshd') do 35 | let(:stdout) { "Process 'sshd'\r\n status running\r\n monitoring status monitored" } 36 | it { should be_monitored_by(:monit) } 37 | end 38 | 39 | describe service('tinc') do 40 | let(:stdout) { "Process 'tinc-myvpn'\r\n status running\r\n monitoring status monitored" } 41 | it { should be_monitored_by(:monit).with_name('tinc-myvpn') } 42 | end 43 | 44 | describe service('unicorn') do 45 | it { should be_monitored_by(:god) } 46 | end 47 | 48 | describe service('sshd') do 49 | it { 50 | expect { 51 | should be_monitored_by('not implemented') 52 | }.to raise_error(NotImplementedError) 53 | } 54 | end 55 | -------------------------------------------------------------------------------- /spec/type/base/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'base' 4 | 5 | describe user('root') do 6 | it { should exist } 7 | end 8 | 9 | describe user('root') do 10 | it { should belong_to_group 'root' } 11 | end 12 | 13 | describe user('root') do 14 | it { should belong_to_primary_group 'root' } 15 | end 16 | 17 | describe user('root') do 18 | it { should have_uid 0 } 19 | end 20 | 21 | describe user('root') do 22 | its(:uid) { should == 0 } 23 | its(:uid) { should < 10 } 24 | end 25 | 26 | describe user('root') do 27 | it { should have_login_shell '/bin/bash' } 28 | end 29 | 30 | describe user('root') do 31 | it { should have_home_directory '/root' } 32 | end 33 | 34 | describe user('root') do 35 | it { should have_authorized_key 'ssh-rsa ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGH foo@bar.local' } 36 | end 37 | 38 | describe user('root') do 39 | let(:stdout) { "$1$T0aTw9NJ$NdMldLUQ8WqhlEEGToNzl/\n" } 40 | its(:encrypted_password) { should eq '$1$T0aTw9NJ$NdMldLUQ8WqhlEEGToNzl/' } 41 | end 42 | 43 | describe user('root') do 44 | its(:minimum_days_between_password_change) { should == 0 } 45 | end 46 | 47 | describe user('root') do 48 | its(:maximum_days_between_password_change) { should == 0 } 49 | end 50 | 51 | describe user('root') do 52 | it { should be_is_system_user } 53 | end 54 | -------------------------------------------------------------------------------- /spec/type/darwin/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'darwin' 4 | 5 | describe file('/tmp') do 6 | it { should be_readable.by_user('mail') } 7 | end 8 | 9 | describe file('/tmp') do 10 | it { should be_writable.by_user('mail') } 11 | end 12 | 13 | describe file('/tmp') do 14 | it { should be_executable.by_user('mail') } 15 | end 16 | 17 | describe file('/etc/services') do 18 | let(:stdout) { "35435ea447c19f0ea5ef971837ab9ced\n" } 19 | its(:md5sum) { should eq '35435ea447c19f0ea5ef971837ab9ced' } 20 | end 21 | 22 | describe file('/etc/services') do 23 | let(:stdout) {"0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a" } 24 | its(:sha256sum) { should eq '0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a' } 25 | end 26 | 27 | describe file('/etc/pam.d/system-auth') do 28 | it { should be_linked_to '/etc/pam.d/system-auth-ac' } 29 | end 30 | 31 | describe file('/etc/passwd') do 32 | it { should be_mode 644 } 33 | end 34 | 35 | describe file('/etc/passwd') do 36 | it { should be_owned_by 'root' } 37 | end 38 | 39 | describe file('/etc/passwd') do 40 | it { should be_grouped_into 'root' } 41 | end 42 | -------------------------------------------------------------------------------- /spec/type/darwin/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'darwin' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | it { should be_installed.by('homebrew') } 15 | end 16 | 17 | describe package('httpd') do 18 | it { should be_installed.by('pkgutil') } 19 | end 20 | -------------------------------------------------------------------------------- /spec/type/darwin/port_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'darwin' 4 | 5 | describe port(80) do 6 | it { should be_listening } 7 | end 8 | 9 | describe port(80) do 10 | it { should be_listening.with('tcp') } 11 | end 12 | 13 | describe port(80) do 14 | it do 15 | expect { 16 | should be_listening.with('not implemented') 17 | }.to raise_error(ArgumentError, %r/\A`be_listening` matcher doesn\'t support/) 18 | end 19 | end 20 | 21 | describe port(80) do 22 | it { should be_listening.on('127.0.0.1') } 23 | end 24 | 25 | describe port(53) do 26 | it { should be_listening.with('udp') } 27 | end 28 | -------------------------------------------------------------------------------- /spec/type/darwin/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'darwin' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | 13 | describe service('sshd') do 14 | it { should be_running } 15 | end 16 | 17 | -------------------------------------------------------------------------------- /spec/type/debian/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'debian' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | it { should be_installed.by('apt').with_version('2.2.15-28.el6') } 15 | end 16 | 17 | describe package('httpd') do 18 | let(:stdout) { "2.2.15\n" } 19 | its(:version) { should eq '2.2.15' } 20 | its(:version) { should > '2.2.14' } 21 | its(:version) { should < '2.2.16' } 22 | its(:version) { should > '2.2.9' } 23 | end 24 | -------------------------------------------------------------------------------- /spec/type/debian/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'debian' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/fedora/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'fedora' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | 13 | describe service('sshd') do 14 | it { should be_running } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/fedora15/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'fedora', :release => 15 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | 13 | describe service('sshd') do 14 | it { should be_running } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/fedora20/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'fedora', :release => 20 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | 13 | describe service('sshd') do 14 | it { should be_running } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/freebsd/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'freebsd' 4 | 5 | describe file('/etc/passwd') do 6 | it { should be_mode 644 } 7 | end 8 | 9 | describe file('/etc/passwd') do 10 | it { should be_owned_by 'root' } 11 | end 12 | 13 | describe file('/etc/passwd') do 14 | it { should be_grouped_into 'root' } 15 | end 16 | 17 | describe file('/sbin/nologin') do 18 | it { should be_linked_to '/usr/sbin/nologin' } 19 | end 20 | 21 | describe file('/etc/passwd') do 22 | let(:stdout) { Time.now.to_i.to_s } 23 | its(:mtime) { should > DateTime.now - 1 } 24 | end 25 | 26 | describe file('/etc/passwod') do 27 | let(:stdout) { 100.to_s } 28 | its(:size) { should > 0 } 29 | end 30 | -------------------------------------------------------------------------------- /spec/type/freebsd/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'freebsd' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | let(:stdout) { "2.2.15\n" } 15 | its(:version) { should eq '2.2.15' } 16 | its(:version) { should > '2.2.14' } 17 | its(:version) { should < '2.2.16' } 18 | its(:version) { should > '2.2.9' } 19 | end 20 | -------------------------------------------------------------------------------- /spec/type/freebsd/port_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'freebsd' 4 | 5 | describe port(80) do 6 | it { should be_listening } 7 | end 8 | 9 | describe port(80) do 10 | it { should be_listening.with('tcp') } 11 | end 12 | 13 | describe port(80) do 14 | it do 15 | expect { 16 | should be_listening.with('not implemented') 17 | }.to raise_error(ArgumentError, %r/\A`be_listening` matcher doesn\'t support/) 18 | end 19 | end 20 | 21 | describe port(80) do 22 | it { should be_listening.on('127.0.0.1') } 23 | end 24 | 25 | describe port(53) do 26 | it { should be_listening.with('udp') } 27 | end 28 | -------------------------------------------------------------------------------- /spec/type/freebsd/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'freebsd' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | -------------------------------------------------------------------------------- /spec/type/freebsd10/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'freebsd', :release => 10 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | let(:stdout) { "2.2.15\n" } 15 | its(:version) { should eq '2.2.15' } 16 | its(:version) { should > '2.2.14' } 17 | its(:version) { should < '2.2.16' } 18 | its(:version) { should > '2.2.9' } 19 | end 20 | -------------------------------------------------------------------------------- /spec/type/gentoo/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'gentoo' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/gentoo/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'gentoo' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_running } 11 | end 12 | 13 | -------------------------------------------------------------------------------- /spec/type/linux/bond_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe bond('bond0') do 6 | it { should exist } 7 | end 8 | 9 | describe bond('bond0') do 10 | let(:stdout) { 'eth0' } 11 | it { should have_interface 'eth0' } 12 | end 13 | -------------------------------------------------------------------------------- /spec/type/linux/bridge_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe bridge('br0') do 6 | it { should exist } 7 | end 8 | 9 | describe bridge('br0') do 10 | let(:stdout) { 'eth0' } 11 | it { should have_interface 'eth0' } 12 | end 13 | -------------------------------------------------------------------------------- /spec/type/linux/cgroup_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe cgroup('group1') do 6 | let(:stdout) { "1\r\n" } 7 | its('cpuset.cpus') { should eq 1 } 8 | end 9 | 10 | describe cgroup('group1') do 11 | let(:stdout) { "1\r\n" } 12 | its('cpuset.cpus') { should_not eq 0 } 13 | end 14 | -------------------------------------------------------------------------------- /spec/type/linux/docker_container_pre_1_8_spec.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | require 'spec_helper' 3 | require 'json' 4 | 5 | property[:os] = nil 6 | set :os, {:family => 'linux'} 7 | 8 | describe docker_container('c1') do 9 | it { should exist } 10 | end 11 | 12 | describe docker_container('c1 pre 1.8') do 13 | let(:stdout) { inspect_container } 14 | it { should be_running } 15 | it { should have_volume('/tmp', '/data') } 16 | it { should_not have_volume('/tmp', '/data-bad') } 17 | its(:inspection) { should include 'Driver' => 'aufs' } 18 | its(['Config.Cmd']) { should include '/bin/sh' } 19 | its(['HostConfig.PortBindings.80.[0].HostPort']) { should eq '8080' } 20 | end 21 | 22 | describe docker_container('restarting pre 1.8') do 23 | let(:stdout) do 24 | attrs = JSON.parse(inspect_container) 25 | attrs.first['State']['Restarting'] = true 26 | attrs.to_json 27 | end 28 | 29 | it { should_not be_running } 30 | end 31 | 32 | def inspect_container 33 | <<'EOS' 34 | [{ 35 | "Args": [], 36 | "Config": { 37 | "AttachStderr": false, 38 | "AttachStdin": false, 39 | "AttachStdout": false, 40 | "Cmd": [ 41 | "/bin/sh" 42 | ], 43 | "CpuShares": 0, 44 | "Cpuset": "", 45 | "Domainname": "", 46 | "Entrypoint": null, 47 | "Env": [ 48 | "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 49 | ], 50 | "ExposedPorts": null, 51 | "Hostname": "65cd2e2d7963", 52 | "Image": "busybox", 53 | "Memory": 0, 54 | "MemorySwap": 0, 55 | "NetworkDisabled": false, 56 | "OnBuild": null, 57 | "OpenStdin": true, 58 | "PortSpecs": null, 59 | "StdinOnce": false, 60 | "Tty": true, 61 | "User": "", 62 | "Volumes": null, 63 | "WorkingDir": "" 64 | }, 65 | "Created": "2014-09-26T15:08:37.527931773Z", 66 | "Driver": "aufs", 67 | "ExecDriver": "native-0.2", 68 | "HostConfig": { 69 | "Binds": [ 70 | "/data:/tmp" 71 | ], 72 | "ContainerIDFile": "", 73 | "Dns": null, 74 | "DnsSearch": null, 75 | "Links": null, 76 | "LxcConf": [], 77 | "NetworkMode": "bridge", 78 | "PortBindings": { 79 | "80": [ 80 | { 81 | "HostIp": "", 82 | "HostPort": "8080" 83 | } 84 | ] 85 | }, 86 | "Privileged": false, 87 | "PublishAllPorts": false, 88 | "VolumesFrom": null 89 | }, 90 | "HostnamePath": "/mnt/sda1/var/lib/docker/containers/65cd2e2d7963bacaecda2d7fcd89499010bc0d38d70bce5ad0af7112a94a4545/hostname", 91 | "HostsPath": "/mnt/sda1/var/lib/docker/containers/65cd2e2d7963bacaecda2d7fcd89499010bc0d38d70bce5ad0af7112a94a4545/hosts", 92 | "Id": "65cd2e2d7963bacaecda2d7fcd89499010bc0d38d70bce5ad0af7112a94a4545", 93 | "Image": "e72ac664f4f0c6a061ac4ef332557a70d69b0c624b6add35f1c181ff7fff2287", 94 | "MountLabel": "", 95 | "Name": "/c1", 96 | "NetworkSettings": { 97 | "Bridge": "docker0", 98 | "Gateway": "172.17.42.1", 99 | "IPAddress": "172.17.0.24", 100 | "IPPrefixLen": 16, 101 | "PortMapping": null, 102 | "Ports": {} 103 | }, 104 | "Path": "/bin/sh", 105 | "ProcessLabel": "", 106 | "ResolvConfPath": "/mnt/sda1/var/lib/docker/containers/65cd2e2d7963bacaecda2d7fcd89499010bc0d38d70bce5ad0af7112a94a4545/resolv.conf", 107 | "State": { 108 | "ExitCode": 0, 109 | "FinishedAt": "0001-01-01T00:00:00Z", 110 | "Paused": false, 111 | "Pid": 4123, 112 | "Running": true, 113 | "StartedAt": "2014-09-26T15:08:37.737780273Z" 114 | }, 115 | "Volumes": { 116 | "/tmp": "/data" 117 | }, 118 | "VolumesRW": { 119 | "/tmp": true 120 | } 121 | } 122 | ] 123 | EOS 124 | end 125 | -------------------------------------------------------------------------------- /spec/type/linux/docker_container_spec.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | require 'spec_helper' 3 | require 'multi_json' 4 | 5 | property[:os] = nil 6 | set :os, {:family => 'linux'} 7 | 8 | describe docker_container('c1') do 9 | it { should exist } 10 | end 11 | 12 | describe docker_container('c1') do 13 | let(:stdout) { inspect_container } 14 | it { should be_running } 15 | it { should have_volume('/tmp', '/data') } 16 | it { should_not have_volume('/tmp', '/data-bad') } 17 | its(:inspection) { should include 'Driver' => 'aufs' } 18 | its(['Config.Cmd']) { should include '/bin/sh' } 19 | its(['HostConfig.PortBindings.80.[0].HostPort']) { should eq '8080' } 20 | its(['HostConfig.PortBindings.80.[1].HostPort']) { should eq '8081' } 21 | end 22 | 23 | describe docker_container('restarting') do 24 | let(:stdout) do 25 | attrs = MultiJson.load(inspect_container) 26 | attrs.first['State']['Restarting'] = true 27 | attrs.to_json 28 | end 29 | 30 | it { should_not be_running } 31 | end 32 | 33 | def inspect_container 34 | <<'EOS' 35 | [{ 36 | "Args": [], 37 | "Config": { 38 | "AttachStderr": false, 39 | "AttachStdin": false, 40 | "AttachStdout": false, 41 | "Cmd": [ 42 | "/bin/sh" 43 | ], 44 | "CpuShares": 0, 45 | "Cpuset": "", 46 | "Domainname": "", 47 | "Entrypoint": null, 48 | "Env": [ 49 | "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 50 | ], 51 | "ExposedPorts": null, 52 | "Hostname": "65cd2e2d7963", 53 | "Image": "busybox", 54 | "Memory": 0, 55 | "MemorySwap": 0, 56 | "NetworkDisabled": false, 57 | "OnBuild": null, 58 | "OpenStdin": true, 59 | "PortSpecs": null, 60 | "StdinOnce": false, 61 | "Tty": true, 62 | "User": "", 63 | "Volumes": null, 64 | "WorkingDir": "" 65 | }, 66 | "Created": "2014-09-26T15:08:37.527931773Z", 67 | "Driver": "aufs", 68 | "ExecDriver": "native-0.2", 69 | "HostConfig": { 70 | "Binds": [ 71 | "/data:/tmp" 72 | ], 73 | "ContainerIDFile": "", 74 | "Dns": null, 75 | "DnsSearch": null, 76 | "Links": null, 77 | "LxcConf": [], 78 | "NetworkMode": "bridge", 79 | "PortBindings": { 80 | "80": [ 81 | { 82 | "HostIp": "", 83 | "HostPort": "8080" 84 | }, 85 | { 86 | "HostIp": "", 87 | "HostPort": "8081" 88 | } 89 | ] 90 | }, 91 | "Privileged": false, 92 | "PublishAllPorts": false, 93 | "VolumesFrom": null 94 | }, 95 | "HostnamePath": "/mnt/sda1/var/lib/docker/containers/65cd2e2d7963bacaecda2d7fcd89499010bc0d38d70bce5ad0af7112a94a4545/hostname", 96 | "HostsPath": "/mnt/sda1/var/lib/docker/containers/65cd2e2d7963bacaecda2d7fcd89499010bc0d38d70bce5ad0af7112a94a4545/hosts", 97 | "Id": "65cd2e2d7963bacaecda2d7fcd89499010bc0d38d70bce5ad0af7112a94a4545", 98 | "Image": "e72ac664f4f0c6a061ac4ef332557a70d69b0c624b6add35f1c181ff7fff2287", 99 | "MountLabel": "", 100 | "Name": "/c1", 101 | "NetworkSettings": { 102 | "Bridge": "docker0", 103 | "Gateway": "172.17.42.1", 104 | "IPAddress": "172.17.0.24", 105 | "IPPrefixLen": 16, 106 | "PortMapping": null, 107 | "Ports": {} 108 | }, 109 | "Path": "/bin/sh", 110 | "ProcessLabel": "", 111 | "ResolvConfPath": "/mnt/sda1/var/lib/docker/containers/65cd2e2d7963bacaecda2d7fcd89499010bc0d38d70bce5ad0af7112a94a4545/resolv.conf", 112 | "State": { 113 | "ExitCode": 0, 114 | "FinishedAt": "0001-01-01T00:00:00Z", 115 | "Paused": false, 116 | "Pid": 4123, 117 | "Running": true, 118 | "StartedAt": "2014-09-26T15:08:37.737780273Z" 119 | }, 120 | "Mounts": [ 121 | { 122 | "Source": "/data", 123 | "Destination": "/tmp", 124 | "Mode": "", 125 | "RW": true 126 | } 127 | ] 128 | } 129 | ] 130 | EOS 131 | end 132 | -------------------------------------------------------------------------------- /spec/type/linux/docker_image_spec.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | require 'spec_helper' 3 | 4 | property[:os] = nil 5 | set :os, {:family => 'linux'} 6 | 7 | describe docker_image('busybox:latest') do 8 | it { should exist } 9 | end 10 | 11 | describe docker_image('busybox:latest') do 12 | let(:stdout) { inspect_image } 13 | its(:inspection) { should include 'Architecture' => 'amd64' } 14 | its(['Architecture']) { should eq 'amd64' } 15 | its(['Config.Cmd']) { should include '/bin/sh' } 16 | end 17 | 18 | def inspect_image 19 | <<'EOS' 20 | [{ 21 | "Architecture": "amd64", 22 | "Author": "Jérôme Petazzoni \u003cjerome@docker.com\u003e", 23 | "Comment": "", 24 | "Config": { 25 | "AttachStderr": false, 26 | "AttachStdin": false, 27 | "AttachStdout": false, 28 | "Cmd": [ 29 | "/bin/sh" 30 | ], 31 | "CpuShares": 0, 32 | "Cpuset": "", 33 | "Domainname": "", 34 | "Entrypoint": null, 35 | "Env": [ 36 | "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 37 | ], 38 | "ExposedPorts": null, 39 | "Hostname": "88f18f678e5d", 40 | "Image": "e433a6c5b276a31aa38bf6eaba9cd1cfd69ea33f706ed72b3f20bafde5cd8644", 41 | "Memory": 0, 42 | "MemorySwap": 0, 43 | "NetworkDisabled": false, 44 | "OnBuild": [], 45 | "OpenStdin": false, 46 | "PortSpecs": null, 47 | "StdinOnce": false, 48 | "Tty": false, 49 | "User": "", 50 | "Volumes": null, 51 | "WorkingDir": "" 52 | }, 53 | "Container": "8e73b239682fe73338323d9af83d3c5aa5bb7d22a3fe84cbfcf5f47e756d6636", 54 | "ContainerConfig": { 55 | "AttachStderr": false, 56 | "AttachStdin": false, 57 | "AttachStdout": false, 58 | "Cmd": [ 59 | "/bin/sh", 60 | "-c", 61 | "#(nop) CMD [/bin/sh]" 62 | ], 63 | "CpuShares": 0, 64 | "Cpuset": "", 65 | "Domainname": "", 66 | "Entrypoint": null, 67 | "Env": [ 68 | "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 69 | ], 70 | "ExposedPorts": null, 71 | "Hostname": "88f18f678e5d", 72 | "Image": "e433a6c5b276a31aa38bf6eaba9cd1cfd69ea33f706ed72b3f20bafde5cd8644", 73 | "Memory": 0, 74 | "MemorySwap": 0, 75 | "NetworkDisabled": false, 76 | "OnBuild": [], 77 | "OpenStdin": false, 78 | "PortSpecs": null, 79 | "StdinOnce": false, 80 | "Tty": false, 81 | "User": "", 82 | "Volumes": null, 83 | "WorkingDir": "" 84 | }, 85 | "Created": "2014-10-01T20:46:08.914288461Z", 86 | "DockerVersion": "1.2.0", 87 | "Id": "e72ac664f4f0c6a061ac4ef332557a70d69b0c624b6add35f1c181ff7fff2287", 88 | "Os": "linux", 89 | "Parent": "e433a6c5b276a31aa38bf6eaba9cd1cfd69ea33f706ed72b3f20bafde5cd8644", 90 | "Size": 0 91 | } 92 | ] 93 | EOS 94 | end 95 | -------------------------------------------------------------------------------- /spec/type/linux/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | property[:os] = nil 4 | set :os, {:family => 'linux'} 5 | 6 | describe file('/tmp') do 7 | it { should be_readable.by_user('mail') } 8 | end 9 | 10 | describe file('/tmp') do 11 | it { should be_writable.by_user('mail') } 12 | end 13 | 14 | describe file('/tmp') do 15 | it { should be_executable.by_user('mail') } 16 | end 17 | 18 | describe file('/tmp') do 19 | it { should be_immutable } 20 | end 21 | 22 | describe file('/tmp') do 23 | let(:exit_status) { 0 } 24 | let(:stdout) { 'unconfined_u:unconfined_r:unconfined_t:s0' } 25 | its(:selinux_label) { should eq 'unconfined_u:unconfined_r:unconfined_t:s0' } 26 | end 27 | 28 | -------------------------------------------------------------------------------- /spec/type/linux/fstab_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe fstab do 6 | let(:stdout) { "/dev/sda1 /mnt ext4 ro,errors=remount-ro,barrier=0 0 2\r\n" } 7 | it { should have_entry( :mount_point => '/mnt' ) } 8 | end 9 | 10 | describe fstab do 11 | let(:exit_status) { 1 } 12 | it { should_not have_entry( :mount_point => '/mnt' ) } 13 | end 14 | 15 | describe fstab do 16 | let(:stdout) { "/dev/sda1 /mnt ext4 ro,errors=remount-ro,barrier=0 0 2\r\n" } 17 | it do 18 | should have_entry( 19 | :device => '/dev/sda1', 20 | :mount_point => '/mnt', 21 | :type => 'ext4', 22 | :options => { 23 | :ro => true, 24 | :errors => 'remount-ro', 25 | :barrier => 0 26 | }, 27 | :dump => 0, 28 | :pass => 2 29 | ) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/type/linux/interface_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe interface('eth0') do 6 | let(:stdout) { '1000' } 7 | its(:speed) { should eq 1000 } 8 | end 9 | 10 | describe interface('eth0') do 11 | let(:stdout) { '1500' } 12 | its(:mtu) { should eq 1500 } 13 | end 14 | 15 | describe interface('eth0') do 16 | it { should have_ipv4_address('192.168.10.10') } 17 | end 18 | 19 | describe interface('eth0') do 20 | it { should have_ipv4_address('192.168.10.10/24') } 21 | end 22 | 23 | describe interface('eth0') do 24 | it { should have_ipv6_address('2001:0db8:bd05:01d2:288a:1fc0:0001:10ee') } 25 | end 26 | 27 | describe interface('eth1') do 28 | let(:stdout) { "1.2.3.4/1\r\n" } 29 | its(:ipv4_address) { should match(/^[\d.]+\/\d+$/) } 30 | end 31 | 32 | describe interface('eth1') do 33 | let(:stdout) { "2001:db8::1234/1\r\n" } 34 | its(:ipv6_address) { should match(/^[a-f\d:]+\/\d+$/i) } 35 | end 36 | 37 | describe interface('eth0') do 38 | let(:stdout) { 'up' } 39 | it { should be_up } 40 | end 41 | 42 | describe interface('invalid-interface') do 43 | let(:stdout) { '1000' } 44 | its(:speed) { should_not eq 100 } 45 | end 46 | 47 | describe interface('invalid-interface') do 48 | let(:stdout) { '9001' } 49 | its(:mtu) { should_not eq 1500 } 50 | end 51 | -------------------------------------------------------------------------------- /spec/type/linux/ip6tables_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe ip6tables do 6 | it { should have_rule '-P INPUT ACCEPT' } 7 | end 8 | 9 | describe ip6tables do 10 | it { should have_rule('-P INPUT ACCEPT').with_table('mangle').with_chain('INPUT') } 11 | end 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /spec/type/linux/iptables_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe iptables do 6 | it { should have_rule '-P INPUT ACCEPT' } 7 | end 8 | 9 | describe iptables do 10 | it { should have_rule('-P INPUT ACCEPT').with_table('mangle').with_chain('INPUT') } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/linux/kernel_module_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe kernel_module('lp') do 6 | it { should be_loaded } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/linux/kvm_guest_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe kvm('ct01') do 6 | it { should exist } 7 | end 8 | 9 | describe kvm('ct01') do 10 | it { should be_running } 11 | end 12 | 13 | describe kvm('ct01') do 14 | it { should be_enabled } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/linux/linux_audit_system_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe linux_audit_system do 6 | let(:stdout) { out_auditctl1_1 } 7 | it { should be_enabled } 8 | end 9 | 10 | describe linux_audit_system do 11 | let(:stdout) { out_auditctl1_2 } 12 | it { should_not be_enabled } 13 | end 14 | 15 | describe linux_audit_system do 16 | let(:stdout) { out_auditctl1_1 } 17 | it { should be_running } 18 | end 19 | 20 | describe linux_audit_system do 21 | let(:stdout) { out_auditctl1_3 } 22 | it { should_not be_running } 23 | end 24 | 25 | describe linux_audit_system do 26 | let(:stdout) { out_auditctl1_4 } 27 | it { should_not be_running } 28 | end 29 | 30 | describe linux_audit_system do 31 | let(:stdout) { out_auditctl2_1 } 32 | it { should be_enabled } 33 | end 34 | 35 | describe linux_audit_system do 36 | let(:stdout) { out_auditctl2_2 } 37 | it { should_not be_enabled } 38 | end 39 | 40 | describe linux_audit_system do 41 | let(:stdout) { out_auditctl2_1 } 42 | it { should be_running } 43 | end 44 | 45 | describe linux_audit_system do 46 | let(:stdout) { out_auditctl2_3 } 47 | it { should_not be_running } 48 | end 49 | 50 | describe linux_audit_system do 51 | let(:stdout) { out_auditctl2_4 } 52 | it { should_not be_running } 53 | end 54 | 55 | describe linux_audit_system do 56 | let(:stdout) { '-a -w /etc/sysconfig -p wa -k test' } 57 | its(:rules) { should match %r!-w /etc/sysconfig.*-k test! } 58 | end 59 | 60 | describe linux_audit_system do 61 | let(:stdout) { 'test' } 62 | its(:rules) { should eq 'test' } 63 | its(:rules) { should match /es/ } 64 | its(:rules) { should_not match /ab/ } 65 | end 66 | 67 | # variants of auditctl -s output for different versions 68 | 69 | def out_auditctl1_1 70 | "AUDIT_STATUS: enabled=1 flag=1 pid=881 rate_limit=0 backlog_limit=320 lost=0 backlog=0" 71 | end 72 | 73 | def out_auditctl1_2 74 | "AUDIT_STATUS: enabled=0 flag=1 pid=881 rate_limit=0 backlog_limit=320 lost=0 backlog=0" 75 | end 76 | 77 | def out_auditctl1_3 78 | "AUDIT_STATUS: enabled=1 flag=1 pid=0 rate_limit=0 backlog_limit=320 lost=0 backlog=0" 79 | end 80 | 81 | def out_auditctl1_4 82 | "AUDIT_STATUS: enabled=1 flag=1 pid= rate_limit=0 backlog_limit=320 lost=0 backlog=0" 83 | end 84 | 85 | def out_auditctl2_1 86 | < 'linux' 4 | 5 | describe linux_kernel_parameter('net.ipv4.tcp_syncookies') do 6 | let(:stdout) { "1\n" } 7 | its(:value) { should eq 1 } 8 | end 9 | 10 | describe linux_kernel_parameter('net.ipv4.tcp_syncookies') do 11 | let(:stdout) { "1\n" } 12 | its(:value) { should_not eq 2 } 13 | end 14 | 15 | describe linux_kernel_parameter('kernel.osrelease') do 16 | let(:stdout) { "2.6.32-131.0.15.el6.x86_64\n" } 17 | its(:value) { should eq "2.6.32-131.0.15.el6.x86_64" } 18 | end 19 | 20 | describe linux_kernel_parameter('kernel.osrelease') do 21 | let(:stdout) { "2.6.32-131.0.15.el6.x86_64\n" } 22 | its(:value) { should_not eq "2.6.32-131.0.15.el6.i386" } 23 | end 24 | 25 | describe linux_kernel_parameter('net.ipv4.tcp_wmem') do 26 | let(:stdout) { "4096 16384 4194304\n" } 27 | its(:value) { should match /16384/ } 28 | end 29 | 30 | describe linux_kernel_parameter('net.ipv4.tcp_wmem') do 31 | let(:stdout) { "4096 16384 4194304\n" } 32 | its(:value) { should_not match /123456/ } 33 | end 34 | -------------------------------------------------------------------------------- /spec/type/linux/lxc_container_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe lxc('ct01') do 6 | it { should exist } 7 | end 8 | 9 | describe lxc('ct01') do 10 | it { should be_running } 11 | end 12 | 13 | -------------------------------------------------------------------------------- /spec/type/linux/selinux_module_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe selinux_module('bootloader') do 6 | it { should be_installed } 7 | end 8 | 9 | describe selinux_module('bootloader') do 10 | it { should be_installed.with_version('1.10') } 11 | end 12 | 13 | describe selinux_module('bootloader') do 14 | it { should be_enabled } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/linux/selinux_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe selinux do 6 | it { should be_enforcing } 7 | end 8 | 9 | describe selinux do 10 | it { should be_enforcing.with_policy('mls') } 11 | end 12 | 13 | describe selinux do 14 | it { should be_permissive } 15 | end 16 | 17 | describe selinux do 18 | it { should be_permissive.with_policy('targeted') } 19 | end 20 | 21 | describe selinux do 22 | it { should be_disabled } 23 | end 24 | -------------------------------------------------------------------------------- /spec/type/linux/x509_certificate_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe x509_certificate('test.pem') do 6 | let(:exit_status) { 0 } 7 | it { should be_certificate } 8 | end 9 | 10 | describe x509_certificate('test.pem') do 11 | let(:exit_status) { 1 } 12 | it { should_not be_certificate } 13 | end 14 | 15 | describe x509_certificate('test-openssl-1.0.pem') do 16 | let(:stdout) { sample_subj_openssl_1_0 } 17 | its(:subject) { should eq 'O = some, OU = thing' } 18 | end 19 | 20 | describe x509_certificate('test-openssl-1.1.pem') do 21 | let(:stdout) { sample_subj_openssl_1_1 } 22 | its(:subject) { should eq 'O = some, OU = thing' } 23 | end 24 | 25 | describe x509_certificate('test-openssl-1.0.pem') do 26 | let(:stdout) { sample_issuer_openssl_1_0 } 27 | its(:issuer) { should eq 'O = some, OU = issuer' } 28 | end 29 | 30 | describe x509_certificate('test-openssl-1.1.pem') do 31 | let(:stdout) { sample_issuer_openssl_1_1 } 32 | its(:issuer) { should eq 'O = some, OU = issuer' } 33 | end 34 | 35 | describe x509_certificate('test.pem') do 36 | let(:stdout) { sample_validity } 37 | it { should be_valid } 38 | its(:validity_in_days) { should be >= 1000 } 39 | end 40 | 41 | describe x509_certificate('test.pem') do 42 | let(:stdout) { sample_validity2 } 43 | it { should_not be_valid } 44 | end 45 | 46 | describe x509_certificate('test.pem') do 47 | let(:stdout) { sample_san } 48 | its(:subject_alt_names) { should eq %w[DNS:*.example.com DNS:www.example.net IP:192.0.2.10] } 49 | end 50 | 51 | def sample_subj_openssl_1_0 52 | <<'EOS' 53 | subject= /O=some/OU=thing 54 | EOS 55 | end 56 | 57 | def sample_subj_openssl_1_1 58 | <<'EOS' 59 | subject=O = some, OU = thing 60 | EOS 61 | end 62 | 63 | def sample_issuer_openssl_1_0 64 | <<'EOS' 65 | issuer= /O=some/OU=issuer 66 | EOS 67 | end 68 | 69 | def sample_issuer_openssl_1_1 70 | <<'EOS' 71 | issuer=O = some, OU = issuer 72 | EOS 73 | end 74 | 75 | def sample_validity 76 | <<'EOS' 77 | notBefore=Jul 1 11:11:00 2000 GMT 78 | notAfter=Jul 1 11:11:00 2050 GMT 79 | EOS 80 | end 81 | 82 | def sample_validity2 83 | <<'EOS' 84 | notBefore=Jul 1 11:11:00 2000 GMT 85 | notAfter=Jul 1 11:11:00 2010 GMT 86 | EOS 87 | end 88 | 89 | def sample_san 90 | <<'EOS' 91 | Certificate: 92 | Data: 93 | Version: 3 (0x2) 94 | X509v3 extensions: 95 | X509v3 Extended Key Usage: 96 | TLS Web Server Authentication, TLS Web Client Authentication 97 | X509v3 Subject Alternative Name: 98 | DNS:*.example.com, DNS:www.example.net, IP:192.0.2.10 99 | EOS 100 | end 101 | -------------------------------------------------------------------------------- /spec/type/linux/x509_private_key_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe x509_private_key('key.pem') do 6 | let(:exit_status) { 0 } 7 | let(:stdout) { 'RSA key ok' } 8 | it { should be_valid } 9 | end 10 | 11 | describe x509_private_key('key.pem') do 12 | let(:exit_status) { 1 } 13 | let(:stdout) { 'RSA key ok' } 14 | it { should_not be_valid } 15 | end 16 | 17 | describe x509_private_key('key.pem') do 18 | let(:exit_status) { 0 } 19 | it { should be_encrypted } 20 | end 21 | 22 | describe x509_private_key('key.pem') do 23 | let(:exit_status) { 1 } 24 | it { should_not be_encrypted } 25 | end 26 | 27 | describe x509_private_key('key.pem') do 28 | let(:exit_status) { 0 } 29 | let(:stdout) { 'SHA1SUM' } 30 | it { should have_matching_certificate('cert.pem') } 31 | end -------------------------------------------------------------------------------- /spec/type/linux/zfs_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'linux' 4 | 5 | describe zfs('rpool') do 6 | it { should exist } 7 | end 8 | 9 | describe zfs('rpool') do 10 | it { should have_property 'mountpoint' => '/rpool' } 11 | end 12 | 13 | describe zfs('rpool') do 14 | it { should have_property 'mountpoint' => '/rpool', 'compression' => 'off' } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/nixos/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'nixos' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | it { should be_installed.by('nix').with_version('2.2.15-28.el6') } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/nixos/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'nixos' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | it { should be_running } 8 | end 9 | 10 | -------------------------------------------------------------------------------- /spec/type/openbsd/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, {:family => 'openbsd'} 4 | 5 | describe file('/etc/passwd') do 6 | it { should be_mode 644 } 7 | end 8 | 9 | describe file('/etc/passwd') do 10 | it { should be_owned_by 'root' } 11 | end 12 | 13 | describe file('/etc/passwd') do 14 | it { should be_grouped_into 'root' } 15 | end 16 | 17 | describe file('/etc/pam.d/system-auth') do 18 | it { should be_linked_to '/etc/pam.d/system-auth-ac' } 19 | end 20 | 21 | describe file('/') do 22 | it { should be_mounted } 23 | end 24 | 25 | describe file('/') do 26 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 27 | it { should be_mounted.with( :type => 'ext4' ) } 28 | end 29 | 30 | describe file('/') do 31 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 32 | it { should be_mounted.with( :type => 'ext4', :options => { :rw => true } ) } 33 | end 34 | 35 | describe file('/') do 36 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 37 | it { should be_mounted.with( :type => 'ext4', :options => { :mode => 620 } ) } 38 | end 39 | 40 | describe file('/') do 41 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 42 | it { should be_mounted.with( :type => 'ext4', :device => '/dev/mapper/VolGroup-lv_root' ) } 43 | end 44 | 45 | describe file('/') do 46 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 47 | it { should_not be_mounted.with( :type => 'xfs' ) } 48 | end 49 | 50 | describe file('/') do 51 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 52 | it { should_not be_mounted.with( :type => 'ext4', :options => { :rw => false } ) } 53 | end 54 | 55 | describe file('/') do 56 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 57 | it { should_not be_mounted.with( :type => 'ext4', :options => { :mode => 600 } ) } 58 | end 59 | 60 | describe file('/') do 61 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 62 | it { should_not be_mounted.with( :type => 'xfs', :device => '/dev/mapper/VolGroup-lv_root' ) } 63 | end 64 | 65 | describe file('/') do 66 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 67 | it { should_not be_mounted.with( :type => 'ext4', :device => '/dev/mapper/VolGroup-lv_r00t' ) } 68 | end 69 | 70 | describe file('/') do 71 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 72 | it do 73 | should be_mounted.only_with( 74 | :device => '/dev/mapper/VolGroup-lv_root', 75 | :type => 'ext4', 76 | :options => { 77 | :rw => true, 78 | :mode => 620, 79 | } 80 | ) 81 | end 82 | end 83 | 84 | describe file('/') do 85 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 86 | it do 87 | should_not be_mounted.only_with( 88 | :device => '/dev/mapper/VolGroup-lv_root', 89 | :type => 'ext4', 90 | :options => { 91 | :rw => true, 92 | :mode => 620, 93 | :bind => true, 94 | } 95 | ) 96 | end 97 | end 98 | 99 | describe file('/') do 100 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 101 | it do 102 | should_not be_mounted.only_with( 103 | :device => '/dev/mapper/VolGroup-lv_root', 104 | :type => 'ext4', 105 | :options => { 106 | :rw => true, 107 | } 108 | ) 109 | end 110 | end 111 | 112 | describe file('/') do 113 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 114 | it do 115 | should_not be_mounted.only_with( 116 | :device => '/dev/mapper/VolGroup-lv_roooooooooot', 117 | :type => 'ext4', 118 | :options => { 119 | :rw => true, 120 | :mode => 620, 121 | } 122 | ) 123 | end 124 | end 125 | 126 | describe file('/etc/services') do 127 | let(:stdout) { "35435ea447c19f0ea5ef971837ab9ced\n" } 128 | its(:md5sum) { should eq '35435ea447c19f0ea5ef971837ab9ced' } 129 | end 130 | 131 | describe file('/etc/services') do 132 | let(:stdout) {"0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a" } 133 | its(:sha256sum) { should eq '0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a' } 134 | end 135 | -------------------------------------------------------------------------------- /spec/type/openbsd/interface_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'openbsd' 4 | 5 | describe interface('eth0') do 6 | let(:stdout) { '1000' } 7 | its(:speed) { should eq 1000 } 8 | end 9 | 10 | describe interface('eth0') do 11 | it { should have_ipv4_address("192.168.10.10") } 12 | end 13 | 14 | describe interface('eth0') do 15 | it { should have_ipv4_address("192.168.10.10/24") } 16 | end 17 | 18 | describe interface('eth1') do 19 | let(:stdout) { "1.2.3.4/1\r\n" } 20 | its(:ipv4_address) { should match(/^[\d.]+\/\d+$/) } 21 | end 22 | 23 | describe interface('eth1') do 24 | let(:stdout) { "2001:db8::1234/1\r\n" } 25 | its(:ipv6_address) { should match(/^[a-f\d:]+\/\d+$/i) } 26 | end 27 | 28 | describe interface('invalid-interface') do 29 | let(:stdout) { '1000' } 30 | its(:speed) { should_not eq 100 } 31 | end 32 | -------------------------------------------------------------------------------- /spec/type/openbsd/mail_alias_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'openbsd' 4 | 5 | describe mail_alias('daemon') do 6 | it { should be_aliased_to "root" } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/openbsd/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'openbsd' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/openbsd/port_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'openbsd' 4 | 5 | describe port(80) do 6 | it { should be_listening } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/openbsd/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'openbsd' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_running } 11 | end 12 | 13 | 14 | -------------------------------------------------------------------------------- /spec/type/openbsd/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'openbsd' 4 | 5 | describe user('root') do 6 | it { should have_login_shell '/bin/bash' } 7 | end 8 | 9 | describe user('root') do 10 | it { should have_home_directory '/root' } 11 | end 12 | 13 | -------------------------------------------------------------------------------- /spec/type/opensuse/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'opensuse' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | 13 | describe service('sshd') do 14 | it { should be_running } 15 | end 16 | 17 | -------------------------------------------------------------------------------- /spec/type/plamo/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'plamo' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | -------------------------------------------------------------------------------- /spec/type/plamo/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'plamo' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | -------------------------------------------------------------------------------- /spec/type/redhat/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'redhat' 4 | 5 | describe file('/tmp') do 6 | it { should be_readable.by_user('mail') } 7 | end 8 | 9 | describe file('/tmp') do 10 | it { should be_writable.by_user('mail') } 11 | end 12 | 13 | describe file('/tmp') do 14 | it { should be_executable.by_user('mail') } 15 | end 16 | 17 | describe file('/tmp') do 18 | it { should be_immutable } 19 | end 20 | -------------------------------------------------------------------------------- /spec/type/redhat/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'redhat' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | it { should be_installed.by('rpm').with_version('2.2.15-28.el6') } 15 | end 16 | 17 | describe package('httpd') do 18 | let(:stdout) { "2.2.15\n" } 19 | its(:version) { should eq '2.2.15' } 20 | its(:version) { should > '2.2.14' } 21 | its(:version) { should < '2.2.16' } 22 | its(:version) { should > '2.2.9' } 23 | end 24 | -------------------------------------------------------------------------------- /spec/type/redhat/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'redhat' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/redhat/yumrepo_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'redhat' 4 | 5 | describe yumrepo('epel') do 6 | it { should exist } 7 | end 8 | 9 | describe yumrepo('epel') do 10 | it { should be_enabled } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/redhat5/iptables_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'redhat', :release => 5 4 | 5 | describe iptables do 6 | it { should have_rule '-P INPUT ACCEPT' } 7 | end 8 | 9 | describe iptables do 10 | it { should have_rule('-P INPUT ACCEPT').with_table('mangle').with_chain('INPUT') } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/redhat7/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'redhat', :release => 7 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | it { should be_running } 8 | end 9 | 10 | -------------------------------------------------------------------------------- /spec/type/smartos/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'smartos' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | let(:stdout) { "2.2.15\n" } 15 | its(:version) { should eq '2.2.15' } 16 | its(:version) { should > '2.2.14' } 17 | its(:version) { should < '2.2.16' } 18 | its(:version) { should > '2.2.9' } 19 | end 20 | -------------------------------------------------------------------------------- /spec/type/smartos/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'smartos' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_running } 11 | end 12 | 13 | describe service('sshd') do 14 | it { should have_property :foo => 'bar' } 15 | end 16 | 17 | -------------------------------------------------------------------------------- /spec/type/solaris/cron_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe cron do 6 | it { should have_entry '* * * * * /usr/local/bin/batch.sh' } 7 | end 8 | 9 | describe cron do 10 | it { should have_entry('* * * * * /usr/local/bin/batch.sh').with_user('root') } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/solaris/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe file('/tmp') do 6 | it { should be_readable.by_user('mail') } 7 | end 8 | 9 | describe file('/tmp') do 10 | it { should be_writable.by_user('mail') } 11 | end 12 | 13 | describe file('/tmp') do 14 | it { should be_executable.by_user('mail') } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/solaris/group_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe group('root') do 6 | it { should have_gid 0 } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/solaris/host_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe host('127.0.0.1') do 6 | it { should be_reachable } 7 | end 8 | 9 | describe host('127.0.0.1') do 10 | it { should be_reachable.with(:proto => 'icmp', :timeout=> 1) } 11 | end 12 | 13 | describe host('127.0.0.1') do 14 | it { should be_reachable.with(:proto => 'tcp', :port => 22, :timeout=> 1) } 15 | end 16 | 17 | describe host('127.0.0.1') do 18 | it { should be_reachable.with(:proto => 'udp', :port => 53, :timeout=> 1) } 19 | end 20 | -------------------------------------------------------------------------------- /spec/type/solaris/ipfilter_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe ipfilter do 6 | it { should have_rule 'pass in quick on lo0 all' } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/solaris/ipnat_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe ipnat do 6 | it { should have_rule 'map net1 192.168.0.0/24 -> 0.0.0.0/32' } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/solaris/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/solaris/port_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe port(80) do 6 | it { should be_listening } 7 | end 8 | 9 | describe port(80) do 10 | it { should be_listening.with('tcp') } 11 | end 12 | 13 | describe port(80) do 14 | it do 15 | expect { 16 | should be_listening.with('not implemented') 17 | }.to raise_error(ArgumentError, %r/\A`be_listening` matcher doesn\'t support/) 18 | end 19 | end 20 | 21 | describe port(80) do 22 | it { should be_listening.on('127.0.0.1') } 23 | end 24 | 25 | describe port(80) do 26 | it do 27 | expect{ should be_listening.on('') }.to raise_error(ArgumentError) 28 | end 29 | end 30 | 31 | describe port(123) do 32 | it { should be_listening.with('udp') } 33 | end 34 | 35 | -------------------------------------------------------------------------------- /spec/type/solaris/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_running } 11 | end 12 | 13 | describe service('sshd') do 14 | it { should have_property :foo => 'bar' } 15 | end 16 | 17 | -------------------------------------------------------------------------------- /spec/type/solaris/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe user('root') do 6 | it { should belong_to_group 'root' } 7 | end 8 | 9 | describe user('root') do 10 | it { should have_login_shell '/bin/bash' } 11 | end 12 | 13 | describe user('root') do 14 | it { should have_home_directory '/root' } 15 | end 16 | 17 | -------------------------------------------------------------------------------- /spec/type/solaris/zfs_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris' 4 | 5 | describe zfs('rpool') do 6 | it { should exist } 7 | end 8 | 9 | describe zfs('rpool') do 10 | it { should have_property 'mountpoint' => '/rpool' } 11 | end 12 | 13 | describe zfs('rpool') do 14 | it { should have_property 'mountpoint' => '/rpool', 'compression' => 'off' } 15 | end 16 | -------------------------------------------------------------------------------- /spec/type/solaris10/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris', :release => 10 4 | 5 | describe file('/etc/ssh/sshd_config') do 6 | it { should be_file } 7 | end 8 | 9 | describe file('/etc/ssh') do 10 | it { should be_directory } 11 | end 12 | 13 | describe file('/var/run/unicorn.sock') do 14 | it { should be_socket } 15 | end 16 | 17 | describe file('/etc/ssh/sshd_config') do 18 | it { should contain 'This is the sshd server system-wide configuration file' } 19 | end 20 | 21 | describe file('/etc/ssh/sshd_config') do 22 | it { should contain /^This is the sshd server system-wide configuration file/ } 23 | end 24 | 25 | describe file('Gemfile') do 26 | it { should contain('rspec').from(/^group :test do/).to(/^end/) } 27 | end 28 | 29 | describe file('Gemfile') do 30 | it { should contain('rspec').after(/^group :test do/) } 31 | end 32 | 33 | describe file('Gemfile') do 34 | it { should contain('rspec').before(/^end/) } 35 | end 36 | 37 | describe file('/etc/passwd') do 38 | it { should be_mode 644 } 39 | end 40 | 41 | describe file('/etc/passwd') do 42 | it { should be_owned_by 'root' } 43 | end 44 | 45 | describe file('/etc/passwd') do 46 | it { should be_grouped_into 'root' } 47 | end 48 | 49 | describe file('/etc/pam.d/system-auth') do 50 | it { should be_linked_to '/etc/pam.d/system-auth-ac' } 51 | end 52 | 53 | describe file('/dev') do 54 | let(:stdout) { "755\r\n" } 55 | it { should be_readable } 56 | end 57 | 58 | describe file('/dev') do 59 | let(:stdout) { "333\r\n" } 60 | it { should_not be_readable } 61 | end 62 | 63 | describe file('/dev') do 64 | let(:stdout) { "400\r\n" } 65 | it { should be_readable.by('owner') } 66 | end 67 | 68 | describe file('/dev') do 69 | let(:stdout) { "044\r\n" } 70 | it { should_not be_readable.by('owner') } 71 | end 72 | 73 | describe file('/dev') do 74 | let(:stdout) { "040\r\n" } 75 | it { should be_readable.by('group') } 76 | end 77 | 78 | describe file('/dev') do 79 | let(:stdout) { "404\r\n" } 80 | it { should_not be_readable.by('group') } 81 | end 82 | 83 | describe file('/dev') do 84 | let(:stdout) { "044\r\n" } 85 | it { should be_readable.by('others') } 86 | end 87 | 88 | describe file('/dev') do 89 | let(:stdout) { "443\r\n" } 90 | it { should_not be_readable.by('others') } 91 | end 92 | 93 | describe file('/dev') do 94 | let(:stdout) { "755\r\n" } 95 | it { should be_writable } 96 | end 97 | 98 | describe file('/dev') do 99 | let(:stdout) { "555\r\n" } 100 | it { should_not be_writable } 101 | end 102 | 103 | describe file('/dev') do 104 | let(:stdout) { "200\r\n" } 105 | it { should be_writable.by('owner') } 106 | end 107 | 108 | describe file('/dev') do 109 | let(:stdout) { "555\r\n" } 110 | it { should_not be_writable.by('owner') } 111 | end 112 | 113 | describe file('/dev') do 114 | let(:stdout) { "030\r\n" } 115 | it { should be_writable.by('group') } 116 | end 117 | 118 | describe file('/dev') do 119 | let(:stdout) { "555\r\n" } 120 | it { should_not be_writable.by('group') } 121 | end 122 | 123 | describe file('/dev') do 124 | let(:stdout) { "666\r\n" } 125 | it { should be_writable.by('others') } 126 | end 127 | 128 | describe file('/dev') do 129 | let(:stdout) { "555\r\n" } 130 | it { should_not be_writable.by('others') } 131 | end 132 | 133 | 134 | describe file('/dev') do 135 | let(:stdout) { "755\r\n" } 136 | it { should be_executable } 137 | end 138 | 139 | describe file('/dev') do 140 | let(:stdout) { "666\r\n" } 141 | it { should_not be_executable } 142 | end 143 | 144 | describe file('/dev') do 145 | let(:stdout) { "100\r\n" } 146 | it { should be_executable.by('owner') } 147 | end 148 | 149 | describe file('/dev') do 150 | let(:stdout) { "666\r\n" } 151 | it { should_not be_executable.by('owner') } 152 | end 153 | 154 | describe file('/dev') do 155 | let(:stdout) { "070\r\n" } 156 | it { should be_executable.by('group') } 157 | end 158 | 159 | describe file('/dev') do 160 | let(:stdout) { "666\r\n" } 161 | it { should_not be_executable.by('group') } 162 | end 163 | 164 | describe file('/dev') do 165 | let(:stdout) { "001\r\n" } 166 | it { should be_executable.by('others') } 167 | end 168 | 169 | describe file('/dev') do 170 | let(:stdout) { "666\r\n" } 171 | it { should_not be_executable.by('others') } 172 | end 173 | 174 | describe file('/') do 175 | it { should be_mounted } 176 | end 177 | 178 | describe file('/') do 179 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 180 | it { should be_mounted.with( :type => 'ext4' ) } 181 | end 182 | 183 | describe file('/') do 184 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 185 | it { should be_mounted.with( :type => 'ext4', :options => { :rw => true } ) } 186 | end 187 | 188 | describe file('/') do 189 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 190 | it { should be_mounted.with( :type => 'ext4', :options => { :mode => 620 } ) } 191 | end 192 | 193 | describe file('/') do 194 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 195 | it { should be_mounted.with( :type => 'ext4', :device => '/dev/mapper/VolGroup-lv_root' ) } 196 | end 197 | 198 | describe file('/') do 199 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 200 | it { should_not be_mounted.with( :type => 'xfs' ) } 201 | end 202 | 203 | describe file('/') do 204 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 205 | it { should_not be_mounted.with( :type => 'ext4', :options => { :rw => false } ) } 206 | end 207 | 208 | describe file('/') do 209 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 210 | it { should_not be_mounted.with( :type => 'ext4', :options => { :mode => 600 } ) } 211 | end 212 | 213 | describe file('/') do 214 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 215 | it { should_not be_mounted.with( :type => 'xfs', :device => '/dev/mapper/VolGroup-lv_root' ) } 216 | end 217 | 218 | describe file('/') do 219 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 220 | it { should_not be_mounted.with( :type => 'ext4', :device => '/dev/mapper/VolGroup-lv_r00t' ) } 221 | end 222 | 223 | describe file('/') do 224 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 225 | it do 226 | should be_mounted.only_with( 227 | :device => '/dev/mapper/VolGroup-lv_root', 228 | :type => 'ext4', 229 | :options => { 230 | :rw => true, 231 | :mode => 620, 232 | } 233 | ) 234 | end 235 | end 236 | 237 | describe file('/') do 238 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 239 | it do 240 | should_not be_mounted.only_with( 241 | :device => '/dev/mapper/VolGroup-lv_root', 242 | :type => 'ext4', 243 | :options => { 244 | :rw => true, 245 | :mode => 620, 246 | :bind => true, 247 | } 248 | ) 249 | end 250 | end 251 | 252 | describe file('/') do 253 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 254 | it do 255 | should_not be_mounted.only_with( 256 | :device => '/dev/mapper/VolGroup-lv_root', 257 | :type => 'ext4', 258 | :options => { 259 | :rw => true, 260 | } 261 | ) 262 | end 263 | end 264 | 265 | describe file('/') do 266 | let(:stdout) { "/dev/mapper/VolGroup-lv_root on / type ext4 (rw,mode=620)\r\n" } 267 | it do 268 | should_not be_mounted.only_with( 269 | :device => '/dev/mapper/VolGroup-lv_roooooooooot', 270 | :type => 'ext4', 271 | :options => { 272 | :rw => true, 273 | :mode => 620, 274 | } 275 | ) 276 | end 277 | end 278 | 279 | describe file('/etc/services') do 280 | let(:stdout) { "35435ea447c19f0ea5ef971837ab9ced\n" } 281 | its(:md5sum) { should eq '35435ea447c19f0ea5ef971837ab9ced' } 282 | end 283 | 284 | describe file('/etc/services') do 285 | let(:stdout) {"0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a" } 286 | its(:md5sum) { should eq '0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a' } 287 | end 288 | 289 | describe file('/etc/passwd') do 290 | let(:stdout) {< 'solaris', :release => 10 4 | 5 | describe group('root') do 6 | it { should exist } 7 | end 8 | 9 | -------------------------------------------------------------------------------- /spec/type/solaris10/host_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris', :release => 10 4 | 5 | describe host('127.0.0.1') do 6 | it { should be_reachable } 7 | end 8 | 9 | describe host('127.0.0.1') do 10 | it { should be_reachable.with(:proto => 'icmp', :timeout=> 1) } 11 | end 12 | 13 | describe host('127.0.0.1') do 14 | it { should be_reachable.with(:proto => 'tcp', :port => 22, :timeout=> 1) } 15 | end 16 | 17 | -------------------------------------------------------------------------------- /spec/type/solaris10/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris', :release => 10 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | -------------------------------------------------------------------------------- /spec/type/solaris10/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'solaris', :release => 10 4 | 5 | describe user('root') do 6 | it { should have_authorized_key 'XXXXXXXXXXXXXXX' } 7 | end 8 | 9 | -------------------------------------------------------------------------------- /spec/type/suse/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'suse' 4 | 5 | describe package('httpd') do 6 | it { should be_installed } 7 | end 8 | 9 | describe package('httpd') do 10 | it { should be_installed.with_version('2.2.15-28.el6') } 11 | end 12 | 13 | describe package('httpd') do 14 | it { should be_installed.by('rpm').with_version('2.2.15-28.el6') } 15 | end 16 | 17 | describe package('httpd') do 18 | let(:stdout) { "2.2.15\n" } 19 | its(:version) { should eq '2.2.15' } 20 | its(:version) { should > '2.2.14' } 21 | its(:version) { should < '2.2.16' } 22 | its(:version) { should > '2.2.9' } 23 | end 24 | -------------------------------------------------------------------------------- /spec/type/suse/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'suse' 4 | 5 | describe service('sshd') do 6 | it { should be_enabled } 7 | end 8 | 9 | describe service('sshd') do 10 | it { should be_enabled.with_level(4) } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/ubuntu/ppa_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'ubuntu' 4 | 5 | describe ppa('username/ppa-name') do 6 | it { should exist } 7 | end 8 | 9 | describe ppa('username/ppa-name') do 10 | it { should be_enabled } 11 | end 12 | -------------------------------------------------------------------------------- /spec/type/ubuntu/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :os, :family => 'ubuntu' 4 | 5 | describe service('sshd') do 6 | it { should be_running } 7 | end 8 | -------------------------------------------------------------------------------- /spec/type/windows/command_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | set :os, :family => 'windows' 5 | 6 | describe command('test_cmd /test/path/file') do 7 | let(:stdout) { "test output 1.2.3\r\n" } 8 | its(:stdout) { should match /test output 1.2.3/ } 9 | end 10 | 11 | describe 'complete matching of stdout' do 12 | context command('test_cmd /test/path/file') do 13 | let(:stdout) { "foocontent-should-be-includedbar\r\n" } 14 | its(:stdout) { should_not eq 'content-should-be-included' } 15 | end 16 | end 17 | 18 | describe 'regexp matching of stdout' do 19 | context command('test_cmd /test/path/file') do 20 | let(:stdout) { "test output 1.2.3\r\n" } 21 | its(:stdout) { should match /1\.2\.3/ } 22 | end 23 | end 24 | 25 | describe command('test_cmd /test/path/file') do 26 | let(:stderr) { "No such file or directory\r\n" } 27 | its(:stderr) { should match /No such file or directory/ } 28 | end 29 | 30 | describe 'complete matching of stderr' do 31 | context command('test_cmd /test/path/file') do 32 | let(:stderr) { "No such file or directory\r\n" } 33 | its(:stderr) { should_not eq 'file' } 34 | end 35 | end 36 | 37 | describe 'regexp matching of stderr' do 38 | context command('test_cmd /test/path/file') do 39 | let(:stderr) { "No such file or directory\r\n" } 40 | its(:stderr) { should match /file/ } 41 | end 42 | end 43 | 44 | describe command('test_cmd /test/path/file') do 45 | its(:exit_status) { should eq 0 } 46 | end 47 | 48 | describe command('dir "c:\"') do 49 | let(:stdout) { < 'windows' 6 | 7 | describe windows_feature('Minesweeper') do 8 | it{ should be_installed } 9 | end 10 | 11 | describe windows_feature('IIS-Webserver') do 12 | it{ should be_installed.by(:dism) } 13 | end 14 | 15 | describe windows_feature('Web-Webserver') do 16 | it{ should be_installed.by(:powershell) } 17 | end 18 | -------------------------------------------------------------------------------- /spec/type/windows/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe file('/some/valid/file') do 8 | it { should be_file } 9 | end 10 | 11 | describe file('/some/valid/folder') do 12 | it { should be_directory } 13 | end 14 | 15 | describe file('/some/file') do 16 | it { should contain 'search text' } 17 | end 18 | 19 | describe file('/some/file') do 20 | it { should contain /^search text/ } 21 | end 22 | 23 | describe file('Gemfile') do 24 | it { should contain('rspec').from(/^group :test do/).to(/^end/) } 25 | end 26 | 27 | describe file('Gemfile') do 28 | it { should contain('rspec').after(/^group :test do/) } 29 | end 30 | 31 | describe file('Gemfile') do 32 | it { should contain('rspec').before(/end/) } 33 | end 34 | 35 | describe file('/some/file') do 36 | it { should be_readable } 37 | end 38 | 39 | describe file('/some/file') do 40 | it "should raise error if trying to check access by 'owner' or 'group' or 'others'" do 41 | ['owner', 'group', 'others'].each do |access| 42 | expect { should be_readable.by(access) }.to raise_error(RuntimeError) 43 | end 44 | end 45 | end 46 | 47 | describe file('/some/file') do 48 | it { should be_readable.by('test.identity') } 49 | end 50 | 51 | describe file('/some/file') do 52 | it { should be_readable.by_user('test.identity') } 53 | end 54 | 55 | describe file('/some/file') do 56 | it { should be_writable } 57 | end 58 | 59 | describe file('/some/file') do 60 | it "should raise error if trying to check access by 'owner' or 'group' or 'others'" do 61 | ['owner', 'group', 'others'].each do |access| 62 | expect { should be_writable.by(access) }.to raise_error(RuntimeError) 63 | end 64 | end 65 | end 66 | 67 | describe file('/some/file') do 68 | it { should be_writable.by('test.identity') } 69 | end 70 | 71 | describe file('/some/file') do 72 | it { should be_writable.by_user('test.identity') } 73 | end 74 | 75 | describe file('/some/file') do 76 | it { should be_executable } 77 | end 78 | 79 | describe file('/some/file') do 80 | it "should raise error if trying to check access by 'owner' or 'group' or 'others'" do 81 | ['owner', 'group', 'others'].each do |access| 82 | expect { should be_executable.by(access) }.to raise_error(RuntimeError) 83 | end 84 | end 85 | end 86 | 87 | describe file('/some/file') do 88 | it { should be_executable.by('test.identity') } 89 | end 90 | 91 | describe file('/some/file') do 92 | it { should be_executable.by_user('test.identity') } 93 | end 94 | 95 | describe file('/some/file') do 96 | it { should be_version 1 } 97 | end 98 | 99 | describe file('/some/test/file') do 100 | it "should raise error if command is not implemented" do 101 | { 102 | :be_socket => [], 103 | :be_mode => 644, 104 | :be_grouped_into => 'root', 105 | :be_linked_to => '/some/other/file', 106 | :be_mounted => [] 107 | }.each do |method, args| 108 | expect { should self.send(method, *args) }.to raise_error(NotImplementedError) 109 | end 110 | end 111 | 112 | it "should raise error if command is not defined" do 113 | { 114 | :match_md5checksum => '35435ea447c19f0ea5ef971837ab9ced', 115 | :match_sha256checksum => '0c3feee1353a8459f8c7d84885e6bc602ef853751ffdbce3e3b6dfa1d345fc7a' 116 | }.each do |method, args| 117 | expect { should self.send(method, *args) }.to raise_error(NoMethodError) 118 | end 119 | end 120 | end 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /spec/type/windows/group_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe group('test.group') do 8 | it { should exist } 9 | end 10 | 11 | describe group('test.domain\test.group') do 12 | it { should exist } 13 | end 14 | 15 | describe group('test.group') do 16 | it "should raise error if command is not supported" do 17 | { 18 | :have_gid => [nil], 19 | }.each do |method, args| 20 | expect { should self.send(method, *args) }.to raise_error(NotImplementedError) 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/type/windows/host_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | set :os, :family => 'windows' 5 | 6 | describe host('127.0.0.1') do 7 | it { should be_resolvable } 8 | end 9 | 10 | describe host('127.0.0.1') do 11 | it { should be_resolvable.by('hosts') } 12 | end 13 | 14 | describe host('127.0.0.1') do 15 | it { should be_resolvable.by('dns') } 16 | end 17 | 18 | describe host('127.0.0.1') do 19 | it { should be_reachable } 20 | end 21 | 22 | describe host('127.0.0.1') do 23 | it { should be_reachable.with(:proto => "icmp", :timeout=> 1) } 24 | end 25 | 26 | describe host('127.0.0.1') do 27 | it { should be_reachable.with(:proto => "tcp", :port => 22, :timeout=> 1) } 28 | end 29 | 30 | describe host('127.0.0.1') do 31 | it { should be_reachable.with(:proto => "udp", :port => 53, :timeout=> 1) } 32 | end 33 | -------------------------------------------------------------------------------- /spec/type/windows/hot_fix_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe windows_hot_fix('DESCRIPTION-OR-KB-ID') do 8 | it { should be_installed } 9 | end 10 | 11 | describe windows_hot_fix('DESCRIPTION') do 12 | it { should be_installed.with_version('KB-ID') } 13 | end 14 | 15 | describe windows_hot_fix('DESCRIPTION_WITH_KB123456789_INLINED') do 16 | it { should be_installed } 17 | end 18 | 19 | describe windows_hot_fix('DESCRIPTION_WITH_SUFFIX_KB123456789') do 20 | it { should be_installed } 21 | end 22 | 23 | -------------------------------------------------------------------------------- /spec/type/windows/iis_app_pool_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe iis_app_pool('Default App Pool') do 8 | it { should exist } 9 | it { should have_dotnet_version('2.0') } 10 | it { should have_32bit_enabled } 11 | it { should have_idle_timeout(5) } 12 | it { should have_identity_type('foo') } 13 | it { should have_periodic_restart(60) } 14 | it { should have_user_profile_enabled } 15 | it { should have_username('user') } 16 | it { should have_managed_pipeline_mode('mode') } 17 | end 18 | -------------------------------------------------------------------------------- /spec/type/windows/iis_webisite_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe iis_website('Default Website') do 8 | it { should exist } 9 | it { should be_enabled } 10 | it { should be_running } 11 | it { should be_in_app_pool('Default App Pool') } 12 | it { should have_physical_path('C:\\inetpub\\www') } 13 | it { should have_site_bindings('port').with_protocol('protocol').with_ipaddress('ipaddress').with_host_header('host_header') } 14 | it { should have_virtual_dir('vdir').with_path('path') } 15 | it { should have_site_application('app').with_pool('pool').with_physical_path('physical_path') } 16 | end 17 | -------------------------------------------------------------------------------- /spec/type/windows/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe package('foo') do 8 | it { should be_installed } 9 | end 10 | 11 | -------------------------------------------------------------------------------- /spec/type/windows/port_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe port(80) do 8 | it { should be_listening } 9 | end 10 | 11 | describe port(80) do 12 | it { should be_listening.with("tcp") } 13 | end 14 | 15 | describe port(123) do 16 | it { should be_listening.with("udp") } 17 | end 18 | 19 | describe port(80) do 20 | it { 21 | expect { 22 | should be_listening.with('not implemented') 23 | }.to raise_error(ArgumentError, %r/\A`be_listening` matcher doesn\'t support/) 24 | } 25 | end 26 | -------------------------------------------------------------------------------- /spec/type/windows/registry_key_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | set :os, :family => 'windows' 5 | 6 | describe windows_registry_key('PATH/TO/THE_KEY') do 7 | it { should exist } 8 | end 9 | 10 | describe windows_registry_key('PATH/TO/THE_KEY') do 11 | it { should have_value('Test Value') } 12 | end 13 | 14 | describe 'Key value types' do 15 | context 'default type' do 16 | describe windows_registry_key('PATH/TO/THE_KEY') do 17 | it { should have_property('TestProperty') } 18 | end 19 | end 20 | 21 | { 22 | :type_string => 'String', 23 | :type_binary => 'Binary', 24 | :type_dword => 'DWord', 25 | :type_qword => 'QWord', 26 | :type_multistring => 'MultiString', 27 | :type_expandstring => 'ExpandString' 28 | }.each do |sym, type| 29 | context "type #{type}" do 30 | describe windows_registry_key('PATH/TO/THE_KEY') do 31 | it { should have_property('TestProperty', sym) } 32 | end 33 | end 34 | end 35 | end 36 | 37 | describe windows_registry_key('PATH/TO/THE_KEY') do 38 | it { should have_property_value('TestProperty', :type_binary, '12a07b') } 39 | end 40 | 41 | describe windows_registry_key('PATH/TO/THE_KEY') do 42 | it { should have_property_value('TestProperty', :type_dword, 'fffffd6c') } 43 | end 44 | 45 | describe windows_registry_key('PATH/TO/THE_KEY') do 46 | it { should have_property_value('TestProperty', :type_qword, '1e240') } 47 | end 48 | 49 | describe windows_registry_key('PATH/TO/THE_KEY') do 50 | it { 51 | value = <<-EOF 52 | test line1 53 | test line2 54 | test line3 55 | EOF 56 | should have_property_value('TestProperty', :type_multistring, value) 57 | } 58 | end 59 | -------------------------------------------------------------------------------- /spec/type/windows/scheduled_task_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe windows_scheduled_task('foo') do 8 | it { should exist } 9 | end 10 | -------------------------------------------------------------------------------- /spec/type/windows/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe service('Test Service') do 8 | it { should be_enabled } 9 | end 10 | 11 | describe service('Test Service') do 12 | it { should be_running } 13 | end 14 | 15 | describe service('service') do 16 | it { should be_installed } 17 | end 18 | 19 | describe service('service') do 20 | it { should have_start_mode 'mode' } 21 | end 22 | 23 | describe service('Test service') do 24 | it "should raise error if trying to check service process controller" do 25 | expect { should be_running.under('supervisor') }.to raise_error(NotImplementedError) 26 | end 27 | it "should raise error if trying to check service monitoring" do 28 | expect { should_not be_monitored_by('monit') }.to raise_error(NotImplementedError) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/type/windows/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | set :backend, :cmd 4 | 5 | set :os, :family => 'windows' 6 | 7 | describe user('test.user') do 8 | it { should exist } 9 | end 10 | 11 | describe user('test.domain\test.user') do 12 | it { should exist } 13 | end 14 | 15 | describe user('test.user') do 16 | it { should belong_to_group 'test.group' } 17 | end 18 | 19 | describe user('test.user.domain\test.user') do 20 | it { should belong_to_group 'test.group.domain\test.group' } 21 | end 22 | 23 | describe user('test.user') do 24 | it "should raise error if command is not supported" do 25 | { 26 | :have_uid => [nil], 27 | :have_login_shell => [nil], 28 | :have_authorized_key => [nil], 29 | }.each do |method, args| 30 | expect { should self.send(method, *args) }.to raise_error(NotImplementedError) 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /wercker.yml: -------------------------------------------------------------------------------- 1 | build: 2 | box: 3 | id: mizzy/wercker-serverspec 4 | steps: 5 | - script: 6 | name: initialize git submodules 7 | code: git submodule update --init --recursive 8 | - script: 9 | name: Run walter 10 | code: ./$WORKING_DIR/walter -config ./$WORKING_DIR/pipeline.yml -build 11 | after-steps: 12 | - wantedly/pretty-slack-notify: 13 | webhook_url: $SLACK_WEBHOOK_URL 14 | --------------------------------------------------------------------------------