inspec 4.3.2 → 4.6.3

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 (368) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +36 -38
  3. data/README.md +37 -21
  4. data/etc/deprecations.json +10 -0
  5. data/etc/plugin_filters.json +8 -0
  6. data/inspec.gemspec +38 -39
  7. data/lib/bundles/inspec-compliance/api.rb +1 -1
  8. data/lib/bundles/inspec-compliance/configuration.rb +1 -1
  9. data/lib/bundles/inspec-compliance/http.rb +1 -1
  10. data/lib/bundles/inspec-compliance/support.rb +1 -1
  11. data/lib/bundles/inspec-compliance/target.rb +1 -1
  12. data/lib/bundles/inspec-supermarket.rb +3 -7
  13. data/lib/bundles/inspec-supermarket/api.rb +10 -13
  14. data/lib/bundles/inspec-supermarket/cli.rb +12 -15
  15. data/lib/bundles/inspec-supermarket/target.rb +7 -11
  16. data/lib/fetchers/git.rb +14 -15
  17. data/lib/fetchers/local.rb +6 -10
  18. data/lib/fetchers/mock.rb +3 -5
  19. data/lib/fetchers/url.rb +42 -44
  20. data/lib/inspec.rb +23 -24
  21. data/lib/inspec/archive/tar.rb +2 -6
  22. data/lib/inspec/archive/zip.rb +3 -7
  23. data/lib/inspec/backend.rb +8 -9
  24. data/lib/inspec/base_cli.rb +64 -65
  25. data/lib/inspec/cached_fetcher.rb +2 -3
  26. data/lib/inspec/cli.rb +136 -97
  27. data/lib/inspec/config.rb +71 -61
  28. data/lib/inspec/control_eval_context.rb +22 -18
  29. data/lib/inspec/dependencies/cache.rb +2 -3
  30. data/lib/inspec/dependencies/dependency_set.rb +2 -3
  31. data/lib/inspec/dependencies/lockfile.rb +8 -9
  32. data/lib/inspec/dependencies/requirement.rb +7 -8
  33. data/lib/inspec/dependencies/resolver.rb +5 -7
  34. data/lib/inspec/describe.rb +2 -6
  35. data/lib/inspec/dist.rb +20 -0
  36. data/lib/inspec/dsl.rb +4 -7
  37. data/lib/inspec/dsl_shared.rb +1 -2
  38. data/lib/inspec/env_printer.rb +11 -12
  39. data/lib/inspec/errors.rb +0 -4
  40. data/lib/inspec/exceptions.rb +0 -1
  41. data/lib/inspec/expect.rb +5 -8
  42. data/lib/inspec/fetcher.rb +7 -10
  43. data/lib/inspec/file_provider.rb +24 -24
  44. data/lib/inspec/formatters.rb +3 -3
  45. data/lib/inspec/formatters/base.rb +8 -8
  46. data/lib/inspec/globals.rb +2 -2
  47. data/lib/inspec/impact.rb +5 -7
  48. data/lib/inspec/input_registry.rb +84 -33
  49. data/lib/inspec/library_eval_context.rb +3 -6
  50. data/lib/inspec/log.rb +1 -5
  51. data/lib/inspec/metadata.rb +17 -16
  52. data/lib/inspec/method_source.rb +5 -9
  53. data/lib/inspec/objects.rb +10 -12
  54. data/lib/inspec/objects/control.rb +7 -9
  55. data/lib/inspec/objects/describe.rb +9 -11
  56. data/lib/inspec/objects/each_loop.rb +1 -3
  57. data/lib/inspec/objects/input.rb +24 -26
  58. data/lib/inspec/objects/list.rb +4 -6
  59. data/lib/inspec/objects/or_test.rb +2 -4
  60. data/lib/inspec/objects/ruby_helper.rb +3 -5
  61. data/lib/inspec/objects/tag.rb +0 -2
  62. data/lib/inspec/objects/test.rb +9 -11
  63. data/lib/inspec/objects/value.rb +3 -5
  64. data/lib/inspec/plugin/v1.rb +2 -2
  65. data/lib/inspec/plugin/v1/plugin_types/cli.rb +1 -5
  66. data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +2 -5
  67. data/lib/inspec/plugin/v1/plugin_types/resource.rb +4 -6
  68. data/lib/inspec/plugin/v1/plugin_types/secret.rb +1 -5
  69. data/lib/inspec/plugin/v1/plugin_types/source_reader.rb +1 -5
  70. data/lib/inspec/plugin/v1/plugins.rb +15 -19
  71. data/lib/inspec/plugin/v1/registry.rb +0 -4
  72. data/lib/inspec/plugin/v2.rb +8 -8
  73. data/lib/inspec/plugin/v2/activator.rb +1 -1
  74. data/lib/inspec/plugin/v2/config_file.rb +6 -6
  75. data/lib/inspec/plugin/v2/filter.rb +13 -13
  76. data/lib/inspec/plugin/v2/installer.rb +36 -24
  77. data/lib/inspec/plugin/v2/loader.rb +28 -28
  78. data/lib/inspec/plugin/v2/plugin_base.rb +15 -2
  79. data/lib/inspec/plugin/v2/plugin_types/cli.rb +5 -5
  80. data/lib/inspec/plugin/v2/plugin_types/input.rb +34 -0
  81. data/lib/inspec/plugin/v2/plugin_types/mock.rb +1 -1
  82. data/lib/inspec/plugin/v2/registry.rb +7 -7
  83. data/lib/inspec/polyfill.rb +0 -3
  84. data/lib/inspec/profile.rb +55 -63
  85. data/lib/inspec/profile_context.rb +27 -30
  86. data/lib/inspec/profile_vendor.rb +6 -9
  87. data/lib/inspec/reporters.rb +24 -24
  88. data/lib/inspec/reporters/automate.rb +17 -19
  89. data/lib/inspec/reporters/base.rb +1 -1
  90. data/lib/inspec/reporters/cli.rb +88 -91
  91. data/lib/inspec/reporters/json.rb +2 -4
  92. data/lib/inspec/reporters/json_automate.rb +1 -3
  93. data/lib/inspec/reporters/json_min.rb +1 -3
  94. data/lib/inspec/reporters/junit.rb +26 -28
  95. data/lib/inspec/reporters/yaml.rb +1 -3
  96. data/lib/inspec/require_loader.rb +0 -4
  97. data/lib/inspec/resource.rb +4 -125
  98. data/lib/inspec/resources.rb +121 -0
  99. data/lib/{resources → inspec/resources}/aide_conf.rb +24 -25
  100. data/lib/{resources → inspec/resources}/apache.rb +13 -14
  101. data/lib/{resources → inspec/resources}/apache_conf.rb +16 -17
  102. data/lib/{resources → inspec/resources}/apt.rb +17 -17
  103. data/lib/{resources → inspec/resources}/audit_policy.rb +7 -6
  104. data/lib/{resources → inspec/resources}/auditd.rb +62 -64
  105. data/lib/{resources → inspec/resources}/auditd_conf.rb +7 -8
  106. data/lib/{resources → inspec/resources}/bash.rb +6 -8
  107. data/lib/{resources → inspec/resources}/bond.rb +15 -14
  108. data/lib/{resources → inspec/resources}/bridge.rb +8 -8
  109. data/lib/{resources → inspec/resources}/chocolatey_package.rb +10 -8
  110. data/lib/{resources → inspec/resources}/command.rb +11 -10
  111. data/lib/{resources → inspec/resources}/cpan.rb +12 -12
  112. data/lib/{resources → inspec/resources}/cran.rb +9 -9
  113. data/lib/{resources → inspec/resources}/crontab.rb +47 -48
  114. data/lib/{resources → inspec/resources}/csv.rb +5 -5
  115. data/lib/{resources → inspec/resources}/dh_params.rb +5 -7
  116. data/lib/{resources → inspec/resources}/directory.rb +5 -7
  117. data/lib/{resources → inspec/resources}/docker.rb +63 -63
  118. data/lib/{resources → inspec/resources}/docker_container.rb +6 -6
  119. data/lib/{resources → inspec/resources}/docker_image.rb +9 -9
  120. data/lib/{resources → inspec/resources}/docker_object.rb +8 -13
  121. data/lib/{resources → inspec/resources}/docker_plugin.rb +6 -6
  122. data/lib/{resources → inspec/resources}/docker_service.rb +7 -7
  123. data/lib/{resources → inspec/resources}/elasticsearch.rb +40 -42
  124. data/lib/{resources → inspec/resources}/etc_fstab.rb +23 -24
  125. data/lib/{resources → inspec/resources}/etc_group.rb +26 -27
  126. data/lib/{resources → inspec/resources}/etc_hosts.rb +11 -13
  127. data/lib/{resources → inspec/resources}/etc_hosts_allow_deny.rb +25 -27
  128. data/lib/{resources → inspec/resources}/file.rb +80 -79
  129. data/lib/{resources → inspec/resources}/filesystem.rb +20 -15
  130. data/lib/{resources → inspec/resources}/firewalld.rb +26 -26
  131. data/lib/{resources → inspec/resources}/gem.rb +12 -12
  132. data/lib/{resources → inspec/resources}/groups.rb +28 -27
  133. data/lib/{resources → inspec/resources}/grub_conf.rb +46 -48
  134. data/lib/{resources → inspec/resources}/host.rb +31 -29
  135. data/lib/{resources → inspec/resources}/http.rb +24 -24
  136. data/lib/{resources → inspec/resources}/iis_app.rb +6 -7
  137. data/lib/{resources → inspec/resources}/iis_app_pool.rb +21 -19
  138. data/lib/{resources → inspec/resources}/iis_site.rb +17 -15
  139. data/lib/{resources → inspec/resources}/inetd_conf.rb +9 -10
  140. data/lib/{resources → inspec/resources}/ini.rb +7 -8
  141. data/lib/{resources → inspec/resources}/interface.rb +30 -30
  142. data/lib/{resources → inspec/resources}/iptables.rb +8 -8
  143. data/lib/{resources → inspec/resources}/json.rb +8 -10
  144. data/lib/{resources → inspec/resources}/kernel_module.rb +15 -15
  145. data/lib/{resources → inspec/resources}/kernel_parameter.rb +8 -8
  146. data/lib/{resources → inspec/resources}/key_rsa.rb +8 -10
  147. data/lib/{resources → inspec/resources}/ksh.rb +6 -8
  148. data/lib/{resources → inspec/resources}/limits_conf.rb +8 -9
  149. data/lib/{resources/login_def.rb → inspec/resources/login_defs.rb} +9 -10
  150. data/lib/{resources → inspec/resources}/mount.rb +6 -8
  151. data/lib/{resources → inspec/resources}/mssql_session.rb +16 -18
  152. data/lib/inspec/resources/mysql.rb +81 -0
  153. data/lib/{resources → inspec/resources}/mysql_conf.rb +13 -14
  154. data/lib/{resources → inspec/resources}/mysql_session.rb +16 -16
  155. data/lib/{resources → inspec/resources}/nginx.rb +16 -17
  156. data/lib/{resources → inspec/resources}/nginx_conf.rb +26 -27
  157. data/lib/{resources → inspec/resources}/npm.rb +9 -10
  158. data/lib/{resources → inspec/resources}/ntp_conf.rb +9 -10
  159. data/lib/{resources → inspec/resources}/oneget.rb +8 -8
  160. data/lib/{resources → inspec/resources}/oracledb_session.rb +33 -34
  161. data/lib/{resources → inspec/resources}/os.rb +6 -8
  162. data/lib/{resources → inspec/resources}/os_env.rb +11 -12
  163. data/lib/{resources → inspec/resources}/package.rb +66 -65
  164. data/lib/{resources → inspec/resources}/packages.rb +13 -13
  165. data/lib/{resources → inspec/resources}/parse_config.rb +8 -8
  166. data/lib/{resources → inspec/resources}/passwd.rb +18 -19
  167. data/lib/{resources → inspec/resources}/pip.rb +19 -19
  168. data/lib/{resources → inspec/resources}/platform.rb +9 -11
  169. data/lib/{resources → inspec/resources}/port.rb +134 -136
  170. data/lib/{resources → inspec/resources}/postgres.rb +40 -32
  171. data/lib/{resources → inspec/resources}/postgres_conf.rb +17 -17
  172. data/lib/{resources → inspec/resources}/postgres_hba_conf.rb +21 -23
  173. data/lib/{resources → inspec/resources}/postgres_ident_conf.rb +12 -14
  174. data/lib/{resources → inspec/resources}/postgres_session.rb +8 -9
  175. data/lib/{resources → inspec/resources}/powershell.rb +17 -13
  176. data/lib/{resources → inspec/resources}/processes.rb +29 -29
  177. data/lib/{resources/rabbitmq_conf.rb → inspec/resources/rabbitmq_config.rb} +10 -11
  178. data/lib/{resources → inspec/resources}/registry_key.rb +14 -14
  179. data/lib/inspec/resources/script.rb +1 -0
  180. data/lib/{resources → inspec/resources}/security_identifier.rb +11 -10
  181. data/lib/{resources → inspec/resources}/security_policy.rb +59 -58
  182. data/lib/{resources → inspec/resources}/service.rb +74 -75
  183. data/lib/{resources → inspec/resources}/shadow.rb +44 -45
  184. data/lib/{resources/ssh_conf.rb → inspec/resources/ssh_config.rb} +16 -17
  185. data/lib/{resources → inspec/resources}/ssl.rb +28 -29
  186. data/lib/inspec/resources/sys_info.rb +30 -0
  187. data/lib/{resources → inspec/resources}/toml.rb +5 -7
  188. data/lib/{resources → inspec/resources}/users.rb +65 -65
  189. data/lib/{resources → inspec/resources}/vbscript.rb +8 -9
  190. data/lib/{resources → inspec/resources}/virtualization.rb +60 -62
  191. data/lib/{resources → inspec/resources}/windows_feature.rb +9 -9
  192. data/lib/{resources → inspec/resources}/windows_hotfix.rb +5 -5
  193. data/lib/{resources → inspec/resources}/windows_task.rb +16 -15
  194. data/lib/{resources → inspec/resources}/wmi.rb +7 -8
  195. data/lib/{resources → inspec/resources}/x509_certificate.rb +9 -11
  196. data/lib/{resources/xinetd.rb → inspec/resources/xinetd_conf.rb} +27 -29
  197. data/lib/{resources → inspec/resources}/xml.rb +7 -7
  198. data/lib/{resources → inspec/resources}/yaml.rb +5 -6
  199. data/lib/{resources → inspec/resources}/yum.rb +10 -10
  200. data/lib/{resources → inspec/resources}/zfs_dataset.rb +6 -6
  201. data/lib/{resources → inspec/resources}/zfs_pool.rb +4 -4
  202. data/lib/inspec/rspec_extensions.rb +24 -8
  203. data/lib/inspec/rule.rb +14 -15
  204. data/lib/inspec/runner.rb +28 -28
  205. data/lib/inspec/runner_mock.rb +1 -5
  206. data/lib/inspec/runner_rspec.rb +18 -20
  207. data/lib/inspec/runtime_profile.rb +2 -5
  208. data/lib/inspec/schema.rb +142 -143
  209. data/lib/inspec/secrets.rb +3 -7
  210. data/lib/inspec/secrets/yaml.rb +3 -5
  211. data/lib/inspec/shell.rb +11 -15
  212. data/lib/inspec/shell_detector.rb +6 -7
  213. data/lib/inspec/source_reader.rb +4 -8
  214. data/lib/inspec/ui.rb +33 -39
  215. data/lib/inspec/ui_table_helper.rb +12 -0
  216. data/lib/{utils → inspec/utils}/command_wrapper.rb +4 -8
  217. data/lib/{utils → inspec/utils}/convert.rb +0 -4
  218. data/lib/{utils → inspec/utils}/database_helpers.rb +4 -8
  219. data/lib/inspec/utils/deprecation.rb +6 -0
  220. data/lib/{utils → inspec/utils}/deprecation/config_file.rb +19 -19
  221. data/lib/{utils → inspec/utils}/deprecation/deprecator.rb +12 -12
  222. data/lib/{utils → inspec/utils}/deprecation/errors.rb +1 -1
  223. data/lib/{utils → inspec/utils}/deprecation/global_method.rb +2 -2
  224. data/lib/{utils → inspec/utils}/enumerable_delegation.rb +0 -2
  225. data/lib/{utils → inspec/utils}/erlang_parser.rb +61 -65
  226. data/lib/{utils → inspec/utils}/file_reader.rb +1 -2
  227. data/lib/{utils → inspec/utils}/filter.rb +30 -33
  228. data/lib/{utils → inspec/utils}/filter_array.rb +0 -2
  229. data/lib/{utils → inspec/utils}/find_files.rb +9 -12
  230. data/lib/{utils → inspec/utils}/hash.rb +1 -5
  231. data/lib/inspec/utils/json_log.rb +15 -0
  232. data/lib/inspec/utils/latest_version.rb +13 -0
  233. data/lib/{utils → inspec/utils}/modulator.rb +0 -3
  234. data/lib/{utils → inspec/utils}/nginx_parser.rb +31 -35
  235. data/lib/{utils → inspec/utils}/object_traversal.rb +0 -3
  236. data/lib/{utils → inspec/utils}/parser.rb +45 -45
  237. data/lib/{utils → inspec/utils}/pkey_reader.rb +4 -2
  238. data/lib/{utils → inspec/utils}/simpleconfig.rb +8 -10
  239. data/lib/{utils → inspec/utils}/spdx.rb +1 -4
  240. data/lib/{utils → inspec/utils}/spdx.txt +0 -0
  241. data/lib/inspec/utils/telemetry.rb +3 -3
  242. data/lib/inspec/utils/telemetry/collector.rb +30 -9
  243. data/lib/inspec/utils/telemetry/data_series.rb +3 -1
  244. data/lib/inspec/utils/telemetry/global_methods.rb +1 -1
  245. data/lib/inspec/version.rb +1 -1
  246. data/lib/matchers/matchers.rb +22 -25
  247. data/lib/plugins/inspec-artifact/lib/inspec-artifact.rb +1 -1
  248. data/lib/plugins/inspec-artifact/lib/inspec-artifact/base.rb +52 -45
  249. data/lib/plugins/inspec-artifact/lib/inspec-artifact/cli.rb +18 -16
  250. data/lib/plugins/inspec-artifact/test/functional/inspec_artifact_test.rb +12 -11
  251. data/lib/plugins/inspec-compliance/lib/inspec-compliance.rb +1 -1
  252. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +73 -73
  253. data/lib/plugins/inspec-compliance/lib/inspec-compliance/api/login.rb +66 -62
  254. data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +59 -57
  255. data/lib/plugins/inspec-compliance/lib/inspec-compliance/configuration.rb +11 -11
  256. data/lib/plugins/inspec-compliance/lib/inspec-compliance/http.rb +20 -22
  257. data/lib/plugins/inspec-compliance/lib/inspec-compliance/support.rb +2 -4
  258. data/lib/plugins/inspec-compliance/lib/inspec-compliance/target.rb +30 -27
  259. data/lib/plugins/inspec-compliance/test/functional/inspec_compliance_test.rb +12 -14
  260. data/lib/plugins/inspec-compliance/test/integration/default/cli.rb +39 -41
  261. data/lib/plugins/inspec-compliance/test/unit/api/login_test.rb +64 -64
  262. data/lib/plugins/inspec-compliance/test/unit/api_test.rb +157 -156
  263. data/lib/plugins/inspec-compliance/test/unit/target_test.rb +85 -85
  264. data/lib/plugins/inspec-habitat/Berksfile +2 -2
  265. data/lib/plugins/inspec-habitat/lib/inspec-habitat.rb +1 -1
  266. data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +15 -13
  267. data/lib/plugins/inspec-habitat/lib/inspec-habitat/profile.rb +64 -63
  268. data/lib/plugins/inspec-habitat/templates/habitat/hooks/run.erb +3 -3
  269. data/lib/plugins/inspec-habitat/templates/habitat/plan.sh.erb +11 -11
  270. data/lib/plugins/inspec-habitat/test/cookbooks/inspec_habitat_fixture/Berksfile +1 -1
  271. data/lib/plugins/inspec-habitat/test/cookbooks/inspec_habitat_fixture/metadata.rb +8 -8
  272. data/lib/plugins/inspec-habitat/test/cookbooks/inspec_habitat_fixture/recipes/default.rb +17 -17
  273. data/lib/plugins/inspec-habitat/test/functional/inspec_habitat_test.rb +9 -8
  274. data/lib/plugins/inspec-habitat/test/integration/default/inspec_habitat/controls/inspec_habitat.rb +14 -14
  275. data/lib/plugins/inspec-habitat/test/support/example_profile/controls/example.rb +4 -4
  276. data/lib/plugins/inspec-habitat/test/unit/profile_test.rb +42 -41
  277. data/lib/plugins/inspec-init/lib/inspec-init.rb +1 -1
  278. data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +6 -8
  279. data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +72 -74
  280. data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +9 -11
  281. data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +4 -4
  282. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Gemfile +0 -1
  283. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec +0 -2
  284. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template.rb +0 -2
  285. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/cli_command.rb +0 -2
  286. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.rb +0 -2
  287. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/version.rb +0 -2
  288. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/functional/inspec_plugin_template_test.rb +5 -5
  289. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/helper.rb +1 -3
  290. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/unit/cli_args_test.rb +2 -2
  291. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/unit/plugin_def_test.rb +2 -2
  292. data/lib/plugins/inspec-init/templates/profiles/aws/controls/example.rb +10 -11
  293. data/lib/plugins/inspec-init/templates/profiles/azure/controls/example.rb +4 -5
  294. data/lib/plugins/inspec-init/templates/profiles/gcp/controls/example.rb +10 -11
  295. data/lib/plugins/inspec-init/templates/profiles/os/controls/example.rb +6 -7
  296. data/lib/plugins/inspec-init/test/functional/inspec_init_plugin_test.rb +51 -50
  297. data/lib/plugins/inspec-init/test/functional/inspec_init_profile_test.rb +35 -33
  298. data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli.rb +1 -2
  299. data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +72 -70
  300. data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/plugin.rb +1 -1
  301. data/lib/plugins/inspec-plugin-manager-cli/test/fixtures/plugins/wrong-name/lib/wrong-name.rb +1 -1
  302. data/lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb +281 -271
  303. data/lib/plugins/inspec-plugin-manager-cli/test/unit/cli_args_test.rb +41 -41
  304. data/lib/plugins/inspec-plugin-manager-cli/test/unit/plugin_def_test.rb +25 -6
  305. data/lib/plugins/shared/core_plugin_test_helper.rb +43 -38
  306. data/lib/resource_support/aws.rb +67 -67
  307. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +4 -1
  308. data/lib/resource_support/aws/aws_resource_mixin.rb +4 -3
  309. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +4 -1
  310. data/lib/resources/aws/aws_billing_report.rb +15 -8
  311. data/lib/resources/aws/aws_billing_reports.rb +10 -7
  312. data/lib/resources/aws/aws_cloudtrail_trail.rb +9 -5
  313. data/lib/resources/aws/aws_cloudtrail_trails.rb +9 -5
  314. data/lib/resources/aws/aws_cloudwatch_alarm.rb +9 -5
  315. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +12 -8
  316. data/lib/resources/aws/aws_config_delivery_channel.rb +13 -9
  317. data/lib/resources/aws/aws_config_recorder.rb +10 -6
  318. data/lib/resources/aws/aws_ebs_volume.rb +12 -8
  319. data/lib/resources/aws/aws_ebs_volumes.rb +9 -5
  320. data/lib/resources/aws/aws_ec2_instance.rb +14 -11
  321. data/lib/resources/aws/aws_ec2_instances.rb +9 -5
  322. data/lib/resources/aws/aws_ecs_cluster.rb +11 -7
  323. data/lib/resources/aws/aws_eks_cluster.rb +13 -9
  324. data/lib/resources/aws/aws_elb.rb +9 -5
  325. data/lib/resources/aws/aws_elbs.rb +9 -5
  326. data/lib/resources/aws/aws_flow_log.rb +17 -13
  327. data/lib/resources/aws/aws_iam_access_key.rb +15 -11
  328. data/lib/resources/aws/aws_iam_access_keys.rb +19 -15
  329. data/lib/resources/aws/aws_iam_group.rb +9 -5
  330. data/lib/resources/aws/aws_iam_groups.rb +9 -5
  331. data/lib/resources/aws/aws_iam_password_policy.rb +13 -10
  332. data/lib/resources/aws/aws_iam_policies.rb +9 -5
  333. data/lib/resources/aws/aws_iam_policy.rb +16 -12
  334. data/lib/resources/aws/aws_iam_role.rb +9 -5
  335. data/lib/resources/aws/aws_iam_root_user.rb +12 -8
  336. data/lib/resources/aws/aws_iam_user.rb +12 -12
  337. data/lib/resources/aws/aws_iam_users.rb +10 -10
  338. data/lib/resources/aws/aws_kms_key.rb +12 -8
  339. data/lib/resources/aws/aws_kms_keys.rb +9 -5
  340. data/lib/resources/aws/aws_rds_instance.rb +11 -8
  341. data/lib/resources/aws/aws_route_table.rb +11 -7
  342. data/lib/resources/aws/aws_route_tables.rb +10 -6
  343. data/lib/resources/aws/aws_s3_bucket.rb +14 -11
  344. data/lib/resources/aws/aws_s3_bucket_object.rb +12 -9
  345. data/lib/resources/aws/aws_s3_buckets.rb +9 -7
  346. data/lib/resources/aws/aws_security_group.rb +16 -12
  347. data/lib/resources/aws/aws_security_groups.rb +12 -8
  348. data/lib/resources/aws/aws_sns_subscription.rb +15 -11
  349. data/lib/resources/aws/aws_sns_topic.rb +10 -6
  350. data/lib/resources/aws/aws_sns_topics.rb +9 -5
  351. data/lib/resources/aws/aws_sqs_queue.rb +18 -14
  352. data/lib/resources/aws/aws_subnet.rb +11 -7
  353. data/lib/resources/aws/aws_subnets.rb +9 -5
  354. data/lib/resources/aws/aws_vpc.rb +10 -6
  355. data/lib/resources/aws/aws_vpcs.rb +9 -5
  356. data/lib/resources/azure/azure_backend.rb +20 -18
  357. data/lib/resources/azure/azure_generic_resource.rb +13 -15
  358. data/lib/resources/azure/azure_resource_group.rb +17 -19
  359. data/lib/resources/azure/azure_virtual_machine.rb +6 -8
  360. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +6 -8
  361. data/lib/source_readers/flat.rb +6 -10
  362. data/lib/source_readers/inspec.rb +8 -12
  363. metadata +141 -142
  364. data/lib/resources/mysql.rb +0 -82
  365. data/lib/resources/sys_info.rb +0 -28
  366. data/lib/utils/deprecation.rb +0 -6
  367. data/lib/utils/json_log.rb +0 -18
  368. data/lib/utils/latest_version.rb +0 -22
