inspec 0.30.0 → 0.31.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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -2
  3. data/Gemfile +2 -1
  4. data/docs/cli.rst +1 -17
  5. data/docs/resources.rst +128 -0
  6. data/docs/shell.rst +130 -0
  7. data/inspec.gemspec +3 -4
  8. data/lib/bundles/inspec-compliance/.kitchen.yml +0 -1
  9. data/lib/bundles/inspec-compliance/README.md +8 -3
  10. data/lib/bundles/inspec-compliance/api.rb +21 -6
  11. data/lib/bundles/inspec-compliance/bootstrap.sh +13 -9
  12. data/lib/bundles/inspec-compliance/cli.rb +23 -19
  13. data/lib/bundles/inspec-compliance/target.rb +1 -0
  14. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +42 -5
  15. data/lib/bundles/inspec-init/cli.rb +9 -0
  16. data/lib/bundles/inspec-supermarket/cli.rb +9 -0
  17. data/lib/bundles/inspec-supermarket/target.rb +2 -1
  18. data/lib/fetchers/local.rb +5 -2
  19. data/lib/fetchers/url.rb +1 -0
  20. data/lib/inspec/base_cli.rb +2 -1
  21. data/lib/inspec/cli.rb +14 -5
  22. data/lib/inspec/dependencies/dependency_set.rb +38 -0
  23. data/lib/inspec/dependencies/requirement.rb +103 -0
  24. data/lib/inspec/{dependencies.rb → dependencies/resolver.rb} +13 -132
  25. data/lib/inspec/dependencies/vendor_index.rb +98 -0
  26. data/lib/inspec/plugins/source_reader.rb +4 -0
  27. data/lib/inspec/profile.rb +2 -2
  28. data/lib/inspec/resource.rb +2 -0
  29. data/lib/inspec/runner.rb +13 -1
  30. data/lib/inspec/runner_mock.rb +4 -0
  31. data/lib/inspec/runner_rspec.rb +6 -2
  32. data/lib/inspec/shell.rb +22 -1
  33. data/lib/inspec/version.rb +1 -1
  34. data/lib/resources/iis_site.rb +107 -0
  35. data/lib/resources/port.rb +11 -4
  36. data/lib/resources/ssh_conf.rb +10 -2
  37. data/lib/resources/ssl.rb +94 -0
  38. data/lib/resources/xinetd.rb +11 -2
  39. data/lib/utils/parser.rb +6 -1
  40. metadata +17 -561
  41. data/lib/utils/hash_map.rb +0 -37
  42. data/tasks/maintainers.rb +0 -213
  43. data/test/bench/startup/startup.flat.txt +0 -1005
  44. data/test/bench/startup/startup.graph.html +0 -71958
  45. data/test/bench/startup/startup.grind.dat +0 -101602
  46. data/test/bench/startup/startup.stack.html +0 -24516
  47. data/test/bench/startup.flat.txt +0 -998
  48. data/test/bench/startup.graph.html +0 -71420
  49. data/test/bench/startup.grind.dat +0 -103554
  50. data/test/bench/startup.stack.html +0 -25015
  51. data/test/cookbooks/os_prepare/attributes/default.rb +0 -2
  52. data/test/cookbooks/os_prepare/files/empty.iso +0 -0
  53. data/test/cookbooks/os_prepare/files/example.csv +0 -7
  54. data/test/cookbooks/os_prepare/files/example.ini +0 -6
  55. data/test/cookbooks/os_prepare/files/example.json +0 -12
  56. data/test/cookbooks/os_prepare/files/example.yml +0 -7
  57. data/test/cookbooks/os_prepare/metadata.rb +0 -13
  58. data/test/cookbooks/os_prepare/recipes/_runit_service_centos.rb +0 -34
  59. data/test/cookbooks/os_prepare/recipes/_upstart_service_centos.rb +0 -25
  60. data/test/cookbooks/os_prepare/recipes/apache.rb +0 -14
  61. data/test/cookbooks/os_prepare/recipes/apt.rb +0 -20
  62. data/test/cookbooks/os_prepare/recipes/auditctl.rb +0 -8
  63. data/test/cookbooks/os_prepare/recipes/default.rb +0 -29
  64. data/test/cookbooks/os_prepare/recipes/file.rb +0 -46
  65. data/test/cookbooks/os_prepare/recipes/iptables.rb +0 -13
  66. data/test/cookbooks/os_prepare/recipes/json_yaml_csv_ini.rb +0 -34
  67. data/test/cookbooks/os_prepare/recipes/mount.rb +0 -33
  68. data/test/cookbooks/os_prepare/recipes/package.rb +0 -25
  69. data/test/cookbooks/os_prepare/recipes/postgres.rb +0 -20
  70. data/test/cookbooks/os_prepare/recipes/prep_container.rb +0 -15
  71. data/test/cookbooks/os_prepare/recipes/registry_key.rb +0 -87
  72. data/test/cookbooks/os_prepare/recipes/service.rb +0 -19
  73. data/test/cookbooks/os_prepare/templates/default/sv-default-svlog-run.erb +0 -2
  74. data/test/docker_run.rb +0 -162
  75. data/test/docker_test.rb +0 -58
  76. data/test/functional/helper.rb +0 -37
  77. data/test/functional/inheritance_test.rb +0 -62
  78. data/test/functional/inspec_archive_test.rb +0 -80
  79. data/test/functional/inspec_compliance_test.rb +0 -61
  80. data/test/functional/inspec_exec_json_test.rb +0 -122
  81. data/test/functional/inspec_exec_jsonmin_test.rb +0 -59
  82. data/test/functional/inspec_exec_test.rb +0 -123
  83. data/test/functional/inspec_json_profile_test.rb +0 -103
  84. data/test/functional/inspec_test.rb +0 -91
  85. data/test/helper.rb +0 -329
  86. data/test/integration/default/_debug_spec.rb +0 -8
  87. data/test/integration/default/apache_conf_spec.rb +0 -21
  88. data/test/integration/default/apt_spec.rb +0 -37
  89. data/test/integration/default/auditd_rules_spec.rb +0 -32
  90. data/test/integration/default/cmp_matcher_spec.rb +0 -115
  91. data/test/integration/default/csv_spec.rb +0 -11
  92. data/test/integration/default/etc_group_spec.rb +0 -29
  93. data/test/integration/default/file_spec.rb +0 -195
  94. data/test/integration/default/group_spec.rb +0 -59
  95. data/test/integration/default/ini_spec.rb +0 -11
  96. data/test/integration/default/iptables_spec.rb +0 -29
  97. data/test/integration/default/json_spec.rb +0 -11
  98. data/test/integration/default/kernel_module_spec.rb +0 -23
  99. data/test/integration/default/kernel_parameter_spec.rb +0 -60
  100. data/test/integration/default/mount_spec.rb +0 -19
  101. data/test/integration/default/os_spec.rb +0 -13
  102. data/test/integration/default/package_spec.rb +0 -30
  103. data/test/integration/default/port_spec.rb +0 -27
  104. data/test/integration/default/postgres_session_spec.rb +0 -13
  105. data/test/integration/default/powershell_spec.rb +0 -42
  106. data/test/integration/default/registry_key_spec.rb +0 -109
  107. data/test/integration/default/secpol_spec.rb +0 -11
  108. data/test/integration/default/service_spec.rb +0 -128
  109. data/test/integration/default/user_spec.rb +0 -96
  110. data/test/integration/default/vbscript_spec.rb +0 -22
  111. data/test/integration/default/wmi_spec.rb +0 -66
  112. data/test/integration/default/yaml_spec.rb +0 -11
  113. data/test/resource/command_test.rb +0 -33
  114. data/test/resource/dsl_test.rb +0 -45
  115. data/test/resource/file_test.rb +0 -146
  116. data/test/resource/ssh_config.rb +0 -9
  117. data/test/resource/sshd_config.rb +0 -9
  118. data/test/test-extra.yaml +0 -11
  119. data/test/test.yaml +0 -11
  120. data/test/unit/control_test.rb +0 -58
  121. data/test/unit/fetchers/local_test.rb +0 -67
  122. data/test/unit/fetchers/mock_test.rb +0 -43
  123. data/test/unit/fetchers/tar_test.rb +0 -36
  124. data/test/unit/fetchers/url_test.rb +0 -152
  125. data/test/unit/fetchers/zip_test.rb +0 -36
  126. data/test/unit/fetchers_test.rb +0 -65
  127. data/test/unit/metadata_test.rb +0 -137
  128. data/test/unit/mock/cmd/$env-PATH +0 -1
  129. data/test/unit/mock/cmd/Get-NetAdapter +0 -24
  130. data/test/unit/mock/cmd/GetUserAccount +0 -33
  131. data/test/unit/mock/cmd/GetWin32Group +0 -23
  132. data/test/unit/mock/cmd/Resolve-DnsName +0 -26
  133. data/test/unit/mock/cmd/Test-NetConnection +0 -4
  134. data/test/unit/mock/cmd/auditctl +0 -3
  135. data/test/unit/mock/cmd/auditctl-legacy +0 -7
  136. data/test/unit/mock/cmd/auditctl-s +0 -8
  137. data/test/unit/mock/cmd/auditpol +0 -2
  138. data/test/unit/mock/cmd/brew-info-jq +0 -1
  139. data/test/unit/mock/cmd/chage-l-root +0 -7
  140. data/test/unit/mock/cmd/dpkg-s-curl +0 -21
  141. data/test/unit/mock/cmd/dscl +0 -5
  142. data/test/unit/mock/cmd/env +0 -1
  143. data/test/unit/mock/cmd/etc-apt +0 -7
  144. data/test/unit/mock/cmd/find-apache2-conf-enabled +0 -1
  145. data/test/unit/mock/cmd/find-apache2-ports-conf +0 -1
  146. data/test/unit/mock/cmd/find-etc-rc-d-name-S +0 -12
  147. data/test/unit/mock/cmd/find-net-interface +0 -9
  148. data/test/unit/mock/cmd/find-xinetd.d +0 -2
  149. data/test/unit/mock/cmd/gem-list-local-a-q-rubocop +0 -1
  150. data/test/unit/mock/cmd/get-net-tcpconnection +0 -24
  151. data/test/unit/mock/cmd/get-netadapter-binding-bridge +0 -4
  152. data/test/unit/mock/cmd/get-package-firefox +0 -30
  153. data/test/unit/mock/cmd/get-package-ruby +0 -18
  154. data/test/unit/mock/cmd/get-service-dhcp +0 -10
  155. data/test/unit/mock/cmd/get-windows-feature +0 -7
  156. data/test/unit/mock/cmd/get-wmiobject +0 -9
  157. data/test/unit/mock/cmd/getent-hosts-example.com +0 -1
  158. data/test/unit/mock/cmd/getent-passwd-jfolmer +0 -1
  159. data/test/unit/mock/cmd/getent-passwd-root +0 -1
  160. data/test/unit/mock/cmd/hpux-netstat-inet +0 -10
  161. data/test/unit/mock/cmd/hpux-netstat-inet6 +0 -11
  162. data/test/unit/mock/cmd/id-chartmann +0 -1
  163. data/test/unit/mock/cmd/id-jfolmer +0 -1
  164. data/test/unit/mock/cmd/id-root +0 -1
  165. data/test/unit/mock/cmd/initctl--version +0 -5
  166. data/test/unit/mock/cmd/initctl-show-config-ssh +0 -3
  167. data/test/unit/mock/cmd/initctl-status-ssh +0 -1
  168. data/test/unit/mock/cmd/iptables-s +0 -6
  169. data/test/unit/mock/cmd/launchctl-list +0 -3
  170. data/test/unit/mock/cmd/logins-x +0 -4
  171. data/test/unit/mock/cmd/ls-1-etc-init.d +0 -2
  172. data/test/unit/mock/cmd/ls-sys-class-net-br +0 -2
  173. data/test/unit/mock/cmd/lsmod +0 -2
  174. data/test/unit/mock/cmd/lsof-nP-i-FpctPn +0 -63
  175. data/test/unit/mock/cmd/mount +0 -1
  176. data/test/unit/mock/cmd/mount-multiple +0 -2
  177. data/test/unit/mock/cmd/netstat-an.utf8 +0 -13
  178. data/test/unit/mock/cmd/netstat-tulpen +0 -6
  179. data/test/unit/mock/cmd/npm-ls-g--json-bower +0 -9
  180. data/test/unit/mock/cmd/pacman-qi-curl +0 -21
  181. data/test/unit/mock/cmd/ping-example.com +0 -6
  182. data/test/unit/mock/cmd/pip-show-jinja2 +0 -11
  183. data/test/unit/mock/cmd/pkg-info-system-file-system-zfs +0 -8
  184. data/test/unit/mock/cmd/pkginfo-l-SUNWzfsr +0 -7
  185. data/test/unit/mock/cmd/ps-aux +0 -5
  186. data/test/unit/mock/cmd/ps-auxZ +0 -3
  187. data/test/unit/mock/cmd/pw-usershow-root-7 +0 -1
  188. data/test/unit/mock/cmd/reg_schedule +0 -6
  189. data/test/unit/mock/cmd/rpm-qia-curl +0 -24
  190. data/test/unit/mock/cmd/s11-netstat-an-finet-finet6 +0 -32
  191. data/test/unit/mock/cmd/sbin_sysctl +0 -1
  192. data/test/unit/mock/cmd/secedit-export +0 -7
  193. data/test/unit/mock/cmd/service-e +0 -2
  194. data/test/unit/mock/cmd/service-sendmail-onestatus +0 -3
  195. data/test/unit/mock/cmd/service-sshd-status +0 -1
  196. data/test/unit/mock/cmd/sockstat +0 -5
  197. data/test/unit/mock/cmd/success +0 -0
  198. data/test/unit/mock/cmd/swlist-l-product +0 -1
  199. data/test/unit/mock/cmd/systemctl-show-all-dbus +0 -6
  200. data/test/unit/mock/cmd/systemctl-show-all-sshd +0 -7
  201. data/test/unit/mock/cmd/win32_product +0 -8
  202. data/test/unit/mock/cmd/yum-repolist-all +0 -52
  203. data/test/unit/mock/files/apache2.conf +0 -14
  204. data/test/unit/mock/files/auditd.conf +0 -4
  205. data/test/unit/mock/files/bond0 +0 -37
  206. data/test/unit/mock/files/etcgroup +0 -3
  207. data/test/unit/mock/files/example.csv +0 -6
  208. data/test/unit/mock/files/grub.conf +0 -21
  209. data/test/unit/mock/files/inetd.conf +0 -2
  210. data/test/unit/mock/files/kitchen.yml +0 -7
  211. data/test/unit/mock/files/limits.conf +0 -5
  212. data/test/unit/mock/files/login.defs +0 -5
  213. data/test/unit/mock/files/mysql.conf +0 -8
  214. data/test/unit/mock/files/mysql2.conf +0 -2
  215. data/test/unit/mock/files/ntp.conf +0 -5
  216. data/test/unit/mock/files/passwd +0 -2
  217. data/test/unit/mock/files/policyfile.lock.json +0 -12
  218. data/test/unit/mock/files/ports.conf +0 -6
  219. data/test/unit/mock/files/rootwrap.conf +0 -7
  220. data/test/unit/mock/files/serve-cgi-bin.conf +0 -20
  221. data/test/unit/mock/files/shadow +0 -2
  222. data/test/unit/mock/files/ssh_config +0 -5
  223. data/test/unit/mock/files/sshd_config +0 -7
  224. data/test/unit/mock/files/sysctl.conf +0 -7
  225. data/test/unit/mock/files/xinetd.conf +0 -9
  226. data/test/unit/mock/files/xinetd.d/.gitkeep +0 -0
  227. data/test/unit/mock/files/xinetd.d_chargen-dgram +0 -9
  228. data/test/unit/mock/files/xinetd.d_chargen-stream +0 -9
  229. data/test/unit/mock/profiles/complete-metadata/inspec.yml +0 -7
  230. data/test/unit/mock/profiles/complete-profile/controls/filesystem_spec.rb +0 -16
  231. data/test/unit/mock/profiles/complete-profile/inspec.yml +0 -10
  232. data/test/unit/mock/profiles/complete-profile/libraries/testlib.rb +0 -1
  233. data/test/unit/mock/profiles/empty-metadata/inspec.yml +0 -0
  234. data/test/unit/mock/profiles/legacy-complete-metadata/metadata.rb +0 -7
  235. data/test/unit/mock/profiles/legacy-complete-metadata/test/.gitkeep +0 -0
  236. data/test/unit/mock/profiles/legacy-empty-metadata/controls/.gitkeep +0 -0
  237. data/test/unit/mock/profiles/legacy-empty-metadata/metadata.rb +0 -0
  238. data/test/unit/mock/profiles/legacy-simple-metadata/metadata.rb +0 -1
  239. data/test/unit/mock/profiles/legacy-simple-metadata/test/.gitkeep +0 -0
  240. data/test/unit/mock/profiles/library/controls/filesystem_spec.rb +0 -7
  241. data/test/unit/mock/profiles/library/inspec.yml +0 -10
  242. data/test/unit/mock/profiles/library/libraries/gordonlib.rb +0 -2
  243. data/test/unit/mock/profiles/library/libraries/testlib.rb +0 -12
  244. data/test/unit/mock/profiles/resource-tiny/inspec.yml +0 -10
  245. data/test/unit/mock/profiles/resource-tiny/libraries/resource.rb +0 -3
  246. data/test/unit/mock/profiles/simple-metadata/inspec.yml +0 -1
  247. data/test/unit/mock/profiles/skippy-profile-os/controls/one.rb +0 -3
  248. data/test/unit/mock/profiles/skippy-profile-os/inspec.yml +0 -5
  249. data/test/unit/mock/profiles/spec_only/specfile.rb +0 -11
  250. data/test/unit/mock/profiles/supported_inspec/inspec.yml +0 -2
  251. data/test/unit/mock/profiles/unsupported_inspec/inspec.yml +0 -2
  252. data/test/unit/objects_test.rb +0 -65
  253. data/test/unit/plugin_test.rb +0 -44
  254. data/test/unit/plugins/resource_test.rb +0 -60
  255. data/test/unit/profile_context_test.rb +0 -345
  256. data/test/unit/profile_test.rb +0 -252
  257. data/test/unit/resources/apache_conf_test.rb +0 -31
  258. data/test/unit/resources/apt_test.rb +0 -46
  259. data/test/unit/resources/audit_policy_test.rb +0 -13
  260. data/test/unit/resources/auditd_conf_test.rb +0 -15
  261. data/test/unit/resources/auditd_rules_test.rb +0 -91
  262. data/test/unit/resources/bash_test.rb +0 -29
  263. data/test/unit/resources/bond_test.rb +0 -24
  264. data/test/unit/resources/bridge_test.rb +0 -56
  265. data/test/unit/resources/csv_test.rb +0 -35
  266. data/test/unit/resources/etc_group_test.rb +0 -37
  267. data/test/unit/resources/file_test.rb +0 -202
  268. data/test/unit/resources/gem_test.rb +0 -20
  269. data/test/unit/resources/group_test.rb +0 -96
  270. data/test/unit/resources/grub_conf_test.rb +0 -29
  271. data/test/unit/resources/host_test.rb +0 -38
  272. data/test/unit/resources/inetd_conf_test.rb +0 -15
  273. data/test/unit/resources/ini_test.rb +0 -16
  274. data/test/unit/resources/interface_test.rb +0 -54
  275. data/test/unit/resources/iptables_test.rb +0 -35
  276. data/test/unit/resources/json_test.rb +0 -36
  277. data/test/unit/resources/kernel_module_test.rb +0 -23
  278. data/test/unit/resources/kernel_parameter_test.rb +0 -13
  279. data/test/unit/resources/limits_conf_test.rb +0 -14
  280. data/test/unit/resources/login_def_test.rb +0 -16
  281. data/test/unit/resources/mount_test.rb +0 -26
  282. data/test/unit/resources/mysql_conf_test.rb +0 -14
  283. data/test/unit/resources/npm_test.rb +0 -20
  284. data/test/unit/resources/ntp_conf_test.rb +0 -16
  285. data/test/unit/resources/oneget_test.rb +0 -45
  286. data/test/unit/resources/os_env_test.rb +0 -18
  287. data/test/unit/resources/os_test.rb +0 -40
  288. data/test/unit/resources/package_test.rb +0 -87
  289. data/test/unit/resources/parse_config_test.rb +0 -26
  290. data/test/unit/resources/passwd_test.rb +0 -111
  291. data/test/unit/resources/pip_test.rb +0 -15
  292. data/test/unit/resources/port_test.rb +0 -165
  293. data/test/unit/resources/powershell_test.rb +0 -32
  294. data/test/unit/resources/processes_test.rb +0 -72
  295. data/test/unit/resources/registry_key_test.rb +0 -18
  296. data/test/unit/resources/security_policy_test.rb +0 -16
  297. data/test/unit/resources/service_test.rb +0 -305
  298. data/test/unit/resources/shadow_test.rb +0 -67
  299. data/test/unit/resources/ssh_conf_test.rb +0 -33
  300. data/test/unit/resources/user_test.rb +0 -124
  301. data/test/unit/resources/vbscript_test.rb +0 -18
  302. data/test/unit/resources/windows_feature.rb +0 -17
  303. data/test/unit/resources/wmi_test.rb +0 -42
  304. data/test/unit/resources/xinetd_test.rb +0 -60
  305. data/test/unit/resources/yaml_test.rb +0 -34
  306. data/test/unit/resources/yum_test.rb +0 -68
  307. data/test/unit/shell_detector_test.rb +0 -78
  308. data/test/unit/source_reader_test.rb +0 -17
  309. data/test/unit/source_readers/flat_test.rb +0 -61
  310. data/test/unit/source_readers/inspec_test.rb +0 -38
  311. data/test/unit/utils/filter_array_test.rb +0 -59
  312. data/test/unit/utils/filter_table_test.rb +0 -177
  313. data/test/unit/utils/find_files_test.rb +0 -23
  314. data/test/unit/utils/passwd_parser_test.rb +0 -32
  315. data/test/unit/utils/simpleconfig_test.rb +0 -80
  316. data/test/unit/utils/solaris_netstat_parser.rb +0 -124
