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
@@ -5,19 +5,15 @@ module VagrantPlugins
5
5
  module AuthCommand
6
6
  module Command
7
7
  class Whoami < Vagrant.plugin("2", :command)
8
+ include Util
9
+
8
10
  def execute
9
11
  options = {}
10
12
 
11
13
  opts = OptionParser.new do |o|
12
- o.banner = "Usage: vagrant cloud auth whoami [options] [token]"
14
+ o.banner = "Usage: vagrant cloud auth whoami [token]"
13
15
  o.separator ""
14
16
  o.separator "Display currently logged in user"
15
- o.separator ""
16
- o.separator "Options:"
17
- o.separator ""
18
- o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |l|
19
- options[:login] = l
20
- end
21
17
  end
22
18
 
23
19
  # Parse the options
@@ -28,28 +24,30 @@ module VagrantPlugins
28
24
  help: opts.help.chomp
29
25
  end
30
26
 
31
- @client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:login])
32
-
33
27
  if argv.first
34
28
  token = argv.first
35
29
  else
36
- token = @client.token
30
+ client = Client.new(@env)
31
+ token = client.token
37
32
  end
38
33
 
39
- whoami(token, options[:username])
34
+ whoami(token)
40
35
  end
41
36
 
42
- def whoami(access_token, username)
43
- server_url = VagrantPlugins::CloudCommand::Util.api_server_url
44
- account = VagrantPlugins::CloudCommand::Util.account(username, access_token, server_url)
45
-
37
+ def whoami(access_token)
38
+ if access_token.to_s.empty?
39
+ @env.ui.error(I18n.t("cloud_command.check_not_logged_in"))
40
+ return 1
41
+ end
46
42
  begin
47
- success = account.validate_token
48
- user = success["user"]["username"]
49
- @env.ui.success("Currently logged in as #{user}")
43
+ account = VagrantCloud::Account.new(
44
+ custom_server: api_server_url,
45
+ access_token: access_token
46
+ )
47
+ @env.ui.success("Currently logged in as #{account.username}")
50
48
  return 0
51
- rescue VagrantCloud::ClientError => e
52
- @env.ui.error(I18n.t("cloud_command.errors.whoami.read_error", org: username))
49
+ rescue VagrantCloud::Error::ClientError => e
50
+ @env.ui.error(I18n.t("cloud_command.errors.whoami.read_error"))
53
51
  @env.ui.error(e)
54
52
  return 1
55
53
  end
@@ -5,6 +5,8 @@ module VagrantPlugins
5
5
  module BoxCommand
6
6
  module Command
7
7
  class Create < Vagrant.plugin("2", :command)
8
+ include Util
9
+
8
10
  def execute
9
11
  options = {}
10
12
 
@@ -19,13 +21,10 @@ module VagrantPlugins
19
21
  o.on("-d", "--description DESCRIPTION", String, "Full description of the box") do |d|
20
22
  options[:description] = d
21
23
  end
22
- o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
23
- options[:username] = u
24
- end
25
24
  o.on("-s", "--short-description DESCRIPTION", String, "Short description of the box") do |s|
26
25
  options[:short] = s
27
26
  end
28
- o.on("-p", "--private", "Makes box private") do |p|
27
+ o.on("-p", "--[no-]private", "Makes box private") do |p|
29
28
  options[:private] = p
30
29
  end
31
30
  end
@@ -38,35 +37,40 @@ module VagrantPlugins
38
37
  help: opts.help.chomp
39
38
  end
40
39
 
41
- @client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
40
+ @client = client_login(@env)
42
41
 
43
- box = argv.first.split('/', 2)
44
- org = box[0]
45
- box_name = box[1]
46
- create_box(org, box_name, options, @client.token)
42
+ org, box_name = argv.first.split('/', 2)
43
+ create_box(org, box_name, @client.token, options.slice(:description, :short, :private))
47
44
  end
