vagrant-unbundled 2.2.7.0 → 2.2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. checksums.yaml +4 -4
  2. data/.hashibot.hcl +2 -0
  3. data/CHANGELOG.md +228 -0
  4. data/Gemfile +1 -1
  5. data/README.md +9 -51
  6. data/RELEASE.md +1 -1
  7. data/bin/vagrant +50 -1
  8. data/contrib/README.md +1 -0
  9. data/contrib/sudoers/linux-suse +2 -2
  10. data/contrib/zsh/_vagrant +738 -0
  11. data/contrib/zsh/generate_zsh_completion.rb +165 -0
  12. data/lib/vagrant.rb +28 -5
  13. data/lib/vagrant/action.rb +7 -0
  14. data/lib/vagrant/action/builder.rb +184 -38
  15. data/lib/vagrant/action/builtin/box_add.rb +24 -8
  16. data/lib/vagrant/action/builtin/box_check_outdated.rb +2 -1
  17. data/lib/vagrant/action/builtin/cleanup_disks.rb +56 -0
  18. data/lib/vagrant/action/builtin/cloud_init_setup.rb +122 -0
  19. data/lib/vagrant/action/builtin/cloud_init_wait.rb +30 -0
  20. data/lib/vagrant/action/builtin/delayed.rb +26 -0
  21. data/lib/vagrant/action/builtin/disk.rb +14 -1
  22. data/lib/vagrant/action/builtin/handle_box.rb +3 -1
  23. data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +28 -9
  24. data/lib/vagrant/action/builtin/has_provisioner.rb +36 -0
  25. data/lib/vagrant/action/builtin/mixin_provisioners.rb +1 -0
  26. data/lib/vagrant/action/builtin/mixin_synced_folders.rb +20 -21
  27. data/lib/vagrant/action/builtin/set_hostname.rb +5 -1
  28. data/lib/vagrant/action/builtin/synced_folders.rb +16 -0
  29. data/lib/vagrant/action/builtin/trigger.rb +37 -0
  30. data/lib/vagrant/action/hook.rb +76 -23
  31. data/lib/vagrant/action/runner.rb +12 -27
  32. data/lib/vagrant/action/warden.rb +28 -31
  33. data/lib/vagrant/box.rb +11 -4
  34. data/lib/vagrant/box_collection.rb +1 -1
  35. data/lib/vagrant/bundler.rb +310 -61
  36. data/lib/vagrant/cli.rb +4 -2
  37. data/lib/vagrant/environment.rb +1 -0
  38. data/lib/vagrant/errors.rb +69 -1
  39. data/lib/vagrant/machine.rb +64 -11
  40. data/lib/vagrant/machine_index.rb +28 -1
  41. data/lib/vagrant/patches/net-ssh.rb +186 -0
  42. data/lib/vagrant/plugin/manager.rb +45 -16
  43. data/lib/vagrant/plugin/v2/command.rb +7 -2
  44. data/lib/vagrant/plugin/v2/components.rb +6 -0
  45. data/lib/vagrant/plugin/v2/manager.rb +67 -0
  46. data/lib/vagrant/plugin/v2/plugin.rb +13 -0
  47. data/lib/vagrant/plugin/v2/synced_folder.rb +50 -0
  48. data/lib/vagrant/plugin/v2/trigger.rb +64 -25
  49. data/lib/vagrant/shared_helpers.rb +36 -0
  50. data/lib/vagrant/ui.rb +43 -2
  51. data/lib/vagrant/util.rb +2 -0
  52. data/lib/vagrant/util/ansi_escape_code_remover.rb +1 -1
  53. data/lib/vagrant/util/caps.rb +48 -0
  54. data/lib/vagrant/util/credential_scrubber.rb +1 -1
  55. data/lib/vagrant/util/curl_helper.rb +12 -8
  56. data/lib/vagrant/util/directory.rb +19 -0
  57. data/lib/vagrant/util/downloader.rb +10 -5
  58. data/lib/vagrant/util/guest_hosts.rb +68 -0
  59. data/lib/vagrant/util/guest_inspection.rb +9 -1
  60. data/lib/vagrant/util/install_cli_autocomplete.rb +118 -0
  61. data/lib/vagrant/util/io.rb +7 -27
  62. data/lib/vagrant/util/ipv4_interfaces.rb +15 -0
  63. data/lib/vagrant/util/is_port_open.rb +8 -19
  64. data/lib/vagrant/util/map_command_options.rb +33 -0
  65. data/lib/vagrant/util/mime.rb +92 -0
  66. data/lib/vagrant/util/network_ip.rb +11 -1
  67. data/lib/vagrant/util/numeric.rb +28 -0
  68. data/lib/vagrant/util/platform.rb +10 -2
  69. data/lib/vagrant/util/powershell.rb +31 -15
  70. data/lib/vagrant/util/subprocess.rb +9 -1
  71. data/lib/vagrant/util/template_renderer.rb +2 -2
  72. data/lib/vagrant/util/uploader.rb +7 -4
  73. data/lib/vagrant/vagrantfile.rb +2 -2
  74. data/plugins/commands/autocomplete/command/install.rb +49 -0
  75. data/plugins/commands/autocomplete/command/root.rb +64 -0
  76. data/plugins/commands/autocomplete/plugin.rb +18 -0
  77. data/plugins/commands/cap/command.rb +5 -1
  78. data/plugins/commands/cloud/auth/login.rb +20 -23
  79. data/plugins/commands/cloud/auth/logout.rb +2 -10
  80. data/plugins/commands/cloud/auth/middleware/add_authentication.rb +60 -31
  81. data/plugins/commands/cloud/auth/middleware/add_downloader_authentication.rb +64 -0
  82. data/plugins/commands/cloud/auth/whoami.rb +18 -20
  83. data/plugins/commands/cloud/box/create.rb +33 -29
  84. data/plugins/commands/cloud/box/delete.rb +30 -24
  85. data/plugins/commands/cloud/box/show.rb +41 -31
  86. data/plugins/commands/cloud/box/update.rb +34 -26
  87. data/plugins/commands/cloud/client/client.rb +55 -79
  88. data/plugins/commands/cloud/list.rb +3 -4
  89. data/plugins/commands/cloud/locales/en.yml +15 -11
  90. data/plugins/commands/cloud/plugin.rb +10 -0
  91. data/plugins/commands/cloud/provider/create.rb +38 -28
  92. data/plugins/commands/cloud/provider/delete.rb +39 -29
  93. data/plugins/commands/cloud/provider/update.rb +37 -28
  94. data/plugins/commands/cloud/provider/upload.rb +53 -33
  95. data/plugins/commands/cloud/publish.rb +193 -106
  96. data/plugins/commands/cloud/search.rb +34 -21
  97. data/plugins/commands/cloud/util.rb +273 -161
  98. data/plugins/commands/cloud/version/create.rb +33 -28
  99. data/plugins/commands/cloud/version/delete.rb +35 -28
  100. data/plugins/commands/cloud/version/release.rb +35 -29
  101. data/plugins/commands/cloud/version/revoke.rb +36 -29
  102. data/plugins/commands/cloud/version/update.rb +29 -25
  103. data/plugins/commands/destroy/command.rb +7 -7
  104. data/plugins/commands/login/plugin.rb +0 -13
  105. data/plugins/commands/ssh_config/command.rb +1 -1
  106. data/plugins/communicators/ssh/communicator.rb +25 -24
  107. data/plugins/communicators/winrm/config.rb +1 -1
  108. data/plugins/communicators/winrm/helper.rb +1 -1
  109. data/plugins/communicators/winrm/shell.rb +1 -1
  110. data/plugins/communicators/winssh/communicator.rb +126 -38
  111. data/plugins/communicators/winssh/config.rb +3 -7
  112. data/plugins/guests/alpine/cap/change_host_name.rb +10 -11
  113. data/plugins/guests/alpine/cap/configure_networks.rb +1 -1
  114. data/plugins/guests/alt/cap/change_host_name.rb +40 -53
  115. data/plugins/guests/arch/cap/change_host_name.rb +5 -14
  116. data/plugins/guests/arch/cap/configure_networks.rb +27 -10
  117. data/plugins/guests/arch/cap/smb.rb +1 -1
  118. data/plugins/guests/atomic/cap/change_host_name.rb +5 -14
  119. data/plugins/guests/centos/cap/flavor.rb +24 -0
  120. data/plugins/guests/centos/guest.rb +9 -0
  121. data/plugins/guests/centos/plugin.rb +20 -0
  122. data/plugins/guests/darwin/cap/change_host_name.rb +10 -6
  123. data/plugins/guests/darwin/cap/darwin_version.rb +40 -0
  124. data/plugins/guests/darwin/cap/mount_smb_shared_folder.rb +1 -1
  125. data/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb +33 -10
  126. data/plugins/guests/darwin/plugin.rb +15 -0
  127. data/plugins/guests/debian/cap/change_host_name.rb +12 -11
  128. data/plugins/guests/debian/cap/configure_networks.rb +14 -6
  129. data/plugins/guests/esxi/cap/public_key.rb +3 -1
  130. data/plugins/guests/fedora/guest.rb +4 -4
  131. data/plugins/guests/freebsd/cap/change_host_name.rb +10 -6
  132. data/plugins/guests/gentoo/cap/change_host_name.rb +14 -22
  133. data/plugins/guests/haiku/cap/rsync.rb +19 -0
  134. data/plugins/guests/haiku/plugin.rb +15 -0
  135. data/plugins/guests/linux/cap/change_host_name.rb +46 -0
  136. data/plugins/guests/linux/cap/halt.rb +9 -1
  137. data/plugins/guests/linux/cap/mount_smb_shared_folder.rb +25 -34
  138. data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +10 -11
  139. data/plugins/guests/linux/cap/persist_mount_shared_folder.rb +74 -0
  140. data/plugins/guests/linux/cap/reboot.rb +36 -7
  141. data/plugins/guests/linux/plugin.rb +10 -0
  142. data/plugins/guests/omnios/cap/change_host_name.rb +10 -16
  143. data/plugins/guests/openbsd/cap/change_host_name.rb +10 -6
  144. data/plugins/guests/openwrt/cap/change_host_name.rb +19 -0
  145. data/plugins/guests/openwrt/cap/halt.rb +16 -0
  146. data/plugins/guests/openwrt/cap/insert_public_key.rb +20 -0
  147. data/plugins/guests/openwrt/cap/remove_public_key.rb +22 -0
  148. data/plugins/guests/openwrt/cap/rsync.rb +35 -0
  149. data/plugins/guests/openwrt/guest.rb +23 -0
  150. data/plugins/guests/openwrt/plugin.rb +61 -0
  151. data/plugins/guests/photon/cap/change_host_name.rb +9 -15
  152. data/plugins/guests/pld/cap/change_host_name.rb +11 -17
  153. data/plugins/guests/redhat/cap/change_host_name.rb +14 -5
  154. data/plugins/guests/redhat/cap/flavor.rb +3 -1
  155. data/plugins/guests/redhat/cap/smb.rb +20 -0
  156. data/plugins/guests/redhat/plugin.rb +5 -0
  157. data/plugins/guests/slackware/cap/change_host_name.rb +11 -17
  158. data/plugins/guests/solaris11/plugin.rb +5 -0
  159. data/plugins/guests/suse/cap/change_host_name.rb +31 -9
  160. data/plugins/guests/windows/cap/public_key.rb +3 -3
  161. data/plugins/guests/windows/cap/reboot.rb +10 -5
  162. data/plugins/hosts/darwin/cap/fs_iso.rb +49 -0
  163. data/plugins/hosts/darwin/plugin.rb +10 -0
  164. data/plugins/hosts/linux/cap/fs_iso.rb +49 -0
  165. data/plugins/hosts/linux/cap/nfs.rb +1 -0
  166. data/plugins/hosts/linux/cap/rdp.rb +1 -1
  167. data/plugins/hosts/linux/plugin.rb +10 -0
  168. data/plugins/hosts/windows/cap/fs_iso.rb +48 -0
  169. data/plugins/hosts/windows/cap/rdp.rb +1 -1
  170. data/plugins/hosts/windows/plugin.rb +15 -0
  171. data/plugins/kernel_v2/config/cloud_init.rb +133 -0
  172. data/plugins/kernel_v2/config/disk.rb +67 -14
  173. data/plugins/kernel_v2/config/ssh_connect.rb +24 -0
  174. data/plugins/kernel_v2/config/vm.rb +155 -21
  175. data/plugins/kernel_v2/config/vm_provisioner.rb +13 -2
  176. data/plugins/kernel_v2/config/vm_trigger.rb +6 -5
  177. data/plugins/providers/docker/action.rb +8 -17
  178. data/plugins/providers/docker/action/forwarded_ports.rb +2 -0
  179. data/plugins/providers/docker/action/prepare_forwarded_port_collision_params.rb +61 -0
  180. data/plugins/providers/docker/cap/has_communicator.rb +11 -0
  181. data/plugins/providers/docker/communicator.rb +1 -1
  182. data/plugins/providers/docker/driver.rb +58 -7
  183. data/plugins/providers/docker/plugin.rb +5 -0
  184. data/plugins/providers/hyperv/action.rb +3 -1
  185. data/plugins/providers/hyperv/action/configure.rb +8 -0
  186. data/plugins/providers/hyperv/action/export.rb +4 -2
  187. data/plugins/providers/hyperv/cap/cleanup_disks.rb +54 -0
  188. data/plugins/providers/hyperv/cap/configure_disks.rb +200 -0
  189. data/plugins/providers/hyperv/cap/validate_disk_ext.rb +34 -0
  190. data/plugins/providers/hyperv/config.rb +5 -0
  191. data/plugins/providers/hyperv/driver.rb +90 -9
  192. data/plugins/providers/hyperv/plugin.rb +25 -0
  193. data/plugins/providers/hyperv/scripts/attach_disk_drive.ps1 +28 -0
  194. data/plugins/providers/hyperv/scripts/dismount_vhd.ps1 +13 -0
  195. data/plugins/providers/hyperv/scripts/get_vhd.ps1 +16 -0
  196. data/plugins/providers/hyperv/scripts/get_vm_status.ps1 +1 -1
  197. data/plugins/providers/hyperv/scripts/list_hdds.ps1 +17 -0
  198. data/plugins/providers/hyperv/scripts/new_vhd.ps1 +31 -0
  199. data/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 +25 -0
  200. data/plugins/providers/hyperv/scripts/resize_disk_drive.ps1 +18 -0
  201. data/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +24 -0
  202. data/plugins/providers/hyperv/scripts/set_vm_integration_services.ps1 +3 -3
  203. data/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 +14 -6
  204. data/plugins/providers/virtualbox/action.rb +13 -1
  205. data/plugins/providers/virtualbox/action/export.rb +4 -2
  206. data/plugins/providers/virtualbox/action/forward_ports.rb +2 -2
  207. data/plugins/providers/virtualbox/action/import.rb +8 -4
  208. data/plugins/providers/virtualbox/action/network.rb +12 -5
  209. data/plugins/providers/virtualbox/action/prepare_clone_snapshot.rb +4 -2
  210. data/plugins/providers/virtualbox/action/snapshot_delete.rb +4 -2
  211. data/plugins/providers/virtualbox/action/snapshot_restore.rb +4 -2
  212. data/plugins/providers/virtualbox/cap/cleanup_disks.rb +85 -0
  213. data/plugins/providers/virtualbox/cap/configure_disks.rb +440 -0
  214. data/plugins/providers/virtualbox/cap/mount_options.rb +40 -0
  215. data/plugins/providers/virtualbox/cap/validate_disk_ext.rb +34 -0
  216. data/plugins/providers/virtualbox/driver/base.rb +15 -0
  217. data/plugins/providers/virtualbox/driver/meta.rb +16 -2
  218. data/plugins/providers/virtualbox/driver/version_5_0.rb +217 -2
  219. data/plugins/providers/virtualbox/driver/version_6_1.rb +23 -0
  220. data/plugins/providers/virtualbox/model/storage_controller.rb +135 -0
  221. data/plugins/providers/virtualbox/model/storage_controller_array.rb +98 -0
  222. data/plugins/providers/virtualbox/plugin.rb +42 -0
  223. data/plugins/providers/virtualbox/provider.rb +2 -1
  224. data/plugins/providers/virtualbox/synced_folder.rb +1 -0
  225. data/plugins/provisioners/ansible/cap/guest/alpine/ansible_install.rb +44 -0
  226. data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +1 -1
  227. data/plugins/provisioners/ansible/plugin.rb +5 -0
  228. data/plugins/provisioners/ansible/provisioner/base.rb +1 -1
  229. data/plugins/provisioners/container/client.rb +203 -0
  230. data/plugins/provisioners/container/config.rb +83 -0
  231. data/plugins/provisioners/container/installer.rb +13 -0
  232. data/plugins/provisioners/container/plugin.rb +23 -0
  233. data/plugins/provisioners/container/provisioner.rb +28 -0
  234. data/plugins/provisioners/docker/cap/{redhat → centos}/docker_install.rb +10 -7
  235. data/plugins/provisioners/docker/cap/centos/docker_start_service.rb +24 -0
  236. data/plugins/provisioners/docker/client.rb +4 -175
  237. data/plugins/provisioners/docker/config.rb +2 -72
  238. data/plugins/provisioners/docker/installer.rb +3 -5
  239. data/plugins/provisioners/docker/plugin.rb +6 -6
  240. data/plugins/provisioners/docker/provisioner.rb +4 -10
  241. data/plugins/provisioners/podman/cap/centos/podman_install.rb +35 -0
  242. data/plugins/provisioners/podman/cap/linux/podman_installed.rb +13 -0
  243. data/plugins/provisioners/podman/cap/redhat/podman_install.rb +26 -0
  244. data/plugins/provisioners/podman/client.rb +12 -0
  245. data/plugins/provisioners/podman/config.rb +28 -0
  246. data/plugins/provisioners/podman/installer.rb +33 -0
  247. data/plugins/provisioners/podman/plugin.rb +38 -0
  248. data/plugins/provisioners/podman/provisioner.rb +52 -0
  249. data/plugins/provisioners/salt/bootstrap-salt.sh +7 -4
  250. data/plugins/provisioners/salt/provisioner.rb +4 -0
  251. data/plugins/provisioners/shell/config.rb +1 -6
  252. data/plugins/provisioners/shell/provisioner.rb +61 -26
  253. data/plugins/synced_folders/nfs/synced_folder.rb +3 -1
  254. data/plugins/synced_folders/smb/cap/default_fstab_modification.rb +11 -0
  255. data/plugins/synced_folders/smb/cap/mount_options.rb +56 -0
  256. data/plugins/synced_folders/smb/plugin.rb +20 -0
  257. data/plugins/synced_folders/smb/synced_folder.rb +2 -2
  258. data/plugins/synced_folders/unix_mount_helpers.rb +14 -0
  259. data/scripts/website_push_www.sh +1 -1
  260. data/templates/commands/init/Vagrantfile.min.erb +3 -0
  261. data/templates/guests/arch/{network_dhcp.erb → default_network/network_dhcp.erb} +0 -0
  262. data/templates/guests/arch/{network_static.erb → default_network/network_static.erb} +0 -0
  263. data/templates/guests/arch/{network_static6.erb → default_network/network_static6.erb} +0 -0
  264. data/templates/guests/arch/systemd_networkd/network_dhcp.erb +6 -0
  265. data/templates/guests/arch/systemd_networkd/network_static.erb +9 -0
  266. data/templates/guests/arch/systemd_networkd/network_static6.erb +9 -0
  267. data/templates/guests/linux/etc_fstab.erb +6 -0
  268. data/templates/guests/nixos/network.erb +5 -6
  269. data/templates/locales/en.yml +221 -5
  270. data/templates/locales/providers_docker.yml +4 -0
  271. data/templates/nfs/exports_darwin.erb +1 -1
  272. data/vagrant.gemspec +14 -20
  273. data/version.txt +1 -1
  274. metadata +5092 -8978
  275. data/lib/vagrant/action/builtin/after_trigger.rb +0 -31
  276. data/lib/vagrant/action/builtin/before_trigger.rb +0 -28
  277. data/plugins/commands/login/client.rb +0 -253
  278. data/plugins/commands/login/command.rb +0 -137
  279. data/plugins/commands/login/errors.rb +0 -24
  280. data/plugins/commands/login/locales/en.yml +0 -49
  281. data/plugins/provisioners/docker/cap/redhat/docker_start_service.rb +0 -16
  282. data/scripts/website_push_docs.sh +0 -40