@@ -1,13 +1,17 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  # options
4
- inspec_bin = '/opt/chef-compliance/embedded/bin/inspec'
4
+ inspec_bin = 'BUNDLE_GEMFILE=/inspec/Gemfile bundle exec inspec'
5
5
  api_url = 'https://0.0.0.0'
6
6
  profile = '/inspec/examples/profile'
7
7
 
8
+ user = command('whoami').stdout.strip
9
+ pwd = command('pwd').stdout.strip
10
+ puts "Run test as #{user} in path #{pwd}"
11
+
8
12
  # TODO: determine tokens automatically, define in kitchen yml
9
- access_token = ENV['COMPLIANCE_ACCESS_TOKEN']
10
- refresh_token = ENV['COMPLIANCE_REFRESH_TOKEN']
13
+ access_token = ENV['COMPLIANCE_ACCESSTOKEN']
14
+ refresh_token = ENV['COMPLIANCE_REFRESHTOKEN']
11
15
 
12
16
  %w{refresh_token access_token}.each do |type|
13
17
  case type
@@ -24,9 +28,35 @@ refresh_token = ENV['COMPLIANCE_REFRESH_TOKEN']
24
28
  its('exit_status') { should eq 0 }
25
29
  end
26
30
 
31
+ # version command fails gracefully when server not configured
32
+ describe command("#{inspec_bin} compliance version") do
33
+ its('stdout') { should include 'Server configuration information is missing' }
34
+ its('stderr') { should eq '' }
35
+ its('exit_status') { should eq 1 }
36
+ end
37
+
38
+ # submitting a wrong token should have an exit of 0
39
+ describe command("#{inspec_bin} compliance login #{api_url} --insecure --user 'admin' --token 'wrong-token'") do
40
+ its('stdout') { should include 'token stored' }
41
+ end
42
+
43
+ # compliance login --help should give an accurate message for login
44
+ describe command("#{inspec_bin} compliance login --help") do
45
+ its('stdout') { should include "inspec compliance login SERVER --insecure --user='USER' --token='TOKEN'" }
46
+ its('exit_status') { should eq 0 }
47
+ end
48
+
49
+ # profiles command fails gracefully when token/server info is incorrect
50
+ describe command("#{inspec_bin} compliance profiles") do
51
+ its('stdout') { should include '401 Unauthorized. Please check your token' }
52
+ its('stderr') { should eq '' }
53
+ its('exit_status') { should eq 1 }
54
+ end
55
+
27
56
  # login via access token token