48
45
 
49
- # @param [String] - org
50
- # @param [String] - box_name
51
- # @param [Hash] - options
52
- def create_box(org, box_name, options, access_token)
53
- server_url = VagrantPlugins::CloudCommand::Util.api_server_url
54
- account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
55
- box = VagrantCloud::Box.new(account, box_name, nil, options[:short], options[:description], access_token)
56
-
57
- begin
58
- success = box.create
59
- @env.ui.success(I18n.t("cloud_command.box.create_success", org: org, box_name: box_name))
60
- success = success.delete_if { |_, v| v.nil? }
61
- VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
62
- return 0
63
- rescue VagrantCloud::ClientError => e
64
- @env.ui.error(I18n.t("cloud_command.errors.box.create_fail", org: org, box_name: box_name))
65
- @env.ui.error(e)
66
- return 1
67
- end
46
+ # Create a new box
47
+ #
48
+ # @param [String] org Organization name of box
49
+ # @param [String] box_name Name of box
50
+ # @param [String] access_token User access token
51
+ # @param [Hash] options Options for box filtering
52
+ # @option options [String] :short Short description of box
53
+ # @option options [String] :description Full description of box
54
+ # @option options [Boolean] :private Set box visibility as private
55
+ # @return [Integer]
56
+ def create_box(org, box_name, access_token, options={})
57
+ account = VagrantCloud::Account.new(
58
+ custom_server: api_server_url,
59
+ access_token: access_token
60
+ )
61
+ box = account.organization(name: org).add_box(box_name)
62
+ box.short_description = options[:short] if options.key?(:short)
63
+ box.description = options[:description] if options.key?(:description)
64
+ box.private = options[:private] if options.key?(:private)
65
+ box.save
68
66
 
69
- return 1
67
+ @env.ui.success(I18n.t("cloud_command.box.create_success", org: org, box_name: box_name))
68
+ format_box_results(box, @env)
69
+ 0
70
+ rescue VagrantCloud::Error => e
71
+ @env.ui.error(I18n.t("cloud_command.errors.box.create_fail", org: org, box_name: box_name))
72
+ @env.ui.error(e.message)
73
+ 1
70
74
  end
71
75
  end
72
76
  end
@@ -5,6 +5,8 @@ module VagrantPlugins
5
5
  module BoxCommand
6
6
  module Command
7
7
  class Delete < Vagrant.plugin("2", :command)
8
+ include Util
9
+
8
10
  def execute
9
11
  options = {}
10
12
 
@@ -16,8 +18,8 @@ module VagrantPlugins
16
18
  o.separator "Options:"
17
19
  o.separator ""
18
20
 
19
- o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
20
- options[:username] = u
21
+ o.on("-f", "--[no-]force", "Do not prompt for deletion confirmation") do |f|
22
+ options[:force] = f
21
23
  end
22
24
  end
23
25
 
@@ -29,34 +31,38 @@ module VagrantPlugins
29
31
  help: opts.help.chomp
30
32
  end
31
33
 
32
- @env.ui.warn(I18n.t("cloud_command.box.delete_warn", box: argv.first))
33
- cont = @env.ui.ask(I18n.t("cloud_command.continue"))
34
- return 1 if cont.strip.downcase != "y"
34
+ if !options[:force]
35
+ @env.ui.warn(I18n.t("cloud_command.box.delete_warn", box: argv.first))
36
+ cont = @env.ui.ask(I18n.t("cloud_command.continue"))
37
+ return 1 if cont.strip.downcase != "y"
38
+ end
35
39
 
36
- @client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
40
+ @client = client_login(@env)
37
41
 
38
- box = argv.first.split('/', 2)
39
- org = box[0]
40
- box_name = box[1]
41
- delete_box(org, box_name, options[:username], @client.token)
42
+ org, box_name = argv.first.split('/', 2)
43
+ delete_box(org, box_name, @client.token)
42
44
  end