@@ -1,205 +1,317 @@
1
1
  module VagrantPlugins
2
2
  module CloudCommand
3
- class Util
4
- class << self
5
- # @param [String] username - Vagrant Cloud username
6
- # @param [String] access_token - Vagrant Cloud Token used to authenticate
7
- # @param [String] vagrant_cloud_server - Vagrant Cloud server to make API request
8
- # @return [VagrantCloud::Account]
9
- def account(username, access_token, vagrant_cloud_server)
10
- if !defined?(@_account)
11
- @_account = VagrantCloud::Account.new(username, access_token, vagrant_cloud_server)
12
- end
13
- @_account
3
+ module Util
4
+ # @return [String] Vagrant Cloud server URL
5
+ def api_server_url
6
+ if Vagrant.server_url == Vagrant::DEFAULT_SERVER_URL
7
+ return "#{Vagrant.server_url}/api/v1"
14
8
  end
15
-
16
- def api_server_url
17
- if Vagrant.server_url == Vagrant::DEFAULT_SERVER_URL
18
- return "#{Vagrant.server_url}/api/v1"
19
- else
20
- return Vagrant.server_url
9
+ begin
10
+ addr = URI.parse(Vagrant.server_url)
11
+ if addr.path.empty? || addr.path.to_s == "/"
12
+ addr.path = "/api/v1"
21
13
  end
