inspec 2.1.21 → 2.1.30

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 (502) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +101 -101
  3. data/CHANGELOG.md +3062 -3045
  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 +447 -447
  9. data/Rakefile +322 -322
  10. data/bin/inspec +12 -12
  11. data/docs/.gitignore +2 -2
  12. data/docs/README.md +40 -40
  13. data/docs/dsl_inspec.md +258 -258
  14. data/docs/dsl_resource.md +100 -100
  15. data/docs/glossary.md +99 -99
  16. data/docs/habitat.md +191 -191
  17. data/docs/inspec_and_friends.md +114 -114
  18. data/docs/matchers.md +169 -169
  19. data/docs/migration.md +293 -293
  20. data/docs/platforms.md +118 -118
  21. data/docs/plugin_kitchen_inspec.md +50 -50
  22. data/docs/profiles.md +376 -376
  23. data/docs/reporters.md +105 -105
  24. data/docs/resources/aide_conf.md.erb +75 -75
  25. data/docs/resources/apache.md.erb +67 -67
  26. data/docs/resources/apache_conf.md.erb +68 -68
  27. data/docs/resources/apt.md.erb +71 -71
  28. data/docs/resources/audit_policy.md.erb +47 -47
  29. data/docs/resources/auditd.md.erb +79 -79
  30. data/docs/resources/auditd_conf.md.erb +68 -68
  31. data/docs/resources/aws_cloudtrail_trail.md.erb +140 -140
  32. data/docs/resources/aws_cloudtrail_trails.md.erb +81 -81
  33. data/docs/resources/aws_cloudwatch_alarm.md.erb +86 -86
  34. data/docs/resources/aws_cloudwatch_log_metric_filter.md.erb +151 -151
  35. data/docs/resources/aws_config_delivery_channel.md +79 -79
  36. data/docs/resources/aws_config_recorder.md.erb +71 -71
  37. data/docs/resources/aws_ec2_instance.md.erb +106 -106
  38. data/docs/resources/aws_iam_access_key.md.erb +123 -123
  39. data/docs/resources/aws_iam_access_keys.md.erb +198 -198
  40. data/docs/resources/aws_iam_group.md.erb +46 -46
  41. data/docs/resources/aws_iam_groups.md.erb +43 -43
  42. data/docs/resources/aws_iam_password_policy.md.erb +76 -76
  43. data/docs/resources/aws_iam_policies.md.erb +82 -82
  44. data/docs/resources/aws_iam_policy.md.erb +144 -144
  45. data/docs/resources/aws_iam_role.md.erb +63 -63
  46. data/docs/resources/aws_iam_root_user.md.erb +70 -58
  47. data/docs/resources/aws_iam_user.md.erb +64 -64
  48. data/docs/resources/aws_iam_users.md.erb +89 -89
  49. data/docs/resources/aws_kms_key.md.erb +171 -171
  50. data/docs/resources/aws_kms_keys.md.erb +84 -84
  51. data/docs/resources/aws_rds_instance.md.erb +60 -60
  52. data/docs/resources/aws_route_table.md.erb +47 -47
  53. data/docs/resources/aws_route_tables.md.erb +49 -0
  54. data/docs/resources/aws_s3_bucket.md.erb +134 -134
  55. data/docs/resources/aws_s3_bucket_object.md.erb +83 -83
  56. data/docs/resources/aws_s3_buckets.md.erb +53 -0
  57. data/docs/resources/aws_security_group.md.erb +151 -151
  58. data/docs/resources/aws_security_groups.md.erb +91 -91
  59. data/docs/resources/aws_sns_subscription.md.erb +124 -124
  60. data/docs/resources/aws_sns_topic.md.erb +63 -63
  61. data/docs/resources/aws_sns_topics.md.erb +52 -52
  62. data/docs/resources/aws_subnet.md.erb +134 -134
  63. data/docs/resources/aws_subnets.md.erb +126 -126
  64. data/docs/resources/aws_vpc.md.erb +120 -120
  65. data/docs/resources/aws_vpcs.md.erb +48 -48
  66. data/docs/resources/azure_generic_resource.md.erb +171 -171
  67. data/docs/resources/azure_resource_group.md.erb +284 -284
  68. data/docs/resources/azure_virtual_machine.md.erb +347 -347
  69. data/docs/resources/azure_virtual_machine_data_disk.md.erb +224 -224
  70. data/docs/resources/bash.md.erb +75 -75
  71. data/docs/resources/bond.md.erb +90 -90
  72. data/docs/resources/bridge.md.erb +57 -57
  73. data/docs/resources/bsd_service.md.erb +67 -67
  74. data/docs/resources/chocolatey_package.md.erb +58 -0
  75. data/docs/resources/command.md.erb +138 -138
  76. data/docs/resources/cpan.md.erb +79 -79
  77. data/docs/resources/cran.md.erb +64 -64
  78. data/docs/resources/crontab.md.erb +89 -89
  79. data/docs/resources/csv.md.erb +54 -54
  80. data/docs/resources/dh_params.md.erb +205 -205
  81. data/docs/resources/directory.md.erb +30 -30
  82. data/docs/resources/docker.md.erb +219 -219
  83. data/docs/resources/docker_container.md.erb +103 -103
  84. data/docs/resources/docker_image.md.erb +94 -94
  85. data/docs/resources/docker_service.md.erb +114 -114
  86. data/docs/resources/elasticsearch.md.erb +242 -242
  87. data/docs/resources/etc_fstab.md.erb +125 -125
  88. data/docs/resources/etc_group.md.erb +75 -75
  89. data/docs/resources/etc_hosts.md.erb +78 -78
  90. data/docs/resources/etc_hosts_allow.md.erb +74 -74
  91. data/docs/resources/etc_hosts_deny.md.erb +74 -74
  92. data/docs/resources/file.md.erb +526 -526
  93. data/docs/resources/filesystem.md.erb +41 -41
  94. data/docs/resources/firewalld.md.erb +107 -107
  95. data/docs/resources/gem.md.erb +79 -79
  96. data/docs/resources/group.md.erb +61 -61
  97. data/docs/resources/grub_conf.md.erb +101 -101
  98. data/docs/resources/host.md.erb +86 -86
  99. data/docs/resources/http.md.erb +196 -196
  100. data/docs/resources/iis_app.md.erb +122 -122
  101. data/docs/resources/iis_site.md.erb +135 -135
  102. data/docs/resources/inetd_conf.md.erb +94 -94
  103. data/docs/resources/ini.md.erb +76 -76
  104. data/docs/resources/interface.md.erb +58 -58
  105. data/docs/resources/iptables.md.erb +64 -64
  106. data/docs/resources/json.md.erb +63 -63
  107. data/docs/resources/kernel_module.md.erb +120 -120
  108. data/docs/resources/kernel_parameter.md.erb +53 -53
  109. data/docs/resources/key_rsa.md.erb +85 -85
  110. data/docs/resources/launchd_service.md.erb +57 -57
  111. data/docs/resources/limits_conf.md.erb +75 -75
  112. data/docs/resources/login_defs.md.erb +71 -71
  113. data/docs/resources/mount.md.erb +69 -69
  114. data/docs/resources/mssql_session.md.erb +60 -60
  115. data/docs/resources/mysql_conf.md.erb +99 -99
  116. data/docs/resources/mysql_session.md.erb +74 -74
  117. data/docs/resources/nginx.md.erb +79 -79
  118. data/docs/resources/nginx_conf.md.erb +138 -138
  119. data/docs/resources/npm.md.erb +60 -60
  120. data/docs/resources/ntp_conf.md.erb +60 -60
  121. data/docs/resources/oneget.md.erb +53 -53
  122. data/docs/resources/oracledb_session.md.erb +52 -52
  123. data/docs/resources/os.md.erb +141 -141
  124. data/docs/resources/os_env.md.erb +78 -78
  125. data/docs/resources/package.md.erb +120 -120
  126. data/docs/resources/packages.md.erb +67 -67
  127. data/docs/resources/parse_config.md.erb +103 -103
  128. data/docs/resources/parse_config_file.md.erb +138 -138
  129. data/docs/resources/passwd.md.erb +141 -141
  130. data/docs/resources/pip.md.erb +67 -67
  131. data/docs/resources/port.md.erb +137 -137
  132. data/docs/resources/postgres_conf.md.erb +79 -79
  133. data/docs/resources/postgres_hba_conf.md.erb +93 -93
  134. data/docs/resources/postgres_ident_conf.md.erb +76 -76
  135. data/docs/resources/postgres_session.md.erb +69 -69
  136. data/docs/resources/powershell.md.erb +102 -102
  137. data/docs/resources/processes.md.erb +109 -109
  138. data/docs/resources/rabbitmq_config.md.erb +41 -41
  139. data/docs/resources/registry_key.md.erb +158 -158
  140. data/docs/resources/runit_service.md.erb +57 -57
  141. data/docs/resources/security_policy.md.erb +47 -47
  142. data/docs/resources/service.md.erb +121 -121
  143. data/docs/resources/shadow.md.erb +146 -146
  144. data/docs/resources/ssh_config.md.erb +73 -73
  145. data/docs/resources/sshd_config.md.erb +83 -83
  146. data/docs/resources/ssl.md.erb +119 -119
  147. data/docs/resources/sys_info.md.erb +42 -42
  148. data/docs/resources/systemd_service.md.erb +57 -57
  149. data/docs/resources/sysv_service.md.erb +57 -57
  150. data/docs/resources/upstart_service.md.erb +57 -57
  151. data/docs/resources/user.md.erb +140 -140
  152. data/docs/resources/users.md.erb +127 -127
  153. data/docs/resources/vbscript.md.erb +55 -55
  154. data/docs/resources/virtualization.md.erb +57 -57
  155. data/docs/resources/windows_feature.md.erb +47 -47
  156. data/docs/resources/windows_hotfix.md.erb +53 -53
  157. data/docs/resources/windows_task.md.erb +95 -95
  158. data/docs/resources/wmi.md.erb +81 -81
  159. data/docs/resources/x509_certificate.md.erb +151 -151
  160. data/docs/resources/xinetd_conf.md.erb +156 -156
  161. data/docs/resources/xml.md.erb +85 -85
  162. data/docs/resources/yaml.md.erb +69 -69
  163. data/docs/resources/yum.md.erb +98 -98
  164. data/docs/resources/zfs_dataset.md.erb +53 -53
  165. data/docs/resources/zfs_pool.md.erb +47 -47
  166. data/docs/ruby_usage.md +203 -203
  167. data/docs/shared/matcher_be.md.erb +1 -1
  168. data/docs/shared/matcher_cmp.md.erb +43 -43
  169. data/docs/shared/matcher_eq.md.erb +3 -3
  170. data/docs/shared/matcher_include.md.erb +1 -1
  171. data/docs/shared/matcher_match.md.erb +1 -1
  172. data/docs/shell.md +217 -217
  173. data/examples/README.md +8 -8
  174. data/examples/inheritance/README.md +65 -65
  175. data/examples/inheritance/controls/example.rb +14 -14
  176. data/examples/inheritance/inspec.yml +15 -15
  177. data/examples/kitchen-ansible/.kitchen.yml +25 -25
  178. data/examples/kitchen-ansible/Gemfile +19 -19
  179. data/examples/kitchen-ansible/README.md +53 -53
  180. data/examples/kitchen-ansible/files/nginx.repo +6 -6
  181. data/examples/kitchen-ansible/tasks/main.yml +16 -16
  182. data/examples/kitchen-ansible/test/integration/default/default.yml +5 -5
  183. data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -28
  184. data/examples/kitchen-chef/.kitchen.yml +20 -20
  185. data/examples/kitchen-chef/Berksfile +3 -3
  186. data/examples/kitchen-chef/Gemfile +19 -19
  187. data/examples/kitchen-chef/README.md +27 -27
  188. data/examples/kitchen-chef/metadata.rb +7 -7
  189. data/examples/kitchen-chef/recipes/default.rb +6 -6
  190. data/examples/kitchen-chef/recipes/nginx.rb +30 -30
  191. data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -28
  192. data/examples/kitchen-puppet/.kitchen.yml +22 -22
  193. data/examples/kitchen-puppet/Gemfile +20 -20
  194. data/examples/kitchen-puppet/Puppetfile +25 -25
  195. data/examples/kitchen-puppet/README.md +53 -53
  196. data/examples/kitchen-puppet/manifests/site.pp +33 -33
  197. data/examples/kitchen-puppet/metadata.json +11 -11
  198. data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
  199. data/examples/meta-profile/README.md +37 -37
  200. data/examples/meta-profile/controls/example.rb +13 -13
  201. data/examples/meta-profile/inspec.yml +13 -13
  202. data/examples/profile-attribute.yml +2 -2
  203. data/examples/profile-attribute/README.md +14 -14
  204. data/examples/profile-attribute/controls/example.rb +11 -11
  205. data/examples/profile-attribute/inspec.yml +8 -8
  206. data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
  207. data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
  208. data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
  209. data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
  210. data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
  211. data/examples/profile-aws/inspec.yml +11 -11
  212. data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
  213. data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
  214. data/examples/profile-azure/inspec.yml +11 -11
  215. data/examples/profile-sensitive/README.md +29 -29
  216. data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
  217. data/examples/profile-sensitive/controls/sensitive.rb +9 -9
  218. data/examples/profile-sensitive/inspec.yml +8 -8
  219. data/examples/profile/README.md +48 -48
  220. data/examples/profile/controls/example.rb +23 -23
  221. data/examples/profile/controls/gordon.rb +36 -36
  222. data/examples/profile/controls/meta.rb +34 -34
  223. data/examples/profile/inspec.yml +10 -10
  224. data/examples/profile/libraries/gordon_config.rb +59 -53
  225. data/inspec.gemspec +47 -47
  226. data/lib/bundles/README.md +3 -3
  227. data/lib/bundles/inspec-artifact.rb +7 -7
  228. data/lib/bundles/inspec-artifact/README.md +1 -1
  229. data/lib/bundles/inspec-artifact/cli.rb +277 -277
  230. data/lib/bundles/inspec-compliance.rb +16 -16
  231. data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
  232. data/lib/bundles/inspec-compliance/README.md +185 -185
  233. data/lib/bundles/inspec-compliance/api.rb +316 -316
  234. data/lib/bundles/inspec-compliance/api/login.rb +152 -152
  235. data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
  236. data/lib/bundles/inspec-compliance/cli.rb +254 -254
  237. data/lib/bundles/inspec-compliance/configuration.rb +103 -103
  238. data/lib/bundles/inspec-compliance/http.rb +86 -86
  239. data/lib/bundles/inspec-compliance/support.rb +36 -36
  240. data/lib/bundles/inspec-compliance/target.rb +98 -98
  241. data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
  242. data/lib/bundles/inspec-habitat.rb +12 -12
  243. data/lib/bundles/inspec-habitat/cli.rb +36 -36
  244. data/lib/bundles/inspec-habitat/log.rb +10 -10
  245. data/lib/bundles/inspec-habitat/profile.rb +391 -391
  246. data/lib/bundles/inspec-init.rb +8 -8
  247. data/lib/bundles/inspec-init/README.md +31 -31
  248. data/lib/bundles/inspec-init/cli.rb +97 -97
  249. data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
  250. data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
  251. data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
  252. data/lib/bundles/inspec-supermarket.rb +13 -13
  253. data/lib/bundles/inspec-supermarket/README.md +45 -45
  254. data/lib/bundles/inspec-supermarket/api.rb +84 -84
  255. data/lib/bundles/inspec-supermarket/cli.rb +73 -73
  256. data/lib/bundles/inspec-supermarket/target.rb +34 -34
  257. data/lib/fetchers/git.rb +163 -163
  258. data/lib/fetchers/local.rb +74 -74
  259. data/lib/fetchers/mock.rb +35 -35
  260. data/lib/fetchers/url.rb +204 -204
  261. data/lib/inspec.rb +24 -24
  262. data/lib/inspec/archive/tar.rb +29 -29
  263. data/lib/inspec/archive/zip.rb +19 -19
  264. data/lib/inspec/backend.rb +93 -93
  265. data/lib/inspec/base_cli.rb +363 -357
  266. data/lib/inspec/cached_fetcher.rb +66 -66
  267. data/lib/inspec/cli.rb +292 -292
  268. data/lib/inspec/completions/bash.sh.erb +45 -45
  269. data/lib/inspec/completions/fish.sh.erb +34 -34
  270. data/lib/inspec/completions/zsh.sh.erb +61 -61
  271. data/lib/inspec/control_eval_context.rb +179 -179
  272. data/lib/inspec/dependencies/cache.rb +72 -72
  273. data/lib/inspec/dependencies/dependency_set.rb +92 -92
  274. data/lib/inspec/dependencies/lockfile.rb +115 -115
  275. data/lib/inspec/dependencies/requirement.rb +123 -123
  276. data/lib/inspec/dependencies/resolver.rb +86 -86
  277. data/lib/inspec/describe.rb +27 -27
  278. data/lib/inspec/dsl.rb +66 -66
  279. data/lib/inspec/dsl_shared.rb +33 -33
  280. data/lib/inspec/env_printer.rb +157 -157
  281. data/lib/inspec/errors.rb +14 -13
  282. data/lib/inspec/exceptions.rb +12 -12
  283. data/lib/inspec/expect.rb +45 -45
  284. data/lib/inspec/fetcher.rb +45 -45
  285. data/lib/inspec/file_provider.rb +275 -275
  286. data/lib/inspec/formatters.rb +3 -3
  287. data/lib/inspec/formatters/base.rb +259 -250
  288. data/lib/inspec/formatters/json_rspec.rb +20 -20
  289. data/lib/inspec/formatters/show_progress.rb +12 -12
  290. data/lib/inspec/library_eval_context.rb +58 -58
  291. data/lib/inspec/log.rb +11 -11
  292. data/lib/inspec/metadata.rb +247 -247
  293. data/lib/inspec/method_source.rb +24 -24
  294. data/lib/inspec/objects.rb +14 -14
  295. data/lib/inspec/objects/attribute.rb +65 -65
  296. data/lib/inspec/objects/control.rb +61 -61
  297. data/lib/inspec/objects/describe.rb +92 -92
  298. data/lib/inspec/objects/each_loop.rb +36 -36
  299. data/lib/inspec/objects/list.rb +15 -15
  300. data/lib/inspec/objects/or_test.rb +40 -40
  301. data/lib/inspec/objects/ruby_helper.rb +15 -15
  302. data/lib/inspec/objects/tag.rb +27 -27
  303. data/lib/inspec/objects/test.rb +87 -87
  304. data/lib/inspec/objects/value.rb +27 -27
  305. data/lib/inspec/plugins.rb +60 -60
  306. data/lib/inspec/plugins/cli.rb +24 -24
  307. data/lib/inspec/plugins/fetcher.rb +86 -86
  308. data/lib/inspec/plugins/resource.rb +135 -135
  309. data/lib/inspec/plugins/secret.rb +15 -15
  310. data/lib/inspec/plugins/source_reader.rb +40 -40
  311. data/lib/inspec/polyfill.rb +12 -12
  312. data/lib/inspec/profile.rb +513 -513
  313. data/lib/inspec/profile_context.rb +208 -208
  314. data/lib/inspec/profile_vendor.rb +66 -66
  315. data/lib/inspec/reporters.rb +60 -54
  316. data/lib/inspec/reporters/automate.rb +76 -0
  317. data/lib/inspec/reporters/base.rb +25 -24
  318. data/lib/inspec/reporters/cli.rb +356 -356
  319. data/lib/inspec/reporters/json.rb +116 -116
  320. data/lib/inspec/reporters/json_min.rb +48 -48
  321. data/lib/inspec/reporters/junit.rb +77 -77
  322. data/lib/inspec/require_loader.rb +33 -33
  323. data/lib/inspec/resource.rb +187 -186
  324. data/lib/inspec/rule.rb +266 -266
  325. data/lib/inspec/runner.rb +345 -345
  326. data/lib/inspec/runner_mock.rb +41 -41
  327. data/lib/inspec/runner_rspec.rb +175 -175
  328. data/lib/inspec/runtime_profile.rb +26 -26
  329. data/lib/inspec/schema.rb +213 -213
  330. data/lib/inspec/secrets.rb +19 -19
  331. data/lib/inspec/secrets/yaml.rb +30 -30
  332. data/lib/inspec/shell.rb +220 -220
  333. data/lib/inspec/shell_detector.rb +90 -90
  334. data/lib/inspec/source_reader.rb +29 -29
  335. data/lib/inspec/version.rb +8 -8
  336. data/lib/matchers/matchers.rb +339 -339
  337. data/lib/resource_support/aws.rb +49 -47
  338. data/lib/resource_support/aws/aws_backend_base.rb +12 -12
  339. data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
  340. data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
  341. data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
  342. data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
  343. data/lib/resources/aide_conf.rb +151 -151
  344. data/lib/resources/apache.rb +48 -48
  345. data/lib/resources/apache_conf.rb +149 -149
  346. data/lib/resources/apt.rb +149 -149
  347. data/lib/resources/audit_policy.rb +63 -63
  348. data/lib/resources/auditd.rb +231 -231
  349. data/lib/resources/auditd_conf.rb +46 -46
  350. data/lib/resources/aws/aws_cloudtrail_trail.rb +77 -77
  351. data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
  352. data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
  353. data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
  354. data/lib/resources/aws/aws_config_delivery_channel.rb +76 -76
  355. data/lib/resources/aws/aws_config_recorder.rb +98 -98
  356. data/lib/resources/aws/aws_ec2_instance.rb +157 -157
  357. data/lib/resources/aws/aws_iam_access_key.rb +106 -106
  358. data/lib/resources/aws/aws_iam_access_keys.rb +149 -149
  359. data/lib/resources/aws/aws_iam_group.rb +56 -56
  360. data/lib/resources/aws/aws_iam_groups.rb +52 -52
  361. data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
  362. data/lib/resources/aws/aws_iam_policies.rb +53 -53
  363. data/lib/resources/aws/aws_iam_policy.rb +125 -125
  364. data/lib/resources/aws/aws_iam_role.rb +51 -51
  365. data/lib/resources/aws/aws_iam_root_user.rb +78 -60
  366. data/lib/resources/aws/aws_iam_user.rb +111 -111
  367. data/lib/resources/aws/aws_iam_users.rb +108 -108
  368. data/lib/resources/aws/aws_kms_key.rb +96 -96
  369. data/lib/resources/aws/aws_kms_keys.rb +53 -53
  370. data/lib/resources/aws/aws_rds_instance.rb +71 -71
  371. data/lib/resources/aws/aws_route_table.rb +63 -63
  372. data/lib/resources/aws/aws_route_tables.rb +60 -0
  373. data/lib/resources/aws/aws_s3_bucket.rb +115 -115
  374. data/lib/resources/aws/aws_s3_bucket_object.rb +82 -82
  375. data/lib/resources/aws/aws_s3_buckets.rb +51 -0
  376. data/lib/resources/aws/aws_security_group.rb +93 -93
  377. data/lib/resources/aws/aws_security_groups.rb +68 -68
  378. data/lib/resources/aws/aws_sns_subscription.rb +78 -78
  379. data/lib/resources/aws/aws_sns_topic.rb +53 -53
  380. data/lib/resources/aws/aws_sns_topics.rb +56 -56
  381. data/lib/resources/aws/aws_subnet.rb +88 -88
  382. data/lib/resources/aws/aws_subnets.rb +53 -53
  383. data/lib/resources/aws/aws_vpc.rb +69 -69
  384. data/lib/resources/aws/aws_vpcs.rb +45 -45
  385. data/lib/resources/azure/azure_backend.rb +377 -377
  386. data/lib/resources/azure/azure_generic_resource.rb +59 -59
  387. data/lib/resources/azure/azure_resource_group.rb +152 -152
  388. data/lib/resources/azure/azure_virtual_machine.rb +264 -264
  389. data/lib/resources/azure/azure_virtual_machine_data_disk.rb +134 -134
  390. data/lib/resources/bash.rb +35 -35
  391. data/lib/resources/bond.rb +69 -69
  392. data/lib/resources/bridge.rb +122 -122
  393. data/lib/resources/chocolatey_package.rb +78 -0
  394. data/lib/resources/command.rb +73 -73
  395. data/lib/resources/cpan.rb +58 -58
  396. data/lib/resources/cran.rb +64 -64
  397. data/lib/resources/crontab.rb +169 -169
  398. data/lib/resources/csv.rb +56 -56
  399. data/lib/resources/dh_params.rb +77 -77
  400. data/lib/resources/directory.rb +25 -25
  401. data/lib/resources/docker.rb +236 -236
  402. data/lib/resources/docker_container.rb +89 -89
  403. data/lib/resources/docker_image.rb +83 -83
  404. data/lib/resources/docker_object.rb +57 -57
  405. data/lib/resources/docker_service.rb +90 -90
  406. data/lib/resources/elasticsearch.rb +169 -169
  407. data/lib/resources/etc_fstab.rb +94 -94
  408. data/lib/resources/etc_group.rb +152 -152
  409. data/lib/resources/etc_hosts.rb +66 -66
  410. data/lib/resources/etc_hosts_allow_deny.rb +112 -112
  411. data/lib/resources/file.rb +298 -298
  412. data/lib/resources/filesystem.rb +31 -31
  413. data/lib/resources/firewalld.rb +143 -143
  414. data/lib/resources/gem.rb +70 -70
  415. data/lib/resources/groups.rb +215 -215
  416. data/lib/resources/grub_conf.rb +227 -227
  417. data/lib/resources/host.rb +306 -306
  418. data/lib/resources/http.rb +253 -253
  419. data/lib/resources/iis_app.rb +101 -101
  420. data/lib/resources/iis_site.rb +148 -148
  421. data/lib/resources/inetd_conf.rb +54 -54
  422. data/lib/resources/ini.rb +29 -29
  423. data/lib/resources/interface.rb +129 -129
  424. data/lib/resources/iptables.rb +80 -80
  425. data/lib/resources/json.rb +107 -107
  426. data/lib/resources/kernel_module.rb +107 -107
  427. data/lib/resources/kernel_parameter.rb +58 -58
  428. data/lib/resources/key_rsa.rb +61 -61
  429. data/lib/resources/limits_conf.rb +46 -46
  430. data/lib/resources/login_def.rb +57 -57
  431. data/lib/resources/mount.rb +88 -88
  432. data/lib/resources/mssql_session.rb +101 -101
  433. data/lib/resources/mysql.rb +82 -81
  434. data/lib/resources/mysql_conf.rb +127 -127
  435. data/lib/resources/mysql_session.rb +85 -85
  436. data/lib/resources/nginx.rb +96 -96
  437. data/lib/resources/nginx_conf.rb +226 -226
  438. data/lib/resources/npm.rb +48 -48
  439. data/lib/resources/ntp_conf.rb +51 -51
  440. data/lib/resources/oneget.rb +71 -71
  441. data/lib/resources/oracledb_session.rb +139 -139
  442. data/lib/resources/os.rb +36 -36
  443. data/lib/resources/os_env.rb +75 -75
  444. data/lib/resources/package.rb +370 -370
  445. data/lib/resources/packages.rb +111 -111
  446. data/lib/resources/parse_config.rb +112 -112
  447. data/lib/resources/passwd.rb +76 -76
  448. data/lib/resources/pip.rb +130 -130
  449. data/lib/resources/platform.rb +109 -109
  450. data/lib/resources/port.rb +771 -771
  451. data/lib/resources/postgres.rb +131 -130
  452. data/lib/resources/postgres_conf.rb +114 -114
  453. data/lib/resources/postgres_hba_conf.rb +90 -90
  454. data/lib/resources/postgres_ident_conf.rb +79 -79
  455. data/lib/resources/postgres_session.rb +71 -71
  456. data/lib/resources/powershell.rb +66 -66
  457. data/lib/resources/processes.rb +204 -204
  458. data/lib/resources/rabbitmq_conf.rb +51 -51
  459. data/lib/resources/registry_key.rb +297 -297
  460. data/lib/resources/security_policy.rb +180 -180
  461. data/lib/resources/service.rb +794 -790
  462. data/lib/resources/shadow.rb +149 -149
  463. data/lib/resources/ssh_conf.rb +97 -97
  464. data/lib/resources/ssl.rb +99 -99
  465. data/lib/resources/sys_info.rb +28 -28
  466. data/lib/resources/toml.rb +32 -32
  467. data/lib/resources/users.rb +654 -654
  468. data/lib/resources/vbscript.rb +68 -68
  469. data/lib/resources/virtualization.rb +247 -247
  470. data/lib/resources/windows_feature.rb +84 -84
  471. data/lib/resources/windows_hotfix.rb +35 -35
  472. data/lib/resources/windows_task.rb +102 -102
  473. data/lib/resources/wmi.rb +110 -110
  474. data/lib/resources/x509_certificate.rb +137 -137
  475. data/lib/resources/xinetd.rb +106 -106
  476. data/lib/resources/xml.rb +46 -46
  477. data/lib/resources/yaml.rb +43 -43
  478. data/lib/resources/yum.rb +180 -180
  479. data/lib/resources/zfs_dataset.rb +60 -60
  480. data/lib/resources/zfs_pool.rb +49 -49
  481. data/lib/source_readers/flat.rb +39 -39
  482. data/lib/source_readers/inspec.rb +75 -75
  483. data/lib/utils/command_wrapper.rb +27 -27
  484. data/lib/utils/convert.rb +12 -12
  485. data/lib/utils/database_helpers.rb +77 -77
  486. data/lib/utils/erlang_parser.rb +192 -192
  487. data/lib/utils/file_reader.rb +25 -25
  488. data/lib/utils/filter.rb +273 -273
  489. data/lib/utils/filter_array.rb +27 -27
  490. data/lib/utils/find_files.rb +44 -44
  491. data/lib/utils/hash.rb +41 -41
  492. data/lib/utils/json_log.rb +18 -18
  493. data/lib/utils/latest_version.rb +22 -22
  494. data/lib/utils/modulator.rb +12 -12
  495. data/lib/utils/nginx_parser.rb +85 -85
  496. data/lib/utils/object_traversal.rb +49 -49
  497. data/lib/utils/parser.rb +274 -274
  498. data/lib/utils/plugin_registry.rb +93 -93
  499. data/lib/utils/simpleconfig.rb +120 -120
  500. data/lib/utils/spdx.rb +13 -13
  501. data/lib/utils/spdx.txt +343 -343
  502. metadata +9 -2
