inspec 2.0.16 → 2.0.17

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