inspec 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rubocop.yml +65 -0
  4. data/.travis.yml +23 -0
  5. data/CHANGELOG.md +38 -0
  6. data/Gemfile +33 -0
  7. data/LICENSE +201 -0
  8. data/MAINTAINERS.md +28 -0
  9. data/MAINTAINERS.toml +42 -0
  10. data/README.md +257 -0
  11. data/Rakefile +47 -0
  12. data/bin/inspec +109 -0
  13. data/docs/ctl_inspec.rst +195 -0
  14. data/docs/dsl_inspec.rst +182 -0
  15. data/docs/readme.rst +100 -0
  16. data/docs/resources.rst +4319 -0
  17. data/docs/template.rst +51 -0
  18. data/examples/test-kitchen/.kitchen.yml +20 -0
  19. data/examples/test-kitchen/Berksfile +3 -0
  20. data/examples/test-kitchen/Gemfile +21 -0
  21. data/examples/test-kitchen/README.md +27 -0
  22. data/examples/test-kitchen/metadata.rb +7 -0
  23. data/examples/test-kitchen/recipes/default.rb +6 -0
  24. data/examples/test-kitchen/recipes/nginx.rb +30 -0
  25. data/examples/test-kitchen/test/integration/default/web_spec.rb +28 -0
  26. data/inspec.gemspec +30 -0
  27. data/lib/inspec.rb +20 -0
  28. data/lib/inspec/backend.rb +42 -0
  29. data/lib/inspec/dsl.rb +151 -0
  30. data/lib/inspec/log.rb +34 -0
  31. data/lib/inspec/metadata.rb +79 -0
  32. data/lib/inspec/plugins.rb +9 -0
  33. data/lib/inspec/plugins/resource.rb +62 -0
  34. data/lib/inspec/profile.rb +138 -0
  35. data/lib/inspec/profile_context.rb +170 -0
  36. data/lib/inspec/resource.rb +76 -0
  37. data/lib/inspec/rspec_json_formatter.rb +27 -0
  38. data/lib/inspec/rule.rb +170 -0
  39. data/lib/inspec/runner.rb +154 -0
  40. data/lib/inspec/shell.rb +66 -0
  41. data/lib/inspec/targets.rb +9 -0
  42. data/lib/inspec/targets/core.rb +27 -0
  43. data/lib/inspec/targets/dir.rb +67 -0
  44. data/lib/inspec/targets/file.rb +29 -0
  45. data/lib/inspec/targets/folder.rb +43 -0
  46. data/lib/inspec/targets/tar.rb +34 -0
  47. data/lib/inspec/targets/url.rb +39 -0
  48. data/lib/inspec/targets/zip.rb +47 -0
  49. data/lib/inspec/version.rb +7 -0
  50. data/lib/matchers/matchers.rb +221 -0
  51. data/lib/resources/apache.rb +29 -0
  52. data/lib/resources/apache_conf.rb +113 -0
  53. data/lib/resources/apt.rb +140 -0
  54. data/lib/resources/audit_policy.rb +63 -0
  55. data/lib/resources/auditd_conf.rb +56 -0
  56. data/lib/resources/auditd_rules.rb +53 -0
  57. data/lib/resources/bond.rb +65 -0
  58. data/lib/resources/bridge.rb +114 -0
  59. data/lib/resources/command.rb +57 -0
  60. data/lib/resources/csv.rb +32 -0
  61. data/lib/resources/directory.rb +15 -0
  62. data/lib/resources/etc_group.rb +150 -0
  63. data/lib/resources/file.rb +110 -0
  64. data/lib/resources/gem.rb +46 -0
  65. data/lib/resources/group.rb +132 -0
  66. data/lib/resources/host.rb +143 -0
  67. data/lib/resources/inetd_conf.rb +56 -0
  68. data/lib/resources/interface.rb +127 -0
  69. data/lib/resources/iptables.rb +65 -0
  70. data/lib/resources/json.rb +64 -0
  71. data/lib/resources/kernel_module.rb +40 -0
  72. data/lib/resources/kernel_parameter.rb +55 -0
  73. data/lib/resources/limits_conf.rb +55 -0
  74. data/lib/resources/login_def.rb +60 -0
  75. data/lib/resources/mysql.rb +81 -0
  76. data/lib/resources/mysql_conf.rb +116 -0
  77. data/lib/resources/mysql_session.rb +52 -0
  78. data/lib/resources/npm.rb +44 -0
  79. data/lib/resources/ntp_conf.rb +58 -0
  80. data/lib/resources/oneget.rb +63 -0
  81. data/lib/resources/os.rb +22 -0
  82. data/lib/resources/os_env.rb +34 -0
  83. data/lib/resources/package.rb +169 -0
  84. data/lib/resources/parse_config.rb +75 -0
  85. data/lib/resources/passwd.rb +93 -0
  86. data/lib/resources/pip.rb +75 -0
  87. data/lib/resources/port.rb +296 -0
  88. data/lib/resources/postgres.rb +37 -0
  89. data/lib/resources/postgres_conf.rb +87 -0
  90. data/lib/resources/postgres_session.rb +59 -0
  91. data/lib/resources/processes.rb +57 -0
  92. data/lib/resources/registry_key.rb +54 -0
  93. data/lib/resources/script.rb +34 -0
  94. data/lib/resources/security_policy.rb +73 -0
  95. data/lib/resources/service.rb +379 -0
  96. data/lib/resources/ssh_conf.rb +75 -0
  97. data/lib/resources/user.rb +374 -0
  98. data/lib/resources/windows_feature.rb +77 -0
  99. data/lib/resources/yaml.rb +23 -0
  100. data/lib/resources/yum.rb +154 -0
  101. data/lib/utils/convert.rb +12 -0
  102. data/lib/utils/detect.rb +15 -0
  103. data/lib/utils/find_files.rb +36 -0
  104. data/lib/utils/hash.rb +13 -0
  105. data/lib/utils/modulator.rb +12 -0
  106. data/lib/utils/parser.rb +61 -0
  107. data/lib/utils/simpleconfig.rb +115 -0
  108. data/tasks/maintainers.rb +213 -0
  109. data/test/docker_run.rb +156 -0
  110. data/test/docker_test.rb +51 -0
  111. data/test/helper.rb +200 -0
  112. data/test/integration/.kitchen.yml +42 -0
  113. data/test/integration/Berksfile +4 -0
  114. data/test/integration/cookbooks/os_prepare/metadata.rb +8 -0
  115. data/test/integration/cookbooks/os_prepare/recipes/apt.rb +20 -0
  116. data/test/integration/cookbooks/os_prepare/recipes/default.rb +9 -0
  117. data/test/integration/cookbooks/os_prepare/recipes/file.rb +21 -0
  118. data/test/integration/cookbooks/os_prepare/recipes/package.rb +26 -0
  119. data/test/integration/default/_debug_spec.rb +1 -0
  120. data/test/integration/default/apt_spec.rb +42 -0
  121. data/test/integration/default/file_spec.rb +109 -0
  122. data/test/integration/default/group_spec.rb +32 -0
  123. data/test/integration/default/kernel_module_spec.rb +17 -0
  124. data/test/integration/default/kernel_parameter_spec.rb +56 -0
  125. data/test/integration/default/package_spec.rb +11 -0
  126. data/test/integration/default/service_spec.rb +28 -0
  127. data/test/integration/default/user_spec.rb +44 -0
  128. data/test/resource/command_test.rb +33 -0
  129. data/test/resource/dsl_test.rb +45 -0
  130. data/test/resource/file_test.rb +130 -0
  131. data/test/resource/ssh_config.rb +9 -0
  132. data/test/resource/sshd_config.rb +9 -0
  133. data/test/test-extra.yaml +11 -0
  134. data/test/test.yaml +11 -0
  135. data/test/unit/mock/cmd/Get-NetAdapter +24 -0
  136. data/test/unit/mock/cmd/GetUserAccount +33 -0
  137. data/test/unit/mock/cmd/GetWin32Group +23 -0
  138. data/test/unit/mock/cmd/PATH +1 -0
  139. data/test/unit/mock/cmd/Resolve-DnsName +26 -0
  140. data/test/unit/mock/cmd/Test-NetConnection +4 -0
  141. data/test/unit/mock/cmd/auditctl +7 -0
  142. data/test/unit/mock/cmd/auditpol +2 -0
  143. data/test/unit/mock/cmd/brew-info-jq +1 -0
  144. data/test/unit/mock/cmd/chage-l-root +7 -0
  145. data/test/unit/mock/cmd/dpkg-s-curl +21 -0
  146. data/test/unit/mock/cmd/dscl +5 -0
  147. data/test/unit/mock/cmd/etc-apt +7 -0
  148. data/test/unit/mock/cmd/find-etc-rc-d-name-S +12 -0
  149. data/test/unit/mock/cmd/find-net-interface +9 -0
  150. data/test/unit/mock/cmd/gem-list-local-a-q-rubocop +1 -0
  151. data/test/unit/mock/cmd/get-net-tcpconnection +24 -0
  152. data/test/unit/mock/cmd/get-netadapter-binding-bridge +4 -0
  153. data/test/unit/mock/cmd/get-package-firefox +30 -0
  154. data/test/unit/mock/cmd/get-package-ruby +18 -0
  155. data/test/unit/mock/cmd/get-service-dhcp +10 -0
  156. data/test/unit/mock/cmd/get-windows-feature +7 -0
  157. data/test/unit/mock/cmd/getent-hosts-example.com +1 -0
  158. data/test/unit/mock/cmd/getent-passwd-root +1 -0
  159. data/test/unit/mock/cmd/id-chartmann +1 -0
  160. data/test/unit/mock/cmd/id-root +1 -0
  161. data/test/unit/mock/cmd/initctl-show-config-ssh +3 -0
  162. data/test/unit/mock/cmd/initctl-status-ssh +1 -0
  163. data/test/unit/mock/cmd/iptables-s +6 -0
  164. data/test/unit/mock/cmd/launchctl-list +3 -0
  165. data/test/unit/mock/cmd/ls-1-etc-init.d +2 -0
  166. data/test/unit/mock/cmd/ls-sys-class-net-br +2 -0
  167. data/test/unit/mock/cmd/lsmod +2 -0
  168. data/test/unit/mock/cmd/lsof-np-itcp +4 -0
  169. data/test/unit/mock/cmd/netstat-tulpen +5 -0
  170. data/test/unit/mock/cmd/npm-ls-g--json-bower +9 -0
  171. data/test/unit/mock/cmd/pacman-qi-curl +21 -0
  172. data/test/unit/mock/cmd/ping-example.com +6 -0
  173. data/test/unit/mock/cmd/pip-show-jinja2 +11 -0
  174. data/test/unit/mock/cmd/ps-aux +3 -0
  175. data/test/unit/mock/cmd/pw-usershow-root-7 +1 -0
  176. data/test/unit/mock/cmd/reg_schedule +1 -0
  177. data/test/unit/mock/cmd/rpm-qia-curl +24 -0
  178. data/test/unit/mock/cmd/sbin_sysctl +1 -0
  179. data/test/unit/mock/cmd/secedit-export +7 -0
  180. data/test/unit/mock/cmd/service-e +2 -0
  181. data/test/unit/mock/cmd/service-sendmail-onestatus +3 -0
  182. data/test/unit/mock/cmd/service-sshd-status +1 -0
  183. data/test/unit/mock/cmd/sockstat +5 -0
  184. data/test/unit/mock/cmd/success +0 -0
  185. data/test/unit/mock/cmd/systemctl-show-all-sshd +6 -0
  186. data/test/unit/mock/cmd/win32_product +8 -0
  187. data/test/unit/mock/cmd/yum-repolist-all +52 -0
  188. data/test/unit/mock/files/auditd.conf +4 -0
  189. data/test/unit/mock/files/bond0 +37 -0
  190. data/test/unit/mock/files/etcgroup +3 -0
  191. data/test/unit/mock/files/example.csv +6 -0
  192. data/test/unit/mock/files/inetd.conf +2 -0
  193. data/test/unit/mock/files/kitchen.yml +7 -0
  194. data/test/unit/mock/files/limits.conf +5 -0
  195. data/test/unit/mock/files/login.defs +5 -0
  196. data/test/unit/mock/files/mysql.conf +8 -0
  197. data/test/unit/mock/files/mysql2.conf +2 -0
  198. data/test/unit/mock/files/ntp.conf +5 -0
  199. data/test/unit/mock/files/passwd +2 -0
  200. data/test/unit/mock/files/policyfile.lock.json +12 -0
  201. data/test/unit/mock/files/ssh_config +5 -0
  202. data/test/unit/mock/files/sshd_config +7 -0
  203. data/test/unit/mock/profiles/empty/metadata.rb +0 -0
  204. data/test/unit/mock/profiles/metadata/metadata.rb +1 -0
  205. data/test/unit/profile_context_test.rb +140 -0
  206. data/test/unit/profile_test.rb +49 -0
  207. data/test/unit/resources/apt_test.rb +46 -0
  208. data/test/unit/resources/audit_policy_test.rb +13 -0
  209. data/test/unit/resources/auditd_conf_test.rb +15 -0
  210. data/test/unit/resources/auditd_rules_test.rb +21 -0
  211. data/test/unit/resources/bond_test.rb +24 -0
  212. data/test/unit/resources/bridge_test.rb +56 -0
  213. data/test/unit/resources/csv_test.rb +35 -0
  214. data/test/unit/resources/etc_group_test.rb +37 -0
  215. data/test/unit/resources/gem_test.rb +20 -0
  216. data/test/unit/resources/group_test.rb +96 -0
  217. data/test/unit/resources/host_test.rb +38 -0
  218. data/test/unit/resources/inetd_conf_test.rb +15 -0
  219. data/test/unit/resources/interface_test.rb +54 -0
  220. data/test/unit/resources/iptables_test.rb +30 -0
  221. data/test/unit/resources/json_test.rb +36 -0
  222. data/test/unit/resources/kernel_module_test.rb +23 -0
  223. data/test/unit/resources/kernel_parameter_test.rb +13 -0
  224. data/test/unit/resources/limits_conf_test.rb +14 -0
  225. data/test/unit/resources/login_def_test.rb +16 -0
  226. data/test/unit/resources/mysql_conf_test.rb +14 -0
  227. data/test/unit/resources/npm_test.rb +20 -0
  228. data/test/unit/resources/ntp_conf_test.rb +16 -0
  229. data/test/unit/resources/oneget_test.rb +45 -0
  230. data/test/unit/resources/os_env_test.rb +13 -0
  231. data/test/unit/resources/package_test.rb +51 -0
  232. data/test/unit/resources/passwd_test.rb +24 -0
  233. data/test/unit/resources/pip_test.rb +15 -0
  234. data/test/unit/resources/port_test.rb +46 -0
  235. data/test/unit/resources/processes_test.rb +32 -0
  236. data/test/unit/resources/registry_key_test.rb +19 -0
  237. data/test/unit/resources/script_test.rb +19 -0
  238. data/test/unit/resources/security_policy_test.rb +16 -0
  239. data/test/unit/resources/service_test.rb +116 -0
  240. data/test/unit/resources/ssh_conf_test.rb +33 -0
  241. data/test/unit/resources/user_test.rb +93 -0
  242. data/test/unit/resources/windows_feature.rb +17 -0
  243. data/test/unit/resources/yaml_test.rb +34 -0
  244. data/test/unit/resources/yum_test.rb +68 -0
  245. data/test/unit/simpleconfig_test.rb +80 -0
  246. data/test/unit/utils/content_parser_test.rb +30 -0
  247. metadata +555 -0
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'inspec/targets/core'
6
+ require 'inspec/targets/file'
7
+ require 'inspec/targets/folder'
8
+ require 'inspec/targets/url'
9
+ require 'inspec/targets/dir'
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'utils/modulator'
6
+
7
+ module Inspec
8
+ module Targets
9
+ extend Modulator
10
+
11
+ def self.__resolve(items)
12
+ items.map do |_|
13
+ # @TODO
14
+ end.flatten
15
+ end
16
+
17
+ def self.resolve(targets)
18
+ Array(targets).map do |target|
19
+ handler = modules.values.find { |m| m.handles?(target) }
20
+ if handler.nil?
21
+ fail "Don't know how to handle target: #{target}"
22
+ end
23
+ handler.resolve(target)
24
+ end.flatten
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ module Inspec::Targets
6
+ module DirsHelper
7
+ class ProfileDir
8
+ def handles?(paths)
9
+ paths.include?('test') && paths.include?('metadata.rb')
10
+ end
11
+
12
+ def get_libraries(paths)
13
+ paths.find_all do |path|
14
+ path.start_with?('libraries') && path.end_with?('.rb')
15
+ end
16
+ end
17
+
18
+ def get_filenames(paths)
19
+ paths.find_all do |path|
20
+ path.start_with?('test') && path.end_with?('.rb')
21
+ end
22
+ end
23
+ end
24
+
25
+ class ChefAuditDir
26
+ def handles?(paths)
27
+ paths.include?('recipes') and paths.include?('metadata.rb')
28
+ end
29
+
30
+ def get_filenames(paths)
31
+ paths.find_all do |x|
32
+ x.start_with? 'recipes/' and x.end_with? '.rb'
33
+ end
34
+ end
35
+ end
36
+
37
+ class ServerspecDir
38
+ def handles?(paths)
39
+ paths.include?('spec')
40
+ end
41
+
42
+ def get_filenames(paths)
43
+ paths.find_all do |path|
44
+ path.start_with? 'spec' and path.end_with? '_spec.rb'
45
+ end
46
+ end
47
+ end
48
+
49
+ class FlatDir
50
+ def handles?(paths)
51
+ get_filenames(paths).empty? == false
52
+ end
53
+
54
+ def get_filenames(paths)
55
+ paths.find_all { |x| x.end_with?('.rb') and !x.include?('/') }
56
+ end
57
+ end
58
+
59
+ HANDLERS = [
60
+ ProfileDir, ChefAuditDir, ServerspecDir, FlatDir
61
+ ].map(&:new)
62
+
63
+ def self.get_handler(paths)
64
+ HANDLERS.find { |x| x.handles? paths }
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ module Inspec::Targets
6
+ class FileHelper
7
+ def handles?(target)
8
+ File.file?(target) and target.end_with?('.rb')
9
+ end
10
+
11
+ def resolve(target, opts = {})
12
+ base = opts[:base_folder]
13
+ path = base.nil? ? target : File.join(base, target)
14
+ {
15
+ content: File.read(path),
16
+ type: opts[:as] || :test,
17
+ ref: path,
18
+ }
19
+ end
20
+
21
+ def resolve_all(targets, opts = {})
22
+ Array(targets).map do |target|
23
+ resolve(target, opts)
24
+ end
25
+ end
26
+ end
27
+
28
+ Inspec::Targets.add_module('file', FileHelper.new)
29
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'inspec/targets/dir'
6
+ require 'inspec/targets/file'
7
+
8
+ module Inspec::Targets
9
+ class FolderHelper
10
+ def handles?(target)
11
+ File.directory?(target)
12
+ end
13
+
14
+ def resolve(target)
15
+ # find all files in the folder
16
+ files = Dir[File.join(target, '**', '*')]
17
+ # remove the prefix
18
+ prefix = File.join(target, '')
19
+ files = files.map { |x| x.sub(prefix, '') }
20
+ # get the dirs helper
21
+ helper = DirsHelper.get_handler(files)
22
+ if helper.nil?
23
+ fail "Don't know how to handle folder #{target}"
24
+ end
25
+
26
+ # get all test file contents
27
+ file_handler = Inspec::Targets.modules['file']
28
+ raw_files = helper.get_filenames(files)
29
+ tests = file_handler.resolve_all(raw_files, base_folder: target)
30
+
31
+ libs = []
32
+ if helper.respond_to? :get_libraries
33
+ raw_libs = helper.get_libraries(files)
34
+ libs = file_handler.resolve_all(raw_libs,
35
+ base_folder: target, as: :library)
36
+ end
37
+
38
+ libs + tests
39
+ end
40
+ end
41
+
42
+ Inspec::Targets.add_module('folder', FolderHelper.new)
43
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'rubygems/package'
6
+ require 'zlib'
7
+
8
+ module Inspec::Targets
9
+ class TarHelper
10
+ def structure(input)
11
+ files = []
12
+ Gem::Package::TarReader.new(Zlib::GzipReader.open input) do |tar|
13
+ files = tar.map(&:full_name)
14
+ end
15
+ files
16
+ end
17
+
18
+ def content(input)
19
+ content = {}
20
+ Gem::Package::TarReader.new(Zlib::GzipReader.open input) do |tar|
21
+ tar.each do |entry|
22
+ if entry.directory?
23
+ # nothing to do
24
+ elsif entry.file?
25
+ content[entry.full_name] = entry.read
26
+ elsif entry.header.typeflag == '2'
27
+ # ignore symlinks for now
28
+ end
29
+ end
30
+ end
31
+ content
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'uri'
6
+ require 'tempfile'
7
+ require 'open-uri'
8
+ require 'inspec/targets/zip'
9
+
10
+ module Inspec::Targets
11
+ class UrlHelper
12
+ def handles?(target)
13
+ uri = URI.parse(target)
14
+ return false if uri.nil? or uri.scheme.nil?
15
+ %{ http https }.include? uri.scheme
16
+ end
17
+
18
+ def resolve(target)
19
+ return nil unless target.start_with? 'https://github.com' and
20
+ target.end_with? '.git'
21
+
22
+ url = target.sub(/.git$/, '') + '/archive/master.zip'
23
+ resolve_zip(url)
24
+ end
25
+
26
+ def resolve_zip(url)
27
+ zipfile = Tempfile.new('inspec-dl-')
28
+ zipfile.binmode
29
+ zipfile.write(open(url).read)
30
+ zipfile.rewind
31
+ content = ZipHelper.new.resolve(zipfile.path)
32
+ zipfile.close
33
+ zipfile.unlink
34
+ content
35
+ end
36
+ end
37
+
38
+ Inspec::Targets.add_module('url', UrlHelper.new)
39
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'zip'
6
+ require 'inspec/targets/dir'
7
+
8
+ module Inspec::Targets
9
+ class ZipHelper
10
+ def content(input, _filter)
11
+ content = []
12
+ ::Zip::InputStream.open(input) do |io|
13
+ while (entry = io.get_next_entry)
14
+ h = {
15
+ content: io.read,
16
+ ref: File.join(input, entry.name),
17
+ }
18
+ content.push(h)
19
+ end
20
+ end
21
+ content
22
+ end
23
+
24
+ def structure(input)
25
+ files = []
26
+ ::Zip::InputStream.open(input) do |io|
27
+ while (entry = io.get_next_entry)
28
+ files.push(entry.name)
29
+ end
30
+ end
31
+ files
32
+ end
33
+
34
+ def resolve(path)
35
+ files = structure(path)
36
+ helper = DirsHelper.get_handler(files)
37
+ if helper.nil?
38
+ fail "Don't know how to handle folder #{path}"
39
+ end
40
+ # get all file contents
41
+ # @TODO
42
+ _file_handler = Inspec::Targets.modules['file']
43
+ test_files = helper.get_filenames(files)
44
+ content(path, test_files)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ module Inspec
6
+ VERSION = '0.9.0'
7
+ end
@@ -0,0 +1,221 @@
1
+ # encoding: utf-8
2
+ # copyright: 2015, Vulcano Security GmbH
3
+ # author: Dominik Richter
4
+ # author: Christoph Hartmann
5
+ # license: All rights reserved
6
+
7
+ RSpec::Matchers.define :be_readable do
8
+ match do |file|
9
+ file.readable?(@by, @by_user)
10
+ end
11
+
12
+ chain :by do |by|
13
+ @by = by
14
+ end
15
+
16
+ chain :by_user do |by_user|
17
+ @by_user = by_user
18
+ end
19
+
20
+ description do
21
+ res = 'be readable'
22
+ res += " by #{@by}" unless @by.nil?
23
+ res += " by user #{@by_user}" unless @by_user.nil?
24
+ res
25
+ end
26
+ end
27
+
28
+ RSpec::Matchers.define :be_writable do
29
+ match do |file|
30
+ file.writable?(@by, @by_user)
31
+ end
32
+
33
+ chain :by do |by|
34
+ @by = by
35
+ end
36
+
37
+ chain :by_user do |by_user|
38
+ @by_user = by_user
39
+ end
40
+
41
+ description do
42
+ res = 'be writable'
43
+ res += " by #{@by}" unless @by.nil?
44
+ res += " by user #{@by_user}" unless @by_user.nil?
45
+ res
46
+ end
47
+ end
48
+
49
+ RSpec::Matchers.define :be_executable do
50
+ match do |file|
51
+ file.executable?(@by, @by_user)
52
+ end
53
+
54
+ chain :by do |by|
55
+ @by = by
56
+ end
57
+
58
+ chain :by_user do |by_user|
59
+ @by_user = by_user
60
+ end
61
+
62
+ description do
63
+ res = 'be executable'
64
+ res += " by #{@by}" unless @by.nil?
65
+ res += " by user #{@by_user}" unless @by_user.nil?
66
+ res
67
+ end
68
+ end
69
+
70
+ # matcher to check /etc/passwd, /etc/shadow and /etc/group
71
+ RSpec::Matchers.define :contain_legacy_plus do
72
+ match do |file|
73
+ file.content.match(/^\+:/)
74
+ end
75
+ end
76
+
77
+ # verifies that no entry in an array contains a value
78
+ RSpec::Matchers.define :contain_match do |regex|
79
+ match do |arr|
80
+ arr.inject { |result, i|
81
+ result = i.match(regex)
82
+ result || i.match(/$/)
83
+ }
84
+ end
85
+ end
86
+
87
+ RSpec::Matchers.define :contain_duplicates do
88
+ match do |arr|
89
+ dup = arr.select { |element| arr.count(element) > 1 }
90
+ !dup.uniq.empty?
91
+ end
92
+ end
93
+
94
+ # for packages
95
+ RSpec::Matchers.define :be_installed do
96
+ match do |package|
97
+ package.installed? == true
98
+ end
99
+
100
+ failure_message do |package|
101
+ "expected that `#{package}` is installed"
102
+ end
103
+
104
+ chain :by do
105
+ fail "[UNSUPPORTED] Please use the new resources 'gem', 'npm' or 'pip'."
106
+ end
107
+
108
+ chain :with_version do |version|
109
+ warn "[DEPRECATION] `with_version` is deprecated. Please use `its(:version) { should eq '1.4.1' }` instead."
110
+ @version = version
111
+ end
112
+ end
113
+
114
+ # for services
115
+ RSpec::Matchers.define :be_enabled do
116
+ match do |service|
117
+ service.enabled? == true
118
+ end
119
+
120
+ chain :with_level do |_level|
121
+ fail '[UNSUPPORTED] with level is not supported'
122
+ end
123
+
124
+ failure_message do |service|
125
+ "expected that `#{service}` is enabled"
126
+ end
127
+ end
128
+
129
+ # service resource matcher for serverspec compatibility
130
+ # Deprecated: You should not use this matcher anymore
131
+ RSpec::Matchers.define :be_running do
132
+ match do |service|
133
+ service.running? == true
134
+ end
135
+
136
+ chain :under do |_under|
137
+ fail '[UNSUPPORTED] under is not supported'
138
+ end
139
+
140
+ failure_message do |service|
141
+ "expected that `#{service}` is running"
142
+ end
143
+ end
144
+
145
+ # user resource matcher for serverspec compatibility
146
+ # Deprecated: You should not use this matcher anymore
147
+ RSpec::Matchers.define :belong_to_group do |compare_group|
148
+ match do |user|
149
+ warn "[DEPRECATION] `belong_to_group` is deprecated. Please use `its(:groups) { should include('root') }` instead."
150
+ user.groups.include?(compare_group)
151
+ end
152
+
153
+ failure_message do |group|
154
+ "expected that the user belongs to group `#{group}`"
155
+ end
156
+ end
157
+
158
+ # user resource matcher for serverspec compatibility
159
+ # Deprecated: You should not use this matcher anymore
160
+ RSpec::Matchers.define :belong_to_primary_group do |compare_group|
161
+ match do |user|
162
+ warn "[DEPRECATION] `belong_to_primary_group` is deprecated. Please use `its(:group) { should eq 'root' }` instead."
163
+ user.group == compare_group
164
+ end
165
+
166
+ failure_message do |group|
167
+ "expected that the user belongs to primary group `#{group}`"
168
+ end
169
+ end
170
+
171
+ # matcher to check if host is reachable
172
+ RSpec::Matchers.define :be_reachable do
173
+ match do |host|
174
+ host.reachable? == true
175
+ end
176
+
177
+ chain :with do |_attr|
178
+ fail '[UNSUPPORTED] `with` is not supported in combination with `be_reachable`'
179
+ end
180
+
181
+ failure_message do |host|
182
+ "expected that host #{host} is reachable"
183
+ end
184
+ end
185
+
186
+ # matcher to check if host is resolvable
187
+ RSpec::Matchers.define :be_resolvable do
188
+ match do |host|
189
+ host.resolvable? == true
190
+ end
191
+
192
+ chain :by do |_type|
193
+ fail "[UNSUPPORTED] `by` is not supported in combination with `be_resolvable`. Please use the following syntax `host('example.com', port: 53, proto: 'udp')`."
194
+ end
195
+
196
+ failure_message do |host|
197
+ "expected that host #{host} is resolvable"
198
+ end
199
+ end
200
+
201
+ # matcher for iptables
202
+ RSpec::Matchers.define :have_rule do |rule|
203
+ match do |tables|
204
+ tables.has_rule?(rule)
205
+ end
206
+
207
+ chain :with_table do |_table|
208
+ fail "[UNSUPPORTED] `with_table` is not supported in combination with `have_rule`. Please use the following syntax `iptables(table:'mangle', chain: 'input')`."
209
+ end
210
+
211
+ chain :with_chain do |_chain|
212
+ fail "[UNSUPPORTED] `with_table` is not supported in combination with `with_chain`. Please use the following syntax `iptables(table:'mangle', chain: 'input')`."
213
+ end
214
+ end
215
+
216
+ # unsupported
217
+ RSpec::Matchers.define :contain do |_rule|
218
+ match do |_resource|
219
+ fail "[UNSUPPORTED] `contain` matcher. Please use the following syntax `its('content') { should match('value') }`."
220
+ end
221
+ end