43
45
 
44
- def delete_box(org, box_name, username, access_token)
45
- server_url = VagrantPlugins::CloudCommand::Util.api_server_url
46
- account = VagrantPlugins::CloudCommand::Util.account(username, access_token, server_url)
47
- box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
48
-
49
- begin
50
- success = box.delete(org, box_name)
46
+ # Delete the requested box
47
+ #
48
+ # @param [String] org Organization name of box
49
+ # @param [String] box_name Name of box
50
+ # @param [String] access_token User access token
51
+ # @return [Integer]
52
+ def delete_box(org, box_name, access_token)
53
+ account = VagrantCloud::Account.new(
54
+ custom_server: api_server_url,
55
+ access_token: access_token
56
+ )
57
+ with_box(account: account, org: org, box: box_name) do |box|
58
+ box.delete
51
59
  @env.ui.success(I18n.t("cloud_command.box.delete_success", org: org, box_name: box_name))
52
- return 0
53
- rescue VagrantCloud::ClientError => e
54
- @env.ui.error(I18n.t("cloud_command.errors.box.delete_fail", org: org, box_name: box_name))
55
- @env.ui.error(e)
56
- return 1
60
+ 0
57
61
  end
58
-
59
- return 1
62
+ rescue VagrantCloud::Error => e
63
+ @env.ui.error(I18n.t("cloud_command.errors.box.delete_fail", org: org, box_name: box_name))
64
+ @env.ui.error(e.message)
65
+ 1
60
66
  end
61
67
  end
62
68
  end
@@ -5,8 +5,10 @@ module VagrantPlugins
5
5
  module BoxCommand
6
6
  module Command
7
7
  class Show < Vagrant.plugin("2", :command)
8
+ include Util
9
+
8
10
  def execute
9
- options = {}
11
+ options = {quiet: true, versions: []}
10
12
 
11
13
  opts = OptionParser.new do |o|
12
14
  o.banner = "Usage: vagrant cloud box show [options] organization/box-name"
@@ -16,11 +18,11 @@ module VagrantPlugins
16
18
  o.separator "Options:"
17
19
  o.separator ""
18
20
 
19
- o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
20
- options[:username] = u
21
+ o.on("--versions VERSION", String, "Display box information for a specific version (can be defined multiple times)") do |v|
22
+ options[:versions] << v
21
23
  end
22
- o.on("--versions VERSION", String, "Display box information for a specific version") do |v|
23
- options[:version] = v
24
+ o.on("--[no-]auth", "Authenticate with Vagrant Cloud if required before searching") do |l|
25
+ options[:quiet] = !l
24
26
  end
25
27
  end
26
28
 
@@ -32,40 +34,48 @@ module VagrantPlugins
32
34
  help: opts.help.chomp
33
35
  end
34
36
 
35
- @client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
36
- box = argv.first.split('/', 2)
37
+ @client = client_login(@env, options.slice(:quiet))
38
+ org, box_name = argv.first.split('/', 2)
37
39
 
38
- show_box(box[0], box[1], options, @client.token)
40
+ show_box(org, box_name, @client&.token, options.slice(:versions))
39
41
  end
40
42
 
41
- def show_box(org, box_name, options, access_token)
42
- username = options[:username]
43
-
44
- server_url = VagrantPlugins::CloudCommand::Util.api_server_url
45
- account = VagrantPlugins::CloudCommand::Util.account(username, access_token, server_url)
46
- box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
47
-
48
- begin
49
- success = box.read(org, box_name)
43
+ # Display the requested box to the user
44
+ #
45
+ # @param [String] org Organization name of box
46
+ # @param [String] box_name Name of box
47
+ # @param [String] access_token User access token
48
+ # @param [Hash] options Options for box filtering
49
+ # @option options [String] :versions Specific verisons of box
50
+ # @return [Integer]
51
+ def show_box(org, box_name, access_token, options={})
52
+ account = VagrantCloud::Account.new(
53
+ custom_server: api_server_url,
54
+ access_token: access_token
55
+ )
56
+ with_box(account: account, org: org, box: box_name) do |box|
57
+ if box && !Array(options[:versions]).empty?
58
+ box = box.versions.find_all{ |v| options[:versions].include?(v.version) }
59
+ else
60
+ box = [box]
61
+ end
50
62
 
