inspec 2.1.81 → 2.1.83

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 (507) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +101 -101
  3. data/CHANGELOG.md +3183 -3177
  4. data/Gemfile +56 -56
  5. data/LICENSE +14 -14
  6. data/MAINTAINERS.md +33 -33
  7. data/MAINTAINERS.toml +52 -52
  8. data/README.md +453 -453
  9. data/Rakefile +349 -349
  10. data/bin/inspec +12 -12
  11. data/docs/.gitignore +2 -2
  12. data/docs/README.md +41 -40
  13. data/docs/dev/control-eval.md +61 -61
  14. data/docs/dsl_inspec.md +258 -258
  15. data/docs/dsl_resource.md +100 -100
  16. data/docs/glossary.md +99 -99
  17. data/docs/habitat.md +191 -191
  18. data/docs/inspec_and_friends.md +114 -114
  19. data/docs/matchers.md +169 -169
  20. data/docs/migration.md +293 -293
  21. data/docs/platforms.md +118 -118
  22. data/docs/plugin_kitchen_inspec.md +50 -50
  23. data/docs/profiles.md +378 -378
  24. data/docs/reporters.md +105 -105
  25. data/docs/resources/aide_conf.md.erb +75 -75
  26. data/docs/resources/apache.md.erb +67 -67
  27. data/docs/resources/apache_conf.md.erb +68 -68
  28. data/docs/resources/apt.md.erb +71 -71
  29. data/docs/resources/audit_policy.md.erb +47 -47
  30. data/docs/resources/auditd.md.erb +79 -79
  31. data/docs/resources/auditd_conf.md.erb +68 -68
  32. data/docs/resources/aws_cloudtrail_trail.md.erb +155 -155
  33. data/docs/resources/aws_cloudtrail_trails.md.erb +86 -86
  34. data/docs/resources/aws_cloudwatch_alarm.md.erb +91 -91
  35. data/docs/resources/aws_cloudwatch_log_metric_filter.md.erb +154 -154
  36. data/docs/resources/aws_config_delivery_channel.md.erb +101 -101
  37. data/docs/resources/aws_config_recorder.md.erb +86 -86
  38. data/docs/resources/aws_ec2_instance.md.erb +112 -112
  39. data/docs/resources/aws_ec2_instances.md.erb +79 -79
  40. data/docs/resources/aws_iam_access_key.md.erb +129 -129
  41. data/docs/resources/aws_iam_access_keys.md.erb +204 -204
  42. data/docs/resources/aws_iam_group.md.erb +64 -64
  43. data/docs/resources/aws_iam_groups.md.erb +49 -49
  44. data/docs/resources/aws_iam_password_policy.md.erb +82 -82
  45. data/docs/resources/aws_iam_policies.md.erb +87 -87
  46. data/docs/resources/aws_iam_policy.md.erb +245 -245
  47. data/docs/resources/aws_iam_role.md.erb +69 -69
  48. data/docs/resources/aws_iam_root_user.md.erb +76 -76
  49. data/docs/resources/aws_iam_user.md.erb +120 -120
  50. data/docs/resources/aws_iam_users.md.erb +279 -279
  51. data/docs/resources/aws_kms_key.md.erb +177 -177
  52. data/docs/resources/aws_kms_keys.md.erb +89 -89
  53. data/docs/resources/aws_rds_instance.md.erb +66 -66
  54. data/docs/resources/aws_route_table.md.erb +53 -53
  55. data/docs/resources/aws_route_tables.md.erb +55 -55
  56. data/docs/resources/aws_s3_bucket.md.erb +146 -146
  57. data/docs/resources/aws_s3_bucket_object.md.erb +89 -89
  58. data/docs/resources/aws_s3_buckets.md.erb +59 -59
  59. data/docs/resources/aws_security_group.md.erb +296 -296
  60. data/docs/resources/aws_security_groups.md.erb +97 -97
  61. data/docs/resources/aws_sns_subscription.md.erb +130 -130
  62. data/docs/resources/aws_sns_topic.md.erb +69 -69
  63. data/docs/resources/aws_sns_topics.md.erb +58 -58
  64. data/docs/resources/aws_subnet.md.erb +140 -140
  65. data/docs/resources/aws_subnets.md.erb +132 -132
  66. data/docs/resources/aws_vpc.md.erb +125 -125
  67. data/docs/resources/aws_vpcs.md.erb +125 -125
  68. data/docs/resources/azure_generic_resource.md.erb +171 -171
  69. data/docs/resources/azure_resource_group.md.erb +284 -284
  70. data/docs/resources/azure_virtual_machine.md.erb +347 -347
  71. data/docs/resources/azure_virtual_machine_data_disk.md.erb +224 -224
  72. data/docs/resources/bash.md.erb +75 -75
  73. data/docs/resources/bond.md.erb +90 -90
  74. data/docs/resources/bridge.md.erb +57 -57
  75. data/docs/resources/bsd_service.md.erb +67 -67
  76. data/docs/resources/chocolatey_package.md.erb +58 -58
  77. data/docs/resources/command.md.erb +138 -138
  78. data/docs/resources/cpan.md.erb +79 -79
  79. data/docs/resources/cran.md.erb +64 -64
  80. data/docs/resources/crontab.md.erb +89 -89
  81. data/docs/resources/csv.md.erb +54 -54
  82. data/docs/resources/dh_params.md.erb +205 -205
  83. data/docs/resources/directory.md.erb +30 -30
  84. data/docs/resources/docker.md.erb +219 -219
  85. data/docs/resources/docker_container.md.erb +103 -103
  86. data/docs/resources/docker_image.md.erb +94 -94
  87. data/docs/resources/docker_service.md.erb +114 -114
  88. data/docs/resources/elasticsearch.md.erb +242 -242
  89. data/docs/resources/etc_fstab.md.erb +125 -125
  90. data/docs/resources/etc_group.md.erb +75 -75
  91. data/docs/resources/etc_hosts.md.erb +78 -78
  92. data/docs/resources/etc_hosts_allow.md.erb +74 -74
  93. data/docs/resources/etc_hosts_deny.md.erb +74 -74
  94. data/docs/resources/file.md.erb +526 -526
  95. data/docs/resources/filesystem.md.erb +41 -41
  96. data/docs/resources/firewalld.md.erb +107 -107
  97. data/docs/resources/gem.md.erb +79 -79
  98. data/docs/resources/group.md.erb +61 -61
  99. data/docs/resources/grub_conf.md.erb +101 -101
  100. data/docs/resources/host.md.erb +86 -86
  101. data/docs/resources/http.md.erb +197 -197
  102. data/docs/resources/iis_app.md.erb +122 -122
  103. data/docs/resources/iis_site.md.erb +135 -135
  104. data/docs/resources/inetd_conf.md.erb +94 -94
  105. data/docs/resources/ini.md.erb +76 -76
  106. data/docs/resources/interface.md.erb +58 -58
  107. data/docs/resources/iptables.md.erb +64 -64
  108. data/docs/resources/json.md.erb +63 -63
  109. data/docs/resources/kernel_module.md.erb +120 -120
  110. data/docs/resources/kernel_parameter.md.erb +53 -53
  111. data/docs/resources/key_rsa.md.erb +85 -85
  112. data/docs/resources/launchd_service.md.erb +57 -57
  113. data/docs/resources/limits_conf.md.erb +75 -75
  114. data/docs/resources/login_defs.md.erb +71 -71
  115. data/docs/resources/mount.md.erb +69 -69
  116. data/docs/resources/mssql_session.md.erb +60 -60
  117. data/docs/resources/mysql_conf.md.erb +99 -99
  118. data/docs/resources/mysql_session.md.erb +74 -74
  119. data/docs/resources/nginx.md.erb +79 -79
  120. data/docs/resources/nginx_conf.md.erb +138 -138
  121. data/docs/resources/npm.md.erb +60 -60
  122. data/docs/resources/ntp_conf.md.erb +60 -60
  123. data/docs/resources/oneget.md.erb +53 -53
  124. data/docs/resources/oracledb_session.md.erb +52 -52
  125. data/docs/resources/os.md.erb +141 -141
  126. data/docs/resources/os_env.md.erb +91 -91
  127. data/docs/resources/package.md.erb +120 -120
  128. data/docs/resources/packages.md.erb +67 -67
  129. data/docs/resources/parse_config.md.erb +103 -103
  130. data/docs/resources/parse_config_file.md.erb +138 -138
  131. data/docs/resources/passwd.md.erb +141 -141
  132. data/docs/resources/pip.md.erb +67 -67
  133. data/docs/resources/port.md.erb +137 -137
  134. data/docs/resources/postgres_conf.md.erb +79 -79
  135. data/docs/resources/postgres_hba_conf.md.erb +93 -93
  136. data/docs/resources/postgres_ident_conf.md.erb +76 -76
  137. data/docs/resources/postgres_session.md.erb +69 -69
  138. data/docs/resources/powershell.md.erb +102 -102
  139. data/docs/resources/processes.md.erb +109 -109
  140. data/docs/resources/rabbitmq_config.md.erb +41 -41
  141. data/docs/resources/registry_key.md.erb +158 -158
  142. data/docs/resources/runit_service.md.erb +57 -57
  143. data/docs/resources/security_policy.md.erb +47 -47
  144. data/docs/resources/service.md.erb +121 -121
  145. data/docs/resources/shadow.md.erb +146 -146
  146. data/docs/resources/ssh_config.md.erb +73 -73
  147. data/docs/resources/sshd_config.md.erb +83 -83
  148. data/docs/resources/ssl.md.erb +119 -119
  149. data/docs/resources/sys_info.md.erb +42 -42
  150. data/docs/resources/systemd_service.md.erb +57 -57
  151. data/docs/resources/sysv_service.md.erb +57 -57
  152. data/docs/resources/upstart_service.md.erb +57 -57
  153. data/docs/resources/user.md.erb +140 -140
  154. data/docs/resources/users.md.erb +127 -127
  155. data/docs/resources/vbscript.md.erb +55 -55
  156. data/docs/resources/virtualization.md.erb +57 -57
  157. data/docs/resources/windows_feature.md.erb +47 -47
  158. data/docs/resources/windows_hotfix.md.erb +53 -53
  159. data/docs/resources/windows_task.md.erb +95 -95
  160. data/docs/resources/wmi.md.erb +81 -81
  161. data/docs/resources/x509_certificate.md.erb +151 -151
  162. data/docs/resources/xinetd_conf.md.erb +156 -156
  163. data/docs/resources/xml.md.erb +85 -85
  164. data/docs/resources/yaml.md.erb +69 -69
  165. data/docs/resources/yum.md.erb +98 -98
  166. data/docs/resources/zfs_dataset.md.erb +53 -53
  167. data/docs/resources/zfs_pool.md.erb +47 -47
  168. data/docs/ruby_usage.md +203 -203
  169. data/docs/shared/matcher_be.md.erb +1 -1
  170. data/docs/shared/matcher_cmp.md.erb +43 -43
  171. data/docs/shared/matcher_eq.md.erb +3 -3
  172. data/docs/shared/matcher_include.md.erb +1 -1
  173. data/docs/shared/matcher_match.md.erb +1 -1
  174. data/docs/shell.md +217 -217
  175. data/examples/README.md +8 -8
  176. data/examples/inheritance/README.md +65 -65
  177. data/examples/inheritance/controls/example.rb +14 -14
  178. data/examples/inheritance/inspec.yml +15 -15
  179. data/examples/kitchen-ansible/.kitchen.yml +25 -25
  180. data/examples/kitchen-ansible/Gemfile +19 -19
  181. data/examples/kitchen-ansible/README.md +53 -53
  182. data/examples/kitchen-ansible/files/nginx.repo +6 -6
  183. data/examples/kitchen-ansible/tasks/main.yml +16 -16
  184. data/examples/kitchen-ansible/test/integration/default/default.yml +5 -5
  185. data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -28
  186. data/examples/kitchen-chef/.kitchen.yml +20 -20
  187. data/examples/kitchen-chef/Berksfile +3 -3
  188. data/examples/kitchen-chef/Gemfile +19 -19
  189. data/examples/kitchen-chef/README.md +27 -27
  190. data/examples/kitchen-chef/metadata.rb +7 -7
  191. data/examples/kitchen-chef/recipes/default.rb +6 -6
  192. data/examples/kitchen-chef/recipes/nginx.rb +30 -30
  193. data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -28
  194. data/examples/kitchen-puppet/.kitchen.yml +23 -23
  195. data/examples/kitchen-puppet/Gemfile +20 -20
  196. data/examples/kitchen-puppet/Puppetfile +25 -25
  197. data/examples/kitchen-puppet/README.md +53 -53
  198. data/examples/kitchen-puppet/manifests/site.pp +33 -33
  199. data/examples/kitchen-puppet/metadata.json +11 -11
  200. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
  201. data/examples/meta-profile/README.md +37 -37
  202. data/examples/meta-profile/controls/example.rb +13 -13
  203. data/examples/meta-profile/inspec.yml +13 -13
  204. data/examples/profile-attribute.yml +2 -2
  205. data/examples/profile-attribute/README.md +14 -14
  206. data/examples/profile-attribute/controls/example.rb +11 -11
  207. data/examples/profile-attribute/inspec.yml +8 -8
  208. data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
  209. data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
  210. data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
  211. data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
  212. data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
  213. data/examples/profile-aws/inspec.yml +11 -11
  214. data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
  215. data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
  216. data/examples/profile-azure/inspec.yml +11 -11
  217. data/examples/profile-sensitive/README.md +29 -29
  218. data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
  219. data/examples/profile-sensitive/controls/sensitive.rb +9 -9
  220. data/examples/profile-sensitive/inspec.yml +8 -8
  221. data/examples/profile/README.md +48 -48
  222. data/examples/profile/controls/example.rb +23 -23
  223. data/examples/profile/controls/gordon.rb +36 -36
  224. data/examples/profile/controls/meta.rb +34 -34
  225. data/examples/profile/inspec.yml +10 -10
  226. data/examples/profile/libraries/gordon_config.rb +59 -59
  227. data/inspec.gemspec +49 -49
  228. data/lib/bundles/README.md +3 -3
  229. data/lib/bundles/inspec-artifact.rb +7 -7
  230. data/lib/bundles/inspec-artifact/README.md +1 -1
  231. data/lib/bundles/inspec-artifact/cli.rb +277 -277
  232. data/lib/bundles/inspec-compliance.rb +16 -16
  233. data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
  234. data/lib/bundles/inspec-compliance/README.md +193 -193
  235. data/lib/bundles/inspec-compliance/api.rb +360 -360
  236. data/lib/bundles/inspec-compliance/api/login.rb +193 -193
  237. data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
  238. data/lib/bundles/inspec-compliance/cli.rb +260 -260
  239. data/lib/bundles/inspec-compliance/configuration.rb +103 -103
  240. data/lib/bundles/inspec-compliance/http.rb +125 -125
  241. data/lib/bundles/inspec-compliance/support.rb +36 -36
  242. data/lib/bundles/inspec-compliance/target.rb +112 -112
  243. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
  244. data/lib/bundles/inspec-habitat.rb +12 -12
  245. data/lib/bundles/inspec-habitat/cli.rb +36 -36
  246. data/lib/bundles/inspec-habitat/log.rb +10 -10
  247. data/lib/bundles/inspec-habitat/profile.rb +391 -391
  248. data/lib/bundles/inspec-init.rb +8 -8
  249. data/lib/bundles/inspec-init/README.md +31 -31
  250. data/lib/bundles/inspec-init/cli.rb +97 -97
  251. data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
  252. data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
  253. data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
  254. data/lib/bundles/inspec-supermarket.rb +13 -13
  255. data/lib/bundles/inspec-supermarket/README.md +45 -45
  256. data/lib/bundles/inspec-supermarket/api.rb +84 -84
  257. data/lib/bundles/inspec-supermarket/cli.rb +73 -73
  258. data/lib/bundles/inspec-supermarket/target.rb +34 -34
  259. data/lib/fetchers/git.rb +163 -163
  260. data/lib/fetchers/local.rb +74 -74
  261. data/lib/fetchers/mock.rb +35 -35
  262. data/lib/fetchers/url.rb +247 -247
  263. data/lib/inspec.rb +24 -24
  264. data/lib/inspec/archive/tar.rb +29 -29
  265. data/lib/inspec/archive/zip.rb +19 -19
  266. data/lib/inspec/backend.rb +93 -93
  267. data/lib/inspec/base_cli.rb +368 -368
  268. data/lib/inspec/cached_fetcher.rb +66 -66
  269. data/lib/inspec/cli.rb +292 -292
  270. data/lib/inspec/completions/bash.sh.erb +45 -45
  271. data/lib/inspec/completions/fish.sh.erb +34 -34
  272. data/lib/inspec/completions/zsh.sh.erb +61 -61
  273. data/lib/inspec/control_eval_context.rb +179 -179
  274. data/lib/inspec/dependencies/cache.rb +72 -72
  275. data/lib/inspec/dependencies/dependency_set.rb +92 -92
  276. data/lib/inspec/dependencies/lockfile.rb +115 -115
  277. data/lib/inspec/dependencies/requirement.rb +123 -123
  278. data/lib/inspec/dependencies/resolver.rb +86 -86
  279. data/lib/inspec/describe.rb +27 -27
  280. data/lib/inspec/dsl.rb +66 -66
  281. data/lib/inspec/dsl_shared.rb +33 -33
  282. data/lib/inspec/env_printer.rb +157 -157
  283. data/lib/inspec/errors.rb +14 -14
  284. data/lib/inspec/exceptions.rb +12 -12
  285. data/lib/inspec/expect.rb +45 -45
  286. data/lib/inspec/fetcher.rb +45 -45
  287. data/lib/inspec/file_provider.rb +275 -275
  288. data/lib/inspec/formatters.rb +3 -3
  289. data/lib/inspec/formatters/base.rb +259 -259
  290. data/lib/inspec/formatters/json_rspec.rb +20 -20
  291. data/lib/inspec/formatters/show_progress.rb +12 -12
  292. data/lib/inspec/library_eval_context.rb +58 -58
  293. data/lib/inspec/log.rb +11 -11
  294. data/lib/inspec/metadata.rb +247 -247
  295. data/lib/inspec/method_source.rb +24 -24
  296. data/lib/inspec/objects.rb +14 -14
  297. data/lib/inspec/objects/attribute.rb +75 -75
  298. data/lib/inspec/objects/control.rb +61 -61
  299. data/lib/inspec/objects/describe.rb +92 -92
  300. data/lib/inspec/objects/each_loop.rb +36 -36
  301. data/lib/inspec/objects/list.rb +15 -15
  302. data/lib/inspec/objects/or_test.rb +40 -40
  303. data/lib/inspec/objects/ruby_helper.rb +15 -15
  304. data/lib/inspec/objects/tag.rb +27 -27
  305. data/lib/inspec/objects/test.rb +87 -87
  306. data/lib/inspec/objects/value.rb +27 -27
  307. data/lib/inspec/plugins.rb +60 -60
  308. data/lib/inspec/plugins/cli.rb +24 -24
  309. data/lib/inspec/plugins/fetcher.rb +86 -86
  310. data/lib/inspec/plugins/resource.rb +135 -135
  311. data/lib/inspec/plugins/secret.rb +15 -15
  312. data/lib/inspec/plugins/source_reader.rb +40 -40
  313. data/lib/inspec/polyfill.rb +12 -12
  314. data/lib/inspec/profile.rb +513 -513
  315. data/lib/inspec/profile_context.rb +208 -208
  316. data/lib/inspec/profile_vendor.rb +66 -66
  317. data/lib/inspec/reporters.rb +60 -60
  318. data/lib/inspec/reporters/automate.rb +76 -76
  319. data/lib/inspec/reporters/base.rb +25 -25
  320. data/lib/inspec/reporters/cli.rb +356 -356
  321. data/lib/inspec/reporters/json.rb +117 -117
  322. data/lib/inspec/reporters/json_min.rb +48 -48
  323. data/lib/inspec/reporters/junit.rb +78 -78
  324. data/lib/inspec/require_loader.rb +33 -33
  325. data/lib/inspec/resource.rb +190 -190
  326. data/lib/inspec/rule.rb +280 -280
  327. data/lib/inspec/runner.rb +345 -345
  328. data/lib/inspec/runner_mock.rb +41 -41
  329. data/lib/inspec/runner_rspec.rb +175 -175
  330. data/lib/inspec/runtime_profile.rb +26 -26
  331. data/lib/inspec/schema.rb +213 -213
  332. data/lib/inspec/secrets.rb +19 -19
  333. data/lib/inspec/secrets/yaml.rb +30 -30
  334. data/lib/inspec/shell.rb +220 -220
  335. data/lib/inspec/shell_detector.rb +90 -90
  336. data/lib/inspec/source_reader.rb +29 -29
  337. data/lib/inspec/version.rb +8 -8
  338. data/lib/matchers/matchers.rb +339 -339
  339. data/lib/resource_support/aws.rb +50 -50
  340. data/lib/resource_support/aws/aws_backend_base.rb +12 -12
  341. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
  342. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
  343. data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
  344. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
  345. data/lib/resources/aide_conf.rb +151 -151
  346. data/lib/resources/apache.rb +48 -48
  347. data/lib/resources/apache_conf.rb +149 -149
  348. data/lib/resources/apt.rb +149 -149
  349. data/lib/resources/audit_policy.rb +63 -63
  350. data/lib/resources/auditd.rb +231 -231
  351. data/lib/resources/auditd_conf.rb +46 -46
  352. data/lib/resources/aws/aws_cloudtrail_trail.rb +93 -93
  353. data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
  354. data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
  355. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
  356. data/lib/resources/aws/aws_config_delivery_channel.rb +70 -70
  357. data/lib/resources/aws/aws_config_recorder.rb +93 -93
  358. data/lib/resources/aws/aws_ec2_instance.rb +157 -157
  359. data/lib/resources/aws/aws_ec2_instances.rb +64 -64
  360. data/lib/resources/aws/aws_iam_access_key.rb +106 -106
  361. data/lib/resources/aws/aws_iam_access_keys.rb +149 -149
  362. data/lib/resources/aws/aws_iam_group.rb +58 -58
  363. data/lib/resources/aws/aws_iam_groups.rb +52 -52
  364. data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
  365. data/lib/resources/aws/aws_iam_policies.rb +53 -53
  366. data/lib/resources/aws/aws_iam_policy.rb +291 -291
  367. data/lib/resources/aws/aws_iam_role.rb +55 -55
  368. data/lib/resources/aws/aws_iam_root_user.rb +78 -78
  369. data/lib/resources/aws/aws_iam_user.rb +142 -142
  370. data/lib/resources/aws/aws_iam_users.rb +146 -146
  371. data/lib/resources/aws/aws_kms_key.rb +96 -96
  372. data/lib/resources/aws/aws_kms_keys.rb +53 -53
  373. data/lib/resources/aws/aws_rds_instance.rb +71 -71
  374. data/lib/resources/aws/aws_route_table.rb +63 -63
  375. data/lib/resources/aws/aws_route_tables.rb +60 -60
  376. data/lib/resources/aws/aws_s3_bucket.rb +137 -137
  377. data/lib/resources/aws/aws_s3_bucket_object.rb +82 -82
  378. data/lib/resources/aws/aws_s3_buckets.rb +51 -51
  379. data/lib/resources/aws/aws_security_group.rb +249 -249
  380. data/lib/resources/aws/aws_security_groups.rb +68 -68
  381. data/lib/resources/aws/aws_sns_subscription.rb +78 -78
  382. data/lib/resources/aws/aws_sns_topic.rb +53 -53
  383. data/lib/resources/aws/aws_sns_topics.rb +56 -56
  384. data/lib/resources/aws/aws_subnet.rb +88 -88
  385. data/lib/resources/aws/aws_subnets.rb +53 -53
  386. data/lib/resources/aws/aws_vpc.rb +73 -73
  387. data/lib/resources/aws/aws_vpcs.rb +52 -52
  388. data/lib/resources/azure/azure_backend.rb +377 -377
  389. data/lib/resources/azure/azure_generic_resource.rb +59 -59
  390. data/lib/resources/azure/azure_resource_group.rb +152 -152
  391. data/lib/resources/azure/azure_virtual_machine.rb +264 -264
  392. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +134 -134
  393. data/lib/resources/bash.rb +35 -35
  394. data/lib/resources/bond.rb +69 -69
  395. data/lib/resources/bridge.rb +122 -122
  396. data/lib/resources/chocolatey_package.rb +78 -78
  397. data/lib/resources/command.rb +73 -73
  398. data/lib/resources/cpan.rb +58 -58
  399. data/lib/resources/cran.rb +64 -64
  400. data/lib/resources/crontab.rb +169 -169
  401. data/lib/resources/csv.rb +56 -56
  402. data/lib/resources/dh_params.rb +77 -77
  403. data/lib/resources/directory.rb +25 -25
  404. data/lib/resources/docker.rb +236 -236
  405. data/lib/resources/docker_container.rb +89 -89
  406. data/lib/resources/docker_image.rb +83 -83
  407. data/lib/resources/docker_object.rb +57 -57
  408. data/lib/resources/docker_service.rb +90 -90
  409. data/lib/resources/elasticsearch.rb +169 -169
  410. data/lib/resources/etc_fstab.rb +94 -94
  411. data/lib/resources/etc_group.rb +154 -154
  412. data/lib/resources/etc_hosts.rb +66 -66
  413. data/lib/resources/etc_hosts_allow_deny.rb +112 -112
  414. data/lib/resources/file.rb +298 -298
  415. data/lib/resources/filesystem.rb +31 -31
  416. data/lib/resources/firewalld.rb +143 -143
  417. data/lib/resources/gem.rb +70 -70
  418. data/lib/resources/groups.rb +215 -215
  419. data/lib/resources/grub_conf.rb +227 -227
  420. data/lib/resources/host.rb +306 -306
  421. data/lib/resources/http.rb +253 -253
  422. data/lib/resources/iis_app.rb +101 -101
  423. data/lib/resources/iis_site.rb +148 -148
  424. data/lib/resources/inetd_conf.rb +54 -54
  425. data/lib/resources/ini.rb +29 -29
  426. data/lib/resources/interface.rb +129 -129
  427. data/lib/resources/iptables.rb +80 -80
  428. data/lib/resources/json.rb +111 -111
  429. data/lib/resources/kernel_module.rb +107 -107
  430. data/lib/resources/kernel_parameter.rb +58 -58
  431. data/lib/resources/key_rsa.rb +63 -63
  432. data/lib/resources/limits_conf.rb +46 -46
  433. data/lib/resources/login_def.rb +57 -57
  434. data/lib/resources/mount.rb +88 -88
  435. data/lib/resources/mssql_session.rb +101 -101
  436. data/lib/resources/mysql.rb +82 -82
  437. data/lib/resources/mysql_conf.rb +127 -127
  438. data/lib/resources/mysql_session.rb +85 -85
  439. data/lib/resources/nginx.rb +96 -96
  440. data/lib/resources/nginx_conf.rb +226 -226
  441. data/lib/resources/npm.rb +48 -48
  442. data/lib/resources/ntp_conf.rb +51 -51
  443. data/lib/resources/oneget.rb +71 -71
  444. data/lib/resources/oracledb_session.rb +139 -139
  445. data/lib/resources/os.rb +36 -36
  446. data/lib/resources/os_env.rb +86 -86
  447. data/lib/resources/package.rb +370 -370
  448. data/lib/resources/packages.rb +111 -111
  449. data/lib/resources/parse_config.rb +112 -112
  450. data/lib/resources/passwd.rb +76 -76
  451. data/lib/resources/pip.rb +130 -130
  452. data/lib/resources/platform.rb +109 -109
  453. data/lib/resources/port.rb +771 -771
  454. data/lib/resources/postgres.rb +131 -131
  455. data/lib/resources/postgres_conf.rb +114 -114
  456. data/lib/resources/postgres_hba_conf.rb +90 -90
  457. data/lib/resources/postgres_ident_conf.rb +79 -79
  458. data/lib/resources/postgres_session.rb +71 -71
  459. data/lib/resources/powershell.rb +67 -67
  460. data/lib/resources/processes.rb +204 -204
  461. data/lib/resources/rabbitmq_conf.rb +51 -51
  462. data/lib/resources/registry_key.rb +297 -297
  463. data/lib/resources/security_policy.rb +180 -180
  464. data/lib/resources/service.rb +794 -794
  465. data/lib/resources/shadow.rb +159 -159
  466. data/lib/resources/ssh_conf.rb +97 -97
  467. data/lib/resources/ssl.rb +99 -99
  468. data/lib/resources/sys_info.rb +28 -28
  469. data/lib/resources/toml.rb +32 -32
  470. data/lib/resources/users.rb +654 -654
  471. data/lib/resources/vbscript.rb +68 -68
  472. data/lib/resources/virtualization.rb +247 -247
  473. data/lib/resources/windows_feature.rb +84 -84
  474. data/lib/resources/windows_hotfix.rb +35 -35
  475. data/lib/resources/windows_task.rb +102 -102
  476. data/lib/resources/wmi.rb +110 -110
  477. data/lib/resources/x509_certificate.rb +137 -137
  478. data/lib/resources/xinetd.rb +106 -106
  479. data/lib/resources/xml.rb +46 -46
  480. data/lib/resources/yaml.rb +43 -43
  481. data/lib/resources/yum.rb +180 -180
  482. data/lib/resources/zfs_dataset.rb +60 -60
  483. data/lib/resources/zfs_pool.rb +49 -49
  484. data/lib/source_readers/flat.rb +39 -39
  485. data/lib/source_readers/inspec.rb +75 -75
  486. data/lib/utils/command_wrapper.rb +27 -27
  487. data/lib/utils/convert.rb +12 -12
  488. data/lib/utils/database_helpers.rb +77 -77
  489. data/lib/utils/enumerable_delegation.rb +9 -9
  490. data/lib/utils/erlang_parser.rb +192 -192
  491. data/lib/utils/file_reader.rb +25 -25
  492. data/lib/utils/filter.rb +273 -273
  493. data/lib/utils/filter_array.rb +27 -27
  494. data/lib/utils/find_files.rb +47 -47
  495. data/lib/utils/hash.rb +41 -41
  496. data/lib/utils/json_log.rb +18 -18
  497. data/lib/utils/latest_version.rb +22 -22
  498. data/lib/utils/modulator.rb +12 -12
  499. data/lib/utils/nginx_parser.rb +105 -105
  500. data/lib/utils/object_traversal.rb +49 -49
  501. data/lib/utils/parser.rb +274 -274
  502. data/lib/utils/pkey_reader.rb +15 -15
  503. data/lib/utils/plugin_registry.rb +93 -93
  504. data/lib/utils/simpleconfig.rb +120 -120
  505. data/lib/utils/spdx.rb +13 -13
  506. data/lib/utils/spdx.txt +343 -343
  507. metadata +3 -3