14
+
15
+ addr.to_s
16
+ rescue URI::Error
17
+ Vagrant.server_url
22
18
  end
19
+ end
23
20
 
24
- # @param [Vagrant::Environment] env
25
- # @param [Hash] options
26
- # @returns [VagrantPlugins::CloudCommand::Client]
27
- def client_login(env, options)
28
- if !defined?(@_client)
29
- @_client = Client.new(env)
30
- return @_client if @_client.logged_in?
21
+ # @param [Vagrant::Environment] env
22
+ # @param [Hash] options
23
+ # @option options [String] :login Username or email
24
+ # @option options [String] :description Description of login usage for token
25
+ # @option options [String] :code 2FA code for login
26
+ # @option options [Boolean] :quiet Do not prompt user
27
+ # @returns [VagrantPlugins::CloudCommand::Client, nil]
28
+ def client_login(env, options={})
29
+ return @_client if defined?(@_client)
30
+ @_client = Client.new(env)
31
+ return @_client if @_client.logged_in?
31
32
 
32
- # Let the user know what is going on.
33
- env.ui.output(I18n.t("cloud_command.command_header") + "\n")
33
+ # If directed to be quiet, do not continue and
34
+ # just return nil
35
+ return if options[:quiet]
34
36
 
35
- # If it is a private cloud installation, show that
36
- if Vagrant.server_url != Vagrant::DEFAULT_SERVER_URL
37
- env.ui.output("Vagrant Cloud URL: #{Vagrant.server_url}")
38
- end
37
+ # Let the user know what is going on.
38
+ env.ui.output(I18n.t("cloud_command.command_header") + "\n")
39
39
 