51
- if options[:version]
52
- # show *this* version only
53
- results = success["versions"].select{ |v| v if v["version"] == options[:version] }.first
54
- if !results
55
- @env.ui.warn(I18n.t("cloud_command.box.show_filter_empty", version: options[:version], org: org, box_name: box_name))
56
- return 0
63
+ if !box.empty?
64
+ box.each do |b|
65
+ format_box_results(b, @env)
66
+ @env.ui.output("")
57
67
  end
68
+ 0
58
69
  else
59
- results = success
70
+ @env.ui.warn(I18n.t("cloud_command.box.show_filter_empty",
71
+ version: options[:version], org: org, box_name: box_name))
72
+ 1
60
73
  end
61
- results = results.delete_if { |_, v| v.nil? }
62
- VagrantPlugins::CloudCommand::Util.format_box_results(results, @env)
63
- return 0
64
- rescue VagrantCloud::ClientError => e
65
- @env.ui.error(I18n.t("cloud_command.errors.box.show_fail", org: org,box_name:box_name))
66
- @env.ui.error(e)
67
- return 1
68
74
  end
75
+ rescue VagrantCloud::Error => e
76
+ @env.ui.error(I18n.t("cloud_command.errors.box.show_fail", org: org,box_name:box_name))
77
+ @env.ui.error(e.message)
78
+ 1
69
79
  end
70
80
  end
71
81
  end
@@ -5,6 +5,8 @@ module VagrantPlugins
5
5
  module BoxCommand
6
6
  module Command
7
7
  class Update < Vagrant.plugin("2", :command)
8
+ include Util
9
+
8
10
  def execute
9
11
  options = {}
10
12
 
@@ -19,13 +21,10 @@ module VagrantPlugins
19
21
  o.on("-d", "--description DESCRIPTION", "Full description of the box") do |d|
20
22
  options[:description] = d
21
23
  end
22
- o.on("-u", "--username", "The username of the organization that will own the box") do |u|
23
- options[:username] = u
24
- end
25
24
  o.on("-s", "--short-description DESCRIPTION", "Short description of the box") do |s|
26
- options[:short_description] = s
25
+ options[:short] = s
27
26
  end
28
- o.on("-p", "--private", "Makes box private") do |p|
27
+ o.on("-p", "--[no-]private", "Makes box private") do |p|
29
28
  options[:private] = p
30
29
  end
31
30
  end
@@ -33,36 +32,45 @@ module VagrantPlugins
33
32
  # Parse the options
34
33
  argv = parse_options(opts)
35
34
  return if !argv
36
- if argv.empty? || argv.length > 1 || options.length == 0
35
+ if argv.empty? || argv.length > 1 || options.slice(:description, :short, :private).length == 0
37
36
  raise Vagrant::Errors::CLIInvalidUsage,
38
37
  help: opts.help.chomp
39
38
  end
40
39
 
41
- @client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
42
- box = argv.first.split('/', 2)
40
+ @client = client_login(@env)
41
+ org, box_name = argv.first.split('/', 2)
43
42
 
44
- update_box(box[0], box[1], options, @client.token)
43
+ update_box(org, box_name, @client.token, options.slice(:short, :description, :private))
45
44
  end
46
45
 
