chef 16.13.16-universal-mingw32 → 17.3.48-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (730) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +11 -22
  3. data/README.md +1 -1
  4. data/Rakefile +2 -2
  5. data/chef-universal-mingw32.gemspec +1 -1
  6. data/chef.gemspec +12 -24
  7. data/lib/chef/action_collection.rb +6 -26
  8. data/lib/chef/application.rb +1 -1
  9. data/lib/chef/application/base.rb +16 -1
  10. data/lib/chef/applications.rb +0 -1
  11. data/lib/chef/chef_fs/command_line.rb +5 -2
  12. data/lib/chef/chef_fs/file_pattern.rb +2 -2
  13. data/lib/chef/chef_fs/file_system.rb +9 -10
  14. data/lib/chef/client.rb +9 -3
  15. data/lib/chef/compliance/default_attributes.rb +5 -4
  16. data/lib/chef/compliance/fetcher/automate.rb +0 -7
  17. data/lib/chef/compliance/reporter/automate.rb +17 -7
  18. data/lib/chef/compliance/reporter/chef_server_automate.rb +11 -6
  19. data/lib/chef/compliance/reporter/cli.rb +77 -0
  20. data/lib/chef/compliance/reporter/compliance_enforcer.rb +4 -0
  21. data/lib/chef/compliance/reporter/json_file.rb +8 -1
  22. data/lib/chef/compliance/runner.rb +65 -27
  23. data/lib/chef/cookbook/cookbook_version_loader.rb +3 -3
  24. data/lib/chef/cookbook/gem_installer.rb +5 -1
  25. data/lib/chef/cookbook/synchronizer.rb +3 -5
  26. data/lib/chef/cookbook_loader.rb +2 -4
  27. data/lib/chef/cookbook_uploader.rb +0 -1
  28. data/lib/chef/cookbook_version.rb +26 -4
  29. data/lib/chef/data_bag_item.rb +11 -2
  30. data/lib/chef/data_collector.rb +0 -1
  31. data/lib/chef/data_collector/run_end_message.rb +1 -1
  32. data/lib/chef/delayed_evaluator.rb +4 -0
  33. data/lib/chef/deprecated.rb +18 -4
  34. data/lib/chef/dsl.rb +1 -0
  35. data/lib/chef/dsl/chef_vault.rb +6 -6
  36. data/lib/chef/dsl/declare_resource.rb +5 -10
  37. data/lib/chef/dsl/reboot_pending.rb +1 -2
  38. data/lib/chef/{knife/group_list.rb → dsl/render_helpers.rb} +18 -17
  39. data/lib/chef/dsl/secret.rb +64 -0
  40. data/lib/chef/dsl/toml.rb +116 -0
  41. data/lib/chef/dsl/universal.rb +5 -0
  42. data/lib/chef/event_dispatch/base.rb +2 -1
  43. data/lib/chef/exceptions.rb +25 -0
  44. data/lib/chef/formatters/doc.rb +2 -1
  45. data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +20 -22
  46. data/lib/chef/group.rb +75 -0
  47. data/lib/chef/handler.rb +46 -8
  48. data/lib/chef/handler/slow_report.rb +66 -0
  49. data/lib/chef/json_compat.rb +1 -1
  50. data/lib/chef/mixin/get_source_from_package.rb +1 -1
  51. data/lib/chef/node.rb +21 -20
  52. data/lib/chef/node/attribute.rb +6 -4
  53. data/lib/chef/node/immutable_collections.rb +13 -0
  54. data/lib/chef/node/mixin/deep_merge_cache.rb +11 -7
  55. data/lib/chef/org.rb +3 -2
  56. data/lib/chef/policy_builder/policyfile.rb +88 -45
  57. data/lib/chef/property.rb +18 -0
  58. data/lib/chef/provider.rb +1 -1
  59. data/lib/chef/provider/cron.rb +1 -1
  60. data/lib/chef/provider/directory.rb +6 -6
  61. data/lib/chef/provider/execute.rb +2 -1
  62. data/lib/chef/provider/file.rb +3 -3
  63. data/lib/chef/provider/git.rb +5 -7
  64. data/lib/chef/provider/group/groupadd.rb +3 -3
  65. data/lib/chef/provider/group/groupmod.rb +3 -3
  66. data/lib/chef/provider/group/pw.rb +3 -3
  67. data/lib/chef/provider/ifconfig.rb +2 -2
  68. data/lib/chef/provider/link.rb +3 -3
  69. data/lib/chef/provider/lwrp_base.rb +1 -1
  70. data/lib/chef/provider/mount.rb +5 -5
  71. data/lib/chef/provider/mount/aix.rb +3 -3
  72. data/lib/chef/provider/mount/mount.rb +5 -5
  73. data/lib/chef/provider/mount/windows.rb +1 -1
  74. data/lib/chef/provider/package.rb +17 -21
  75. data/lib/chef/provider/package/apt.rb +27 -1
  76. data/lib/chef/provider/package/deb.rb +3 -3
  77. data/lib/chef/provider/package/dnf/dnf_helper.py +12 -11
  78. data/lib/chef/provider/package/dnf/python_helper.rb +9 -8
  79. data/lib/chef/provider/package/habitat.rb +168 -0
  80. data/lib/chef/provider/package/portage.rb +2 -2
  81. data/lib/chef/provider/package/powershell.rb +5 -0
  82. data/lib/chef/provider/package/rubygems.rb +11 -17
  83. data/lib/chef/provider/package/windows.rb +2 -4
  84. data/lib/chef/provider/package/yum.rb +1 -4
  85. data/lib/chef/provider/package/yum/python_helper.rb +15 -10
  86. data/lib/chef/provider/package/yum/yum_helper.py +47 -63
  87. data/lib/chef/provider/registry_key.rb +1 -1
  88. data/lib/chef/provider/route.rb +2 -2
  89. data/lib/chef/provider/service.rb +6 -6
  90. data/lib/chef/provider/service/aixinit.rb +1 -1
  91. data/lib/chef/provider/service/debian.rb +1 -1
  92. data/lib/chef/provider/service/freebsd.rb +15 -21
  93. data/lib/chef/provider/service/macosx.rb +4 -4
  94. data/lib/chef/provider/service/systemd.rb +43 -14
  95. data/lib/chef/provider/service/upstart.rb +2 -13
  96. data/lib/chef/provider/service/windows.rb +12 -12
  97. data/lib/chef/provider/subversion.rb +10 -12
  98. data/lib/chef/provider/support/zypper_repo.erb +4 -2
  99. data/lib/chef/provider/systemd_unit.rb +36 -10
  100. data/lib/chef/provider/template/content.rb +3 -7
  101. data/lib/chef/provider/user.rb +2 -2
  102. data/lib/chef/provider/user/dscl.rb +1 -1
  103. data/lib/chef/provider/user/mac.rb +17 -20
  104. data/lib/chef/provider/user/pw.rb +1 -1
  105. data/lib/chef/provider/user/windows.rb +1 -1
  106. data/lib/chef/provider/windows_script.rb +1 -1
  107. data/lib/chef/provider/zypper_repository.rb +28 -32
  108. data/lib/chef/providers.rb +1 -1
  109. data/lib/chef/resource.rb +6 -7
  110. data/lib/chef/resource/alternatives.rb +6 -6
  111. data/lib/chef/resource/apt_package.rb +1 -1
  112. data/lib/chef/resource/apt_preference.rb +2 -2
  113. data/lib/chef/resource/apt_repository.rb +6 -6
  114. data/lib/chef/resource/apt_update.rb +5 -4
  115. data/lib/chef/resource/archive_file.rb +2 -3
  116. data/lib/chef/resource/breakpoint.rb +1 -1
  117. data/lib/chef/resource/build_essential.rb +2 -6
  118. data/lib/chef/resource/chef_client_config.rb +10 -5
  119. data/lib/chef/resource/chef_client_cron.rb +5 -5
  120. data/lib/chef/resource/chef_client_launchd.rb +6 -6
  121. data/lib/chef/resource/chef_client_scheduled_task.rb +16 -16
  122. data/lib/chef/resource/chef_client_systemd_timer.rb +5 -5
  123. data/lib/chef/resource/chef_client_trusted_certificate.rb +2 -2
  124. data/lib/chef/resource/chef_handler.rb +3 -7
  125. data/lib/chef/resource/chef_sleep.rb +1 -1
  126. data/lib/chef/resource/chef_vault_secret.rb +5 -10
  127. data/lib/chef/resource/chocolatey_config.rb +2 -6
  128. data/lib/chef/resource/chocolatey_feature.rb +2 -6
  129. data/lib/chef/resource/chocolatey_source.rb +4 -10
  130. data/lib/chef/resource/cron/_cron_shared.rb +2 -2
  131. data/lib/chef/resource/cron/cron_d.rb +4 -6
  132. data/lib/chef/resource/cron_access.rb +2 -4
  133. data/lib/chef/resource/dmg_package.rb +6 -10
  134. data/lib/chef/resource/dpkg_package.rb +1 -1
  135. data/lib/chef/resource/dsc_resource.rb +1 -1
  136. data/lib/chef/resource/execute.rb +11 -6
  137. data/lib/chef/resource/file.rb +1 -1
  138. data/lib/chef/resource/gem_package.rb +2 -1
  139. data/lib/chef/resource/group.rb +6 -6
  140. data/lib/chef/{knife/recipe_list.rb → resource/habitat/_habitat_shared.rb} +13 -17
  141. data/lib/chef/resource/habitat/habitat_package.rb +129 -0
  142. data/lib/chef/resource/habitat/habitat_sup.rb +329 -0
  143. data/lib/chef/resource/habitat/habitat_sup_systemd.rb +67 -0
  144. data/lib/chef/resource/habitat/habitat_sup_windows.rb +90 -0
  145. data/lib/chef/resource/habitat_config.rb +107 -0
  146. data/lib/chef/resource/habitat_install.rb +247 -0
  147. data/lib/chef/resource/habitat_service.rb +451 -0
  148. data/lib/chef/resource/habitat_user_toml.rb +92 -0
  149. data/lib/chef/resource/homebrew_cask.rb +17 -10
  150. data/lib/chef/resource/homebrew_package.rb +1 -1
  151. data/lib/chef/resource/homebrew_tap.rb +4 -7
  152. data/lib/chef/resource/homebrew_update.rb +2 -2
  153. data/lib/chef/resource/hostname.rb +68 -22
  154. data/lib/chef/resource/http_request.rb +1 -1
  155. data/lib/chef/resource/inspec_waiver_file_entry.rb +156 -0
  156. data/lib/chef/resource/kernel_module.rb +6 -17
  157. data/lib/chef/resource/locale.rb +2 -3
  158. data/lib/chef/resource/lwrp_base.rb +20 -1
  159. data/lib/chef/resource/macos_userdefaults.rb +10 -14
  160. data/lib/chef/resource/mdadm.rb +53 -7
  161. data/lib/chef/resource/mount.rb +2 -1
  162. data/lib/chef/resource/ohai_hint.rb +2 -6
  163. data/lib/chef/resource/openbsd_package.rb +17 -0
  164. data/lib/chef/resource/openssl_dhparam.rb +1 -2
  165. data/lib/chef/resource/openssl_ec_private_key.rb +3 -5
  166. data/lib/chef/resource/openssl_ec_public_key.rb +1 -3
  167. data/lib/chef/resource/openssl_rsa_private_key.rb +2 -4
  168. data/lib/chef/resource/openssl_rsa_public_key.rb +1 -3
  169. data/lib/chef/resource/openssl_x509_certificate.rb +3 -6
  170. data/lib/chef/resource/openssl_x509_crl.rb +1 -3
  171. data/lib/chef/resource/openssl_x509_request.rb +1 -3
  172. data/lib/chef/resource/osx_profile.rb +3 -3
  173. data/lib/chef/resource/plist.rb +8 -8
  174. data/lib/chef/resource/powershell_package_source.rb +2 -4
  175. data/lib/chef/resource/powershell_script.rb +1 -1
  176. data/lib/chef/resource/reboot.rb +38 -9
  177. data/lib/chef/resource/remote_directory.rb +2 -2
  178. data/lib/chef/resource/remote_file.rb +3 -3
  179. data/lib/chef/resource/rhsm_errata.rb +16 -3
  180. data/lib/chef/resource/rhsm_errata_level.rb +11 -6
  181. data/lib/chef/resource/rhsm_register.rb +12 -6
  182. data/lib/chef/resource/rhsm_repo.rb +17 -6
  183. data/lib/chef/resource/rhsm_subscription.rb +2 -6
  184. data/lib/chef/resource/scm/git.rb +1 -1
  185. data/lib/chef/resource/ssh_known_hosts_entry.rb +4 -7
  186. data/lib/chef/resource/sudo.rb +8 -12
  187. data/lib/chef/resource/support/HabService.dll.config.erb +19 -0
  188. data/lib/chef/resource/support/client.erb +8 -1
  189. data/lib/chef/resource/support/sup.toml.erb +179 -0
  190. data/lib/chef/resource/swap_file.rb +2 -6
  191. data/lib/chef/resource/sysctl.rb +2 -6
  192. data/lib/chef/resource/systemd_unit.rb +2 -2
  193. data/lib/chef/resource/template.rb +1 -1
  194. data/lib/chef/resource/timezone.rb +1 -3
  195. data/lib/chef/resource/user/mac_user.rb +1 -1
  196. data/lib/chef/resource/user_ulimit.rb +2 -2
  197. data/lib/chef/resource/windows_ad_join.rb +2 -6
  198. data/lib/chef/resource/windows_audit_policy.rb +2 -2
  199. data/lib/chef/resource/windows_auto_run.rb +2 -5
  200. data/lib/chef/resource/windows_certificate.rb +207 -73
  201. data/lib/chef/resource/windows_defender.rb +163 -0
  202. data/lib/chef/resource/windows_defender_exclusion.rb +125 -0
  203. data/lib/chef/resource/windows_dfs_folder.rb +2 -6
  204. data/lib/chef/resource/windows_dfs_namespace.rb +2 -6
  205. data/lib/chef/resource/windows_dfs_server.rb +1 -3
  206. data/lib/chef/resource/windows_dns_record.rb +2 -6
  207. data/lib/chef/resource/windows_dns_zone.rb +2 -6
  208. data/lib/chef/resource/windows_env.rb +6 -5
  209. data/lib/chef/resource/windows_feature.rb +3 -9
  210. data/lib/chef/resource/windows_feature_dism.rb +3 -9
  211. data/lib/chef/resource/windows_feature_powershell.rb +3 -3
  212. data/lib/chef/resource/windows_firewall_profile.rb +4 -4
  213. data/lib/chef/resource/windows_firewall_rule.rb +20 -9
  214. data/lib/chef/resource/windows_font.rb +3 -5
  215. data/lib/chef/resource/windows_pagefile.rb +104 -69
  216. data/lib/chef/resource/windows_path.rb +4 -4
  217. data/lib/chef/resource/windows_printer.rb +80 -61
  218. data/lib/chef/resource/windows_printer_port.rb +49 -66
  219. data/lib/chef/resource/windows_security_policy.rb +56 -40
  220. data/lib/chef/resource/windows_share.rb +14 -21
  221. data/lib/chef/resource/windows_shortcut.rb +4 -6
  222. data/lib/chef/resource/windows_task.rb +19 -7
  223. data/lib/chef/resource/windows_uac.rb +3 -5
  224. data/lib/chef/resource/windows_update_settings.rb +259 -0
  225. data/lib/chef/resource/windows_user_privilege.rb +4 -4
  226. data/lib/chef/resource/windows_workgroup.rb +3 -4
  227. data/lib/chef/resource/yum_package.rb +10 -10
  228. data/lib/chef/resource/zypper_package.rb +4 -4
  229. data/lib/chef/resource/zypper_repository.rb +28 -8
  230. data/lib/chef/resource_builder.rb +8 -2
  231. data/lib/chef/resource_reporter.rb +0 -1
  232. data/lib/chef/resources.rb +13 -2
  233. data/lib/chef/run_lock.rb +1 -1
  234. data/lib/chef/runner.rb +1 -1
  235. data/lib/chef/secret_fetcher.rb +54 -0
  236. data/lib/chef/secret_fetcher/aws_secrets_manager.rb +53 -0
  237. data/lib/chef/secret_fetcher/azure_key_vault.rb +56 -0
  238. data/lib/chef/secret_fetcher/base.rb +72 -0
  239. data/lib/chef/secret_fetcher/example.rb +46 -0
  240. data/lib/chef/shell/ext.rb +3 -3
  241. data/lib/chef/user.rb +0 -1
  242. data/lib/chef/user_v1.rb +3 -4
  243. data/lib/chef/util/dsc/configuration_generator.rb +1 -0
  244. data/lib/chef/util/dsc/local_configuration_manager.rb +1 -1
  245. data/lib/chef/version.rb +1 -1
  246. data/lib/chef/win32/api.rb +9 -2
  247. data/lib/chef/win32/registry.rb +4 -2
  248. data/spec/data/cookbooks/openldap/libraries/openldap.rb +1 -1
  249. data/spec/data/lwrp/resources/bar.rb +2 -0
  250. data/spec/data/lwrp/resources/buck_passer.rb +1 -0
  251. data/spec/data/lwrp/resources/buck_passer_2.rb +1 -0
  252. data/spec/data/lwrp/resources/embedded_resource_accesses_providers_scope.rb +1 -0
  253. data/spec/data/lwrp/resources/foo.rb +2 -0
  254. data/spec/data/lwrp/resources/inline_compiler.rb +1 -0
  255. data/spec/data/lwrp/resources/monkey_name_printer.rb +1 -0
  256. data/spec/data/lwrp/resources/paint_drying_watcher.rb +1 -0
  257. data/spec/data/lwrp/resources/thumb_twiddler.rb +1 -0
  258. data/spec/data/lwrp/resources_with_default_attributes/nodeattr.rb +2 -0
  259. data/spec/data/lwrp_const_scoping/resources/conflict.rb +1 -0
  260. data/spec/data/lwrp_override/resources/foo.rb +1 -0
  261. data/spec/data/rubygems.org/nonexistent_gem-info +1 -0
  262. data/spec/data/rubygems.org/sexp_processor-info +49 -0
  263. data/spec/data/run_context/cookbooks/circular-dep1/resources/resource.rb +1 -0
  264. data/spec/data/run_context/cookbooks/circular-dep2/resources/resource.rb +1 -0
  265. data/spec/data/run_context/cookbooks/dependency1/resources/resource.rb +1 -0
  266. data/spec/data/run_context/cookbooks/dependency2/resources/resource.rb +1 -0
  267. data/spec/data/run_context/cookbooks/no-default-attr/resources/resource.rb +1 -0
  268. data/spec/data/run_context/cookbooks/test-with-circular-deps/resources/resource.rb +2 -0
  269. data/spec/data/run_context/cookbooks/test-with-deps/resources/resource.rb +1 -0
  270. data/spec/data/run_context/cookbooks/test/resources/resource.rb +2 -0
  271. data/spec/functional/dsl/registry_helper_spec.rb +1 -1
  272. data/spec/functional/mixin/from_file_spec.rb +1 -1
  273. data/spec/functional/resource/aixinit_service_spec.rb +7 -7
  274. data/spec/functional/resource/apt_package_spec.rb +1 -1
  275. data/spec/functional/resource/chocolatey_package_spec.rb +13 -0
  276. data/spec/functional/resource/dnf_package_spec.rb +857 -534
  277. data/spec/functional/resource/group_spec.rb +1 -1
  278. data/spec/functional/resource/link_spec.rb +1 -1
  279. data/spec/functional/resource/registry_spec.rb +8 -8
  280. data/spec/functional/resource/remote_file_spec.rb +1 -1
  281. data/spec/functional/resource/user/mac_user_spec.rb +2 -2
  282. data/spec/functional/resource/windows_certificate_spec.rb +92 -35
  283. data/spec/functional/resource/windows_env_spec.rb +2 -2
  284. data/spec/functional/resource/windows_hostname_spec.rb +91 -0
  285. data/spec/functional/resource/windows_pagefile_spec.rb +98 -0
  286. data/spec/functional/resource/yum_package_spec.rb +495 -428
  287. data/spec/functional/version_spec.rb +1 -1
  288. data/spec/functional/win32/registry_spec.rb +1 -1
  289. data/spec/integration/client/client_spec.rb +5 -22
  290. data/spec/integration/client/exit_code_spec.rb +1 -1
  291. data/spec/integration/client/ipv6_spec.rb +1 -1
  292. data/spec/integration/compliance/compliance_spec.rb +1 -1
  293. data/spec/integration/ohai/ohai_spec.rb +7 -6
  294. data/spec/integration/recipes/accumulator_spec.rb +13 -1
  295. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +5 -1
  296. data/spec/integration/recipes/lwrp_spec.rb +3 -1
  297. data/spec/integration/recipes/notifies_spec.rb +15 -1
  298. data/spec/integration/recipes/notifying_block_spec.rb +2 -1
  299. data/spec/integration/recipes/recipe_dsl_spec.rb +10 -10
  300. data/spec/integration/recipes/resource_action_spec.rb +4 -4
  301. data/spec/integration/recipes/unified_mode_spec.rb +71 -1
  302. data/spec/integration/recipes/use_partial_spec.rb +4 -1
  303. data/spec/spec_helper.rb +13 -13
  304. data/spec/support/chef_helpers.rb +1 -17
  305. data/spec/support/lib/chef/resource/with_state.rb +0 -1
  306. data/spec/support/lib/chef/resource/zen_follower.rb +0 -1
  307. data/spec/support/lib/chef/resource/zen_master.rb +0 -1
  308. data/spec/support/matchers/leak.rb +7 -9
  309. data/spec/support/platform_helpers.rb +1 -8
  310. data/spec/support/shared/functional/execute_resource.rb +1 -1
  311. data/spec/support/shared/integration/integration_helper.rb +0 -1
  312. data/spec/support/shared/unit/provider/file.rb +3 -9
  313. data/spec/support/shared/unit/script_resource.rb +2 -2
  314. data/spec/unit/application/solo_spec.rb +2 -2
  315. data/spec/unit/chef_fs/diff_spec.rb +1 -1
  316. data/spec/unit/chef_fs/file_system/repository/directory_spec.rb +1 -1
  317. data/spec/unit/chef_fs/file_system_spec.rb +1 -1
  318. data/spec/unit/compliance/fetcher/automate_spec.rb +0 -16
  319. data/spec/unit/compliance/reporter/automate_spec.rb +26 -2
  320. data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +20 -0
  321. data/spec/unit/compliance/reporter/compliance_enforcer_spec.rb +1 -0
  322. data/spec/unit/compliance/runner_spec.rb +31 -5
  323. data/spec/unit/cookbook_version_spec.rb +52 -0
  324. data/spec/unit/data_bag_item_spec.rb +1 -6
  325. data/spec/unit/data_collector_spec.rb +47 -1
  326. data/spec/unit/dsl/reboot_pending_spec.rb +2 -2
  327. data/spec/unit/dsl/registry_helper_spec.rb +1 -1
  328. data/spec/unit/dsl/render_helpers_spec.rb +102 -0
  329. data/spec/unit/dsl/secret_spec.rb +65 -0
  330. data/spec/unit/handler_spec.rb +8 -2
  331. data/spec/unit/lwrp_spec.rb +1 -1
  332. data/spec/unit/mixin/params_validate_spec.rb +4 -3
  333. data/spec/unit/node/attribute_spec.rb +1 -1
  334. data/spec/unit/node_spec.rb +78 -0
  335. data/spec/unit/org_group_spec.rb +45 -0
  336. data/spec/unit/policy_builder/dynamic_spec.rb +0 -5
  337. data/spec/unit/policy_builder/policyfile_spec.rb +144 -56
  338. data/spec/unit/property_spec.rb +23 -22
  339. data/spec/unit/provider/apt_update_spec.rb +3 -1
  340. data/spec/unit/provider/cron_spec.rb +1 -1
  341. data/spec/unit/provider/group/gpasswd_spec.rb +2 -2
  342. data/spec/unit/provider/group/groupmod_spec.rb +2 -2
  343. data/spec/unit/provider/group/pw_spec.rb +2 -2
  344. data/spec/unit/provider/group_spec.rb +1 -1
  345. data/spec/unit/provider/link_spec.rb +1 -1
  346. data/spec/unit/provider/mount/aix_spec.rb +1 -1
  347. data/spec/unit/provider/package/apt_spec.rb +84 -18
  348. data/spec/unit/provider/package/deb_spec.rb +3 -3
  349. data/spec/unit/provider/package/dnf/python_helper_spec.rb +1 -0
  350. data/spec/unit/provider/package/powershell_spec.rb +74 -12
  351. data/spec/unit/provider/package/rubygems_spec.rb +21 -33
  352. data/spec/unit/provider/package/yum/python_helper_spec.rb +1 -0
  353. data/spec/unit/provider/service/arch_service_spec.rb +1 -0
  354. data/spec/unit/provider/service/debian_service_spec.rb +1 -0
  355. data/spec/unit/provider/service/macosx_spec.rb +2 -2
  356. data/spec/unit/provider/service/systemd_service_spec.rb +138 -23
  357. data/spec/unit/provider/service/upstart_service_spec.rb +0 -29
  358. data/spec/unit/provider/service/windows_spec.rb +2 -2
  359. data/spec/unit/provider/subversion_spec.rb +2 -2
  360. data/spec/unit/provider/systemd_unit_spec.rb +79 -60
  361. data/spec/unit/provider/zypper_repository_spec.rb +5 -12
  362. data/spec/unit/provider_spec.rb +0 -8
  363. data/spec/unit/resource/inspec_waiver_file_entry_spec.rb +80 -0
  364. data/spec/unit/resource/powershell_script_spec.rb +2 -2
  365. data/spec/unit/resource/windows_defender_exclusion_spec.rb +62 -0
  366. data/spec/unit/resource/windows_defender_spec.rb +71 -0
  367. data/spec/unit/resource/windows_firewall_rule_spec.rb +12 -7
  368. data/spec/unit/resource/windows_pagefile_spec.rb +4 -9
  369. data/spec/unit/resource/windows_task_spec.rb +1 -1
  370. data/spec/unit/resource/windows_update_settings_spec.rb +64 -0
  371. data/spec/unit/resource/zypper_repository_spec.rb +1 -1
  372. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +63 -0
  373. data/spec/unit/secret_fetcher_spec.rb +82 -0
  374. data/spec/unit/user_spec.rb +1 -1
  375. data/spec/unit/user_v1_spec.rb +6 -4
  376. data/tasks/rspec.rb +9 -6
  377. metadata +59 -519
  378. data/bin/knife +0 -24
  379. data/lib/chef/application/knife.rb +0 -234
  380. data/lib/chef/application/windows_service.rb +0 -338
  381. data/lib/chef/application/windows_service_manager.rb +0 -205
  382. data/lib/chef/chef_fs/knife.rb +0 -160
  383. data/lib/chef/chef_fs/parallelizer.rb +0 -102
  384. data/lib/chef/chef_fs/parallelizer/flatten_enumerable.rb +0 -35
  385. data/lib/chef/chef_fs/parallelizer/parallel_enumerable.rb +0 -278
  386. data/lib/chef/cookbook_site_streaming_uploader.rb +0 -244
  387. data/lib/chef/knife.rb +0 -665
  388. data/lib/chef/knife/acl_add.rb +0 -57
  389. data/lib/chef/knife/acl_base.rb +0 -183
  390. data/lib/chef/knife/acl_bulk_add.rb +0 -78
  391. data/lib/chef/knife/acl_bulk_remove.rb +0 -83
  392. data/lib/chef/knife/acl_remove.rb +0 -62
  393. data/lib/chef/knife/acl_show.rb +0 -56
  394. data/lib/chef/knife/bootstrap.rb +0 -1192
  395. data/lib/chef/knife/bootstrap/chef_vault_handler.rb +0 -162
  396. data/lib/chef/knife/bootstrap/client_builder.rb +0 -212
  397. data/lib/chef/knife/bootstrap/templates/README.md +0 -11
  398. data/lib/chef/knife/bootstrap/templates/chef-full.erb +0 -242
  399. data/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb +0 -278
  400. data/lib/chef/knife/bootstrap/train_connector.rb +0 -336
  401. data/lib/chef/knife/client_bulk_delete.rb +0 -104
  402. data/lib/chef/knife/client_create.rb +0 -101
  403. data/lib/chef/knife/client_delete.rb +0 -62
  404. data/lib/chef/knife/client_edit.rb +0 -52
  405. data/lib/chef/knife/client_key_create.rb +0 -73
  406. data/lib/chef/knife/client_key_delete.rb +0 -80
  407. data/lib/chef/knife/client_key_edit.rb +0 -83
  408. data/lib/chef/knife/client_key_list.rb +0 -73
  409. data/lib/chef/knife/client_key_show.rb +0 -80
  410. data/lib/chef/knife/client_list.rb +0 -41
  411. data/lib/chef/knife/client_reregister.rb +0 -58
  412. data/lib/chef/knife/client_show.rb +0 -48
  413. data/lib/chef/knife/config_get.rb +0 -39
  414. data/lib/chef/knife/config_get_profile.rb +0 -37
  415. data/lib/chef/knife/config_list.rb +0 -139
  416. data/lib/chef/knife/config_list_profiles.rb +0 -37
  417. data/lib/chef/knife/config_show.rb +0 -127
  418. data/lib/chef/knife/config_use.rb +0 -61
  419. data/lib/chef/knife/config_use_profile.rb +0 -47
  420. data/lib/chef/knife/configure.rb +0 -150
  421. data/lib/chef/knife/configure_client.rb +0 -48
  422. data/lib/chef/knife/cookbook_bulk_delete.rb +0 -71
  423. data/lib/chef/knife/cookbook_delete.rb +0 -151
  424. data/lib/chef/knife/cookbook_download.rb +0 -142
  425. data/lib/chef/knife/cookbook_list.rb +0 -47
  426. data/lib/chef/knife/cookbook_metadata.rb +0 -106
  427. data/lib/chef/knife/cookbook_metadata_from_file.rb +0 -49
  428. data/lib/chef/knife/cookbook_show.rb +0 -98
  429. data/lib/chef/knife/cookbook_upload.rb +0 -292
  430. data/lib/chef/knife/core/bootstrap_context.rb +0 -264
  431. data/lib/chef/knife/core/cookbook_scm_repo.rb +0 -159
  432. data/lib/chef/knife/core/formatting_options.rb +0 -49
  433. data/lib/chef/knife/core/gem_glob_loader.rb +0 -138
  434. data/lib/chef/knife/core/generic_presenter.rb +0 -232
  435. data/lib/chef/knife/core/hashed_command_loader.rb +0 -100
  436. data/lib/chef/knife/core/node_editor.rb +0 -130
  437. data/lib/chef/knife/core/node_presenter.rb +0 -133
  438. data/lib/chef/knife/core/object_loader.rb +0 -115
  439. data/lib/chef/knife/core/status_presenter.rb +0 -147
  440. data/lib/chef/knife/core/subcommand_loader.rb +0 -203
  441. data/lib/chef/knife/core/text_formatter.rb +0 -85
  442. data/lib/chef/knife/core/ui.rb +0 -338
  443. data/lib/chef/knife/core/windows_bootstrap_context.rb +0 -406
  444. data/lib/chef/knife/data_bag_create.rb +0 -81
  445. data/lib/chef/knife/data_bag_delete.rb +0 -49
  446. data/lib/chef/knife/data_bag_edit.rb +0 -74
  447. data/lib/chef/knife/data_bag_from_file.rb +0 -113
  448. data/lib/chef/knife/data_bag_list.rb +0 -42
  449. data/lib/chef/knife/data_bag_secret_options.rb +0 -122
  450. data/lib/chef/knife/data_bag_show.rb +0 -69
  451. data/lib/chef/knife/delete.rb +0 -125
  452. data/lib/chef/knife/deps.rb +0 -156
  453. data/lib/chef/knife/diff.rb +0 -83
  454. data/lib/chef/knife/download.rb +0 -84
  455. data/lib/chef/knife/edit.rb +0 -88
  456. data/lib/chef/knife/environment_compare.rb +0 -128
  457. data/lib/chef/knife/environment_create.rb +0 -52
  458. data/lib/chef/knife/environment_delete.rb +0 -44
  459. data/lib/chef/knife/environment_edit.rb +0 -44
  460. data/lib/chef/knife/environment_from_file.rb +0 -84
  461. data/lib/chef/knife/environment_list.rb +0 -41
  462. data/lib/chef/knife/environment_show.rb +0 -47
  463. data/lib/chef/knife/exec.rb +0 -99
  464. data/lib/chef/knife/group_add.rb +0 -55
  465. data/lib/chef/knife/group_create.rb +0 -49
  466. data/lib/chef/knife/group_destroy.rb +0 -53
  467. data/lib/chef/knife/group_remove.rb +0 -56
  468. data/lib/chef/knife/group_show.rb +0 -49
  469. data/lib/chef/knife/key_create.rb +0 -112
  470. data/lib/chef/knife/key_create_base.rb +0 -50
  471. data/lib/chef/knife/key_delete.rb +0 -55
  472. data/lib/chef/knife/key_edit.rb +0 -118
  473. data/lib/chef/knife/key_edit_base.rb +0 -55
  474. data/lib/chef/knife/key_list.rb +0 -90
  475. data/lib/chef/knife/key_list_base.rb +0 -45
  476. data/lib/chef/knife/key_show.rb +0 -53
  477. data/lib/chef/knife/list.rb +0 -177
  478. data/lib/chef/knife/node_bulk_delete.rb +0 -75
  479. data/lib/chef/knife/node_create.rb +0 -47
  480. data/lib/chef/knife/node_delete.rb +0 -46
  481. data/lib/chef/knife/node_edit.rb +0 -70
  482. data/lib/chef/knife/node_environment_set.rb +0 -53
  483. data/lib/chef/knife/node_from_file.rb +0 -51
  484. data/lib/chef/knife/node_list.rb +0 -44
  485. data/lib/chef/knife/node_policy_set.rb +0 -79
  486. data/lib/chef/knife/node_run_list_add.rb +0 -104
  487. data/lib/chef/knife/node_run_list_remove.rb +0 -67
  488. data/lib/chef/knife/node_run_list_set.rb +0 -66
  489. data/lib/chef/knife/node_show.rb +0 -63
  490. data/lib/chef/knife/null.rb +0 -12
  491. data/lib/chef/knife/raw.rb +0 -123
  492. data/lib/chef/knife/rehash.rb +0 -50
  493. data/lib/chef/knife/role_bulk_delete.rb +0 -66
  494. data/lib/chef/knife/role_create.rb +0 -53
  495. data/lib/chef/knife/role_delete.rb +0 -46
  496. data/lib/chef/knife/role_edit.rb +0 -45
  497. data/lib/chef/knife/role_env_run_list_add.rb +0 -87
  498. data/lib/chef/knife/role_env_run_list_clear.rb +0 -55
  499. data/lib/chef/knife/role_env_run_list_remove.rb +0 -57
  500. data/lib/chef/knife/role_env_run_list_replace.rb +0 -60
  501. data/lib/chef/knife/role_env_run_list_set.rb +0 -70
  502. data/lib/chef/knife/role_from_file.rb +0 -51
  503. data/lib/chef/knife/role_list.rb +0 -42
  504. data/lib/chef/knife/role_run_list_add.rb +0 -87
  505. data/lib/chef/knife/role_run_list_clear.rb +0 -55
  506. data/lib/chef/knife/role_run_list_remove.rb +0 -56
  507. data/lib/chef/knife/role_run_list_replace.rb +0 -60
  508. data/lib/chef/knife/role_run_list_set.rb +0 -69
  509. data/lib/chef/knife/role_show.rb +0 -48
  510. data/lib/chef/knife/search.rb +0 -194
  511. data/lib/chef/knife/serve.rb +0 -65
  512. data/lib/chef/knife/show.rb +0 -72
  513. data/lib/chef/knife/ssh.rb +0 -645
  514. data/lib/chef/knife/ssl_check.rb +0 -284
  515. data/lib/chef/knife/ssl_fetch.rb +0 -161
  516. data/lib/chef/knife/status.rb +0 -95
  517. data/lib/chef/knife/supermarket_download.rb +0 -121
  518. data/lib/chef/knife/supermarket_install.rb +0 -192
  519. data/lib/chef/knife/supermarket_list.rb +0 -76
  520. data/lib/chef/knife/supermarket_search.rb +0 -53
  521. data/lib/chef/knife/supermarket_share.rb +0 -166
  522. data/lib/chef/knife/supermarket_show.rb +0 -66
  523. data/lib/chef/knife/supermarket_unshare.rb +0 -61
  524. data/lib/chef/knife/tag_create.rb +0 -52
  525. data/lib/chef/knife/tag_delete.rb +0 -60
  526. data/lib/chef/knife/tag_list.rb +0 -47
  527. data/lib/chef/knife/upload.rb +0 -86
  528. data/lib/chef/knife/user_create.rb +0 -107
  529. data/lib/chef/knife/user_delete.rb +0 -44
  530. data/lib/chef/knife/user_dissociate.rb +0 -42
  531. data/lib/chef/knife/user_edit.rb +0 -52
  532. data/lib/chef/knife/user_invite_add.rb +0 -43
  533. data/lib/chef/knife/user_invite_list.rb +0 -34
  534. data/lib/chef/knife/user_invite_rescind.rb +0 -63
  535. data/lib/chef/knife/user_key_create.rb +0 -73
  536. data/lib/chef/knife/user_key_delete.rb +0 -80
  537. data/lib/chef/knife/user_key_edit.rb +0 -83
  538. data/lib/chef/knife/user_key_list.rb +0 -73
  539. data/lib/chef/knife/user_key_show.rb +0 -80
  540. data/lib/chef/knife/user_list.rb +0 -42
  541. data/lib/chef/knife/user_reregister.rb +0 -59
  542. data/lib/chef/knife/user_show.rb +0 -48
  543. data/lib/chef/knife/xargs.rb +0 -282
  544. data/lib/chef/knife/yaml_convert.rb +0 -91
  545. data/lib/chef/provider/package/yum/simplejson/LICENSE.txt +0 -79
  546. data/lib/chef/provider/package/yum/simplejson/__init__.py +0 -318
  547. data/lib/chef/provider/package/yum/simplejson/__init__.pyc +0 -0
  548. data/lib/chef/provider/package/yum/simplejson/decoder.py +0 -354
  549. data/lib/chef/provider/package/yum/simplejson/decoder.pyc +0 -0
  550. data/lib/chef/provider/package/yum/simplejson/encoder.py +0 -440
  551. data/lib/chef/provider/package/yum/simplejson/encoder.pyc +0 -0
  552. data/lib/chef/provider/package/yum/simplejson/scanner.py +0 -65
  553. data/lib/chef/provider/package/yum/simplejson/scanner.pyc +0 -0
  554. data/lib/chef/provider/package/yum/simplejson/tool.py +0 -37
  555. data/lib/chef/resource/user/dscl_user.rb +0 -35
  556. data/spec/functional/knife/configure_spec.rb +0 -33
  557. data/spec/functional/knife/cookbook_delete_spec.rb +0 -156
  558. data/spec/functional/knife/exec_spec.rb +0 -55
  559. data/spec/functional/knife/rehash_spec.rb +0 -39
  560. data/spec/functional/knife/smoke_test.rb +0 -42
  561. data/spec/functional/knife/ssh_spec.rb +0 -352
  562. data/spec/functional/resource/user/dscl_spec.rb +0 -188
  563. data/spec/functional/resource/windows_service_spec.rb +0 -105
  564. data/spec/functional/win32/service_manager_spec.rb +0 -220
  565. data/spec/integration/knife/chef_fs_data_store_spec.rb +0 -557
  566. data/spec/integration/knife/chef_repo_path_spec.rb +0 -962
  567. data/spec/integration/knife/chef_repository_file_system_spec.rb +0 -200
  568. data/spec/integration/knife/chefignore_spec.rb +0 -301
  569. data/spec/integration/knife/client_bulk_delete_spec.rb +0 -131
  570. data/spec/integration/knife/client_create_spec.rb +0 -70
  571. data/spec/integration/knife/client_delete_spec.rb +0 -64
  572. data/spec/integration/knife/client_key_create_spec.rb +0 -66
  573. data/spec/integration/knife/client_key_delete_spec.rb +0 -43
  574. data/spec/integration/knife/client_key_list_spec.rb +0 -61
  575. data/spec/integration/knife/client_key_show_spec.rb +0 -45
  576. data/spec/integration/knife/client_list_spec.rb +0 -49
  577. data/spec/integration/knife/client_show_spec.rb +0 -37
  578. data/spec/integration/knife/common_options_spec.rb +0 -174
  579. data/spec/integration/knife/config_list_spec.rb +0 -220
  580. data/spec/integration/knife/config_show_spec.rb +0 -192
  581. data/spec/integration/knife/config_use_spec.rb +0 -198
  582. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +0 -113
  583. data/spec/integration/knife/cookbook_bulk_delete_spec.rb +0 -65
  584. data/spec/integration/knife/cookbook_download_spec.rb +0 -72
  585. data/spec/integration/knife/cookbook_list_spec.rb +0 -55
  586. data/spec/integration/knife/cookbook_show_spec.rb +0 -149
  587. data/spec/integration/knife/cookbook_upload_spec.rb +0 -128
  588. data/spec/integration/knife/data_bag_create_spec.rb +0 -125
  589. data/spec/integration/knife/data_bag_delete_spec.rb +0 -59
  590. data/spec/integration/knife/data_bag_edit_spec.rb +0 -105
  591. data/spec/integration/knife/data_bag_from_file_spec.rb +0 -116
  592. data/spec/integration/knife/data_bag_list_spec.rb +0 -44
  593. data/spec/integration/knife/data_bag_show_spec.rb +0 -95
  594. data/spec/integration/knife/delete_spec.rb +0 -1018
  595. data/spec/integration/knife/deps_spec.rb +0 -703
  596. data/spec/integration/knife/diff_spec.rb +0 -605
  597. data/spec/integration/knife/download_spec.rb +0 -1336
  598. data/spec/integration/knife/environment_compare_spec.rb +0 -75
  599. data/spec/integration/knife/environment_create_spec.rb +0 -41
  600. data/spec/integration/knife/environment_delete_spec.rb +0 -37
  601. data/spec/integration/knife/environment_from_file_spec.rb +0 -116
  602. data/spec/integration/knife/environment_list_spec.rb +0 -42
  603. data/spec/integration/knife/environment_show_spec.rb +0 -77
  604. data/spec/integration/knife/list_spec.rb +0 -1060
  605. data/spec/integration/knife/node_bulk_delete_spec.rb +0 -52
  606. data/spec/integration/knife/node_create_spec.rb +0 -47
  607. data/spec/integration/knife/node_delete_spec.rb +0 -48
  608. data/spec/integration/knife/node_environment_set_spec.rb +0 -46
  609. data/spec/integration/knife/node_from_file_spec.rb +0 -59
  610. data/spec/integration/knife/node_list_spec.rb +0 -45
  611. data/spec/integration/knife/node_run_list_add_spec.rb +0 -54
  612. data/spec/integration/knife/node_run_list_remove_spec.rb +0 -36
  613. data/spec/integration/knife/node_run_list_set_spec.rb +0 -41
  614. data/spec/integration/knife/node_show_spec.rb +0 -36
  615. data/spec/integration/knife/raw_spec.rb +0 -297
  616. data/spec/integration/knife/redirection_spec.rb +0 -64
  617. data/spec/integration/knife/role_bulk_delete_spec.rb +0 -52
  618. data/spec/integration/knife/role_create_spec.rb +0 -41
  619. data/spec/integration/knife/role_delete_spec.rb +0 -48
  620. data/spec/integration/knife/role_from_file_spec.rb +0 -96
  621. data/spec/integration/knife/role_list_spec.rb +0 -45
  622. data/spec/integration/knife/role_show_spec.rb +0 -51
  623. data/spec/integration/knife/search_node_spec.rb +0 -40
  624. data/spec/integration/knife/serve_spec.rb +0 -92
  625. data/spec/integration/knife/show_spec.rb +0 -197
  626. data/spec/integration/knife/upload_spec.rb +0 -1617
  627. data/spec/support/shared/functional/win32_service.rb +0 -57
  628. data/spec/unit/application/knife_spec.rb +0 -241
  629. data/spec/unit/chef_fs/parallelizer_spec.rb +0 -479
  630. data/spec/unit/cookbook_site_streaming_uploader_spec.rb +0 -198
  631. data/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb +0 -152
  632. data/spec/unit/knife/bootstrap/client_builder_spec.rb +0 -207
  633. data/spec/unit/knife/bootstrap/train_connector_spec.rb +0 -244
  634. data/spec/unit/knife/bootstrap_spec.rb +0 -2220
  635. data/spec/unit/knife/client_bulk_delete_spec.rb +0 -166
  636. data/spec/unit/knife/client_create_spec.rb +0 -169
  637. data/spec/unit/knife/client_delete_spec.rb +0 -99
  638. data/spec/unit/knife/client_edit_spec.rb +0 -53
  639. data/spec/unit/knife/client_list_spec.rb +0 -34
  640. data/spec/unit/knife/client_reregister_spec.rb +0 -62
  641. data/spec/unit/knife/client_show_spec.rb +0 -52
  642. data/spec/unit/knife/configure_client_spec.rb +0 -81
  643. data/spec/unit/knife/configure_spec.rb +0 -190
  644. data/spec/unit/knife/cookbook_bulk_delete_spec.rb +0 -87
  645. data/spec/unit/knife/cookbook_delete_spec.rb +0 -239
  646. data/spec/unit/knife/cookbook_download_spec.rb +0 -255
  647. data/spec/unit/knife/cookbook_list_spec.rb +0 -88
  648. data/spec/unit/knife/cookbook_metadata_from_file_spec.rb +0 -72
  649. data/spec/unit/knife/cookbook_metadata_spec.rb +0 -182
  650. data/spec/unit/knife/cookbook_show_spec.rb +0 -253
  651. data/spec/unit/knife/cookbook_upload_spec.rb +0 -364
  652. data/spec/unit/knife/core/bootstrap_context_spec.rb +0 -287
  653. data/spec/unit/knife/core/cookbook_scm_repo_spec.rb +0 -187
  654. data/spec/unit/knife/core/gem_glob_loader_spec.rb +0 -209
  655. data/spec/unit/knife/core/hashed_command_loader_spec.rb +0 -112
  656. data/spec/unit/knife/core/node_editor_spec.rb +0 -211
  657. data/spec/unit/knife/core/object_loader_spec.rb +0 -81
  658. data/spec/unit/knife/core/status_presenter_spec.rb +0 -54
  659. data/spec/unit/knife/core/subcommand_loader_spec.rb +0 -64
  660. data/spec/unit/knife/core/ui_spec.rb +0 -656
  661. data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +0 -238
  662. data/spec/unit/knife/data_bag_create_spec.rb +0 -175
  663. data/spec/unit/knife/data_bag_edit_spec.rb +0 -126
  664. data/spec/unit/knife/data_bag_from_file_spec.rb +0 -174
  665. data/spec/unit/knife/data_bag_secret_options_spec.rb +0 -173
  666. data/spec/unit/knife/data_bag_show_spec.rb +0 -139
  667. data/spec/unit/knife/environment_compare_spec.rb +0 -112
  668. data/spec/unit/knife/environment_create_spec.rb +0 -91
  669. data/spec/unit/knife/environment_delete_spec.rb +0 -71
  670. data/spec/unit/knife/environment_edit_spec.rb +0 -79
  671. data/spec/unit/knife/environment_from_file_spec.rb +0 -90
  672. data/spec/unit/knife/environment_list_spec.rb +0 -54
  673. data/spec/unit/knife/environment_show_spec.rb +0 -52
  674. data/spec/unit/knife/key_create_spec.rb +0 -223
  675. data/spec/unit/knife/key_delete_spec.rb +0 -133
  676. data/spec/unit/knife/key_edit_spec.rb +0 -264
  677. data/spec/unit/knife/key_helper.rb +0 -74
  678. data/spec/unit/knife/key_list_spec.rb +0 -216
  679. data/spec/unit/knife/key_show_spec.rb +0 -126
  680. data/spec/unit/knife/node_bulk_delete_spec.rb +0 -94
  681. data/spec/unit/knife/node_delete_spec.rb +0 -77
  682. data/spec/unit/knife/node_edit_spec.rb +0 -116
  683. data/spec/unit/knife/node_environment_set_spec.rb +0 -61
  684. data/spec/unit/knife/node_from_file_spec.rb +0 -59
  685. data/spec/unit/knife/node_list_spec.rb +0 -62
  686. data/spec/unit/knife/node_policy_set_spec.rb +0 -122
  687. data/spec/unit/knife/node_run_list_add_spec.rb +0 -145
  688. data/spec/unit/knife/node_run_list_remove_spec.rb +0 -106
  689. data/spec/unit/knife/node_run_list_set_spec.rb +0 -115
  690. data/spec/unit/knife/node_show_spec.rb +0 -65
  691. data/spec/unit/knife/raw_spec.rb +0 -43
  692. data/spec/unit/knife/role_bulk_delete_spec.rb +0 -80
  693. data/spec/unit/knife/role_create_spec.rb +0 -80
  694. data/spec/unit/knife/role_delete_spec.rb +0 -67
  695. data/spec/unit/knife/role_edit_spec.rb +0 -77
  696. data/spec/unit/knife/role_env_run_list_add_spec.rb +0 -217
  697. data/spec/unit/knife/role_env_run_list_clear_spec.rb +0 -94
  698. data/spec/unit/knife/role_env_run_list_remove_spec.rb +0 -102
  699. data/spec/unit/knife/role_env_run_list_replace_spec.rb +0 -105
  700. data/spec/unit/knife/role_env_run_list_set_spec.rb +0 -99
  701. data/spec/unit/knife/role_from_file_spec.rb +0 -69
  702. data/spec/unit/knife/role_list_spec.rb +0 -54
  703. data/spec/unit/knife/role_run_list_add_spec.rb +0 -179
  704. data/spec/unit/knife/role_run_list_clear_spec.rb +0 -84
  705. data/spec/unit/knife/role_run_list_remove_spec.rb +0 -92
  706. data/spec/unit/knife/role_run_list_replace_spec.rb +0 -98
  707. data/spec/unit/knife/role_run_list_set_spec.rb +0 -89
  708. data/spec/unit/knife/role_show_spec.rb +0 -59
  709. data/spec/unit/knife/ssh_spec.rb +0 -403
  710. data/spec/unit/knife/ssl_check_spec.rb +0 -256
  711. data/spec/unit/knife/ssl_fetch_spec.rb +0 -222
  712. data/spec/unit/knife/status_spec.rb +0 -112
  713. data/spec/unit/knife/supermarket_download_spec.rb +0 -152
  714. data/spec/unit/knife/supermarket_install_spec.rb +0 -202
  715. data/spec/unit/knife/supermarket_list_spec.rb +0 -70
  716. data/spec/unit/knife/supermarket_search_spec.rb +0 -85
  717. data/spec/unit/knife/supermarket_share_spec.rb +0 -208
  718. data/spec/unit/knife/supermarket_unshare_spec.rb +0 -78
  719. data/spec/unit/knife/tag_create_spec.rb +0 -23
  720. data/spec/unit/knife/tag_delete_spec.rb +0 -25
  721. data/spec/unit/knife/tag_list_spec.rb +0 -23
  722. data/spec/unit/knife/user_create_spec.rb +0 -184
  723. data/spec/unit/knife/user_delete_spec.rb +0 -46
  724. data/spec/unit/knife/user_edit_spec.rb +0 -48
  725. data/spec/unit/knife/user_list_spec.rb +0 -36
  726. data/spec/unit/knife/user_reregister_spec.rb +0 -56
  727. data/spec/unit/knife/user_show_spec.rb +0 -46
  728. data/spec/unit/knife_spec.rb +0 -634
  729. data/spec/unit/provider/user/dscl_spec.rb +0 -699
  730. data/spec/unit/windows_service_spec.rb +0 -118