40
- options = {} if !options
41
- # Ask for the username
42
- if options[:login]
43
- @_client.username_or_email = options[:login]
44
- env.ui.output("Vagrant Cloud username or email: #{@_client.username_or_email}")
45
- else
46
- @_client.username_or_email = env.ui.ask("Vagrant Cloud username or email: ")
47
- end
40
+ # If it is a private cloud installation, show that
41
+ if Vagrant.server_url != Vagrant::DEFAULT_SERVER_URL
42
+ env.ui.output("Vagrant Cloud URL: #{Vagrant.server_url}")
43
+ end
48
44
 
49
- @_client.password = env.ui.ask("Password (will be hidden): ", echo: false)
45
+ options = {} if !options
46
+ # Ask for the username
47
+ if options[:login]
48
+ @_client.username_or_email = options[:login]
49
+ env.ui.output("Vagrant Cloud username or email: #{@_client.username_or_email}")
50
+ else
51
+ @_client.username_or_email = env.ui.ask("Vagrant Cloud username or email: ")
52
+ end
50
53
 
51
- description_default = "Vagrant login from #{Socket.gethostname}"
52
- if !options[:description]
53
- description = env.ui.ask("Token description (Defaults to #{description_default.inspect}): ")
54
- else
55
- description = options[:description]
56
- env.ui.output("Token description: #{description}")
57
- end
54
+ @_client.password = env.ui.ask("Password (will be hidden): ", echo: false)
58
55
 