47
- def update_box(org, box_name, options, access_token)
48
- server_url = VagrantPlugins::CloudCommand::Util.api_server_url
49
- account = VagrantPlugins::CloudCommand::Util.account(options[:username], access_token, server_url)
50
- box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
51
-
52
- options[:organization] = org
53
- options[:name] = box_name
54
- begin
55
- success = box.update(options)
46
+ # Update an existing box
47
+ #
48
+ # @param [String] org Organization name of box
49
+ # @param [String] box_name Name of box
50
+ # @param [String] access_token User access token
51
+ # @param [Hash] options Options for box filtering
52
+ # @option options [String] :short Short description of box
53
+ # @option options [String] :description Full description of box
54
+ # @option options [Boolean] :private Set box visibility as private
55
+ # @return [Integer]
56
+ def update_box(org, box_name, access_token, options={})
57
+ account = VagrantCloud::Account.new(
58
+ custom_server: api_server_url,
59
+ access_token: access_token
60
+ )
61
+ with_box(account: account, org: org, box: box_name) do |box|
62
+ box.short_description = options[:short] if options.key?(:short)
63
+ box.description = options[:description] if options.key?(:description)
64
+ box.private = options[:private] if options.key?(:private)
65
+ box.save
56
66
  @env.ui.success(I18n.t("cloud_command.box.update_success", org: org, box_name: box_name))
57
- success = success.delete_if{|_, v|v.nil?}
58
- VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
59
- return 0
60
- rescue VagrantCloud::ClientError => e
61
- @env.ui.error(I18n.t("cloud_command.errors.box.update_fail", org: org, box_name: box_name))
62
- @env.ui.error(e)
63
- return 1
67
+ format_box_results(box, @env)
68
+ 0
64
69
  end
65
- return 1
70
+ rescue VagrantCloud::Error => e
71
+ @env.ui.error(I18n.t("cloud_command.errors.box.update_fail", org: org, box_name: box_name))
72
+ @env.ui.error(e.message)
73
+ 1
66
74
  end
67
75
  end
68
76
  end
@@ -1,4 +1,3 @@
1
- require "rest_client"
2
1
  require "vagrant_cloud"
3
2
  require "vagrant/util/downloader"
4
3
  require "vagrant/util/presence"
@@ -7,13 +6,22 @@ require Vagrant.source_root.join("plugins/commands/cloud/errors")
7
6
  module VagrantPlugins
8
7
  module CloudCommand
9
8
  class Client
9
+ # @private
10
+ # Reset the cached values for scrubber. This is not considered a public
11
+ # API and should only be used for testing.
12
+ def self.reset!
13
+ class_variables.each(&method(:remove_class_variable))
14
+ end
15
+
10
16
  ######################################################################
11
17
  # Class that deals with managing users 'local' token for Vagrant Cloud
12
18
  ######################################################################
13
19
  APP = "app".freeze
14
20
 
21
+ include Util
15
22
  include Vagrant::Util::Presence
16
23
 
24
+ attr_accessor :client
17
25
  attr_accessor :username_or_email
18
26
  attr_accessor :password
19
27
  attr_reader :two_factor_default_delivery_method
@@ -25,6 +33,10 @@ module VagrantPlugins
25
33
  def initialize(env)
26
34
  @logger = Log4r::Logger.new("vagrant::cloud::client")
27
35
  @env = env
36
+ @client = VagrantCloud::Client.new(
37
+ access_token: token,
38
+ url_base: api_server_url
39
+ )
28
40
  end
29
41
 
30
42
  # Removes the token, effectively logging the user out.
@@ -38,14 +50,11 @@ module VagrantPlugins
38
50
  #
39
51
  # @return [Boolean]
40
52
  def logged_in?
41
- token = self.token
42
- return false if !token
43
- Vagrant::Util::CredentialScrubber.sensitive(token)
53
+ return false if !client.access_token
54
+ Vagrant::Util::CredentialScrubber.sensitive(client.access_token)
44
55
 
45
56
  with_error_handling do
