inspec 2.1.80 → 2.1.81

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 (510) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +101 -101
  3. data/CHANGELOG.md +3177 -3172
  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 +40 -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/modules/.gitkeep +0 -0
  201. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
  202. data/examples/meta-profile/README.md +37 -37
  203. data/examples/meta-profile/controls/example.rb +13 -13
  204. data/examples/meta-profile/inspec.yml +13 -13
  205. data/examples/profile-attribute.yml +2 -2
  206. data/examples/profile-attribute/README.md +14 -14
  207. data/examples/profile-attribute/controls/example.rb +11 -11
  208. data/examples/profile-attribute/inspec.yml +8 -8
  209. data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
  210. data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
  211. data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
  212. data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
  213. data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
  214. data/examples/profile-aws/inspec.yml +11 -11
  215. data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
  216. data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
  217. data/examples/profile-azure/inspec.yml +11 -11
  218. data/examples/profile-sensitive/README.md +29 -29
  219. data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
  220. data/examples/profile-sensitive/controls/sensitive.rb +9 -9
  221. data/examples/profile-sensitive/inspec.yml +8 -8
  222. data/examples/profile/README.md +48 -48
  223. data/examples/profile/controls/example.rb +23 -23
  224. data/examples/profile/controls/gordon.rb +36 -36
  225. data/examples/profile/controls/meta.rb +34 -34
  226. data/examples/profile/inspec.yml +10 -10
  227. data/examples/profile/libraries/gordon_config.rb +59 -59
  228. data/inspec.gemspec +49 -49
  229. data/lib/bundles/README.md +3 -3
  230. data/lib/bundles/inspec-artifact.rb +7 -7
  231. data/lib/bundles/inspec-artifact/README.md +1 -1
  232. data/lib/bundles/inspec-artifact/cli.rb +277 -277
  233. data/lib/bundles/inspec-compliance.rb +16 -16
  234. data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
  235. data/lib/bundles/inspec-compliance/README.md +193 -193
  236. data/lib/bundles/inspec-compliance/api.rb +360 -360
  237. data/lib/bundles/inspec-compliance/api/login.rb +193 -193
  238. data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
  239. data/lib/bundles/inspec-compliance/cli.rb +260 -260
  240. data/lib/bundles/inspec-compliance/configuration.rb +103 -103
  241. data/lib/bundles/inspec-compliance/http.rb +125 -125
  242. data/lib/bundles/inspec-compliance/images/cc-token.png +0 -0
  243. data/lib/bundles/inspec-compliance/support.rb +36 -36
  244. data/lib/bundles/inspec-compliance/target.rb +112 -112
  245. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
  246. data/lib/bundles/inspec-habitat.rb +12 -12
  247. data/lib/bundles/inspec-habitat/cli.rb +36 -36
  248. data/lib/bundles/inspec-habitat/log.rb +10 -10
  249. data/lib/bundles/inspec-habitat/profile.rb +391 -391
  250. data/lib/bundles/inspec-init.rb +8 -8
  251. data/lib/bundles/inspec-init/README.md +31 -31
  252. data/lib/bundles/inspec-init/cli.rb +97 -97
  253. data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
  254. data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
  255. data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
  256. data/lib/bundles/inspec-init/templates/profile/libraries/.gitkeep +0 -0
  257. data/lib/bundles/inspec-supermarket.rb +13 -13
  258. data/lib/bundles/inspec-supermarket/README.md +45 -45
  259. data/lib/bundles/inspec-supermarket/api.rb +84 -84
  260. data/lib/bundles/inspec-supermarket/cli.rb +73 -73
  261. data/lib/bundles/inspec-supermarket/target.rb +34 -34
  262. data/lib/fetchers/git.rb +163 -163
  263. data/lib/fetchers/local.rb +74 -74
  264. data/lib/fetchers/mock.rb +35 -35
  265. data/lib/fetchers/url.rb +247 -247
  266. data/lib/inspec.rb +24 -24
  267. data/lib/inspec/archive/tar.rb +29 -29
  268. data/lib/inspec/archive/zip.rb +19 -19
  269. data/lib/inspec/backend.rb +93 -93
  270. data/lib/inspec/base_cli.rb +368 -368
  271. data/lib/inspec/cached_fetcher.rb +66 -66
  272. data/lib/inspec/cli.rb +292 -292
  273. data/lib/inspec/completions/bash.sh.erb +45 -45
  274. data/lib/inspec/completions/fish.sh.erb +34 -34
  275. data/lib/inspec/completions/zsh.sh.erb +61 -61
  276. data/lib/inspec/control_eval_context.rb +179 -179
  277. data/lib/inspec/dependencies/cache.rb +72 -72
  278. data/lib/inspec/dependencies/dependency_set.rb +92 -92
  279. data/lib/inspec/dependencies/lockfile.rb +115 -115
  280. data/lib/inspec/dependencies/requirement.rb +123 -123
  281. data/lib/inspec/dependencies/resolver.rb +86 -86
  282. data/lib/inspec/describe.rb +27 -27
  283. data/lib/inspec/dsl.rb +66 -66
  284. data/lib/inspec/dsl_shared.rb +33 -33
  285. data/lib/inspec/env_printer.rb +157 -157
  286. data/lib/inspec/errors.rb +14 -14
  287. data/lib/inspec/exceptions.rb +12 -12
  288. data/lib/inspec/expect.rb +45 -45
  289. data/lib/inspec/fetcher.rb +45 -45
  290. data/lib/inspec/file_provider.rb +275 -275
  291. data/lib/inspec/formatters.rb +3 -3
  292. data/lib/inspec/formatters/base.rb +259 -259
  293. data/lib/inspec/formatters/json_rspec.rb +20 -20
  294. data/lib/inspec/formatters/show_progress.rb +12 -12
  295. data/lib/inspec/library_eval_context.rb +58 -58
  296. data/lib/inspec/log.rb +11 -11
  297. data/lib/inspec/metadata.rb +247 -247
  298. data/lib/inspec/method_source.rb +24 -24
  299. data/lib/inspec/objects.rb +14 -14
  300. data/lib/inspec/objects/attribute.rb +75 -75
  301. data/lib/inspec/objects/control.rb +61 -61
  302. data/lib/inspec/objects/describe.rb +92 -92
  303. data/lib/inspec/objects/each_loop.rb +36 -36
  304. data/lib/inspec/objects/list.rb +15 -15
  305. data/lib/inspec/objects/or_test.rb +40 -40
  306. data/lib/inspec/objects/ruby_helper.rb +15 -15
  307. data/lib/inspec/objects/tag.rb +27 -27
  308. data/lib/inspec/objects/test.rb +87 -87
  309. data/lib/inspec/objects/value.rb +27 -27
  310. data/lib/inspec/plugins.rb +60 -60
  311. data/lib/inspec/plugins/cli.rb +24 -24
  312. data/lib/inspec/plugins/fetcher.rb +86 -86
  313. data/lib/inspec/plugins/resource.rb +135 -135
  314. data/lib/inspec/plugins/secret.rb +15 -15
  315. data/lib/inspec/plugins/source_reader.rb +40 -40
  316. data/lib/inspec/polyfill.rb +12 -12
  317. data/lib/inspec/profile.rb +513 -513
  318. data/lib/inspec/profile_context.rb +208 -208
  319. data/lib/inspec/profile_vendor.rb +66 -66
  320. data/lib/inspec/reporters.rb +60 -60
  321. data/lib/inspec/reporters/automate.rb +76 -76
  322. data/lib/inspec/reporters/base.rb +25 -25
  323. data/lib/inspec/reporters/cli.rb +356 -356
  324. data/lib/inspec/reporters/json.rb +117 -117
  325. data/lib/inspec/reporters/json_min.rb +48 -48
  326. data/lib/inspec/reporters/junit.rb +78 -78
  327. data/lib/inspec/require_loader.rb +33 -33
  328. data/lib/inspec/resource.rb +190 -190
  329. data/lib/inspec/rule.rb +280 -280
  330. data/lib/inspec/runner.rb +345 -345
  331. data/lib/inspec/runner_mock.rb +41 -41
  332. data/lib/inspec/runner_rspec.rb +175 -175
  333. data/lib/inspec/runtime_profile.rb +26 -26
  334. data/lib/inspec/schema.rb +213 -213
  335. data/lib/inspec/secrets.rb +19 -19
  336. data/lib/inspec/secrets/yaml.rb +30 -30
  337. data/lib/inspec/shell.rb +220 -220
  338. data/lib/inspec/shell_detector.rb +90 -90
  339. data/lib/inspec/source_reader.rb +29 -29
  340. data/lib/inspec/version.rb +8 -8
  341. data/lib/matchers/matchers.rb +339 -339
  342. data/lib/resource_support/aws.rb +50 -50
  343. data/lib/resource_support/aws/aws_backend_base.rb +12 -12
  344. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
  345. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
  346. data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
  347. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
  348. data/lib/resources/aide_conf.rb +151 -151
  349. data/lib/resources/apache.rb +48 -48
  350. data/lib/resources/apache_conf.rb +149 -149
  351. data/lib/resources/apt.rb +149 -149
  352. data/lib/resources/audit_policy.rb +63 -63
  353. data/lib/resources/auditd.rb +231 -231
  354. data/lib/resources/auditd_conf.rb +46 -46
  355. data/lib/resources/aws/aws_cloudtrail_trail.rb +93 -93
  356. data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
  357. data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
  358. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
  359. data/lib/resources/aws/aws_config_delivery_channel.rb +70 -70
  360. data/lib/resources/aws/aws_config_recorder.rb +93 -93
  361. data/lib/resources/aws/aws_ec2_instance.rb +157 -157
  362. data/lib/resources/aws/aws_ec2_instances.rb +64 -64
  363. data/lib/resources/aws/aws_iam_access_key.rb +106 -106
  364. data/lib/resources/aws/aws_iam_access_keys.rb +149 -149
  365. data/lib/resources/aws/aws_iam_group.rb +58 -58
  366. data/lib/resources/aws/aws_iam_groups.rb +52 -52
  367. data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
  368. data/lib/resources/aws/aws_iam_policies.rb +53 -53
  369. data/lib/resources/aws/aws_iam_policy.rb +291 -291
  370. data/lib/resources/aws/aws_iam_role.rb +55 -55
  371. data/lib/resources/aws/aws_iam_root_user.rb +78 -78
  372. data/lib/resources/aws/aws_iam_user.rb +142 -142
  373. data/lib/resources/aws/aws_iam_users.rb +146 -146
  374. data/lib/resources/aws/aws_kms_key.rb +96 -96
  375. data/lib/resources/aws/aws_kms_keys.rb +53 -53
  376. data/lib/resources/aws/aws_rds_instance.rb +71 -71
  377. data/lib/resources/aws/aws_route_table.rb +63 -63
  378. data/lib/resources/aws/aws_route_tables.rb +60 -60
  379. data/lib/resources/aws/aws_s3_bucket.rb +137 -137
  380. data/lib/resources/aws/aws_s3_bucket_object.rb +82 -82
  381. data/lib/resources/aws/aws_s3_buckets.rb +51 -51
  382. data/lib/resources/aws/aws_security_group.rb +249 -249
  383. data/lib/resources/aws/aws_security_groups.rb +68 -68
  384. data/lib/resources/aws/aws_sns_subscription.rb +78 -78
  385. data/lib/resources/aws/aws_sns_topic.rb +53 -53
  386. data/lib/resources/aws/aws_sns_topics.rb +56 -56
  387. data/lib/resources/aws/aws_subnet.rb +88 -88
  388. data/lib/resources/aws/aws_subnets.rb +53 -53
  389. data/lib/resources/aws/aws_vpc.rb +73 -73
  390. data/lib/resources/aws/aws_vpcs.rb +52 -52
  391. data/lib/resources/azure/azure_backend.rb +377 -377
  392. data/lib/resources/azure/azure_generic_resource.rb +59 -59
  393. data/lib/resources/azure/azure_resource_group.rb +152 -152
  394. data/lib/resources/azure/azure_virtual_machine.rb +264 -264
  395. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +134 -134
  396. data/lib/resources/bash.rb +35 -35
  397. data/lib/resources/bond.rb +69 -69
  398. data/lib/resources/bridge.rb +122 -122
  399. data/lib/resources/chocolatey_package.rb +78 -78
  400. data/lib/resources/command.rb +73 -73
  401. data/lib/resources/cpan.rb +58 -58
  402. data/lib/resources/cran.rb +64 -64
  403. data/lib/resources/crontab.rb +169 -169
  404. data/lib/resources/csv.rb +56 -56
  405. data/lib/resources/dh_params.rb +77 -77
  406. data/lib/resources/directory.rb +25 -25
  407. data/lib/resources/docker.rb +236 -236
  408. data/lib/resources/docker_container.rb +89 -89
  409. data/lib/resources/docker_image.rb +83 -83
  410. data/lib/resources/docker_object.rb +57 -57
  411. data/lib/resources/docker_service.rb +90 -90
  412. data/lib/resources/elasticsearch.rb +169 -169
  413. data/lib/resources/etc_fstab.rb +94 -94
  414. data/lib/resources/etc_group.rb +154 -154
  415. data/lib/resources/etc_hosts.rb +66 -66
  416. data/lib/resources/etc_hosts_allow_deny.rb +112 -112
  417. data/lib/resources/file.rb +298 -298
  418. data/lib/resources/filesystem.rb +31 -31
  419. data/lib/resources/firewalld.rb +143 -143
  420. data/lib/resources/gem.rb +70 -70
  421. data/lib/resources/groups.rb +215 -215
  422. data/lib/resources/grub_conf.rb +227 -227
  423. data/lib/resources/host.rb +306 -306
  424. data/lib/resources/http.rb +253 -253
  425. data/lib/resources/iis_app.rb +101 -101
  426. data/lib/resources/iis_site.rb +148 -148
  427. data/lib/resources/inetd_conf.rb +54 -54
  428. data/lib/resources/ini.rb +29 -29
  429. data/lib/resources/interface.rb +129 -129
  430. data/lib/resources/iptables.rb +80 -80
  431. data/lib/resources/json.rb +111 -111
  432. data/lib/resources/kernel_module.rb +107 -107
  433. data/lib/resources/kernel_parameter.rb +58 -58
  434. data/lib/resources/key_rsa.rb +63 -63
  435. data/lib/resources/limits_conf.rb +46 -46
  436. data/lib/resources/login_def.rb +57 -57
  437. data/lib/resources/mount.rb +88 -88
  438. data/lib/resources/mssql_session.rb +101 -101
  439. data/lib/resources/mysql.rb +82 -82
  440. data/lib/resources/mysql_conf.rb +127 -127
  441. data/lib/resources/mysql_session.rb +85 -85
  442. data/lib/resources/nginx.rb +96 -96
  443. data/lib/resources/nginx_conf.rb +226 -226
  444. data/lib/resources/npm.rb +48 -48
  445. data/lib/resources/ntp_conf.rb +51 -51
  446. data/lib/resources/oneget.rb +71 -71
  447. data/lib/resources/oracledb_session.rb +139 -139
  448. data/lib/resources/os.rb +36 -36
  449. data/lib/resources/os_env.rb +86 -86
  450. data/lib/resources/package.rb +370 -370
  451. data/lib/resources/packages.rb +111 -111
  452. data/lib/resources/parse_config.rb +112 -112
  453. data/lib/resources/passwd.rb +76 -76
  454. data/lib/resources/pip.rb +130 -130
  455. data/lib/resources/platform.rb +109 -109
  456. data/lib/resources/port.rb +771 -771
  457. data/lib/resources/postgres.rb +131 -131
  458. data/lib/resources/postgres_conf.rb +114 -114
  459. data/lib/resources/postgres_hba_conf.rb +90 -90
  460. data/lib/resources/postgres_ident_conf.rb +79 -79
  461. data/lib/resources/postgres_session.rb +71 -71
  462. data/lib/resources/powershell.rb +67 -67
  463. data/lib/resources/processes.rb +204 -204
  464. data/lib/resources/rabbitmq_conf.rb +51 -51
  465. data/lib/resources/registry_key.rb +297 -297
  466. data/lib/resources/security_policy.rb +180 -180
  467. data/lib/resources/service.rb +794 -794
  468. data/lib/resources/shadow.rb +159 -159
  469. data/lib/resources/ssh_conf.rb +97 -97
  470. data/lib/resources/ssl.rb +99 -99
  471. data/lib/resources/sys_info.rb +28 -28
  472. data/lib/resources/toml.rb +32 -32
  473. data/lib/resources/users.rb +654 -654
  474. data/lib/resources/vbscript.rb +68 -68
  475. data/lib/resources/virtualization.rb +247 -247
  476. data/lib/resources/windows_feature.rb +84 -84
  477. data/lib/resources/windows_hotfix.rb +35 -35
  478. data/lib/resources/windows_task.rb +102 -102
  479. data/lib/resources/wmi.rb +110 -110
  480. data/lib/resources/x509_certificate.rb +137 -137
  481. data/lib/resources/xinetd.rb +106 -106
  482. data/lib/resources/xml.rb +46 -46
  483. data/lib/resources/yaml.rb +43 -43
  484. data/lib/resources/yum.rb +180 -180
  485. data/lib/resources/zfs_dataset.rb +60 -60
  486. data/lib/resources/zfs_pool.rb +49 -49
  487. data/lib/source_readers/flat.rb +39 -39
  488. data/lib/source_readers/inspec.rb +75 -75
  489. data/lib/utils/command_wrapper.rb +27 -27
  490. data/lib/utils/convert.rb +12 -12
  491. data/lib/utils/database_helpers.rb +77 -77
  492. data/lib/utils/enumerable_delegation.rb +9 -9
  493. data/lib/utils/erlang_parser.rb +192 -192
  494. data/lib/utils/file_reader.rb +25 -25
  495. data/lib/utils/filter.rb +273 -273
  496. data/lib/utils/filter_array.rb +27 -27
  497. data/lib/utils/find_files.rb +47 -47
  498. data/lib/utils/hash.rb +41 -41
  499. data/lib/utils/json_log.rb +18 -18
  500. data/lib/utils/latest_version.rb +22 -22
  501. data/lib/utils/modulator.rb +12 -12
  502. data/lib/utils/nginx_parser.rb +105 -105
  503. data/lib/utils/object_traversal.rb +49 -49
  504. data/lib/utils/parser.rb +274 -274
  505. data/lib/utils/pkey_reader.rb +15 -15
  506. data/lib/utils/plugin_registry.rb +93 -93
  507. data/lib/utils/simpleconfig.rb +120 -120
  508. data/lib/utils/spdx.rb +13 -13
  509. data/lib/utils/spdx.txt +343 -343
  510. 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