28
- describe command("#{inspec_bin} compliance login #{api_url} --insecure --user admin #{token_options}") do
29
- its('stdout') { should include 'Successfully authenticated' }
57
+ describe command("#{inspec_bin} compliance login #{api_url} --insecure --user 'admin' #{token_options}") do
58
+ its('stdout') { should include 'token', 'stored' }
59
+ its('stdout') { should_not include 'Your server supports --user and --password only' }
30
60
  its('stderr') { should eq '' }
31
61
  its('exit_status') { should eq 0 }
32
62
  end
@@ -47,6 +77,13 @@ refresh_token = ENV['COMPLIANCE_REFRESH_TOKEN']
47
77
  its('exit_status') { should eq 0 }
48
78
  end
49
79
 
80
+ # returns the version of the server
81
+ describe command("#{inspec_bin} compliance version") do
82
+ its('stdout') { should include 'Chef Compliance version:' }
83
+ its('stderr') { should eq '' }
84
+ its('exit_status') { should eq 0 }
85
+ end
86
+
50
87
  # logout
51
88
  describe command("#{inspec_bin} compliance logout") do
52
89
  its('stdout') { should include 'Successfully logged out' }
@@ -7,6 +7,15 @@ module Init
7
7
  class CLI < Inspec::BaseCLI