@@ -1,244 +0,0 @@
1
- #
2
- # Copyright:: Copyright (c) Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require "spec_helper"
19
- require "ostruct"
20
- require "chef/knife/bootstrap/train_connector"
21
-
22
- describe Chef::Knife::Bootstrap::TrainConnector do
23
- let(:protocol) { "mock" }
24
- let(:family) { "unknown" }
25
- let(:release) { "unknown" } # version
26
- let(:name) { "unknown" }
27
- let(:arch) { "x86_64" }
28
- let(:connection_opts) { {} } # connection opts
29
- let(:host_url) { "mock://user1@example.com" }
30
- let(:mock_connection) { true }
31
-
32
- subject do
33
- # Example groups can still override by setting explicitly it in 'connection_opts'
34
- tc = Chef::Knife::Bootstrap::TrainConnector.new(host_url, protocol, connection_opts)
35
- tc
36
- end
37
-
38
- before(:each) do
39
- if mock_connection
40
- subject.connect!
41
- subject.connection.mock_os(
42
- family: family,
43
- name: name,
44
- release: release,
45
- arch: arch
46
- )
47
- end
48
- end
49
-
50
- describe "platform helpers" do
51
- context "on linux" do
52
- let(:family) { "debian" }
53
- let(:name) { "ubuntu" }
54
- it "reports that it is linux and unix, because that is how train classifies it" do
55
- expect(subject.unix?).to eq true
56
- expect(subject.linux?).to eq true
57
- expect(subject.windows?).to eq false
58
- end
59
- end
60
- context "on unix" do
61
- let(:family) { "os" }
62
- let(:name) { "mac_os_x" }
63
- it "reports only a unix OS" do
64
- expect(subject.unix?).to eq true
65
- expect(subject.linux?).to eq false
66
- expect(subject.windows?).to eq false
67
- end
68
- end
69
- context "on windows" do
70
- let(:family) { "windows" }
71
- let(:name) { "windows" }
72
- it "reports only a windows OS" do
73
- expect(subject.unix?).to eq false
74
- expect(subject.linux?).to eq false
75
- expect(subject.windows?).to eq true
76
- end
77
- end
78
- end
79
-
80
- describe "#connect!" do
81
- it "establishes the connection to the remote host by waiting for it" do
82
- expect(subject.connection).to receive(:wait_until_ready)
83
- subject.connect!
84
- end
85
- end
86
-
87
- describe "#initialize" do
88
- let(:mock_connection) { false }
89
-
90
- context "when provided target is a proper URL" do
91
- let(:protocol) { "ssh" }
92
- let(:host_url) { "mock://user1@localhost:2200" }
93
- it "correctly configures the instance from the URL" do
94
- expect(subject.config[:backend]).to eq "mock"
95
- expect(subject.config[:port]).to eq 2200
96
- expect(subject.config[:host]).to eq "localhost"
97
- expect(subject.config[:user]).to eq "user1"
98
- end
99
-
100
- context "and conflicting options are given" do
101
- let(:connection_opts) { { user: "user2", host: "example.com", port: 15 } }
102
- it "resolves them from the URI" do
103
- expect(subject.config[:backend]).to eq "mock"
104
- expect(subject.config[:port]).to eq 2200
105
- expect(subject.config[:host]).to eq "localhost"
106
- expect(subject.config[:user]).to eq "user1"
107
- end
108
- end
109
- end
110
-
111
- context "when provided target is just a hostname" do
112
- let(:host_url) { "localhost" }
113
- let(:protocol) { "mock" }
114
- it "correctly sets backend protocol from the default" do
115
- expect(subject.config[:backend]).to eq "mock"
116
- end
117
-
118
- context "and options have been provided that are supported by the transport" do
119
- let(:protocol) { "ssh" }
120
- let(:connection_opts) { { port: 15, user: "user2" } }
121
-
122
- it "sets hostname and transport from arguments and provided fields from options" do
123
- expect(subject.config[:backend]).to eq "ssh"
124
- expect(subject.config[:host]).to eq "localhost"
125
- expect(subject.config[:user]).to eq "user2"
126
- expect(subject.config[:port]).to eq 15
127
- end
128
-
129
- end
130
-
131
- end
132
-
133
- context "when provided target is just a an IP address" do
134
- let(:host_url) { "127.0.0.1" }
135
- let(:protocol) { "mock" }
136
- it "correctly sets backend protocol from the default" do
137
- expect(subject.config[:backend]).to eq "mock"
138
- end
139
- end
140
- end
141
-
142
- describe "#temp_dir" do
143
- context "under windows" do
144
- let(:family) { "windows" }
145
- let(:name) { "windows" }
146
-
147
- it "uses the windows command to create the temp dir" do
148
- expected_command = Chef::Knife::Bootstrap::TrainConnector::MKTEMP_WIN_COMMAND
149
- expect(subject).to receive(:run_command!).with(expected_command)
150
- .and_return double("result", stdout: "C:/a/path")
151
- expect(subject.temp_dir).to eq "C:/a/path"
152
- end
153
-
154
- end
155
- context "under linux and unix-like" do
156
- let(:family) { "debian" }
157
- let(:name) { "ubuntu" }
158
- let(:random) { "wScHX6" }
159
- let(:dir) { "/tmp/chef_#{random}" }
160
-
161
- before do
162
- allow(SecureRandom).to receive(:alphanumeric).with(6).and_return(random)
163
- end
164
-
165
- context "uses the *nix command to create the temp dir and sets ownership to logged-in" do
166
- it "with sudo privilege" do
167
- subject.config[:sudo] = true
168
- expected_command1 = "mkdir -p '#{dir}'"
169
- expected_command2 = "chown user1 '#{dir}'"
170
- expect(subject).to receive(:run_command!).with(expected_command1)
171
- .and_return double("result", stdout: "\r\n")
172
- expect(subject).to receive(:run_command!).with(expected_command2)
173
- .and_return double("result", stdout: "\r\n")
174
- expect(subject.temp_dir).to eq(dir)
175
- end
176
-
177
- it "without sudo privilege" do
178
- expected_command = "mkdir -p '#{dir}'"
179
- expect(subject).to receive(:run_command!).with(expected_command)
180
- .and_return double("result", stdout: "\r\n")
181
- expect(subject.temp_dir).to eq(dir)
182
- end
183
- end
184
-
185
- context "with noise in stderr" do
186
- it "uses the *nix command to create the temp dir" do
187
- expected_command = "mkdir -p '#{dir}'"
188
- expect(subject).to receive(:run_command!).with(expected_command)
189
- .and_return double("result", stdout: "sudo: unable to resolve host hostname.localhost\r\n" + "#{dir}\r\n")
190
- expect(subject.temp_dir).to eq(dir)
191
- end
192
- end
193
- end
194
- end
195
- context "#upload_file_content!" do
196
- it "creates a local file with expected content and uploads it" do
197
- expect(subject).to receive(:upload_file!) do |local_path, remote_path|
198
- expect(File.read(local_path)).to eq "test data"
199
- expect(remote_path).to eq "/target/path"
200
- end
201
- expect_any_instance_of(Tempfile).to receive(:binmode)
202
- subject.upload_file_content!("test data", "/target/path")
203
- end
204
- end
205
-
206
- context "del_file" do
207
- context "on windows" do
208
- let(:family) { "windows" }
209
- let(:name) { "windows" }
210
- it "deletes the file with a windows command" do
211
- expect(subject).to receive(:run_command!) do |cmd, &_handler|
212
- expect(cmd).to match(/Test-Path "deleteme\.txt".*/)
213
- end
214
- subject.del_file!("deleteme.txt")
215
- end
216
- end
217
- context "on unix-like" do
218
- let(:family) { "debian" }
219
- let(:name) { "ubuntu" }
220
- it "deletes the file with a windows command" do
221
- expect(subject).to receive(:run_command!) do |cmd, &_handler|
222
- expect(cmd).to match(/rm -f "deleteme\.txt".*/)
223
- end
224
- subject.del_file!("deleteme.txt")
225
- end
226
- end
227
- end
228
-
229
- context "#run_command!" do
230
- it "raises a RemoteExecutionFailed when the remote execution failed" do
231
- command_result = double("results", stdout: "", stderr: "failed", exit_status: 1)
232
- expect(subject).to receive(:run_command).and_return command_result
233
-
234
- expect { subject.run_command!("test") }.to raise_error do |e|
235
- expect(e.hostname).to eq subject.hostname
236
- expect(e.class).to eq Chef::Knife::Bootstrap::RemoteExecutionFailed
237
- expect(e.stderr).to eq "failed"
238
- expect(e.stdout).to eq ""
239
- expect(e.exit_status).to eq 1
240
- end
241
- end
242
- end
243
-
244
- end
@@ -1,2220 +0,0 @@
1
- #
2
- # Author:: Ian Meyer (<ianmmeyer@gmail.com>)
3
- # Copyright:: Copyright 2010-2016, Ian Meyer
4
- # Copyright:: Copyright (c) Chef Software Inc.
5
- # License:: Apache License, Version 2.0
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
-
20
- require "spec_helper"
21
-
22
- Chef::Knife::Bootstrap.load_deps
23
-
24
- describe Chef::Knife::Bootstrap do
25
- let(:bootstrap_template) { nil }
26
- let(:stderr) { StringIO.new }
27
- let(:bootstrap_cli_options) { [ ] }
28
- let(:linux_test) { true }
29
- let(:windows_test) { false }
30
- let(:linux_test) { false }
31
- let(:unix_test) { false }
32
- let(:ssh_test) { false }
33
-
34
- let(:connection) do
35
- double("TrainConnector",
36
- windows?: windows_test,
37
- linux?: linux_test,
38
- unix?: unix_test)
39
- end
40
-
41
- let(:knife) do
42
- Chef::Log.logger = Logger.new(StringIO.new)
43
- Chef::Config[:knife][:bootstrap_template] = bootstrap_template unless bootstrap_template.nil?
44
-
45
- k = Chef::Knife::Bootstrap.new(bootstrap_cli_options)
46
- allow(k.ui).to receive(:stderr).and_return(stderr)
47
- allow(k).to receive(:encryption_secret_provided_ignore_encrypt_flag?).and_return(false)
48
- allow(k).to receive(:connection).and_return connection
49
- k.merge_configs
50
- k
51
- end
52
-
53
- context "#check_license" do
54
- let(:acceptor) { instance_double(LicenseAcceptance::Acceptor) }
55
-
56
- before do
57
- expect(LicenseAcceptance::Acceptor).to receive(:new).and_return(acceptor)
58
- end
59
-
60
- describe "when a license is not required" do
61
- it "does not set the chef_license" do
62
- expect(acceptor).to receive(:license_required?).and_return(false)
63
- knife.check_license
64
- expect(Chef::Config[:chef_license]).to eq(nil)
65
- end
66
- end
67
-
68
- describe "when a license is required" do
69
- it "sets the chef_license" do
70
- expect(acceptor).to receive(:license_required?).and_return(true)
71
- expect(acceptor).to receive(:id_from_mixlib).and_return("id")
72
- expect(acceptor).to receive(:check_and_persist)
73
- expect(acceptor).to receive(:acceptance_value).and_return("accept-no-persist")
74
- knife.check_license
75
- expect(Chef::Config[:chef_license]).to eq("accept-no-persist")
76
- end
77
- end
78
- end
79
-
80
- context "#bootstrap_template" do
81
- it "should default to chef-full" do
82
- expect(knife.bootstrap_template).to be_a_kind_of(String)
83
- expect(File.basename(knife.bootstrap_template)).to eq("chef-full")
84
- end
85
- end
86
-
87
- context "#render_template - when using the chef-full default template" do
88
- let(:rendered_template) do
89
- knife.merge_configs
90
- knife.render_template
91
- end
92
-
93
- it "should render client.rb" do
94
- expect(rendered_template).to match("cat > /etc/chef/client.rb <<'EOP'")
95
- expect(rendered_template).to match("chef_server_url \"https://localhost:443\"")
96
- expect(rendered_template).to match("validation_client_name \"chef-validator\"")
97
- expect(rendered_template).to match("log_location STDOUT")
98
- end
99
-
100
- it "should render first-boot.json" do
101
- expect(rendered_template).to match("cat > /etc/chef/first-boot.json <<'EOP'")
102
- expect(rendered_template).to match('{"run_list":\[\]}')
103
- end
104
-
105
- context "and encrypted_data_bag_secret was provided" do
106
- it "should render encrypted_data_bag_secret file" do
107
- expect(knife).to receive(:encryption_secret_provided_ignore_encrypt_flag?).and_return(true)
108
- expect(knife).to receive(:read_secret).and_return("secrets")
109
- expect(rendered_template).to match("cat > /etc/chef/encrypted_data_bag_secret <<'EOP'")
110
- expect(rendered_template).to match('{"run_list":\[\]}')
111
- expect(rendered_template).to match(/secrets/)
112
- end
113
- end
114
- end
115
-
116
- context "with --bootstrap-vault-item" do
117
- let(:bootstrap_cli_options) { [ "--bootstrap-vault-item", "vault1:item1", "--bootstrap-vault-item", "vault1:item2", "--bootstrap-vault-item", "vault2:item1" ] }
118
- it "sets the knife config cli option correctly" do
119
- expect(knife.config[:bootstrap_vault_item]).to eq({ "vault1" => %w{item1 item2}, "vault2" => ["item1"] })
120
- end
121
- end
122
-
123
- context "with --bootstrap-preinstall-command" do
124
- command = "while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1; do\n echo 'waiting for dpkg lock';\n sleep 1;\n done;"
125
- let(:bootstrap_cli_options) { [ "--bootstrap-preinstall-command", command ] }
126
- let(:rendered_template) do
127
- knife.merge_configs
128
- knife.render_template
129
- end
130
- it "configures the preinstall command in the bootstrap template correctly" do
131
- expect(rendered_template).to match(/command/)
132
- end
133
- end
134
-
135
- context "with --bootstrap-proxy" do
136
- let(:bootstrap_cli_options) { [ "--bootstrap-proxy", "1.1.1.1" ] }
137
- let(:rendered_template) do
138
- knife.merge_configs
139
- knife.render_template
140
- end
141
- it "configures the https_proxy environment variable in the bootstrap template correctly" do
142
- expect(rendered_template).to match(/https_proxy="1.1.1.1" export https_proxy/)
143
- end
144
- end
145
-
146
- context "with --bootstrap-no-proxy" do
147
- let(:bootstrap_cli_options) { [ "--bootstrap-no-proxy", "localserver" ] }
148
- let(:rendered_template) do
149
- knife.merge_configs
150
- knife.render_template
151
- end
152
- it "configures the https_proxy environment variable in the bootstrap template correctly" do
153
- expect(rendered_template).to match(/no_proxy="localserver" export no_proxy/)
154
- end
155
- end
156
-
157
- context "with :bootstrap_template and :template_file cli options" do
158
- let(:bootstrap_cli_options) { [ "--bootstrap-template", "my-template", "other-template" ] }
159
-
160
- it "should select bootstrap template" do
161
- expect(File.basename(knife.bootstrap_template)).to eq("my-template")
162
- end
163
- end
164
-
165
- context "when finding templates" do
166
- context "when :bootstrap_template config is set to a file" do
167
- context "that doesn't exist" do
168
- let(:bootstrap_template) { "/opt/blah/not/exists/template.erb" }
169
-
170
- it "raises an error" do
171
- expect { knife.find_template }.to raise_error(Errno::ENOENT)
172
- end
173
- end
174
-
175
- context "that exists" do
176
- let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")) }
177
-
178
- it "loads the given file as the template" do
179
- expect(Chef::Log).to receive(:trace)
180
- expect(knife.find_template).to eq(File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")))
181
- end
182
- end
183
- end
184
-
185
- context "when :bootstrap_template config is set to a template name" do
186
- let(:bootstrap_template) { "example" }
187
-
188
- let(:builtin_template_path) { File.expand_path(File.join(__dir__, "../../../lib/chef/knife/bootstrap/templates", "example.erb")) }
189
-
190
- let(:chef_config_dir_template_path) { "/knife/chef/config/bootstrap/example.erb" }
191
-
192
- let(:env_home_template_path) { "/env/home/.chef/bootstrap/example.erb" }
193
-
194
- let(:gem_files_template_path) { "/Users/schisamo/.rvm/gems/ruby-1.9.2-p180@chef-0.10/gems/knife-windows-0.5.4/lib/chef/knife/bootstrap/fake-bootstrap-template.erb" }
195
-
196
- def configure_chef_config_dir
197
- allow(Chef::Knife).to receive(:chef_config_dir).and_return("/knife/chef/config")
198
- end
199
-
200
- def configure_env_home
201
- allow(Chef::Util::PathHelper).to receive(:home).with(".chef", "bootstrap", "example.erb").and_yield(env_home_template_path)
202
- end
203
-
204
- def configure_gem_files
205
- allow(Gem).to receive(:find_files).and_return([ gem_files_template_path ])
206
- end
207
-
208
- before(:each) do
209
- expect(File).to receive(:exist?).with(bootstrap_template).and_return(false)
210
- end
211
-
212
- context "when file is available everywhere" do
213
- before do
214
- configure_chef_config_dir
215
- configure_env_home
216
- configure_gem_files
217
-
218
- expect(File).to receive(:exist?).with(builtin_template_path).and_return(true)
219
- end
220
-
221
- it "should load the template from built-in templates" do
222
- expect(knife.find_template).to eq(builtin_template_path)
223
- end
224
- end
225
-
226
- context "when file is available in chef_config_dir" do
227
- before do
228
- configure_chef_config_dir
229
- configure_env_home
230
- configure_gem_files
231
-
232
- expect(File).to receive(:exist?).with(builtin_template_path).and_return(false)
233
- expect(File).to receive(:exist?).with(chef_config_dir_template_path).and_return(true)
234
-
235
- it "should load the template from chef_config_dir" do
236
- knife.find_template.should eq(chef_config_dir_template_path)
237
- end
238
- end
239
- end
240
-
241
- context "when file is available in home directory" do
242
- before do
243
- configure_chef_config_dir
244
- configure_env_home
245
- configure_gem_files
246
-
247
- expect(File).to receive(:exist?).with(builtin_template_path).and_return(false)
248
- expect(File).to receive(:exist?).with(chef_config_dir_template_path).and_return(false)
249
- expect(File).to receive(:exist?).with(env_home_template_path).and_return(true)
250
- end
251
-
252
- it "should load the template from chef_config_dir" do
253
- expect(knife.find_template).to eq(env_home_template_path)
254
- end
255
- end
256
-
257
- context "when file is available in Gem files" do
258
- before do
259
- configure_chef_config_dir
260
- configure_env_home
261
- configure_gem_files
262
-
263
- expect(File).to receive(:exist?).with(builtin_template_path).and_return(false)
264
- expect(File).to receive(:exist?).with(chef_config_dir_template_path).and_return(false)
265
- expect(File).to receive(:exist?).with(env_home_template_path).and_return(false)
266
- expect(File).to receive(:exist?).with(gem_files_template_path).and_return(true)
267
- end
268
-
269
- it "should load the template from Gem files" do
270
- expect(knife.find_template).to eq(gem_files_template_path)
271
- end
272
- end
273
-
274
- context "when file is available in Gem files and home dir doesn't exist" do
275
- before do
276
- configure_chef_config_dir
277
- configure_gem_files
278
- allow(Chef::Util::PathHelper).to receive(:home).with(".chef", "bootstrap", "example.erb").and_return(nil)
279
-
280
- expect(File).to receive(:exist?).with(builtin_template_path).and_return(false)
281
- expect(File).to receive(:exist?).with(chef_config_dir_template_path).and_return(false)
282
- expect(File).to receive(:exist?).with(gem_files_template_path).and_return(true)
283
- end
284
-
285
- it "should load the template from Gem files" do
286
- expect(knife.find_template).to eq(gem_files_template_path)
287
- end
288
- end
289
- end
290
- end
291
-
292
- ["-t", "--bootstrap-template"].each do |t|
293
- context "when #{t} option is given in the command line" do
294
- it "sets the knife :bootstrap_template config" do
295
- knife.parse_options([t, "blahblah"])
296
- knife.merge_configs
297
- expect(knife.bootstrap_template).to eq("blahblah")
298
- end
299
- end
300
- end
301
-
302
- context "with run_list template" do
303
- let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")) }
304
-
305
- it "should return an empty run_list" do
306
- expect(knife.render_template).to eq('{"run_list":[]}')
307
- end
308
-
309
- it "should have role[base] in the run_list" do
310
- knife.parse_options(["-r", "role[base]"])
311
- knife.merge_configs
312
- expect(knife.render_template).to eq('{"run_list":["role[base]"]}')
313
- end
314
-
315
- it "should have role[base] and recipe[cupcakes] in the run_list" do
316
- knife.parse_options(["-r", "role[base],recipe[cupcakes]"])
317
- knife.merge_configs
318
- expect(knife.render_template).to eq('{"run_list":["role[base]","recipe[cupcakes]"]}')
319
- end
320
-
321
- context "with bootstrap_attribute options" do
322
- let(:jsonfile) do
323
- file = Tempfile.new (["node", ".json"])
324
- File.open(file.path, "w") { |f| f.puts '{"foo":{"bar":"baz"}}' }
325
- file
326
- end
327
-
328
- it "should have foo => {bar => baz} in the first_boot from cli" do
329
- knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
330
- knife.merge_configs
331
- expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
332
- actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
333
- expect(actual_hash).to eq(expected_hash)
334
- end
335
-
336
- it "should have foo => {bar => baz} in the first_boot from file" do
337
- knife.parse_options(["--json-attribute-file", jsonfile.path])
338
- knife.merge_configs
339
- expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
340
- actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
341
- expect(actual_hash).to eq(expected_hash)
342
- jsonfile.close
343
- end
344
-
345
- it "raises a Chef::Exceptions::BootstrapCommandInputError with the proper error message" do
346
- knife.parse_options(["-j", '{"foo":{"bar":"baz"}}'])
347
- knife.parse_options(["--json-attribute-file", jsonfile.path])
348
- knife.merge_configs
349
- allow(knife).to receive(:validate_name_args!)
350
- expect(knife).to receive(:check_license)
351
-
352
- expect { knife.run }.to raise_error(Chef::Exceptions::BootstrapCommandInputError)
353
- jsonfile.close
354
- end
355
- end
356
- end
357
-
358
- context "with hints template" do
359
- let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test-hints.erb")) }
360
-
361
- it "should create a hint file when told to" do
362
- knife.parse_options(["--hint", "openstack"])
363
- knife.merge_configs
364
- expect(knife.render_template).to match(%r{/etc/chef/ohai/hints/openstack.json})
365
- end
366
-
367
- it "should populate a hint file with JSON when given a file to read" do
368
- allow(::File).to receive(:read).and_return('{ "foo" : "bar" }')
369
- knife.parse_options(["--hint", "openstack=hints/openstack.json"])
370
- knife.merge_configs
371
- expect(knife.render_template).to match(/\{\"foo\":\"bar\"\}/)
372
- end
373
- end
374
-
375
- describe "specifying no_proxy with various entries" do
376
- subject(:knife) do
377
- k = described_class.new
378
- Chef::Config[:knife][:bootstrap_template] = template_file
379
- allow(k).to receive(:connection).and_return connection
380
- k.parse_options(options)
381
- k.merge_configs
382
- k
383
- end
384
-
385
- let(:options) { ["--bootstrap-no-proxy", setting] }
386
-
387
- let(:template_file) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "no_proxy.erb")) }
388
-
389
- let(:rendered_template) do
390
- knife.render_template
391
- end
392
-
393
- context "via --bootstrap-no-proxy" do
394
- let(:setting) { "api.opscode.com" }
395
-
396
- it "renders the client.rb with a single FQDN no_proxy entry" do
397
- expect(rendered_template).to match(/.*no_proxy\s*"api.opscode.com".*/)
398
- end
399
- end
400
-
401
- context "via --bootstrap-no-proxy multiple" do
402
- let(:setting) { "api.opscode.com,172.16.10.*" }
403
-
404
- it "renders the client.rb with comma-separated FQDN and wildcard IP address no_proxy entries" do
405
- expect(rendered_template).to match(/.*no_proxy\s*"api.opscode.com,172.16.10.\*".*/)
406
- end
407
- end
408
-
409
- context "via --ssl-verify-mode none" do
410
- let(:options) { ["--node-ssl-verify-mode", "none"] }
411
-
412
- it "renders the client.rb with ssl_verify_mode set to :verify_none" do
413
- expect(rendered_template).to match(/ssl_verify_mode :verify_none/)
414
- end
415
- end
416
-
417
- context "via --node-ssl-verify-mode peer" do
418
- let(:options) { ["--node-ssl-verify-mode", "peer"] }
419
-
420
- it "renders the client.rb with ssl_verify_mode set to :verify_peer" do
421
- expect(rendered_template).to match(/ssl_verify_mode :verify_peer/)
422
- end
423
- end
424
-
425
- context "via --node-ssl-verify-mode all" do
426
- let(:options) { ["--node-ssl-verify-mode", "all"] }
427
-
428
- it "raises error" do
429
- expect { rendered_template }.to raise_error(RuntimeError)
430
- end
431
- end
432
-
433
- context "via --node-verify-api-cert" do
434
- let(:options) { ["--node-verify-api-cert"] }
435
-
436
- it "renders the client.rb with verify_api_cert set to true" do
437
- expect(rendered_template).to match(/verify_api_cert true/)
438
- end
439
- end
440
-
441
- context "via --no-node-verify-api-cert" do
442
- let(:options) { ["--no-node-verify-api-cert"] }
443
-
444
- it "renders the client.rb with verify_api_cert set to false" do
445
- expect(rendered_template).to match(/verify_api_cert false/)
446
- end
447
- end
448
- end
449
-
450
- describe "specifying the encrypted data bag secret key" do
451
- let(:secret) { "supersekret" }
452
- let(:options) { [] }
453
- let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "secret.erb")) }
454
- let(:rendered_template) do
455
- knife.parse_options(options)
456
- knife.merge_configs
457
- knife.render_template
458
- end
459
-
460
- it "creates a secret file" do
461
- expect(knife).to receive(:encryption_secret_provided_ignore_encrypt_flag?).and_return(true)
462
- expect(knife).to receive(:read_secret).and_return(secret)
463
- expect(rendered_template).to match(/#{secret}/)
464
- end
465
-
466
- it "renders the client.rb with an encrypted_data_bag_secret entry" do
467
- expect(knife).to receive(:encryption_secret_provided_ignore_encrypt_flag?).and_return(true)
468
- expect(knife).to receive(:read_secret).and_return(secret)
469
- expect(rendered_template).to match(%r{encrypted_data_bag_secret\s*"/etc/chef/encrypted_data_bag_secret"})
470
- end
471
-
472
- end
473
-
474
- describe "when transferring trusted certificates" do
475
- let(:rendered_template) do
476
- knife.merge_configs
477
- knife.render_template
478
- end
479
-
480
- before do
481
- Chef::Config[:trusted_certs_dir] = Chef::Util::PathHelper.cleanpath(File.join(CHEF_SPEC_DATA, "trusted_certs"))
482
- end
483
-
484
- it "creates /etc/chef/trusted_certs" do
485
- expect(rendered_template).to match(%r{mkdir -p /etc/chef/trusted_certs})
486
- end
487
-
488
- it "copies the certificates in the directory" do
489
- certificates = Dir[File.join(Chef::Config[:trusted_certs_dir], "*.{crt,pem}")]
490
-
491
- certificates.each do |cert|
492
- expect(rendered_template).to match(%r{cat > /etc/chef/trusted_certs/#{File.basename(cert)} <<'EOP'})
493
- end
494
- end
495
-
496
- it "doesn't create /etc/chef/trusted_certs if :trusted_certs_dir is empty" do
497
- Dir.mktmpdir do |dir|
498
- Chef::Config[:trusted_certs_dir] = dir
499
- expect(rendered_template).not_to match(%r{mkdir -p /etc/chef/trusted_certs})
500
- end
501
- end
502
- end
503
-
504
- context "when doing fips things" do
505
- let(:template_file) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "no_proxy.erb")) }
506
-
507
- before do
508
- Chef::Config[:knife][:bootstrap_template] = template_file
509
- knife.merge_configs
510
- end
511
-
512
- let(:rendered_template) do
513
- knife.render_template
514
- end
515
-
516
- context "when knife is in fips mode" do
517
- before do
518
- Chef::Config[:fips] = true
519
- end
520
-
521
- it "renders 'fips true'" do
522
- expect(rendered_template).to match("fips")
523
- end
524
- end
525
-
526
- context "when knife is not in fips mode" do
527
- before do
528
- # This is required because the chef-fips pipeline does
529
- # has a default value of true for fips
530
- Chef::Config[:fips] = false
531
- end
532
-
533
- it "does not render anything about fips" do
534
- expect(rendered_template).not_to match("fips")
535
- end
536
- end
537
- end
538
-
539
- describe "when transferring client.d" do
540
-
541
- let(:rendered_template) do
542
- knife.merge_configs
543
- knife.render_template
544
- end
545
-
546
- before do
547
- Chef::Config[:client_d_dir] = client_d_dir
548
- end
549
-
550
- context "when client_d_dir is nil" do
551
- let(:client_d_dir) { nil }
552
-
553
- it "does not create /etc/chef/client.d" do
554
- expect(rendered_template).not_to match(%r{mkdir -p /etc/chef/client\.d})
555
- end
556
- end
557
-
558
- context "when client_d_dir is set" do
559
- let(:client_d_dir) do
560
- Chef::Util::PathHelper.cleanpath(
561
- File.join(__dir__, "../../data/client.d_00")
562
- )
563
- end
564
-
565
- it "creates /etc/chef/client.d" do
566
- expect(rendered_template).to match("mkdir -p /etc/chef/client\.d")
567
- end
568
-
569
- context "a flat directory structure" do
570
- it "escapes single-quotes" do
571
- expect(rendered_template).to match("cat > /etc/chef/client.d/02-strings.rb <<'EOP'")
572
- expect(rendered_template).to match("something '\\\\''/foo/bar'\\\\''")
573
- end
574
-
575
- it "creates a file 00-foo.rb" do
576
- expect(rendered_template).to match("cat > /etc/chef/client.d/00-foo.rb <<'EOP'")
577
- expect(rendered_template).to match("d6f9b976-289c-4149-baf7-81e6ffecf228")
578
- end
579
- it "creates a file bar" do
580
- expect(rendered_template).to match("cat > /etc/chef/client.d/bar <<'EOP'")
581
- expect(rendered_template).to match("1 / 0")
582
- end
583
- end
584
-
585
- context "a nested directory structure" do
586
- let(:client_d_dir) do
587
- Chef::Util::PathHelper.cleanpath(
588
- File.join(__dir__, "../../data/client.d_01")
589
- )
590
- end
591
- it "creates a file foo/bar.rb" do
592
- expect(rendered_template).to match("cat > /etc/chef/client.d/foo/bar.rb <<'EOP'")
593
- expect(rendered_template).to match("1 / 0")
594
- end
595
- end
596
- end
597
- end
598
-
599
- describe "#connection_protocol" do
600
- let(:host_descriptor) { "example.com" }
601
- let(:config) { {} }
602
- let(:knife_connection_protocol) { nil }
603
- before do
604
- allow(knife).to receive(:config).and_return config
605
- allow(knife).to receive(:host_descriptor).and_return host_descriptor
606
- if knife_connection_protocol
607
- Chef::Config[:knife][:connection_protocol] = knife_connection_protocol
608
- knife.merge_configs
609
- end
610
- end
611
-
612
- context "when protocol is part of the host argument" do
613
- let(:host_descriptor) { "winrm://myhost" }
614
-
615
- it "returns the value provided by the host argument" do
616
- expect(knife.connection_protocol).to eq "winrm"
617
- end
618
- end
619
-
620
- context "when protocol is provided via the CLI flag" do
621
- let(:config) { { connection_protocol: "winrm" } }
622
- it "returns that value" do
623
- expect(knife.connection_protocol).to eq "winrm"
624
- end
625
-
626
- end
627
- context "when protocol is provided via the host argument and the CLI flag" do
628
- let(:host_descriptor) { "ssh://example.com" }
629
- let(:config) { { connection_protocol: "winrm" } }
630
-
631
- it "returns the value provided by the host argument" do
632
- expect(knife.connection_protocol).to eq "ssh"
633
- end
634
- end
635
-
636
- context "when no explicit protocol is provided" do
637
- let(:config) { {} }
638
- let(:host_descriptor) { "example.com" }
639
- let(:knife_connection_protocol) { "winrm" }
640
- it "falls back to knife config" do
641
- expect(knife.connection_protocol).to eq "winrm"
642
- end
643
- context "and there is no knife bootstrap_protocol" do
644
- let(:knife_connection_protocol) { nil }
645
- it "falls back to 'ssh'" do
646
- expect(knife.connection_protocol).to eq "ssh"
647
- end
648
- end
649
- end
650
-
651
- end
652
-
653
- describe "#validate_protocol!" do
654
- let(:host_descriptor) { "example.com" }
655
- let(:config) { {} }
656
- let(:connection_protocol) { "ssh" }
657
- before do
658
- allow(knife).to receive(:config).and_return config
659
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
660
- allow(knife).to receive(:host_descriptor).and_return host_descriptor
661
- end
662
-
663
- context "when protocol is provided both in the URL and via --protocol" do
664
-
665
- context "and they do not match" do
666
- let(:connection_protocol) { "ssh" }
667
- let(:config) { { connection_protocol: "winrm" } }
668
- it "outputs an error and exits" do
669
- expect(knife.ui).to receive(:error)
670
- expect { knife.validate_protocol! }.to raise_error SystemExit
671
- end
672
- end
673
-
674
- context "and they do match" do
675
- let(:connection_protocol) { "winrm" }
676
- let(:config) { { connection_protocol: "winrm" } }
677
- it "returns true" do
678
- expect(knife.validate_protocol!).to eq true
679
- end
680
- end
681
- end
682
-
683
- context "and the protocol is supported" do
684
-
685
- Chef::Knife::Bootstrap::SUPPORTED_CONNECTION_PROTOCOLS.each do |proto|
686
- let(:connection_protocol) { proto }
687
- it "returns true for #{proto}" do
688
- expect(knife.validate_protocol!).to eq true
689
- end
690
- end
691
- end
692
-
693
- context "and the protocol is not supported" do
694
- let(:connection_protocol) { "invalid" }
695
- it "outputs an error and exits" do
696
- expect(knife.ui).to receive(:error).with(/Unsupported protocol '#{connection_protocol}'/)
697
- expect { knife.validate_protocol! }.to raise_error SystemExit
698
- end
699
- end
700
- end
701
-
702
- describe "#validate_policy_options!" do
703
-
704
- context "when only policy_name is given" do
705
-
706
- let(:bootstrap_cli_options) { %w{ --policy-name my-app-server } }
707
-
708
- it "returns an error stating that policy_name and policy_group must be given together" do
709
- expect { knife.validate_policy_options! }.to raise_error(SystemExit)
710
- expect(stderr.string).to include("ERROR: --policy-name and --policy-group must be specified together")
711
- end
712
-
713
- end
714
-
715
- context "when only policy_group is given" do
716
-
717
- let(:bootstrap_cli_options) { %w{ --policy-group staging } }
718
-
719
- it "returns an error stating that policy_name and policy_group must be given together" do
720
- expect { knife.validate_policy_options! }.to raise_error(SystemExit)
721
- expect(stderr.string).to include("ERROR: --policy-name and --policy-group must be specified together")
722
- end
723
-
724
- end
725
-
726
- context "when both policy_name and policy_group are given, but run list is also given" do
727
-
728
- let(:bootstrap_cli_options) { %w{ --policy-name my-app --policy-group staging --run-list cookbook } }
729
-
730
- it "returns an error stating that policyfile and run_list are exclusive" do
731
- expect { knife.validate_policy_options! }.to raise_error(SystemExit)
732
- expect(stderr.string).to include("ERROR: Policyfile options and --run-list are exclusive")
733
- end
734
-
735
- end
736
-
737
- context "when policy_name and policy_group are given with no conflicting options" do
738
-
739
- let(:bootstrap_cli_options) { %w{ --policy-name my-app --policy-group staging } }
740
-
741
- it "passes options validation" do
742
- expect { knife.validate_policy_options! }.to_not raise_error
743
- end
744
-
745
- it "passes them into the bootstrap context" do
746
- expect(knife.bootstrap_context.first_boot).to have_key(:policy_name)
747
- expect(knife.bootstrap_context.first_boot).to have_key(:policy_group)
748
- end
749
-
750
- it "ensures that run_list is not set in the bootstrap context" do
751
- expect(knife.bootstrap_context.first_boot).to_not have_key(:run_list)
752
- end
753
-
754
- end
755
-
756
- # https://github.com/chef/chef/issues/4131
757
- # Arguably a bug in the plugin: it shouldn't be setting this to nil, but it
758
- # worked before, so make it work now.
759
- context "when a plugin sets the run list option to nil" do
760
- before do
761
- knife.config[:run_list] = nil
762
- end
763
-
764
- it "passes options validation" do
765
- expect { knife.validate_policy_options! }.to_not raise_error
766
- end
767
- end
768
- end
769
-
770
- # TODO - this is the only cli option we validate the _option_ itself -
771
- # so we'll know if someone accidentally deletes or renames use_sudo_password
772
- # Is this worht keeping? If so, then it seems we should expand it
773
- # to cover all options.
774
- context "validating use_sudo_password option" do
775
- it "use_sudo_password contains description and long params for help" do
776
- expect(knife.options).to(have_key(:use_sudo_password)) \
777
- && expect(knife.options[:use_sudo_password][:description].to_s).not_to(eq(""))\
778
- && expect(knife.options[:use_sudo_password][:long].to_s).not_to(eq(""))
779
- end
780
- end
781
-
782
- context "#connection_opts" do
783
- let(:connection_protocol) { "ssh" }
784
- before do
785
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
786
- end
787
- context "behavioral test: " do
788
- let(:expected_connection_opts) do
789
- { base_opts: true,
790
- ssh_identity_opts: true,
791
- ssh_opts: true,
792
- gateway_opts: true,
793
- host_verify_opts: true,
794
- sudo_opts: true,
795
- winrm_opts: true }
796
- end
797
-
798
- it "queries and merges only expected configurations" do
799
- expect(knife).to receive(:base_opts).and_return({ base_opts: true })
800
- expect(knife).to receive(:host_verify_opts).and_return({ host_verify_opts: true })
801
- expect(knife).to receive(:gateway_opts).and_return({ gateway_opts: true })
802
- expect(knife).to receive(:sudo_opts).and_return({ sudo_opts: true })
803
- expect(knife).to receive(:winrm_opts).and_return({ winrm_opts: true })
804
- expect(knife).to receive(:ssh_opts).and_return({ ssh_opts: true })
805
- expect(knife).to receive(:ssh_identity_opts).and_return({ ssh_identity_opts: true })
806
- expect(knife.connection_opts).to match expected_connection_opts
807
- end
808
- end
809
-
810
- context "functional test: " do
811
- context "when protocol is winrm" do
812
- let(:connection_protocol) { "winrm" }
813
- # context "and neither CLI nor Chef::Config config entries have been provided"
814
- # end
815
- context "and all supported values are provided as Chef::Config entries" do
816
- before do
817
- # Set everything to easily identifiable and obviously fake values
818
- # to verify that Chef::Config is being sourced instead of knife.config
819
- knife.config = {}
820
- Chef::Config[:knife][:max_wait] = 9999
821
- Chef::Config[:knife][:winrm_user] = "winbob"
822
- Chef::Config[:knife][:winrm_port] = 9999
823
- Chef::Config[:knife][:ca_trust_file] = "trust.me"
824
- Chef::Config[:knife][:kerberos_realm] = "realm"
825
- Chef::Config[:knife][:kerberos_service] = "service"
826
- Chef::Config[:knife][:winrm_auth_method] = "kerberos" # default is negotiate
827
- Chef::Config[:knife][:winrm_basic_auth_only] = true
828
- Chef::Config[:knife][:winrm_no_verify_cert] = true
829
- Chef::Config[:knife][:session_timeout] = 9999
830
- Chef::Config[:knife][:winrm_ssl] = true
831
- Chef::Config[:knife][:winrm_ssl_peer_fingerprint] = "ABCDEF"
832
- end
833
-
834
- context "and no CLI options have been given" do
835
- let(:expected_result) do
836
- {
837
- logger: Chef::Log, # not configurable
838
- ca_trust_path: "trust.me",
839
- max_wait_until_ready: 9999,
840
- operation_timeout: 9999,
841
- ssl_peer_fingerprint: "ABCDEF",
842
- winrm_transport: "kerberos",
843
- winrm_basic_auth_only: true,
844
- user: "winbob",
845
- port: 9999,
846
- self_signed: true,
847
- ssl: true,
848
- kerberos_realm: "realm",
849
- kerberos_service: "service",
850
- }
851
- end
852
-
853
- it "generates a config hash using the Chef::Config values" do
854
- knife.merge_configs
855
- expect(knife.connection_opts).to match expected_result
856
- end
857
-
858
- end
859
-
860
- context "and some CLI options have been given" do
861
- let(:expected_result) do
862
- {
863
- logger: Chef::Log, # not configurable
864
- ca_trust_path: "no trust",
865
- max_wait_until_ready: 9999,
866
- operation_timeout: 9999,
867
- ssl_peer_fingerprint: "ABCDEF",
868
- winrm_transport: "kerberos",
869
- winrm_basic_auth_only: true,
870
- user: "microsoftbob",
871
- port: 12,
872
- self_signed: true,
873
- ssl: true,
874
- kerberos_realm: "realm",
875
- kerberos_service: "service",
876
- password: "lobster",
877
- }
878
- end
879
-
880
- before do
881
- knife.config[:ca_trust_file] = "no trust"
882
- knife.config[:connection_user] = "microsoftbob"
883
- knife.config[:connection_port] = 12
884
- knife.config[:winrm_port] = "13" # indirectly verify we're not looking for the wrong CLI flag
885
- knife.config[:connection_password] = "lobster"
886
- end
887
-
888
- it "generates a config hash using the CLI options when available and falling back to Chef::Config values" do
889
- knife.merge_configs
890
- expect(knife.connection_opts).to match expected_result
891
- end
892
- end
893
-
894
- context "and all CLI options have been given" do
895
- before do
896
- # We'll force kerberos vi knife.config because it
897
- # causes additional options to populate - make sure
898
- # Chef::Config is different so we can be sure that we didn't
899
- # pull in the Chef::Config value
900
- Chef::Config[:knife][:winrm_auth_method] = "negotiate"
901
- knife.config[:connection_password] = "blue"
902
- knife.config[:max_wait] = 1000
903
- knife.config[:connection_user] = "clippy"
904
- knife.config[:connection_port] = 1000
905
- knife.config[:winrm_port] = 1001 # We should not see this value get used
906
-
907
- knife.config[:ca_trust_file] = "trust.the.internet"
908
- knife.config[:kerberos_realm] = "otherrealm"
909
- knife.config[:kerberos_service] = "otherservice"
910
- knife.config[:winrm_auth_method] = "kerberos" # default is negotiate
911
- knife.config[:winrm_basic_auth_only] = false
912
- knife.config[:winrm_no_verify_cert] = false
913
- knife.config[:session_timeout] = 1000
914
- knife.config[:winrm_ssl] = false
915
- knife.config[:winrm_ssl_peer_fingerprint] = "FEDCBA"
916
- end
917
- let(:expected_result) do
918
- {
919
- logger: Chef::Log, # not configurable
920
- ca_trust_path: "trust.the.internet",
921
- max_wait_until_ready: 1000,
922
- operation_timeout: 1000,
923
- ssl_peer_fingerprint: "FEDCBA",
924
- winrm_transport: "kerberos",
925
- winrm_basic_auth_only: false,
926
- user: "clippy",
927
- port: 1000,
928
- self_signed: false,
929
- ssl: false,
930
- kerberos_realm: "otherrealm",
931
- kerberos_service: "otherservice",
932
- password: "blue",
933
- }
934
- end
935
- it "generates a config hash using the CLI options and pulling nothing from Chef::Config" do
936
- knife.merge_configs
937
- expect(knife.connection_opts).to match expected_result
938
- end
939
- end
940
- end # with underlying Chef::Config values
941
-
942
- context "and no values are provided from Chef::Config or CLI" do
943
- before do
944
- # We will use knife's actual config since these tests
945
- # have assumptions based on CLI default values
946
- end
947
- let(:expected_result) do
948
- {
949
- logger: Chef::Log,
950
- operation_timeout: 60,
951
- self_signed: false,
952
- ssl: false,
953
- ssl_peer_fingerprint: nil,
954
- winrm_basic_auth_only: false,
955
- winrm_transport: "negotiate",
956
- }
957
- end
958
- it "populates appropriate defaults" do
959
- knife.merge_configs
960
- expect(knife.connection_opts).to match expected_result
961
- end
962
- end
963
- end # winrm
964
-
965
- context "when protocol is ssh" do
966
- let(:connection_protocol) { "ssh" }
967
- # context "and neither CLI nor Chef::Config config entries have been provided"
968
- # end
969
- context "and all supported values are provided as Chef::Config entries" do
970
- before do
971
- # Set everything to easily identifiable and obviously fake values
972
- # to verify that Chef::Config is being sourced instead of knife.config
973
- knife.config = {}
974
- Chef::Config[:knife][:max_wait] = 9999
975
- Chef::Config[:knife][:session_timeout] = 9999
976
- Chef::Config[:knife][:ssh_user] = "sshbob"
977
- Chef::Config[:knife][:ssh_port] = 9999
978
- Chef::Config[:knife][:host_key_verify] = false
979
- Chef::Config[:knife][:ssh_gateway_identity] = "/gateway.pem"
980
- Chef::Config[:knife][:ssh_gateway] = "admin@mygateway.local:1234"
981
- Chef::Config[:knife][:ssh_identity_file] = "/identity.pem"
982
- Chef::Config[:knife][:use_sudo_password] = false # We have no password.
983
- end
984
-
985
- context "and no CLI options have been given" do
986
- let(:expected_result) do
987
- {
988
- logger: Chef::Log, # not configurable
989
- max_wait_until_ready: 9999.0,
990
- connection_timeout: 9999,
991
- user: "sshbob",
992
- bastion_host: "mygateway.local",
993
- bastion_port: 1234,
994
- bastion_user: "admin",
995
- forward_agent: false,
996
- keys_only: true,
997
- key_files: ["/identity.pem", "/gateway.pem"],
998
- sudo: false,
999
- verify_host_key: "always",
1000
- port: 9999,
1001
- non_interactive: true,
1002
- }
1003
- end
1004
-
1005
- it "generates a correct config hash using the Chef::Config values" do
1006
- knife.merge_configs
1007
- expect(knife.connection_opts).to match expected_result
1008
- end
1009
- end
1010
-
1011
- context "and unsupported Chef::Config options are given in Chef::Config, not in CLI" do
1012
- before do
1013
- Chef::Config[:knife][:password] = "blah"
1014
- Chef::Config[:knife][:ssh_password] = "blah"
1015
- Chef::Config[:knife][:preserve_home] = true
1016
- Chef::Config[:knife][:use_sudo] = true
1017
- Chef::Config[:knife][:ssh_forward_agent] = "blah"
1018
- end
1019
- it "does not include the corresponding option in the connection options" do
1020
- knife.merge_configs
1021
- expect(knife.connection_opts.key?(:password)).to eq false
1022
- expect(knife.connection_opts.key?(:ssh_forward_agent)).to eq false
1023
- expect(knife.connection_opts.key?(:use_sudo)).to eq false
1024
- expect(knife.connection_opts.key?(:preserve_home)).to eq false
1025
- end
1026
- end
1027
-
1028
- context "and some CLI options have been given" do
1029
- before do
1030
- knife.config = {}
1031
- knife.config[:connection_user] = "sshalice"
1032
- knife.config[:connection_port] = 12
1033
- knife.config[:ssh_port] = "13" # canary to indirectly verify we're not looking for the wrong CLI flag
1034
- knife.config[:connection_password] = "feta cheese"
1035
- knife.config[:max_wait] = 150
1036
- knife.config[:session_timeout] = 120
1037
- knife.config[:use_sudo] = true
1038
- knife.config[:use_sudo_pasword] = true
1039
- knife.config[:ssh_forward_agent] = true
1040
- end
1041
-
1042
- let(:expected_result) do
1043
- {
1044
- logger: Chef::Log, # not configurable
1045
- max_wait_until_ready: 150.0, # cli
1046
- connection_timeout: 120, # cli
1047
- user: "sshalice", # cli
1048
- password: "feta cheese", # cli
1049
- bastion_host: "mygateway.local", # Config
1050
- bastion_port: 1234, # Config
1051
- bastion_user: "admin", # Config
1052
- forward_agent: true, # cli
1053
- keys_only: false, # implied false from config password present
1054
- key_files: ["/identity.pem", "/gateway.pem"], # Config
1055
- sudo: true, # ccli
1056
- verify_host_key: "always", # Config
1057
- port: 12, # cli
1058
- non_interactive: true,
1059
- }
1060
- end
1061
-
1062
- it "generates a config hash using the CLI options when available and falling back to Chef::Config values" do
1063
- knife.merge_configs
1064
- expect(knife.connection_opts).to match expected_result
1065
- end
1066
- end
1067
-
1068
- context "and all CLI options have been given" do
1069
- before do
1070
- knife.config = {}
1071
- knife.config[:max_wait] = 150
1072
- knife.config[:session_timeout] = 120
1073
- knife.config[:connection_user] = "sshroot"
1074
- knife.config[:connection_port] = 1000
1075
- knife.config[:connection_password] = "blah"
1076
- knife.config[:forward_agent] = true
1077
- knife.config[:use_sudo] = true
1078
- knife.config[:use_sudo_password] = true
1079
- knife.config[:preserve_home] = true
1080
- knife.config[:use_sudo_pasword] = true
1081
- knife.config[:ssh_forward_agent] = true
1082
- knife.config[:ssh_verify_host_key] = true
1083
- knife.config[:ssh_gateway_identity] = "/gateway-identity.pem"
1084
- knife.config[:ssh_gateway] = "me@example.com:10"
1085
- knife.config[:ssh_identity_file] = "/my-identity.pem"
1086
-
1087
- # We'll set these as canaries - if one of these values shows up
1088
- # in a failed test, then the behavior of not pulling from these keys
1089
- # out of knife.config is broken:
1090
- knife.config[:ssh_user] = "do not use"
1091
- knife.config[:ssh_port] = 1001
1092
- end
1093
- let(:expected_result) do
1094
- {
1095
- logger: Chef::Log, # not configurable
1096
- max_wait_until_ready: 150,
1097
- connection_timeout: 120,
1098
- user: "sshroot",
1099
- password: "blah",
1100
- port: 1000,
1101
- bastion_host: "example.com",
1102
- bastion_port: 10,
1103
- bastion_user: "me",
1104
- forward_agent: true,
1105
- keys_only: false,
1106
- key_files: ["/my-identity.pem", "/gateway-identity.pem"],
1107
- sudo: true,
1108
- sudo_options: "-H",
1109
- sudo_password: "blah",
1110
- verify_host_key: true,
1111
- non_interactive: true,
1112
- }
1113
- end
1114
- it "generates a config hash using the CLI options and pulling nothing from Chef::Config" do
1115
- knife.merge_configs
1116
- expect(knife.connection_opts).to match expected_result
1117
- end
1118
- end
1119
- end
1120
- context "and no values are provided from Chef::Config or CLI" do
1121
- before do
1122
- # We will use knife's actual config since these tests
1123
- # have assumptions based on CLI default values
1124
- config = {}
1125
- end
1126
-
1127
- let(:expected_result) do
1128
- {
1129
- forward_agent: false,
1130
- key_files: [],
1131
- logger: Chef::Log,
1132
- keys_only: false,
1133
- sudo: false,
1134
- verify_host_key: "always",
1135
- non_interactive: true,
1136
- connection_timeout: 60,
1137
- }
1138
- end
1139
- it "populates appropriate defaults" do
1140
- knife.merge_configs
1141
- expect(knife.connection_opts).to match expected_result
1142
- end
1143
- end
1144
-
1145
- end # ssh
1146
- end # functional tests
1147
-
1148
- end # connection_opts
1149
-
1150
- context "#base_opts" do
1151
- let(:connection_protocol) { nil }
1152
-
1153
- before do
1154
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
1155
- end
1156
-
1157
- context "for all protocols" do
1158
- context "when password is provided" do
1159
- before do
1160
- knife.config[:connection_port] = 250
1161
- knife.config[:connection_user] = "test"
1162
- knife.config[:connection_password] = "opscode"
1163
- end
1164
-
1165
- let(:expected_opts) do
1166
- {
1167
- port: 250,
1168
- user: "test",
1169
- logger: Chef::Log,
1170
- password: "opscode",
1171
- }
1172
- end
1173
- it "generates the correct options" do
1174
- expect(knife.base_opts).to eq expected_opts
1175
- end
1176
-
1177
- end
1178
-
1179
- context "when password is not provided" do
1180
- before do
1181
- knife.config[:connection_port] = 250
1182
- knife.config[:connection_user] = "test"
1183
- end
1184
-
1185
- let(:expected_opts) do
1186
- {
1187
- port: 250,
1188
- user: "test",
1189
- logger: Chef::Log,
1190
- }
1191
- end
1192
- it "generates the correct options" do
1193
- expect(knife.base_opts).to eq expected_opts
1194
- end
1195
- end
1196
- end
1197
- end
1198
-
1199
- context "#host_verify_opts" do
1200
- let(:connection_protocol) { nil }
1201
- before do
1202
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
1203
- end
1204
-
1205
- context "for winrm" do
1206
- let(:connection_protocol) { "winrm" }
1207
- it "returns the expected configuration" do
1208
- knife.config[:winrm_no_verify_cert] = true
1209
- expect(knife.host_verify_opts).to eq( { self_signed: true } )
1210
- end
1211
- it "provides a correct default when no option given" do
1212
- expect(knife.host_verify_opts).to eq( { self_signed: false } )
1213
- end
1214
- end
1215
-
1216
- context "for ssh" do
1217
- let(:connection_protocol) { "ssh" }
1218
- it "returns the expected configuration" do
1219
- knife.config[:ssh_verify_host_key] = false
1220
- expect(knife.host_verify_opts).to eq( { verify_host_key: false } )
1221
- end
1222
- it "provides a correct default when no option given" do
1223
- expect(knife.host_verify_opts).to eq( { verify_host_key: "always" } )
1224
- end
1225
- end
1226
- end
1227
-
1228
- # TODO - test keys_only, password, config source behavior
1229
- context "#ssh_identity_opts" do
1230
- let(:connection_protocol) { nil }
1231
- before do
1232
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
1233
- end
1234
-
1235
- context "for winrm" do
1236
- let(:connection_protocol) { "winrm" }
1237
- it "returns an empty hash" do
1238
- expect(knife.ssh_identity_opts).to eq({})
1239
- end
1240
- end
1241
-
1242
- context "for ssh" do
1243
- let(:connection_protocol) { "ssh" }
1244
- context "when an identity file is specified" do
1245
- before do
1246
- knife.config[:ssh_identity_file] = "/identity.pem"
1247
- end
1248
- it "generates the expected configuration" do
1249
- expect(knife.ssh_identity_opts).to eq({
1250
- key_files: [ "/identity.pem" ],
1251
- keys_only: true,
1252
- })
1253
- end
1254
- context "and a password is also specified" do
1255
- before do
1256
- knife.config[:connection_password] = "blah"
1257
- end
1258
- it "generates the expected configuration (key, keys_only false)" do
1259
- expect(knife.ssh_identity_opts).to eq({
1260
- key_files: [ "/identity.pem" ],
1261
- keys_only: false,
1262
- })
1263
- end
1264
- end
1265
-
1266
- context "and a gateway is not specified" do
1267
- context "but a gateway identity file is specified" do
1268
- it "does not include the gateway identity file in keys" do
1269
- expect(knife.ssh_identity_opts).to eq({
1270
- key_files: ["/identity.pem"],
1271
- keys_only: true,
1272
- })
1273
- end
1274
-
1275
- end
1276
-
1277
- end
1278
-
1279
- context "and a gatway is specified" do
1280
- before do
1281
- knife.config[:ssh_gateway] = "example.com"
1282
- end
1283
- context "and a gateway identity file is not specified" do
1284
- it "config includes only identity file and not gateway identity" do
1285
- expect(knife.ssh_identity_opts).to eq({
1286
- key_files: [ "/identity.pem" ],
1287
- keys_only: true,
1288
- })
1289
- end
1290
- end
1291
-
1292
- context "and a gateway identity file is also specified" do
1293
- before do
1294
- knife.config[:ssh_gateway_identity] = "/gateway.pem"
1295
- end
1296
-
1297
- it "generates the expected configuration (both keys, keys_only true)" do
1298
- expect(knife.ssh_identity_opts).to eq({
1299
- key_files: [ "/identity.pem", "/gateway.pem" ],
1300
- keys_only: true,
1301
- })
1302
- end
1303
- end
1304
- end
1305
- end
1306
-
1307
- context "when no identity file is specified" do
1308
- it "generates the expected configuration (no keys, keys_only false)" do
1309
- expect(knife.ssh_identity_opts).to eq( {
1310
- key_files: [ ],
1311
- keys_only: false,
1312
- })
1313
- end
1314
- context "and a gateway with gateway identity file is specified" do
1315
- before do
1316
- knife.config[:ssh_gateway] = "host"
1317
- knife.config[:ssh_gateway_identity] = "/gateway.pem"
1318
- end
1319
-
1320
- it "generates the expected configuration (gateway key, keys_only false)" do
1321
- expect(knife.ssh_identity_opts).to eq({
1322
- key_files: [ "/gateway.pem" ],
1323
- keys_only: false,
1324
- })
1325
- end
1326
- end
1327
- end
1328
- end
1329
- end
1330
-
1331
- context "#gateway_opts" do
1332
- let(:connection_protocol) { nil }
1333
- before do
1334
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
1335
- end
1336
-
1337
- context "for winrm" do
1338
- let(:connection_protocol) { "winrm" }
1339
- it "returns an empty hash" do
1340
- expect(knife.gateway_opts).to eq({})
1341
- end
1342
- end
1343
-
1344
- context "for ssh" do
1345
- let(:connection_protocol) { "ssh" }
1346
- context "and ssh_gateway with hostname, user and port provided" do
1347
- before do
1348
- knife.config[:ssh_gateway] = "testuser@gateway:9021"
1349
- end
1350
- it "returns a proper bastion host config subset" do
1351
- expect(knife.gateway_opts).to eq({
1352
- bastion_user: "testuser",
1353
- bastion_host: "gateway",
1354
- bastion_port: 9021,
1355
- })
1356
- end
1357
- end
1358
- context "and ssh_gateway with only hostname is given" do
1359
- before do
1360
- knife.config[:ssh_gateway] = "gateway"
1361
- end
1362
- it "returns a proper bastion host config subset" do
1363
- expect(knife.gateway_opts).to eq({
1364
- bastion_user: nil,
1365
- bastion_host: "gateway",
1366
- bastion_port: nil,
1367
- })
1368
- end
1369
- end
1370
- context "and ssh_gateway with hostname and user is is given" do
1371
- before do
1372
- knife.config[:ssh_gateway] = "testuser@gateway"
1373
- end
1374
- it "returns a proper bastion host config subset" do
1375
- expect(knife.gateway_opts).to eq({
1376
- bastion_user: "testuser",
1377
- bastion_host: "gateway",
1378
- bastion_port: nil,
1379
- })
1380
- end
1381
- end
1382
-
1383
- context "and ssh_gateway with hostname and port is is given" do
1384
- before do
1385
- knife.config[:ssh_gateway] = "gateway:11234"
1386
- end
1387
- it "returns a proper bastion host config subset" do
1388
- expect(knife.gateway_opts).to eq({
1389
- bastion_user: nil,
1390
- bastion_host: "gateway",
1391
- bastion_port: 11234,
1392
- })
1393
- end
1394
- end
1395
-
1396
- context "and ssh_gateway is not provided" do
1397
- it "returns an empty hash" do
1398
- expect(knife.gateway_opts).to eq({})
1399
- end
1400
- end
1401
- end
1402
- end
1403
-
1404
- context "#sudo_opts" do
1405
- let(:connection_protocol) { nil }
1406
- before do
1407
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
1408
- end
1409
-
1410
- context "for winrm" do
1411
- let(:connection_protocol) { "winrm" }
1412
- it "returns an empty hash" do
1413
- expect(knife.sudo_opts).to eq({})
1414
- end
1415
- end
1416
-
1417
- context "for ssh" do
1418
- let(:connection_protocol) { "ssh" }
1419
- context "when use_sudo is set" do
1420
- before do
1421
- knife.config[:use_sudo] = true
1422
- end
1423
-
1424
- it "returns a config that enables sudo" do
1425
- expect(knife.sudo_opts).to eq( { sudo: true } )
1426
- end
1427
-
1428
- context "when use_sudo_password is also set" do
1429
- before do
1430
- knife.config[:use_sudo_password] = true
1431
- knife.config[:connection_password] = "opscode"
1432
- end
1433
- it "includes :connection_password value in a sudo-enabled configuration" do
1434
- expect(knife.sudo_opts).to eq({
1435
- sudo: true,
1436
- sudo_password: "opscode",
1437
- })
1438
- end
1439
- end
1440
-
1441
- context "when preserve_home is set" do
1442
- before do
1443
- knife.config[:preserve_home] = true
1444
- end
1445
- it "enables sudo with sudo_option to preserve home" do
1446
- expect(knife.sudo_opts).to eq({
1447
- sudo_options: "-H",
1448
- sudo: true,
1449
- })
1450
- end
1451
- end
1452
- end
1453
-
1454
- context "when use_sudo is not set" do
1455
- before do
1456
- knife.config[:use_sudo_password] = true
1457
- knife.config[:preserve_home] = true
1458
- end
1459
- it "returns configuration for sudo off, ignoring other related options" do
1460
- expect(knife.sudo_opts).to eq( { sudo: false } )
1461
- end
1462
- end
1463
- end
1464
- end
1465
-
1466
- context "#ssh_opts" do
1467
- let(:connection_protocol) { nil }
1468
- before do
1469
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
1470
- end
1471
-
1472
- context "for ssh" do
1473
- let(:connection_protocol) { "ssh" }
1474
- let(:default_opts) do
1475
- {
1476
- non_interactive: true,
1477
- forward_agent: false,
1478
- connection_timeout: 60,
1479
- }
1480
- end
1481
-
1482
- context "by default" do
1483
- it "returns a configuration hash with appropriate defaults" do
1484
- expect(knife.ssh_opts).to eq default_opts
1485
- end
1486
- end
1487
-
1488
- context "when ssh_forward_agent has a value" do
1489
- before do
1490
- knife.config[:ssh_forward_agent] = true
1491
- end
1492
- it "returns a default configuration hash with forward_agent set to true" do
1493
- expect(knife.ssh_opts).to eq(default_opts.merge(forward_agent: true))
1494
- end
1495
- end
1496
- context "when session_timeout has a value" do
1497
- before do
1498
- knife.config[:session_timeout] = 120
1499
- end
1500
- it "returns a default configuration hash with updated timeout value." do
1501
- expect(knife.ssh_opts).to eq(default_opts.merge(connection_timeout: 120))
1502
- end
1503
- end
1504
-
1505
- end
1506
-
1507
- context "for winrm" do
1508
- let(:connection_protocol) { "winrm" }
1509
- it "returns an empty has because ssh is not winrm" do
1510
- expect(knife.ssh_opts).to eq({})
1511
- end
1512
- end
1513
-
1514
- end
1515
-
1516
- context "#winrm_opts" do
1517
- let(:connection_protocol) { nil }
1518
- before do
1519
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
1520
- end
1521
-
1522
- context "for winrm" do
1523
- let(:connection_protocol) { "winrm" }
1524
- let(:expected) do
1525
- {
1526
- winrm_transport: "negotiate",
1527
- winrm_basic_auth_only: false,
1528
- ssl: false,
1529
- ssl_peer_fingerprint: nil,
1530
- operation_timeout: 60,
1531
- }
1532
- end
1533
-
1534
- it "generates a correct configuration hash with expected defaults" do
1535
- expect(knife.winrm_opts).to eq expected
1536
- end
1537
-
1538
- context "with ssl_peer_fingerprint" do
1539
- let(:ssl_peer_fingerprint_expected) do
1540
- expected.merge({ ssl_peer_fingerprint: "ABCD" })
1541
- end
1542
-
1543
- before do
1544
- knife.config[:winrm_ssl_peer_fingerprint] = "ABCD"
1545
- end
1546
-
1547
- it "generates a correct options hash with ssl_peer_fingerprint from the config provided" do
1548
- expect(knife.winrm_opts).to eq ssl_peer_fingerprint_expected
1549
- end
1550
- end
1551
-
1552
- context "with winrm_ssl" do
1553
- let(:ssl_expected) do
1554
- expected.merge({ ssl: true })
1555
- end
1556
- before do
1557
- knife.config[:winrm_ssl] = true
1558
- end
1559
-
1560
- it "generates a correct options hash with ssl from the config provided" do
1561
- expect(knife.winrm_opts).to eq ssl_expected
1562
- end
1563
- end
1564
-
1565
- context "with winrm_auth_method" do
1566
- let(:winrm_auth_method_expected) do
1567
- expected.merge({ winrm_transport: "freeaccess" })
1568
- end
1569
-
1570
- before do
1571
- knife.config[:winrm_auth_method] = "freeaccess"
1572
- end
1573
-
1574
- it "generates a correct options hash with winrm_transport from the config provided" do
1575
- expect(knife.winrm_opts).to eq winrm_auth_method_expected
1576
- end
1577
- end
1578
-
1579
- context "with ca_trust_file" do
1580
- let(:ca_trust_expected) do
1581
- expected.merge({ ca_trust_path: "/trust.me" })
1582
- end
1583
- before do
1584
- knife.config[:ca_trust_file] = "/trust.me"
1585
- end
1586
-
1587
- it "generates a correct options hash with ca_trust_file from the config provided" do
1588
- expect(knife.winrm_opts).to eq ca_trust_expected
1589
- end
1590
- end
1591
-
1592
- context "with kerberos auth" do
1593
- let(:kerberos_expected) do
1594
- expected.merge({
1595
- kerberos_service: "testsvc",
1596
- kerberos_realm: "TESTREALM",
1597
- winrm_transport: "kerberos",
1598
- })
1599
- end
1600
-
1601
- before do
1602
- knife.config[:winrm_auth_method] = "kerberos"
1603
- knife.config[:kerberos_service] = "testsvc"
1604
- knife.config[:kerberos_realm] = "TESTREALM"
1605
- end
1606
-
1607
- it "generates a correct options hash containing kerberos auth configuration from the config provided" do
1608
- expect(knife.winrm_opts).to eq kerberos_expected
1609
- end
1610
- end
1611
-
1612
- context "with winrm_basic_auth_only" do
1613
- before do
1614
- knife.config[:winrm_basic_auth_only] = true
1615
- end
1616
- let(:basic_auth_expected) do
1617
- expected.merge( { winrm_basic_auth_only: true } )
1618
- end
1619
- it "generates a correct options hash containing winrm_basic_auth_only from the config provided" do
1620
- expect(knife.winrm_opts).to eq basic_auth_expected
1621
- end
1622
- end
1623
- end
1624
-
1625
- context "for ssh" do
1626
- let(:connection_protocol) { "ssh" }
1627
- it "returns an empty hash because ssh is not winrm" do
1628
- expect(knife.winrm_opts).to eq({})
1629
- end
1630
- end
1631
- end
1632
- describe "#run" do
1633
- it "performs the steps we expect to run a bootstrap" do
1634
- expect(knife).to receive(:check_license)
1635
- expect(knife).to receive(:validate_name_args!).ordered
1636
- expect(knife).to receive(:validate_protocol!).ordered
1637
- expect(knife).to receive(:validate_first_boot_attributes!).ordered
1638
- expect(knife).to receive(:validate_winrm_transport_opts!).ordered
1639
- expect(knife).to receive(:validate_policy_options!).ordered
1640
- expect(knife).to receive(:winrm_warn_no_ssl_verification).ordered
1641
- expect(knife).to receive(:warn_on_short_session_timeout).ordered
1642
- expect(knife).to receive(:connect!).ordered
1643
- expect(knife).to receive(:register_client).ordered
1644
- expect(knife).to receive(:render_template).and_return "content"
1645
- expect(knife).to receive(:upload_bootstrap).with("content").and_return "/remote/path.sh"
1646
- expect(knife).to receive(:perform_bootstrap).with("/remote/path.sh")
1647
- expect(connection).to receive(:del_file!) # Make sure cleanup happens
1648
-
1649
- knife.run
1650
-
1651
- # Post-run verify expected state changes (not many directly in #run)
1652
- expect($stdout.sync).to eq true
1653
- end
1654
- end
1655
-
1656
- describe "#register_client" do
1657
- let(:vault_handler_mock) { double("ChefVaultHandler") }
1658
- let(:client_builder_mock) { double("ClientBuilder") }
1659
- let(:node_name) { nil }
1660
- before do
1661
- allow(knife).to receive(:chef_vault_handler).and_return vault_handler_mock
1662
- allow(knife).to receive(:client_builder).and_return client_builder_mock
1663
- knife.config[:chef_node_name] = node_name
1664
- end
1665
-
1666
- shared_examples_for "creating the client locally" do
1667
- context "when a valid node name is present" do
1668
- let(:node_name) { "test" }
1669
- before do
1670
- allow(client_builder_mock).to receive(:client).and_return "client"
1671
- allow(client_builder_mock).to receive(:client_path).and_return "/key.pem"
1672
- end
1673
-
1674
- it "runs client_builder and vault_handler" do
1675
- expect(client_builder_mock).to receive(:run)
1676
- expect(vault_handler_mock).to receive(:run).with("client")
1677
- knife.register_client
1678
- end
1679
-
1680
- it "sets the path to the client key in the bootstrap context" do
1681
- allow(client_builder_mock).to receive(:run)
1682
- allow(vault_handler_mock).to receive(:run).with("client")
1683
- knife.register_client
1684
- expect(knife.bootstrap_context.client_pem).to eq "/key.pem"
1685
- end
1686
- end
1687
-
1688
- context "when no valid node name is present" do
1689
- let(:node_name) { nil }
1690
- it "shows an error and exits" do
1691
- expect(knife.ui).to receive(:error)
1692
- expect { knife.register_client }.to raise_error(SystemExit)
1693
- end
1694
- end
1695
- end
1696
- context "when chef_vault_handler says we're using vault" do
1697
- let(:vault_handler_mock) { double("ChefVaultHandler") }
1698
- before do
1699
- allow(vault_handler_mock).to receive(:doing_chef_vault?).and_return true
1700
- end
1701
- it_behaves_like "creating the client locally"
1702
- end
1703
-
1704
- context "when an non-existant validation key is specified in chef config" do
1705
- before do
1706
- Chef::Config[:validation_key] = "/blah"
1707
- allow(vault_handler_mock).to receive(:doing_chef_vault?).and_return false
1708
- allow(File).to receive(:exist?).with(%r{/blah}).and_return false
1709
- end
1710
- it_behaves_like "creating the client locally"
1711
- end
1712
-
1713
- context "when a valid validation key is given and we're doing old-style client creation" do
1714
- before do
1715
- Chef::Config[:validation_key] = "/blah"
1716
- allow(File).to receive(:exist?).with(%r{/blah}).and_return true
1717
- allow(vault_handler_mock).to receive(:doing_chef_vault?).and_return false
1718
- end
1719
-
1720
- it "shows a warning message" do
1721
- expect(knife.ui).to receive(:warn).twice
1722
- knife.register_client
1723
- end
1724
- end
1725
- end
1726
-
1727
- describe "#perform_bootstrap" do
1728
- let(:exit_status) { 0 }
1729
- let(:stdout) { "" }
1730
- let(:result_mock) { double("result", exit_status: exit_status, stderr: "A message", stdout: stdout) }
1731
-
1732
- before do
1733
- allow(connection).to receive(:hostname).and_return "testhost"
1734
- end
1735
- it "runs the remote script and logs the output" do
1736
- expect(knife.ui).to receive(:info).with(/Bootstrapping.*/)
1737
- expect(knife).to receive(:bootstrap_command)
1738
- .with("/path.sh")
1739
- .and_return("sh /path.sh")
1740
- expect(connection)
1741
- .to receive(:run_command)
1742
- .with("sh /path.sh")
1743
- .and_yield("output here", nil)
1744
- .and_return result_mock
1745
-
1746
- expect(knife.ui).to receive(:msg).with(/testhost/)
1747
- knife.perform_bootstrap("/path.sh")
1748
- end
1749
-
1750
- context "when the remote command fails" do
1751
- let(:exit_status) { 1 }
1752
- it "shows an error and exits" do
1753
- expect(knife.ui).to receive(:info).with(/Bootstrapping.*/)
1754
- expect(knife).to receive(:bootstrap_command)
1755
- .with("/path.sh")
1756
- .and_return("sh /path.sh")
1757
- expect(connection).to receive(:run_command).with("sh /path.sh").and_return result_mock
1758
- expect { knife.perform_bootstrap("/path.sh") }.to raise_error(SystemExit)
1759
- end
1760
- end
1761
-
1762
- context "when the remote command failed due to su auth error" do
1763
- let(:exit_status) { 1 }
1764
- let(:stdout) { "su: Authentication failure" }
1765
- let(:connection_obj) { double("connection", transport_options: {}) }
1766
- it "shows an error and exits" do
1767
- allow(connection).to receive(:connection).and_return(connection_obj)
1768
- expect(knife.ui).to receive(:info).with(/Bootstrapping.*/)
1769
- expect(knife).to receive(:bootstrap_command)
1770
- .with("/path.sh")
1771
- .and_return("su - USER -c 'sh /path.sh'")
1772
- expect(connection)
1773
- .to receive(:run_command)
1774
- .with("su - USER -c 'sh /path.sh'")
1775
- .and_yield("output here", nil)
1776
- .and_raise(Train::UserError)
1777
- expect { knife.perform_bootstrap("/path.sh") }.to raise_error(Train::UserError)
1778
- end
1779
- end
1780
- end
1781
-
1782
- describe "#connect!" do
1783
- before do
1784
- # These are not required at run-time because train will handle its own
1785
- # protocol loading. In this case, we're simulating train failures and have to load
1786
- # them ourselves.
1787
- require "net/ssh"
1788
- require "train/transports/ssh"
1789
- end
1790
-
1791
- context "in the normal case" do
1792
- it "connects using the connection_opts and notifies the operator of progress" do
1793
- expect(knife.ui).to receive(:info).with(/Connecting to.*/)
1794
- expect(knife).to receive(:connection_opts).and_return( { opts: "here" })
1795
- expect(knife).to receive(:do_connect).with( { opts: "here" } )
1796
- knife.connect!
1797
- end
1798
- end
1799
-
1800
- context "when a general non-auth-failure occurs" do
1801
- let(:expected_error) { RuntimeError.new }
1802
- before do
1803
- allow(knife).to receive(:do_connect).and_raise(expected_error)
1804
- end
1805
- it "re-raises the exception" do
1806
- expect { knife.connect! }.to raise_error(expected_error)
1807
- end
1808
- end
1809
-
1810
- context "when ssh fingerprint is invalid" do
1811
- let(:expected_error) { Train::Error.new("fingerprint AA:BB is unknown for \"blah,127.0.0.1\"") }
1812
- before do
1813
- allow(knife).to receive(:do_connect).and_raise(expected_error)
1814
- end
1815
- it "warns, prompts to accept, then connects with verify_host_key of accept_new" do
1816
- expect(knife).to receive(:do_connect).and_raise(expected_error)
1817
- expect(knife.ui).to receive(:confirm)
1818
- .with(/.*host 'blah \(127.0.0.1\)'.*AA:BB.*Are you sure you want to continue.*/m)
1819
- .and_return(true)
1820
- expect(knife).to receive(:do_connect) do |opts|
1821
- expect(opts[:verify_host_key]).to eq :accept_new
1822
- end
1823
- knife.connect!
1824
- end
1825
- end
1826
-
1827
- context "when an auth failure occurs" do
1828
- let(:expected_error) do
1829
- e = Train::Error.new
1830
- actual = Net::SSH::AuthenticationFailed.new
1831
- # Simulate train's nested error - they wrap
1832
- # ssh/network errors in a TrainError.
1833
- allow(e).to receive(:cause).and_return(actual)
1834
- e
1835
- end
1836
-
1837
- let(:expected_error_password_prompt) do
1838
- e = Train::ClientError.new
1839
- reason = :no_ssh_password_or_key_available
1840
- allow(e).to receive(:reason).and_return(reason)
1841
- e
1842
- end
1843
-
1844
- let(:expected_error_password_prompt_winrm) do
1845
- e = RuntimeError.new
1846
- message = "password is a required option"
1847
- allow(e).to receive(:message).and_return(message)
1848
- e
1849
- end
1850
-
1851
- context "and password auth was used" do
1852
- before do
1853
- allow(connection).to receive(:password_auth?).and_return true
1854
- end
1855
-
1856
- it "re-raises the error so as not to resubmit the same failing password" do
1857
- expect(knife).to receive(:do_connect).and_raise(expected_error)
1858
- expect { knife.connect! }.to raise_error(expected_error)
1859
- end
1860
- end
1861
-
1862
- context "and password auth was not used" do
1863
- before do
1864
- allow(connection).to receive(:password_auth?).and_return false
1865
- allow(connection).to receive(:user).and_return "testuser"
1866
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
1867
- end
1868
-
1869
- context "when using ssh" do
1870
- let(:connection_protocol) { "ssh" }
1871
-
1872
- it "warns, prompts for password, then reconnects with a password-enabled configuration using the new password" do
1873
- expect(knife).to receive(:do_connect).and_raise(expected_error_password_prompt)
1874
- expect(knife.ui).to receive(:warn).with(/Failed to auth.*/)
1875
- expect(knife.ui).to receive(:ask).and_return("newpassword")
1876
- # Ensure that we set echo off to prevent showing password on the screen
1877
- expect(knife).to receive(:do_connect) do |opts|
1878
- expect(opts[:password]).to eq "newpassword"
1879
- end
1880
- knife.connect!
1881
- end
1882
- end
1883
-
1884
- context "when using winrm" do
1885
- let(:connection_protocol) { "winrm" }
1886
-
1887
- it "warns, prompts for password, then reconnects with a password-enabled configuration using the new password for" do
1888
- expect(knife).to receive(:do_connect).and_raise(expected_error_password_prompt_winrm)
1889
- expect(knife.ui).to receive(:warn).with(/Failed to auth.*/)
1890
- expect(knife.ui).to receive(:ask).and_return("newpassword")
1891
- # Ensure that we set echo off to prevent showing password on the screen
1892
- expect(knife).to receive(:do_connect) do |opts|
1893
- expect(opts[:password]).to eq "newpassword"
1894
- end
1895
- knife.connect!
1896
- end
1897
- end
1898
- end
1899
- end
1900
- end
1901
-
1902
- it "verifies that a server to bootstrap was given as a command line arg" do
1903
- knife.name_args = nil
1904
- expect(knife).to receive(:check_license)
1905
- expect { knife.run }.to raise_error(SystemExit)
1906
- expect(stderr.string).to match(/ERROR:.+FQDN or ip/)
1907
- end
1908
-
1909
- describe "#bootstrap_context" do
1910
- context "under Windows" do
1911
- let(:windows_test) { true }
1912
- it "creates a WindowsBootstrapContext" do
1913
- require "chef/knife/core/windows_bootstrap_context"
1914
- expect(knife.bootstrap_context.class).to eq Chef::Knife::Core::WindowsBootstrapContext
1915
- end
1916
- end
1917
-
1918
- context "under linux" do
1919
- let(:linux_test) { true }
1920
- it "creates a BootstrapContext" do
1921
- require "chef/knife/core/bootstrap_context"
1922
- expect(knife.bootstrap_context.class).to eq Chef::Knife::Core::BootstrapContext
1923
- end
1924
- end
1925
- end
1926
-
1927
- describe "#config_value" do
1928
- before do
1929
- knife.config[:test_key_a] = "a from cli"
1930
- knife.config[:test_key_b] = "b from cli"
1931
- Chef::Config[:knife][:test_key_a] = "a from Chef::Config"
1932
- Chef::Config[:knife][:test_key_c] = "c from Chef::Config"
1933
- Chef::Config[:knife][:alt_test_key_c] = "alt c from Chef::Config"
1934
- knife.merge_configs
1935
- Chef::Config[:treat_deprecation_warnings_as_errors] = false
1936
- end
1937
-
1938
- it "returns the Chef::Config value from the cli when the CLI key is set" do
1939
- expect(knife.config_value(:test_key_a, :alt_test_key_c)).to eq "a from cli"
1940
- end
1941
-
1942
- it "returns the Chef::Config value from the alternative key when the CLI key is not set" do
1943
- expect(knife.config_value(:test_key_d, :alt_test_key_c)).to eq "alt c from Chef::Config"
1944
- end
1945
-
1946
- it "returns the default value when the key is not provided by CLI or Chef::Config" do
1947
- expect(knife.config_value(:missing_key, :missing_key, "found")).to eq "found"
1948
- end
1949
- end
1950
-
1951
- describe "#upload_bootstrap" do
1952
- before do
1953
- allow(connection).to receive(:temp_dir).and_return(temp_dir)
1954
- allow(connection).to receive(:normalize_path) { |a| a }
1955
- end
1956
-
1957
- let(:content) { "bootstrap script content" }
1958
- context "under Windows" do
1959
- let(:windows_test) { true }
1960
- let(:temp_dir) { "C:/Temp/bootstrap" }
1961
- it "creates a bat file in the temp dir provided by connection, using given content" do
1962
- expect(connection).to receive(:upload_file_content!).with(content, "C:/Temp/bootstrap/bootstrap.bat")
1963
- expect(knife.upload_bootstrap(content)).to eq "C:/Temp/bootstrap/bootstrap.bat"
1964
- end
1965
- end
1966
-
1967
- context "under Linux" do
1968
- let(:linux_test) { true }
1969
- let(:temp_dir) { "/tmp/bootstrap" }
1970
- it "creates a 'sh file in the temp dir provided by connection, using given content" do
1971
- expect(connection).to receive(:upload_file_content!).with(content, "/tmp/bootstrap/bootstrap.sh")
1972
- expect(knife.upload_bootstrap(content)).to eq "/tmp/bootstrap/bootstrap.sh"
1973
- end
1974
- end
1975
- end
1976
-
1977
- describe "#bootstrap_command" do
1978
- context "under Windows" do
1979
- let(:windows_test) { true }
1980
- it "prefixes the command to run under cmd.exe" do
1981
- expect(knife.bootstrap_command("autoexec.bat")).to eq "cmd.exe /C autoexec.bat"
1982
- end
1983
-
1984
- end
1985
- context "under Linux" do
1986
- let(:linux_test) { true }
1987
- it "prefixes the command to run under sh" do
1988
- expect(knife.bootstrap_command("bootstrap.sh")).to eq "sh bootstrap.sh"
1989
- end
1990
-
1991
- context "with --su-user option" do
1992
- let(:connection_obj) { double("connection", transport_options: {}) }
1993
- before do
1994
- knife.config[:su_user] = "root"
1995
- allow(connection).to receive(:connection).and_return(connection_obj)
1996
- end
1997
- it "prefixes the command to run using su -USER -c" do
1998
- expect(knife.bootstrap_command("bootstrap.sh")).to eq "su - #{knife.config[:su_user]} -c 'sh bootstrap.sh'"
1999
- expect(connection_obj.transport_options.key?(:pty)).to eq true
2000
- end
2001
-
2002
- it "sudo appended if --sudo option enabled" do
2003
- knife.config[:use_sudo] = true
2004
- expect(knife.bootstrap_command("bootstrap.sh")).to eq "sudo su - #{knife.config[:su_user]} -c 'sh bootstrap.sh'"
2005
- expect(connection_obj.transport_options.key?(:pty)).to eq true
2006
- end
2007
- end
2008
- end
2009
- end
2010
-
2011
- describe "#default_bootstrap_template" do
2012
- context "under Windows" do
2013
- let(:windows_test) { true }
2014
- it "is windows-chef-client-msi" do
2015
- expect(knife.default_bootstrap_template).to eq "windows-chef-client-msi"
2016
- end
2017
-
2018
- end
2019
- context "under Linux" do
2020
- let(:linux_test) { true }
2021
- it "is chef-full" do
2022
- expect(knife.default_bootstrap_template).to eq "chef-full"
2023
- end
2024
- end
2025
- end
2026
-
2027
- describe "#do_connect" do
2028
- let(:host_descriptor) { "example.com" }
2029
- let(:connection) { double("TrainConnector") }
2030
- let(:connector_mock) { double("TargetResolver", targets: [ connection ]) }
2031
- before do
2032
- allow(knife).to receive(:host_descriptor).and_return host_descriptor
2033
- end
2034
-
2035
- it "creates a TrainConnector and connects it" do
2036
- expect(Chef::Knife::Bootstrap::TrainConnector).to receive(:new).and_return connection
2037
- expect(connection).to receive(:connect!)
2038
- knife.do_connect({})
2039
- end
2040
-
2041
- context "when sshd configured with requiretty" do
2042
- let(:pty_err_msg) { "Sudo requires a TTY. Please see the README on how to configure sudo to allow for non-interactive usage." }
2043
- let(:expected_error) { Train::UserError.new(pty_err_msg, :sudo_no_tty) }
2044
- before do
2045
- allow(connection).to receive(:connect!).and_raise(expected_error)
2046
- end
2047
- it "retry with pty true request option" do
2048
- expect(Chef::Knife::Bootstrap::TrainConnector).to receive(:new).and_return(connection).exactly(2).times
2049
- expect(knife.ui).to receive(:warn).with("#{pty_err_msg} - trying with pty request")
2050
- expect { knife.do_connect({}) }.to raise_error(expected_error)
2051
- end
2052
- end
2053
- end
2054
-
2055
- describe "validate_winrm_transport_opts!" do
2056
- before do
2057
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
2058
- end
2059
-
2060
- context "when using ssh" do
2061
- let(:connection_protocol) { "ssh" }
2062
- it "returns true" do
2063
- expect(knife.validate_winrm_transport_opts!).to eq true
2064
- end
2065
- end
2066
- context "when using winrm" do
2067
- let(:connection_protocol) { "winrm" }
2068
- context "with plaintext auth" do
2069
- before do
2070
- knife.config[:winrm_auth_method] = "plaintext"
2071
- end
2072
- context "with ssl" do
2073
- before do
2074
- knife.config[:winrm_ssl] = true
2075
- end
2076
- it "will not error because we won't send anything in plaintext regardless" do
2077
- expect(knife.validate_winrm_transport_opts!).to eq true
2078
- end
2079
- end
2080
- context "without ssl" do
2081
- before do
2082
- knife.config[:winrm_ssl] = false
2083
- end
2084
- context "and no validation key exists" do
2085
- before do
2086
- Chef::Config[:validation_key] = "validation_key.pem"
2087
- allow(File).to receive(:exist?).with(/.*validation_key.pem/).and_return false
2088
- end
2089
-
2090
- it "will error because we will generate and send a client key over the wire in plaintext" do
2091
- expect { knife.validate_winrm_transport_opts! }.to raise_error(SystemExit)
2092
- end
2093
-
2094
- end
2095
- context "and a validation key exists" do
2096
- before do
2097
- Chef::Config[:validation_key] = "validation_key.pem"
2098
- allow(File).to receive(:exist?).with(/.*validation_key.pem/).and_return true
2099
- end
2100
- # TODO - don't we still send validation key?
2101
- it "will not error because we don not send client key over the wire" do
2102
- expect(knife.validate_winrm_transport_opts!).to eq true
2103
- end
2104
- end
2105
- end
2106
- end
2107
-
2108
- context "with other auth" do
2109
- before do
2110
- knife.config[:winrm_auth_method] = "kerberos"
2111
- end
2112
-
2113
- context "and no validation key exists" do
2114
- before do
2115
-
2116
- Chef::Config[:validation_key] = "validation_key.pem"
2117
- allow(File).to receive(:exist?).with(/.*validation_key.pem/).and_return false
2118
- end
2119
-
2120
- it "will not error because we're not using plaintext auth" do
2121
- expect(knife.validate_winrm_transport_opts!).to eq true
2122
- end
2123
- end
2124
- context "and a validation key exists" do
2125
- before do
2126
- Chef::Config[:validation_key] = "validation_key.pem"
2127
- allow(File).to receive(:exist?).with(/.*validation_key.pem/).and_return true
2128
- end
2129
-
2130
- it "will not error because a client key won't be sent over the wire in plaintext when a validation key is present" do
2131
- expect(knife.validate_winrm_transport_opts!).to eq true
2132
- end
2133
- end
2134
-
2135
- end
2136
-
2137
- end
2138
-
2139
- end
2140
-
2141
- describe "#winrm_warn_no_ssl_verification" do
2142
- before do
2143
- allow(knife).to receive(:connection_protocol).and_return connection_protocol
2144
- end
2145
-
2146
- context "when using ssh" do
2147
- let(:connection_protocol) { "ssh" }
2148
- it "does not issue a warning" do
2149
- expect(knife.ui).to_not receive(:warn)
2150
- knife.winrm_warn_no_ssl_verification
2151
- end
2152
- end
2153
- context "when using winrm" do
2154
- let(:connection_protocol) { "winrm" }
2155
- context "winrm_no_verify_cert is set" do
2156
- before do
2157
- knife.config[:winrm_no_verify_cert] = true
2158
- end
2159
-
2160
- context "and ca_trust_file is present" do
2161
- before do
2162
- knife.config[:ca_trust_file] = "file"
2163
- end
2164
-
2165
- it "does not issue a warning" do
2166
- expect(knife.ui).to_not receive(:warn)
2167
- knife.winrm_warn_no_ssl_verification
2168
- end
2169
- end
2170
-
2171
- context "and winrm_ssl_peer_fingerprint is present" do
2172
- before do
2173
- knife.config[:winrm_ssl_peer_fingerprint] = "ABCD"
2174
- end
2175
- it "does not issue a warning" do
2176
- expect(knife.ui).to_not receive(:warn)
2177
- knife.winrm_warn_no_ssl_verification
2178
- end
2179
- end
2180
- context "and neither ca_trust_file nor winrm_ssl_peer_fingerprint is present" do
2181
- it "issues a warning" do
2182
- expect(knife.ui).to receive(:warn)
2183
- knife.winrm_warn_no_ssl_verification
2184
- end
2185
- end
2186
- end
2187
- end
2188
- end
2189
-
2190
- describe "#warn_on_short_session_timeout" do
2191
- let(:session_timeout) { 60 }
2192
-
2193
- before do
2194
- allow(knife).to receive(:session_timeout).and_return(session_timeout)
2195
- end
2196
-
2197
- context "timeout is not set at all" do
2198
- let(:session_timeout) { nil }
2199
- it "does not issue a warning" do
2200
- expect(knife.ui).to_not receive(:warn)
2201
- knife.warn_on_short_session_timeout
2202
- end
2203
- end
2204
-
2205
- context "timeout is more than 15" do
2206
- let(:session_timeout) { 16 }
2207
- it "does not issue a warning" do
2208
- expect(knife.ui).to_not receive(:warn)
2209
- knife.warn_on_short_session_timeout
2210
- end
2211
- end
2212
- context "timeout is 15 or less" do
2213
- let(:session_timeout) { 15 }
2214
- it "issues a warning" do
2215
- expect(knife.ui).to receive(:warn)
2216
- knife.warn_on_short_session_timeout
2217
- end
2218
- end
2219
- end
2220
- end