@@ -1,12 +1,12 @@
1
- # encoding: utf-8
1
+ require "inspec/resources/json"
2
2
 
3
3
  # Parses a csv document
4
4
  # This implementation was inspired by a blog post
5
5
  # @see http://technicalpickles.com/posts/parsing-csv-with-ruby
6
6
  module Inspec::Resources
7
7
  class CsvConfig < JsonConfig
8
- name 'csv'
9
- desc 'Use the csv InSpec audit resource to test configuration data in a CSV file.'
8
+ name "csv"
9
+ desc "Use the csv InSpec audit resource to test configuration data in a CSV file."
10
10
  example <<~EXAMPLE
11
11
  describe csv('example.csv') do
12
12
  its('name') { should eq(['John', 'Alice']) }
@@ -20,7 +20,7 @@ module Inspec::Resources
20
20
  # { 'name' => 'row2', 'col1' => 'value3', 'col2' => 'value4' }
21
21
  # ]
22
22
  def parse(content)
23
- require 'csv'
23
+ require "csv"
24
24
 
25
25
  # convert empty field to nil
26
26
  CSV::Converters[:blank_to_nil] = lambda do |field|
@@ -50,7 +50,7 @@ module Inspec::Resources
50
50
  # used by JsonConfig to build up a full to_s method