8
8
  namespace 'init'
9
9
 
10
+ # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
11
+ def self.banner(command, _namespace = nil, _subcommand = false)
12
+ "#{basename} #{subcommand_prefix} #{command.usage}"
13
+ end
14
+
15
+ def self.subcommand_prefix
16
+ namespace
17
+ end
18
+
10
19
  # read template directoy
11
20
  template_dir = File.join(File.dirname(__FILE__), 'templates')
12
21
  Dir.glob(File.join(template_dir, '*')) do |template|
@@ -6,6 +6,15 @@ module Supermarket
6
6
  class SupermarketCLI < Inspec::BaseCLI
7
7
  namespace 'supermarket'
8
8
 
9
+ # TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
10
+ def self.banner(command, _namespace = nil, _subcommand = false)
11
+ "#{basename} #{subcommand_prefix} #{command.usage}"
12
+ end
13
+
14
+ def self.subcommand_prefix
15
+ namespace
16
+ end
17
+
9
18
  desc 'profiles', 'list all available profiles in Chef Supermarket'
10
19
  def profiles
11
20
  # display profiles in format user/profile
@@ -13,11 +13,12 @@ module Supermarket
13
13
  priority 500
14
14
 
15
15
  def self.resolve(target, opts = {})
16
+ return nil unless target.is_a?(String)
16
17
  return nil unless URI(target).scheme == 'supermarket'