46
- url = "#{Vagrant.server_url}/api/v1/authenticate" +
47
- "?access_token=#{token}"
48
- RestClient.get(url, content_type: :json)
57
+ client.authentication_token_validate
49
58
  true
50
59
  end
51
60
  rescue Errors::Unauthorized
@@ -62,23 +71,17 @@ module VagrantPlugins
62
71
  @logger.info("Logging in '#{username_or_email}'")
63
72
 
64
73
  Vagrant::Util::CredentialScrubber.sensitive(password)
65
- response = post(
66
- "/api/v1/authenticate", {
67
- user: {
68
- login: username_or_email,
69
- password: password
70
- },
71
- token: {
72
- description: description
73
- },
74
- two_factor: {
75
- code: code
76
- }
77
- }
78
- )
74
+ with_error_handling do
75
+ r = client.authentication_token_create(username: username_or_email,
76
+ password: password, description: description, code: code)
79
77
 
80
- Vagrant::Util::CredentialScrubber.sensitive(response["token"])
81
- response["token"]
78
+ Vagrant::Util::CredentialScrubber.sensitive(r[:token])
79
+ @client = VagrantCloud::Client.new(
80
+ access_token: r[:token],
81
+ url_base: api_server_url
82
+ )
83
+ r[:token]
84
+ end
82
85
  end
83
86
 
84
87
  # Requests a 2FA code
@@ -87,50 +90,14 @@ module VagrantPlugins
87
90
  @env.ui.warn("Requesting 2FA code via #{delivery_method.upcase}...")
88
91
 
89
92
  Vagrant::Util::CredentialScrubber.sensitive(password)
90
- response = post(
91
- "/api/v1/two-factor/request-code", {
92
- user: {
93
- login: username_or_email,
94
- password: password
95
- },
96
- two_factor: {
97
- delivery_method: delivery_method.downcase
98
- }
99
- }
100
- )
101
-
102
- two_factor = response['two_factor']
103
- obfuscated_destination = two_factor['obfuscated_destination']
104
-
105
- @env.ui.success("2FA code sent to #{obfuscated_destination}.")
106
- end
107
-
108
- # Issues a post to a Vagrant Cloud path with the given payload.
109
- # @param [String] path
110
- # @param [Hash] payload
111
- # @return [Hash] response data
112
- def post(path, payload)
113
93
  with_error_handling do
114
- url = File.join(Vagrant.server_url, path)
115
-
116
- proxy = nil
117
- proxy ||= ENV["HTTPS_PROXY"] || ENV["https_proxy"]
118
- proxy ||= ENV["HTTP_PROXY"] || ENV["http_proxy"]
119
- RestClient.proxy = proxy
120
-
121
- response = RestClient::Request.execute(
122
- method: :post,
123
- url: url,
124
- payload: JSON.dump(payload),
125
- proxy: proxy,
126
- headers: {
127
- accept: :json,
128
- content_type: :json,
129
- user_agent: Vagrant::Util::Downloader::USER_AGENT,
130
- },
131
- )
94
+ r = client.authentication_request_2fa_code(
95
+ username: username_or_email, password: password, delivery_method: delivery_method)
132
96
 
133
- JSON.load(response.to_s)
97
+ two_factor = r[:two_factor]
98
+ obfuscated_destination = two_factor[:obfuscated_destination]
99
+
100
+ @env.ui.success("2FA code sent to #{obfuscated_destination}.")
134
101
  end
135
102
  end
136
103
 
@@ -138,12 +105,16 @@ module VagrantPlugins
138
105
  #
139
106
  # @param [String] token
140
107
  def store_token(token)
108
+ Vagrant::Util::CredentialScrubber.sensitive(token)
141
109
  @logger.info("Storing token in #{token_path}")
142
110
 
143
111
  token_path.open("w") do |f|
144
112
  f.write(token)
145
113
  end
146
114
 
