vagrant-unbundled 1.9.8.1 → 2.0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +47 -0
- data/Gemfile.lock +1 -1
- data/lib/vagrant/errors.rb +4 -0
- data/lib/vagrant/util/guest_inspection.rb +1 -1
- data/lib/vagrant/util/platform.rb +67 -16
- data/lib/vagrant/util/ssh.rb +2 -1
- data/plugins/commands/login/client.rb +101 -11
- data/plugins/commands/login/command.rb +41 -16
- data/plugins/commands/login/errors.rb +7 -0
- data/plugins/commands/login/locales/en.yml +4 -1
- data/plugins/commands/ssh_config/command.rb +9 -0
- data/plugins/communicators/winrm/shell.rb +14 -1
- data/plugins/guests/alt/cap/change_host_name.rb +46 -0
- data/plugins/guests/alt/cap/configure_networks.rb +126 -0
- data/plugins/guests/alt/cap/flavor.rb +63 -0
- data/plugins/guests/alt/cap/network_scripts_dir.rb +11 -0
- data/plugins/guests/alt/cap/rsync.rb +13 -0
- data/plugins/guests/alt/guest.rb +9 -0
- data/plugins/guests/alt/plugin.rb +40 -0
- data/plugins/guests/darwin/cap/shell_expand_guest_path.rb +2 -1
- data/plugins/guests/freebsd/cap/shell_expand_guest_path.rb +2 -1
- data/plugins/guests/kali/guest.rb +0 -0
- data/plugins/guests/kali/plugin.rb +0 -0
- data/plugins/guests/linux/cap/shell_expand_guest_path.rb +2 -1
- data/plugins/guests/netbsd/cap/shell_expand_guest_path.rb +2 -1
- data/plugins/guests/openbsd/cap/shell_expand_guest_path.rb +2 -1
- data/plugins/hosts/alt/cap/nfs.rb +43 -0
- data/plugins/hosts/alt/host.rb +11 -0
- data/plugins/hosts/alt/plugin.rb +32 -0
- data/plugins/hosts/gentoo/cap/nfs.rb +6 -13
- data/plugins/hosts/linux/cap/nfs.rb +53 -8
- data/plugins/hosts/redhat/cap/nfs.rb +10 -2
- data/plugins/providers/virtualbox/driver/version_4_0.rb +20 -6
- data/plugins/providers/virtualbox/driver/version_4_1.rb +20 -6
- data/plugins/providers/virtualbox/driver/version_4_2.rb +20 -6
- data/plugins/providers/virtualbox/driver/version_4_3.rb +20 -6
- data/plugins/providers/virtualbox/driver/version_5_0.rb +115 -74
- data/plugins/provisioners/ansible/config/base.rb +42 -6
- data/plugins/provisioners/ansible/config/guest.rb +0 -3
- data/plugins/provisioners/ansible/config/host.rb +12 -3
- data/plugins/provisioners/ansible/constants.rb +14 -0
- data/plugins/provisioners/ansible/errors.rb +13 -4
- data/plugins/provisioners/ansible/provisioner/base.rb +115 -5
- data/plugins/provisioners/ansible/provisioner/guest.rb +35 -15
- data/plugins/provisioners/ansible/provisioner/host.rb +53 -10
- data/plugins/provisioners/file/provisioner.rb +18 -5
- data/plugins/provisioners/salt/config.rb +14 -0
- data/plugins/provisioners/salt/provisioner.rb +37 -6
- data/templates/guests/alt/network_dhcp.erb +7 -0
- data/templates/guests/alt/network_ipv4address.erb +3 -0
- data/templates/guests/alt/network_ipv4route.erb +5 -0
- data/templates/guests/alt/network_static.erb +7 -0
- data/templates/locales/en.yml +45 -7
- data/test/unit/plugins/commands/login/client_test.rb +141 -24
- data/test/unit/plugins/commands/ssh_config/command_test.rb +16 -1
- data/test/unit/plugins/communicators/winrm/shell_test.rb +30 -1
- data/test/unit/plugins/guests/alt/cap/change_host_name_test.rb +42 -0
- data/test/unit/plugins/guests/alt/cap/configure_networks_test.rb +213 -0
- data/test/unit/plugins/guests/alt/cap/flavor_test.rb +72 -0
- data/test/unit/plugins/guests/alt/cap/network_scripts_dir_test.rb +21 -0
- data/test/unit/plugins/guests/alt/cap/rsync_test.rb +29 -0
- data/test/unit/plugins/guests/darwin/cap/shell_expand_guest_path_test.rb +3 -2
- data/test/unit/plugins/guests/freebsd/cap/shell_expand_guest_path_test.rb +3 -2
- data/test/unit/plugins/guests/linux/cap/shell_expand_guest_path_test.rb +3 -2
- data/test/unit/plugins/guests/netbsd/cap/shell_expand_guest_path_test.rb +3 -2
- data/test/unit/plugins/guests/openbsd/cap/shell_expand_guest_path_test.rb +3 -2
- data/test/unit/plugins/hosts/linux/cap/nfs_test.rb +77 -2
- data/test/unit/plugins/provisioners/ansible/config/guest_test.rb +7 -3
- data/test/unit/plugins/provisioners/ansible/config/host_test.rb +18 -3
- data/test/unit/plugins/provisioners/ansible/config/shared.rb +57 -3
- data/test/unit/plugins/provisioners/ansible/provisioner_test.rb +296 -70
- data/test/unit/plugins/provisioners/file/provisioner_test.rb +34 -0
- data/test/unit/plugins/provisioners/salt/config_test.rb +36 -0
- data/test/unit/plugins/provisioners/salt/provisioner_test.rb +85 -0
- data/test/unit/vagrant/util/platform_test.rb +86 -0
- data/test/unit/vagrant/util/ssh_test.rb +7 -7
- data/version.txt +1 -1
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab94e193c0cacc1e2503a53fc9cf56ebbacc8ca6
|
4
|
+
data.tar.gz: e9dff8cd516a995f503ed4e482c30bf788fb864a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7513bbf956fd58b41f9581ed285f799c5f26735a85d04de738aeab51261f75314840b6380e5659d4ae7a1aacc52bcf9cb0a8967d1dd071f9a75b2538efcef3e8
|
7
|
+
data.tar.gz: dddc399868eab9071a5c3db492680ca0896d49f66ce0a44937a2ddc0ae4ec63ee8034fa8d6cebcf05dd0c74e3fc53946175dc14d864614c4d46478168e2c708c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,50 @@
|
|
1
|
+
## 2.0.0 (September 7, 2017)
|
2
|
+
|
3
|
+
IMPROVEMENTS:
|
4
|
+
|
5
|
+
- commands/login: Add support for two-factor authentication [GH-8935]
|
6
|
+
- commands/ssh-config: Properly display windows path if invoked from msys2 or
|
7
|
+
cygwin [GH-8915]
|
8
|
+
- guests/alt: Add support for ALT Linux [GH-8746]
|
9
|
+
- guests/kali: Fix file permissions on guest plugin ruby files [GH-8950]
|
10
|
+
- hosts/linux: Provide common systemd detection for services interaction, fix NFS
|
11
|
+
host interactions [GH-8938]
|
12
|
+
- providers/salt: Remove duplicate stdout, stderr output from salt [GH-8767]
|
13
|
+
- providers/salt: Introduce salt_call_args and salt_args option for salt provisioner
|
14
|
+
[GH-8927]
|
15
|
+
- providers/virtualbox: Improving resilience of some VirtualBox commands [GH-8951]
|
16
|
+
- provisioners/ansible(both): Add the compatibility_mode option, with auto-detection
|
17
|
+
enabled by default [GH-8913, GH-6570]
|
18
|
+
- provisioners/ansible: Add the version option to the host-based provisioner
|
19
|
+
[GH-8913, GH-8914]
|
20
|
+
- provisioners/ansible(both): Add the become and become_user options with deprecation
|
21
|
+
of sudo and sudo_user options [GH-8913, GH-6570]
|
22
|
+
- provisioners/ansible: Add the ask_become_pass option with deprecation of the
|
23
|
+
ask_sudo_pass option [GH-8913, GH-6570]
|
24
|
+
|
25
|
+
BUG FIXES:
|
26
|
+
|
27
|
+
- guests/shell_expand_guest_path : Properly expand guest paths that include relative
|
28
|
+
path alias [GH-8918]
|
29
|
+
- hosts/linux: Remove duplicate export folders before writing /etc/exports [GH-8945]
|
30
|
+
- provisioners/ansible(both): Add single quotes to the inventory host variables, only
|
31
|
+
when necessary [GH-8597]
|
32
|
+
- provisioners/ansible(both): Add the "all:vars" section to the inventory when defined
|
33
|
+
in `groups` option [GH-7730]
|
34
|
+
- provisioners/ansible_local: Extra variables are no longer truncated when a dollar ($)
|
35
|
+
character is present [GH-7735]
|
36
|
+
- provisioners/file: Align file provisioner functionality on all platforms [GH-8939]
|
37
|
+
- util/ssh: Properly quote key path for IdentityFile option to allow for spaces [GH-8924]
|
38
|
+
|
39
|
+
BREAKING CHANGES:
|
40
|
+
|
41
|
+
- Both Ansible provisioners are now capable of automatically setting the compatibility_mode that
|
42
|
+
best fits with the Ansible version in use. You may encounter some compatibility issues when
|
43
|
+
upgrading. If you were using Ansible 2.x and referring to the _ssh-prefixed variables present
|
44
|
+
in the generated inventory (e.g. `ansible_ssh_host`). In this case, you can fix your Vagrant
|
45
|
+
setup by setting compatibility_mode = "1.8", or by migrating to the new variable names (e.g.
|
46
|
+
ansible_host).
|
47
|
+
|
1
48
|
## 1.9.8 (August 23, 2017)
|
2
49
|
|
3
50
|
IMPROVEMENTS:
|
data/Gemfile.lock
CHANGED
data/lib/vagrant/errors.rb
CHANGED
@@ -4,6 +4,7 @@ require "tmpdir"
|
|
4
4
|
|
5
5
|
require "vagrant/util/subprocess"
|
6
6
|
require "vagrant/util/powershell"
|
7
|
+
require "vagrant/util/which"
|
7
8
|
|
8
9
|
module Vagrant
|
9
10
|
module Util
|
@@ -19,6 +20,15 @@ module Vagrant
|
|
19
20
|
@_cygwin
|
20
21
|
end
|
21
22
|
|
23
|
+
def msys?
|
24
|
+
if !defined?(@_msys)
|
25
|
+
@_msys = ENV["VAGRANT_DETECTED_OS"].to_s.downcase.include?("msys") ||
|
26
|
+
platform.include?("msys") ||
|
27
|
+
ENV["OSTYPE"].to_s.downcase.include?("msys")
|
28
|
+
end
|
29
|
+
@_msys
|
30
|
+
end
|
31
|
+
|
22
32
|
def wsl?
|
23
33
|
if !defined?(@_wsl)
|
24
34
|
@_wsl = false
|
@@ -93,25 +103,36 @@ module Vagrant
|
|
93
103
|
# @param [String] path
|
94
104
|
# @return [String]
|
95
105
|
def cygwin_path(path)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
106
|
+
begin
|
107
|
+
# We have to revert to the old env
|
108
|
+
# path here, otherwise it looks like
|
109
|
+
# msys2 ends up using the wrong cygpath
|
110
|
+
# binary and ends up with a `/cygdrive`
|
111
|
+
# when it doesn't exist in msys2
|
112
|
+
original_path_env = ENV['PATH']
|
113
|
+
ENV['PATH'] = ENV['VAGRANT_OLD_ENV_PATH']
|
114
|
+
cygpath = Vagrant::Util::Which.which("cygpath")
|
115
|
+
cygpath.gsub!("/", '\\')
|
116
|
+
process = Subprocess.execute(
|
117
|
+
cygpath, "-u", "-a", path.to_s)
|
118
|
+
return process.stdout.chomp
|
119
|
+
rescue Errors::CommandUnavailableWindows => e
|
120
|
+
# Sometimes cygpath isn't available (msys). Instead, do what we
|
121
|
+
# can with bash tricks.
|
122
|
+
process = Subprocess.execute(
|
123
|
+
"bash",
|
124
|
+
"--noprofile",
|
125
|
+
"--norc",
|
126
|
+
"-c", "cd #{Shellwords.escape(path)} && pwd")
|
127
|
+
return process.stdout.chomp
|
128
|
+
ensure
|
129
|
+
ENV['PATH'] = original_path_env
|
103
130
|
end
|
104
|
-
|
105
|
-
# Sometimes cygpath isn't available (msys). Instead, do what we
|
106
|
-
# can with bash tricks.
|
107
|
-
process = Subprocess.execute(
|
108
|
-
"bash",
|
109
|
-
"--noprofile",
|
110
|
-
"--norc",
|
111
|
-
"-c", "cd #{Shellwords.escape(path)} && pwd")
|
112
|
-
return process.stdout.chomp
|
113
131
|
end
|
114
132
|
|
133
|
+
# Identical to cygwin_path for now
|
134
|
+
alias_method :msys_path, :cygwin_path
|
135
|
+
|
115
136
|
# This takes any path and converts it to a full-length Windows
|
116
137
|
# path on Windows machines in Cygwin.
|
117
138
|
#
|
@@ -264,6 +285,23 @@ module Vagrant
|
|
264
285
|
end
|
265
286
|
end
|
266
287
|
|
288
|
+
# Takes a windows path and formats it to the
|
289
|
+
# 'unix' style (i.e. `/cygdrive/c` or `/c/`)
|
290
|
+
#
|
291
|
+
# @param [Pathname, String] path Path to convert
|
292
|
+
# @param [Hash] hash of arguments
|
293
|
+
# @return [String]
|
294
|
+
def format_windows_path(path, *args)
|
295
|
+
path = cygwin_path(path) if cygwin?
|
296
|
+
path = msys_path(path) if msys?
|
297
|
+
path = wsl_to_windows_path(path) if wsl?
|
298
|
+
if windows? || wsl?
|
299
|
+
path = windows_unc_path(path) if !args.include?(:disable_unc)
|
300
|
+
end
|
301
|
+
|
302
|
+
path
|
303
|
+
end
|
304
|
+
|
267
305
|
# Automatically convert a given path to a Windows path. Will only
|
268
306
|
# be applied if running on a Windows host. If running on Windows
|
269
307
|
# host within the WSL, the actual Windows path will be returned.
|
@@ -410,6 +448,19 @@ module Vagrant
|
|
410
448
|
end
|
411
449
|
end
|
412
450
|
|
451
|
+
# systemd is in use
|
452
|
+
def systemd?
|
453
|
+
if !defined?(@_systemd)
|
454
|
+
if !windows?
|
455
|
+
result = Vagrant::Util::Subprocess.execute("ps", "-o", "comm=", "1")
|
456
|
+
@_systemd = result.stdout.chomp == "systemd"
|
457
|
+
else
|
458
|
+
@_systemd = false
|
459
|
+
end
|
460
|
+
end
|
461
|
+
@_systemd
|
462
|
+
end
|
463
|
+
|
413
464
|
# @private
|
414
465
|
# Reset the cached values for platform. This is not considered a public
|
415
466
|
# API and should only be used for testing.
|
data/lib/vagrant/util/ssh.rb
CHANGED
@@ -139,7 +139,8 @@ module Vagrant
|
|
139
139
|
# Use '-o' instead of '-i' because '-i' does not call
|
140
140
|
# percent_expand in misc.c, but '-o' does. when passing the path,
|
141
141
|
# replace '%' in the path with '%%' to escape the '%'
|
142
|
-
|
142
|
+
path = path.to_s.gsub('%', '%%')
|
143
|
+
command_options += ["-o", "IdentityFile=\"#{path}\""]
|
143
144
|
end
|
144
145
|
end
|
145
146
|
|
@@ -5,8 +5,15 @@ require "vagrant/util/presence"
|
|
5
5
|
module VagrantPlugins
|
6
6
|
module LoginCommand
|
7
7
|
class Client
|
8
|
+
APP = "app".freeze
|
9
|
+
|
8
10
|
include Vagrant::Util::Presence
|
9
11
|
|
12
|
+
attr_accessor :username_or_email
|
13
|
+
attr_accessor :password
|
14
|
+
attr_reader :two_factor_default_delivery_method
|
15
|
+
attr_reader :two_factor_delivery_methods
|
16
|
+
|
10
17
|
# Initializes a login client with the given Vagrant::Environment.
|
11
18
|
#
|
12
19
|
# @param [Vagrant::Environment] env
|
@@ -35,29 +42,67 @@ module VagrantPlugins
|
|
35
42
|
RestClient.get(url, content_type: :json)
|
36
43
|
true
|
37
44
|
end
|
45
|
+
rescue Errors::Unauthorized
|
46
|
+
false
|
38
47
|
end
|
39
48
|
|
40
49
|
# Login logs a user in and returns the token for that user. The token
|
41
50
|
# is _not_ stored unless {#store_token} is called.
|
42
51
|
#
|
43
|
-
# @param [String] username_or_email
|
44
|
-
# @param [String] password
|
45
52
|
# @param [String] description
|
53
|
+
# @param [String] code
|
46
54
|
# @return [String] token The access token, or nil if auth failed.
|
47
|
-
def login(
|
55
|
+
def login(description: nil, code: nil)
|
48
56
|
@logger.info("Logging in '#{username_or_email}'")
|
49
57
|
|
50
|
-
|
51
|
-
|
52
|
-
request = {
|
58
|
+
response = post(
|
59
|
+
"/api/v1/authenticate", {
|
53
60
|
user: {
|
54
61
|
login: username_or_email,
|
55
62
|
password: password
|
56
63
|
},
|
57
64
|
token: {
|
58
65
|
description: description
|
66
|
+
},
|
67
|
+
two_factor: {
|
68
|
+
code: code
|
69
|
+
}
|
70
|
+
}
|
71
|
+
)
|
72
|
+
|
73
|
+
response["token"]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Requests a 2FA code
|
77
|
+
# @param [String] delivery_method
|
78
|
+
def request_code(delivery_method)
|
79
|
+
@env.ui.warn("Requesting 2FA code via #{delivery_method.upcase}...")
|
80
|
+
|
81
|
+
response = post(
|
82
|
+
"/api/v1/two-factor/request-code", {
|
83
|
+
user: {
|
84
|
+
login: username_or_email,
|
85
|
+
password: password
|
86
|
+
},
|
87
|
+
two_factor: {
|
88
|
+
delivery_method: delivery_method.downcase
|
59
89
|
}
|
60
90
|
}
|
91
|
+
)
|
92
|
+
|
93
|
+
two_factor = response['two_factor']
|
94
|
+
obfuscated_destination = two_factor['obfuscated_destination']
|
95
|
+
|
96
|
+
@env.ui.success("2FA code sent to #{obfuscated_destination}.")
|
97
|
+
end
|
98
|
+
|
99
|
+
# Issues a post to a Vagrant Cloud path with the given payload.
|
100
|
+
# @param [String] path
|
101
|
+
# @param [Hash] payload
|
102
|
+
# @return [Hash] response data
|
103
|
+
def post(path, payload)
|
104
|
+
with_error_handling do
|
105
|
+
url = File.join(Vagrant.server_url, path)
|
61
106
|
|
62
107
|
proxy = nil
|
63
108
|
proxy ||= ENV["HTTPS_PROXY"] || ENV["https_proxy"]
|
@@ -67,7 +112,7 @@ module VagrantPlugins
|
|
67
112
|
response = RestClient::Request.execute(
|
68
113
|
method: :post,
|
69
114
|
url: url,
|
70
|
-
payload: JSON.dump(
|
115
|
+
payload: JSON.dump(payload),
|
71
116
|
proxy: proxy,
|
72
117
|
headers: {
|
73
118
|
accept: :json,
|
@@ -76,8 +121,7 @@ module VagrantPlugins
|
|
76
121
|
},
|
77
122
|
)
|
78
123
|
|
79
|
-
|
80
|
-
data["token"]
|
124
|
+
JSON.load(response.to_s)
|
81
125
|
end
|
82
126
|
end
|
83
127
|
|
@@ -138,14 +182,33 @@ EOH
|
|
138
182
|
yield
|
139
183
|
rescue RestClient::Unauthorized
|
140
184
|
@logger.debug("Unauthorized!")
|
141
|
-
|
185
|
+
raise Errors::Unauthorized
|
186
|
+
rescue RestClient::BadRequest => e
|
187
|
+
@logger.debug("Bad request:")
|
188
|
+
@logger.debug(e.message)
|
189
|
+
@logger.debug(e.backtrace.join("\n"))
|
190
|
+
parsed_response = JSON.parse(e.response)
|
191
|
+
errors = parsed_response["errors"].join("\n")
|
192
|
+
raise Errors::ServerError, errors: errors
|
142
193
|
rescue RestClient::NotAcceptable => e
|
143
194
|
@logger.debug("Got unacceptable response:")
|
144
195
|
@logger.debug(e.message)
|
145
196
|
@logger.debug(e.backtrace.join("\n"))
|
146
197
|
|
198
|
+
parsed_response = JSON.parse(e.response)
|
199
|
+
|
200
|
+
if two_factor = parsed_response['two_factor']
|
201
|
+
store_two_factor_information two_factor
|
202
|
+
|
203
|
+
if two_factor_default_delivery_method != APP
|
204
|
+
request_code two_factor_default_delivery_method
|
205
|
+
end
|
206
|
+
|
207
|
+
raise Errors::TwoFactorRequired
|
208
|
+
end
|
209
|
+
|
147
210
|
begin
|
148
|
-
errors =
|
211
|
+
errors = parsed_response["errors"].join("\n")
|
149
212
|
raise Errors::ServerError, errors: errors
|
150
213
|
rescue JSON::ParserError; end
|
151
214
|
|
@@ -158,6 +221,33 @@ EOH
|
|
158
221
|
def token_path
|
159
222
|
@env.data_dir.join("vagrant_login_token")
|
160
223
|
end
|
224
|
+
|
225
|
+
def store_two_factor_information(two_factor)
|
226
|
+
@two_factor_default_delivery_method =
|
227
|
+
two_factor['default_delivery_method']
|
228
|
+
|
229
|
+
@two_factor_delivery_methods =
|
230
|
+
two_factor['delivery_methods']
|
231
|
+
|
232
|
+
@env.ui.warn "2FA is enabled for your account."
|
233
|
+
if two_factor_default_delivery_method == APP
|
234
|
+
@env.ui.info "Enter the code from your authenticator."
|
235
|
+
else
|
236
|
+
@env.ui.info "Default method is " \
|
237
|
+
"'#{two_factor_default_delivery_method}'."
|
238
|
+
end
|
239
|
+
|
240
|
+
other_delivery_methods =
|
241
|
+
two_factor_delivery_methods - [APP]
|
242
|
+
|
243
|
+
if other_delivery_methods.any?
|
244
|
+
other_delivery_methods_sentence = other_delivery_methods
|
245
|
+
.map { |word| "'#{word}'" }
|
246
|
+
.join(' or ')
|
247
|
+
@env.ui.info "You can also type #{other_delivery_methods_sentence} " \
|
248
|
+
"to request a new code."
|
249
|
+
end
|
250
|
+
end
|
161
251
|
end
|
162
252
|
end
|
163
253
|
end
|
@@ -17,6 +17,10 @@ module VagrantPlugins
|
|
17
17
|
options[:check] = c
|
18
18
|
end
|
19
19
|
|
20
|
+
o.on("-d", "--description DESCRIPTION", String, "Description for the Vagrant Cloud token") do |t|
|
21
|
+
options[:description] = t
|
22
|
+
end
|
23
|
+
|
20
24
|
o.on("-k", "--logout", "Logs you out if you're logged in") do |k|
|
21
25
|
options[:logout] = k
|
22
26
|
end
|
@@ -24,6 +28,10 @@ module VagrantPlugins
|
|
24
28
|
o.on("-t", "--token TOKEN", String, "Set the Vagrant Cloud token") do |t|
|
25
29
|
options[:token] = t
|
26
30
|
end
|
31
|
+
|
32
|
+
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Specify your Vagrant Cloud username or email address") do |t|
|
33
|
+
options[:login] = t
|
34
|
+
end
|
27
35
|
end
|
28
36
|
|
29
37
|
# Parse the options
|
@@ -31,6 +39,7 @@ module VagrantPlugins
|
|
31
39
|
return if !argv
|
32
40
|
|
33
41
|
@client = Client.new(@env)
|
42
|
+
@client.username_or_email = options[:login]
|
34
43
|
|
35
44
|
# Determine what task we're actually taking based on flags
|
36
45
|
if options[:check]
|
@@ -50,28 +59,44 @@ module VagrantPlugins
|
|
50
59
|
end
|
51
60
|
|
52
61
|
# Ask for the username
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
62
|
+
if @client.username_or_email
|
63
|
+
@env.ui.output("Vagrant Cloud username or email: #{@client.username_or_email}")
|
64
|
+
end
|
65
|
+
until @client.username_or_email
|
66
|
+
@client.username_or_email = @env.ui.ask("Vagrant Cloud username or email: ")
|
58
67
|
end
|
59
68
|
|
60
|
-
|
61
|
-
password = @env.ui.ask("Password (will be hidden): ", echo: false)
|
69
|
+
until @client.password
|
70
|
+
@client.password = @env.ui.ask("Password (will be hidden): ", echo: false)
|
62
71
|
end
|
63
72
|
|
64
|
-
|
65
|
-
|
66
|
-
description
|
67
|
-
|
73
|
+
description = options[:description]
|
74
|
+
if description
|
75
|
+
@env.ui.output("Token description: #{description}")
|
76
|
+
else
|
77
|
+
description_default = "Vagrant login from #{Socket.gethostname}"
|
78
|
+
until description
|
79
|
+
description =
|
80
|
+
@env.ui.ask("Token description (Defaults to #{description_default.inspect}): ")
|
81
|
+
end
|
82
|
+
description = description_default if description.empty?
|
68
83
|
end
|
69
|
-
description = description_default if description.empty?
|
70
84
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
85
|
+
code = nil
|
86
|
+
|
87
|
+
begin
|
88
|
+
token = @client.login(description: description, code: code)
|
89
|
+
rescue Errors::TwoFactorRequired
|
90
|
+
until code
|
91
|
+
code = @env.ui.ask("2FA code: ")
|
92
|
+
|
93
|
+
if @client.two_factor_delivery_methods.include?(code.downcase)
|
94
|
+
delivery_method, code = code, nil
|
95
|
+
@client.request_code delivery_method
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
retry
|
75
100
|
end
|
76
101
|
|
77
102
|
@client.store_token(token)
|