inspec 2.1.0 → 2.1.10

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 (489) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +101 -101
  3. data/CHANGELOG.md +3024 -3004
  4. data/Gemfile +55 -55
  5. data/LICENSE +14 -14
  6. data/MAINTAINERS.md +33 -33
  7. data/MAINTAINERS.toml +52 -52
  8. data/README.md +447 -446
  9. data/Rakefile +322 -322
  10. data/bin/inspec +12 -12
  11. data/docs/.gitignore +2 -2
  12. data/docs/README.md +40 -40
  13. data/docs/dsl_inspec.md +258 -258
  14. data/docs/dsl_resource.md +100 -93
  15. data/docs/glossary.md +99 -99
  16. data/docs/habitat.md +191 -191
  17. data/docs/inspec_and_friends.md +114 -114
  18. data/docs/matchers.md +169 -169
  19. data/docs/migration.md +293 -293
  20. data/docs/platforms.md +118 -118
  21. data/docs/plugin_kitchen_inspec.md +50 -50
  22. data/docs/profiles.md +376 -376
  23. data/docs/reporters.md +105 -105
  24. data/docs/resources/aide_conf.md.erb +75 -75
  25. data/docs/resources/apache.md.erb +67 -67
  26. data/docs/resources/apache_conf.md.erb +68 -68
  27. data/docs/resources/apt.md.erb +71 -71
  28. data/docs/resources/audit_policy.md.erb +47 -47
  29. data/docs/resources/auditd.md.erb +79 -79
  30. data/docs/resources/auditd_conf.md.erb +68 -68
  31. data/docs/resources/aws_cloudtrail_trail.md.erb +140 -140
  32. data/docs/resources/aws_cloudtrail_trails.md.erb +81 -81
  33. data/docs/resources/aws_cloudwatch_alarm.md.erb +86 -86
  34. data/docs/resources/aws_cloudwatch_log_metric_filter.md.erb +151 -151
  35. data/docs/resources/aws_config_recorder.md.erb +71 -71
  36. data/docs/resources/aws_ec2_instance.md.erb +106 -106
  37. data/docs/resources/aws_iam_access_key.md.erb +123 -123
  38. data/docs/resources/aws_iam_access_keys.md.erb +198 -198
  39. data/docs/resources/aws_iam_group.md.erb +46 -46
  40. data/docs/resources/aws_iam_groups.md.erb +43 -43
  41. data/docs/resources/aws_iam_password_policy.md.erb +76 -76
  42. data/docs/resources/aws_iam_policies.md.erb +82 -82
  43. data/docs/resources/aws_iam_policy.md.erb +144 -144
  44. data/docs/resources/aws_iam_role.md.erb +63 -63
  45. data/docs/resources/aws_iam_root_user.md.erb +58 -58
  46. data/docs/resources/aws_iam_user.md.erb +64 -64
  47. data/docs/resources/aws_iam_users.md.erb +89 -89
  48. data/docs/resources/aws_kms_keys.md.erb +84 -84
  49. data/docs/resources/aws_route_table.md.erb +47 -47
  50. data/docs/resources/aws_s3_bucket.md.erb +134 -134
  51. data/docs/resources/aws_s3_bucket_object.md.erb +83 -0
  52. data/docs/resources/aws_security_group.md.erb +151 -151
  53. data/docs/resources/aws_security_groups.md.erb +91 -91
  54. data/docs/resources/aws_sns_subscription.md.erb +125 -0
  55. data/docs/resources/aws_sns_topic.md.erb +63 -63
  56. data/docs/resources/aws_sns_topics.md.erb +52 -0
  57. data/docs/resources/aws_subnet.md.erb +134 -134
  58. data/docs/resources/aws_subnets.md.erb +126 -126
  59. data/docs/resources/aws_vpc.md.erb +120 -120
  60. data/docs/resources/aws_vpcs.md.erb +48 -48
  61. data/docs/resources/azure_generic_resource.md.erb +171 -171
  62. data/docs/resources/azure_resource_group.md.erb +284 -284
  63. data/docs/resources/azure_virtual_machine.md.erb +347 -347
  64. data/docs/resources/azure_virtual_machine_data_disk.md.erb +224 -224
  65. data/docs/resources/bash.md.erb +75 -75
  66. data/docs/resources/bond.md.erb +90 -90
  67. data/docs/resources/bridge.md.erb +57 -57
  68. data/docs/resources/bsd_service.md.erb +67 -67
  69. data/docs/resources/command.md.erb +138 -138
  70. data/docs/resources/cpan.md.erb +79 -79
  71. data/docs/resources/cran.md.erb +64 -64
  72. data/docs/resources/crontab.md.erb +89 -89
  73. data/docs/resources/csv.md.erb +54 -54
  74. data/docs/resources/dh_params.md.erb +205 -205
  75. data/docs/resources/directory.md.erb +30 -30
  76. data/docs/resources/docker.md.erb +219 -219
  77. data/docs/resources/docker_container.md.erb +103 -103
  78. data/docs/resources/docker_image.md.erb +94 -94
  79. data/docs/resources/docker_service.md.erb +114 -114
  80. data/docs/resources/elasticsearch.md.erb +242 -242
  81. data/docs/resources/etc_fstab.md.erb +125 -125
  82. data/docs/resources/etc_group.md.erb +75 -75
  83. data/docs/resources/etc_hosts.md.erb +78 -78
  84. data/docs/resources/etc_hosts_allow.md.erb +74 -74
  85. data/docs/resources/etc_hosts_deny.md.erb +74 -74
  86. data/docs/resources/file.md.erb +526 -526
  87. data/docs/resources/filesystem.md.erb +41 -41
  88. data/docs/resources/firewalld.md.erb +107 -107
  89. data/docs/resources/gem.md.erb +79 -79
  90. data/docs/resources/group.md.erb +61 -61
  91. data/docs/resources/grub_conf.md.erb +101 -101
  92. data/docs/resources/host.md.erb +86 -86
  93. data/docs/resources/http.md.erb +196 -196
  94. data/docs/resources/iis_app.md.erb +122 -122
  95. data/docs/resources/iis_site.md.erb +135 -135
  96. data/docs/resources/inetd_conf.md.erb +94 -94
  97. data/docs/resources/ini.md.erb +76 -76
  98. data/docs/resources/interface.md.erb +58 -58
  99. data/docs/resources/iptables.md.erb +64 -64
  100. data/docs/resources/json.md.erb +63 -63
  101. data/docs/resources/kernel_module.md.erb +120 -120
  102. data/docs/resources/kernel_parameter.md.erb +53 -53
  103. data/docs/resources/key_rsa.md.erb +85 -85
  104. data/docs/resources/launchd_service.md.erb +57 -57
  105. data/docs/resources/limits_conf.md.erb +75 -75
  106. data/docs/resources/{login_def.md.erb → login_defs.md.erb} +71 -71
  107. data/docs/resources/mount.md.erb +69 -69
  108. data/docs/resources/mssql_session.md.erb +60 -60
  109. data/docs/resources/mysql_conf.md.erb +99 -99
  110. data/docs/resources/mysql_session.md.erb +74 -74
  111. data/docs/resources/nginx.md.erb +79 -79
  112. data/docs/resources/nginx_conf.md.erb +138 -128
  113. data/docs/resources/npm.md.erb +60 -60
  114. data/docs/resources/ntp_conf.md.erb +60 -60
  115. data/docs/resources/oneget.md.erb +53 -53
  116. data/docs/resources/oracledb_session.md.erb +52 -52
  117. data/docs/resources/os.md.erb +141 -141
  118. data/docs/resources/os_env.md.erb +78 -78
  119. data/docs/resources/package.md.erb +120 -120
  120. data/docs/resources/packages.md.erb +67 -67
  121. data/docs/resources/parse_config.md.erb +103 -103
  122. data/docs/resources/parse_config_file.md.erb +138 -138
  123. data/docs/resources/passwd.md.erb +141 -141
  124. data/docs/resources/pip.md.erb +67 -67
  125. data/docs/resources/port.md.erb +137 -137
  126. data/docs/resources/postgres_conf.md.erb +79 -79
  127. data/docs/resources/postgres_hba_conf.md.erb +93 -93
  128. data/docs/resources/postgres_ident_conf.md.erb +76 -76
  129. data/docs/resources/postgres_session.md.erb +69 -69
  130. data/docs/resources/powershell.md.erb +102 -102
  131. data/docs/resources/processes.md.erb +109 -109
  132. data/docs/resources/rabbitmq_config.md.erb +41 -41
  133. data/docs/resources/registry_key.md.erb +158 -158
  134. data/docs/resources/runit_service.md.erb +57 -57
  135. data/docs/resources/security_policy.md.erb +47 -47
  136. data/docs/resources/service.md.erb +121 -121
  137. data/docs/resources/shadow.md.erb +146 -146
  138. data/docs/resources/ssh_config.md.erb +73 -80
  139. data/docs/resources/sshd_config.md.erb +83 -83
  140. data/docs/resources/ssl.md.erb +119 -119
  141. data/docs/resources/sys_info.md.erb +42 -42
  142. data/docs/resources/systemd_service.md.erb +57 -57
  143. data/docs/resources/sysv_service.md.erb +57 -57
  144. data/docs/resources/upstart_service.md.erb +57 -57
  145. data/docs/resources/user.md.erb +140 -140
  146. data/docs/resources/users.md.erb +127 -127
  147. data/docs/resources/vbscript.md.erb +55 -55
  148. data/docs/resources/virtualization.md.erb +57 -57
  149. data/docs/resources/windows_feature.md.erb +47 -47
  150. data/docs/resources/windows_hotfix.md.erb +53 -53
  151. data/docs/resources/windows_task.md.erb +95 -95
  152. data/docs/resources/wmi.md.erb +81 -81
  153. data/docs/resources/x509_certificate.md.erb +151 -151
  154. data/docs/resources/xinetd_conf.md.erb +156 -156
  155. data/docs/resources/xml.md.erb +85 -85
  156. data/docs/resources/yaml.md.erb +69 -69
  157. data/docs/resources/yum.md.erb +98 -98
  158. data/docs/resources/zfs_dataset.md.erb +53 -53
  159. data/docs/resources/zfs_pool.md.erb +47 -47
  160. data/docs/ruby_usage.md +203 -203
  161. data/docs/shared/matcher_be.md.erb +1 -1
  162. data/docs/shared/matcher_cmp.md.erb +43 -43
  163. data/docs/shared/matcher_eq.md.erb +3 -3
  164. data/docs/shared/matcher_include.md.erb +1 -1
  165. data/docs/shared/matcher_match.md.erb +1 -1
  166. data/docs/shell.md +217 -217
  167. data/examples/README.md +8 -8
  168. data/examples/inheritance/README.md +65 -65
  169. data/examples/inheritance/controls/example.rb +14 -14
  170. data/examples/inheritance/inspec.yml +15 -15
  171. data/examples/kitchen-ansible/.kitchen.yml +25 -25
  172. data/examples/kitchen-ansible/Gemfile +19 -19
  173. data/examples/kitchen-ansible/README.md +53 -53
  174. data/examples/kitchen-ansible/files/nginx.repo +6 -6
  175. data/examples/kitchen-ansible/tasks/main.yml +16 -16
  176. data/examples/kitchen-ansible/test/integration/default/default.yml +5 -5
  177. data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -28
  178. data/examples/kitchen-chef/.kitchen.yml +20 -20
  179. data/examples/kitchen-chef/Berksfile +3 -3
  180. data/examples/kitchen-chef/Gemfile +19 -19
  181. data/examples/kitchen-chef/README.md +27 -27
  182. data/examples/kitchen-chef/metadata.rb +7 -7
  183. data/examples/kitchen-chef/recipes/default.rb +6 -6
  184. data/examples/kitchen-chef/recipes/nginx.rb +30 -30
  185. data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -28
  186. data/examples/kitchen-puppet/.kitchen.yml +22 -22
  187. data/examples/kitchen-puppet/Gemfile +20 -20
  188. data/examples/kitchen-puppet/Puppetfile +25 -25
  189. data/examples/kitchen-puppet/README.md +53 -53
  190. data/examples/kitchen-puppet/manifests/site.pp +33 -33
  191. data/examples/kitchen-puppet/metadata.json +11 -11
  192. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
  193. data/examples/meta-profile/README.md +37 -37
  194. data/examples/meta-profile/controls/example.rb +13 -13
  195. data/examples/meta-profile/inspec.yml +13 -13
  196. data/examples/profile-attribute.yml +2 -2
  197. data/examples/profile-attribute/README.md +14 -14
  198. data/examples/profile-attribute/controls/example.rb +11 -11
  199. data/examples/profile-attribute/inspec.yml +8 -8
  200. data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
  201. data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
  202. data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
  203. data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
  204. data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
  205. data/examples/profile-aws/inspec.yml +11 -11
  206. data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
  207. data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
  208. data/examples/profile-azure/inspec.yml +11 -11
  209. data/examples/profile-sensitive/README.md +29 -29
  210. data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
  211. data/examples/profile-sensitive/controls/sensitive.rb +9 -9
  212. data/examples/profile-sensitive/inspec.yml +8 -8
  213. data/examples/profile/README.md +48 -48
  214. data/examples/profile/controls/example.rb +23 -23
  215. data/examples/profile/controls/gordon.rb +36 -36
  216. data/examples/profile/controls/meta.rb +34 -34
  217. data/examples/profile/inspec.yml +10 -10
  218. data/examples/profile/libraries/gordon_config.rb +53 -53
  219. data/inspec.gemspec +47 -47
  220. data/lib/bundles/README.md +3 -3
  221. data/lib/bundles/inspec-artifact.rb +7 -7
  222. data/lib/bundles/inspec-artifact/README.md +1 -1
  223. data/lib/bundles/inspec-artifact/cli.rb +277 -277
  224. data/lib/bundles/inspec-compliance.rb +16 -16
  225. data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
  226. data/lib/bundles/inspec-compliance/README.md +185 -185
  227. data/lib/bundles/inspec-compliance/api.rb +316 -316
  228. data/lib/bundles/inspec-compliance/api/login.rb +152 -152
  229. data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
  230. data/lib/bundles/inspec-compliance/cli.rb +254 -254
  231. data/lib/bundles/inspec-compliance/configuration.rb +103 -103
  232. data/lib/bundles/inspec-compliance/http.rb +86 -86
  233. data/lib/bundles/inspec-compliance/support.rb +36 -36
  234. data/lib/bundles/inspec-compliance/target.rb +98 -98
  235. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
  236. data/lib/bundles/inspec-habitat.rb +12 -12
  237. data/lib/bundles/inspec-habitat/cli.rb +36 -36
  238. data/lib/bundles/inspec-habitat/log.rb +10 -10
  239. data/lib/bundles/inspec-habitat/profile.rb +390 -390
  240. data/lib/bundles/inspec-init.rb +8 -8
  241. data/lib/bundles/inspec-init/README.md +31 -31
  242. data/lib/bundles/inspec-init/cli.rb +97 -97
  243. data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
  244. data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
  245. data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
  246. data/lib/bundles/inspec-supermarket.rb +13 -13
  247. data/lib/bundles/inspec-supermarket/README.md +45 -45
  248. data/lib/bundles/inspec-supermarket/api.rb +84 -84
  249. data/lib/bundles/inspec-supermarket/cli.rb +73 -73
  250. data/lib/bundles/inspec-supermarket/target.rb +34 -34
  251. data/lib/fetchers/git.rb +163 -163
  252. data/lib/fetchers/local.rb +74 -74
  253. data/lib/fetchers/mock.rb +35 -35
  254. data/lib/fetchers/url.rb +204 -204
  255. data/lib/inspec.rb +24 -24
  256. data/lib/inspec/archive/tar.rb +29 -29
  257. data/lib/inspec/archive/zip.rb +19 -19
  258. data/lib/inspec/backend.rb +93 -93
  259. data/lib/inspec/base_cli.rb +357 -355
  260. data/lib/inspec/cached_fetcher.rb +66 -66
  261. data/lib/inspec/cli.rb +292 -292
  262. data/lib/inspec/completions/bash.sh.erb +45 -45
  263. data/lib/inspec/completions/fish.sh.erb +34 -34
  264. data/lib/inspec/completions/zsh.sh.erb +61 -61
  265. data/lib/inspec/control_eval_context.rb +179 -179
  266. data/lib/inspec/dependencies/cache.rb +72 -72
  267. data/lib/inspec/dependencies/dependency_set.rb +92 -92
  268. data/lib/inspec/dependencies/lockfile.rb +115 -115
  269. data/lib/inspec/dependencies/requirement.rb +123 -123
  270. data/lib/inspec/dependencies/resolver.rb +86 -86
  271. data/lib/inspec/describe.rb +27 -27
  272. data/lib/inspec/dsl.rb +66 -66
  273. data/lib/inspec/dsl_shared.rb +33 -33
  274. data/lib/inspec/env_printer.rb +157 -157
  275. data/lib/inspec/errors.rb +13 -13
  276. data/lib/inspec/exceptions.rb +12 -12
  277. data/lib/inspec/expect.rb +45 -45
  278. data/lib/inspec/fetcher.rb +45 -45
  279. data/lib/inspec/file_provider.rb +275 -275
  280. data/lib/inspec/formatters.rb +3 -3
  281. data/lib/inspec/formatters/base.rb +250 -250
  282. data/lib/inspec/formatters/json_rspec.rb +20 -20
  283. data/lib/inspec/formatters/show_progress.rb +12 -12
  284. data/lib/inspec/library_eval_context.rb +58 -58
  285. data/lib/inspec/log.rb +11 -11
  286. data/lib/inspec/metadata.rb +247 -247
  287. data/lib/inspec/method_source.rb +24 -24
  288. data/lib/inspec/objects.rb +14 -14
  289. data/lib/inspec/objects/attribute.rb +65 -65
  290. data/lib/inspec/objects/control.rb +61 -61
  291. data/lib/inspec/objects/describe.rb +92 -92
  292. data/lib/inspec/objects/each_loop.rb +36 -36
  293. data/lib/inspec/objects/list.rb +15 -15
  294. data/lib/inspec/objects/or_test.rb +40 -40
  295. data/lib/inspec/objects/ruby_helper.rb +15 -15
  296. data/lib/inspec/objects/tag.rb +27 -27
  297. data/lib/inspec/objects/test.rb +87 -87
  298. data/lib/inspec/objects/value.rb +27 -27
  299. data/lib/inspec/plugins.rb +60 -60
  300. data/lib/inspec/plugins/cli.rb +24 -24
  301. data/lib/inspec/plugins/fetcher.rb +86 -86
  302. data/lib/inspec/plugins/resource.rb +135 -135
  303. data/lib/inspec/plugins/secret.rb +15 -15
  304. data/lib/inspec/plugins/source_reader.rb +40 -40
  305. data/lib/inspec/polyfill.rb +12 -12
  306. data/lib/inspec/profile.rb +510 -510
  307. data/lib/inspec/profile_context.rb +207 -207
  308. data/lib/inspec/profile_vendor.rb +66 -66
  309. data/lib/inspec/reporters.rb +54 -54
  310. data/lib/inspec/reporters/base.rb +24 -24
  311. data/lib/inspec/reporters/cli.rb +356 -356
  312. data/lib/inspec/reporters/json.rb +116 -116
  313. data/lib/inspec/reporters/json_min.rb +48 -48
  314. data/lib/inspec/reporters/junit.rb +77 -77
  315. data/lib/inspec/require_loader.rb +33 -33
  316. data/lib/inspec/resource.rb +186 -186
  317. data/lib/inspec/rule.rb +266 -266
  318. data/lib/inspec/runner.rb +345 -345
  319. data/lib/inspec/runner_mock.rb +41 -41
  320. data/lib/inspec/runner_rspec.rb +175 -175
  321. data/lib/inspec/runtime_profile.rb +26 -26
  322. data/lib/inspec/schema.rb +213 -213
  323. data/lib/inspec/secrets.rb +19 -19
  324. data/lib/inspec/secrets/yaml.rb +30 -30
  325. data/lib/inspec/shell.rb +220 -220
  326. data/lib/inspec/shell_detector.rb +90 -90
  327. data/lib/inspec/source_reader.rb +29 -29
  328. data/lib/inspec/version.rb +8 -8
  329. data/lib/matchers/matchers.rb +339 -339
  330. data/lib/resource_support/aws.rb +44 -41
  331. data/lib/resource_support/aws/aws_backend_base.rb +12 -12
  332. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
  333. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
  334. data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
  335. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
  336. data/lib/resources/aide_conf.rb +151 -159
  337. data/lib/resources/apache.rb +48 -48
  338. data/lib/resources/apache_conf.rb +149 -156
  339. data/lib/resources/apt.rb +149 -149
  340. data/lib/resources/audit_policy.rb +63 -63
  341. data/lib/resources/auditd.rb +231 -231
  342. data/lib/resources/auditd_conf.rb +46 -55
  343. data/lib/resources/aws/aws_cloudtrail_trail.rb +77 -77
  344. data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
  345. data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
  346. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
  347. data/lib/resources/aws/aws_config_recorder.rb +98 -98
  348. data/lib/resources/aws/aws_ec2_instance.rb +157 -157
  349. data/lib/resources/aws/aws_iam_access_key.rb +106 -106
  350. data/lib/resources/aws/aws_iam_access_keys.rb +149 -149
  351. data/lib/resources/aws/aws_iam_group.rb +56 -56
  352. data/lib/resources/aws/aws_iam_groups.rb +52 -52
  353. data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
  354. data/lib/resources/aws/aws_iam_policies.rb +53 -53
  355. data/lib/resources/aws/aws_iam_policy.rb +125 -125
  356. data/lib/resources/aws/aws_iam_role.rb +51 -51
  357. data/lib/resources/aws/aws_iam_root_user.rb +60 -60
  358. data/lib/resources/aws/aws_iam_user.rb +111 -111
  359. data/lib/resources/aws/aws_iam_users.rb +108 -108
  360. data/lib/resources/aws/aws_kms_keys.rb +53 -53
  361. data/lib/resources/aws/aws_route_table.rb +61 -61
  362. data/lib/resources/aws/aws_s3_bucket.rb +115 -115
  363. data/lib/resources/aws/aws_s3_bucket_object.rb +82 -0
  364. data/lib/resources/aws/aws_security_group.rb +93 -93
  365. data/lib/resources/aws/aws_security_groups.rb +68 -68
  366. data/lib/resources/aws/aws_sns_subscription.rb +78 -0
  367. data/lib/resources/aws/aws_sns_topic.rb +53 -53
  368. data/lib/resources/aws/aws_sns_topics.rb +56 -0
  369. data/lib/resources/aws/aws_subnet.rb +88 -88
  370. data/lib/resources/aws/aws_subnets.rb +53 -53
  371. data/lib/resources/aws/aws_vpc.rb +69 -69
  372. data/lib/resources/aws/aws_vpcs.rb +45 -45
  373. data/lib/resources/azure/azure_backend.rb +377 -377
  374. data/lib/resources/azure/azure_generic_resource.rb +59 -59
  375. data/lib/resources/azure/azure_resource_group.rb +152 -152
  376. data/lib/resources/azure/azure_virtual_machine.rb +264 -264
  377. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +136 -136
  378. data/lib/resources/bash.rb +35 -35
  379. data/lib/resources/bond.rb +69 -68
  380. data/lib/resources/bridge.rb +122 -122
  381. data/lib/resources/command.rb +73 -73
  382. data/lib/resources/cpan.rb +58 -58
  383. data/lib/resources/cran.rb +64 -64
  384. data/lib/resources/crontab.rb +169 -169
  385. data/lib/resources/csv.rb +56 -60
  386. data/lib/resources/dh_params.rb +77 -82
  387. data/lib/resources/directory.rb +25 -25
  388. data/lib/resources/docker.rb +236 -236
  389. data/lib/resources/docker_container.rb +89 -89
  390. data/lib/resources/docker_image.rb +83 -83
  391. data/lib/resources/docker_object.rb +57 -57
  392. data/lib/resources/docker_service.rb +90 -90
  393. data/lib/resources/elasticsearch.rb +169 -169
  394. data/lib/resources/etc_fstab.rb +94 -101
  395. data/lib/resources/etc_group.rb +152 -152
  396. data/lib/resources/etc_hosts.rb +66 -82
  397. data/lib/resources/etc_hosts_allow_deny.rb +112 -122
  398. data/lib/resources/file.rb +298 -298
  399. data/lib/resources/filesystem.rb +31 -31
  400. data/lib/resources/firewalld.rb +143 -143
  401. data/lib/resources/gem.rb +70 -70
  402. data/lib/resources/groups.rb +215 -215
  403. data/lib/resources/grub_conf.rb +227 -237
  404. data/lib/resources/host.rb +306 -306
  405. data/lib/resources/http.rb +251 -251
  406. data/lib/resources/iis_app.rb +101 -101
  407. data/lib/resources/iis_site.rb +148 -148
  408. data/lib/resources/inetd_conf.rb +54 -62
  409. data/lib/resources/ini.rb +29 -29
  410. data/lib/resources/interface.rb +129 -129
  411. data/lib/resources/iptables.rb +80 -80
  412. data/lib/resources/json.rb +107 -117
  413. data/lib/resources/kernel_module.rb +107 -107
  414. data/lib/resources/kernel_parameter.rb +58 -58
  415. data/lib/resources/key_rsa.rb +61 -67
  416. data/lib/resources/limits_conf.rb +46 -55
  417. data/lib/resources/login_def.rb +57 -66
  418. data/lib/resources/mount.rb +88 -88
  419. data/lib/resources/mssql_session.rb +101 -101
  420. data/lib/resources/mysql.rb +81 -81
  421. data/lib/resources/mysql_conf.rb +127 -134
  422. data/lib/resources/mysql_session.rb +85 -85
  423. data/lib/resources/nginx.rb +96 -96
  424. data/lib/resources/nginx_conf.rb +226 -227
  425. data/lib/resources/npm.rb +48 -48
  426. data/lib/resources/ntp_conf.rb +51 -58
  427. data/lib/resources/oneget.rb +71 -71
  428. data/lib/resources/oracledb_session.rb +139 -139
  429. data/lib/resources/os.rb +36 -36
  430. data/lib/resources/os_env.rb +76 -76
  431. data/lib/resources/package.rb +370 -370
  432. data/lib/resources/packages.rb +111 -111
  433. data/lib/resources/parse_config.rb +112 -116
  434. data/lib/resources/passwd.rb +76 -74
  435. data/lib/resources/pip.rb +89 -89
  436. data/lib/resources/platform.rb +109 -109
  437. data/lib/resources/port.rb +771 -771
  438. data/lib/resources/postgres.rb +130 -130
  439. data/lib/resources/postgres_conf.rb +114 -121
  440. data/lib/resources/postgres_hba_conf.rb +90 -99
  441. data/lib/resources/postgres_ident_conf.rb +79 -76
  442. data/lib/resources/postgres_session.rb +71 -71
  443. data/lib/resources/powershell.rb +53 -53
  444. data/lib/resources/processes.rb +204 -204
  445. data/lib/resources/rabbitmq_conf.rb +51 -52
  446. data/lib/resources/registry_key.rb +296 -296
  447. data/lib/resources/security_policy.rb +180 -180
  448. data/lib/resources/service.rb +790 -789
  449. data/lib/resources/shadow.rb +149 -146
  450. data/lib/resources/ssh_conf.rb +97 -102
  451. data/lib/resources/ssl.rb +99 -99
  452. data/lib/resources/sys_info.rb +28 -28
  453. data/lib/resources/toml.rb +32 -32
  454. data/lib/resources/users.rb +654 -654
  455. data/lib/resources/vbscript.rb +68 -68
  456. data/lib/resources/virtualization.rb +247 -247
  457. data/lib/resources/windows_feature.rb +84 -84
  458. data/lib/resources/windows_hotfix.rb +35 -35
  459. data/lib/resources/windows_task.rb +102 -102
  460. data/lib/resources/wmi.rb +110 -110
  461. data/lib/resources/x509_certificate.rb +137 -143
  462. data/lib/resources/xinetd.rb +106 -111
  463. data/lib/resources/xml.rb +46 -46
  464. data/lib/resources/yaml.rb +43 -47
  465. data/lib/resources/yum.rb +180 -180
  466. data/lib/resources/zfs_dataset.rb +60 -60
  467. data/lib/resources/zfs_pool.rb +49 -49
  468. data/lib/source_readers/flat.rb +39 -39
  469. data/lib/source_readers/inspec.rb +75 -75
  470. data/lib/utils/command_wrapper.rb +27 -27
  471. data/lib/utils/convert.rb +12 -12
  472. data/lib/utils/database_helpers.rb +77 -77
  473. data/lib/utils/erlang_parser.rb +192 -192
  474. data/lib/utils/file_reader.rb +25 -0
  475. data/lib/utils/filter.rb +272 -272
  476. data/lib/utils/filter_array.rb +27 -27
  477. data/lib/utils/find_files.rb +44 -44
  478. data/lib/utils/hash.rb +41 -41
  479. data/lib/utils/json_log.rb +18 -18
  480. data/lib/utils/latest_version.rb +22 -22
  481. data/lib/utils/modulator.rb +12 -12
  482. data/lib/utils/nginx_parser.rb +85 -85
  483. data/lib/utils/object_traversal.rb +49 -49
  484. data/lib/utils/parser.rb +274 -274
  485. data/lib/utils/plugin_registry.rb +93 -93
  486. data/lib/utils/simpleconfig.rb +120 -120
  487. data/lib/utils/spdx.rb +13 -13
  488. data/lib/utils/spdx.txt +343 -343
  489. metadata +12 -5