51
51
  # based on whether a file path, content, or command was supplied.
52
52
  def resource_base_name
53
- 'CSV'
53
+ "CSV"
54
54
  end
55
55
  end
56
56
  end
@@ -1,11 +1,9 @@
1
- # encoding: utf-8
2
-
3
- require 'openssl'
4
- require 'utils/file_reader'
1
+ require "openssl"
2
+ require "inspec/utils/file_reader"
5
3
 
6
4
  class DhParams < Inspec.resource(1)
7
- name 'dh_params'
8
- supports platform: 'unix'
5
+ name "dh_params"
6
+ supports platform: "unix"
9
7
  desc '
10
8
  Use the `dh_params` InSpec audit resource to test Diffie-Hellman (DH)
11
9
  parameters.
@@ -44,7 +42,7 @@ class DhParams < Inspec.resource(1)
44
42
  # its('modulus') { should eq '00:91:a0:15:89:e5:bc:38:93:12:02:fc:...' }
45
43
  def modulus
46
44
  return if @dh_params.nil?
47
- '00:' + @dh_params.p.to_s(16).downcase.scan(/.{2}/).join(':')
45
+ "00:" + @dh_params.p.to_s(16).downcase.scan(/.{2}/).join(":")
48
46
  end
49
47
 
50
48
  # its('pem') { should eq '-----BEGIN DH PARAMETERS...' }