@@ -1,116 +1,116 @@
1
- # author: Viktor Yakovlyev
2
- class AwsIamPasswordPolicy < Inspec.resource(1)
3
- name 'aws_iam_password_policy'
4
- desc 'Verifies iam password policy'
5
-
6
- example <<-EOX
7
- describe aws_iam_password_policy do
8
- its('requires_lowercase_characters?') { should be true }
9
- end
10
-
11
- describe aws_iam_password_policy do
12
- its('requires_uppercase_characters?') { should be true }
13
- end
14
- EOX
15
- supports platform: 'aws'
16
-
17
- # TODO: rewrite to avoid direct injection, match other resources, use AwsSingularResourceMixin
18
- def initialize(conn = nil)
19
- catch_aws_errors do
20
- begin
21
- if conn
22
- # We're in a mocked unit test.
23
- @policy = conn.iam_resource.account_password_policy
24
- else
25
- # Don't use the resource approach. It's a CRUD operation
26
- # - if the policy does not exist, you get back a blank object to populate and save.
27
- # Using the Client will throw an exception if no policy exists.
28
- @policy = inspec_runner.backend.aws_client(Aws::IAM::Client).get_account_password_policy.password_policy
29
- end
30
- rescue Aws::IAM::Errors::NoSuchEntity
31
- @policy = nil
32
- end
33
- end
34
- end
35
-
36
- # TODO: DRY up, see https://github.com/chef/inspec/issues/2633
37
- # Copied from resource_support/aws/aws_resource_mixin.rb
38
- def catch_aws_errors
39
- yield
40
- rescue Aws::Errors::MissingCredentialsError
41
- # The AWS error here is unhelpful:
42
- # "unable to sign request without credentials set"
43
- Inspec::Log.error "It appears that you have not set your AWS credentials. You may set them using environment variables, or using the 'aws://region/aws_credentials_profile' target. See https://www.inspec.io/docs/reference/platforms for details."
44
- fail_resource('No AWS credentials available')
45
- rescue Aws::Errors::ServiceError => e
46
- fail_resource e.message
47
- end
48
-
49
- # TODO: DRY up, see https://github.com/chef/inspec/issues/2633
50
- # Copied from resource_support/aws/aws_singular_resource_mixin.rb
51
- def inspec_runner
52
- # When running under inspec-cli, we have an 'inspec' method that
53
- # returns the runner. When running under unit tests, we don't
54
- # have that, but we still have to call this to pass something
55
- # (nil is OK) to the backend.
56
- # TODO: remove with https://github.com/chef/inspec-aws/issues/216
57
- # TODO: remove after rewrite to include AwsSingularResource
58
- inspec if respond_to?(:inspec)
59
- end
60
-
61
- def to_s
62
- 'IAM Password-Policy'
63
- end
64
-
65
- def exists?
66
- !@policy.nil?
67
- end
68
-
69
- #-------------------------- Properties ----------------------------#
70
-
71
- def minimum_password_length
72
- @policy.minimum_password_length
73
- end
74
-
75
- def max_password_age_in_days
76
- raise 'this policy does not expire passwords' unless expire_passwords?
77
- @policy.max_password_age
78
- end
79
-
80
- def number_of_passwords_to_remember
81
- raise 'this policy does not prevent password reuse' \
82
- unless prevent_password_reuse?
83
- @policy.password_reuse_prevention
84
- end
85
-
86
- #-------------------------- Matchers ----------------------------#
87
- [
88
- :require_lowercase_characters,
89
- :require_uppercase_characters,
90
- :require_symbols,
91
- :require_numbers,
92
- :expire_passwords,
93
- ].each do |matcher_stem|
94
- # Create our predicates (for example, 'require_symbols?')
95
- stem_with_question_mark = (matcher_stem.to_s + '?').to_sym
96
- define_method stem_with_question_mark do
97
- @policy.send(matcher_stem)
98
- end
99
- # RSpec will expose that as (for example) `be_require_symbols`.
100
- # To undo that, we have to make a matcher alias.
101
- stem_with_be = ('be_' + matcher_stem.to_s).to_sym
102
- RSpec::Matchers.alias_matcher matcher_stem, stem_with_be
103
- end
104
-
105
- # This one has an awkward name mapping
106
- def allow_users_to_change_passwords?
107
- @policy.allow_users_to_change_password
108
- end
109
- RSpec::Matchers.alias_matcher :allow_users_to_change_passwords, :be_allow_users_to_change_passwords
110
-
111
- # This one has custom logic and renaming
112
- def prevent_password_reuse?
113
- !@policy.password_reuse_prevention.nil?
114
- end
115
- RSpec::Matchers.alias_matcher :prevent_password_reuse, :be_prevent_password_reuse
116
- end
1
+ # author: Viktor Yakovlyev
2
+ class AwsIamPasswordPolicy < Inspec.resource(1)
3
+ name 'aws_iam_password_policy'
4
+ desc 'Verifies iam password policy'
5
+
6
+ example <<-EOX
7
+ describe aws_iam_password_policy do
8
+ its('requires_lowercase_characters?') { should be true }
9
+ end
10
+
11
+ describe aws_iam_password_policy do
12
+ its('requires_uppercase_characters?') { should be true }
13
+ end
14
+ EOX
15
+ supports platform: 'aws'
16
+
17
+ # TODO: rewrite to avoid direct injection, match other resources, use AwsSingularResourceMixin
18
+ def initialize(conn = nil)
19
+ catch_aws_errors do
20
+ begin
21
+ if conn
22
+ # We're in a mocked unit test.
23
+ @policy = conn.iam_resource.account_password_policy
24
+ else
25
+ # Don't use the resource approach. It's a CRUD operation
26
+ # - if the policy does not exist, you get back a blank object to populate and save.
27
+ # Using the Client will throw an exception if no policy exists.
28
+ @policy = inspec_runner.backend.aws_client(Aws::IAM::Client).get_account_password_policy.password_policy
29
+ end
30
+ rescue Aws::IAM::Errors::NoSuchEntity
31
+ @policy = nil
32
+ end
33
+ end
34
+ end
35
+
36
+ # TODO: DRY up, see https://github.com/chef/inspec/issues/2633
37
+ # Copied from resource_support/aws/aws_resource_mixin.rb
38
+ def catch_aws_errors
39
+ yield
40
+ rescue Aws::Errors::MissingCredentialsError
41
+ # The AWS error here is unhelpful:
42
+ # "unable to sign request without credentials set"
43
+ Inspec::Log.error "It appears that you have not set your AWS credentials. You may set them using environment variables, or using the 'aws://region/aws_credentials_profile' target. See https://www.inspec.io/docs/reference/platforms for details."
44
+ fail_resource('No AWS credentials available')
45
+ rescue Aws::Errors::ServiceError => e
46
+ fail_resource e.message
47
+ end
48
+
49
+ # TODO: DRY up, see https://github.com/chef/inspec/issues/2633
50
+ # Copied from resource_support/aws/aws_singular_resource_mixin.rb
51
+ def inspec_runner
52
+ # When running under inspec-cli, we have an 'inspec' method that
53
+ # returns the runner. When running under unit tests, we don't
54
+ # have that, but we still have to call this to pass something
55
+ # (nil is OK) to the backend.
56
+ # TODO: remove with https://github.com/chef/inspec-aws/issues/216
57
+ # TODO: remove after rewrite to include AwsSingularResource
58
+ inspec if respond_to?(:inspec)
59
+ end
60
+
61
+ def to_s
62
+ 'IAM Password-Policy'
63
+ end
64
+
65
+ def exists?
66
+ !@policy.nil?
67
+ end
68
+
69
+ #-------------------------- Properties ----------------------------#
70
+
71
+ def minimum_password_length
72
+ @policy.minimum_password_length
73
+ end
74
+
75
+ def max_password_age_in_days
76
+ raise 'this policy does not expire passwords' unless expire_passwords?
77
+ @policy.max_password_age
78
+ end
79
+
80
+ def number_of_passwords_to_remember
81
+ raise 'this policy does not prevent password reuse' \
82
+ unless prevent_password_reuse?
83
+ @policy.password_reuse_prevention
84
+ end
85
+
86
+ #-------------------------- Matchers ----------------------------#
87
+ [
88
+ :require_lowercase_characters,
89
+ :require_uppercase_characters,
90
+ :require_symbols,
91
+ :require_numbers,
92
+ :expire_passwords,
93
+ ].each do |matcher_stem|
94
+ # Create our predicates (for example, 'require_symbols?')
95
+ stem_with_question_mark = (matcher_stem.to_s + '?').to_sym
96
+ define_method stem_with_question_mark do
97
+ @policy.send(matcher_stem)
98
+ end
99
+ # RSpec will expose that as (for example) `be_require_symbols`.
100
+ # To undo that, we have to make a matcher alias.
101
+ stem_with_be = ('be_' + matcher_stem.to_s).to_sym
102
+ RSpec::Matchers.alias_matcher matcher_stem, stem_with_be
103
+ end
104
+
105
+ # This one has an awkward name mapping
106
+ def allow_users_to_change_passwords?
107
+ @policy.allow_users_to_change_password
108
+ end
109
+ RSpec::Matchers.alias_matcher :allow_users_to_change_passwords, :be_allow_users_to_change_passwords
110
+
111
+ # This one has custom logic and renaming
112
+ def prevent_password_reuse?
113
+ !@policy.password_reuse_prevention.nil?
114
+ end
115
+ RSpec::Matchers.alias_matcher :prevent_password_reuse, :be_prevent_password_reuse
116
+ end
@@ -1,53 +1,53 @@
1
- class AwsIamPolicies < Inspec.resource(1)
2
- name 'aws_iam_policies'
3
- desc 'Verifies settings for AWS IAM Policies in bulk'
4
- example '
5
- describe aws_iam_policies do
6
- it { should exist }
7
- end
8
- '
9
- supports platform: 'aws'
10
-
11
- include AwsPluralResourceMixin
12
- def validate_params(resource_params)
13
- unless resource_params.empty?
14
- raise ArgumentError, 'aws_iam_policies does not accept resource parameters.'
15
- end
16
- resource_params
17
- end
18
-
19
- # Underlying FilterTable implementation.
20
- filter = FilterTable.create
21
- filter.add_accessor(:entries)
22
- .add(:exists?) { |x| !x.entries.empty? }
23
- .add(:policy_names, field: :policy_name)
24
- .add(:arns, field: :arn)
25
- filter.connect(self, :table)
26
-
27
- def to_s
28
- 'IAM Policies'
29
- end
30
-
31
- def fetch_from_api
32
- backend = BackendFactory.create(inspec_runner)
33
- @table = []
34
- pagination_opts = {}
35
- loop do
36
- api_result = backend.list_policies(pagination_opts)
37
- @table += api_result.policies.map(&:to_h)
38
- pagination_opts = { marker: api_result.marker }
39
- break unless api_result.is_truncated
40
- end
41
- end
42
-
43
- class Backend
44
- class AwsClientApi < AwsBackendBase
45
- BackendFactory.set_default_backend(self)
46
- self.aws_client_class = Aws::IAM::Client
47
-
48
- def list_policies(query)
49
- aws_service_client.list_policies(query)
50
- end
51
- end
52
- end
53
- end
1
+ class AwsIamPolicies < Inspec.resource(1)
2
+ name 'aws_iam_policies'
3
+ desc 'Verifies settings for AWS IAM Policies in bulk'
4
+ example '
5
+ describe aws_iam_policies do
6
+ it { should exist }
7
+ end
8
+ '
9
+ supports platform: 'aws'
10
+
11
+ include AwsPluralResourceMixin
12
+ def validate_params(resource_params)
13
+ unless resource_params.empty?
14
+ raise ArgumentError, 'aws_iam_policies does not accept resource parameters.'
15
+ end
16
+ resource_params
17
+ end
18
+
19
+ # Underlying FilterTable implementation.
20
+ filter = FilterTable.create
21
+ filter.add_accessor(:entries)
22
+ .add(:exists?) { |x| !x.entries.empty? }
23
+ .add(:policy_names, field: :policy_name)
24
+ .add(:arns, field: :arn)
25
+ filter.connect(self, :table)
26
+
27
+ def to_s
28
+ 'IAM Policies'
29
+ end
30
+
31
+ def fetch_from_api
32
+ backend = BackendFactory.create(inspec_runner)
33
+ @table = []
34
+ pagination_opts = {}
35
+ loop do
36
+ api_result = backend.list_policies(pagination_opts)
37
+ @table += api_result.policies.map(&:to_h)
38
+ pagination_opts = { marker: api_result.marker }
39
+ break unless api_result.is_truncated
40
+ end
41
+ end
42
+
43
+ class Backend
44
+ class AwsClientApi < AwsBackendBase
45
+ BackendFactory.set_default_backend(self)
46
+ self.aws_client_class = Aws::IAM::Client
47
+
48
+ def list_policies(query)
49
+ aws_service_client.list_policies(query)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,291 +1,291 @@
1
- require 'json'
2
- require 'set'
3
- require 'uri'
4
-
5
- class AwsIamPolicy < Inspec.resource(1)
6
- name 'aws_iam_policy'
7
- desc 'Verifies settings for individual AWS IAM Policy'
8
- example "
9
- describe aws_iam_policy('AWSSupportAccess') do
10
- it { should be_attached }
11
- end
12
- "
13
- supports platform: 'aws'
14
-
15
- include AwsSingularResourceMixin
16
-
17
- attr_reader :arn, :attachment_count, :default_version_id
18
-
19
- EXPECTED_CRITERIA = %w{
20
- Action
21
- Effect
22
- Resource
23
- Sid
24
- }.freeze
25
-
26
- UNIMPLEMENTED_CRITERIA = %w{
27
- Conditional
28
- NotAction
29
- NotPrincipal
30
- NotResource
31
- Principal
32
- }.freeze
33
-
34
- def to_s
35
- "Policy #{@policy_name}"
36
- end
37
-
38
- def attached?
39
- !attachment_count.zero?
40
- end
41
-
42
- def attached_users
43
- return @attached_users if defined? @attached_users
44
- fetch_attached_entities
45
- @attached_users
46
- end
47
-
48
- def attached_groups
49
- return @attached_groups if defined? @attached_groups
50
- fetch_attached_entities
51
- @attached_groups
52
- end
53
-
54
- def attached_roles
55
- return @attached_roles if defined? @attached_roles
56
- fetch_attached_entities
57
- @attached_roles
58
- end
59
-
60
- def attached_to_user?(user_name)
61
- attached_users.include?(user_name)
62
- end
63
-
64
- def attached_to_group?(group_name)
65
- attached_groups.include?(group_name)
66
- end
67
-
68
- def attached_to_role?(role_name)
69
- attached_roles.include?(role_name)
70
- end
71
-
72
- def policy
73
- return nil unless exists?
74
- return @policy if defined?(@policy)
75
-
76
- catch_aws_errors do
77
- backend = BackendFactory.create(inspec_runner)
78
- gpv_response = backend.get_policy_version(policy_arn: arn, version_id: default_version_id)
79
- @policy = JSON.parse(URI.decode_www_form_component(gpv_response.policy_version.document))
80
- end
81
- @policy
82
- end
83
-
84
- def statement_count
85
- return nil unless exists?
86
- # Typically it is an array of statements
87
- if policy['Statement'].is_a? Array
88
- policy['Statement'].count
89
- else
90
- # But if there is one statement, it is permissable to degenerate the array,
91
- # and place the statement as a hash directly under the 'Statement' key
92
- return 1
93
- end
94
- end
95
-
96
- def has_statement?(provided_criteria = {})
97
- return nil unless exists?
98
- raw_criteria = provided_criteria.dup # provided_criteria is used for output formatting - can't delete from it.
99
- criteria = has_statement__normalize_criteria(has_statement__validate_criteria(raw_criteria))
100
- @normalized_statements ||= has_statement__normalize_statements
101
- statements = has_statement__focus_on_sid(@normalized_statements, criteria)
102
- statements.any? do |statement|
103
- true && \
104
- has_statement__effect(statement, criteria) && \
105
- has_statement__array_criterion(:action, statement, criteria) && \
106
- has_statement__array_criterion(:resource, statement, criteria)
107
- end
108
- end
109
-
110
- private
111
-
112
- def has_statement__validate_criteria(raw_criteria)
113
- recognized_criteria = {}
114
- EXPECTED_CRITERIA.each do |expected_criterion|
115
- if raw_criteria.key?(expected_criterion)
116
- recognized_criteria[expected_criterion] = raw_criteria.delete(expected_criterion)
117
- end
118
- end
119
-
120
- # Special message for valid, but unimplemented statement attributes
121
- UNIMPLEMENTED_CRITERIA.each do |unimplemented_criterion|
122
- if raw_criteria.key?(unimplemented_criterion)
123
- raise ArgumentError, "Criterion '#{unimplemented_criterion}' is not supported for performing have_statement queries."
124
- end
125
- end
126
-
127
- # If anything is left, it's spurious
128
- unless raw_criteria.empty?
129
- raise ArgumentError, "Unrecognized criteria #{raw_criteria.keys.join(', ')} to have_statement. Recognized criteria: #{EXPECTED_CRITERIA.join(', ')}"
130
- end
131
-
132
- # Effect has only 2 permitted values
133
- if recognized_criteria.key?('Effect')
134
- unless %w{Allow Deny}.include?(recognized_criteria['Effect'])
135
- raise ArgumentError, "Criterion 'Effect' for have_statement must be one of 'Allow' or 'Deny' - got '#{recognized_criteria['Effect']}'"
136
- end
137
- end
138
-
139
- recognized_criteria
140
- end
141
-
142
- def has_statement__normalize_criteria(criteria)
143
- # Transform keys into lowercase symbols
144
- criteria.keys.each do |provided_key|
145
- criteria[provided_key.downcase.to_sym] = criteria.delete(provided_key)
146
- end
147
-
148
- criteria
149
- end
150
-
151
- def has_statement__normalize_statements
152
- # Some single-statement policies place their statement
153
- # directly in policy['Statement'], rather than in an
154
- # Array within it. See arn:aws:iam::aws:policy/AWSCertificateManagerReadOnly
155
- # Thus, coerce to Array.
156
- policy['Statement'] = [policy['Statement']] if policy['Statement'].is_a? Hash
157
- policy['Statement'].map do |statement|
158
- # Coerce some values into arrays
159
- %w{Action Resource}.each do |field|
160
- if statement.key?(field)
161
- statement[field] = Array(statement[field])
162
- end
163
- end
164
-
165
- # Symbolize all keys
166
- statement.keys.each do |field|
167
- statement[field.downcase.to_sym] = statement.delete(field)
168
- end
169
-
170
- statement
171
- end
172
- end
173
-
174
- def has_statement__focus_on_sid(statements, criteria)
175
- return statements unless criteria.key?(:sid)
176
- sid_seek = criteria[:sid]
177
- statements.select do |statement|
178
- if sid_seek.is_a? Regexp
179
- statement[:sid] =~ sid_seek
180
- else
181
- statement[:sid] == sid_seek
182
- end
183
- end
184
- end
185
-
186
- def has_statement__effect(statement, criteria)
187
- !criteria.key?(:effect) || criteria[:effect] == statement[:effect]
188
- end
189
-
190
- def has_statement__array_criterion(crit_name, statement, criteria)
191
- return true unless criteria.key?(crit_name)
192
- check = criteria[crit_name]
193
- # This is an array due to normalize_statements
194
- # If it is nil, the statement does not have an entry for that dimension;
195
- # but since we were asked to match on it (on nothing), we
196
- # decide to never match
197
- values = statement[crit_name]
198
- return false if values.nil?
199
-
200
- if check.is_a?(String)
201
- # If check is a string, it only has to match one of the values
202
- values.any? { |v| v == check }
203
- elsif check.is_a?(Regexp)
204
- # If check is a regex, it only has to match one of the values
205
- values.any? { |v| v =~ check }
206
- elsif check.is_a?(Array) && check.all? { |c| c.is_a? String }
207
- # If check is an array of strings, perform setwise check
208
- Set.new(values) == Set.new(check)
209
- elsif check.is_a?(Array) && check.all? { |c| c.is_a? Regexp }
210
- # If check is an array of regexes, all values must match all regexes
211
- values.all? { |v| check.all? { |r| v =~ r } }
212
- else
213
- false
214
- end
215
- end
216
-
217
- def validate_params(raw_params)
218
- validated_params = check_resource_param_names(
219
- raw_params: raw_params,
220
- allowed_params: [:policy_name],
221
- allowed_scalar_name: :policy_name,
222
- allowed_scalar_type: String,
223
- )
224
-
225
- if validated_params.empty?
226
- raise ArgumentError, "You must provide the parameter 'policy_name' to aws_iam_policy."
227
- end
228
-
229
- validated_params
230
- end
231
-
232
- def fetch_from_api
233
- backend = BackendFactory.create(inspec_runner)
234
-
235
- policy = nil
236
- pagination_opts = { max_items: 1000 }
237
- loop do
238
- api_result = backend.list_policies(pagination_opts)
239
- policy = api_result.policies.detect do |p|
240
- p.policy_name == @policy_name
241
- end
242
- break if policy # Found it!
243
- break unless api_result.is_truncated # Not found and no more results
244
- pagination_opts[:marker] = api_result.marker
245
- end
246
-
247
- @exists = !policy.nil?
248
-
249
- return unless @exists
250
- @arn = policy[:arn]
251
- @default_version_id = policy[:default_version_id]
252
- @attachment_count = policy[:attachment_count]
253
- end
254
-
255
- def fetch_attached_entities
256
- unless @exists
257
- @attached_groups = nil
258
- @attached_users = nil
259
- @attached_roles = nil
260
- return
261
- end
262
- backend = AwsIamPolicy::BackendFactory.create(inspec_runner)
263
- criteria = { policy_arn: arn }
264
- resp = nil
265
- catch_aws_errors do
266
- resp = backend.list_entities_for_policy(criteria)
267
- end
268
- @attached_groups = resp.policy_groups.map(&:group_name)
269
- @attached_users = resp.policy_users.map(&:user_name)
270
- @attached_roles = resp.policy_roles.map(&:role_name)
271
- end
272
-
273
- class Backend
274
- class AwsClientApi < AwsBackendBase
275
- BackendFactory.set_default_backend(self)
276
- self.aws_client_class = Aws::IAM::Client
277
-
278
- def get_policy_version(criteria)
279
- aws_service_client.get_policy_version(criteria)
280
- end
281
-
282
- def list_policies(criteria)
283
- aws_service_client.list_policies(criteria)
284
- end
285
-
286
- def list_entities_for_policy(criteria)
287
- aws_service_client.list_entities_for_policy(criteria)
288
- end
289
- end
290
- end
291
- end
1
+ require 'json'
2
+ require 'set'
3
+ require 'uri'
4
+
5
+ class AwsIamPolicy < Inspec.resource(1)
6
+ name 'aws_iam_policy'
7
+ desc 'Verifies settings for individual AWS IAM Policy'
8
+ example "
9
+ describe aws_iam_policy('AWSSupportAccess') do
10
+ it { should be_attached }
11
+ end
12
+ "
13
+ supports platform: 'aws'
14
+
15
+ include AwsSingularResourceMixin
16
+
17
+ attr_reader :arn, :attachment_count, :default_version_id
18
+
19
+ EXPECTED_CRITERIA = %w{
20
+ Action
21
+ Effect
22
+ Resource
23
+ Sid
24
+ }.freeze
25
+
26
+ UNIMPLEMENTED_CRITERIA = %w{
27
+ Conditional
28
+ NotAction
29
+ NotPrincipal
30
+ NotResource
31
+ Principal
32
+ }.freeze
33
+
34
+ def to_s
35
+ "Policy #{@policy_name}"
36
+ end
37
+
38
+ def attached?
39
+ !attachment_count.zero?
40
+ end
41
+
42
+ def attached_users
43
+ return @attached_users if defined? @attached_users
44
+ fetch_attached_entities
45
+ @attached_users
46
+ end
47
+
48
+ def attached_groups
49
+ return @attached_groups if defined? @attached_groups
50
+ fetch_attached_entities
51
+ @attached_groups
52
+ end
53
+
54
+ def attached_roles
55
+ return @attached_roles if defined? @attached_roles
56
+ fetch_attached_entities
57
+ @attached_roles
58
+ end
59
+
60
+ def attached_to_user?(user_name)
61
+ attached_users.include?(user_name)
62
+ end
63
+
64
+ def attached_to_group?(group_name)
65
+ attached_groups.include?(group_name)
66
+ end
67
+
68
+ def attached_to_role?(role_name)
69
+ attached_roles.include?(role_name)
70
+ end
71
+
72
+ def policy
73
+ return nil unless exists?
74
+ return @policy if defined?(@policy)
75
+
76
+ catch_aws_errors do
77
+ backend = BackendFactory.create(inspec_runner)
78
+ gpv_response = backend.get_policy_version(policy_arn: arn, version_id: default_version_id)
79
+ @policy = JSON.parse(URI.decode_www_form_component(gpv_response.policy_version.document))
80
+ end
81
+ @policy
82
+ end
83
+
84
+ def statement_count
85
+ return nil unless exists?
86
+ # Typically it is an array of statements
87
+ if policy['Statement'].is_a? Array
88
+ policy['Statement'].count
89
+ else
90
+ # But if there is one statement, it is permissable to degenerate the array,
91
+ # and place the statement as a hash directly under the 'Statement' key
92
+ return 1
93
+ end
94
+ end
95
+
96
+ def has_statement?(provided_criteria = {})
97
+ return nil unless exists?
98
+ raw_criteria = provided_criteria.dup # provided_criteria is used for output formatting - can't delete from it.
99
+ criteria = has_statement__normalize_criteria(has_statement__validate_criteria(raw_criteria))
100
+ @normalized_statements ||= has_statement__normalize_statements
101
+ statements = has_statement__focus_on_sid(@normalized_statements, criteria)
102
+ statements.any? do |statement|
103
+ true && \
104
+ has_statement__effect(statement, criteria) && \
105
+ has_statement__array_criterion(:action, statement, criteria) && \
106
+ has_statement__array_criterion(:resource, statement, criteria)
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ def has_statement__validate_criteria(raw_criteria)
113
+ recognized_criteria = {}
114
+ EXPECTED_CRITERIA.each do |expected_criterion|
115
+ if raw_criteria.key?(expected_criterion)
116
+ recognized_criteria[expected_criterion] = raw_criteria.delete(expected_criterion)
117
+ end
118
+ end
119
+
120
+ # Special message for valid, but unimplemented statement attributes
121
+ UNIMPLEMENTED_CRITERIA.each do |unimplemented_criterion|
122
+ if raw_criteria.key?(unimplemented_criterion)
123
+ raise ArgumentError, "Criterion '#{unimplemented_criterion}' is not supported for performing have_statement queries."
124
+ end
125
+ end
126
+
127
+ # If anything is left, it's spurious
128
+ unless raw_criteria.empty?
129
+ raise ArgumentError, "Unrecognized criteria #{raw_criteria.keys.join(', ')} to have_statement. Recognized criteria: #{EXPECTED_CRITERIA.join(', ')}"
130
+ end
131
+
132
+ # Effect has only 2 permitted values
133
+ if recognized_criteria.key?('Effect')
134
+ unless %w{Allow Deny}.include?(recognized_criteria['Effect'])
135
+ raise ArgumentError, "Criterion 'Effect' for have_statement must be one of 'Allow' or 'Deny' - got '#{recognized_criteria['Effect']}'"
136
+ end
137
+ end
138
+
139
+ recognized_criteria
140
+ end
141
+
142
+ def has_statement__normalize_criteria(criteria)
143
+ # Transform keys into lowercase symbols
144
+ criteria.keys.each do |provided_key|
145
+ criteria[provided_key.downcase.to_sym] = criteria.delete(provided_key)
146
+ end
147
+
148
+ criteria
149
+ end
150
+
151
+ def has_statement__normalize_statements
152
+ # Some single-statement policies place their statement
153
+ # directly in policy['Statement'], rather than in an
154
+ # Array within it. See arn:aws:iam::aws:policy/AWSCertificateManagerReadOnly
155
+ # Thus, coerce to Array.
156
+ policy['Statement'] = [policy['Statement']] if policy['Statement'].is_a? Hash
157
+ policy['Statement'].map do |statement|
158
+ # Coerce some values into arrays
159
+ %w{Action Resource}.each do |field|
160
+ if statement.key?(field)
161
+ statement[field] = Array(statement[field])
162
+ end
163
+ end
164
+
165
+ # Symbolize all keys
166
+ statement.keys.each do |field|
167
+ statement[field.downcase.to_sym] = statement.delete(field)
168
+ end
169
+
170
+ statement
171
+ end
172
+ end
173
+
174
+ def has_statement__focus_on_sid(statements, criteria)
175
+ return statements unless criteria.key?(:sid)
176
+ sid_seek = criteria[:sid]
177
+ statements.select do |statement|
178
+ if sid_seek.is_a? Regexp
179
+ statement[:sid] =~ sid_seek
180
+ else
181
+ statement[:sid] == sid_seek
182
+ end
183
+ end
184
+ end
185
+
186
+ def has_statement__effect(statement, criteria)
187
+ !criteria.key?(:effect) || criteria[:effect] == statement[:effect]
188
+ end
189
+
190
+ def has_statement__array_criterion(crit_name, statement, criteria)
191
+ return true unless criteria.key?(crit_name)
192
+ check = criteria[crit_name]
193
+ # This is an array due to normalize_statements
194
+ # If it is nil, the statement does not have an entry for that dimension;
195
+ # but since we were asked to match on it (on nothing), we
196
+ # decide to never match
197
+ values = statement[crit_name]
198
+ return false if values.nil?
199
+
200
+ if check.is_a?(String)
201
+ # If check is a string, it only has to match one of the values
202
+ values.any? { |v| v == check }
203
+ elsif check.is_a?(Regexp)
204
+ # If check is a regex, it only has to match one of the values
205
+ values.any? { |v| v =~ check }
206
+ elsif check.is_a?(Array) && check.all? { |c| c.is_a? String }
207
+ # If check is an array of strings, perform setwise check
208
+ Set.new(values) == Set.new(check)
209
+ elsif check.is_a?(Array) && check.all? { |c| c.is_a? Regexp }
210
+ # If check is an array of regexes, all values must match all regexes
211
+ values.all? { |v| check.all? { |r| v =~ r } }
212
+ else
213
+ false
214
+ end
215
+ end
216
+
217
+ def validate_params(raw_params)
218
+ validated_params = check_resource_param_names(
219
+ raw_params: raw_params,
220
+ allowed_params: [:policy_name],
221
+ allowed_scalar_name: :policy_name,
222
+ allowed_scalar_type: String,
223
+ )
224
+
225
+ if validated_params.empty?
226
+ raise ArgumentError, "You must provide the parameter 'policy_name' to aws_iam_policy."
227
+ end
228
+
229
+ validated_params
230
+ end
231
+
232
+ def fetch_from_api
233
+ backend = BackendFactory.create(inspec_runner)
234
+
235
+ policy = nil
236
+ pagination_opts = { max_items: 1000 }
237
+ loop do
238
+ api_result = backend.list_policies(pagination_opts)
239
+ policy = api_result.policies.detect do |p|
240
+ p.policy_name == @policy_name
241
+ end
242
+ break if policy # Found it!
243
+ break unless api_result.is_truncated # Not found and no more results
244
+ pagination_opts[:marker] = api_result.marker
245
+ end
246
+
247
+ @exists = !policy.nil?
248
+
249
+ return unless @exists
250
+ @arn = policy[:arn]
251
+ @default_version_id = policy[:default_version_id]
252
+ @attachment_count = policy[:attachment_count]
253
+ end
254
+
255
+ def fetch_attached_entities
256
+ unless @exists
257
+ @attached_groups = nil
258
+ @attached_users = nil
259
+ @attached_roles = nil
260
+ return
261
+ end
262
+ backend = AwsIamPolicy::BackendFactory.create(inspec_runner)
263
+ criteria = { policy_arn: arn }
264
+ resp = nil
265
+ catch_aws_errors do
266
+ resp = backend.list_entities_for_policy(criteria)
267
+ end
268
+ @attached_groups = resp.policy_groups.map(&:group_name)
269
+ @attached_users = resp.policy_users.map(&:user_name)
270
+ @attached_roles = resp.policy_roles.map(&:role_name)
271
+ end
272
+
273
+ class Backend
274
+ class AwsClientApi < AwsBackendBase
275
+ BackendFactory.set_default_backend(self)
276
+ self.aws_client_class = Aws::IAM::Client
277
+
278
+ def get_policy_version(criteria)
279
+ aws_service_client.get_policy_version(criteria)
280
+ end
281
+
282
+ def list_policies(criteria)
283
+ aws_service_client.list_policies(criteria)
284
+ end
285
+
286
+ def list_entities_for_policy(criteria)
287
+ aws_service_client.list_entities_for_policy(criteria)
288
+ end
289
+ end
290
+ end
291
+ end