@@ -1,10 +1,10 @@
1
- # encoding: utf-8
2
- # author: Adam Leff
3
-
4
- require 'mixlib/log'
5
-
6
- module Habitat
7
- class Log
8
- extend Mixlib::Log
9
- end
10
- end
1
+ # encoding: utf-8
2
+ # author: Adam Leff
3
+
4
+ require 'mixlib/log'
5
+
6
+ module Habitat
7
+ class Log
8
+ extend Mixlib::Log
9
+ end
10
+ end
@@ -1,391 +1,391 @@
1
- # encoding: utf-8
2
- # author: Adam Leff
3
-
4
- require 'inspec/profile_vendor'
5
- require 'mixlib/shellout'
6
- require 'tomlrb'
7
-
8
- module Habitat
9
- class Profile
10
- attr_reader :options, :path, :profile
11
-
12
- def self.create(path, options = {})
13
- creator = new(path, options)
14
- hart_file = creator.create
15
- creator.copy(hart_file)
16
- ensure
17
- creator.delete_work_dir
18
- end
19
-
20
- def self.setup(path)
21
- new(path).setup
22
- end
23
-
24
- def self.upload(path, options = {})
25
- uploader = new(path, options)
26
- uploader.upload
27
- ensure
28
- uploader.delete_work_dir
29
- end
30
-
31
- def initialize(path, options = {})
32
- @path = path
33
- @options = options
34
- @cli_config = nil
35
-
36
- log_level = options.fetch('log_level', 'info')
37
- Habitat::Log.level(log_level.to_sym)
38
- end
39
-
40
- def create
41
- Habitat::Log.info("Creating a Habitat artifact for profile: #{path}")
42
-
43
- validate_habitat_installed
44
- validate_habitat_origin
45
- create_profile_object
46
- verify_profile
47
- vendor_profile_dependencies
48
- copy_profile_to_work_dir
49
- create_habitat_directories(work_dir)
50
- create_plan(work_dir)
51
- create_run_hook(work_dir)
52
- create_settings_file(work_dir)
53
- create_default_config(work_dir)
54
-
55
- # returns the path to the .hart file in the work directory
56
- build_hart
57
- rescue => e
58
- Habitat::Log.debug(e.backtrace.join("\n"))
59
- exit_with_error(
60
- 'Unable to generate Habitat artifact.',
61
- "#{e.class} -- #{e.message}",
62
- )
63
- end
64
-
65
- def copy(hart_file)
66
- validate_output_dir
67
-
68
- Habitat::Log.info("Copying artifact to #{output_dir}...")
69
- copy_hart(hart_file)
70
- end
71
-
72
- def upload
73
- validate_habitat_auth_token
74
- hart_file = create
75
- upload_hart(hart_file)
76
- rescue => e
77
- Habitat::Log.debug(e.backtrace.join("\n"))
78
- exit_with_error(
79
- 'Unable to upload Habitat artifact.',
80
- "#{e.class} -- #{e.message}",
81
- )
82
- end
83
-
84
- def delete_work_dir
85
- Habitat::Log.debug("Deleting work directory #{work_dir}")
86
- FileUtils.rm_rf(work_dir) if Dir.exist?(work_dir)
87
- end
88
-
89
- def setup
90
- Habitat::Log.info("Setting up profile at #{path} for Habitat...")
91
- create_profile_object
92
- verify_profile
93
- vendor_profile_dependencies
94
- create_habitat_directories(path)
95
- create_plan(path)
96
- create_run_hook(path)
97
- create_settings_file(path)
98
- create_default_config(path)
99
- end
100
-
101
- private
102
-
103
- def create_profile_object
104
- @profile = Inspec::Profile.for_target(
105
- path,
106
- backend: Inspec::Backend.create(target: 'mock://'),
107
- )
108
- end
109
-
110
- def verify_profile
111
- Habitat::Log.info('Checking to see if the profile is valid...')
112
-
113
- unless profile.check[:summary][:valid]
114
- exit_with_error('Profile check failed. Please fix the profile before creating a Habitat artifact.')
115
- end
116
-
117
- Habitat::Log.info('Profile is valid.')
118
- end
119
-
120
- def vendor_profile_dependencies
121
- profile_vendor = Inspec::ProfileVendor.new(path)
122
- if profile_vendor.lockfile.exist? && profile_vendor.cache_path.exist?
123
- Habitat::Log.info("Profile's dependencies are already vendored, skipping vendor process.")
124
- else
125
- Habitat::Log.info("Vendoring the profile's dependencies...")
126
- profile_vendor.vendor!
127
-
128
- Habitat::Log.info('Ensuring all vendored content has read permissions...')
129
- profile_vendor.make_readable
130
-
131
- # refresh the profile object since the profile now has new files
132
- create_profile_object
133
- end
134
- end
135
-
136
- def validate_habitat_installed
137
- Habitat::Log.info('Checking to see if Habitat is installed...')
138
- cmd = Mixlib::ShellOut.new('hab --version')
139
- cmd.run_command
140
- exit_with_error('Unable to run Habitat commands.', cmd.stderr) if cmd.error?
141
- end
142
-
143
- def validate_habitat_origin
144
- exit_with_error(
145
- 'Unable to determine Habitat origin name.',
146
- 'Run `hab setup` or set the HAB_ORIGIN environment variable.',
147
- ) if habitat_origin.nil?
148
- end
149
-
150
- def validate_habitat_auth_token
151
- exit_with_error(
152
- 'Unable to determine Habitat auth token for publishing.',
153
- 'Run `hab setup` or set the HAB_AUTH_TOKEN environment variable.',
154
- ) if habitat_auth_token.nil?
155
- end
156
-
157
- def validate_output_dir
158
- exit_with_error("Output directory #{output_dir} is not a directory or does not exist.") unless
159
- File.directory?(output_dir)
160
- end
161
-
162
- def work_dir
163
- return @work_dir if @work_dir
164
-
165
- @work_dir ||= Dir.mktmpdir('inspec-habitat-exporter')
166
- Habitat::Log.debug("Generated work directory #{@work_dir}")
167
-
168
- @work_dir
169
- end
170
-
171
- def create_habitat_directories(parent_directory)
172
- [
173
- File.join(parent_directory, 'habitat'),
174
- File.join(parent_directory, 'habitat', 'config'),
175
- File.join(parent_directory, 'habitat', 'hooks'),
176
- ].each do |dir|
177
- Dir.mkdir(dir) unless Dir.exist?(dir)
178
- end
179
- end
180
-
181
- def copy_profile_to_work_dir
182
- Habitat::Log.info('Copying profile contents to the work directory...')
183
- profile.files.each do |f|
184
- src = File.join(profile.root_path, f)
185
- dst = File.join(work_dir, f)
186
- if File.directory?(f)
187
- Habitat::Log.debug("Creating directory #{dst}")
188
- FileUtils.mkdir_p(dst)
189
- else
190
- Habitat::Log.debug("Copying file #{src} to #{dst}")
191
- FileUtils.cp_r(src, dst)
192
- end
193
- end
194
- end
195
-
196
- def create_plan(directory)
197
- plan_file = File.join(directory, 'habitat', 'plan.sh')
198
- Habitat::Log.info("Generating Habitat plan at #{plan_file}...")
199
- File.write(plan_file, plan_contents)
200
- end
201
-
202
- def create_run_hook(directory)
203
- run_hook_file = File.join(directory, 'habitat', 'hooks', 'run')
204
- Habitat::Log.info("Generating a Habitat run hook at #{run_hook_file}...")
205
- File.write(run_hook_file, run_hook_contents)
206
- end
207
-
208
- def create_settings_file(directory)
209
- settings_file = File.join(directory, 'habitat', 'config', 'settings.sh')
210
- Habitat::Log.info("Generating a settings file at #{settings_file}...")
211
- File.write(settings_file, "SLEEP_TIME={{cfg.sleep_time}}\n")
212
- end
213
-
214
- def create_default_config(directory)
215
- default_toml = File.join(directory, 'habitat', 'default.toml')
216
- Habitat::Log.info("Generating Habitat's default.toml configuration...")
217
- File.write(default_toml, 'sleep_time = 300')
218
- end
219
-
220
- def build_hart
221
- Habitat::Log.info('Building our Habitat artifact...')
222
-
223
- env = {
224
- 'TERM' => 'vt100',
225
- 'HAB_ORIGIN' => habitat_origin,
226
- 'HAB_NONINTERACTIVE' => 'true',
227
- }
228
-
229
- env['RUST_LOG'] = 'debug' if Habitat::Log.level == :debug
230
-
231
- # TODO: Would love to use Mixlib::ShellOut here, but it doesn't
232
- # seem to preserve the STDIN tty, and docker gets angry.
233
- Dir.chdir(work_dir) do
234
- unless system(env, 'hab pkg build .')
235
- exit_with_error('Unable to build the Habitat artifact.')
236
- end
237
- end
238
-
239
- hart_files = Dir.glob(File.join(work_dir, 'results', '*.hart'))
240
-
241
- if hart_files.length > 1
242
- exit_with_error('More than one Habitat artifact was created which was not expected.')
243
- elsif hart_files.empty?
244
- exit_with_error('No Habitat artifact was created.')
245
- end
246
-
247
- hart_files.first
248
- end
249
-
250
- def copy_hart(working_dir_hart)
251
- hart_basename = File.basename(working_dir_hart)
252
- dst = File.join(output_dir, hart_basename)
253
- FileUtils.cp(working_dir_hart, dst)
254
-
255
- dst
256
- end
257
-
258
- def upload_hart(hart_file)
259
- Habitat::Log.info('Uploading the Habitat artifact to our Depot...')
260
-
261
- env = {
262
- 'TERM' => 'vt100',
263
- 'HAB_AUTH_TOKEN' => habitat_auth_token,
264
- 'HAB_NONINTERACTIVE' => 'true',
265
- }
266
-
267
- env['HAB_DEPOT_URL'] = ENV['HAB_DEPOT_URL'] if ENV['HAB_DEPOT_URL']
268
-
269
- cmd = Mixlib::ShellOut.new("hab pkg upload #{hart_file}", env: env)
270
- cmd.run_command
271
- if cmd.error?
272
- exit_with_error(
273
- 'Unable to upload Habitat artifact to the Depot.',
274
- cmd.stdout,
275
- cmd.stderr,
276
- )
277
- end
278
-
279
- Habitat::Log.info('Upload complete!')
280
- end
281
-
282
- def habitat_origin
283
- ENV['HAB_ORIGIN'] || habitat_cli_config['origin']
284
- end
285
-
286
- def habitat_auth_token
287
- ENV['HAB_AUTH_TOKEN'] || habitat_cli_config['auth_token']
288
- end
289
-
290
- def habitat_cli_config
291
- return @cli_config if @cli_config
292
-
293
- config_file = File.join(ENV['HOME'], '.hab', 'etc', 'cli.toml')
294
- return {} unless File.exist?(config_file)
295
-
296
- @cli_config = Tomlrb.load_file(config_file)
297
- end
298
-
299
- def output_dir
300
- options[:output_dir] || Dir.pwd
301
- end
302
-
303
- def exit_with_error(*errors)
304
- errors.each do |error_msg|
305
- Habitat::Log.error(error_msg)
306
- end
307
-
308
- exit 1
309
- end
310
-
311
- def package_name
312
- "inspec-profile-#{profile.name}"
313
- end
314
-
315
- def plan_contents
316
- plan = <<~EOL
317
- pkg_name=#{package_name}
318
- pkg_version=#{profile.version}
319
- pkg_origin=#{habitat_origin}
320
- pkg_deps=(chef/inspec core/ruby core/hab)
321
- pkg_svc_user=root
322
- EOL
323
-
324
- plan += "pkg_license='#{profile.metadata.params[:license]}'\n\n" if profile.metadata.params[:license]
325
-
326
- plan += <<~EOL
327
-
328
- do_build() {
329
- cp -vr $PLAN_CONTEXT/../* $HAB_CACHE_SRC_PATH/$pkg_dirname
330
- }
331
-
332
- do_install() {
333
- local profile_contents
334
- local excludes
335
- profile_contents=($(ls))
336
- excludes=(habitat results *.hart)
337
-
338
- for item in ${excludes[@]}; do
339
- profile_contents=(${profile_contents[@]/$item/})
340
- done
341
-
342
- mkdir ${pkg_prefix}/dist
343
- cp -r ${profile_contents[@]} ${pkg_prefix}/dist/
344
- }
345
- EOL
346
-
347
- plan
348
- end
349
-
350
- def run_hook_contents
351
- <<~EOL
352
- #!/bin/sh
353
-
354
- # redirect stderr to stdout
355
- # ultimately, we'd like to log this somewhere useful, but due to
356
- # https://github.com/habitat-sh/habitat/issues/2395, we need to
357
- # avoid doing that for now.
358
- exec 2>&1
359
-
360
- # InSpec will try to create a .cache directory in the user's home directory
361
- # so this needs to be someplace writeable by the hab user
362
- export HOME={{pkg.svc_var_path}}
363
-
364
- PROFILE_IDENT="{{pkg.origin}}/{{pkg.name}}"
365
- RESULTS_DIR="{{pkg.svc_var_path}}/inspec_results"
366
- RESULTS_FILE="${RESULTS_DIR}/{{pkg.name}}.json"
367
-
368
- # Create a directory for inspec formatter output
369
- mkdir -p {{pkg.svc_var_path}}/inspec_results
370
-
371
- while true; do
372
- echo "Executing InSpec for ${PROFILE_IDENT}"
373
- inspec exec {{pkg.path}}/dist --format=json > ${RESULTS_FILE}
374
-
375
- if [ $? -eq 0 ]; then
376
- echo "InSpec run completed successfully."
377
- else
378
- echo "InSpec run did not complete successfully. If you do not see any errors above,"
379
- echo "control failures were detected. Check the InSpec results here for details:"
380
- echo ${RESULTS_FILE}
381
- echo "Otherwise, troubleshoot any errors shown above."
382
- fi
383
-
384
- source {{pkg.svc_config_path}}/settings.sh
385
- echo "sleeping for ${SLEEP_TIME} seconds"
386
- sleep ${SLEEP_TIME}
387
- done
388
- EOL
389
- end
390
- end
391
- end
1
+ # encoding: utf-8
2
+ # author: Adam Leff
3
+
4
+ require 'inspec/profile_vendor'
5
+ require 'mixlib/shellout'
6
+ require 'tomlrb'
7
+
8
+ module Habitat
9
+ class Profile
10
+ attr_reader :options, :path, :profile
11
+
12
+ def self.create(path, options = {})
13
+ creator = new(path, options)
14
+ hart_file = creator.create
15
+ creator.copy(hart_file)
16
+ ensure
17
+ creator.delete_work_dir
18
+ end
19
+
20
+ def self.setup(path)
21
+ new(path).setup
22
+ end
23
+
24
+ def self.upload(path, options = {})
25
+ uploader = new(path, options)
26
+ uploader.upload
27
+ ensure
28
+ uploader.delete_work_dir
29
+ end
30
+
31
+ def initialize(path, options = {})
32
+ @path = path
33
+ @options = options
34
+ @cli_config = nil
35
+
36
+ log_level = options.fetch('log_level', 'info')
37
+ Habitat::Log.level(log_level.to_sym)
38
+ end
39
+
40
+ def create
41
+ Habitat::Log.info("Creating a Habitat artifact for profile: #{path}")
42
+
43
+ validate_habitat_installed
44
+ validate_habitat_origin
45
+ create_profile_object
46
+ verify_profile
47
+ vendor_profile_dependencies
48
+ copy_profile_to_work_dir
49
+ create_habitat_directories(work_dir)
50
+ create_plan(work_dir)
51
+ create_run_hook(work_dir)
52
+ create_settings_file(work_dir)
53
+ create_default_config(work_dir)
54
+
55
+ # returns the path to the .hart file in the work directory
56
+ build_hart
57
+ rescue => e
58
+ Habitat::Log.debug(e.backtrace.join("\n"))
59
+ exit_with_error(
60
+ 'Unable to generate Habitat artifact.',
61
+ "#{e.class} -- #{e.message}",
62
+ )
63
+ end
64
+
65
+ def copy(hart_file)
66
+ validate_output_dir
67
+
68
+ Habitat::Log.info("Copying artifact to #{output_dir}...")
69
+ copy_hart(hart_file)
70
+ end
71
+
72
+ def upload
73
+ validate_habitat_auth_token
74
+ hart_file = create
75
+ upload_hart(hart_file)
76
+ rescue => e
77
+ Habitat::Log.debug(e.backtrace.join("\n"))
78
+ exit_with_error(
79
+ 'Unable to upload Habitat artifact.',
80
+ "#{e.class} -- #{e.message}",
81
+ )
82
+ end
83
+
84
+ def delete_work_dir
85
+ Habitat::Log.debug("Deleting work directory #{work_dir}")
86
+ FileUtils.rm_rf(work_dir) if Dir.exist?(work_dir)
87
+ end
88
+
89
+ def setup
90
+ Habitat::Log.info("Setting up profile at #{path} for Habitat...")
91
+ create_profile_object
92
+ verify_profile
93
+ vendor_profile_dependencies
94
+ create_habitat_directories(path)
95
+ create_plan(path)
96
+ create_run_hook(path)
97
+ create_settings_file(path)
98
+ create_default_config(path)
99
+ end
100
+
101
+ private
102
+
103
+ def create_profile_object
104
+ @profile = Inspec::Profile.for_target(
105
+ path,
106
+ backend: Inspec::Backend.create(target: 'mock://'),
107
+ )
108
+ end
109
+
110
+ def verify_profile
111
+ Habitat::Log.info('Checking to see if the profile is valid...')
112
+
113
+ unless profile.check[:summary][:valid]
114
+ exit_with_error('Profile check failed. Please fix the profile before creating a Habitat artifact.')
115
+ end
116
+
117
+ Habitat::Log.info('Profile is valid.')
118
+ end
119
+
120
+ def vendor_profile_dependencies
121
+ profile_vendor = Inspec::ProfileVendor.new(path)
122
+ if profile_vendor.lockfile.exist? && profile_vendor.cache_path.exist?
123
+ Habitat::Log.info("Profile's dependencies are already vendored, skipping vendor process.")
124
+ else
125
+ Habitat::Log.info("Vendoring the profile's dependencies...")
126
+ profile_vendor.vendor!
127
+
128
+ Habitat::Log.info('Ensuring all vendored content has read permissions...')
129
+ profile_vendor.make_readable
130
+
131
+ # refresh the profile object since the profile now has new files
132
+ create_profile_object
133
+ end
134
+ end
135
+
136
+ def validate_habitat_installed
137
+ Habitat::Log.info('Checking to see if Habitat is installed...')
138
+ cmd = Mixlib::ShellOut.new('hab --version')
139
+ cmd.run_command
140
+ exit_with_error('Unable to run Habitat commands.', cmd.stderr) if cmd.error?
141
+ end
142
+
143
+ def validate_habitat_origin
144
+ exit_with_error(
145
+ 'Unable to determine Habitat origin name.',
146
+ 'Run `hab setup` or set the HAB_ORIGIN environment variable.',
147
+ ) if habitat_origin.nil?
148
+ end
149
+
150
+ def validate_habitat_auth_token
151
+ exit_with_error(
152
+ 'Unable to determine Habitat auth token for publishing.',
153
+ 'Run `hab setup` or set the HAB_AUTH_TOKEN environment variable.',
154
+ ) if habitat_auth_token.nil?
155
+ end
156
+
157
+ def validate_output_dir
158
+ exit_with_error("Output directory #{output_dir} is not a directory or does not exist.") unless
159
+ File.directory?(output_dir)
160
+ end
161
+
162
+ def work_dir
163
+ return @work_dir if @work_dir
164
+
165
+ @work_dir ||= Dir.mktmpdir('inspec-habitat-exporter')
166
+ Habitat::Log.debug("Generated work directory #{@work_dir}")
167
+
168
+ @work_dir
169
+ end
170
+
171
+ def create_habitat_directories(parent_directory)
172
+ [
173
+ File.join(parent_directory, 'habitat'),
174
+ File.join(parent_directory, 'habitat', 'config'),
175
+ File.join(parent_directory, 'habitat', 'hooks'),
176
+ ].each do |dir|
177
+ Dir.mkdir(dir) unless Dir.exist?(dir)
178
+ end
179
+ end
180
+
181
+ def copy_profile_to_work_dir
182
+ Habitat::Log.info('Copying profile contents to the work directory...')
183
+ profile.files.each do |f|
184
+ src = File.join(profile.root_path, f)
185
+ dst = File.join(work_dir, f)
186
+ if File.directory?(f)
187
+ Habitat::Log.debug("Creating directory #{dst}")
188
+ FileUtils.mkdir_p(dst)
189
+ else
190
+ Habitat::Log.debug("Copying file #{src} to #{dst}")
191
+ FileUtils.cp_r(src, dst)
192
+ end
193
+ end
194
+ end
195
+
196
+ def create_plan(directory)
197
+ plan_file = File.join(directory, 'habitat', 'plan.sh')
198
+ Habitat::Log.info("Generating Habitat plan at #{plan_file}...")
199
+ File.write(plan_file, plan_contents)
200
+ end
201
+
202
+ def create_run_hook(directory)
203
+ run_hook_file = File.join(directory, 'habitat', 'hooks', 'run')
204
+ Habitat::Log.info("Generating a Habitat run hook at #{run_hook_file}...")
205
+ File.write(run_hook_file, run_hook_contents)
206
+ end
207
+
208
+ def create_settings_file(directory)
209
+ settings_file = File.join(directory, 'habitat', 'config', 'settings.sh')
210
+ Habitat::Log.info("Generating a settings file at #{settings_file}...")
211
+ File.write(settings_file, "SLEEP_TIME={{cfg.sleep_time}}\n")
212
+ end
213
+
214
+ def create_default_config(directory)
215
+ default_toml = File.join(directory, 'habitat', 'default.toml')
216
+ Habitat::Log.info("Generating Habitat's default.toml configuration...")
217
+ File.write(default_toml, 'sleep_time = 300')
218
+ end
219
+
220
+ def build_hart
221
+ Habitat::Log.info('Building our Habitat artifact...')
222
+
223
+ env = {
224
+ 'TERM' => 'vt100',
225
+ 'HAB_ORIGIN' => habitat_origin,
226
+ 'HAB_NONINTERACTIVE' => 'true',
227
+ }
228
+
229
+ env['RUST_LOG'] = 'debug' if Habitat::Log.level == :debug
230
+
231
+ # TODO: Would love to use Mixlib::ShellOut here, but it doesn't
232
+ # seem to preserve the STDIN tty, and docker gets angry.
233
+ Dir.chdir(work_dir) do
234
+ unless system(env, 'hab pkg build .')
235
+ exit_with_error('Unable to build the Habitat artifact.')
236
+ end
237
+ end
238
+
239
+ hart_files = Dir.glob(File.join(work_dir, 'results', '*.hart'))
240
+
241
+ if hart_files.length > 1
242
+ exit_with_error('More than one Habitat artifact was created which was not expected.')
243
+ elsif hart_files.empty?
244
+ exit_with_error('No Habitat artifact was created.')
245
+ end
246
+
247
+ hart_files.first
248
+ end
249
+
250
+ def copy_hart(working_dir_hart)
251
+ hart_basename = File.basename(working_dir_hart)
252
+ dst = File.join(output_dir, hart_basename)
253
+ FileUtils.cp(working_dir_hart, dst)
254
+
255
+ dst
256
+ end
257
+
258
+ def upload_hart(hart_file)
259
+ Habitat::Log.info('Uploading the Habitat artifact to our Depot...')
260
+
261
+ env = {
262
+ 'TERM' => 'vt100',
263
+ 'HAB_AUTH_TOKEN' => habitat_auth_token,
264
+ 'HAB_NONINTERACTIVE' => 'true',
265
+ }
266
+
267
+ env['HAB_DEPOT_URL'] = ENV['HAB_DEPOT_URL'] if ENV['HAB_DEPOT_URL']
268
+
269
+ cmd = Mixlib::ShellOut.new("hab pkg upload #{hart_file}", env: env)
270
+ cmd.run_command
271
+ if cmd.error?
272
+ exit_with_error(
273
+ 'Unable to upload Habitat artifact to the Depot.',
274
+ cmd.stdout,
275
+ cmd.stderr,
276
+ )
277
+ end
278
+
279
+ Habitat::Log.info('Upload complete!')
280
+ end
281
+
282
+ def habitat_origin
283
+ ENV['HAB_ORIGIN'] || habitat_cli_config['origin']
284
+ end
285
+
286
+ def habitat_auth_token
287
+ ENV['HAB_AUTH_TOKEN'] || habitat_cli_config['auth_token']
288
+ end
289
+
290
+ def habitat_cli_config
291
+ return @cli_config if @cli_config
292
+
293
+ config_file = File.join(ENV['HOME'], '.hab', 'etc', 'cli.toml')
294
+ return {} unless File.exist?(config_file)
295
+
296
+ @cli_config = Tomlrb.load_file(config_file)
297
+ end
298
+
299
+ def output_dir
300
+ options[:output_dir] || Dir.pwd
301
+ end
302
+
303
+ def exit_with_error(*errors)
304
+ errors.each do |error_msg|
305
+ Habitat::Log.error(error_msg)
306
+ end
307
+
308
+ exit 1
309
+ end
310
+
311
+ def package_name
312
+ "inspec-profile-#{profile.name}"
313
+ end
314
+
315
+ def plan_contents
316
+ plan = <<~EOL
317
+ pkg_name=#{package_name}
318
+ pkg_version=#{profile.version}
319
+ pkg_origin=#{habitat_origin}
320
+ pkg_deps=(chef/inspec core/ruby core/hab)
321
+ pkg_svc_user=root
322
+ EOL
323
+
324
+ plan += "pkg_license='#{profile.metadata.params[:license]}'\n\n" if profile.metadata.params[:license]
325
+
326
+ plan += <<~EOL
327
+
328
+ do_build() {
329
+ cp -vr $PLAN_CONTEXT/../* $HAB_CACHE_SRC_PATH/$pkg_dirname
330
+ }
331
+
332
+ do_install() {
333
+ local profile_contents
334
+ local excludes
335
+ profile_contents=($(ls))
336
+ excludes=(habitat results *.hart)
337
+
338
+ for item in ${excludes[@]}; do
339
+ profile_contents=(${profile_contents[@]/$item/})
340
+ done
341
+
342
+ mkdir ${pkg_prefix}/dist
343
+ cp -r ${profile_contents[@]} ${pkg_prefix}/dist/
344
+ }
345
+ EOL
346
+
347
+ plan
348
+ end
349
+
350
+ def run_hook_contents
351
+ <<~EOL
352
+ #!/bin/sh
353
+
354
+ # redirect stderr to stdout
355
+ # ultimately, we'd like to log this somewhere useful, but due to
356
+ # https://github.com/habitat-sh/habitat/issues/2395, we need to
357
+ # avoid doing that for now.
358
+ exec 2>&1
359
+
360
+ # InSpec will try to create a .cache directory in the user's home directory
361
+ # so this needs to be someplace writeable by the hab user
362
+ export HOME={{pkg.svc_var_path}}
363
+
364
+ PROFILE_IDENT="{{pkg.origin}}/{{pkg.name}}"
365
+ RESULTS_DIR="{{pkg.svc_var_path}}/inspec_results"
366
+ RESULTS_FILE="${RESULTS_DIR}/{{pkg.name}}.json"
367
+
368
+ # Create a directory for inspec formatter output
369
+ mkdir -p {{pkg.svc_var_path}}/inspec_results
370
+
371
+ while true; do
372
+ echo "Executing InSpec for ${PROFILE_IDENT}"
373
+ inspec exec {{pkg.path}}/dist --format=json > ${RESULTS_FILE}
374
+
375
+ if [ $? -eq 0 ]; then
376
+ echo "InSpec run completed successfully."
377
+ else
378
+ echo "InSpec run did not complete successfully. If you do not see any errors above,"
379
+ echo "control failures were detected. Check the InSpec results here for details:"
380
+ echo ${RESULTS_FILE}
381
+ echo "Otherwise, troubleshoot any errors shown above."
382
+ fi
383
+
384
+ source {{pkg.svc_config_path}}/settings.sh
385
+ echo "sleeping for ${SLEEP_TIME} seconds"
386
+ sleep ${SLEEP_TIME}
387
+ done
388
+ EOL
389
+ end
390
+ end
391
+ end