@@ -1,13 +1,11 @@
1
- # encoding: utf-8
2
-
3
- require 'resources/file'
1
+ require "inspec/resources/file"
4
2
 
5
3
  module Inspec::Resources
6
4
  class Directory < FileResource
7
- name 'directory'
8
- supports platform: 'unix'
9
- supports platform: 'windows'
10
- desc 'Use the directory InSpec audit resource to test if the file type is a directory. This is equivalent to using the file InSpec audit resource and the be_directory matcher, but provides a simpler and more direct way to test directories. All of the matchers available to file may be used with directory.'
5
+ name "directory"
6
+ supports platform: "unix"
7
+ supports platform: "windows"
8
+ desc "Use the directory InSpec audit resource to test if the file type is a directory. This is equivalent to using the file InSpec audit resource and the be_directory matcher, but provides a simpler and more direct way to test directories. All of the matchers available to file may be used with directory."
11
9
  example <<~EXAMPLE
12
10
  describe directory('path') do
13
11
  it { should be_directory }
@@ -1,31 +1,31 @@
1
- # encoding: utf-8
2
1
  #
3
2
  # Copyright 2017, Christoph Hartmann
4
3
  #
5
4
 
6
- require 'utils/filter'
7
- require 'hashie/mash'
5
+ require "inspec/resources/command"
6
+ require "inspec/utils/filter"
7
+ require "hashie/mash"
8
8
 