17
18
  return nil unless Supermarket::API.exist?(target)
18
19
  tool_info = Supermarket::API.find(target)
19
20
  super(tool_info['tool_source_url'], opts)
20
- rescue URI::Error => _e
21
+ rescue URI::Error
21
22
  nil
22
23
  end
23
24
 
@@ -10,8 +10,11 @@ module Fetchers
10
10
  attr_reader :files
11
11
 
12
12
  def self.resolve(target)
13
- return nil unless File.exist?(target)
14
- new(target)
13
+ unless target.is_a?(String) && File.exist?(target)
14
+ nil
15
+ else
16
+ new(target)
17
+ end
15
18
  end
16
19
 
17
20
  def initialize(target)
data/lib/fetchers/url.rb CHANGED
@@ -14,6 +14,7 @@ module Fetchers
14
14
  attr_reader :files
15
15
 
16
16
  def self.resolve(target, opts = {})
17
+ return nil unless target.is_a?(String)
17
18
  uri = URI.parse(target)
18
19
  return nil if uri.nil? or uri.scheme.nil?
19
20
  return nil unless %{ http https }.include? uri.scheme
@@ -64,7 +64,8 @@ module Inspec
64
64
  # helper method to run tests
65
65
  def run_tests(targets, opts)
66
66
  o = opts.dup
67
- o[:logger] = Logger.new(opts['format'] == 'json' ? nil : STDOUT)
67
+ log_device = opts['format'] == 'json' ? nil : STDOUT
68
+ o[:logger] = Logger.new(log_device)
68
69
  o[:logger].level = get_log_level(o.log_level)
