vagrant-unbundled 2.2.7.0 → 2.2.16.0

Sign up to get free protection for your applications and to get access to all the features.
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