9
9
  module Inspec::Resources
10
10
  class DockerContainerFilter
11
11
  # use filtertable for containers
12
12
  filter = FilterTable.create
13
13
  filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
14
- filter.register_column(:commands, field: 'command')
15
- .register_column(:ids, field: 'id')
16
- .register_column(:images, field: 'image')
17
- .register_column(:labels, field: 'labels', style: :simple)
18
- .register_column(:local_volumes, field: 'localvolumes')
19
- .register_column(:mounts, field: 'mounts')
20
- .register_column(:names, field: 'names')
21
- .register_column(:networks, field: 'networks')
22
- .register_column(:ports, field: 'ports')
23
- .register_column(:running_for, field: 'runningfor')
24
- .register_column(:sizes, field: 'size')
25
- .register_column(:status, field: 'status')
26
- .register_custom_matcher(:running?) { |x|
27
- x.where { status.downcase.start_with?('up') }
28
- }
14
+ filter.register_column(:commands, field: "command")
15
+ .register_column(:ids, field: "id")
16
+ .register_column(:images, field: "image")
17
+ .register_column(:labels, field: "labels", style: :simple)
18
+ .register_column(:local_volumes, field: "localvolumes")
19
+ .register_column(:mounts, field: "mounts")
20
+ .register_column(:names, field: "names")
21
+ .register_column(:networks, field: "networks")
22
+ .register_column(:ports, field: "ports")
23
+ .register_column(:running_for, field: "runningfor")
24
+ .register_column(:sizes, field: "size")
25
+ .register_column(:status, field: "status")
26
+ .register_custom_matcher(:running?) do |x|
27
+ x.where { status.downcase.start_with?("up") }
28
+ end
29
29
  filter.install_filter_methods_on_resource(self, :containers)