69
70
 
70
71
  runner = Inspec::Runner.new(o)
data/lib/inspec/cli.rb CHANGED
@@ -154,20 +154,29 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
154
154
 
155
155
  desc 'shell', 'open an interactive debugging shell'
156
156
  target_options
157
- option :command, aliases: :c
158
- option :format, type: :string, default: nil, hide: true
157
+ option :command, aliases: :c,
158
+ desc: 'A single command string to run instead of launching the shell'
159
+ option :format, type: :string, default: nil, hide: true,
160
+ desc: 'Which formatter to use: cli, progress, documentation, json, json-min'
159
161
  def shell_func
160
162
  diagnose
161
163
  o = opts.dup
162
- o[:logger] = Logger.new(STDOUT)
164
+
165
+ log_device = opts['format'] == 'json' ? nil : STDOUT
166
+ o[:logger] = Logger.new(log_device)
163
167
  o[:logger].level = get_log_level(o.log_level)
168
+
164
169
  if o[:command].nil?
165
170
  runner = Inspec::Runner.new(o)
166
171
  return Inspec::Shell.new(runner).start
167
172
  else
168
173
  res = run_command(o)
169
- jres = res.respond_to?(:to_json) ? res.to_json : JSON.dump(res)
170
- puts jres
174
+ if opts['format'] == 'json'
175
+ jres = res.respond_to?(:to_json) ? res.to_json : JSON.dump(res)
176
+ puts jres
177
+ else
178
+ puts res
179
+ end
171
180
  end
172
181
  rescue RuntimeError, Train::UserError => e
173
182
  $stderr.puts e.message
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ require 'inspec/dependencies/vendor_index'
3
+ require 'inspec/dependencies/resolver'
4
+
5
+ module Inspec
6
+ #
7
+ # A DependencySet manages a list of dependencies for a profile.
8
+ #
9
+ # Currently this class is a thin wrapper interface to coordinate the
10
+ # VendorIndex and the Resolver.
11
+ #
12
+ class DependencySet
13
+ attr_reader :list, :vendor_path
14
+
15
+ # initialize
16
+ #
17
+ # @param cwd [String] current working directory for relative path includes
18
+ # @param vendor_path [String] path which contains vendored dependencies
19
+ # @return [dependencies] this
20
+ def initialize(cwd, vendor_path)
21
+ @cwd = cwd
22
+ @vendor_path = vendor_path || File.join(Dir.home, '.inspec', 'cache')
23
+ @list = nil
24
+ end
25
+
26
+ #
27
+ # 1. Get dependencies, pull things to a local cache if necessary
28
+ # 2. Resolve dependencies
29
+ #
30
+ # @param dependencies [Gem::Dependency] list of dependencies
31
+ # @return [nil]
32
+ def vendor(dependencies)
33
+ return nil if dependencies.nil? || dependencies.empty?
34
+ @vendor_index ||= VendorIndex.new(@vendor_path)
35
+ @list = Resolver.resolve(dependencies, @vendor_index, @cwd)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+ require 'inspec/fetcher'
3
+
4
+ module Inspec
5
+ #
6
+ # Inspec::Requirement represents a given profile dependency, where
7
+ # appropriate we delegate to Inspec::Profile directly.
8
+ #
9
+ class Requirement
10
+ attr_reader :name, :dep, :cwd, :opts
11
+
12
+ def initialize(name, version_constraints, vendor_index, cwd, opts)
13
+ @name = name
14
+ @dep = Gem::Dependency.new(name,
15
+ Gem::Requirement.new(Array(version_constraints)),
16
+ :runtime)
17
+ @vendor_index = vendor_index
18
+ @opts = opts
19
+ @cwd = cwd
20
+ end
21
+
22
+ def matches_spec?(spec)
23
+ params = spec.profile.metadata.params
24
+ @dep.match?(params[:name], params[:version])
25
+ end
26
+
27
+ def source_url
28
+ case source_type
29
+ when :local_path
30
+ "file://#{File.expand_path(opts[:path])}"
31
+ when :url
32
+ @opts[:url]
33
+ end
34
+ end
35
+
36
+ def local_path
37
+ @local_path ||= case source_type
38
+ when :local_path
39
+ File.expand_path(opts[:path], @cwd)
40
+ else
41
+ @vendor_index.prefered_entry_for(@name, source_url)
42
+ end
43
+ end
44
+
45
+ def source_type
46
+ @source_type ||= if @opts[:path]
47
+ :local_path
48
+ elsif opts[:url]
49
+ :url
50
+ else
51
+ fail "Cannot determine source type from #{opts}"
52
+ end
53
+ end
54
+
55
+ def fetcher_class
56
+ @fetcher_class ||= case source_type
57
+ when :local_path
58
+ Fetchers::Local
59
+ when :url
60
+ Fetchers::Url
61
+ else
62
+ fail "No known fetcher for dependency #{name} with source_type #{source_type}"
63
+ end
64
+
65
+ fail "No fetcher for #{name} (options: #{opts})" if @fetcher_class.nil?
66
+ @fetcher_class
67
+ end
68
+
69
+ def pull
70
+ case source_type
71
+ when :local_path
72
+ local_path
73
+ else
74
+ if @vendor_index.exists?(@name, source_url)
75
+ local_path
76
+ else
77
+ archive = fetcher_class.download_archive(source_url)
78
+ @vendor_index.add(@name, source_url, archive.path)
79
+ end
80
+ end
81
+ end
82
+
83
+ def to_s
84
+ dep.to_s
85
+ end
86
+
87
+ def path
88
+ @path ||= pull
89
+ end
90
+
91
+ def profile
92
+ return nil if path.nil?
93
+ @profile ||= Inspec::Profile.for_target(path, {})
94
+ end
95
+
96
+ def self.from_metadata(dep, vendor_index, opts)
97
+ fail 'Cannot load empty dependency.' if dep.nil? || dep.empty?
98
+ name = dep[:name] || fail('You must provide a name for all dependencies')
99
+ version = dep[:version]
100
+ new(name, version, vendor_index, opts[:cwd], opts.merge(dep))
101
+ end
102
+ end
103
+ end
@@ -1,28 +1,32 @@
1
1
  # encoding: utf-8