59
- description = description_default if description.empty?
56
+ description_default = "Vagrant login from #{Socket.gethostname}"
57
+ if !options[:description]
58
+ description = env.ui.ask("Token description (Defaults to #{description_default.inspect}): ")
59
+ else
60
+ description = options[:description]
61
+ env.ui.output("Token description: #{description}")
62
+ end
60
63
 
61
- code = nil
64
+ description = description_default if description.empty?
62
65
 
63
- begin
64
- token = @_client.login(description: description, code: code)
65
- rescue Errors::TwoFactorRequired
66
- until code
67
- code = env.ui.ask("2FA code: ")
66
+ code = nil
68
67
 
69
- if @_client.two_factor_delivery_methods.include?(code.downcase)
70
- delivery_method, code = code, nil
71
- @_client.request_code delivery_method
72
- end
73
- end
68
+ begin
69
+ token = @_client.login(description: description, code: code)
70
+ rescue Errors::TwoFactorRequired
71
+ until code
72
+ code = env.ui.ask("2FA code: ")
74
73
 
75
- retry
74
+ if @_client.two_factor_delivery_methods.include?(code.downcase)
75
+ delivery_method, code = code, nil
76
+ @_client.request_code delivery_method
76
77
  end
77
-
78
- @_client.store_token(token)
79
- Vagrant::Util::CredentialScrubber.sensitive(token)
80
- env.ui.success(I18n.t("cloud_command.logged_in"))
81
- @_client
82
78
  end