30
30
 
31
31
  attr_reader :containers
@@ -37,13 +37,13 @@ module Inspec::Resources
37
37
  class DockerImageFilter
38
38
  filter = FilterTable.create
39
39
  filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
40
- filter.register_column(:ids, field: 'id')
41
- .register_column(:repositories, field: 'repository')
42
- .register_column(:tags, field: 'tag')
43
- .register_column(:sizes, field: 'size')
44
- .register_column(:digests, field: 'digest')
45
- .register_column(:created, field: 'createdat')
46
- .register_column(:created_since, field: 'createdsize')
40
+ filter.register_column(:ids, field: "id")
41
+ .register_column(:repositories, field: "repository")
42
+ .register_column(:tags, field: "tag")
43
+ .register_column(:sizes, field: "size")
44
+ .register_column(:digests, field: "digest")
45
+ .register_column(:created, field: "createdat")
46
+ .register_column(:created_since, field: "createdsize")
47
47
  filter.install_filter_methods_on_resource(self, :images)
48
48
 
49
49
  attr_reader :images
@@ -54,10 +54,10 @@ module Inspec::Resources
54
54
 
55
55
  class DockerPluginFilter
56
56
  filter = FilterTable.create
57
- filter.add(:ids, field: 'id')
58
- .add(:names, field: 'name')
59
- .add(:versions, field: 'version')
60
- .add(:enabled, field: 'enabled')
57
+ filter.add(:ids, field: "id")
58
+ .add(:names, field: "name")
59
+ .add(:versions, field: "version")
60
+ .add(:enabled, field: "enabled")
61
61
  filter.connect(self, :plugins)
62
62
 
63
63
  attr_reader :plugins
@@ -69,12 +69,12 @@ module Inspec::Resources
69
69
  class DockerServiceFilter
70
70
  filter = FilterTable.create
71
71
  filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
72
- filter.register_column(:ids, field: 'id')
73
- .register_column(:names, field: 'name')
74
- .register_column(:modes, field: 'mode')
75
- .register_column(:replicas, field: 'replicas')
76
- .register_column(:images, field: 'image')
77
- .register_column(:ports, field: 'ports')
72
+ filter.register_column(:ids, field: "id")
73
+ .register_column(:names, field: "name")
74
+ .register_column(:modes, field: "mode")
75
+ .register_column(:replicas, field: "replicas")
76
+ .register_column(:images, field: "image")
77
+ .register_column(:ports, field: "ports")
78
78
  filter.install_filter_methods_on_resource(self, :services)
79
79
 
80
80
  attr_reader :services
@@ -88,8 +88,8 @@ module Inspec::Resources
88
88
  # - docker_container
89
89
  # - docker_image
90
90
  class Docker < Inspec.resource(1)