2
2
  # author: Dominik Richter
3
3
  # author: Christoph Hartmann
4
-
5
4
  require 'logger'
6
- require 'fileutils'
7
5
  require 'molinillo'
8
6
  require 'inspec/errors'
7
+ require 'inspec/dependencies/requirement'
9
8
 
10
9
  module Inspec
10
+ #
11
+ # Inspec::Resolver is responsible for recursively resolving all the
12
+ # depenendencies for a given top-level dependency set.
13
+ #
11
14
  class Resolver
12
15
  def self.resolve(requirements, vendor_index, cwd, opts = {})
13
16
  reqs = requirements.map do |req|
14
- Requirement.from_metadata(req, cwd: cwd) ||
15
- fail("Cannot initialize dependency: #{req}")
17
+ req = Inspec::Requirement.from_metadata(req, vendor_index, cwd: cwd)
18
+ req || fail("Cannot initialize dependency: #{req}")
16
19
  end
17
20
 
18
- new(vendor_index, opts).resolve(reqs)
21
+ new(vendor_index, opts.merge(cwd: cwd)).resolve(reqs)
19
22
  end
20
23
 
21
24
  def initialize(vendor_index, opts = {})
22
25
  @logger = opts[:logger] || Logger.new(nil)
23
- @debug_mode = false # TODO: hardcoded for now, grab from options
26
+ @debug_mode = false
24
27
 
25
28
  @vendor_index = vendor_index
29
+ @cwd = opts[:cwd] || './'
26
30
  @resolver = Molinillo::Resolver.new(self, self)
27
31
  @search_cache = {}
28
32
  end
@@ -87,7 +91,9 @@ module Inspec
87
91
  # @return [Array<Object>] the dependencies that are required by the given
88
92
  # `specification`.
89
93
  def dependencies_for(specification)
90
- specification.profile.metadata.dependencies
94
+ specification.profile.metadata.dependencies.map do |r|
95
+ Inspec::Requirement.from_metadata(r, @vendor_index, cwd: @cwd)
96
+ end
91
97
  end
92
98
 
93
99
  # Determines whether the given `requirement` is satisfied by the given
@@ -179,129 +185,4 @@ module Inspec
179
185
  end
180
186
  alias puts print
181
187
  end