83
- @_client
79
+
80
+ retry
84
81
  end
85
82
 
86
- # ===================================================
87
- # Modified from https://stackoverflow.com/a/28685559
88
- # for printing arrays of hashes in formatted tables
89
- # ===================================================
83
+ @_client.store_token(token)
84
+ Vagrant::Util::CredentialScrubber.sensitive(token)
85
+ env.ui.success(I18n.t("cloud_command.logged_in"))
86
+ @_client
87
+ end
90
88
 
91
- # @param [Vagrant::Environment] - env
92
- # @param [Hash] - column_labels - A hash of key values for table labels (i.e. {:col1=>"COL1", :col2=>"COL2"})
93
- # @param [Array] - results - An array of hashes
94
- # @param [Array] - to_jrust_keys - An array of column keys that should be right justified (default is left justified for all columns)
95
- def print_search_table(env, column_labels, results, to_rjust_keys)
96
- columns = column_labels.each_with_object({}) { |(col,label),h|
97
- h[col] = { label: label,
98
- width: [results.map { |g| g[col].size }.max, label.size].max
99
- }}
89
+ # Print search results from Vagrant Cloud to the console
90
+ #
91
+ # @param [Array<VagrantCloud::Box>] search_results Box search results from Vagrant Cloud
92
+ # @param [Boolean] short Print short summary
93
+ # @param [Boolean] json Print output in JSON format
94
+ # @param [Vagrant::Environment] env Current Vagrant environment
95
+ # @return [nil]
96
+ def format_search_results(search_results, short, json, env)
97
+ result = search_results.map do |b|
98
+ {
99
+ name: b.tag,
100
+ version: b.current_version.version,
101
+ downloads: format_downloads(b.downloads.to_s),
102
+ providers: b.current_version.providers.map(&:name).join(", ")
103
+ }
104
+ end
100
105
 
101
- write_header(env, columns)
102
- write_divider(env, columns)
103
- results.each { |h| write_line(env, columns, h,to_rjust_keys) }
104
- write_divider(env, columns)
106
+ if short
107
+ result.map { |b| env.ui.info(b[:name]) }
108
+ elsif json
109
+ env.ui.info(result.to_json)
110
+ else
111
+ column_labels = {}
112
+ columns = result.first.keys
113
+ columns.each do |c|
114
+ column_labels[c] = c.to_s.upcase
115
+ end
116
+ print_search_table(env, column_labels, result, [:downloads])
105
117
  end
118
+ nil
119
+ end
106
120
 
107
- def write_header(env, columns)
108
- env.ui.info "| #{ columns.map { |_,g| g[:label].ljust(g[:width]) }.join(' | ') } |"
121
+ # Output box details result from Vagrant Cloud
122
+ #
123
+ # @param [VagrantCloud::Box, VagrantCloud::Box::Version] box Box or box version to display
124
+ # @param [Vagrant::Environment] env Current Vagrant environment
125
+ # @return [nil]
126
+ def format_box_results(box, env)
127
+ if box.is_a?(VagrantCloud::Box)
128
+ info = box_info(box)
129
+ elsif box.is_a?(VagrantCloud::Box::Provider)
130
+ info = version_info(box.version)
131
+ else
132
+ info = version_info(box)
109
133
  end
110
134
 
111
- def write_divider(env, columns)
112
- env.ui.info "+-#{ columns.map { |_,g| "-"*g[:width] }.join("-+-") }-+"
135
+ width = info.keys.map(&:size).max
136
+ info.each do |k, v|
137
+ whitespace = width - k.size
138
+ env.ui.info "#{k}: #{"".ljust(whitespace)} #{v}"
113
139
  end