91
- name 'docker'
92
- supports platform: 'unix'
91
+ name "docker"
92
+ supports platform: "unix"
93
93
  desc "
94
94
  A resource to retrieve information about docker
95
95
  "
@@ -148,22 +148,22 @@ module Inspec::Resources
148
148
  def version
149
149
  return @version if defined?(@version)
150
150
  data = {}
151
- cmd = inspec.command('docker version --format \'{{ json . }}\'')
151
+ cmd = inspec.command("docker version --format '{{ json . }}'")
152
152
  data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
153
153
  @version = Hashie::Mash.new(data)
154
154
  rescue JSON::ParserError => _e
155
- return Hashie::Mash.new({})
155
+ Hashie::Mash.new({})
156
156
  end
157
157
 
158
158
  def info
159
159
  return @info if defined?(@info)
160
160
  data = {}
161
161
  # docke info format is only supported for Docker 17.03+
162
- cmd = inspec.command('docker info --format \'{{ json . }}\'')
162
+ cmd = inspec.command("docker info --format '{{ json . }}'")
163
163
  data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
164
164
  @info = Hashie::Mash.new(data)
165
165
  rescue JSON::ParserError => _e
166
- return Hashie::Mash.new({})
166
+ Hashie::Mash.new({})
167
167
  end
168
168
 
169
169
  # returns information about docker objects
@@ -173,11 +173,11 @@ module Inspec::Resources
173
173
  data = data[0] if data.is_a?(Array)
174
174
  @inspect = Hashie::Mash.new(data)
175
175
  rescue JSON::ParserError => _e
176
- return Hashie::Mash.new({})
176
+ Hashie::Mash.new({})
177
177
  end
178
178
 
179
179
  def to_s
180
- 'Docker Host'
180
+ "Docker Host"
181
181
  end
182
182
 
183
183
  private
@@ -188,11 +188,11 @@ module Inspec::Resources
188
188
  raw = inspec.command("docker #{subcommand} --format '{#{format.join(', ')}}'").stdout
189
189
  output = []
190
190
  # since docker is not outputting valid json, we need to parse each row
191
- raw.each_line { |entry|
191
+ raw.each_line do |entry|
192
192
  # convert all keys to lower_case to work well with ruby and filter table
193
- row = JSON.parse(entry).map { |key, value|
193
+ row = JSON.parse(entry).map do |key, value|
194
194
  [key.downcase, value]
195
- }.to_h
195
+ end.to_h
196
196
 
197
197
  # ensure all keys are there
198
198
  row = ensure_keys(row, labels)
@@ -201,16 +201,16 @@ module Inspec::Resources
201
201
  # Depending on how it was linked, the actual container name may come before
202
202
  # or after the link information, so we'll just look for the first name that
203
203
  # does not include a slash since that is not a valid character in a container name
204
- if row['names']
205
- row['names'] = row['names'].split(',').find { |c| !c.include?('/') }
204
+ if row["names"]
205
+ row["names"] = row["names"].split(",").find { |c| !c.include?("/") }
206
206
  end
207
207
 
208
208
  # Split labels on ',' or set to empty array
209
209
  # Allows for `docker.containers.where { labels.include?('app=redis') }`
210
- row['labels'] = row.key?('labels') ? row['labels'].split(',') : []
210
+ row["labels"] = row.key?("labels") ? row["labels"].split(",") : []
211
211
 
212
212
  output.push(row)
213
- }
213
+ end
214
214
 
215
215
  output
216
216
  rescue JSON::ParserError => _e
@@ -225,21 +225,21 @@ module Inspec::Resources
225
225
  labels = %w{Command CreatedAt ID Image Labels Mounts Names Ports RunningFor Size Status}
226
226
 
227
227
  # Networks LocalVolumes work with 1.13+ only
228
- if !version.empty? && Gem::Version.new(version['Client']['Version']) >= Gem::Version.new('1.13')
229
- labels.push('Networks')
230
- labels.push('LocalVolumes')
228
+ if !version.empty? && Gem::Version.new(version["Client"]["Version"]) >= Gem::Version.new("1.13")
229
+ labels.push("Networks")
230
+ labels.push("LocalVolumes")
231
231
  end
232
- parse_json_command(labels, 'ps -a --no-trunc')
232
+ parse_json_command(labels, "ps -a --no-trunc")
233
233
  end
234
234
 
235
235
  def parse_services
236
- parse_json_command(%w{ID Name Mode Replicas Image Ports}, 'service ls')
236
+ parse_json_command(%w{ID Name Mode Replicas Image Ports}, "service ls")
237
237
  end
238
238
 
239
239
  def ensure_keys(entry, labels)
240
- labels.each { |key|
240
+ labels.each do |key|
241
241
  entry[key.downcase] = nil if !entry.key?(key.downcase)
242
- }
242
+ end
243
243
  entry
244
244
  end
245
245
 
@@ -247,24 +247,24 @@ module Inspec::Resources
247
247
  # docker does not support the `json .` function here, therefore we need to emulate that behavior.
248
248
  raw_images = inspec.command('docker images -a --no-trunc --format \'{ "id": {{json .ID}}, "repository": {{json .Repository}}, "tag": {{json .Tag}}, "size": {{json .Size}}, "digest": {{json .Digest}}, "createdat": {{json .CreatedAt}}, "createdsize": {{json .CreatedSince}} }\'').stdout
249
249
  c_images = []
250
- raw_images.each_line { |entry|
250
+ raw_images.each_line do |entry|
251
251
  c_images.push(JSON.parse(entry))
252
- }
252
+ end
253
253
  c_images
254
254
  rescue JSON::ParserError => _e
255
- warn 'Could not parse `docker images` output'
255
+ warn "Could not parse `docker images` output"
256
256
  []
257
257
  end
258
258
 
259
259
  def parse_plugins
260
260
  plugins = inspec.command('docker plugin ls --format \'{"id": {{json .ID}}, "name": "{{ with split .Name ":"}}{{index . 0}}{{end}}", "version": "{{ with split .Name ":"}}{{index . 1}}{{end}}", "enabled": {{json .Enabled}} }\'').stdout