@@ -1,85 +1,85 @@
1
- # encoding: utf-8
2
- # copyright: 2015, Vulcano Security GmbH
3
-
4
- require 'shellwords'
5
-
6
- module Inspec::Resources
7
- class MysqlSession < Inspec.resource(1)
8
- name 'mysql_session'
9
- supports platform: 'unix'
10
- supports platform: 'windows'
11
- desc 'Use the mysql_session InSpec audit resource to test SQL commands run against a MySQL database.'
12
- example "
13
- sql = mysql_session('my_user','password','host')
14
- describe sql.query('show databases like \'test\';') do
15
- its('stdout') { should_not match(/test/) }
16
- end
17
- "
18
-
19
- def initialize(user = nil, pass = nil, host = 'localhost', port = nil, socket = nil)
20
- @user = user
21
- @pass = pass
22
- @host = host
23
- @port = port
24
- @socket = socket
25
- init_fallback if user.nil? or pass.nil?
26
- skip_resource("Can't run MySQL SQL checks without authentication") if @user.nil? or @pass.nil?
27
- end
28
-
29
- def query(q, db = '')
30
- mysql_cmd = create_mysql_cmd(q, db)
31
- cmd = inspec.command(mysql_cmd)
32
- out = cmd.stdout + "\n" + cmd.stderr
33
- if out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error/
34
- # skip this test if the server can't run the query
35
- warn("Can't connect to MySQL instance for SQL checks.")
36
- end
37
-
38
- # return the raw command output
39
- cmd
40
- end
41
-
42
- def to_s
43
- 'MySQL Session'
44
- end
45
-
46
- private
47
-
48
- def escape_string(query)
49
- Shellwords.escape(query)
50
- end
51
-
52
- def create_mysql_cmd(q, db = '')
53
- # TODO: simple escape, must be handled by a library
54
- # that does this securely
55
- escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
56
-
57
- # construct the query
58
- command = 'mysql'
59
- command += " -u#{escape_string(@user)}" unless @user.nil?
60
- command += " -p#{escape_string(@pass)}" unless @pass.nil?
61
-
62
- if !@socket.nil?
63
- command += " -S #{@socket}"
64
- else
65
- command += " -h #{@host}"
66
- end
67
- command += " --port #{@port}" unless @port.nil?
68
- command += " #{db}" unless db.empty?
69
- command += %{ -s -e "#{escaped_query}"}
70
- command
71
- end
72
-
73
- def init_fallback
74
- # support debian mysql administration login
75
- debian = inspec.command('test -f /etc/mysql/debian.cnf && cat /etc/mysql/debian.cnf').stdout
76
- return if debian.empty?
77
-
78
- user = debian.match(/^\s*user\s*=\s*([^ ]*)\s*$/)
79
- pass = debian.match(/^\s*password\s*=\s*([^ ]*)\s*$/)
80
- return if user.nil? or pass.nil?
81
- @user = user[1]
82
- @pass = pass[1]
83
- end
84
- end
85
- end
1
+ # encoding: utf-8
2
+ # copyright: 2015, Vulcano Security GmbH
3
+
4
+ require 'shellwords'
5
+
6
+ module Inspec::Resources
7
+ class MysqlSession < Inspec.resource(1)
8
+ name 'mysql_session'
9
+ supports platform: 'unix'
10
+ supports platform: 'windows'
11
+ desc 'Use the mysql_session InSpec audit resource to test SQL commands run against a MySQL database.'
12
+ example "
13
+ sql = mysql_session('my_user','password','host')
14
+ describe sql.query('show databases like \'test\';') do
15
+ its('stdout') { should_not match(/test/) }
16
+ end
17
+ "
18
+
19
+ def initialize(user = nil, pass = nil, host = 'localhost', port = nil, socket = nil)
20
+ @user = user
21
+ @pass = pass
22
+ @host = host
23
+ @port = port
24
+ @socket = socket
25
+ init_fallback if user.nil? or pass.nil?
26
+ skip_resource("Can't run MySQL SQL checks without authentication") if @user.nil? or @pass.nil?
27
+ end
28
+
29
+ def query(q, db = '')
30
+ mysql_cmd = create_mysql_cmd(q, db)
31
+ cmd = inspec.command(mysql_cmd)
32
+ out = cmd.stdout + "\n" + cmd.stderr
33
+ if out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error/
34
+ # skip this test if the server can't run the query
35
+ warn("Can't connect to MySQL instance for SQL checks.")
36
+ end
37
+
38
+ # return the raw command output
39
+ cmd
40
+ end
41
+
42
+ def to_s
43
+ 'MySQL Session'
44
+ end
45
+
46
+ private
47
+
48
+ def escape_string(query)
49
+ Shellwords.escape(query)
50
+ end
51
+
52
+ def create_mysql_cmd(q, db = '')
53
+ # TODO: simple escape, must be handled by a library
54
+ # that does this securely
55
+ escaped_query = q.gsub(/\\/, '\\\\').gsub(/"/, '\\"').gsub(/\$/, '\\$')
56
+
57
+ # construct the query
58
+ command = 'mysql'
59
+ command += " -u#{escape_string(@user)}" unless @user.nil?
60
+ command += " -p#{escape_string(@pass)}" unless @pass.nil?
61
+
62
+ if !@socket.nil?
63
+ command += " -S #{@socket}"
64
+ else
65
+ command += " -h #{@host}"
66
+ end
67
+ command += " --port #{@port}" unless @port.nil?
68
+ command += " #{db}" unless db.empty?
69
+ command += %{ -s -e "#{escaped_query}"}
70
+ command
71
+ end
72
+
73
+ def init_fallback
74
+ # support debian mysql administration login
75
+ debian = inspec.command('test -f /etc/mysql/debian.cnf && cat /etc/mysql/debian.cnf').stdout
76
+ return if debian.empty?
77
+
78
+ user = debian.match(/^\s*user\s*=\s*([^ ]*)\s*$/)
79
+ pass = debian.match(/^\s*password\s*=\s*([^ ]*)\s*$/)
80
+ return if user.nil? or pass.nil?
81
+ @user = user[1]
82
+ @pass = pass[1]
83
+ end
84
+ end
85
+ end
@@ -1,96 +1,96 @@
1
- # encoding: utf-8
2
-
3
- require 'pathname'
4
- require 'hashie/mash'
5
-
6
- module Inspec::Resources
7
- class Nginx < Inspec.resource(1)
8
- name 'nginx'
9
- supports platform: 'unix'
10
- desc 'Use the nginx InSpec audit resource to test information about your NGINX instance.'
11
- example "
12
- describe nginx do
13
- its('conf_path') { should cmp '/etc/nginx/nginx.conf' }
14
- end
15
- describe nginx('/etc/sbin/') do
16
- its('version') { should be >= '1.0.0' }
17
- end
18
- describe nginx do
19
- its('modules') { should include 'my_module' }
20
- end
21
- "
22
- attr_reader :params, :bin_dir
23
-
24
- def initialize(nginx_path = '/usr/sbin/nginx')
25
- return skip_resource 'The `nginx` resource is not yet available on your OS.' if inspec.os.windows?
26
- return skip_resource 'The `nginx` binary not found in the path provided.' unless inspec.command(nginx_path).exist?
27
-
28
- cmd = inspec.command("#{nginx_path} -V 2>&1")
29
- if !cmd.exit_status.zero?
30
- return skip_resource 'Error using the command nginx -V'
31
- end
32
- @data = cmd.stdout
33
- @params = {}
34
- read_content
35
- end
36
-
37
- %w{compiler_info error_log_path http_client_body_temp_path http_fastcgi_temp_path http_log_path http_proxy_temp_path http_scgi_temp_path http_uwsgi_temp_path lock_path modules_path openssl_version prefix sbin_path service support_info version}.each do |property|
38
- define_method(property.to_sym) do
39
- @params[property.to_sym]
40
- end
41
- end
42
-
43
- def openssl_version
44
- result = @data.scan(/built with OpenSSL\s(\S+)\s(\d+\s\S+\s\d{4})/).flatten
45
- Hashie::Mash.new({ 'version' => result[0], 'date' => result[1] })
46
- end
47
-
48
- def compiler_info
49
- result = @data.scan(/built by (\S+)\s(\S+)\s(\S+)/).flatten
50
- Hashie::Mash.new({ 'compiler' => result[0], 'version' => result[1], 'date' => result[2] })
51
- end
52
-
53
- def support_info
54
- support_info = @data.scan(/(.*\S+) support enabled/).flatten
55
- support_info.empty? ? nil : support_info.join(' ')
56
- end
57
-
58
- def modules
59
- @data.scan(/--with-(\S+)_module/).flatten
60
- end
61
-
62
- def to_s
63
- 'Nginx Environment'
64
- end
65
-
66
- private
67
-
68
- def read_content
69
- parse_config
70
- parse_path
71
- parse_http_path
72
- end
73
-
74
- def parse_config
75
- @params[:prefix] = @data.scan(/--prefix=(\S+)\s/).flatten.first
76
- @params[:service] = 'nginx'
77
- @params[:version] = @data.scan(%r{nginx version: nginx\/(\S+)\s}).flatten.first
78
- end
79
-
80
- def parse_path
81
- @params[:sbin_path] = @data.scan(/--sbin-path=(\S+)\s/).flatten.first
82
- @params[:modules_path] = @data.scan(/--modules-path=(\S+)\s/).flatten.first
83
- @params[:error_log_path] = @data.scan(/--error-log-path=(\S+)\s/).flatten.first
84
- @params[:http_log_path] = @data.scan(/--http-log-path=(\S+)\s/).flatten.first
85
- @params[:lock_path] = @data.scan(/--lock-path=(\S+)\s/).flatten.first
86
- end
87
-
88
- def parse_http_path
89
- @params[:http_client_body_temp_path] = @data.scan(/--http-client-body-temp-path=(\S+)\s/).flatten.first
90
- @params[:http_proxy_temp_path] = @data.scan(/--http-proxy-temp-path=(\S+)\s/).flatten.first
91
- @params[:http_fastcgi_temp_path] = @data.scan(/--http-fastcgi-temp-path=(\S+)\s/).flatten.first
92
- @params[:http_uwsgi_temp_path] = @data.scan(/--http-uwsgi-temp-path=(\S+)\s/).flatten.first
93
- @params[:http_scgi_temp_path] = @data.scan(/--http-scgi-temp-path=(\S+)\s/).flatten.first
94
- end
95
- end
96
- end
1
+ # encoding: utf-8
2
+
3
+ require 'pathname'
4
+ require 'hashie/mash'
5
+
6
+ module Inspec::Resources
7
+ class Nginx < Inspec.resource(1)
8
+ name 'nginx'
9
+ supports platform: 'unix'
10
+ desc 'Use the nginx InSpec audit resource to test information about your NGINX instance.'
11
+ example "
12
+ describe nginx do
13
+ its('conf_path') { should cmp '/etc/nginx/nginx.conf' }
14
+ end
15
+ describe nginx('/etc/sbin/') do
16
+ its('version') { should be >= '1.0.0' }
17
+ end
18
+ describe nginx do
19
+ its('modules') { should include 'my_module' }
20
+ end
21
+ "
22
+ attr_reader :params, :bin_dir
23
+
24
+ def initialize(nginx_path = '/usr/sbin/nginx')
25
+ return skip_resource 'The `nginx` resource is not yet available on your OS.' if inspec.os.windows?
26
+ return skip_resource 'The `nginx` binary not found in the path provided.' unless inspec.command(nginx_path).exist?
27
+
28
+ cmd = inspec.command("#{nginx_path} -V 2>&1")
29
+ if !cmd.exit_status.zero?
30
+ return skip_resource 'Error using the command nginx -V'
31
+ end
32
+ @data = cmd.stdout
33
+ @params = {}
34
+ read_content
35
+ end
36
+
37
+ %w{compiler_info error_log_path http_client_body_temp_path http_fastcgi_temp_path http_log_path http_proxy_temp_path http_scgi_temp_path http_uwsgi_temp_path lock_path modules_path openssl_version prefix sbin_path service support_info version}.each do |property|
38
+ define_method(property.to_sym) do
39
+ @params[property.to_sym]
40
+ end
41
+ end
42
+
43
+ def openssl_version
44
+ result = @data.scan(/built with OpenSSL\s(\S+)\s(\d+\s\S+\s\d{4})/).flatten
45
+ Hashie::Mash.new({ 'version' => result[0], 'date' => result[1] })
46
+ end
47
+
48
+ def compiler_info
49
+ result = @data.scan(/built by (\S+)\s(\S+)\s(\S+)/).flatten
50
+ Hashie::Mash.new({ 'compiler' => result[0], 'version' => result[1], 'date' => result[2] })
51
+ end
52
+
53
+ def support_info
54
+ support_info = @data.scan(/(.*\S+) support enabled/).flatten
55
+ support_info.empty? ? nil : support_info.join(' ')
56
+ end
57
+
58
+ def modules
59
+ @data.scan(/--with-(\S+)_module/).flatten
60
+ end
61
+
62
+ def to_s
63
+ 'Nginx Environment'
64
+ end
65
+
66
+ private
67
+
68
+ def read_content
69
+ parse_config
70
+ parse_path
71
+ parse_http_path
72
+ end
73
+
74
+ def parse_config
75
+ @params[:prefix] = @data.scan(/--prefix=(\S+)\s/).flatten.first
76
+ @params[:service] = 'nginx'
77
+ @params[:version] = @data.scan(%r{nginx version: nginx\/(\S+)\s}).flatten.first
78
+ end
79
+
80
+ def parse_path
81
+ @params[:sbin_path] = @data.scan(/--sbin-path=(\S+)\s/).flatten.first
82
+ @params[:modules_path] = @data.scan(/--modules-path=(\S+)\s/).flatten.first
83
+ @params[:error_log_path] = @data.scan(/--error-log-path=(\S+)\s/).flatten.first
84
+ @params[:http_log_path] = @data.scan(/--http-log-path=(\S+)\s/).flatten.first
85
+ @params[:lock_path] = @data.scan(/--lock-path=(\S+)\s/).flatten.first
86
+ end
87
+
88
+ def parse_http_path
89
+ @params[:http_client_body_temp_path] = @data.scan(/--http-client-body-temp-path=(\S+)\s/).flatten.first
90
+ @params[:http_proxy_temp_path] = @data.scan(/--http-proxy-temp-path=(\S+)\s/).flatten.first
91
+ @params[:http_fastcgi_temp_path] = @data.scan(/--http-fastcgi-temp-path=(\S+)\s/).flatten.first
92
+ @params[:http_uwsgi_temp_path] = @data.scan(/--http-uwsgi-temp-path=(\S+)\s/).flatten.first
93
+ @params[:http_scgi_temp_path] = @data.scan(/--http-scgi-temp-path=(\S+)\s/).flatten.first
94
+ end
95
+ end
96
+ end
@@ -1,227 +1,226 @@
1
- # encoding: utf-8
2
-
3
- require 'utils/nginx_parser'
4
- require 'utils/find_files'
5
- require 'forwardable'
6
-
7
- # STABILITY: Experimental
8
- # This resouce needs a proper interace to the underlying data, which is currently missing.
9
- # Until it is added, we will keep it experimental.
10
- #
11
- # TODO: Support it on Windows. To do so, we need to recognize the base os and how
12
- # it combines the file path. Calling `File.join` or similar methods may lead to errors
13
- # when running remotely.
14
- module Inspec::Resources
15
- class NginxConf < Inspec.resource(1)
16
- name 'nginx_conf'
17
- supports platform: 'unix'
18
- desc 'Use the nginx_conf InSpec resource to test configuration data '\
19
- 'for the NginX web server located in /etc/nginx/nginx.conf on '\
20
- 'Linux and UNIX platforms.'
21
- example "
22
- describe nginx_conf.params ...
23
- describe nginx_conf('/path/to/my/nginx.conf').params ...
24
- "
25
-
26
- extend Forwardable
27
-
28
- include FindFiles
29
-
30
- attr_reader :contents
31
-
32
- def initialize(conf_path = nil)
33
- @conf_path = conf_path || '/etc/nginx/nginx.conf'
34
- @contents = {}
35
- return skip_resource 'The `nginx_conf` resource is currently not supported on Windows.' if inspec.os.windows?
36
- end
37
-
38
- def params
39
- @params ||= parse_nginx(@conf_path)
40
- rescue StandardError => e
41
- skip_resource e.message
42
- @params = {}
43
- end
44
-
45
- def http
46
- NginxConfHttp.new(params['http'], self)
47
- end
48
-
49
- def_delegators :http, :servers, :locations
50
-
51
- def to_s
52
- "nginx_conf #{@conf_path}"
53
- end
54
-
55
- private
56
-
57
- def read_content(path)
58
- return @contents[path] if @contents.key?(path)
59
- file = inspec.file(path)
60
- if !file.file?
61
- return skip_resource "Can't find file \"#{path}\""
62
- end
63
- @contents[path] = file.content
64
- end
65
-
66
- def parse_nginx(path)
67
- return nil if inspec.os.windows?
68
- content = read_content(path)
69
- data = NginxConfig.parse(content)
70
- resolve_references(data, File.dirname(path))
71
- rescue StandardError => _
72
- raise "Cannot parse NginX config in #{path}."
73
- end
74
-
75
- # Cycle through the complete parsed data structure and try to find any
76
- # calls to `include`. In NginX, this is used to embed data from other
77
- # files into the current data structure.
78
- #
79
- # The method steps through the object structure that is passed in to
80
- # find any calls to 'include' and returns the object structure with the
81
- # included data merged in.
82
- #
83
- # @param data [Hash] data structure from NginxConfig.parse
84
- # @param rel_path [String] the relative path from which this config is read
85
- # @return [Hash] data structure with references included
86
- def resolve_references(data, rel_path)
87
- # Walk through all array entries to find more references
88
- return data.map { |x| resolve_references(x, rel_path) } if data.is_a?(Array)
89
-
90
- # Return any data that we cannot step into to find more `include` calls
91
- return data unless data.is_a?(Hash)
92
-
93
- # Any call to `include` gets its data read, parsed, and merged back
94
- # into the current data structure
95
- if data.key?('include')
96
- data.delete('include').flatten
97
- .map { |x| File.expand_path(x, rel_path) }
98
- .map { |x| find_files(x) }.flatten
99
- .map { |path| parse_nginx(path) }
100
- .each { |conf| merge_config!(data, conf) }
101
- end
102
-
103
- # Walk through the remaining hash fields to find more references
104
- Hash[data.map { |k, v| [k, resolve_references(v, rel_path)] }]
105
- end
106
-
107
- # Deep merge fields from NginxConfig.parse.
108
- # A regular merge would overwrite values so a deep merge is needed.
109
- # @param data [Hash] data structure from NginxConfig.parse
110
- # @param conf [Hash] data structure to be deep merged into data
111
- # @return [Hash] data structure with conf and data deep merged
112
- def merge_config!(data, conf)
113
- # Catch edge-cases
114
- return if data.nil? || conf.nil?
115
- # Step through all conf items and create combined return value
116
- data.merge!(conf) do |_, v1, v2|
117
- if v1.is_a?(Array) && v2.is_a?(Array)
118
- # If both the data field and the conf field are arrays, then combine them
119
- v1 + v2
120
- elsif v1.is_a?(Hash) && v2.is_a?(Hash)
121
- # If both the data field and the conf field are maps, then deep merge them
122
- merge_config!(v1, v2)
123
- else
124
- # All other cases, just use the new value (regular merge behavior)
125
- v2
126
- end
127
- end
128
- end
129
- end
130
-
131
- class NginxConfHttp
132
- attr_reader :entries
133
- def initialize(params, parent)
134
- @parent = parent
135
- @entries = (params || []).map { |x| NginxConfHttpEntry.new(x, parent) }
136
- end
137
-
138
- def servers
139
- @entries.map(&:servers).flatten
140
- end
141
-
142
- def locations
143
- servers.map(&:locations).flatten
144
- end
145
-
146
- def to_s
147
- @parent.to_s + ', http entries'
148
- end
149
- alias inspect to_s
150
- end
151
-
152
- class NginxConfHttpEntry
153
- attr_reader :params, :parent
154
- def initialize(params, parent)
155
- @params = params || {}
156
- @parent = parent
157
- end
158
-
159
- filter = FilterTable.create
160
- filter.add_accessor(:where)
161
- .add(:servers, field: 'server')
162
- .connect(self, :server_table)
163
-
164
- def locations
165
- servers.map(&:locations).flatten
166
- end
167
-
168
- def to_s
169
- @parent.to_s + ', http entry'
170
- end
171
- alias inspect to_s
172
-
173
- private
174
-
175
- def server_table
176
- @server_table ||= (params['server'] || []).map { |x| { 'server' => NginxConfServer.new(x, self) } }
177
- end
178
- end
179
-
180
- class NginxConfServer
181
- attr_reader :params, :parent
182
- def initialize(params, parent)
183
- @parent = parent
184
- @params = params || {}
185
- end
186
-
187
- filter = FilterTable.create
188
- filter.add_accessor(:where)
189
- .add(:locations, field: 'location')
190
- .connect(self, :location_table)
191
-
192
- def to_s
193
- server = ''
194
- name = Array(params['server_name']).flatten.first
195
- unless name.nil?
196
- server += name
197
- listen = Array(params['listen']).flatten.first
198
- server += ":#{listen}" unless listen.nil?
199
- end
200
-
201
- # go two levels up: 1. to the http entry and 2. to the root nginx conf
202
- @parent.parent.to_s + ", server #{server}"
203
- end
204
- alias inspect to_s
205
-
206
- private
207
-
208
- def location_table
209
- @location_table ||= (params['location'] || []).map { |x| { 'location' => NginxConfLocation.new(x, self) } }
210
- end
211
- end
212
-
213
- class NginxConfLocation
214
- attr_reader :params, :parent
215
- def initialize(params, parent)
216
- @parent = parent
217
- @params = params || {}
218
- end
219
-
220
- def to_s
221
- location = Array(params['_']).join(' ')
222
- # go three levels up: 1. to the server entry, 2. http entry and 3. to the root nginx conf
223
- @parent.parent.parent.to_s + ", location #{location.inspect}"
224
- end
225
- alias inspect to_s
226
- end
227
- end
1
+ # encoding: utf-8
2
+
3
+ require 'utils/nginx_parser'
4
+ require 'utils/find_files'
5
+ require 'utils/file_reader'
6
+ require 'forwardable'
7
+
8
+ # STABILITY: Experimental
9
+ # This resouce needs a proper interace to the underlying data, which is currently missing.
10
+ # Until it is added, we will keep it experimental.
11
+ #
12
+ # TODO: Support it on Windows. To do so, we need to recognize the base os and how
13
+ # it combines the file path. Calling `File.join` or similar methods may lead to errors
14
+ # when running remotely.
15
+ module Inspec::Resources
16
+ class NginxConf < Inspec.resource(1)
17
+ name 'nginx_conf'
18
+ supports platform: 'unix'
19
+ desc 'Use the nginx_conf InSpec resource to test configuration data '\
20
+ 'for the NginX web server located in /etc/nginx/nginx.conf on '\
21
+ 'Linux and UNIX platforms.'
22
+ example "
23
+ describe nginx_conf.params ...
24
+ describe nginx_conf('/path/to/my/nginx.conf').params ...
25
+ "
26
+
27
+ extend Forwardable
28
+
29
+ include FindFiles
30
+ include FileReader
31
+
32
+ attr_reader :contents
33
+
34
+ def initialize(conf_path = nil)
35
+ @conf_path = conf_path || '/etc/nginx/nginx.conf'
36
+ @contents = {}
37
+ return skip_resource 'The `nginx_conf` resource is currently not supported on Windows.' if inspec.os.windows?
38
+ read_content(@conf_path)
39
+ end
40
+
41
+ def params
42
+ @params ||= parse_nginx(@conf_path)
43
+ rescue StandardError => e
44
+ skip_resource e.message
45
+ @params = {}
46
+ end
47
+
48
+ def http
49
+ NginxConfHttp.new(params['http'], self)
50
+ end
51
+
52
+ def_delegators :http, :servers, :locations
53
+
54
+ def to_s
55
+ "nginx_conf #{@conf_path}"
56
+ end
57
+
58
+ private
59
+
60
+ def read_content(path)
61
+ return @contents[path] if @contents.key?(path)
62
+ @contents[path] = read_file_content(path, allow_empty: true)
63
+ end
64
+
65
+ def parse_nginx(path)
66
+ return nil if inspec.os.windows?
67
+ content = read_content(path)
68
+ data = NginxConfig.parse(content)
69
+ resolve_references(data, File.dirname(path))
70
+ rescue StandardError => _
71
+ raise "Cannot parse NginX config in #{path}."
72
+ end
73
+
74
+ # Cycle through the complete parsed data structure and try to find any
75
+ # calls to `include`. In NginX, this is used to embed data from other
76
+ # files into the current data structure.
77
+ #
78
+ # The method steps through the object structure that is passed in to
79
+ # find any calls to 'include' and returns the object structure with the
80
+ # included data merged in.
81
+ #
82
+ # @param data [Hash] data structure from NginxConfig.parse
83
+ # @param rel_path [String] the relative path from which this config is read
84
+ # @return [Hash] data structure with references included
85
+ def resolve_references(data, rel_path)
86
+ # Walk through all array entries to find more references
87
+ return data.map { |x| resolve_references(x, rel_path) } if data.is_a?(Array)
88
+
89
+ # Return any data that we cannot step into to find more `include` calls
90
+ return data unless data.is_a?(Hash)
91
+
92
+ # Any call to `include` gets its data read, parsed, and merged back
93
+ # into the current data structure
94
+ if data.key?('include')
95
+ data.delete('include').flatten
96
+ .map { |x| File.expand_path(x, rel_path) }
97
+ .map { |x| find_files(x) }.flatten
98
+ .map { |path| parse_nginx(path) }
99
+ .each { |conf| merge_config!(data, conf) }
100
+ end
101
+
102
+ # Walk through the remaining hash fields to find more references
103
+ Hash[data.map { |k, v| [k, resolve_references(v, rel_path)] }]
104
+ end
105
+
106
+ # Deep merge fields from NginxConfig.parse.
107
+ # A regular merge would overwrite values so a deep merge is needed.
108
+ # @param data [Hash] data structure from NginxConfig.parse
109
+ # @param conf [Hash] data structure to be deep merged into data
110
+ # @return [Hash] data structure with conf and data deep merged
111
+ def merge_config!(data, conf)
112
+ # Catch edge-cases
113
+ return if data.nil? || conf.nil?
114
+ # Step through all conf items and create combined return value
115
+ data.merge!(conf) do |_, v1, v2|
116
+ if v1.is_a?(Array) && v2.is_a?(Array)
117
+ # If both the data field and the conf field are arrays, then combine them
118
+ v1 + v2
119
+ elsif v1.is_a?(Hash) && v2.is_a?(Hash)
120
+ # If both the data field and the conf field are maps, then deep merge them
121
+ merge_config!(v1, v2)
122
+ else
123
+ # All other cases, just use the new value (regular merge behavior)
124
+ v2
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ class NginxConfHttp
131
+ attr_reader :entries
132
+ def initialize(params, parent)
133
+ @parent = parent
134
+ @entries = (params || []).map { |x| NginxConfHttpEntry.new(x, parent) }
135
+ end
136
+
137
+ def servers
138
+ @entries.map(&:servers).flatten
139
+ end
140
+
141
+ def locations
142
+ servers.map(&:locations).flatten
143
+ end
144
+
145
+ def to_s
146
+ @parent.to_s + ', http entries'
147
+ end
148
+ alias inspect to_s
149
+ end
150
+
151
+ class NginxConfHttpEntry
152
+ attr_reader :params, :parent
153
+ def initialize(params, parent)
154
+ @params = params || {}
155
+ @parent = parent
156
+ end
157
+
158
+ filter = FilterTable.create
159
+ filter.add_accessor(:where)
160
+ .add(:servers, field: 'server')
161
+ .connect(self, :server_table)
162
+
163
+ def locations
164
+ servers.map(&:locations).flatten
165
+ end
166
+
167
+ def to_s
168
+ @parent.to_s + ', http entry'
169
+ end
170
+ alias inspect to_s
171
+
172
+ private
173
+
174
+ def server_table
175
+ @server_table ||= (params['server'] || []).map { |x| { 'server' => NginxConfServer.new(x, self) } }
176
+ end
177
+ end
178
+
179
+ class NginxConfServer
180
+ attr_reader :params, :parent
181
+ def initialize(params, parent)
182
+ @parent = parent
183
+ @params = params || {}
184
+ end
185
+
186
+ filter = FilterTable.create
187
+ filter.add_accessor(:where)
188
+ .add(:locations, field: 'location')
189
+ .connect(self, :location_table)
190
+
191
+ def to_s
192
+ server = ''
193
+ name = Array(params['server_name']).flatten.first
194
+ unless name.nil?
195
+ server += name
196
+ listen = Array(params['listen']).flatten.first
197
+ server += ":#{listen}" unless listen.nil?
198
+ end
199
+
200
+ # go two levels up: 1. to the http entry and 2. to the root nginx conf
201
+ @parent.parent.to_s + ", server #{server}"
202
+ end
203
+ alias inspect to_s
204
+
205
+ private
206
+
207
+ def location_table
208
+ @location_table ||= (params['location'] || []).map { |x| { 'location' => NginxConfLocation.new(x, self) } }
209
+ end
210
+ end
211
+
212
+ class NginxConfLocation
213
+ attr_reader :params, :parent
214
+ def initialize(params, parent)
215
+ @parent = parent
216
+ @params = params || {}
217
+ end
218
+
219
+ def to_s
220
+ location = Array(params['_']).join(' ')
221
+ # go three levels up: 1. to the server entry, 2. http entry and 3. to the root nginx conf
222
+ @parent.parent.parent.to_s + ", location #{location.inspect}"
223
+ end
224
+ alias inspect to_s
225
+ end
226
+ end