140
+ nil
141
+ end
114
142
 
115
- def write_line(env, columns,h,to_rjust_keys)
116
- str = h.keys.map { |k|
117
- if to_rjust_keys.include?(k)
118
- h[k].rjust(columns[k][:width])
119
- else
120
- h[k].ljust(columns[k][:width])
121
- end
122
- }.join(" | ")
123
- env.ui.info "| #{str} |"
143
+ # Load box and yield
144
+ #
145
+ # @param [VagrantCloud::Account] account Vagrant Cloud account
146
+ # @param [String] org Organization name
147
+ # @param [String] box Box name
148
+ # @yieldparam [VagrantCloud::Box] box Requested Vagrant Cloud box
149
+ # @yieldreturn [Integer]
150
+ # @return [Integer]
151
+ def with_box(account:, org:, box:)
152
+ org = account.organization(name: org)
153
+ b = org.boxes.detect { |b| b.name == box }
154
+ if !b
155
+ @env.ui.error(I18n.t("cloud_command.box.not_found",
156
+ org: org.username, box_name: box))
157
+ return 1
124
158
  end
159
+ yield b
160
+ end
125
161
 
126
- # ===================================================
127
- # ===================================================
162
+ # Load box version and yield
163
+ #
164
+ # @param [VagrantCloud::Account] account Vagrant Cloud account
165
+ # @param [String] org Organization name
166
+ # @param [String] box Box name
167
+ # @param [String] version Box version
168
+ # @yieldparam [VagrantCloud::Box::Version] version Requested Vagrant Cloud box version
169
+ # @yieldreturn [Integer]
170
+ # @return [Integer]
171
+ def with_version(account:, org:, box:, version:)
172
+ with_box(account: account, org: org, box: box) do |b|
173
+ v = b.versions.detect { |v| v.version == version }
174
+ if !v
175
+ @env.ui.error(I18n.t("cloud_command.version.not_found",
176
+ box_name: box, org: org, version: version))
177
+ return 1
178
+ end
179
+ yield v
180
+ end
181
+ end
128
182
 
129
- # Takes a "mostly" flat key=>value hash from Vagrant Cloud
130
- # and prints its results in a list
131
- #
132
- # @param [Hash] - results - A response hash from vagrant cloud
133
- # @param [Vagrant::Environment] - env
134
- def format_box_results(results, env)
135
- # TODO: remove other description fields? Maybe leave "short"?
136
- results.delete("description_html")
183
+ # Load box version and yield
184
+ #
185
+ # @param [VagrantCloud::Account] account Vagrant Cloud account
186
+ # @param [String] org Organization name
187
+ # @param [String] box Box name
188
+ # @param [String] version Box version
189
+ # @param [String] provider Box version provider name
190
+ # @yieldparam [VagrantCloud::Box::Provider] provider Requested Vagrant Cloud box version provider
191
+ # @yieldreturn [Integer]
192
+ # @return [Integer]
193
+ def with_provider(account:, org:, box:, version:, provider:)
194
+ with_version(account: account, org: org, box: box, version: version) do |v|
195
+ p = v.providers.detect { |p| p.name == provider }
196
+ if !p
197
+ @env.ui.error(I18n.t("cloud_command.provider.not_found",
198
+ org: org, box_name: box, version: version, provider_name: provider))
199
+ return 1
200
+ end
201
+ yield p
202
+ end
203
+ end
137
204
 
138
- if results["current_version"]
139
- versions = results.delete("versions")
140
- results["providers"] = results["current_version"]["providers"]
205
+ protected
141
206
 
142
- results["old_versions"] = versions.map{ |v| v["version"] }[1..5].join(", ") + "..."
207
+ # Extract box information for display
208
+ #
209
+ # @param [VagrantCloud::Box] box Box for extracting information
210
+ # @return [Hash<String,String>]
211
+ def box_info(box)
212
+ Hash.new.tap do |i|
213
+ i["Box"] = box.tag
214
+ i["Description"] = box.description
215
+ i["Private"] = box.private ? "yes" : "no"
216
+ i["Created"] = box.created_at
217
+ i["Updated"] = box.updated_at
218
+ if !box.current_version.nil?
219
+ i["Current Version"] = box.current_version.version
220
+ else
221
+ i["Current Version"] = "N/A"
143
222
  end
223
+ i["Versions"] = box.versions.slice(0, 5).map(&:version).join(", ")
224
+ if box.versions.size > 5
225
+ i["Versions"] += " ..."
226
+ end
227
+ i["Downloads"] = format_downloads(box.downloads)
228
+ end
229
+ end
144
230
 
231
+ # Extract version information for display
232
+ #
233
+ # @param [VagrantCloud::Box::Version] version Box version for extracting information
234
+ # @return [Hash<String,String>]
235
+ def version_info(version)
236
+ Hash.new.tap do |i|
237
+ i["Box"] = version.box.tag
238
+ i["Version"] = version.version
239
+ i["Description"] = version.description
240
+ i["Status"] = version.status
241
+ i["Providers"] = version.providers.map(&:name).sort.join(", ")
242
+ i["Created"] = version.created_at
243
+ i["Updated"] = version.updated_at
244
+ end
245
+ end
145
246
 