261
261
  c_plugins = []
262
- plugins.each_line { |entry|
262
+ plugins.each_line do |entry|
263
263
  c_plugins.push(JSON.parse(entry))
264
- }
264
+ end
265
265
  c_plugins
266
266
  rescue JSON::ParserError => _e
267
- warn 'Could not parse `docker plugin ls` output'
267
+ warn "Could not parse `docker plugin ls` output"
268
268
  []
269
269
  end
270
270
  end
@@ -1,16 +1,16 @@
1
- # encoding: utf-8
2
1
  #
3
2
  # Copyright 2017, Christoph Hartmann
4
3
 
5
- require_relative 'docker_object'
4
+ require "inspec/resources/docker"
5
+ require_relative "docker_object"
6
6
 
7
7
  module Inspec::Resources
8
8
  class DockerContainer < Inspec.resource(1)
9
9
  include Inspec::Resources::DockerObject
10
10
 
11
- name 'docker_container'
12
- supports platform: 'unix'
13
- desc ''
11
+ name "docker_container"
12
+ supports platform: "unix"
13
+ desc ""
14
14
  example <<~EXAMPLE
15
15
  describe docker_container('an-echo-server') do
16
16
  it { should exist }
@@ -40,7 +40,7 @@ module Inspec::Resources
40
40
  end
41
41
 
42
42
  def running?
43
- status.downcase.start_with?('up') if object_info.entries.length == 1
43
+ status.downcase.start_with?("up") if object_info.entries.length == 1
44
44
  end
45
45
 
46
46
  def status
@@ -1,16 +1,16 @@
1
- # encoding: utf-8
2
1
  #
3
2
  # Copyright 2017, Christoph Hartmann
4
3
 
5
- require_relative 'docker_object'
4
+ require "inspec/resources/docker"
5
+ require_relative "docker_object"
6
6
 
7
7
  module Inspec::Resources
8
8
  class DockerImage < Inspec.resource(1)
9
9
  include Inspec::Resources::DockerObject
10
10
 
11
- name 'docker_image'
12
- supports platform: 'unix'
13
- desc ''
11
+ name "docker_image"
12
+ supports platform: "unix"
13
+ desc ""
14
14
  example <<~EXAMPLE
15
15
  describe docker_image('alpine:latest') do
16
16
  it { should exist }
@@ -59,11 +59,11 @@ module Inspec::Resources
59
59
  opts.merge!(parse_components_from_image(opts[:image]))
60
60
 
61
61
  # assume a "latest" tag if we don't have one
62
- opts[:tag] ||= 'latest'
62
+ opts[:tag] ||= "latest"
63
63
 
64
64
  # if the ID isn't nil and doesn't contain a hash indicator (indicated by the presence
65
65
  # of a colon, which separates the indicator from the actual hash), we assume it's sha256.
66
- opts[:id] = 'sha256:' + opts[:id] unless opts[:id].nil? || opts[:id].include?(':')
66
+ opts[:id] = "sha256:" + opts[:id] unless opts[:id].nil? || opts[:id].include?(":")
67
67
 
68
68
  # Assemble/reassemble the image from the repo and tag
69
69
  opts[:image] = "#{opts[:repo]}:#{opts[:tag]}" unless opts[:repo].nil?
@@ -75,9 +75,9 @@ module Inspec::Resources
75
75
  def object_info
76
76
  return @info if defined?(@info)
77
77
  opts = @opts
78
- @info = inspec.docker.images.where {
78
+ @info = inspec.docker.images.where do
79
79
  (repository == opts[:repo] && tag == opts[:tag]) || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id])))
80
- }
80
+ end
81
81
  end
82
82
  end
83
83
  end
@@ -1,11 +1,6 @@
1
- # encoding: utf-8
2
1
  #
3
2
  # Copyright 2017, Christoph Hartmann
4
3
  #
5
- # author: Christoph Hartmann
6
- # author: Patrick Muench
7
- # author: Dominik Richter
8
- # author: Matt Kulka
9
4
 
10
5
  module Inspec::Resources::DockerObject
11
6
  def exist?
@@ -23,30 +18,30 @@ module Inspec::Resources::DockerObject
23
18
  # option parameters, such as repo and tag. Return empty data back to the caller.
24
19
  return {} if image_string.nil?
25
20
 
26
- first_colon = image_string.index(':') || -1
27
- first_slash = image_string.index('/') || -1
21
+ first_colon = image_string.index(":") || -1
22
+ first_slash = image_string.index("/") || -1
28
23
 
29
- if image_string.count(':') == 2
24
+ if image_string.count(":") == 2
30
25
  # If there are two colons in the image string, it contains a repo-with-port and a tag.
31
26
  # example: localhost:5000/chef/inspec:1.46.3
32
- partitioned_string = image_string.rpartition(':')
27
+ partitioned_string = image_string.rpartition(":")
33
28
  repo = partitioned_string.first
34
29
  tag = partitioned_string.last
35
- image_name = repo.split('/')[1..-1].join
36
- elsif image_string.count(':') == 1 && first_colon < first_slash
30
+ image_name = repo.split("/")[1..-1].join
31
+ elsif image_string.count(":") == 1 && first_colon < first_slash
37
32
  # If there's one colon in the image string, and it comes before a forward-slash,
38
33
  # it contains a repo-with-port but no tag.
39
34
  # example: localhost:5000/ubuntu
40
35
  repo = image_string
41
36
  tag = nil
42
- image_name = repo.split('/')[1..-1].join
37
+ image_name = repo.split("/")[1..-1].join
43
38
  else
44
39
  # If there's one colon in the image string and it doesn't preceed a slash, or if
45
40
  # there is no colon at all, then it separates the repo from the tag, if there is a tag.
46
41
  # example: chef/inspec:1.46.3
47
42
  # example: chef/inspec
48
43
  # example: ubuntu:14.04
49
- repo, tag = image_string.split(':')
44
+ repo, tag = image_string.split(":")
50
45
  image_name = repo
51
46
  end
52
47