115
+ # Reset after we store the token since this is now _our_ token
116
+ @client = VagrantCloud::Client.new(access_token: token, url_base: api_server_url)
117
+
147
118
  nil
148
119
  end
149
120
 
@@ -154,7 +125,9 @@ module VagrantPlugins
154
125
  # @return [String]
155
126
  def token
156
127
  if present?(ENV["VAGRANT_CLOUD_TOKEN"]) && token_path.exist?
157
- @env.ui.warn <<-EOH.strip
128
+ # Only show warning if it has not been previously shown
129
+ if !defined?(@@double_token_warning)
130
+ @env.ui.warn <<-EOH.strip
158
131
  Vagrant detected both the VAGRANT_CLOUD_TOKEN environment variable and a Vagrant login
159
132
  token are present on this system. The VAGRANT_CLOUD_TOKEN environment variable takes
160
133
  precedence over the locally stored token. To remove this error, either unset
@@ -163,21 +136,24 @@ the VAGRANT_CLOUD_TOKEN environment variable or remove the login token stored on
163
136
  ~/.vagrant.d/data/vagrant_login_token
164
137
 
165
138
  EOH
139
+ @@double_token_warning = true
140
+ end
166
141
  end
167
142
 
168
143
  if present?(ENV["VAGRANT_CLOUD_TOKEN"])
169
144
  @logger.debug("Using authentication token from environment variable")
170
- return ENV["VAGRANT_CLOUD_TOKEN"]
171
- end
172
-
173
- if token_path.exist?
145
+ t = ENV["VAGRANT_CLOUD_TOKEN"]
146
+ elsif token_path.exist?
174
147
  @logger.debug("Using authentication token from disk at #{token_path}")
175
- return token_path.read.strip
148
+ t = token_path.read.strip
149
+ elsif present?(ENV["ATLAS_TOKEN"])
150
+ @logger.warn("ATLAS_TOKEN detected within environment. Using ATLAS_TOKEN in place of VAGRANT_CLOUD_TOKEN.")
151
+ t = ENV["ATLAS_TOKEN"]
176
152
  end
177
153
 
178
- if present?(ENV["ATLAS_TOKEN"])
179
- @logger.warn("ATLAS_TOKEN detected within environment. Using ATLAS_TOKEN in place of VAGRANT_CLOUD_TOKEN.")
180
- return ENV["ATLAS_TOKEN"]
154
+ if !t.nil?
155
+ Vagrant::Util::CredentialScrubber.sensitive(t)
156
+ return t
181
157
  end
182
158
 
183
159
  @logger.debug("No authentication token in environment or #{token_path}")
@@ -189,22 +165,22 @@ EOH
189
165
 
190
166
  def with_error_handling(&block)
191
167
  yield
192
- rescue RestClient::Unauthorized
168
+ rescue Excon::Error::Unauthorized
193
169
  @logger.debug("Unauthorized!")
194
170
  raise Errors::Unauthorized
195
- rescue RestClient::BadRequest => e
171
+ rescue Excon::Error::BadRequest => e
196
172
  @logger.debug("Bad request:")
197
173
  @logger.debug(e.message)
198
174
  @logger.debug(e.backtrace.join("\n"))
199
- parsed_response = JSON.parse(e.response)
175
+ parsed_response = JSON.parse(e.response.body)
200
176
  errors = parsed_response["errors"].join("\n")
201
177
  raise Errors::ServerError, errors: errors
202
- rescue RestClient::NotAcceptable => e
178
+ rescue Excon::Error::NotAcceptable => e
203
179
  @logger.debug("Got unacceptable response:")
204
180
  @logger.debug(e.message)
205
181
  @logger.debug(e.backtrace.join("\n"))
206
182
 
207
- parsed_response = JSON.parse(e.response)
183
+ parsed_response = JSON.parse(e.response.body)
208
184
 
209
185
  if two_factor = parsed_response['two_factor']
210
186
  store_two_factor_information two_factor