182
-
183
- class Package
184
- def initialize(path, version)
185
- @path = path
186
- @version = version
187
- end
188
- end
189
-
190
- class VendorIndex
191
- attr_reader :list, :path
192
- def initialize(path)
193
- @path = path
194
- FileUtils.mkdir_p(path) unless File.directory?(path)
195
- @list = Dir[File.join(path, '*')].map { |x| load_path(x) }
196
- end
197
-
198
- def find(_dependency)
199
- # TODO
200
- fail NotImplementedError, '#find(dependency) on VendorIndex seeks implementation.'
201
- end
202
-
203
- private
204
-
205
- def load_path(_path)
206
- # TODO
207
- fail NotImplementedError, '#load_path(path) on VendorIndex wants to be implemented.'
208
- end
209
- end
210
-
211
- class Requirement
212
- attr_reader :name, :dep, :cwd, :opts
213
- def initialize(name, dep, cwd, opts)
214
- @name = name
215
- @dep = Gem::Dependency.new(name, Gem::Requirement.new(Array(dep)), :runtime)
216
- @opts = opts
217
- @cwd = cwd
218
- end
219
-
220
- def matches_spec?(spec)
221
- params = spec.profile.metadata.params
222
- @dep.match?(params[:name], params[:version])
223
- end
224
-
225
- def pull
226
- case
227
- when @opts[:path] then pull_path(@opts[:path])
228
- else
229
- # TODO: should default to supermarket
230
- fail 'You must specify the source of the dependency (for now...)'
231
- end
232
- end
233
-
234
- def path
235
- @path || pull
236
- end
237
-
238
- def profile
239
- return nil if path.nil?
240
- @profile ||= Inspec::Profile.for_target(path, {})
241
- end
242
-
243
- def self.from_metadata(dep, opts)
244
- fail 'Cannot load empty dependency.' if dep.nil? || dep.empty?
245
- name = dep[:name] || fail('You must provide a name for all dependencies')
246
- version = dep[:version]
247
- new(name, version, opts[:cwd], dep)
248
- end
249
-
250
- def to_s
251
- @dep.to_s
252
- end
253
-
254
- private
255
-
256
- def pull_path(path)
257
- abspath = File.absolute_path(path, @cwd)
258
- fail "Dependency path doesn't exist: #{path}" unless File.exist?(abspath)
259
- fail "Dependency path isn't a folder: #{path}" unless File.directory?(abspath)
260
- @path = abspath
261
- true
262
- end
263
- end
264
-
265
- class SupermarketDependency
266
- def initialize(url, requirement)
267
- @url = url
268
- @requirement = requirement
269
- end
270
-
271
- def self.load(dep)
272
- return nil if dep.nil?
273
- sname = dep[:supermarket]
274
- return nil if sname.nil?
275
- surl = dep[:supermarket_url] || 'default_url...'
276
- requirement = dep[:version]
277
- url = surl + '/' + sname
278
- new(url, requirement)
279
- end
280
- end
281
-
282
- class Dependencies
283
- attr_reader :list, :vendor_path
284
-
285
- # initialize
286
- #
287
- # @param cwd [String] current working directory for relative path includes
288
- # @param vendor_path [String] path which contains vendored dependencies
289
- # @return [dependencies] this
290
- def initialize(cwd, vendor_path)
291
- @cwd = cwd
292
- @vendor_path = vendor_path || File.join(Dir.home, '.inspec', 'cache')
293
- @list = nil
294
- end
295
-
296
- # 1. Get dependencies, pull things to a local cache if necessary
297
- # 2. Resolve dependencies
298
- #
299
- # @param dependencies [Gem::Dependency] list of dependencies
300
- # @return [nil]
301
- def vendor(dependencies)
302
- return if dependencies.nil? || dependencies.empty?
303
- @vendor_index ||= VendorIndex.new(@vendor_path)
304
- @list = Resolver.resolve(dependencies, @vendor_index, @cwd)
305
- end
306
- end
307
188
  end
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+ require 'digest'
3
+ require 'fileutils'
4
+
5
+ module Inspec
6
+ #
7
+ # VendorIndex manages an on-disk cache of inspec profiles. The
8
+ # cache can contain:
9
+ #
10
+ # - .tar.gz profile archives
11
+ # - .zip profile archives
12
+ # - unpacked profiles
13
+ #
14
+ # Cache entries names include a hash of their source to prevent
15
+ # conflicts between depenedencies with the same name from different
16
+ # sources.
17
+ #
18
+ #
19
+ class VendorIndex
20
+ attr_reader :path
21
+ def initialize(path)
22
+ @path = path
23
+ FileUtils.mkdir_p(path) unless File.directory?(path)
24
+ end
25
+
26
+ def add(name, source, path_from)
27
+ path_to = base_path_for(name, source)
28
+ path_to = if File.directory?(path_to)
29
+ path_to
30
+ elsif path_from.end_with?('.zip')
31
+ "#{path_to}.tar.gz"
32
+ elsif path_from.end_with?('.tar.gz')
33
+ "#{path_to}.tar.gz"
34
+ else
35
+ fail "Cannot add unknown archive #{path} to vendor index"
36
+ end
37
+ FileUtils.cp_r(path_from, path_to)
38
+ path_to
39
+ end
40
+
41
+ def prefered_entry_for(name, source_url)
42
+ path = base_path_for(name, source_url)
43
+ if File.directory?(path)
44
+ path
45
+ elsif File.exist?("#{path}.tar.gz")
46
+ "#{path}.tar.gz"
47
+ elsif File.exist?("#{path}.zip")
48
+ "#{path}.zip"
49
+ end
50
+ end
51
+
52
+ #
53
+ # For a given name and source_url, return true if the
54
+ # profile exists in the VendorIndex.
55
+ #
56
+ # @param [String] name
57
+ # @param [String] source_url
58
+ # @return [Boolean]
59
+ #
60
+ def exists?(name, source_url)
61
+ path = base_path_for(name, source_url)
62
+ File.directory?(path) || File.exist?("#{path}.tar.gz") || File.exist?("#{path}.zip")
63
+ end
64
+
65
+ #
66
+ # Return the path to given profile in the vendor index.
67
+ #
68
+ # The `source_url` parameter should be a URI-like string that
69
+ # fully specifies the source of the exact version we want to pull
70
+ # down.
71
+ #
72
+ # @param [String] name
73
+ # @param [String] source_url
74
+ # @return [String]
75
+ #
76
+ def base_path_for(name, source_url)
77
+ File.join(@path, key_for(name, source_url))
78
+ end
79
+
80
+ private
81
+
82
+ #
83
+ # Return the key for a given profile in the vendor index.
84
+ #
85
+ # The `source_url` parameter should be a URI-like string that
86
+ # fully specifies the source of the exact version we want to pull
87
+ # down.
88
+ #
89
+ # @param [String] name
90
+ # @param [String] source_url
91
+ # @return [String]
92
+ #
93
+ def key_for(name, source_url)
94
+ source_hash = Digest::SHA256.hexdigest source_url
95
+ "#{name}-#{source_hash}"
96
+ end
97
+ end
98
+ end
@@ -20,6 +20,10 @@ module Inspec
20
20
 
21
21
  # Retrieve this profile's tests
22
22
  #
23
+ # "tests" here refers to a test file. Individual controls and anonymous
24
+ # tests are later extracted from the raw contents of a test file. The map
25
+ # her simply maps from a test file name to the file contents.
26
+ #
23
27
  # @return [Hash] Collection with references pointing to test contents
24
28
  def tests
25
29
  fail "SourceReader #{self} does not implement `tests()`. This method is required"
@@ -8,7 +8,7 @@ require 'inspec/polyfill'
8
8
  require 'inspec/fetcher'
9
9
  require 'inspec/source_reader'
10
10
  require 'inspec/metadata'
11
- require 'inspec/dependencies'
11
+ require 'inspec/dependencies/dependency_set'
12
12
 
13
13
  module Inspec
14
14
  class Profile # rubocop:disable Metrics/ClassLength
@@ -298,7 +298,7 @@ module Inspec
298
298
 
299
299
  def load_dependencies
300
300
  cwd = File.directory?(@target) ? @target : nil
301
- res = Inspec::Dependencies.new(cwd, nil)
301
+ res = Inspec::DependencySet.new(cwd, nil)
302
302
  res.vendor(metadata.dependencies)
303
303
  res
304
304
  end
@@ -65,6 +65,7 @@ require 'resources/gem'
65
65
  require 'resources/group'
66
66
  require 'resources/grub_conf'
67
67
  require 'resources/host'
68
+ require 'resources/iis_site'
68
69
  require 'resources/inetd_conf'
69
70
  require 'resources/interface'
70
71
  require 'resources/iptables'
@@ -97,6 +98,7 @@ require 'resources/registry_key'
97
98
  require 'resources/security_policy'
98
99
  require 'resources/service'
99
100
  require 'resources/shadow'
101
+ require 'resources/ssl'
100
102
  require 'resources/ssh_conf'
101
103
  require 'resources/user'
102
104
  require 'resources/vbscript'