146
- width = results.keys.map{|k| k.size}.max
147
- results.each do |k,v|
148
- if k == "versions"
149
- v = v.map{ |ver| ver["version"] }.join(", ")
150
- elsif k == "current_version"
151
- v = v["version"]
152
- elsif k == "providers"
153
- v = v.map{ |p| p["name"] }.join(", ")
154
- elsif k == "downloads"
155
- v = format_downloads(v.to_s)
156
- end
157
-
158
- whitespace = width-k.size
159
- env.ui.info "#{k}:" + "".ljust(whitespace) + " #{v}"
160
- end
247
+ # Print table results from search request
248
+ #
249
+ # @param [Vagrant::Environment] env Current Vagrant environment
250
+ # @param [Hash] column_labels A hash of key/value pairs for table labels (i.e. {col1: "COL1"})
251
+ # @param [Array] results An array of hashes representing search resuls
252
+ # @param [Array] to_jrust_keys - List of columns keys to right justify (left justify is defualt)
253
+ # @return [nil]
254
+ # @note Modified from https://stackoverflow.com/a/28685559
255
+ def print_search_table(env, column_labels, results, to_rjust_keys)
256
+ columns = column_labels.each_with_object({}) do |(col,label),h|
257
+ h[col] = {
258
+ label: label,
259
+ width: [results.map { |g| g[col].size }.max, label.size].max
260
+ }
161
261
  end
162
262
 
163
- # Converts a string of numbers into a formatted number
164
- #
165
- # 1234 -> 1,234
166
- #
167
- # @param [String] - download_string
168
- def format_downloads(download_string)
169
- return download_string.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
170
- end
171
-
172
-
173
- # @param [Array] search_results - Box search results from Vagrant Cloud
174
- # @param [String,nil] short - determines if short version will be printed
175
- # @param [String,nil] json - determines if json version will be printed
176
- # @param [Vagrant::Environment] - env
177
- def format_search_results(search_results, short, json, env)
178
- result = []
179
- search_results.each do |b|
180
- box = {}
181
- box = {
182
- name: b["tag"],
183
- version: b["current_version"]["version"],
184
- downloads: format_downloads(b["downloads"].to_s),
185
- providers: b["current_version"]["providers"].map{ |p| p["name"] }.join(",")
186
- }
187
- result << box
188
- end
263
+ write_header(env, columns)
264
+ write_divider(env, columns)
265
+ results.each { |h| write_line(env, columns, h, to_rjust_keys) }
266
+ write_divider(env, columns)
267
+ end
189
268
 
190
- if short
191
- result.map {|b| env.ui.info(b[:name])}
192
- elsif json
193
- env.ui.info(result.to_json)
269
+ # Write the header for a table
270
+ #
271
+ # @param [Vagrant::Environment] env Current Vagrant environment
272
+ # @param [Array<Hash>] columns List of columns in Hash format with `:label` and `:width` keys
273
+ # @return [nil]
274
+ def write_header(env, columns)
275
+ env.ui.info "| #{ columns.map { |_,g| g[:label].ljust(g[:width]) }.join(' | ') } |"
276
+ nil
277
+ end
278
+
279
+ # Write a row divider for a table
280
+ #
281
+ # @param [Vagrant::Environment] env Current Vagrant environment
282
+ # @param [Array<Hash>] columns List of columns in Hash format with `:label` and `:width` keys
283
+ # @return [nil]
284
+ def write_divider(env, columns)
285
+ env.ui.info "+-#{ columns.map { |_,g| "-"*g[:width] }.join("-+-") }-+"
286
+ nil
287
+ end
288
+
289
+ # Write a line of content for a table
290
+ #
291
+ # @param [Vagrant::Environment] env Current Vagrant environment
292
+ # @param [Array<Hash>] columns List of columns in Hash format with `:label` and `:width` keys
293
+ # @param [Hash] h Values to print in row
294
+ # @param [Array<String>] to_rjust_keys List of columns to right justify
295
+ # @return [nil]
296
+ def write_line(env, columns, h, to_rjust_keys)
297
+ str = h.keys.map { |k|
298
+ if to_rjust_keys.include?(k)
299
+ h[k].rjust(columns[k][:width])
194
300
  else
195
- column_labels = {}
196
- columns = result.first.keys
197
- columns.each do |c|
198
- column_labels[c] = c.to_s.upcase
199
- end
200
- print_search_table(env, column_labels, result, [:downloads])
301
+ h[k].ljust(columns[k][:width])
201
302
  end
202
- end
303
+ }.join(" | ")
304
+ env.ui.info "| #{str} |"
305
+ nil
306
+ end
307
+
308
+ # Converts a string of numbers into a formatted number
309
+ #
310
+ # 1234 -> 1,234
311
+ #
312
+ # @param [String] number Numer to format
313
+ def format_downloads(number)
314
+ number.to_s.chars.reverse.each_slice(3).map(&:join).join(",").reverse
203
315
  end
204
316
  end
205
317
  end