inspec 0.30.0 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.
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'