Merge pull request #11916 from chrisroberts/e-vagrant-cloud-lib
Update cloud command to use refactored library implementation
This commit is contained in:
commit
57ddab2672
@ -13,9 +13,11 @@ module Vagrant
|
||||
# a hand-rolled Ruby library, so we defer to its expertise.
|
||||
class Uploader
|
||||
|
||||
# @param [String] destination - valid URL to upload file to
|
||||
# @param [String] file - location of file to upload on disk
|
||||
# @param [Hash] options
|
||||
# @param [String] destination Valid URL to upload file to
|
||||
# @param [String] file Location of file to upload on disk
|
||||
# @param [Hash] options
|
||||
# @option options [Vagrant::UI] :ui UI interface for output
|
||||
# @option options [String, Symbol] :method Request method for upload
|
||||
def initialize(destination, file, options=nil)
|
||||
options ||= {}
|
||||
@logger = Log4r::Logger.new("vagrant::util::uploader")
|
||||
@ -27,6 +29,7 @@ module Vagrant
|
||||
if !@request_method
|
||||
@request_method = "PUT"
|
||||
end
|
||||
@request_method = @request_method.to_s.upcase
|
||||
end
|
||||
|
||||
def upload!
|
||||
@ -51,7 +54,7 @@ module Vagrant
|
||||
protected
|
||||
|
||||
def build_options
|
||||
options = [@destination, "--request", @request_method, "--upload-file", @file]
|
||||
options = [@destination, "--request", @request_method, "--upload-file", @file, "--fail"]
|
||||
return options
|
||||
end
|
||||
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module AuthCommand
|
||||
module Command
|
||||
class Login < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -16,15 +18,10 @@ module VagrantPlugins
|
||||
o.on("-c", "--check", "Checks if currently logged in") do |c|
|
||||
options[:check] = c
|
||||
end
|
||||
|
||||
o.on("-d", "--description DESCRIPTION", String, "Set description for the Vagrant Cloud token") do |d|
|
||||
options[:description] = d
|
||||
end
|
||||
|
||||
o.on("-k", "--logout", "Logout from Vagrant Cloud") do |k|
|
||||
options[:logout] = k
|
||||
end
|
||||
|
||||
o.on("-t", "--token TOKEN", String, "Set the Vagrant Cloud token") do |t|
|
||||
options[:token] = t
|
||||
end
|
||||
@ -37,26 +34,32 @@ module VagrantPlugins
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if !argv.empty?
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = Client.new(@env)
|
||||
@client.username_or_email = options[:login]
|
||||
client = Client.new(@env)
|
||||
client.username_or_email = options[:login]
|
||||
|
||||
# Determine what task we're actually taking based on flags
|
||||
if options[:check]
|
||||
return execute_check
|
||||
elsif options[:logout]
|
||||
return execute_logout
|
||||
return execute_check(client)
|
||||
elsif options[:token]
|
||||
return execute_token(options[:token])
|
||||
return execute_token(client, options[:token])
|
||||
else
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options)
|
||||
if client.logged_in?
|
||||
@env.ui.success(I18n.t("cloud_command.check_logged_in"))
|
||||
else
|
||||
client_login(@env, options.slice(:login, :description))
|
||||
end
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
def execute_check
|
||||
if @client.logged_in?
|
||||
def execute_check(client)
|
||||
if client.logged_in?
|
||||
@env.ui.success(I18n.t("cloud_command.check_logged_in"))
|
||||
return 0
|
||||
else
|
||||
@ -65,17 +68,11 @@ module VagrantPlugins
|
||||
end
|
||||
end
|
||||
|
||||
def execute_logout
|
||||
@client.clear_token
|
||||
@env.ui.success(I18n.t("cloud_command.logged_out"))
|
||||
return 0
|
||||
end
|
||||
|
||||
def execute_token(token)
|
||||
@client.store_token(token)
|
||||
def execute_token(client, token)
|
||||
client.store_token(token)
|
||||
@env.ui.success(I18n.t("cloud_command.token_saved"))
|
||||
|
||||
if @client.logged_in?
|
||||
if client.logged_in?
|
||||
@env.ui.success(I18n.t("cloud_command.check_logged_in"))
|
||||
return 0
|
||||
else
|
||||
|
||||
@ -9,15 +9,9 @@ module VagrantPlugins
|
||||
options = {}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant cloud auth logout [options]"
|
||||
o.banner = "Usage: vagrant cloud auth logout"
|
||||
o.separator ""
|
||||
o.separator "Log out of Vagrant Cloud"
|
||||
o.separator ""
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |l|
|
||||
options[:login] = l
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
@ -28,9 +22,7 @@ module VagrantPlugins
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
# Initializes client and deletes token on disk
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
|
||||
@client = Client.new(@env)
|
||||
@client.clear_token
|
||||
@env.ui.success(I18n.t("cloud_command.logged_out"))
|
||||
return 0
|
||||
|
||||
@ -5,19 +5,15 @@ module VagrantPlugins
|
||||
module AuthCommand
|
||||
module Command
|
||||
class Whoami < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant cloud auth whoami [options] [token]"
|
||||
o.banner = "Usage: vagrant cloud auth whoami [token]"
|
||||
o.separator ""
|
||||
o.separator "Display currently logged in user"
|
||||
o.separator ""
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |l|
|
||||
options[:login] = l
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
@ -28,28 +24,30 @@ module VagrantPlugins
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:login])
|
||||
|
||||
if argv.first
|
||||
token = argv.first
|
||||
else
|
||||
token = @client.token
|
||||
client = Client.new(@env)
|
||||
token = client.token
|
||||
end
|
||||
|
||||
whoami(token, options[:username])
|
||||
whoami(token)
|
||||
end
|
||||
|
||||
def whoami(access_token, username)
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(username, access_token, server_url)
|
||||
|
||||
def whoami(access_token)
|
||||
if access_token.to_s.empty?
|
||||
@env.ui.error(I18n.t("cloud_command.check_not_logged_in"))
|
||||
return 1
|
||||
end
|
||||
begin
|
||||
success = account.validate_token
|
||||
user = success["user"]["username"]
|
||||
@env.ui.success("Currently logged in as #{user}")
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
@env.ui.success("Currently logged in as #{account.username}")
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.whoami.read_error", org: username))
|
||||
rescue VagrantCloud::Error::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.whoami.read_error"))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module BoxCommand
|
||||
module Command
|
||||
class Create < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -19,13 +21,10 @@ module VagrantPlugins
|
||||
o.on("-d", "--description DESCRIPTION", String, "Full description of the box") do |d|
|
||||
options[:description] = d
|
||||
end
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
end
|
||||
o.on("-s", "--short-description DESCRIPTION", String, "Short description of the box") do |s|
|
||||
options[:short] = s
|
||||
end
|
||||
o.on("-p", "--private", "Makes box private") do |p|
|
||||
o.on("-p", "--[no-]private", "Makes box private") do |p|
|
||||
options[:private] = p
|
||||
end
|
||||
end
|
||||
@ -38,35 +37,40 @@ module VagrantPlugins
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
@client = client_login(@env)
|
||||
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
create_box(org, box_name, options, @client.token)
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
create_box(org, box_name, @client.token, options.slice(:description, :short, :private))
|
||||
end
|
||||
|
||||
# @param [String] - org
|
||||
# @param [String] - box_name
|
||||
# @param [Hash] - options
|
||||
def create_box(org, box_name, options, access_token)
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, options[:short], options[:description], access_token)
|
||||
# Create a new box
|
||||
#
|
||||
# @param [String] org Organization name of box
|
||||
# @param [String] box_name Name of box
|
||||
# @param [String] access_token User access token
|
||||
# @param [Hash] options Options for box filtering
|
||||
# @option options [String] :short Short description of box
|
||||
# @option options [String] :description Full description of box
|
||||
# @option options [Boolean] :private Set box visibility as private
|
||||
# @return [Integer]
|
||||
def create_box(org, box_name, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
box = account.organization(name: org).add_box(box_name)
|
||||
box.short_description = options[:short] if options.key?(:short)
|
||||
box.description = options[:description] if options.key?(:description)
|
||||
box.private = options[:private] if options.key?(:private)
|
||||
box.save
|
||||
|
||||
begin
|
||||
success = box.create
|
||||
@env.ui.success(I18n.t("cloud_command.box.create_success", org: org, box_name: box_name))
|
||||
success = success.delete_if { |_, v| v.nil? }
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.box.create_fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
end
|
||||
|
||||
return 1
|
||||
@env.ui.success(I18n.t("cloud_command.box.create_success", org: org, box_name: box_name))
|
||||
format_box_results(box, @env)
|
||||
0
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.box.create_fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module BoxCommand
|
||||
module Command
|
||||
class Delete < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -16,8 +18,8 @@ module VagrantPlugins
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
o.on("-f", "--[no-]force", "Do not prompt for deletion confirmation") do |f|
|
||||
options[:force] = f
|
||||
end
|
||||
end
|
||||
|
||||
@ -29,34 +31,38 @@ module VagrantPlugins
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@env.ui.warn(I18n.t("cloud_command.box.delete_warn", box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
delete_box(org, box_name, options[:username], @client.token)
|
||||
end
|
||||
|
||||
def delete_box(org, box_name, username, access_token)
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(username, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
|
||||
begin
|
||||
success = box.delete(org, box_name)
|
||||
@env.ui.success(I18n.t("cloud_command.box.delete_success", org: org, box_name: box_name))
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.box.delete_fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
if !options[:force]
|
||||
@env.ui.warn(I18n.t("cloud_command.box.delete_warn", box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
end
|
||||
|
||||
return 1
|
||||
@client = client_login(@env)
|
||||
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
delete_box(org, box_name, @client.token)
|
||||
end
|
||||
|
||||
# Delete the requested box
|
||||
#
|
||||
# @param [String] org Organization name of box
|
||||
# @param [String] box_name Name of box
|
||||
# @param [String] access_token User access token
|
||||
# @return [Integer]
|
||||
def delete_box(org, box_name, access_token)
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_box(account: account, org: org, box: box_name) do |box|
|
||||
box.delete
|
||||
@env.ui.success(I18n.t("cloud_command.box.delete_success", org: org, box_name: box_name))
|
||||
0
|
||||
end
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.box.delete_fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,8 +5,10 @@ module VagrantPlugins
|
||||
module BoxCommand
|
||||
module Command
|
||||
class Show < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
options = {quiet: true, versions: []}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant cloud box show [options] organization/box-name"
|
||||
@ -16,11 +18,11 @@ module VagrantPlugins
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
o.on("--versions VERSION", String, "Display box information for a specific version (can be defined multiple times)") do |v|
|
||||
options[:versions] << v
|
||||
end
|
||||
o.on("--versions VERSION", String, "Display box information for a specific version") do |v|
|
||||
options[:version] = v
|
||||
o.on("--[no-]auth", "Authenticate with Vagrant Cloud if required before searching") do |l|
|
||||
options[:quiet] = !l
|
||||
end
|
||||
end
|
||||
|
||||
@ -32,40 +34,48 @@ module VagrantPlugins
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
box = argv.first.split('/', 2)
|
||||
@client = client_login(@env, options.slice(:quiet))
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
|
||||
show_box(box[0], box[1], options, @client.token)
|
||||
show_box(org, box_name, @client&.token, options.slice(:versions))
|
||||
end
|
||||
|
||||
def show_box(org, box_name, options, access_token)
|
||||
username = options[:username]
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(username, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
|
||||
begin
|
||||
success = box.read(org, box_name)
|
||||
|
||||
if options[:version]
|
||||
# show *this* version only
|
||||
results = success["versions"].select{ |v| v if v["version"] == options[:version] }.first
|
||||
if !results
|
||||
@env.ui.warn(I18n.t("cloud_command.box.show_filter_empty", version: options[:version], org: org, box_name: box_name))
|
||||
return 0
|
||||
end
|
||||
# Display the requested box to the user
|
||||
#
|
||||
# @param [String] org Organization name of box
|
||||
# @param [String] box_name Name of box
|
||||
# @param [String] access_token User access token
|
||||
# @param [Hash] options Options for box filtering
|
||||
# @option options [String] :versions Specific verisons of box
|
||||
# @return [Integer]
|
||||
def show_box(org, box_name, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_box(account: account, org: org, box: box_name) do |box|
|
||||
if box && !Array(options[:versions]).empty?
|
||||
box = box.versions.find_all{ |v| options[:versions].include?(v.version) }
|
||||
else
|
||||
results = success
|
||||
box = [box]
|
||||
end
|
||||
|
||||
if !box.empty?
|
||||
box.each do |b|
|
||||
format_box_results(b, @env)
|
||||
@env.ui.output("")
|
||||
end
|
||||
0
|
||||
else
|
||||
@env.ui.warn(I18n.t("cloud_command.box.show_filter_empty",
|
||||
version: options[:version], org: org, box_name: box_name))
|
||||
1
|
||||
end
|
||||
results = results.delete_if { |_, v| v.nil? }
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(results, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.box.show_fail", org: org,box_name:box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
end
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.box.show_fail", org: org,box_name:box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module BoxCommand
|
||||
module Command
|
||||
class Update < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -19,13 +21,10 @@ module VagrantPlugins
|
||||
o.on("-d", "--description DESCRIPTION", "Full description of the box") do |d|
|
||||
options[:description] = d
|
||||
end
|
||||
o.on("-u", "--username", "The username of the organization that will own the box") do |u|
|
||||
options[:username] = u
|
||||
end
|
||||
o.on("-s", "--short-description DESCRIPTION", "Short description of the box") do |s|
|
||||
options[:short_description] = s
|
||||
options[:short] = s
|
||||
end
|
||||
o.on("-p", "--private", "Makes box private") do |p|
|
||||
o.on("-p", "--[no-]private", "Makes box private") do |p|
|
||||
options[:private] = p
|
||||
end
|
||||
end
|
||||
@ -33,36 +32,45 @@ module VagrantPlugins
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 1 || options.length == 0
|
||||
if argv.empty? || argv.length > 1 || options.slice(:description, :short, :private).length == 0
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
box = argv.first.split('/', 2)
|
||||
@client = client_login(@env)
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
|
||||
update_box(box[0], box[1], options, @client.token)
|
||||
update_box(org, box_name, @client.token, options.slice(:short, :description, :private))
|
||||
end
|
||||
|
||||
def update_box(org, box_name, options, access_token)
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(options[:username], access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
|
||||
options[:organization] = org
|
||||
options[:name] = box_name
|
||||
begin
|
||||
success = box.update(options)
|
||||
# Update an existing box
|
||||
#
|
||||
# @param [String] org Organization name of box
|
||||
# @param [String] box_name Name of box
|
||||
# @param [String] access_token User access token
|
||||
# @param [Hash] options Options for box filtering
|
||||
# @option options [String] :short Short description of box
|
||||
# @option options [String] :description Full description of box
|
||||
# @option options [Boolean] :private Set box visibility as private
|
||||
# @return [Integer]
|
||||
def update_box(org, box_name, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_box(account: account, org: org, box: box_name) do |box|
|
||||
box.short_description = options[:short] if options.key?(:short)
|
||||
box.description = options[:description] if options.key?(:description)
|
||||
box.private = options[:private] if options.key?(:private)
|
||||
box.save
|
||||
@env.ui.success(I18n.t("cloud_command.box.update_success", org: org, box_name: box_name))
|
||||
success = success.delete_if{|_, v|v.nil?}
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.box.update_fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
format_box_results(box, @env)
|
||||
0
|
||||
end
|
||||
return 1
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.box.update_fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
require "rest_client"
|
||||
require "vagrant_cloud"
|
||||
require "vagrant/util/downloader"
|
||||
require "vagrant/util/presence"
|
||||
@ -14,6 +13,7 @@ module VagrantPlugins
|
||||
|
||||
include Vagrant::Util::Presence
|
||||
|
||||
attr_accessor :client
|
||||
attr_accessor :username_or_email
|
||||
attr_accessor :password
|
||||
attr_reader :two_factor_default_delivery_method
|
||||
@ -25,6 +25,7 @@ module VagrantPlugins
|
||||
def initialize(env)
|
||||
@logger = Log4r::Logger.new("vagrant::cloud::client")
|
||||
@env = env
|
||||
@client = VagrantCloud::Client.new(access_token: token)
|
||||
end
|
||||
|
||||
# Removes the token, effectively logging the user out.
|
||||
@ -38,14 +39,11 @@ module VagrantPlugins
|
||||
#
|
||||
# @return [Boolean]
|
||||
def logged_in?
|
||||
token = self.token
|
||||
return false if !token
|
||||
Vagrant::Util::CredentialScrubber.sensitive(token)
|
||||
return false if !client.access_token
|
||||
Vagrant::Util::CredentialScrubber.sensitive(client.access_token)
|
||||
|
||||
with_error_handling do
|
||||
url = "#{Vagrant.server_url}/api/v1/authenticate" +
|
||||
"?access_token=#{token}"
|
||||
RestClient.get(url, content_type: :json)
|
||||
client.authentication_token_validate
|
||||
true
|
||||
end
|
||||
rescue Errors::Unauthorized
|
||||
@ -62,23 +60,14 @@ module VagrantPlugins
|
||||
@logger.info("Logging in '#{username_or_email}'")
|
||||
|
||||
Vagrant::Util::CredentialScrubber.sensitive(password)
|
||||
response = post(
|
||||
"/api/v1/authenticate", {
|
||||
user: {
|
||||
login: username_or_email,
|
||||
password: password
|
||||
},
|
||||
token: {
|
||||
description: description
|
||||
},
|
||||
two_factor: {
|
||||
code: code
|
||||
}
|
||||
}
|
||||
)
|
||||
with_error_handling do
|
||||
r = client.authentication_token_create(username: username_or_email,
|
||||
password: password, description: description, code: code)
|
||||
|
||||
Vagrant::Util::CredentialScrubber.sensitive(response["token"])
|
||||
response["token"]
|
||||
Vagrant::Util::CredentialScrubber.sensitive(r[:token])
|
||||
@client = VagrantCloud::Client.new(access_token: r[:token])
|
||||
r[:token]
|
||||
end
|
||||
end
|
||||
|
||||
# Requests a 2FA code
|
||||
@ -87,50 +76,14 @@ module VagrantPlugins
|
||||
@env.ui.warn("Requesting 2FA code via #{delivery_method.upcase}...")
|
||||
|
||||
Vagrant::Util::CredentialScrubber.sensitive(password)
|
||||
response = post(
|
||||
"/api/v1/two-factor/request-code", {
|
||||
user: {
|
||||
login: username_or_email,
|
||||
password: password
|
||||
},
|
||||
two_factor: {
|
||||
delivery_method: delivery_method.downcase
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
two_factor = response['two_factor']
|
||||
obfuscated_destination = two_factor['obfuscated_destination']
|
||||
|
||||
@env.ui.success("2FA code sent to #{obfuscated_destination}.")
|
||||
end
|
||||
|
||||
# Issues a post to a Vagrant Cloud path with the given payload.
|
||||
# @param [String] path
|
||||
# @param [Hash] payload
|
||||
# @return [Hash] response data
|
||||
def post(path, payload)
|
||||
with_error_handling do
|
||||
url = File.join(Vagrant.server_url, path)
|
||||
r = client.authentication_request_2fa_code(
|
||||
username: username_or_email, password: password, delivery_method: delivery_method)
|
||||
|
||||
proxy = nil
|
||||
proxy ||= ENV["HTTPS_PROXY"] || ENV["https_proxy"]
|
||||
proxy ||= ENV["HTTP_PROXY"] || ENV["http_proxy"]
|
||||
RestClient.proxy = proxy
|
||||
two_factor = r[:two_factor]
|
||||
obfuscated_destination = two_factor[:obfuscated_destination]
|
||||
|
||||
response = RestClient::Request.execute(
|
||||
method: :post,
|
||||
url: url,
|
||||
payload: JSON.dump(payload),
|
||||
proxy: proxy,
|
||||
headers: {
|
||||
accept: :json,
|
||||
content_type: :json,
|
||||
user_agent: Vagrant::Util::Downloader::USER_AGENT,
|
||||
},
|
||||
)
|
||||
|
||||
JSON.load(response.to_s)
|
||||
@env.ui.success("2FA code sent to #{obfuscated_destination}.")
|
||||
end
|
||||
end
|
||||
|
||||
@ -138,12 +91,16 @@ module VagrantPlugins
|
||||
#
|
||||
# @param [String] token
|
||||
def store_token(token)
|
||||
Vagrant::Util::CredentialScrubber.sensitive(token)
|
||||
@logger.info("Storing token in #{token_path}")
|
||||
|
||||
token_path.open("w") do |f|
|
||||
f.write(token)
|
||||
end
|
||||
|
||||
# Reset after we store the token since this is now _our_ token
|
||||
@client = VagrantCloud::Client.new(access_token: token)
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
@ -167,17 +124,18 @@ EOH
|
||||
|
||||
if present?(ENV["VAGRANT_CLOUD_TOKEN"])
|
||||
@logger.debug("Using authentication token from environment variable")
|
||||
return ENV["VAGRANT_CLOUD_TOKEN"]
|
||||
end
|
||||
|
||||
if token_path.exist?
|
||||
t = ENV["VAGRANT_CLOUD_TOKEN"]
|
||||
elsif token_path.exist?
|
||||
@logger.debug("Using authentication token from disk at #{token_path}")
|
||||
return token_path.read.strip
|
||||
t = token_path.read.strip
|
||||
elsif present?(ENV["ATLAS_TOKEN"])
|
||||
@logger.warn("ATLAS_TOKEN detected within environment. Using ATLAS_TOKEN in place of VAGRANT_CLOUD_TOKEN.")
|
||||
t = ENV["ATLAS_TOKEN"]
|
||||
end
|
||||
|
||||
if present?(ENV["ATLAS_TOKEN"])
|
||||
@logger.warn("ATLAS_TOKEN detected within environment. Using ATLAS_TOKEN in place of VAGRANT_CLOUD_TOKEN.")
|
||||
return ENV["ATLAS_TOKEN"]
|
||||
if !t.nil?
|
||||
Vagrant::Util::CredentialScrubber.sensitive(t)
|
||||
return t
|
||||
end
|
||||
|
||||
@logger.debug("No authentication token in environment or #{token_path}")
|
||||
@ -189,22 +147,22 @@ EOH
|
||||
|
||||
def with_error_handling(&block)
|
||||
yield
|
||||
rescue RestClient::Unauthorized
|
||||
rescue Excon::Error::Unauthorized
|
||||
@logger.debug("Unauthorized!")
|
||||
raise Errors::Unauthorized
|
||||
rescue RestClient::BadRequest => e
|
||||
rescue Excon::Error::BadRequest => e
|
||||
@logger.debug("Bad request:")
|
||||
@logger.debug(e.message)
|
||||
@logger.debug(e.backtrace.join("\n"))
|
||||
parsed_response = JSON.parse(e.response)
|
||||
parsed_response = JSON.parse(e.response.body)
|
||||
errors = parsed_response["errors"].join("\n")
|
||||
raise Errors::ServerError, errors: errors
|
||||
rescue RestClient::NotAcceptable => e
|
||||
rescue Excon::Error::NotAcceptable => e
|
||||
@logger.debug("Got unacceptable response:")
|
||||
@logger.debug(e.message)
|
||||
@logger.debug(e.backtrace.join("\n"))
|
||||
|
||||
parsed_response = JSON.parse(e.response)
|
||||
parsed_response = JSON.parse(e.response.body)
|
||||
|
||||
if two_factor = parsed_response['two_factor']
|
||||
store_two_factor_information two_factor
|
||||
|
||||
@ -4,6 +4,8 @@ module VagrantPlugins
|
||||
module CloudCommand
|
||||
module Command
|
||||
class List < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -27,9 +29,6 @@ module VagrantPlugins
|
||||
o.on("-s", "--sort-by", "Column to sort list (created, downloads, updated)") do |s|
|
||||
options[:check] = s
|
||||
end
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |t|
|
||||
options[:username] = u
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
@ -40,7 +39,7 @@ module VagrantPlugins
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
@client = client_login(@env)
|
||||
|
||||
# TODO: This endpoint is not implemented yet
|
||||
|
||||
|
||||
@ -13,14 +13,8 @@ en:
|
||||
|
||||
Press ctrl-c to cancel...
|
||||
publish:
|
||||
update_continue: |-
|
||||
%{obj} already exists, updating instead...
|
||||
box_create:
|
||||
Creating a box entry...
|
||||
version_create:
|
||||
Creating a version entry...
|
||||
provider_create:
|
||||
Creating a provider entry...
|
||||
box_save:
|
||||
Saving box information...
|
||||
upload_provider:
|
||||
Uploading provider with file %{file}
|
||||
release:
|
||||
@ -45,7 +39,7 @@ en:
|
||||
version_desc: |-
|
||||
Version Description: %{version_description}
|
||||
continue: |-
|
||||
Do you wish to continue? [y/N]
|
||||
Do you wish to continue? [y/N]
|
||||
box:
|
||||
show_filter_empty: |-
|
||||
No version matched %{version} for %{org}/%{box_name}
|
||||
@ -57,6 +51,8 @@ en:
|
||||
This will completely remove %{box} from Vagrant Cloud. This cannot be undone.
|
||||
update_success: |-
|
||||
Updated box %{org}/%{box_name}
|
||||
not_found: |-
|
||||
Failed to locate requested box: %{org}/%{box_name}
|
||||
search:
|
||||
no_results: |-
|
||||
No results found for `%{query}`
|
||||
@ -77,6 +73,8 @@ en:
|
||||
Deleted provider %{provider} on %{org}/%{box_name} for version %{version}
|
||||
update_success: |-
|
||||
Updated provider %{provider} on %{org}/%{box_name} for version %{version}
|
||||
not_found: |-
|
||||
Failed to locate %{provider_name} provider for %{org}/%{box_name} on version %{version}
|
||||
version:
|
||||
create_success: |-
|
||||
Created version %{version} on %{org}/%{box_name} for version %{version}
|
||||
@ -94,6 +92,8 @@ en:
|
||||
This will release version %{version} from %{box} to Vagrant Cloud and be available to download.
|
||||
delete_warn: |-
|
||||
This will completely remove version %{version} from %{box} from Vagrant Cloud. This cannot be undone.
|
||||
not_found: |-
|
||||
Failed to locate version %{version} for %{org}/%{box_name}
|
||||
errors:
|
||||
search:
|
||||
fail: |-
|
||||
|
||||
@ -12,6 +12,11 @@ module VagrantPlugins
|
||||
DESC
|
||||
|
||||
command(:cloud) do
|
||||
# Set this to match Vagant logging level so we get
|
||||
# desired request/response information within the
|
||||
# logger output
|
||||
ENV["VAGRANT_CLOUD_LOG"] = Vagrant.log_level
|
||||
|
||||
require_relative "root"
|
||||
init!
|
||||
Command::Root
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module ProviderCommand
|
||||
module Command
|
||||
class Create < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -16,9 +18,6 @@ module VagrantPlugins
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
end
|
||||
o.on("-c", "--checksum CHECKSUM_VALUE", String, "Checksum of the box for this provider. --checksum-type option is required.") do |c|
|
||||
options[:checksum] = c
|
||||
end
|
||||
@ -30,48 +29,59 @@ module VagrantPlugins
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 4
|
||||
if argv.count < 3 || argv.count > 4
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
@client = client_login(@env)
|
||||
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
provider_name = argv[1]
|
||||
version = argv[2]
|
||||
url = argv[3]
|
||||
|
||||
upload_provider(org, box_name, provider_name, version, url, @client.token, options)
|
||||
create_provider(org, box_name, version, provider_name, url, @client.token, options)
|
||||
end
|
||||
|
||||
def upload_provider(org, box_name, provider_name, version, url, access_token, options)
|
||||
# Create a provider for the box version
|
||||
#
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box Box name
|
||||
# @param [String] version Box version
|
||||
# @param [String] provider Provider name
|
||||
# @param [String] url Provider asset URL
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options
|
||||
# @option options [String] :checksum Checksum of the box asset
|
||||
# @option options [String] :checksum_type Type of the checksum
|
||||
# @return [Integer]
|
||||
def create_provider(org, box, version, provider, url, access_token, options={})
|
||||
if !url
|
||||
@env.ui.warn(I18n.t("cloud_command.upload.no_url"))
|
||||
end
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_version(account: account, org: org, box: box, version: version) do |version|
|
||||
provider = version.add_provider(provider)
|
||||
provider.checksum = options[:checksum] if options.key?(:checksum)
|
||||
provider.checksum_type = options[:checksum_type] if options.key?(:checksum_type)
|
||||
provider.url = url if url
|
||||
|
||||
org = options[:username] if options[:username]
|
||||
provider.save
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
cloud_version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
||||
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, url, org, box_name,
|
||||
access_token, nil, options[:checksum], options[:checksum_type])
|
||||
|
||||
begin
|
||||
success = provider.create_provider
|
||||
@env.ui.success(I18n.t("cloud_command.provider.create_success", provider: provider_name, org: org, box_name: box_name, version: version))
|
||||
success = success.compact
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.provider.create_fail", provider: provider_name, org: org, box_name: box_name, version: version))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
@env.ui.success(I18n.t("cloud_command.provider.create_success",
|
||||
provider: provider.name, org: org, box_name: box, version: version.version))
|
||||
format_box_results(provider, @env)
|
||||
0
|
||||
end
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.provider.create_fail",
|
||||
provider: provider, org: org, box_name: box, version: version))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module ProviderCommand
|
||||
module Command
|
||||
class Delete < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -15,53 +17,61 @@ module VagrantPlugins
|
||||
o.separator ""
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
o.on("-f", "--[no-]force", "Force deletion of box version provider without confirmation") do |f|
|
||||
options[:force] = f
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 3
|
||||
if argv.count != 3
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
provider_name = argv[1]
|
||||
version = argv[2]
|
||||
|
||||
@env.ui.warn(I18n.t("cloud_command.provider.delete_warn", provider: provider_name, version:version, box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
@env.ui.warn(I18n.t("cloud_command.provider.delete_warn",
|
||||
provider: provider_name, version:version, box: argv.first))
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
if !options[:force]
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
end
|
||||
|
||||
delete_provider(org, box_name, provider_name, version, @client.token, options)
|
||||
@client = client_login(@env)
|
||||
|
||||
delete_provider(org, box_name, version, provider_name, @client.token, options)
|
||||
end
|
||||
|
||||
def delete_provider(org, box_name, provider_name, version, access_token, options)
|
||||
org = options[:username] if options[:username]
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
cloud_version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
||||
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, nil, nil, nil, access_token)
|
||||
|
||||
begin
|
||||
success = provider.delete
|
||||
@env.ui.error(I18n.t("cloud_command.provider.delete_success", provider: provider_name, org: org, box_name: box_name, version: version))
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.provider.delete_fail", provider: provider_name, org: org, box_name: box_name, version: version))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
# Delete a provider for the box version
|
||||
#
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box Box name
|
||||
# @param [String] version Box version
|
||||
# @param [String] provider Provider name
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options Currently unused
|
||||
# @return [Integer]
|
||||
def delete_provider(org, box, version, provider, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_provider(account: account, org: org, box: box, version: version, provider: provider) do |p|
|
||||
p.delete
|
||||
@env.ui.error(I18n.t("cloud_command.provider.delete_success",
|
||||
provider: provider, org: org, box_name: box, version: version))
|
||||
0
|
||||
end
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.provider.delete_fail",
|
||||
provider: provider, org: org, box_name: box, version: version))
|
||||
@env.ui.error(e)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,20 +5,19 @@ module VagrantPlugins
|
||||
module ProviderCommand
|
||||
module Command
|
||||
class Update < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant cloud provider update [options] organization/box-name provider-name version url"
|
||||
o.banner = "Usage: vagrant cloud provider update [options] organization/box-name provider-name version [url]"
|
||||
o.separator ""
|
||||
o.separator "Updates a provider entry on Vagrant Cloud"
|
||||
o.separator ""
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
end
|
||||
o.on("-c", "--checksum CHECKSUM_VALUE", String, "Checksum of the box for this provider. --checksum-type option is required.") do |c|
|
||||
options[:checksum] = c
|
||||
end
|
||||
@ -30,48 +29,58 @@ module VagrantPlugins
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 4
|
||||
if argv.count < 3 || argv.count > 4
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
@client = client_login(@env)
|
||||
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
provider_name = argv[1]
|
||||
version = argv[2]
|
||||
url = argv[3]
|
||||
|
||||
update_provider(org, box_name, provider_name, version, url, @client.token, options)
|
||||
update_provider(org, box_name, version, provider_name, url, @client.token, options)
|
||||
end
|
||||
|
||||
def update_provider(org, box_name, provider_name, version, url, access_token, options)
|
||||
# Update a provider for the box version
|
||||
#
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box Box name
|
||||
# @param [String] version Box version
|
||||
# @param [String] provider Provider name
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options
|
||||
# @option options [String] :checksum Checksum of the box asset
|
||||
# @option options [String] :checksum_type Type of the checksum
|
||||
# @return [Integer]
|
||||
def update_provider(org, box, version, provider, url, access_token, options)
|
||||
if !url
|
||||
@env.ui.warn(I18n.t("cloud_command.upload.no_url"))
|
||||
end
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
|
||||
org = options[:username] if options[:username]
|
||||
with_provider(account: account, org: org, box: box, version: version, provider: provider) do |p|
|
||||
p.checksum = options[:checksum] if options.key?(:checksum)
|
||||
p.checksum_type = options[:checksum_type] if options.key?(:checksum_type)
|
||||
p.url = url if !url.nil?
|
||||
p.save
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
cloud_version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
||||
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, url, org, box_name,
|
||||
access_token, nil, options[:checksum], options[:checksum_type])
|
||||
@env.ui.success(I18n.t("cloud_command.provider.update_success",
|
||||
provider: provider, org: org, box_name: box, version: version))
|
||||
|
||||
begin
|
||||
success = provider.update
|
||||
@env.ui.success(I18n.t("cloud_command.provider.update_success", provider:provider_name, org: org, box_name: box_name, version: version))
|
||||
success = success.delete_if{|_, v|v.nil?}
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.provider.update_fail", provider:provider_name, org: org, box_name: box_name, version: version))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
format_box_results(p, @env)
|
||||
0
|
||||
end
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.provider.update_fail",
|
||||
provider: provider, org: org, box_name: box, version: version))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -6,8 +6,10 @@ module VagrantPlugins
|
||||
module ProviderCommand
|
||||
module Command
|
||||
class Upload < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
options = {direct: true}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant cloud provider upload [options] organization/box-name provider-name version box-file"
|
||||
@ -16,57 +18,65 @@ module VagrantPlugins
|
||||
o.separator ""
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
o.on("-D", "--[no-]direct", "Upload asset directly to backend storage") do |d|
|
||||
options[:direct] = d
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 4
|
||||
if argv.count != 4
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
@client = client_login(@env)
|
||||
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
provider_name = argv[1]
|
||||
version = argv[2]
|
||||
file = argv[3] # path expand
|
||||
file = File.expand_path(argv[3])
|
||||
|
||||
upload_provider(org, box_name, provider_name, version, file, @client.token, options)
|
||||
upload_provider(org, box_name, version, provider_name, file, @client.token, options)
|
||||
end
|
||||
|
||||
def upload_provider(org, box_name, provider_name, version, file, access_token, options)
|
||||
org = options[:username] if options[:username]
|
||||
# Upload an asset for a box version provider
|
||||
#
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box Box name
|
||||
# @param [String] version Box version
|
||||
# @param [String] provider Provider name
|
||||
# @param [String] file Path to asset
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options
|
||||
# @option options [Boolean] :direct Upload directly to backend storage
|
||||
# @return [Integer]
|
||||
def upload_provider(org, box, version, provider, file, access_token, options)
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
cloud_version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
||||
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, nil, org, box_name, access_token)
|
||||
|
||||
ul = Vagrant::Util::Uploader.new(provider.upload_url, file, ui: @env.ui)
|
||||
ui = Vagrant::UI::Prefixed.new(@env.ui, "cloud")
|
||||
|
||||
begin
|
||||
ui.output(I18n.t("cloud_command.provider.upload", org: org, box_name: box_name, version: version, provider: provider_name))
|
||||
ui.info("Upload File: #{file}")
|
||||
|
||||
ul.upload!
|
||||
|
||||
ui.success("Successfully uploaded box '#{org}/#{box_name}' (v#{version}) for '#{provider_name}'")
|
||||
return 0
|
||||
rescue Vagrant::Errors::UploaderError, VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.provider.upload_fail", provider: provider_name, org: org, box_name: box_name, version: version))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
with_provider(account: account, org: org, box: box, version: version, provider: provider) do |p|
|
||||
p.upload(direct: options[:direct]) do |upload_url|
|
||||
m = options[:direct] ? :put : :put
|
||||
uploader = Vagrant::Util::Uploader.new(upload_url, file, ui: @env.ui, method: m)
|
||||
ui = Vagrant::UI::Prefixed.new(@env.ui, "cloud")
|
||||
ui.output(I18n.t("cloud_command.provider.upload",
|
||||
org: org, box_name: box, version: version, provider: provider))
|
||||
ui.info("Upload File: #{file}")
|
||||
uploader.upload!
|
||||
ui.success(I18n.t("cloud_command.provider.upload_success",
|
||||
org: org, box_name: box, version: version, provider: provider))
|
||||
end
|
||||
0
|
||||
end
|
||||
rescue Vagrant::Errors::UploaderError, VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.provider.upload_fail",
|
||||
provider: provider, org: org, box_name: box, version: version))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,11 +5,13 @@ module VagrantPlugins
|
||||
module CloudCommand
|
||||
module Command
|
||||
class Publish < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
options = {direct_upload: true}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant cloud publish [options] organization/box-name version provider-name provider-file"
|
||||
o.banner = "Usage: vagrant cloud publish [options] organization/box-name version provider-name [provider-file]"
|
||||
o.separator ""
|
||||
o.separator "Create and release a new Vagrant Box on Vagrant Cloud"
|
||||
o.separator ""
|
||||
@ -19,7 +21,7 @@ module VagrantPlugins
|
||||
o.on("--box-version VERSION", String, "Version of box to create") do |v|
|
||||
options[:box_version] = v
|
||||
end
|
||||
o.on("--url URL", String, "Remote URL to download this provider") do |u|
|
||||
o.on("--url URL", String, "Remote URL to download this provider (cannot be used with provider-file)") do |u|
|
||||
options[:url] = u
|
||||
end
|
||||
o.on("-d", "--description DESCRIPTION", String, "Full description of box") do |d|
|
||||
@ -28,154 +30,229 @@ module VagrantPlugins
|
||||
o.on("--version-description DESCRIPTION", String, "Description of the version to create") do |v|
|
||||
options[:version_description] = v
|
||||
end
|
||||
o.on("-f", "--force", "Disables confirmation to create or update box") do |f|
|
||||
o.on("-f", "--[no-]force", "Disables confirmation to create or update box") do |f|
|
||||
options[:force] = f
|
||||
end
|
||||
o.on("-p", "--private", "Makes box private") do |p|
|
||||
o.on("-p", "--[no-]private", "Makes box private") do |p|
|
||||
options[:private] = p
|
||||
end
|
||||
o.on("-r", "--release", "Releases box") do |p|
|
||||
o.on("-r", "--[no-]release", "Releases box") do |p|
|
||||
options[:release] = p
|
||||
end
|
||||
o.on("-s", "--short-description DESCRIPTION", String, "Short description of the box") do |s|
|
||||
options[:short_description] = s
|
||||
end
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
end
|
||||
o.on("-c", "--checksum CHECKSUM_VALUE", String, "Checksum of the box for this provider. --checksum-type option is required.") do |c|
|
||||
options[:checksum] = c
|
||||
end
|
||||
o.on("-C", "--checksum-type TYPE", String, "Type of checksum used (md5, sha1, sha256, sha384, sha512). --checksum option is required.") do |c|
|
||||
options[:checksum_type] = c
|
||||
end
|
||||
o.on("--[no-]direct-upload", "Upload asset directly to backend storage") do |d|
|
||||
options[:direct_upload] = d
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
|
||||
if argv.empty? || argv.length > 4 || argv.length < 3 || (argv.length == 3 && !options[:url])
|
||||
if argv.length < 3 || # missing required arguments
|
||||
argv.length > 4 || # too many arguments
|
||||
(argv.length < 4 && !options.key?(:url)) || # file argument required if url is not provided
|
||||
(argv.length > 3 && options.key?(:url)) # cannot provider url and file argument
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
version = argv[1]
|
||||
provider_name = argv[2]
|
||||
box_file = argv[3]
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
_, version, provider_name, box_file = argv
|
||||
|
||||
if !options[:url] && !File.file?(box_file)
|
||||
if box_file && !File.file?(box_file)
|
||||
raise Vagrant::Errors::BoxFileNotExist,
|
||||
file: box_file
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
@client = client_login(@env)
|
||||
params = options.slice(:private, :release, :url, :short_description,
|
||||
:description, :version_description, :checksum, :checksum_type)
|
||||
|
||||
publish_box(org, box_name, version, provider_name, box_file, options, @client.token)
|
||||
end
|
||||
|
||||
def publish_box(org, box_name, version, provider_name, box_file, options, access_token)
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
|
||||
@env.ui.warn(I18n.t("cloud_command.publish.confirm.warn"))
|
||||
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.box", org: org,
|
||||
box_name: box_name, version: version, provider_name: provider_name))
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.private")) if options[:private]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.release")) if options[:release]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.box_url",
|
||||
url: options[:url])) if options[:url]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.box_description",
|
||||
description: options[:description])) if options[:description]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.box_short_desc",
|
||||
short_description: options[:short_description])) if options[:short_description]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.version_desc",
|
||||
version_description: options[:version_description])) if options[:version_description]
|
||||
# Display output to user describing action to be taken
|
||||
display_preamble(org, box_name, version, provider_name, params)
|
||||
|
||||
if !options[:force]
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
end
|
||||
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, options[:short_description], options[:description], access_token)
|
||||
cloud_version = VagrantCloud::Version.new(box, version, nil, options[:version_description], access_token)
|
||||
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, options[:url], org, box_name,
|
||||
access_token, nil, options[:checksum], options[:checksum_type])
|
||||
# Load up all the models we'll need to publish the asset
|
||||
box = load_box(org, box_name, @client.token)
|
||||
box_v = load_box_version(box, version)
|
||||
box_p = load_version_provider(box_v, provider_name)
|
||||
|
||||
ui = Vagrant::UI::Prefixed.new(@env.ui, "cloud")
|
||||
# Update all the data
|
||||
set_box_info(box, params.slice(:private, :short_description, :description))
|
||||
set_version_info(box_v, params.slice(:version_description))
|
||||
set_provider_info(box_p, params.slice(:checksum, :checksum_type, :url))
|
||||
|
||||
begin
|
||||
ui.info(I18n.t("cloud_command.publish.box_create"))
|
||||
box.create
|
||||
rescue VagrantCloud::ClientError => e
|
||||
if e.error_code == 422
|
||||
ui.warn(I18n.t("cloud_command.publish.update_continue", obj: "Box"))
|
||||
box.update(options)
|
||||
else
|
||||
@env.ui.error(I18n.t("cloud_command.errors.publish.fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
end
|
||||
# Save any updated state
|
||||
@env.ui.warn(I18n.t("cloud_command.publish.box_save"))
|
||||
box.save
|
||||
|
||||
# If we have a box file asset, upload it
|
||||
if box_file
|
||||
upload_box_file(box_p, box_file, options.slice(:direct_upload))
|
||||
end
|
||||
|
||||
begin
|
||||
ui.info(I18n.t("cloud_command.publish.version_create"))
|
||||
cloud_version.create_version
|
||||
rescue VagrantCloud::ClientError => e
|
||||
if e.error_code == 422
|
||||
ui.warn(I18n.t("cloud_command.publish.update_continue", obj: "Version"))
|
||||
cloud_version.update
|
||||
else
|
||||
@env.ui.error(I18n.t("cloud_command.errors.publish.fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
end
|
||||
rescue VagrantCloud::InvalidVersion => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.publish.fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
# If configured to release the box, release it
|
||||
if options[:release] && !box_v.released?
|
||||
release_version(box_v)
|
||||
end
|
||||
|
||||
begin
|
||||
ui.info(I18n.t("cloud_command.publish.provider_create"))
|
||||
provider.create_provider
|
||||
rescue VagrantCloud::ClientError => e
|
||||
if e.error_code == 422
|
||||
ui.warn(I18n.t("cloud_command.publish.update_continue", obj: "Provider"))
|
||||
provider.update
|
||||
else
|
||||
@env.ui.error(I18n.t("cloud_command.errors.publish.fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
end
|
||||
end
|
||||
# And we're done!
|
||||
@env.ui.success(I18n.t("cloud_command.publish.complete", org: org, box_name: box_name))
|
||||
format_box_results(box, @env)
|
||||
0
|
||||
rescue VagrantCloud::Error => err
|
||||
@env.ui.error(I18n.t("cloud_command.errors.publish.fail", org: org, box_name: box_name))
|
||||
@env.ui.error(err.message)
|
||||
1
|
||||
end
|
||||
|
||||
begin
|
||||
if !options[:url]
|
||||
box_file = File.absolute_path(box_file)
|
||||
ui.info(I18n.t("cloud_command.publish.upload_provider", file: box_file))
|
||||
ul = Vagrant::Util::Uploader.new(provider.upload_url, box_file, ui: @env.ui)
|
||||
ul.upload!
|
||||
end
|
||||
if options[:release]
|
||||
ui.info(I18n.t("cloud_command.publish.release"))
|
||||
cloud_version.release
|
||||
end
|
||||
@env.ui.success(I18n.t("cloud_command.publish.complete", org: org, box_name: box_name))
|
||||
success = box.read(org, box_name)
|
||||
success = success.delete_if{|_, v|v.nil?}
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue Vagrant::Errors::UploaderError, VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.publish.fail", org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
# Upload the file for the given box provider
|
||||
#
|
||||
# @param [VagrantCloud::Box::Provider] provider Vagrant Cloud box version provider
|
||||
# @param [String] box_file Path to local asset for upload
|
||||
# @param [Hash] options
|
||||
# @option options [Boolean] :direct_upload Upload directly to backend storage
|
||||
# @return [nil]
|
||||
def upload_box_file(provider, box_file, options={})
|
||||
box_file = File.absolute_path(box_file)
|
||||
@env.ui.info(I18n.t("cloud_command.publish.upload_provider", file: box_file))
|
||||
provider.upload(direct: options[:direct_upload]) do |upload_url|
|
||||
Vagrant::Util::Uploader.new(upload_url, box_file, ui: @env.ui, method: :put).upload!
|
||||
end
|
||||
return 1
|
||||
nil
|
||||
end
|
||||
|
||||
# Release the box version
|
||||
#
|
||||
# @param [VagrantCloud::Box::Version] version Vagrant Cloud box version
|
||||
# @return [nil]
|
||||
def release_version(version)
|
||||
@env.ui.info(I18n.t("cloud_command.publish.release"))
|
||||
version.release
|
||||
nil
|
||||
end
|
||||
|
||||
# Set any box related attributes that were provided
|
||||
#
|
||||
# @param [VagrantCloud::Box] box Vagrant Cloud box
|
||||
# @param [Hash] options
|
||||
# @option options [Boolean] :private Box access is private
|
||||
# @option options [String] :short_description Short description of box
|
||||
# @option options [String] :description Full description of box
|
||||
# @return [VagrantCloud::Box]
|
||||
def set_box_info(box, options={})
|
||||
box.private = options[:private] if options.key?(:private)
|
||||
box.short_description = options[:short_description] if options.key?(:short_description)
|
||||
box.description = options[:description] if options.key?(:description)
|
||||
box
|
||||
end
|
||||
|
||||
# Set any version related attributes that were provided
|
||||
#
|
||||
# @param [VagrantCloud::Box::Version] version Vagrant Cloud box version
|
||||
# @param [Hash] options
|
||||
# @option options [String] :version_description Description for this version
|
||||
# @return [VagrantCloud::Box::Version]
|
||||
def set_version_info(version, options={})
|
||||
version.description = options[:version_description] if options.key?(:version_description)
|
||||
version
|
||||
end
|
||||
|
||||
# Set any provider related attributes that were provided
|
||||
#
|
||||
# @param [VagrantCloud::Box::Provider] provider Vagrant Cloud box version provider
|
||||
# @param [Hash] options
|
||||
# @option options [String] :url Remote URL for self hosted
|
||||
# @option options [String] :checksum_type Type of checksum value provided
|
||||
# @option options [String] :checksum Checksum of the box asset
|
||||
# @return [VagrantCloud::Box::Provider]
|
||||
def set_provider_info(provider, options={})
|
||||
provider.url = options[:url] if options.key?(:url)
|
||||
provider.checksum_type = options[:checksum_type] if options.key?(:checksum_type)
|
||||
provider.checksum = options[:checksum] if options.key?(:checksum)
|
||||
provider
|
||||
end
|
||||
|
||||
# Load the requested version provider
|
||||
#
|
||||
# @param [VagrantCloud::Box::Version] version The version of the Vagrant Cloud box
|
||||
# @param [String] provider_name Name of the provider
|
||||
# @return [VagrantCloud::Box::Provider]
|
||||
def load_version_provider(version, provider_name)
|
||||
provider = version.providers.detect { |pv| pv.name == provider_name }
|
||||
return provider if provider
|
||||
version.add_provider(provider_name)
|
||||
end
|
||||
|
||||
# Load the requested box version
|
||||
#
|
||||
# @param [VagrantCloud::Box] box The Vagrant Cloud box
|
||||
# @param [String] version Version of the box
|
||||
# @return [VagrantCloud::Box::Version]
|
||||
def load_box_version(box, version)
|
||||
v = box.versions.detect { |v| v.version == version }
|
||||
return v if v
|
||||
box.add_version(version)
|
||||
end
|
||||
|
||||
# Load the requested box
|
||||
#
|
||||
# @param [String] org Organization name for box
|
||||
# @param [String] box_name Name of the box
|
||||
# @param [String] access_token User access token
|
||||
# @return [VagrantCloud::Box]
|
||||
def load_box(org, box_name, access_token)
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
box = account.organization(name: org).boxes.detect { |b| b.name == box_name }
|
||||
return box if box
|
||||
account.organization(name: org).add_box(box_name)
|
||||
end
|
||||
|
||||
# Display publishing information to user before starting process
|
||||
#
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box_name Name of the box to publish
|
||||
# @param [String] version Version of the box to publish
|
||||
# @param [String] provider_name Name of the provider being published
|
||||
# @param [Hash] options
|
||||
# @option options [Boolean] :private Box is private
|
||||
# @option options [Boolean] :release Box should be released
|
||||
# @option options [String] :url Remote URL for self-hosted boxes
|
||||
# @option options [String] :description Description of the box
|
||||
# @option options [String] :short_description Short description of the box
|
||||
# @option options [String] :version_description Description of the box version
|
||||
# @return [nil]
|
||||
def display_preamble(org, box_name, version, provider_name, options={})
|
||||
@env.ui.warn(I18n.t("cloud_command.publish.confirm.warn"))
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.box", org: org,
|
||||
box_name: box_name, version: version, provider_name: provider_name))
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.private")) if options[:private]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.release")) if options[:release]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.box_url",
|
||||
url: options[:url])) if options[:url]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.box_description",
|
||||
description: options[:description])) if options[:description]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.box_short_desc",
|
||||
short_description: options[:short_description])) if options[:short_description]
|
||||
@env.ui.info(I18n.t("cloud_command.publish.confirm.version_desc",
|
||||
version_description: options[:version_description])) if options[:version_description]
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -4,8 +4,10 @@ module VagrantPlugins
|
||||
module CloudCommand
|
||||
module Command
|
||||
class Search < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
options = {quiet: true}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant cloud search [options] query"
|
||||
@ -37,45 +39,56 @@ module VagrantPlugins
|
||||
o.on("--sort-by SORT", "Field to sort results on (created, downloads, updated) Default: downloads") do |s|
|
||||
options[:sort] = s
|
||||
end
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address to login with") do |u|
|
||||
options[:username] = u
|
||||
o.on("--[no-]auth", "Authenticate with Vagrant Cloud if required before searching") do |l|
|
||||
options[:quiet] = !l
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.length > 1
|
||||
if argv.length != 1
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
@client = client_login(@env, options.slice(:quiet))
|
||||
query = argv.first
|
||||
|
||||
options[:limit] = 25 if !(options[:limit].to_i < 1) && !options[:limit]
|
||||
|
||||
search(query, options, @client.token)
|
||||
search(query, @client&.token, options)
|
||||
end
|
||||
|
||||
def search(query, options, access_token)
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
search = VagrantCloud::Search.new(access_token, server_url)
|
||||
# Perform requested search and display results to user
|
||||
#
|
||||
# @param [String] query Search query string
|
||||
# @param [Hash] options
|
||||
# @option options [String] :provider Filter by provider
|
||||
# @option options [String] :sort Field to sort results
|
||||
# @option options [Integer] :limit Number of results to display
|
||||
# @option options [Integer] :page Page of results to display
|
||||
# @param [String] access_token User access token
|
||||
# @return [Integer]
|
||||
def search(query, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
params = {query: query}.merge(options.slice(:provider, :sort, :order, :limit, :page))
|
||||
result = account.searcher.search(**params)
|
||||
|
||||
begin
|
||||
search_results = search.search(query, options[:provider], options[:sort], options[:order], options[:limit], options[:page])
|
||||
if !search_results["boxes"].empty?
|
||||
VagrantPlugins::CloudCommand::Util.format_search_results(search_results["boxes"], options[:short], options[:json], @env)
|
||||
else
|
||||
@env.ui.warn(I18n.t("cloud_command.search.no_results", query: query))
|
||||
end
|
||||
if result.boxes.empty?
|
||||
@env.ui.warn(I18n.t("cloud_command.search.no_results", query: query))
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.search.fail"))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
end
|
||||
return 1
|
||||
|
||||
format_search_results(result.boxes, options[:short], options[:json], @env)
|
||||
0
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.search.fail"))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,205 +1,309 @@
|
||||
module VagrantPlugins
|
||||
module CloudCommand
|
||||
class Util
|
||||
class << self
|
||||
# @param [String] username - Vagrant Cloud username
|
||||
# @param [String] access_token - Vagrant Cloud Token used to authenticate
|
||||
# @param [String] vagrant_cloud_server - Vagrant Cloud server to make API request
|
||||
# @return [VagrantCloud::Account]
|
||||
def account(username, access_token, vagrant_cloud_server)
|
||||
if !defined?(@_account)
|
||||
@_account = VagrantCloud::Account.new(username, access_token, vagrant_cloud_server)
|
||||
end
|
||||
@_account
|
||||
module Util
|
||||
# @return [String] Vagrant Cloud server URL
|
||||
def api_server_url
|
||||
if Vagrant.server_url == Vagrant::DEFAULT_SERVER_URL
|
||||
return "#{Vagrant.server_url}/api/v1"
|
||||
else
|
||||
return Vagrant.server_url
|
||||
end
|
||||
end
|
||||
|
||||
# @param [Vagrant::Environment] env
|
||||
# @param [Hash] options
|
||||
# @option options [String] :login Username or email
|
||||
# @option options [String] :description Description of login usage for token
|
||||
# @option options [String] :code 2FA code for login
|
||||
# @option options [Boolean] :quiet Do not prompt user
|
||||
# @returns [VagrantPlugins::CloudCommand::Client, nil]
|
||||
def client_login(env, options={})
|
||||
return @_client if defined?(@_client)
|
||||
@_client = Client.new(env)
|
||||
return @_client if @_client.logged_in?
|
||||
|
||||
# If directed to be quiet, do not continue and
|
||||
# just return nil
|
||||
return if options[:quiet]
|
||||
|
||||
# Let the user know what is going on.
|
||||
env.ui.output(I18n.t("cloud_command.command_header") + "\n")
|
||||
|
||||
# If it is a private cloud installation, show that
|
||||
if Vagrant.server_url != Vagrant::DEFAULT_SERVER_URL
|
||||
env.ui.output("Vagrant Cloud URL: #{Vagrant.server_url}")
|
||||
end
|
||||
|
||||
def api_server_url
|
||||
if Vagrant.server_url == Vagrant::DEFAULT_SERVER_URL
|
||||
return "#{Vagrant.server_url}/api/v1"
|
||||
options = {} if !options
|
||||
# Ask for the username
|
||||
if options[:login]
|
||||
@_client.username_or_email = options[:login]
|
||||
env.ui.output("Vagrant Cloud username or email: #{@_client.username_or_email}")
|
||||
else
|
||||
@_client.username_or_email = env.ui.ask("Vagrant Cloud username or email: ")
|
||||
end
|
||||
|
||||
@_client.password = env.ui.ask("Password (will be hidden): ", echo: false)
|
||||
|
||||
description_default = "Vagrant login from #{Socket.gethostname}"
|
||||
if !options[:description]
|
||||
description = env.ui.ask("Token description (Defaults to #{description_default.inspect}): ")
|
||||
else
|
||||
description = options[:description]
|
||||
env.ui.output("Token description: #{description}")
|
||||
end
|
||||
|
||||
description = description_default if description.empty?
|
||||
|
||||
code = nil
|
||||
|
||||
begin
|
||||
token = @_client.login(description: description, code: code)
|
||||
rescue Errors::TwoFactorRequired
|
||||
until code
|
||||
code = env.ui.ask("2FA code: ")
|
||||
|
||||
if @_client.two_factor_delivery_methods.include?(code.downcase)
|
||||
delivery_method, code = code, nil
|
||||
@_client.request_code delivery_method
|
||||
end
|
||||
end
|
||||
|
||||
retry
|
||||
end
|
||||
|
||||
@_client.store_token(token)
|
||||
Vagrant::Util::CredentialScrubber.sensitive(token)
|
||||
env.ui.success(I18n.t("cloud_command.logged_in"))
|
||||
@_client
|
||||
end
|
||||
|
||||
# Print search results from Vagrant Cloud to the console
|
||||
#
|
||||
# @param [Array<VagrantCloud::Box>] search_results Box search results from Vagrant Cloud
|
||||
# @param [Boolean] short Print short summary
|
||||
# @param [Boolean] json Print output in JSON format
|
||||
# @param [Vagrant::Environment] env Current Vagrant environment
|
||||
# @return [nil]
|
||||
def format_search_results(search_results, short, json, env)
|
||||
result = search_results.map do |b|
|
||||
{
|
||||
name: b.tag,
|
||||
version: b.current_version.version,
|
||||
downloads: format_downloads(b.downloads.to_s),
|
||||
providers: b.current_version.providers.map(&:name).join(", ")
|
||||
}
|
||||
end
|
||||
|
||||
if short
|
||||
result.map { |b| env.ui.info(b[:name]) }
|
||||
elsif json
|
||||
env.ui.info(result.to_json)
|
||||
else
|
||||
column_labels = {}
|
||||
columns = result.first.keys
|
||||
columns.each do |c|
|
||||
column_labels[c] = c.to_s.upcase
|
||||
end
|
||||
print_search_table(env, column_labels, result, [:downloads])
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
# Output box details result from Vagrant Cloud
|
||||
#
|
||||
# @param [VagrantCloud::Box, VagrantCloud::Box::Version] box Box or box version to display
|
||||
# @param [Vagrant::Environment] env Current Vagrant environment
|
||||
# @return [nil]
|
||||
def format_box_results(box, env)
|
||||
if box.is_a?(VagrantCloud::Box)
|
||||
info = box_info(box)
|
||||
elsif box.is_a?(VagrantCloud::Box::Provider)
|
||||
info = version_info(box.version)
|
||||
else
|
||||
info = version_info(box)
|
||||
end
|
||||
|
||||
width = info.keys.map(&:size).max
|
||||
info.each do |k, v|
|
||||
whitespace = width - k.size
|
||||
env.ui.info "#{k}: #{"".ljust(whitespace)} #{v}"
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
# Load box and yield
|
||||
#
|
||||
# @param [VagrantCloud::Account] account Vagrant Cloud account
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box Box name
|
||||
# @yieldparam [VagrantCloud::Box] box Requested Vagrant Cloud box
|
||||
# @yieldreturn [Integer]
|
||||
# @return [Integer]
|
||||
def with_box(account:, org:, box:)
|
||||
org = account.organization(name: org)
|
||||
b = org.boxes.detect { |b| b.name == box }
|
||||
if !b
|
||||
@env.ui.error(I18n.t("cloud_command.box.not_found",
|
||||
org: org.username, box_name: box))
|
||||
return 1
|
||||
end
|
||||
yield b
|
||||
end
|
||||
|
||||
# Load box version and yield
|
||||
#
|
||||
# @param [VagrantCloud::Account] account Vagrant Cloud account
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box Box name
|
||||
# @param [String] version Box version
|
||||
# @yieldparam [VagrantCloud::Box::Version] version Requested Vagrant Cloud box version
|
||||
# @yieldreturn [Integer]
|
||||
# @return [Integer]
|
||||
def with_version(account:, org:, box:, version:)
|
||||
with_box(account: account, org: org, box: box) do |b|
|
||||
v = b.versions.detect { |v| v.version == version }
|
||||
if !v
|
||||
@env.ui.error(I18n.t("cloud_command.version.not_found",
|
||||
box_name: box, org: org, version: version))
|
||||
return 1
|
||||
end
|
||||
yield v
|
||||
end
|
||||
end
|
||||
|
||||
# Load box version and yield
|
||||
#
|
||||
# @param [VagrantCloud::Account] account Vagrant Cloud account
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box Box name
|
||||
# @param [String] version Box version
|
||||
# @param [String] provider Box version provider name
|
||||
# @yieldparam [VagrantCloud::Box::Provider] provider Requested Vagrant Cloud box version provider
|
||||
# @yieldreturn [Integer]
|
||||
# @return [Integer]
|
||||
def with_provider(account:, org:, box:, version:, provider:)
|
||||
with_version(account: account, org: org, box: box, version: version) do |v|
|
||||
p = v.providers.detect { |p| p.name == provider }
|
||||
if !p
|
||||
@env.ui.error(I18n.t("cloud_command.provider.not_found",
|
||||
org: org, box_name: box, version: version, provider_name: provider))
|
||||
return 1
|
||||
end
|
||||
yield p
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Extract box information for display
|
||||
#
|
||||
# @param [VagrantCloud::Box] box Box for extracting information
|
||||
# @return [Hash<String,String>]
|
||||
def box_info(box)
|
||||
Hash.new.tap do |i|
|
||||
i["Box"] = box.tag
|
||||
i["Description"] = box.description
|
||||
i["Private"] = box.private ? "yes" : "no"
|
||||
i["Created"] = box.created_at
|
||||
i["Updated"] = box.updated_at
|
||||
if !box.current_version.nil?
|
||||
i["Current Version"] = box.current_version.version
|
||||
else
|
||||
return Vagrant.server_url
|
||||
i["Current Version"] = "N/A"
|
||||
end
|
||||
end
|
||||
|
||||
# @param [Vagrant::Environment] env
|
||||
# @param [Hash] options
|
||||
# @returns [VagrantPlugins::CloudCommand::Client]
|
||||
def client_login(env, options)
|
||||
if !defined?(@_client)
|
||||
@_client = Client.new(env)
|
||||
return @_client if @_client.logged_in?
|
||||
|
||||
# Let the user know what is going on.
|
||||
env.ui.output(I18n.t("cloud_command.command_header") + "\n")
|
||||
|
||||
# If it is a private cloud installation, show that
|
||||
if Vagrant.server_url != Vagrant::DEFAULT_SERVER_URL
|
||||
env.ui.output("Vagrant Cloud URL: #{Vagrant.server_url}")
|
||||
end
|
||||
|
||||
options = {} if !options
|
||||
# Ask for the username
|
||||
if options[:login]
|
||||
@_client.username_or_email = options[:login]
|
||||
env.ui.output("Vagrant Cloud username or email: #{@_client.username_or_email}")
|
||||
else
|
||||
@_client.username_or_email = env.ui.ask("Vagrant Cloud username or email: ")
|
||||
end
|
||||
|
||||
@_client.password = env.ui.ask("Password (will be hidden): ", echo: false)
|
||||
|
||||
description_default = "Vagrant login from #{Socket.gethostname}"
|
||||
if !options[:description]
|
||||
description = env.ui.ask("Token description (Defaults to #{description_default.inspect}): ")
|
||||
else
|
||||
description = options[:description]
|
||||
env.ui.output("Token description: #{description}")
|
||||
end
|
||||
|
||||
description = description_default if description.empty?
|
||||
|
||||
code = nil
|
||||
|
||||
begin
|
||||
token = @_client.login(description: description, code: code)
|
||||
rescue Errors::TwoFactorRequired
|
||||
until code
|
||||
code = env.ui.ask("2FA code: ")
|
||||
|
||||
if @_client.two_factor_delivery_methods.include?(code.downcase)
|
||||
delivery_method, code = code, nil
|
||||
@_client.request_code delivery_method
|
||||
end
|
||||
end
|
||||
|
||||
retry
|
||||
end
|
||||
|
||||
@_client.store_token(token)
|
||||
Vagrant::Util::CredentialScrubber.sensitive(token)
|
||||
env.ui.success(I18n.t("cloud_command.logged_in"))
|
||||
@_client
|
||||
i["Versions"] = box.versions.slice(0, 5).map(&:version).join(", ")
|
||||
if box.versions.size > 5
|
||||
i["Versions"] += " ..."
|
||||
end
|
||||
@_client
|
||||
i["Downloads"] = format_downloads(box.downloads)
|
||||
end
|
||||
end
|
||||
|
||||
# Extract version information for display
|
||||
#
|
||||
# @param [VagrantCloud::Box::Version] version Box version for extracting information
|
||||
# @return [Hash<String,String>]
|
||||
def version_info(version)
|
||||
Hash.new.tap do |i|
|
||||
i["Box"] = version.box.tag
|
||||
i["Version"] = version.version
|
||||
i["Description"] = version.description
|
||||
i["Status"] = version.status
|
||||
i["Providers"] = version.providers.map(&:name).sort.join(", ")
|
||||
i["Created"] = version.created_at
|
||||
i["Updated"] = version.updated_at
|
||||
end
|
||||
end
|
||||
|
||||
# Print table results from search request
|
||||
#
|
||||
# @param [Vagrant::Environment] env Current Vagrant environment
|
||||
# @param [Hash] column_labels A hash of key/value pairs for table labels (i.e. {col1: "COL1"})
|
||||
# @param [Array] results An array of hashes representing search resuls
|
||||
# @param [Array] to_jrust_keys - List of columns keys to right justify (left justify is defualt)
|
||||
# @return [nil]
|
||||
# @note Modified from https://stackoverflow.com/a/28685559
|
||||
def print_search_table(env, column_labels, results, to_rjust_keys)
|
||||
columns = column_labels.each_with_object({}) do |(col,label),h|
|
||||
h[col] = {
|
||||
label: label,
|
||||
width: [results.map { |g| g[col].size }.max, label.size].max
|
||||
}
|
||||
end
|
||||
|
||||
# ===================================================
|
||||
# Modified from https://stackoverflow.com/a/28685559
|
||||
# for printing arrays of hashes in formatted tables
|
||||
# ===================================================
|
||||
write_header(env, columns)
|
||||
write_divider(env, columns)
|
||||
results.each { |h| write_line(env, columns, h, to_rjust_keys) }
|
||||
write_divider(env, columns)
|
||||
end
|
||||
|
||||
# @param [Vagrant::Environment] - env
|
||||
# @param [Hash] - column_labels - A hash of key values for table labels (i.e. {:col1=>"COL1", :col2=>"COL2"})
|
||||
# @param [Array] - results - An array of hashes
|
||||
# @param [Array] - to_jrust_keys - An array of column keys that should be right justified (default is left justified for all columns)
|
||||
def print_search_table(env, column_labels, results, to_rjust_keys)
|
||||
columns = column_labels.each_with_object({}) { |(col,label),h|
|
||||
h[col] = { label: label,
|
||||
width: [results.map { |g| g[col].size }.max, label.size].max
|
||||
}}
|
||||
# Write the header for a table
|
||||
#
|
||||
# @param [Vagrant::Environment] env Current Vagrant environment
|
||||
# @param [Array<Hash>] columns List of columns in Hash format with `:label` and `:width` keys
|
||||
# @return [nil]
|
||||
def write_header(env, columns)
|
||||
env.ui.info "| #{ columns.map { |_,g| g[:label].ljust(g[:width]) }.join(' | ') } |"
|
||||
nil
|
||||
end
|
||||
|
||||
write_header(env, columns)
|
||||
write_divider(env, columns)
|
||||
results.each { |h| write_line(env, columns, h,to_rjust_keys) }
|
||||
write_divider(env, columns)
|
||||
end
|
||||
# Write a row divider for a table
|
||||
#
|
||||
# @param [Vagrant::Environment] env Current Vagrant environment
|
||||
# @param [Array<Hash>] columns List of columns in Hash format with `:label` and `:width` keys
|
||||
# @return [nil]
|
||||
def write_divider(env, columns)
|
||||
env.ui.info "+-#{ columns.map { |_,g| "-"*g[:width] }.join("-+-") }-+"
|
||||
nil
|
||||
end
|
||||
|
||||
def write_header(env, columns)
|
||||
env.ui.info "| #{ columns.map { |_,g| g[:label].ljust(g[:width]) }.join(' | ') } |"
|
||||
end
|
||||
|
||||
def write_divider(env, columns)
|
||||
env.ui.info "+-#{ columns.map { |_,g| "-"*g[:width] }.join("-+-") }-+"
|
||||
end
|
||||
|
||||
def write_line(env, columns,h,to_rjust_keys)
|
||||
str = h.keys.map { |k|
|
||||
if to_rjust_keys.include?(k)
|
||||
h[k].rjust(columns[k][:width])
|
||||
else
|
||||
h[k].ljust(columns[k][:width])
|
||||
end
|
||||
}.join(" | ")
|
||||
env.ui.info "| #{str} |"
|
||||
end
|
||||
|
||||
# ===================================================
|
||||
# ===================================================
|
||||
|
||||
# Takes a "mostly" flat key=>value hash from Vagrant Cloud
|
||||
# and prints its results in a list
|
||||
#
|
||||
# @param [Hash] - results - A response hash from vagrant cloud
|
||||
# @param [Vagrant::Environment] - env
|
||||
def format_box_results(results, env)
|
||||
# TODO: remove other description fields? Maybe leave "short"?
|
||||
results.delete("description_html")
|
||||
|
||||
if results["current_version"]
|
||||
versions = results.delete("versions")
|
||||
results["providers"] = results["current_version"]["providers"]
|
||||
|
||||
results["old_versions"] = versions.map{ |v| v["version"] }[1..5].join(", ") + "..."
|
||||
end
|
||||
|
||||
|
||||
width = results.keys.map{|k| k.size}.max
|
||||
results.each do |k,v|
|
||||
if k == "versions"
|
||||
v = v.map{ |ver| ver["version"] }.join(", ")
|
||||
elsif k == "current_version"
|
||||
v = v["version"]
|
||||
elsif k == "providers"
|
||||
v = v.map{ |p| p["name"] }.join(", ")
|
||||
elsif k == "downloads"
|
||||
v = format_downloads(v.to_s)
|
||||
end
|
||||
|
||||
whitespace = width-k.size
|
||||
env.ui.info "#{k}:" + "".ljust(whitespace) + " #{v}"
|
||||
end
|
||||
end
|
||||
|
||||
# Converts a string of numbers into a formatted number
|
||||
#
|
||||
# 1234 -> 1,234
|
||||
#
|
||||
# @param [String] - download_string
|
||||
def format_downloads(download_string)
|
||||
return download_string.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
||||
end
|
||||
|
||||
|
||||
# @param [Array] search_results - Box search results from Vagrant Cloud
|
||||
# @param [String,nil] short - determines if short version will be printed
|
||||
# @param [String,nil] json - determines if json version will be printed
|
||||
# @param [Vagrant::Environment] - env
|
||||
def format_search_results(search_results, short, json, env)
|
||||
result = []
|
||||
search_results.each do |b|
|
||||
box = {}
|
||||
box = {
|
||||
name: b["tag"],
|
||||
version: b["current_version"]["version"],
|
||||
downloads: format_downloads(b["downloads"].to_s),
|
||||
providers: b["current_version"]["providers"].map{ |p| p["name"] }.join(",")
|
||||
}
|
||||
result << box
|
||||
end
|
||||
|
||||
if short
|
||||
result.map {|b| env.ui.info(b[:name])}
|
||||
elsif json
|
||||
env.ui.info(result.to_json)
|
||||
# Write a line of content for a table
|
||||
#
|
||||
# @param [Vagrant::Environment] env Current Vagrant environment
|
||||
# @param [Array<Hash>] columns List of columns in Hash format with `:label` and `:width` keys
|
||||
# @param [Hash] h Values to print in row
|
||||
# @param [Array<String>] to_rjust_keys List of columns to right justify
|
||||
# @return [nil]
|
||||
def write_line(env, columns, h, to_rjust_keys)
|
||||
str = h.keys.map { |k|
|
||||
if to_rjust_keys.include?(k)
|
||||
h[k].rjust(columns[k][:width])
|
||||
else
|
||||
column_labels = {}
|
||||
columns = result.first.keys
|
||||
columns.each do |c|
|
||||
column_labels[c] = c.to_s.upcase
|
||||
end
|
||||
print_search_table(env, column_labels, result, [:downloads])
|
||||
h[k].ljust(columns[k][:width])
|
||||
end
|
||||
end
|
||||
}.join(" | ")
|
||||
env.ui.info "| #{str} |"
|
||||
nil
|
||||
end
|
||||
|
||||
# Converts a string of numbers into a formatted number
|
||||
#
|
||||
# 1234 -> 1,234
|
||||
#
|
||||
# @param [String] number Numer to format
|
||||
def format_downloads(number)
|
||||
number.to_s.chars.reverse.each_slice(3).map(&:join).join(",").reverse
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module VersionCommand
|
||||
module Command
|
||||
class Create < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -19,48 +21,51 @@ module VagrantPlugins
|
||||
o.on("-d", "--description DESCRIPTION", String, "A description for this version") do |d|
|
||||
options[:description] = d
|
||||
end
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 2
|
||||
if argv.empty? || argv.length != 2
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
@client = client_login(@env)
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
version = argv[1]
|
||||
|
||||
create_version(org, box_name, version, @client.token, options)
|
||||
create_version(org, box_name, version, @client.token, options.slice(:description))
|
||||
end
|
||||
|
||||
def create_version(org, box_name, box_version, access_token, options)
|
||||
org = options[:username] if options[:username]
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
version = VagrantCloud::Version.new(box, box_version, nil, options[:description], access_token)
|
||||
|
||||
begin
|
||||
success = version.create_version
|
||||
@env.ui.success(I18n.t("cloud_command.version.create_success", version: box_version, org: org, box_name: box_name))
|
||||
success = success.delete_if{|_, v|v.nil?}
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.create_fail", version: box_version, org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
# Create a new version of the box
|
||||
#
|
||||
# @param [String] org Organization box is within
|
||||
# @param [String] box_name Name of box
|
||||
# @param [String] box_version Version of box to create
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options
|
||||
# @option options [String] :description Description of box version
|
||||
# @return [Integer]
|
||||
def create_version(org, box_name, box_version, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_box(account: account, org: org, box: box_name) do |box|
|
||||
version = box.add_version(box_version)
|
||||
version.description = options[:description] if options.key?(:description)
|
||||
version.save
|
||||
@env.ui.success(I18n.t("cloud_command.version.create_success",
|
||||
version: box_version, org: org, box_name: box_name))
|
||||
format_box_results(version, @env)
|
||||
0
|
||||
end
|
||||
return 1
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.create_fail",
|
||||
version: box_version, org: org, box_name: box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module VersionCommand
|
||||
module Command
|
||||
class Delete < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -15,51 +17,56 @@ module VagrantPlugins
|
||||
o.separator ""
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
o.on("-f", "--[no-]force", "Force deletion without confirmation") do |f|
|
||||
options[:force] = f
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 2
|
||||
if argv.size != 2
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
version = argv[1]
|
||||
|
||||
@env.ui.warn(I18n.t("cloud_command.version.delete_warn", version: version, box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
if !options[:force]
|
||||
@env.ui.warn(I18n.t("cloud_command.version.delete_warn", version: version, box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
@client = client_login(@env)
|
||||
|
||||
delete_version(org, box_name, version, options, @client.token)
|
||||
delete_version(org, box_name, version, @client.token, options.slice)
|
||||
end
|
||||
|
||||
def delete_version(org, box_name, box_version, options, access_token)
|
||||
org = options[:username] if options[:username]
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
version = VagrantCloud::Version.new(box, box_version, nil, nil, access_token)
|
||||
|
||||
begin
|
||||
success = version.delete
|
||||
@env.ui.success(I18n.t("cloud_command.version.delete_success", version: box_version, org: org, box_name: box_name))
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.delete_fail", version: box_version, org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
# Delete the requested box version
|
||||
#
|
||||
# @param [String] org Box organization name
|
||||
# @param [String] box_name Name of the box
|
||||
# @param [String] box_version Version of the box
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options Current unsued
|
||||
def delete_version(org, box_name, box_version, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_version(account: account, org: org, box: box_name, version: box_version) do |version|
|
||||
version.delete
|
||||
@env.ui.success(I18n.t("cloud_command.version.delete_success",
|
||||
version: box_version, org: org, box_name: box_name))
|
||||
0
|
||||
end
|
||||
return 1
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.delete_fail",
|
||||
version: box_version, org: org, box_name: box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module VersionCommand
|
||||
module Command
|
||||
class Release < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -15,11 +17,7 @@ module VagrantPlugins
|
||||
o.separator ""
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
end
|
||||
options[:force] = false
|
||||
o.on("-f", "--force", "Release without confirmation") do |f|
|
||||
o.on("-f", "--[no-]force", "Release without confirmation") do |f|
|
||||
options[:force] = f
|
||||
end
|
||||
end
|
||||
@ -27,46 +25,48 @@ module VagrantPlugins
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 2
|
||||
if argv.size != 2
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
if not options[:force]
|
||||
@env.ui.warn(I18n.t("cloud_command.version.release_warn", version: argv[1], box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
if !options[:force]
|
||||
@env.ui.warn(I18n.t("cloud_command.version.release_warn", version: argv[1], box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
@client = client_login(@env)
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
version = argv[1]
|
||||
|
||||
release_version(org, box_name, version, @client.token, options)
|
||||
end
|
||||
|
||||
def release_version(org, box_name, version, access_token, options)
|
||||
org = options[:username] if options[:username]
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
||||
|
||||
begin
|
||||
success = version.release
|
||||
@env.ui.success(I18n.t("cloud_command.version.release_success", version: version, org: org, box_name: box_name))
|
||||
success = success.delete_if{|_, v|v.nil?}
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.release_fail", version: version, org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
# Release the box version
|
||||
#
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box_name Box name
|
||||
# @param [String] version Version of the box
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options Currently unused
|
||||
# @return [Integer]
|
||||
def release_version(org, box_name, version, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_version(account: account, org: org, box: box_name, version: version) do |v|
|
||||
v.release
|
||||
@env.ui.success(I18n.t("cloud_command.version.release_success",
|
||||
version: version, org: org, box_name: box_name))
|
||||
0
|
||||
end
|
||||
return 1
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.release_fail",
|
||||
version: version, org: org, box_name: box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module VersionCommand
|
||||
module Command
|
||||
class Revoke < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -15,52 +17,57 @@ module VagrantPlugins
|
||||
o.separator ""
|
||||
o.separator "Options:"
|
||||
o.separator ""
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
o.on("-f", "--[no-]force", "Force revocation without confirmation") do |f|
|
||||
options[:force] = f
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 2
|
||||
if argv.size != 2
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@env.ui.warn(I18n.t("cloud_command.version.revoke_warn", version: argv[1], box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
if !options[:force]
|
||||
@env.ui.warn(I18n.t("cloud_command.version.revoke_warn", version: argv[1], box: argv.first))
|
||||
cont = @env.ui.ask(I18n.t("cloud_command.continue"))
|
||||
return 1 if cont.strip.downcase != "y"
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
@client = client_login(@env)
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
version = argv[1]
|
||||
|
||||
revoke_version(org, box_name, version, @client.token, options)
|
||||
end
|
||||
|
||||
def revoke_version(org, box_name, box_version, access_token, options)
|
||||
org = options[:username] if options[:username]
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
version = VagrantCloud::Version.new(box, box_version, nil, nil, access_token)
|
||||
|
||||
begin
|
||||
success = version.revoke
|
||||
@env.ui.success(I18n.t("cloud_command.version.revoke_success", version: box_version, org: org, box_name: box_name))
|
||||
success = success.delete_if{|_, v|v.nil?}
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.revoke_fail", version: box_version, org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
# Revoke release of box version
|
||||
#
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box_name Box name
|
||||
# @param [String] version Version of the box
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options Currently unused
|
||||
# @return [Integer]
|
||||
def revoke_version(org, box_name, box_version, access_token, options={})
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_version(account: account, org: org, box: box_name, version: box_version) do |version|
|
||||
version.revoke
|
||||
@env.ui.success(I18n.t("cloud_command.version.revoke_success",
|
||||
version: box_version, org: org, box_name: box_name))
|
||||
format_box_results(version, @env)
|
||||
0
|
||||
end
|
||||
return 1
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.revoke_fail",
|
||||
version: box_version, org: org, box_name: box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ module VagrantPlugins
|
||||
module VersionCommand
|
||||
module Command
|
||||
class Update < Vagrant.plugin("2", :command)
|
||||
include Util
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
@ -19,48 +21,50 @@ module VagrantPlugins
|
||||
o.on("-d", "--description DESCRIPTION", "A description for this version") do |d|
|
||||
options[:description] = d
|
||||
end
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||
options[:username] = u
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
if argv.empty? || argv.length > 2
|
||||
if argv.size != 2
|
||||
raise Vagrant::Errors::CLIInvalidUsage,
|
||||
help: opts.help.chomp
|
||||
end
|
||||
|
||||
@client = VagrantPlugins::CloudCommand::Util.client_login(@env, options[:username])
|
||||
box = argv.first.split('/', 2)
|
||||
org = box[0]
|
||||
box_name = box[1]
|
||||
@client = client_login(@env)
|
||||
org, box_name = argv.first.split('/', 2)
|
||||
version = argv[1]
|
||||
|
||||
update_version(org, box_name, version, @client.token, options)
|
||||
end
|
||||
|
||||
# Update the version of the box
|
||||
# @param [String] org Organization name
|
||||
# @param [String] box_name Box name
|
||||
# @param [String] version Version of the box
|
||||
# @param [String] access_token User Vagrant Cloud access token
|
||||
# @param [Hash] options
|
||||
# @options options [String] :description Description of box version
|
||||
# @return [Integer]
|
||||
def update_version(org, box_name, box_version, access_token, options)
|
||||
org = options[:username] if options[:username]
|
||||
account = VagrantCloud::Account.new(
|
||||
custom_server: api_server_url,
|
||||
access_token: access_token
|
||||
)
|
||||
with_version(account: account, org: org, box: box_name, version: box_version) do |version|
|
||||
version.description = options[:description] if options.key?(:description)
|
||||
version.save
|
||||
|
||||
server_url = VagrantPlugins::CloudCommand::Util.api_server_url
|
||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||
version = VagrantCloud::Version.new(box, box_version, nil, options[:description], access_token)
|
||||
|
||||
begin
|
||||
success = version.update
|
||||
@env.ui.success(I18n.t("cloud_command.version.update_success", version: box_version, org: org, box_name: box_name))
|
||||
success = success.delete_if{|_, v|v.nil?}
|
||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||
return 0
|
||||
rescue VagrantCloud::ClientError => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.update_fail", version: box_version, org: org, box_name: box_name))
|
||||
@env.ui.error(e)
|
||||
return 1
|
||||
@env.ui.success(I18n.t("cloud_command.version.update_success",
|
||||
version: box_version, org: org, box_name: box_name))
|
||||
format_box_results(version, @env)
|
||||
0
|
||||
end
|
||||
return 1
|
||||
rescue VagrantCloud::Error => e
|
||||
@env.ui.error(I18n.t("cloud_command.errors.version.update_fail",
|
||||
version: box_version, org: org, box_name: box_name))
|
||||
@env.ui.error(e.message)
|
||||
1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,253 +0,0 @@
|
||||
require "rest_client"
|
||||
require "vagrant/util/downloader"
|
||||
require "vagrant/util/presence"
|
||||
|
||||
module VagrantPlugins
|
||||
module LoginCommand
|
||||
class Client
|
||||
APP = "app".freeze
|
||||
|
||||
include Vagrant::Util::Presence
|
||||
|
||||
attr_accessor :username_or_email
|
||||
attr_accessor :password
|
||||
attr_reader :two_factor_default_delivery_method
|
||||
attr_reader :two_factor_delivery_methods
|
||||
|
||||
# Initializes a login client with the given Vagrant::Environment.
|
||||
#
|
||||
# @param [Vagrant::Environment] env
|
||||
def initialize(env)
|
||||
@logger = Log4r::Logger.new("vagrant::login::client")
|
||||
@env = env
|
||||
end
|
||||
|
||||
# Removes the token, effectively logging the user out.
|
||||
def clear_token
|
||||
@logger.info("Clearing token")
|
||||
token_path.delete if token_path.file?
|
||||
end
|
||||
|
||||
# Checks if the user is logged in by verifying their authentication
|
||||
# token.
|
||||
#
|
||||
# @return [Boolean]
|
||||
def logged_in?
|
||||
token = self.token
|
||||
return false if !token
|
||||
|
||||
with_error_handling do
|
||||
url = "#{Vagrant.server_url}/api/v1/authenticate" +
|
||||
"?access_token=#{token}"
|
||||
RestClient.get(url, content_type: :json)
|
||||
true
|
||||
end
|
||||
rescue Errors::Unauthorized
|
||||
false
|
||||
end
|
||||
|
||||
# Login logs a user in and returns the token for that user. The token
|
||||
# is _not_ stored unless {#store_token} is called.
|
||||
#
|
||||
# @param [String] description
|
||||
# @param [String] code
|
||||
# @return [String] token The access token, or nil if auth failed.
|
||||
def login(description: nil, code: nil)
|
||||
@logger.info("Logging in '#{username_or_email}'")
|
||||
|
||||
response = post(
|
||||
"/api/v1/authenticate", {
|
||||
user: {
|
||||
login: username_or_email,
|
||||
password: password
|
||||
},
|
||||
token: {
|
||||
description: description
|
||||
},
|
||||
two_factor: {
|
||||
code: code
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
response["token"]
|
||||
end
|
||||
|
||||
# Requests a 2FA code
|
||||
# @param [String] delivery_method
|
||||
def request_code(delivery_method)
|
||||
@env.ui.warn("Requesting 2FA code via #{delivery_method.upcase}...")
|
||||
|
||||
response = post(
|
||||
"/api/v1/two-factor/request-code", {
|
||||
user: {
|
||||
login: username_or_email,
|
||||
password: password
|
||||
},
|
||||
two_factor: {
|
||||
delivery_method: delivery_method.downcase
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
two_factor = response['two_factor']
|
||||
obfuscated_destination = two_factor['obfuscated_destination']
|
||||
|
||||
@env.ui.success("2FA code sent to #{obfuscated_destination}.")
|
||||
end
|
||||
|
||||
# Issues a post to a Vagrant Cloud path with the given payload.
|
||||
# @param [String] path
|
||||
# @param [Hash] payload
|
||||
# @return [Hash] response data
|
||||
def post(path, payload)
|
||||
with_error_handling do
|
||||
url = File.join(Vagrant.server_url, path)
|
||||
|
||||
proxy = nil
|
||||
proxy ||= ENV["HTTPS_PROXY"] || ENV["https_proxy"]
|
||||
proxy ||= ENV["HTTP_PROXY"] || ENV["http_proxy"]
|
||||
RestClient.proxy = proxy
|
||||
|
||||
response = RestClient::Request.execute(
|
||||
method: :post,
|
||||
url: url,
|
||||
payload: JSON.dump(payload),
|
||||
proxy: proxy,
|
||||
headers: {
|
||||
accept: :json,
|
||||
content_type: :json,
|
||||
user_agent: Vagrant::Util::Downloader::USER_AGENT,
|
||||
},
|
||||
)
|
||||
|
||||
JSON.load(response.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
# Stores the given token locally, removing any previous tokens.
|
||||
#
|
||||
# @param [String] token
|
||||
def store_token(token)
|
||||
@logger.info("Storing token in #{token_path}")
|
||||
|
||||
token_path.open("w") do |f|
|
||||
f.write(token)
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
# Reads the access token if there is one. This will first read the
|
||||
# `VAGRANT_CLOUD_TOKEN` environment variable and then fallback to the stored
|
||||
# access token on disk.
|
||||
#
|
||||
# @return [String]
|
||||
def token
|
||||
if present?(ENV["VAGRANT_CLOUD_TOKEN"]) && token_path.exist?
|
||||
@env.ui.warn <<-EOH.strip
|
||||
Vagrant detected both the VAGRANT_CLOUD_TOKEN environment variable and a Vagrant login
|
||||
token are present on this system. The VAGRANT_CLOUD_TOKEN environment variable takes
|
||||
precedence over the locally stored token. To remove this error, either unset
|
||||
the VAGRANT_CLOUD_TOKEN environment variable or remove the login token stored on disk:
|
||||
|
||||
~/.vagrant.d/data/vagrant_login_token
|
||||
|
||||
EOH
|
||||
end
|
||||
|
||||
if present?(ENV["VAGRANT_CLOUD_TOKEN"])
|
||||
@logger.debug("Using authentication token from environment variable")
|
||||
return ENV["VAGRANT_CLOUD_TOKEN"]
|
||||
end
|
||||
|
||||
if token_path.exist?
|
||||
@logger.debug("Using authentication token from disk at #{token_path}")
|
||||
return token_path.read.strip
|
||||
end
|
||||
|
||||
if present?(ENV["ATLAS_TOKEN"])
|
||||
@logger.warn("ATLAS_TOKEN detected within environment. Using ATLAS_TOKEN in place of VAGRANT_CLOUD_TOKEN.")
|
||||
return ENV["ATLAS_TOKEN"]
|
||||
end
|
||||
|
||||
@logger.debug("No authentication token in environment or #{token_path}")
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def with_error_handling(&block)
|
||||
yield
|
||||
rescue RestClient::Unauthorized
|
||||
@logger.debug("Unauthorized!")
|
||||
raise Errors::Unauthorized
|
||||
rescue RestClient::BadRequest => e
|
||||
@logger.debug("Bad request:")
|
||||
@logger.debug(e.message)
|
||||
@logger.debug(e.backtrace.join("\n"))
|
||||
parsed_response = JSON.parse(e.response)
|
||||
errors = parsed_response["errors"].join("\n")
|
||||
raise Errors::ServerError, errors: errors
|
||||
rescue RestClient::NotAcceptable => e
|
||||
@logger.debug("Got unacceptable response:")
|
||||
@logger.debug(e.message)
|
||||
@logger.debug(e.backtrace.join("\n"))
|
||||
|
||||
parsed_response = JSON.parse(e.response)
|
||||
|
||||
if two_factor = parsed_response['two_factor']
|
||||
store_two_factor_information two_factor
|
||||
|
||||
if two_factor_default_delivery_method != APP
|
||||
request_code two_factor_default_delivery_method
|
||||
end
|
||||
|
||||
raise Errors::TwoFactorRequired
|
||||
end
|
||||
|
||||
begin
|
||||
errors = parsed_response["errors"].join("\n")
|
||||
raise Errors::ServerError, errors: errors
|
||||
rescue JSON::ParserError; end
|
||||
|
||||
raise "An unexpected error occurred: #{e.inspect}"
|
||||
rescue SocketError
|
||||
@logger.info("Socket error")
|
||||
raise Errors::ServerUnreachable, url: Vagrant.server_url.to_s
|
||||
end
|
||||
|
||||
def token_path
|
||||
@env.data_dir.join("vagrant_login_token")
|
||||
end
|
||||
|
||||
def store_two_factor_information(two_factor)
|
||||
@two_factor_default_delivery_method =
|
||||
two_factor['default_delivery_method']
|
||||
|
||||
@two_factor_delivery_methods =
|
||||
two_factor['delivery_methods']
|
||||
|
||||
@env.ui.warn "2FA is enabled for your account."
|
||||
if two_factor_default_delivery_method == APP
|
||||
@env.ui.info "Enter the code from your authenticator."
|
||||
else
|
||||
@env.ui.info "Default method is " \
|
||||
"'#{two_factor_default_delivery_method}'."
|
||||
end
|
||||
|
||||
other_delivery_methods =
|
||||
two_factor_delivery_methods - [APP]
|
||||
|
||||
if other_delivery_methods.any?
|
||||
other_delivery_methods_sentence = other_delivery_methods
|
||||
.map { |word| "'#{word}'" }
|
||||
.join(' or ')
|
||||
@env.ui.info "You can also type #{other_delivery_methods_sentence} " \
|
||||
"to request a new code."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,137 +0,0 @@
|
||||
require 'socket'
|
||||
|
||||
module VagrantPlugins
|
||||
module LoginCommand
|
||||
class Command < Vagrant.plugin("2", "command")
|
||||
def self.synopsis
|
||||
"log in to HashiCorp's Vagrant Cloud"
|
||||
end
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant login"
|
||||
o.separator ""
|
||||
o.on("-c", "--check", "Only checks if you're logged in") do |c|
|
||||
options[:check] = c
|
||||
end
|
||||
|
||||
o.on("-d", "--description DESCRIPTION", String, "Description for the Vagrant Cloud token") do |t|
|
||||
options[:description] = t
|
||||
end
|
||||
|
||||
o.on("-k", "--logout", "Logs you out if you're logged in") do |k|
|
||||
options[:logout] = k
|
||||
end
|
||||
|
||||
o.on("-t", "--token TOKEN", String, "Set the Vagrant Cloud token") do |t|
|
||||
options[:token] = t
|
||||
end
|
||||
|
||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Specify your Vagrant Cloud username or email address") do |t|
|
||||
options[:login] = t
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
|
||||
@client = Client.new(@env)
|
||||
@client.username_or_email = options[:login]
|
||||
|
||||
# Determine what task we're actually taking based on flags
|
||||
if options[:check]
|
||||
return execute_check
|
||||
elsif options[:logout]
|
||||
return execute_logout
|
||||
elsif options[:token]
|
||||
return execute_token(options[:token])
|
||||
end
|
||||
|
||||
# Let the user know what is going on.
|
||||
@env.ui.output(I18n.t("login_command.command_header") + "\n")
|
||||
|
||||
# If it is a private cloud installation, show that
|
||||
if Vagrant.server_url != Vagrant::DEFAULT_SERVER_URL
|
||||
@env.ui.output("Vagrant Cloud URL: #{Vagrant.server_url}")
|
||||
end
|
||||
|
||||
# Ask for the username
|
||||
if @client.username_or_email
|
||||
@env.ui.output("Vagrant Cloud username or email: #{@client.username_or_email}")
|
||||
end
|
||||
until @client.username_or_email
|
||||
@client.username_or_email = @env.ui.ask("Vagrant Cloud username or email: ")
|
||||
end
|
||||
|
||||
until @client.password
|
||||
@client.password = @env.ui.ask("Password (will be hidden): ", echo: false)
|
||||
end
|
||||
|
||||
description = options[:description]
|
||||
if description
|
||||
@env.ui.output("Token description: #{description}")
|
||||
else
|
||||
description_default = "Vagrant login from #{Socket.gethostname}"
|
||||
until description
|
||||
description =
|
||||
@env.ui.ask("Token description (Defaults to #{description_default.inspect}): ")
|
||||
end
|
||||
description = description_default if description.empty?
|
||||
end
|
||||
|
||||
code = nil
|
||||
|
||||
begin
|
||||
token = @client.login(description: description, code: code)
|
||||
rescue Errors::TwoFactorRequired
|
||||
until code
|
||||
code = @env.ui.ask("2FA code: ")
|
||||
|
||||
if @client.two_factor_delivery_methods.include?(code.downcase)
|
||||
delivery_method, code = code, nil
|
||||
@client.request_code delivery_method
|
||||
end
|
||||
end
|
||||
|
||||
retry
|
||||
end
|
||||
|
||||
@client.store_token(token)
|
||||
@env.ui.success(I18n.t("login_command.logged_in"))
|
||||
0
|
||||
end
|
||||
|
||||
def execute_check
|
||||
if @client.logged_in?
|
||||
@env.ui.success(I18n.t("login_command.check_logged_in"))
|
||||
return 0
|
||||
else
|
||||
@env.ui.error(I18n.t("login_command.check_not_logged_in"))
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
def execute_logout
|
||||
@client.clear_token
|
||||
@env.ui.success(I18n.t("login_command.logged_out"))
|
||||
return 0
|
||||
end
|
||||
|
||||
def execute_token(token)
|
||||
@client.store_token(token)
|
||||
@env.ui.success(I18n.t("login_command.token_saved"))
|
||||
|
||||
if @client.logged_in?
|
||||
@env.ui.success(I18n.t("login_command.check_logged_in"))
|
||||
return 0
|
||||
else
|
||||
@env.ui.error(I18n.t("login_command.invalid_token"))
|
||||
return 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,24 +0,0 @@
|
||||
module VagrantPlugins
|
||||
module LoginCommand
|
||||
module Errors
|
||||
class Error < Vagrant::Errors::VagrantError
|
||||
error_namespace("login_command.errors")
|
||||
end
|
||||
|
||||
class ServerError < Error
|
||||
error_key(:server_error)
|
||||
end
|
||||
|
||||
class ServerUnreachable < Error
|
||||
error_key(:server_unreachable)
|
||||
end
|
||||
|
||||
class Unauthorized < Error
|
||||
error_key(:unauthorized)
|
||||
end
|
||||
|
||||
class TwoFactorRequired < Error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,49 +0,0 @@
|
||||
en:
|
||||
login_command:
|
||||
middleware:
|
||||
authentication:
|
||||
different_target: |-
|
||||
Vagrant has detected a custom Vagrant server in use for downloading
|
||||
box files. An authentication token is currently set which will be
|
||||
added to the box request. If the custom Vagrant server should not
|
||||
be receiving the authentication token, please unset it.
|
||||
|
||||
Known Vagrant server: %{known_host}
|
||||
Custom Vagrant server: %{custom_host}
|
||||
|
||||
Press ctrl-c to cancel...
|
||||
errors:
|
||||
server_error: |-
|
||||
The Vagrant Cloud server responded with a not-OK response:
|
||||
|
||||
%{errors}
|
||||
server_unreachable: |-
|
||||
The Vagrant Cloud server is not currently accepting connections. Please check
|
||||
your network connection and try again later.
|
||||
|
||||
unauthorized: |-
|
||||
Invalid username or password. Please try again.
|
||||
|
||||
check_logged_in: |-
|
||||
You are already logged in.
|
||||
check_not_logged_in: |-
|
||||
You are not currently logged in. Please run `vagrant login` and provide
|
||||
your login information to authenticate.
|
||||
command_header: |-
|
||||
In a moment we will ask for your username and password to HashiCorp's
|
||||
Vagrant Cloud. After authenticating, we will store an access token locally on
|
||||
disk. Your login details will be transmitted over a secure connection, and
|
||||
are never stored on disk locally.
|
||||
|
||||
If you do not have an Vagrant Cloud account, sign up at
|
||||
https://www.vagrantcloud.com
|
||||
invalid_login: |-
|
||||
Invalid username or password. Please try again.
|
||||
invalid_token: |-
|
||||
Invalid token. Please try again.
|
||||
logged_in: |-
|
||||
You are now logged in.
|
||||
logged_out: |-
|
||||
You are logged out.
|
||||
token_saved: |-
|
||||
The token was successfully saved.
|
||||
@ -2,9 +2,6 @@ require "vagrant"
|
||||
|
||||
module VagrantPlugins
|
||||
module LoginCommand
|
||||
autoload :Client, File.expand_path("../client", __FILE__)
|
||||
autoload :Errors, File.expand_path("../errors", __FILE__)
|
||||
|
||||
class Plugin < Vagrant.plugin("2")
|
||||
name "vagrant-login"
|
||||
description <<-DESC
|
||||
@ -13,18 +10,8 @@ module VagrantPlugins
|
||||
|
||||
command(:login) do
|
||||
require File.expand_path("../../cloud/auth/login", __FILE__)
|
||||
init!
|
||||
VagrantPlugins::CloudCommand::AuthCommand::Command::Login
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def self.init!
|
||||
return if defined?(@_init)
|
||||
I18n.load_path << File.expand_path("../../cloud/locales/en.yml", __FILE__)
|
||||
I18n.reload!
|
||||
@_init = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -7,95 +7,169 @@ describe VagrantPlugins::CloudCommand::AuthCommand::Command::Login do
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:env) { isolated_environment.create_vagrant_env }
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", logged_in?: logged_in) }
|
||||
let(:logged_in) { true }
|
||||
|
||||
let(:token_path) { env.data_dir.join("vagrant_login_token") }
|
||||
|
||||
let(:stdout) { StringIO.new }
|
||||
let(:stderr) { StringIO.new }
|
||||
before do
|
||||
allow(env).to receive(:action_runner).
|
||||
and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Client).
|
||||
to receive(:new).and_return(client)
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
stub_env("ATLAS_TOKEN" => "")
|
||||
describe "#execute_check" do
|
||||
context "when user is logged in" do
|
||||
let(:logged_in) { true }
|
||||
|
||||
it "should output a success message" do
|
||||
expect(env.ui).to receive(:success)
|
||||
subject.execute_check(client)
|
||||
end
|
||||
|
||||
it "should return zero value" do
|
||||
expect(subject.execute_check(client)).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not logged in" do
|
||||
let(:logged_in) { false }
|
||||
|
||||
it "should output an error message" do
|
||||
expect(env.ui).to receive(:error)
|
||||
subject.execute_check(client)
|
||||
end
|
||||
|
||||
it "should return a non-zero value" do
|
||||
r = subject.execute_check(client)
|
||||
expect(r).not_to eq(0)
|
||||
expect(r).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
describe "#execute_token" do
|
||||
let(:token) { double("token") }
|
||||
|
||||
before do
|
||||
allow(env).to receive(:action_runner).and_return(action_runner)
|
||||
before { allow(client).to receive(:store_token) }
|
||||
|
||||
it "should store the token" do
|
||||
expect(client).to receive(:store_token).with(token)
|
||||
subject.execute_token(client, token)
|
||||
end
|
||||
|
||||
context "when token is valid" do
|
||||
let(:logged_in) { true }
|
||||
|
||||
it "should output a success message" do
|
||||
expect(env.ui).to receive(:success).twice
|
||||
subject.execute_token(client, token)
|
||||
end
|
||||
|
||||
it "should return a zero value" do
|
||||
expect(subject.execute_token(client, token)).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when token is invalid" do
|
||||
let(:logged_in) { false }
|
||||
|
||||
it "should output an error message" do
|
||||
expect(env.ui).to receive(:error)
|
||||
subject.execute_token(client, token)
|
||||
end
|
||||
|
||||
it "should return a non-zero value" do
|
||||
r = subject.execute_token(client, token)
|
||||
expect(r).not_to eq(0)
|
||||
expect(r).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#execute" do
|
||||
context "with no args" do
|
||||
let(:argv) { [] }
|
||||
before do
|
||||
allow(client).to receive(:username_or_email=)
|
||||
allow(client).to receive(:store_token)
|
||||
end
|
||||
|
||||
context "with --check" do
|
||||
let(:argv) { ["--check"] }
|
||||
context "when arguments are passed" do
|
||||
before { argv << "argument" }
|
||||
|
||||
context "when there is a token" do
|
||||
before do
|
||||
stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate})
|
||||
.to_return(status: 200)
|
||||
end
|
||||
|
||||
before do
|
||||
File.open(token_path, "w+") { |f| f.write("abcd1234") }
|
||||
end
|
||||
|
||||
it "returns 0" do
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when there is no token" do
|
||||
it "returns 1" do
|
||||
expect(subject.execute).to eq(1)
|
||||
end
|
||||
it "should print help" do
|
||||
expect { subject.execute }.to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with --logout" do
|
||||
let(:argv) { ["--logout"] }
|
||||
context "when --check flag is used" do
|
||||
before { argv << "--check" }
|
||||
|
||||
it "returns 0" do
|
||||
it "should run login check" do
|
||||
expect(subject).to receive(:execute_check).with(client)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should return the value of the check execution" do
|
||||
result = double("result")
|
||||
expect(subject).to receive(:execute_check).with(client).and_return(result)
|
||||
expect(subject.execute).to eq(result)
|
||||
end
|
||||
end
|
||||
|
||||
context "when --token flag is used" do
|
||||
let(:new_token) { "NEW-TOKEN" }
|
||||
|
||||
before { argv.push("--token").push(new_token) }
|
||||
|
||||
it "should execute the token action" do
|
||||
expect(subject).to receive(:execute_token).with(client, new_token)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should return value of token action" do
|
||||
result = double("result")
|
||||
expect(subject).to receive(:execute_token).with(client, new_token).and_return(result)
|
||||
expect(subject.execute).to eq(result)
|
||||
end
|
||||
|
||||
it "should store the new token" do
|
||||
expect(client).to receive(:store_token).with(new_token)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is logged in" do
|
||||
let(:logged_in) { true }
|
||||
|
||||
it "should output success message" do
|
||||
expect(env.ui).to receive(:success)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should return a zero value" do
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
|
||||
it "clears the token" do
|
||||
subject.execute
|
||||
expect(File.exist?(token_path)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "with --token" do
|
||||
let(:argv) { ["--token", "efgh5678"] }
|
||||
context "when user is not logged in" do
|
||||
let(:logged_in) { false }
|
||||
|
||||
context "when the token is valid" do
|
||||
before do
|
||||
stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate})
|
||||
.to_return(status: 200)
|
||||
end
|
||||
|
||||
it "sets the token" do
|
||||
subject.execute
|
||||
token = File.read(token_path).strip
|
||||
expect(token).to eq("efgh5678")
|
||||
end
|
||||
|
||||
it "returns 0" do
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
it "should run the client login" do
|
||||
expect(subject).to receive(:client_login)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "when the token is invalid" do
|
||||
before do
|
||||
stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate})
|
||||
.to_return(status: 401)
|
||||
end
|
||||
context "when username and description flags are supplied" do
|
||||
let(:username) { "my-username" }
|
||||
let(:description) { "my-description" }
|
||||
|
||||
it "returns 1" do
|
||||
expect(subject.execute).to eq(1)
|
||||
before { argv.push("--username").push(username).push("--description").push(description) }
|
||||
|
||||
it "should include login and description to login" do
|
||||
expect(subject).to receive(:client_login).with(env, hash_including(login: username, description: description))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -12,17 +12,15 @@ describe VagrantPlugins::CloudCommand::AuthCommand::Command::Logout do
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:client) { double("client") }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
|
||||
before do
|
||||
allow(VagrantPlugins::CloudCommand::Client).to receive(:new).and_return(client)
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
end
|
||||
|
||||
context "with any arguments" do
|
||||
|
||||
@ -6,49 +6,105 @@ describe VagrantPlugins::CloudCommand::AuthCommand::Command::Whoami do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
let(:env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:client) { double("client", token: token) }
|
||||
let(:token) { double("token") }
|
||||
let(:account_username) { "account-username" }
|
||||
let(:account) { double("account", username: account_username) }
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:account) { double("account") }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:account).
|
||||
and_return(account)
|
||||
allow(env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Client).to receive(:new).and_return(client)
|
||||
allow(VagrantCloud::Account).to receive(:new).and_return(account)
|
||||
end
|
||||
|
||||
context "with too many arguments" do
|
||||
let(:argv) { ["token", "token", "token"] }
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
describe "whoami" do
|
||||
context "when token is unset" do
|
||||
let(:token) { "" }
|
||||
|
||||
it "should output an error" do
|
||||
expect(env.ui).to receive(:error)
|
||||
subject.whoami(token)
|
||||
end
|
||||
|
||||
it "should return non-zero" do
|
||||
r = subject.whoami(token)
|
||||
expect(r).not_to eq(0)
|
||||
expect(r).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
|
||||
context "when token is set" do
|
||||
let(:token) { "my-token" }
|
||||
|
||||
it "should load an account to validate" do
|
||||
expect(VagrantCloud::Account).to receive(:new).
|
||||
with(hash_including(access_token: token)).and_return(account)
|
||||
subject.whoami(token)
|
||||
end
|
||||
|
||||
it "should output the account username" do
|
||||
expect(env.ui).to receive(:success).with(/#{account_username}/)
|
||||
subject.whoami(token)
|
||||
end
|
||||
|
||||
it "should return zero value" do
|
||||
expect(subject.whoami(token)).to eq(0)
|
||||
end
|
||||
|
||||
context "when error is encountered" do
|
||||
before { allow(VagrantCloud::Account).to receive(:new).and_raise(VagrantCloud::Error::ClientError) }
|
||||
|
||||
it "should output an error" do
|
||||
expect(env.ui).to receive(:error).twice
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should return a non-zero value" do
|
||||
r = subject.execute
|
||||
expect(r).not_to eq(0)
|
||||
expect(r).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with username" do
|
||||
let(:argv) { ["token"] }
|
||||
let(:org_hash) { {"user"=>{"username"=>"mario"}, "boxes"=>[{"name"=>"box"}]} }
|
||||
|
||||
it "gets information about a user" do
|
||||
expect(account).to receive(:validate_token).and_return(org_hash)
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
before do
|
||||
allow(subject).to receive(:whoami)
|
||||
end
|
||||
|
||||
it "returns 1 if encountering an error making request" do
|
||||
allow(account).to receive(:validate_token).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
context "with too many arguments" do
|
||||
let(:argv) { ["token", "token", "token"] }
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with no argument" do
|
||||
it "should use stored token via client" do
|
||||
expect(subject).to receive(:whoami).with(token)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "with token argument" do
|
||||
let(:token_arg) { "TOKEN_ARG" }
|
||||
let(:argv) { [token_arg] }
|
||||
|
||||
it "should use the passed token" do
|
||||
expect(subject).to receive(:whoami).with(token_arg)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,57 +5,146 @@ require Vagrant.source_root.join("plugins/commands/cloud/box/create")
|
||||
describe VagrantPlugins::CloudCommand::BoxCommand::Command::Create do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
end
|
||||
describe "#create_box" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(account).to receive(:organization).with(name: org_name).
|
||||
and_return(organization)
|
||||
allow(subject).to receive(:format_box_results).with(box, env)
|
||||
allow(organization).to receive(:add_box).and_return(box)
|
||||
allow(box).to receive(:save)
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
it "should add a new box to the organization" do
|
||||
expect(organization).to receive(:add_box).with(box_name).
|
||||
and_return(box)
|
||||
subject.create_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
|
||||
it "should save the new box" do
|
||||
expect(box).to receive(:save)
|
||||
subject.create_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
|
||||
it "should return a zero value on success" do
|
||||
expect(subject.create_box(org_name, box_name, access_token, options)).
|
||||
to eq(0)
|
||||
end
|
||||
|
||||
it "should return a non-zero value on error" do
|
||||
expect(box).to receive(:save).and_raise(VagrantCloud::Error)
|
||||
result = subject.create_box(org_name, box_name, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
|
||||
context "with option set" do
|
||||
let(:options) { {short: short, description: description, private: priv} }
|
||||
let(:short) { double("short") }
|
||||
let(:description) { double("description") }
|
||||
let(:priv) { double("private") }
|
||||
|
||||
it "should set info into box" do
|
||||
expect(box).to receive(:short_description=).with(short)
|
||||
expect(box).to receive(:description=).with(description)
|
||||
expect(box).to receive(:private=).with(priv)
|
||||
subject.create_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "-s", "short", "-d", "long"] }
|
||||
|
||||
it "creates a box" do
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, "short", "long", client.token)
|
||||
.and_return(box)
|
||||
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(box).to receive(:create).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, "short", "long", client.token)
|
||||
.and_return(box)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(box).to receive(:create).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 422))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: access_token) }
|
||||
let(:box) { double("box") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).and_return(client)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
allow(subject).to receive(:create_box)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "should create the box" do
|
||||
expect(subject).to receive(:create_box).with(org_name, box_name, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "when description flag is provided" do
|
||||
let(:description) { "my-description" }
|
||||
|
||||
before { argv.push("--description").push(description) }
|
||||
|
||||
it "should create box with given description" do
|
||||
expect(subject).to receive(:create_box).
|
||||
with(org_name, box_name, access_token, hash_including(description: description))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "when short flag is provided" do
|
||||
let(:description) { "my-description" }
|
||||
|
||||
before { argv.push("--short").push(description) }
|
||||
|
||||
it "should create box with given short description" do
|
||||
expect(subject).to receive(:create_box).
|
||||
with(org_name, box_name, access_token, hash_including(short: description))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "when private flag is provided" do
|
||||
before { argv.push("--private") }
|
||||
|
||||
it "should create box as private" do
|
||||
expect(subject).to receive(:create_box).
|
||||
with(org_name, box_name, access_token, hash_including(private: true))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,58 +5,109 @@ require Vagrant.source_root.join("plugins/commands/cloud/box/delete")
|
||||
describe VagrantPlugins::CloudCommand::BoxCommand::Command::Delete do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
end
|
||||
describe "#delete_box" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_box).with(account: account, org: org_name, box: box_name).
|
||||
and_yield(box)
|
||||
allow(account).to receive(:organization).with(name: org_name).
|
||||
and_return(organization)
|
||||
allow(box).to receive(:delete)
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
it "should return 0 on success" do
|
||||
expect(subject.delete_box(org_name, box_name, access_token)).to eq(0)
|
||||
end
|
||||
|
||||
it "should delete the box" do
|
||||
expect(box).to receive(:delete)
|
||||
subject.delete_box(org_name, box_name, access_token)
|
||||
end
|
||||
|
||||
it "should return non-zero on error" do
|
||||
expect(box).to receive(:delete).and_raise(VagrantCloud::Error)
|
||||
result = subject.delete_box(org_name, box_name, access_token)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name"] }
|
||||
describe "#execute" do
|
||||
|
||||
it "creates a box" do
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
|
||||
expect(box).to receive(:delete).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(box).to receive(:delete).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: access_token) }
|
||||
let(:box) { double("box") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
allow(subject).to receive(:delete_box)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let (:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "should delete the box" do
|
||||
expect(subject).to receive(:delete_box).
|
||||
with(org_name, box_name, access_token)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should prompt for confirmation" do
|
||||
expect(iso_env.ui).to receive(:ask).and_return("y")
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with force flag" do
|
||||
before { argv.push("--force") }
|
||||
|
||||
it "should not prompt for confirmation" do
|
||||
expect(iso_env.ui).not_to receive(:ask)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,59 +5,147 @@ require Vagrant.source_root.join("plugins/commands/cloud/box/show")
|
||||
describe VagrantPlugins::CloudCommand::BoxCommand::Command::Show do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
end
|
||||
describe "#show_box" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(ui).to receive(:output)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_box).with(account: account, org: org_name, box: box_name).
|
||||
and_yield(box)
|
||||
allow(account).to receive(:organization).with(name: org_name).
|
||||
and_return(organization)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
it "should return 0 on success" do
|
||||
expect(subject.show_box(org_name, box_name, access_token, options)).to eq(0)
|
||||
end
|
||||
|
||||
it "should display the box results" do
|
||||
expect(subject).to receive(:format_box_results).with(box, env)
|
||||
subject.show_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
|
||||
it "should return non-zero on error" do
|
||||
expect(subject).to receive(:with_box).and_raise(VagrantCloud::Error)
|
||||
result = subject.show_box(org_name, box_name, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
|
||||
context "with version defined" do
|
||||
let(:options) { {versions: [version]} }
|
||||
let(:box_version) { double("box_version", version: version) }
|
||||
let(:box_versions) { [box_version] }
|
||||
let(:version) { double("version") }
|
||||
|
||||
before do
|
||||
allow(box).to receive(:versions).and_return(box_versions)
|
||||
end
|
||||
|
||||
it "should print the version details" do
|
||||
expect(subject).to receive(:format_box_results).with(box_version, env)
|
||||
subject.show_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
|
||||
context "when version is not found" do
|
||||
let(:box_versions) { [] }
|
||||
|
||||
it "should return non-zero" do
|
||||
result = subject.show_box(org_name, box_name, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
|
||||
it "should not print any box information" do
|
||||
expect(subject).not_to receive(:format_box_results)
|
||||
subject.show_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name"] }
|
||||
|
||||
it "creates a box" do
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
|
||||
expect(box).to receive(:read).and_return({})
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(box).to receive(:read).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:show_box)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let (:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "should show the box" do
|
||||
expect(subject).to receive(:show_box).with(org_name, box_name, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should create the client login quietly" do
|
||||
expect(subject).to receive(:client_login).with(iso_env, hash_including(quiet: true))
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with auth flag" do
|
||||
before { argv.push("--auth") }
|
||||
|
||||
it "should set quiet option to false when creating client" do
|
||||
expect(subject).to receive(:client_login).with(iso_env, hash_including(quiet: false))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "with versions flag set" do
|
||||
let(:version_option) { "1.0.0" }
|
||||
|
||||
before { argv.push("--versions").push(version_option) }
|
||||
|
||||
it "should show box with version option set" do
|
||||
expect(subject).to receive(:show_box).
|
||||
with(org_name, box_name, access_token, hash_including(versions: [version_option]))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,64 +1,146 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/box/update")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::BoxCommand::Command::Update do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
end
|
||||
describe "#update_box" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_box).with(account: account, org: org_name, box: box_name).
|
||||
and_yield(box)
|
||||
allow(account).to receive(:organization).with(name: org_name).
|
||||
and_return(organization)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
allow(box).to receive(:save)
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
it "should save the box" do
|
||||
expect(box).to receive(:save)
|
||||
subject.update_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
|
||||
it "should return 0 on success" do
|
||||
result = subject.update_box(org_name, box_name, access_token, options)
|
||||
expect(result).to eq(0)
|
||||
end
|
||||
|
||||
it "should return non-zero on error" do
|
||||
expect(box).to receive(:save).and_raise(VagrantCloud::Error)
|
||||
result = subject.update_box(org_name, box_name, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
|
||||
it "should display the box information" do
|
||||
expect(subject).to receive(:format_box_results).with(box, env)
|
||||
subject.update_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
|
||||
context "with options set" do
|
||||
let(:options) { {short: short, description: description, private: priv} }
|
||||
let(:short) { double("short") }
|
||||
let(:description) { double("description") }
|
||||
let(:priv) { double("private") }
|
||||
|
||||
it "should set box info" do
|
||||
expect(box).to receive(:short_description=).with(short)
|
||||
expect(box).to receive(:description=).with(description)
|
||||
expect(box).to receive(:private=).with(priv)
|
||||
subject.update_box(org_name, box_name, access_token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "-d", "update", "-s", "short"] }
|
||||
|
||||
it "creates a box" do
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
|
||||
expect(box).to receive(:update).
|
||||
with(organization: "vagrant", name: "box-name", description: "update", short_description: "short").
|
||||
and_return({})
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(box).to receive(:update).
|
||||
with(organization: "vagrant", name: "box-name", description: "update", short_description: "short").
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).and_return(client)
|
||||
allow(subject).to receive(:update_box)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "should show help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with description flag set" do
|
||||
let(:description) { "my-description" }
|
||||
|
||||
before { argv.push("--description").push(description) }
|
||||
|
||||
it "should update box with description" do
|
||||
expect(subject).to receive(:update_box).
|
||||
with(org_name, box_name, access_token, hash_including(description: description))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "with short flag set" do
|
||||
let(:description) { "my-description" }
|
||||
|
||||
before { argv.push("--short-description").push(description) }
|
||||
|
||||
it "should update box with short description" do
|
||||
expect(subject).to receive(:update_box).
|
||||
with(org_name, box_name, access_token, hash_including(short: description))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "with private flag set" do
|
||||
before { argv.push("--private") }
|
||||
|
||||
it "should update box with private" do
|
||||
expect(subject).to receive(:update_box).
|
||||
with(org_name, box_name, access_token, hash_including(private: true))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -6,6 +6,8 @@ describe VagrantPlugins::CloudCommand::Client do
|
||||
include_context "unit"
|
||||
|
||||
let(:env) { isolated_environment.create_vagrant_env }
|
||||
let(:token) { nil }
|
||||
let(:vc_client) { double("vagrantcloud-client", access_token: token) }
|
||||
|
||||
subject(:client) { described_class.new(env) }
|
||||
|
||||
@ -16,246 +18,246 @@ describe VagrantPlugins::CloudCommand::Client do
|
||||
|
||||
before do
|
||||
stub_env("ATLAS_TOKEN" => nil)
|
||||
subject.clear_token
|
||||
stub_env("VAGRANT_CLOUD_TOKEN" => nil)
|
||||
allow(VagrantCloud::Client).to receive(:new).and_return(vc_client)
|
||||
allow(Vagrant::Util::CredentialScrubber).to receive(:sensitive)
|
||||
end
|
||||
|
||||
after do
|
||||
Vagrant::Util::CredentialScrubber.reset!
|
||||
end
|
||||
|
||||
describe "#logged_in?" do
|
||||
let(:url) { "#{Vagrant.server_url}/api/v1/authenticate?access_token=#{token}" }
|
||||
let(:headers) { { "Content-Type" => "application/json" } }
|
||||
|
||||
before { allow(subject).to receive(:token).and_return(token) }
|
||||
|
||||
context "when there is no token" do
|
||||
let(:token) { nil }
|
||||
|
||||
it "returns false" do
|
||||
expect(subject.logged_in?).to be(false)
|
||||
context "when token is not set" do
|
||||
it "should return false" do
|
||||
expect(subject.logged_in?).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context "when there is a token" do
|
||||
let(:token) { "ABCD1234" }
|
||||
context "when token is set" do
|
||||
let(:token) { double("token") }
|
||||
|
||||
it "returns true if the endpoint returns a 200" do
|
||||
stub_request(:get, url)
|
||||
.with(headers: headers)
|
||||
.to_return(body: JSON.pretty_generate("token" => token))
|
||||
expect(subject.logged_in?).to be(true)
|
||||
before do
|
||||
allow(vc_client).to receive(:authentication_token_validate)
|
||||
end
|
||||
|
||||
it "raises an error if the endpoint returns a non-200" do
|
||||
stub_request(:get, url)
|
||||
.with(headers: headers)
|
||||
.to_return(body: JSON.pretty_generate("bad" => true), status: 401)
|
||||
expect(subject.logged_in?).to be(false)
|
||||
it "should return true when token is valid" do
|
||||
expect(subject.logged_in?).to be_truthy
|
||||
end
|
||||
|
||||
it "raises an exception if the server cannot be found" do
|
||||
stub_request(:get, url)
|
||||
.to_raise(SocketError)
|
||||
expect { subject.logged_in? }
|
||||
.to raise_error(VagrantPlugins::CloudCommand::Errors::ServerUnreachable)
|
||||
it "should validate the set token" do
|
||||
expect(vc_client).to receive(:authentication_token_validate)
|
||||
subject.logged_in?
|
||||
end
|
||||
|
||||
it "should return false when token does not validate" do
|
||||
expect(vc_client).to receive(:authentication_token_validate).
|
||||
and_raise(Excon::Error::Unauthorized.new(StandardError.new))
|
||||
expect(subject.logged_in?).to be_falsey
|
||||
end
|
||||
|
||||
it "should add token to scrubber" do
|
||||
expect(Vagrant::Util::CredentialScrubber).to receive(:sensitive).with(token)
|
||||
subject.logged_in?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#login" do
|
||||
let(:request) {
|
||||
{
|
||||
user: {
|
||||
login: login,
|
||||
password: password,
|
||||
},
|
||||
token: {
|
||||
description: description,
|
||||
},
|
||||
two_factor: {
|
||||
code: nil
|
||||
}
|
||||
}
|
||||
}
|
||||
let(:new_token) { double("new-token") }
|
||||
let(:result) { {token: new_token} }
|
||||
let(:password) { double("password") }
|
||||
let(:username) { double("username") }
|
||||
|
||||
let(:login) { "foo" }
|
||||
let(:password) { "supersecretpassword" }
|
||||
let(:description) { "Token description" }
|
||||
|
||||
let(:headers) {
|
||||
{
|
||||
"Accept" => "application/json",
|
||||
"Content-Type" => "application/json",
|
||||
}
|
||||
}
|
||||
let(:response) {
|
||||
{
|
||||
token: "mysecrettoken"
|
||||
}
|
||||
}
|
||||
|
||||
it "returns the access token after successful login" do
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/authenticate").
|
||||
with(body: JSON.dump(request), headers: headers).
|
||||
to_return(status: 200, body: JSON.dump(response))
|
||||
|
||||
client.username_or_email = login
|
||||
client.password = password
|
||||
|
||||
expect(client.login(description: "Token description")).to eq("mysecrettoken")
|
||||
before do
|
||||
subject.username_or_email = username
|
||||
subject.password = password
|
||||
allow(vc_client).to receive(:authentication_token_create).
|
||||
and_return(result)
|
||||
end
|
||||
|
||||
context "when 2fa is required" do
|
||||
let(:response) {
|
||||
{
|
||||
two_factor: {
|
||||
default_delivery_method: default_delivery_method,
|
||||
delivery_methods: delivery_methods
|
||||
}
|
||||
}
|
||||
}
|
||||
let(:default_delivery_method) { "app" }
|
||||
let(:delivery_methods) { ["app"] }
|
||||
|
||||
before do
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/authenticate").
|
||||
to_return(status: 406, body: JSON.dump(response))
|
||||
end
|
||||
|
||||
it "raises a two-factor required error" do
|
||||
expect {
|
||||
client.login
|
||||
}.to raise_error(VagrantPlugins::CloudCommand::Errors::TwoFactorRequired)
|
||||
end
|
||||
|
||||
context "when the default delivery method is not app" do
|
||||
let(:default_delivery_method) { "sms" }
|
||||
let(:delivery_methods) { ["app", "sms"] }
|
||||
|
||||
it "requests a code and then raises a two-factor required error" do
|
||||
expect(client)
|
||||
.to receive(:request_code)
|
||||
.with(default_delivery_method)
|
||||
|
||||
expect {
|
||||
client.login
|
||||
}.to raise_error(VagrantPlugins::CloudCommand::Errors::TwoFactorRequired)
|
||||
end
|
||||
end
|
||||
it "should add password to scrubber" do
|
||||
expect(Vagrant::Util::CredentialScrubber).to receive(:sensitive).with(password)
|
||||
subject.login
|
||||
end
|
||||
|
||||
context "on bad login" do
|
||||
before do
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/authenticate").
|
||||
to_return(status: 401, body: "")
|
||||
end
|
||||
|
||||
it "raises an error" do
|
||||
expect {
|
||||
client.login
|
||||
}.to raise_error(VagrantPlugins::CloudCommand::Errors::Unauthorized)
|
||||
end
|
||||
it "should create an authentication token" do
|
||||
expect(vc_client).to receive(:authentication_token_create).
|
||||
and_return(result)
|
||||
subject.login
|
||||
end
|
||||
|
||||
context "if it can't reach the server" do
|
||||
before do
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/authenticate").
|
||||
to_raise(SocketError)
|
||||
end
|
||||
it "should wrap remote request to handle errors" do
|
||||
expect(subject).to receive(:with_error_handling)
|
||||
subject.login
|
||||
end
|
||||
|
||||
it "raises an exception" do
|
||||
expect {
|
||||
subject.login
|
||||
}.to raise_error(VagrantPlugins::CloudCommand::Errors::ServerUnreachable)
|
||||
it "should add new token to scrubber" do
|
||||
expect(Vagrant::Util::CredentialScrubber).to receive(:sensitive).with(new_token)
|
||||
subject.login
|
||||
end
|
||||
|
||||
it "should create a new internal client" do
|
||||
expect(VagrantCloud::Client).to receive(:new).with(access_token: new_token)
|
||||
subject.login
|
||||
end
|
||||
|
||||
it "should create authentication token using username and password" do
|
||||
expect(vc_client).to receive(:authentication_token_create).
|
||||
with(hash_including(username: username, password: password)).and_return(result)
|
||||
subject.login
|
||||
end
|
||||
|
||||
it "should return the new token" do
|
||||
expect(subject.login).to eq(new_token)
|
||||
end
|
||||
|
||||
context "with description and code" do
|
||||
let(:description) { double("description") }
|
||||
let(:code) { double("code") }
|
||||
|
||||
it "should create authentication token using description and code" do
|
||||
expect(vc_client).to receive(:authentication_token_create).with(
|
||||
hash_including(username: username, password: password,
|
||||
description: description, code: code))
|
||||
subject.login(description: description, code: code)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#request_code" do
|
||||
let(:request) {
|
||||
{
|
||||
user: {
|
||||
login: login,
|
||||
password: password,
|
||||
},
|
||||
two_factor: {
|
||||
delivery_method: delivery_method
|
||||
}
|
||||
}
|
||||
}
|
||||
let(:password) { double("password") }
|
||||
let(:username) { double("username") }
|
||||
let(:delivery_method) { double("delivery-method", upcase: nil) }
|
||||
let(:result) { {two_factor: two_factor} }
|
||||
let(:two_factor) { {obfuscated_destination: obfuscated_destination} }
|
||||
let(:obfuscated_destination) { double("obfuscated-destination", to_s: "2FA_DESTINATION") }
|
||||
|
||||
let(:login) { "foo" }
|
||||
let(:password) { "supersecretpassword" }
|
||||
let(:delivery_method) { "sms" }
|
||||
before do
|
||||
subject.password = password
|
||||
subject.username_or_email = username
|
||||
allow(vc_client).to receive(:authentication_request_2fa_code).and_return(result)
|
||||
end
|
||||
|
||||
let(:headers) {
|
||||
{
|
||||
"Accept" => "application/json",
|
||||
"Content-Type" => "application/json"
|
||||
}
|
||||
}
|
||||
it "should add password to scrubber" do
|
||||
expect(Vagrant::Util::CredentialScrubber).to receive(:sensitive).with(password)
|
||||
subject.request_code(delivery_method)
|
||||
end
|
||||
|
||||
let(:response) {
|
||||
{
|
||||
two_factor: {
|
||||
obfuscated_destination: "SMS number ending in 1234"
|
||||
}
|
||||
}
|
||||
}
|
||||
it "should request the code" do
|
||||
expect(vc_client).to receive(:authentication_request_2fa_code).with(
|
||||
hash_including(username: username, password: password, delivery_method: delivery_method))
|
||||
subject.request_code(delivery_method)
|
||||
end
|
||||
|
||||
it "displays that the code was sent" do
|
||||
expect(env.ui)
|
||||
.to receive(:success)
|
||||
.with("2FA code sent to SMS number ending in 1234.")
|
||||
it "should print the destination" do
|
||||
expect(env.ui).to receive(:success).with(/2FA_DESTINATION/)
|
||||
subject.request_code(delivery_method)
|
||||
end
|
||||
end
|
||||
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/two-factor/request-code").
|
||||
with(body: JSON.dump(request), headers: headers).
|
||||
to_return(status: 201, body: JSON.dump(response))
|
||||
describe "#store_token" do
|
||||
let(:token_path) { double("token-path") }
|
||||
let(:new_token) { double("new-token") }
|
||||
|
||||
client.username_or_email = login
|
||||
client.password = password
|
||||
before do
|
||||
allow(subject).to receive(:token_path).and_return(token_path)
|
||||
allow(token_path).to receive(:open)
|
||||
end
|
||||
|
||||
client.request_code delivery_method
|
||||
it "should add token to scrubber" do
|
||||
expect(Vagrant::Util::CredentialScrubber).to receive(:sensitive).with(new_token)
|
||||
subject.store_token(new_token)
|
||||
end
|
||||
|
||||
it "should create a new internal client with token" do
|
||||
expect(VagrantCloud::Client).to receive(:new).with(access_token: new_token)
|
||||
subject.store_token(new_token)
|
||||
end
|
||||
|
||||
it "should open the token path and write the new token" do
|
||||
f = double("file")
|
||||
expect(token_path).to receive(:open).with("w").and_yield(f)
|
||||
expect(f).to receive(:write).with(new_token)
|
||||
subject.store_token(new_token)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#token" do
|
||||
it "reads ATLAS_TOKEN" do
|
||||
stub_env("ATLAS_TOKEN" => "ABCD1234")
|
||||
expect(subject.token).to eq("ABCD1234")
|
||||
let(:env_token) { "ENV_TOKEN" }
|
||||
let(:file_token) { "FILE_TOKEN" }
|
||||
let(:token_path) { double("token-path", read: file_token) }
|
||||
let(:path_exists) { false }
|
||||
|
||||
before do
|
||||
expect(subject).to receive(:token).and_call_original
|
||||
allow(subject).to receive(:token_path).and_return(token_path)
|
||||
allow(token_path).to receive(:exist?).and_return(path_exists)
|
||||
end
|
||||
|
||||
it "reads the stored file" do
|
||||
subject.store_token("EFGH5678")
|
||||
expect(subject.token).to eq("EFGH5678")
|
||||
context "when VAGRANT_CLOUD_TOKEN env var is set" do
|
||||
before { stub_env("VAGRANT_CLOUD_TOKEN" => env_token) }
|
||||
|
||||
it "should return the env token" do
|
||||
expect(subject.token).to eq(env_token)
|
||||
end
|
||||
|
||||
context "when token path exists" do
|
||||
let(:path_exists) { true }
|
||||
|
||||
it "should return the env token" do
|
||||
expect(subject.token).to eq(env_token)
|
||||
end
|
||||
|
||||
it "should print warning of two tokens" do
|
||||
expect(env.ui).to receive(:warn)
|
||||
subject.token
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "prefers the environment variable" do
|
||||
stub_env("VAGRANT_CLOUD_TOKEN" => "ABCD1234")
|
||||
subject.store_token("EFGH5678")
|
||||
expect(subject.token).to eq("ABCD1234")
|
||||
context "when token path exists" do
|
||||
let(:path_exists) { true }
|
||||
|
||||
it "should return the stored token" do
|
||||
expect(subject.token).to eq(file_token)
|
||||
end
|
||||
|
||||
context "when VAGRANT_CLOUD_TOKEN env var is set" do
|
||||
before { stub_env("VAGRANT_CLOUD_TOKEN" => env_token) }
|
||||
|
||||
it "should return the env token" do
|
||||
expect(subject.token).to eq(env_token)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "prints a warning if the envvar and stored file are both present" do
|
||||
stub_env("VAGRANT_CLOUD_TOKEN" => "ABCD1234")
|
||||
subject.store_token("EFGH5678")
|
||||
expect(env.ui).to receive(:warn).with(/detected both/)
|
||||
subject.token
|
||||
end
|
||||
context "when ATLAS_TOKEN env var is set" do
|
||||
before { stub_env("ATLAS_TOKEN" => env_token) }
|
||||
|
||||
it "returns nil if there's no token set" do
|
||||
expect(subject.token).to be(nil)
|
||||
end
|
||||
end
|
||||
it "should return the env token" do
|
||||
expect(subject.token).to eq(env_token)
|
||||
end
|
||||
|
||||
describe "#store_token, #clear_token" do
|
||||
it "stores the token and can re-access it" do
|
||||
subject.store_token("foo")
|
||||
expect(subject.token).to eq("foo")
|
||||
expect(described_class.new(env).token).to eq("foo")
|
||||
end
|
||||
context "when VAGRANT_CLOUD_TOKEN is set" do
|
||||
let(:vc_token) { "VC_TOKEN" }
|
||||
|
||||
it "deletes the token" do
|
||||
subject.store_token("foo")
|
||||
subject.clear_token
|
||||
expect(subject.token).to be_nil
|
||||
before { stub_env("VAGRANT_CLOUD_TOKEN" => vc_token) }
|
||||
|
||||
it "should return the VAGRANT_CLOUD_TOKEN value" do
|
||||
expect(subject.token).to eq(vc_token)
|
||||
end
|
||||
end
|
||||
|
||||
context "when file exists" do
|
||||
let(:path_exists) { true }
|
||||
|
||||
it "should return the file token" do
|
||||
expect(subject.token).to eq(file_token)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,85 +1,174 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/provider/create")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Create do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { "0.1.0" }
|
||||
let(:provider_name) { "my-provider" }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version, providers: [provider]) }
|
||||
let(:provider) { double("provider", name: provider_name) }
|
||||
let(:provider_url) { double("provider_url") }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#create_provider" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_version).with(account: account, org: org_name, box: box_name, version: box_version).
|
||||
and_yield(version)
|
||||
allow(account).to receive(:organization).with(name: org_name).
|
||||
and_return(organization)
|
||||
allow(version).to receive(:add_provider).and_return(provider)
|
||||
allow(provider).to receive(:save)
|
||||
allow(provider).to receive(:url=)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
let(:provider) { double("provider") }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
allow(VagrantCloud::Version).to receive(:new)
|
||||
.with(box, "1.0.0", nil, nil, client.token)
|
||||
.and_return(version)
|
||||
end
|
||||
it "should add a new provider to the box version" do
|
||||
expect(version).to receive(:add_provider).with(provider_name)
|
||||
subject.create_provider(org_name, box_name, box_version, provider_name, provider_url, access_token, options)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
it "should not set checksum or checksum_type when not provided" do
|
||||
expect(provider).not_to receive(:checksum=)
|
||||
expect(provider).not_to receive(:checksum_type=)
|
||||
subject.create_provider(org_name, box_name, box_version, provider_name, provider_url, access_token, options)
|
||||
end
|
||||
|
||||
context "with checksum and checksum type options set" do
|
||||
let(:checksum) { double("checksum") }
|
||||
let(:checksum_type) { double("checksum_type") }
|
||||
let(:options) { {checksum: checksum, checksum_type: checksum_type} }
|
||||
|
||||
it "should set the checksum and checksum type" do
|
||||
expect(provider).to receive(:checksum=).with(checksum)
|
||||
expect(provider).to receive(:checksum_type=).with(checksum_type)
|
||||
subject.create_provider(org_name, box_name, box_version, provider_name, provider_url, access_token, options)
|
||||
end
|
||||
end
|
||||
|
||||
context "when URL is set" do
|
||||
it "should set the URL" do
|
||||
expect(provider).to receive(:url=).with(provider_url)
|
||||
subject.create_provider(org_name, box_name, box_version, provider_name, provider_url, access_token, options)
|
||||
end
|
||||
end
|
||||
|
||||
context "when URL is not set" do
|
||||
let(:provider_url) { nil }
|
||||
|
||||
it "should not set the URL" do
|
||||
expect(provider).not_to receive(:url=).with(provider_url)
|
||||
subject.create_provider(org_name, box_name, box_version, provider_name, provider_url, access_token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "virtualbox", "1.0.0"] }
|
||||
|
||||
it "creates a provider" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token, nil, nil, nil).
|
||||
and_return(provider)
|
||||
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(iso_env.ui).to receive(:warn)
|
||||
expect(provider).to receive(:create_provider).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token, nil, nil, nil).
|
||||
and_return(provider)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(provider).to receive(:create_provider).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 422))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:create_provider)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments and a remote url" do
|
||||
let (:argv) { ["vagrant/box-name", "virtualbox", "1.0.0", "https://example.com/box"] }
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
it "creates a provider" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, "https://example.com/box", "vagrant", "box-name", client.token, nil, nil, nil).
|
||||
and_return(provider)
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(iso_env.ui).not_to receive(:warn)
|
||||
expect(provider).to receive(:create_provider).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with provider argument" do
|
||||
let(:provider_arg) { "my-provider" }
|
||||
|
||||
before { argv << provider_arg }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "should create the provider" do
|
||||
expect(subject).to receive(:create_provider).with(org_name, box_name, version_arg, provider_arg, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should not provide URL value" do
|
||||
expect(subject).to receive(:create_provider).with(org_name, box_name, version_arg, provider_arg, nil, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with URL argument" do
|
||||
let(:url_arg) { "provider-url" }
|
||||
|
||||
before { argv << url_arg }
|
||||
|
||||
it "should provide the URL value" do
|
||||
expect(subject).to receive(:create_provider).with(org_name, box_name, version_arg, provider_arg, url_arg, any_args)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "with checksum and checksum type flags" do
|
||||
let(:checksum_arg) { "checksum" }
|
||||
let(:checksum_type_arg) { "checksum_type" }
|
||||
|
||||
before { argv.push("--checksum").push(checksum_arg).push("--checksum-type").push(checksum_type_arg) }
|
||||
|
||||
it "should include the checksum options" do
|
||||
expect(subject).to receive(:create_provider).
|
||||
with(org_name, box_name, version_arg, provider_arg, any_args, hash_including(checksum: checksum_arg, checksum_type: checksum_type_arg))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,70 +1,140 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/provider/delete")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Delete do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { "1.0.0" }
|
||||
let(:box_version_provider) { "my-provider" }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version, providers: [provider]) }
|
||||
let(:provider) { double("provider", name: box_version_provider) }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#delete_provider" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_provider).
|
||||
with(account: account, org: org_name, box: box_name, version: box_version, provider: box_version_provider).
|
||||
and_yield(provider)
|
||||
allow(provider).to receive(:delete)
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
let(:provider) { double("provider") }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
allow(VagrantCloud::Version).to receive(:new)
|
||||
.with(box, "1.0.0", nil, nil, client.token)
|
||||
.and_return(version)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
end
|
||||
it "should delete the provider" do
|
||||
expect(provider).to receive(:delete)
|
||||
subject.delete_provider(org_name, box_name, box_version, box_version_provider, access_token, options)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
it "should return zero on success" do
|
||||
r = subject.delete_provider(org_name, box_name, box_version, box_version_provider, access_token, options)
|
||||
expect(r).to eq(0)
|
||||
end
|
||||
|
||||
context "when error is encountered" do
|
||||
before do
|
||||
expect(provider).to receive(:delete).and_raise(VagrantCloud::Error)
|
||||
end
|
||||
|
||||
it "should return non-zero" do
|
||||
r = subject.delete_provider(org_name, box_name, box_version, box_version_provider, access_token, options)
|
||||
expect(r).to be_a(Integer)
|
||||
expect(r).not_to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "virtualbox", "1.0.0"] }
|
||||
|
||||
it "deletes a provider" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, nil, nil, nil, client.token).
|
||||
and_return(provider)
|
||||
|
||||
expect(provider).to receive(:delete).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, nil, nil, nil, client.token).
|
||||
and_return(provider)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(provider).to receive(:delete).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
allow(subject).to receive(:delete_provider)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with provider argument" do
|
||||
let(:provider_arg) { "my-provider" }
|
||||
|
||||
before { argv << provider_arg }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "should delete the provider" do
|
||||
expect(subject).to receive(:delete_provider).
|
||||
with(org_name, box_name, version_arg, provider_arg, access_token, anything)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should prompt for confirmation" do
|
||||
expect(iso_env.ui).to receive(:ask).and_return("y")
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with force flag" do
|
||||
before { argv << "--force" }
|
||||
|
||||
it "should not prompt for confirmation" do
|
||||
expect(iso_env.ui).not_to receive(:ask)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,85 +1,175 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/provider/update")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { "1.0.0" }
|
||||
let(:box_version_provider) { "my-provider" }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version, provdiers: [provider]) }
|
||||
let(:provider) { double("provider", name: box_version_provider) }
|
||||
let(:provider_url) { nil }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#update_provider" do
|
||||
let(:argv) { [] }
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_provider).
|
||||
with(account: account, org: org_name, box: box_name, version: box_version, provider: box_version_provider).
|
||||
and_yield(provider)
|
||||
allow(provider).to receive(:save)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box", create: true, read: {}) }
|
||||
let(:version) { double("version", create_version: true, release: true) }
|
||||
let(:provider) { double("provider", create_provider: true, upload_file: true) }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
allow(VagrantCloud::Version).to receive(:new)
|
||||
.with(box, "1.0.0", nil, nil, client.token)
|
||||
.and_return(version)
|
||||
end
|
||||
it "should update the provider" do
|
||||
expect(provider).to receive(:save)
|
||||
subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
it "should return 0 on success" do
|
||||
result = subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
|
||||
expect(result).to eq(0)
|
||||
end
|
||||
|
||||
it "should return non-zero result on error" do
|
||||
expect(provider).to receive(:save).and_raise(VagrantCloud::Error)
|
||||
result = subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
|
||||
it "should not update the URL when unset" do
|
||||
expect(provider).not_to receive(:url=)
|
||||
subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
|
||||
end
|
||||
|
||||
context "when URL is set" do
|
||||
let(:provider_url) { double("provider-url") }
|
||||
|
||||
it "should update the URL" do
|
||||
expect(provider).to receive(:url=).with(provider_url)
|
||||
subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with options set" do
|
||||
let(:checksum) { double("checksum") }
|
||||
let(:checksum_type) { double("checksum_type") }
|
||||
let(:options) { {checksum: checksum, checksum_type: checksum_type} }
|
||||
|
||||
it "should set checksum options before saving" do
|
||||
expect(provider).to receive(:checksum=).with(checksum)
|
||||
expect(provider).to receive(:checksum_type=).with(checksum_type)
|
||||
subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "virtualbox", "1.0.0"] }
|
||||
|
||||
it "updates a provider" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token, nil, nil, nil).
|
||||
and_return(provider)
|
||||
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(iso_env.ui).to receive(:warn)
|
||||
expect(provider).to receive(:update).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token, nil, nil, nil).
|
||||
and_return(provider)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(provider).to receive(:update).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:update_provider)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments and a remote url" do
|
||||
let (:argv) { ["vagrant/box-name", "virtualbox", "1.0.0", "https://example.com/box"] }
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
it "creates a provider" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, "https://example.com/box", "vagrant", "box-name", client.token, nil, nil, nil).
|
||||
and_return(provider)
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(iso_env.ui).not_to receive(:warn)
|
||||
expect(provider).to receive(:update).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with provider argument" do
|
||||
let(:provider_arg) { "my-provider" }
|
||||
|
||||
before { argv << provider_arg }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "should create the provider" do
|
||||
expect(subject).to receive(:update_provider).with(org_name, box_name, version_arg, provider_arg, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should not provide URL value" do
|
||||
expect(subject).to receive(:update_provider).with(org_name, box_name, version_arg, provider_arg, nil, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with URL argument" do
|
||||
let(:url_arg) { "provider-url" }
|
||||
|
||||
before { argv << url_arg }
|
||||
|
||||
it "should provide the URL value" do
|
||||
expect(subject).to receive(:update_provider).with(org_name, box_name, version_arg, provider_arg, url_arg, any_args)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
|
||||
context "with checksum and checksum type flags" do
|
||||
let(:checksum_arg) { "checksum" }
|
||||
let(:checksum_type_arg) { "checksum_type" }
|
||||
|
||||
before { argv.push("--checksum").push(checksum_arg).push("--checksum-type").push(checksum_type_arg) }
|
||||
|
||||
it "should include the checksum options" do
|
||||
expect(subject).to receive(:update_provider).
|
||||
with(org_name, box_name, version_arg, provider_arg, any_args, hash_including(checksum: checksum_arg, checksum_type: checksum_type_arg))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,79 +1,184 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/provider/upload")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Upload do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { "1.0.0" }
|
||||
let(:box_version_provider) { "my-provider" }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version, provdiers: [provider]) }
|
||||
let(:provider) { double("provider", name: box_version_provider) }
|
||||
let(:provider_file) { double("provider-file") }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#upload_provider" do
|
||||
let(:argv) { [] }
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:upload_url) { double("upload-url") }
|
||||
let(:uploader) { double("uploader") }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
let(:provider) { double("provider") }
|
||||
let(:uploader) { double("uploader") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
allow(VagrantCloud::Version).to receive(:new)
|
||||
.with(box, "1.0.0", nil, nil, client.token)
|
||||
.and_return(version)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:output)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(I18n).to receive(:t)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_provider).
|
||||
with(account: account, org: org_name, box: box_name, version: box_version, provider: box_version_provider).
|
||||
and_yield(provider)
|
||||
allow(provider).to receive(:upload).and_yield(upload_url)
|
||||
allow(uploader).to receive(:upload!)
|
||||
allow(Vagrant::UI::Prefixed).to receive(:new).with(ui, "cloud").and_return(ui)
|
||||
allow(Vagrant::Util::Uploader).to receive(:new).and_return(uploader)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "virtualbox", "1.0.0", "path/to/box.box"] }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
it "uploads a provider" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token).
|
||||
and_return(provider)
|
||||
allow(provider).to receive(:upload_url).
|
||||
and_return("http://example.com/there")
|
||||
allow(Vagrant::Util::Uploader).to receive(:new).
|
||||
with("http://example.com/there", "path/to/box.box", {ui: anything}).
|
||||
and_return(uploader)
|
||||
it "should upload the provider file" do
|
||||
expect(provider).to receive(:upload)
|
||||
subject.upload_provider(org_name, box_name, box_version, box_version_provider, provider_file, access_token, options)
|
||||
end
|
||||
|
||||
it "should return zero on success" do
|
||||
r = subject.upload_provider(org_name, box_name, box_version, box_version_provider, provider_file, access_token, options)
|
||||
expect(r).to eq(0)
|
||||
end
|
||||
|
||||
it "should return non-zero on API error" do
|
||||
expect(provider).to receive(:upload).and_raise(VagrantCloud::Error)
|
||||
r = subject.upload_provider(org_name, box_name, box_version, box_version_provider, provider_file, access_token, options)
|
||||
expect(r).not_to eq(0)
|
||||
expect(r).to be_a(Integer)
|
||||
end
|
||||
|
||||
it "should return non-zero on upload error" do
|
||||
expect(provider).to receive(:upload).and_raise(Vagrant::Errors::UploaderError)
|
||||
r = subject.upload_provider(org_name, box_name, box_version, box_version_provider, provider_file, access_token, options)
|
||||
expect(r).not_to eq(0)
|
||||
expect(r).to be_a(Integer)
|
||||
end
|
||||
|
||||
it "should should upload via uploader" do
|
||||
expect(uploader).to receive(:upload!)
|
||||
expect(subject.execute).to eq(0)
|
||||
subject.upload_provider(org_name, box_name, box_version, box_version_provider, provider_file, access_token, options)
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Provider).to receive(:new).
|
||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token).
|
||||
and_return(provider)
|
||||
allow(provider).to receive(:upload_url).
|
||||
and_return("http://example.com/there")
|
||||
allow(Vagrant::Util::Uploader).to receive(:new).
|
||||
with("http://example.com/there", "path/to/box.box", {ui: anything}).
|
||||
and_return(uploader)
|
||||
it "should not use direct upload by default" do
|
||||
expect(provider).to receive(:upload) do |**args|
|
||||
expect(args[:direct]).to be_falsey
|
||||
end
|
||||
subject.upload_provider(org_name, box_name, box_version, box_version_provider, provider_file, access_token, options)
|
||||
end
|
||||
|
||||
allow(uploader).to receive(:upload!).
|
||||
and_raise(Vagrant::Errors::UploaderError.new(exit_code: 1, message: "Error"))
|
||||
expect(subject.execute).to eq(1)
|
||||
context "with direct option" do
|
||||
let(:options) { {direct: true} }
|
||||
|
||||
it "should use direct upload" do
|
||||
expect(provider).to receive(:upload) do |**args|
|
||||
expect(args[:direct]).to be_truthy
|
||||
end
|
||||
subject.upload_provider(org_name, box_name, box_version, box_version_provider, provider_file, access_token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:upload_provider)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with provider argument" do
|
||||
let(:provider_arg) { "my-provider" }
|
||||
|
||||
before { argv << provider_arg }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with file argument" do
|
||||
let(:file_arg) { "/dev/null/file" }
|
||||
|
||||
before { argv << file_arg }
|
||||
|
||||
it "should upload the provider file" do
|
||||
expect(subject).to receive(:upload_provider).
|
||||
with(org_name, box_name, version_arg, provider_arg, file_arg, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should do direct upload by default" do
|
||||
expect(subject).to receive(:upload_provider).
|
||||
with(any_args, hash_including(direct: true))
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with --no-direct flag" do
|
||||
before { argv << "--no-direct" }
|
||||
|
||||
it "should not perform direct upload" do
|
||||
expect(subject).to receive(:upload_provider).
|
||||
with(any_args, hash_including(direct: false))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,127 +5,316 @@ require Vagrant.source_root.join("plugins/commands/cloud/publish")
|
||||
describe VagrantPlugins::CloudCommand::Command::Publish do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) { double("iso_env") }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
let(:provider) { double("provider") }
|
||||
let(:uploader) { double("uploader") }
|
||||
let(:ui) { double("ui") }
|
||||
let(:upload_url) { double("upload_url") }
|
||||
let(:access_token) { double("access_token") }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:box_path) { "path/to/the/virtualbox.box" }
|
||||
|
||||
let(:box) { double("box", create: true, read: {}) }
|
||||
let(:version) { double("version", create_version: true, release: true) }
|
||||
let(:provider) { double("provider", create_provider: true, upload_file: true) }
|
||||
let(:uploader) { double("uploader") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
allow(VagrantCloud::Box).to receive(:new).and_return(box)
|
||||
allow(VagrantCloud::Version).to receive(:new).and_return(version)
|
||||
allow(VagrantCloud::Provider).to receive(:new).and_return(provider)
|
||||
|
||||
allow(File).to receive(:absolute_path).and_return("/full/#{box_path}")
|
||||
allow(File).to receive(:file?).and_return(true)
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(iso_env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: anything).
|
||||
and_return(account)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "missing required arguments" do
|
||||
let(:argv) { ["vagrant/box", "1.0.0", "virtualbox"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "missing box file" do
|
||||
let(:argv) { ["vagrant/box", "1.0.0", "virtualbox", "/notreal/file.box"] }
|
||||
|
||||
it "raises an exception" do
|
||||
allow(File).to receive(:file?).and_return(false)
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::BoxFileNotExist)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let(:argv) { ["vagrant/box", "1.0.0", "virtualbox", box_path] }
|
||||
|
||||
it "publishes a box given options" do
|
||||
allow(provider).to receive(:upload_url).and_return("http://example.com/there")
|
||||
allow(Vagrant::Util::Uploader).to receive(:new).
|
||||
with("http://example.com/there", "/full/path/to/the/virtualbox.box", {ui: anything}).
|
||||
and_return(uploader)
|
||||
describe "#upload_box_file" do
|
||||
before do
|
||||
allow(provider).to receive(:upload).and_yield(upload_url)
|
||||
allow(uploader).to receive(:upload!)
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(subject.execute).to eq(0)
|
||||
allow(File).to receive(:absolute_path).and_return(box)
|
||||
allow(Vagrant::Util::Uploader).to receive(:new).and_return(uploader)
|
||||
end
|
||||
|
||||
it "catches a ClientError if something goes wrong" do
|
||||
allow(provider).to receive(:upload_url).and_return("http://example.com/there")
|
||||
allow(Vagrant::Util::Uploader).to receive(:new).
|
||||
with("http://example.com/there", "/full/path/to/the/virtualbox.box", {ui: anything}).
|
||||
and_return(uploader)
|
||||
allow(uploader).to receive(:upload!)
|
||||
allow(box).to receive(:create).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
it "should get absolute path for box file" do
|
||||
expect(File).to receive(:absolute_path).and_return(box)
|
||||
subject.upload_box_file(provider, box)
|
||||
end
|
||||
|
||||
it "calls update if entity already exists" do
|
||||
allow(provider).to receive(:upload_url).and_return("http://example.com/there")
|
||||
allow(Vagrant::Util::Uploader).to receive(:new).
|
||||
with("http://example.com/there", "/full/path/to/the/virtualbox.box", {ui: anything}).
|
||||
and_return(uploader)
|
||||
allow(uploader).to receive(:upload!)
|
||||
allow(box).to receive(:create).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 422))
|
||||
expect(box).to receive(:update)
|
||||
expect(subject.execute).to eq(0)
|
||||
it "should upload through provider" do
|
||||
expect(provider).to receive(:upload).and_return(upload_url)
|
||||
subject.upload_box_file(provider, box)
|
||||
end
|
||||
|
||||
it "should create uploader with given url" do
|
||||
expect(Vagrant::Util::Uploader).to receive(:new).
|
||||
with(upload_url, any_args).and_return(uploader)
|
||||
subject.upload_box_file(provider, box)
|
||||
end
|
||||
|
||||
it "should upload with PUT method by default" do
|
||||
expect(Vagrant::Util::Uploader).to receive(:new).
|
||||
with(upload_url, anything, hash_including(method: :put)).and_return(uploader)
|
||||
subject.upload_box_file(provider, box)
|
||||
end
|
||||
|
||||
it "should upload with PUT method when direct upload option set" do
|
||||
expect(Vagrant::Util::Uploader).to receive(:new).
|
||||
with(upload_url, anything, hash_including(method: :put)).and_return(uploader)
|
||||
subject.upload_box_file(provider, box, direct_upload: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments and releasing a box" do
|
||||
let(:argv) { ["vagrant/box", "1.0.0", "virtualbox", box_path, "--release"] }
|
||||
|
||||
it "releases the box" do
|
||||
allow(provider).to receive(:upload_url).and_return("http://example.com/there")
|
||||
allow(Vagrant::Util::Uploader).to receive(:new).
|
||||
with("http://example.com/there", "/full/path/to/the/virtualbox.box", {ui: anything}).
|
||||
and_return(uploader)
|
||||
allow(uploader).to receive(:upload!)
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
describe "#release_version" do
|
||||
it "should release the version" do
|
||||
expect(version).to receive(:release)
|
||||
expect(subject.execute).to eq(0)
|
||||
subject.release_version(version)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments and a remote url" do
|
||||
let(:argv) { ["vagrant/box", "1.0.0", "virtualbox", "--url", "https://www.example.com/path/to/the/virtualbox.box"] }
|
||||
describe "#set_box_info" do
|
||||
context "with no options set" do
|
||||
let(:options) { {} }
|
||||
|
||||
it "does not upload a file" do
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(subject.execute).to eq(0)
|
||||
expect(provider).not_to receive(:upload_file)
|
||||
it "should not modify the box" do
|
||||
subject.set_box_info(box, options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with options set" do
|
||||
let(:priv) { double("private") }
|
||||
let(:short_description) { double("short_description") }
|
||||
let(:description) { double("description") }
|
||||
|
||||
let(:options) {
|
||||
{private: priv, description: description, short_description: short_description}
|
||||
}
|
||||
|
||||
it "should set info on box" do
|
||||
expect(box).to receive(:private=).with(priv)
|
||||
expect(box).to receive(:short_description=).with(short_description)
|
||||
expect(box).to receive(:description=).with(description)
|
||||
subject.set_box_info(box, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#set_version_info" do
|
||||
context "with no options set" do
|
||||
let(:options) { {} }
|
||||
|
||||
it "should not modify the verison" do
|
||||
subject.set_version_info(version, options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with options set" do
|
||||
let(:options) { {version_description: version_description} }
|
||||
let(:version_description) { double("version_description") }
|
||||
|
||||
it "should set info on version" do
|
||||
expect(version).to receive(:description=).with(version_description)
|
||||
subject.set_version_info(version, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#set_provider_info" do
|
||||
context "with no options set" do
|
||||
let(:options) { {} }
|
||||
|
||||
it "should not modify the provider" do
|
||||
subject.set_provider_info(provider, options)
|
||||
end
|
||||
end
|
||||
|
||||
context "with options set" do
|
||||
let(:options) { {url: url, checksum: checksum, checksum_type: checksum_type} }
|
||||
let(:url) { double("url") }
|
||||
let(:checksum) { double("checksum") }
|
||||
let(:checksum_type) { double("checksum_type") }
|
||||
|
||||
it "should set info on provider" do
|
||||
expect(provider).to receive(:url=).with(url)
|
||||
expect(provider).to receive(:checksum=).with(checksum)
|
||||
expect(provider).to receive(:checksum_type=).with(checksum_type)
|
||||
subject.set_provider_info(provider, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "load_box_version" do
|
||||
let(:box_version) { "1.0.0" }
|
||||
|
||||
context "when vesion exists" do
|
||||
before do
|
||||
allow(box).to receive(:versions).and_return([version])
|
||||
allow(version).to receive(:version).and_return(box_version)
|
||||
end
|
||||
|
||||
it "should return the existing version" do
|
||||
expect(subject.load_box_version(box, box_version)).to eq(version)
|
||||
end
|
||||
end
|
||||
|
||||
context "when version does not exist" do
|
||||
let(:new_version) { double("new_version") }
|
||||
|
||||
before do
|
||||
allow(box).to receive(:versions).and_return([version])
|
||||
allow(version).to receive(:version)
|
||||
end
|
||||
|
||||
it "should add a new version" do
|
||||
expect(box).to receive(:add_version).with(box_version).
|
||||
and_return(new_version)
|
||||
expect(subject.load_box_version(box, box_version)).to eq(new_version)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#load_box" do
|
||||
let(:org_name) { "org-name" }
|
||||
let(:box_name) { "my-box" }
|
||||
|
||||
before do
|
||||
allow(account).to receive(:organization).with(name: org_name).
|
||||
and_return(organization)
|
||||
end
|
||||
|
||||
context "when box exists" do
|
||||
before do
|
||||
allow(box).to receive(:name).and_return(box_name)
|
||||
allow(organization).to receive(:boxes).and_return([box])
|
||||
end
|
||||
|
||||
it "should return the existing box" do
|
||||
expect(subject.load_box(org_name, box_name, access_token)).to eq(box)
|
||||
end
|
||||
end
|
||||
|
||||
context "when box does not exist" do
|
||||
let(:new_box) { double("new_box") }
|
||||
|
||||
before do
|
||||
allow(organization).to receive(:boxes).and_return([])
|
||||
end
|
||||
|
||||
it "should add a new box to organization" do
|
||||
expect(organization).to receive(:add_box).with(box_name).
|
||||
and_return(new_box)
|
||||
expect(subject.load_box(org_name, box_name, access_token)).to eq(new_box)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "#execute" do
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:box_path) { "path/to/the/virtualbox.box" }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).
|
||||
and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
|
||||
allow(iso_env.ui).to receive(:ask).and_return("y")
|
||||
allow(File).to receive(:absolute_path).and_return("/full/#{box_path}")
|
||||
allow(File).to receive(:file?).and_return(true)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "missing required arguments" do
|
||||
let(:argv) { ["vagrant/box", "1.0.0", "virtualbox"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "missing box file" do
|
||||
let(:argv) { ["vagrant/box", "1.0.0", "virtualbox", "/notreal/file.box"] }
|
||||
|
||||
it "raises an exception" do
|
||||
allow(File).to receive(:file?).and_return(false)
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::BoxFileNotExist)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let(:org_name) { "vagrant" }
|
||||
let(:box_name) { "box" }
|
||||
let(:box_version) { "1.0.0" }
|
||||
let(:box_version_provider) { "virtualbox" }
|
||||
|
||||
let(:argv) { [
|
||||
"#{org_name}/#{box_name}", box_version, box_version_provider, box_path
|
||||
] }
|
||||
|
||||
before do
|
||||
allow(account).to receive(:organization).with(name: org_name).
|
||||
and_return(organization)
|
||||
allow(subject).to receive(:load_box).and_return(box)
|
||||
allow(subject).to receive(:load_box_version).and_return(version)
|
||||
allow(subject).to receive(:load_version_provider).and_return(provider)
|
||||
allow(provider).to receive(:upload)
|
||||
|
||||
allow(box).to receive(:save)
|
||||
end
|
||||
|
||||
it "should prompt user for confirmation" do
|
||||
expect(iso_env.ui).to receive(:ask).and_return("y")
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
|
||||
context "when --force option is provided" do
|
||||
before { argv << "--force" }
|
||||
|
||||
it "should not prompt user for confirmation" do
|
||||
expect(iso_env.ui).not_to receive(:ask)
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when --release option is provided" do
|
||||
before do
|
||||
argv << "--release"
|
||||
end
|
||||
|
||||
it "should release box version when not released" do
|
||||
expect(version).to receive(:released?).and_return(false)
|
||||
expect(version).to receive(:release)
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when Vagrant Cloud error is encountered" do
|
||||
before { expect(box).to receive(:save).and_raise(VagrantCloud::Error) }
|
||||
|
||||
it "should return non-zero result" do
|
||||
result = subject.execute
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,6 +5,7 @@ require Vagrant.source_root.join("plugins/commands/cloud/search")
|
||||
describe VagrantPlugins::CloudCommand::Command::Search do
|
||||
include_context "unit"
|
||||
|
||||
let(:token) { double("token") }
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
@ -13,65 +14,146 @@ describe VagrantPlugins::CloudCommand::Command::Search do
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
describe "#search" do
|
||||
let(:query) { double("query") }
|
||||
let(:options) { {} }
|
||||
let(:account) { double("account", searcher: searcher) }
|
||||
let(:searcher) { double("searcher") }
|
||||
let(:results) { double("results", boxes: boxes) }
|
||||
let(:boxes) { [] }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_search_results).
|
||||
and_return(true)
|
||||
end
|
||||
before do
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: token).and_return(account)
|
||||
allow(searcher).to receive(:search).and_return(results)
|
||||
allow(subject).to receive(:format_search_results)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
let (:search) { double("search", search: {"boxes"=>["all of them"]}) }
|
||||
it "should perform search" do
|
||||
expect(searcher).to receive(:search).with(hash_including(query: query)).and_return(results)
|
||||
subject.search(query, token, options)
|
||||
end
|
||||
|
||||
it "makes a request to search all boxes and formats them" do
|
||||
allow(VagrantCloud::Search).to receive(:new).
|
||||
and_return(search)
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_search_results)
|
||||
expect(subject.execute).to eq(0)
|
||||
it "should print a warning when no results are found" do
|
||||
expect(iso_env.ui).to receive(:warn)
|
||||
subject.search(query, token, options)
|
||||
end
|
||||
|
||||
context "with valid options" do
|
||||
let(:provider) { double("provider") }
|
||||
let(:sort) { double("sort") }
|
||||
let(:order) { double("order") }
|
||||
let(:limit) { double("limit") }
|
||||
let(:page) { double("page") }
|
||||
|
||||
let(:options) { {
|
||||
provider: provider,
|
||||
sort: sort,
|
||||
order: order,
|
||||
limit: limit,
|
||||
page: page
|
||||
} }
|
||||
|
||||
it "should use options when performing search" do
|
||||
expect(searcher).to receive(:search) do |**args|
|
||||
options.each_pair do |k, v|
|
||||
expect(args[k]).to eq(v)
|
||||
end
|
||||
results
|
||||
end
|
||||
subject.search(query, token, options)
|
||||
end
|
||||
|
||||
context "with invalid options" do
|
||||
before { options[:invalid_option] = "testing" }
|
||||
|
||||
it "should only pass supported options to search" do
|
||||
expect(searcher).to receive(:search) do |**args|
|
||||
options.each_pair do |k, v|
|
||||
next if k == :invalid_option
|
||||
expect(args[k]).to eq(v)
|
||||
end
|
||||
expect(args.key?(:invalid_option)).to be_falsey
|
||||
results
|
||||
end
|
||||
subject.search(query, token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with search results" do
|
||||
let(:results) { double("results", boxes: [double("result")]) }
|
||||
|
||||
it "should format the results" do
|
||||
expect(subject).to receive(:format_search_results).with(results.boxes, any_args)
|
||||
subject.search(query, token, options)
|
||||
end
|
||||
|
||||
context "with format options" do
|
||||
let(:options) { {short: true, json: false} }
|
||||
|
||||
it "should pass options to format" do
|
||||
expect(subject).to receive(:format_search_results).with(results.boxes, true, false, iso_env)
|
||||
subject.search(query, token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with no arguments and an error occurs making requests" do
|
||||
let (:search) { double("search") }
|
||||
|
||||
it "catches a ClientError if something goes wrong" do
|
||||
allow(VagrantCloud::Search).to receive(:new).
|
||||
and_return(search)
|
||||
allow(search).to receive(:search).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
|
||||
expect(subject.execute).to eq(1)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
end
|
||||
|
||||
context "with no arguments and no results" do
|
||||
let (:search) { double("search", search: {"boxes"=>[]}) }
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
it "makes a request to search all boxes and formats them" do
|
||||
allow(VagrantCloud::Search).to receive(:new).
|
||||
and_return(search)
|
||||
expect(VagrantPlugins::CloudCommand::Util).not_to receive(:format_search_results)
|
||||
subject.execute
|
||||
let(:action_runner) { double("action_runner") }
|
||||
|
||||
let(:client) { double("client", token: token) }
|
||||
let(:box) { double("box") }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).and_return(client)
|
||||
allow(subject).to receive(:search)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:search) { double("search", search: {"boxes"=>["all of them"]}) }
|
||||
let (:argv) { ["ubuntu", "--page", "1", "--order", "desc", "--limit", "100", "--provider", "provider", "--sort", "downloads"] }
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
it "sends the options to make a request with" do
|
||||
allow(VagrantCloud::Search).to receive(:new).
|
||||
and_return(search)
|
||||
expect(search).to receive(:search).
|
||||
with("ubuntu", "provider", "downloads", "desc", 100, 1)
|
||||
subject.execute
|
||||
context "with query argument" do
|
||||
let(:query_arg) { "search-query" }
|
||||
|
||||
before { argv << query_arg }
|
||||
|
||||
it "should run the search" do
|
||||
expect(subject).to receive(:search).with(query_arg, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should setup client login quietly by default" do
|
||||
expect(subject).to receive(:client_login).with(iso_env, hash_including(quiet: true))
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with --auth flag" do
|
||||
before { argv << "--auth" }
|
||||
|
||||
it "should not setup login client quietly" do
|
||||
expect(subject).to receive(:client_login).with(iso_env, hash_including(quiet: false))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,65 +1,135 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/version/create")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::VersionCommand::Command::Create do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { double("box_version") }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version) }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#create_version" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_box).with(account: account, org: org_name, box: box_name).
|
||||
and_yield(box)
|
||||
allow(account).to receive(:organization).with(name: org_name).
|
||||
and_return(organization)
|
||||
allow(box).to receive(:add_version).and_return(version)
|
||||
allow(version).to receive(:save)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
end
|
||||
it "should add a new version to the box" do
|
||||
expect(box).to receive(:add_version).with(box_version)
|
||||
subject.create_version(org_name, box_name, box_version, access_token, options)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
it "should save the new version" do
|
||||
expect(version).to receive(:save)
|
||||
subject.create_version(org_name, box_name, box_version, access_token, options)
|
||||
end
|
||||
|
||||
it "should return 0 on success" do
|
||||
result = subject.create_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).to eq(0)
|
||||
end
|
||||
|
||||
it "should return non-zero on error" do
|
||||
expect(version).to receive(:save).and_raise(VagrantCloud::Error)
|
||||
result = subject.create_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
|
||||
context "with description option set" do
|
||||
let(:description) { double("description") }
|
||||
let(:options) { {description: description} }
|
||||
|
||||
it "should set description on version" do
|
||||
expect(version).to receive(:description=).with(description)
|
||||
subject.create_version(org_name, box_name, box_version, access_token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "1.0.0", "-d", "description"] }
|
||||
|
||||
it "creates a version" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, "description", client.token).
|
||||
and_return(version)
|
||||
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(version).to receive(:create_version).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, "description", client.token).
|
||||
and_return(version)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(version).to receive(:create_version).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 422))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:create_version)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "should create the version" do
|
||||
expect(subject).to receive(:create_version).with(org_name, box_name, version_arg, any_args)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with description flag" do
|
||||
let(:description) { "my-description" }
|
||||
|
||||
before { argv.push("--description").push(description) }
|
||||
|
||||
it "should create version with description option set" do
|
||||
expect(subject).to receive(:create_version).
|
||||
with(org_name, box_name, version_arg, access_token, hash_including(description: description))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,66 +1,122 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/version/delete")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::VersionCommand::Command::Delete do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { double("box_version") }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version) }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#delete_version" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_version).
|
||||
with(account: account, org: org_name, box: box_name, version: box_version).
|
||||
and_yield(version)
|
||||
allow(version).to receive(:delete)
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
end
|
||||
it "should delete the version" do
|
||||
expect(version).to receive(:delete)
|
||||
subject.delete_version(org_name, box_name, box_version, access_token, options)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
it "should return 0 on success" do
|
||||
result = subject.delete_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).to eq(0)
|
||||
end
|
||||
|
||||
it "should return non-zero on error" do
|
||||
expect(version).to receive(:delete).and_raise(VagrantCloud::Error)
|
||||
result = subject.delete_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "1.0.0"] }
|
||||
|
||||
it "deletes a version" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, nil, client.token).
|
||||
and_return(version)
|
||||
|
||||
expect(version).to receive(:delete).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, nil, client.token).
|
||||
and_return(version)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(version).to receive(:delete).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
allow(subject).to receive(:delete_version)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "should delete the version" do
|
||||
expect(subject).to receive(:delete_version).
|
||||
with(org_name, box_name, version_arg, access_token, anything)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should prompt for confirmation" do
|
||||
expect(iso_env.ui).to receive(:ask).and_return("y")
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with force flag" do
|
||||
before { argv << "--force" }
|
||||
|
||||
it "should not prompt for confirmation" do
|
||||
expect(iso_env.ui).not_to receive(:ask)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,91 +1,121 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/version/release")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::VersionCommand::Command::Release do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { double("box_version") }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version) }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#release_version" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_version).
|
||||
with(account: account, org: org_name, box: box_name, version: box_version).
|
||||
and_yield(version)
|
||||
allow(version).to receive(:release)
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
end
|
||||
it "should release the version" do
|
||||
expect(version).to receive(:release)
|
||||
subject.release_version(org_name, box_name, box_version, access_token, options)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
it "should return 0 on success" do
|
||||
result = subject.release_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).to eq(0)
|
||||
end
|
||||
|
||||
it "should return a non-zero on error" do
|
||||
expect(version).to receive(:release).and_raise(VagrantCloud::Error)
|
||||
result = subject.release_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
|
||||
context "interactive mode with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "1.0.0"] }
|
||||
|
||||
it "releases a version" do
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, nil, client.token).
|
||||
and_return(version)
|
||||
|
||||
expect(version).to receive(:release).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, nil, client.token).
|
||||
and_return(version)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(version).to receive(:release).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
end
|
||||
end
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
context "non-interactive mode with arguments" do
|
||||
let (:argv) { ["--force", "vagrant/box-name", "1.0.0"] }
|
||||
|
||||
it "releases a version" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, nil, client.token).
|
||||
and_return(version)
|
||||
|
||||
expect(version).to receive(:release).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:release_version)
|
||||
allow(iso_env.ui).to receive(:ask).and_return("y")
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, nil, client.token).
|
||||
and_return(version)
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
allow(version).to receive(:release).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "should release the version" do
|
||||
expect(subject).to receive(:release_version).
|
||||
with(org_name, box_name, version_arg, access_token, anything)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should prompt for confirmation" do
|
||||
expect(iso_env.ui).to receive(:ask).and_return("y")
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with force flag" do
|
||||
before { argv << "--force" }
|
||||
|
||||
it "should not prompt for confirmation" do
|
||||
expect(iso_env.ui).not_to receive(:ask)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,66 +1,123 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/version/revoke")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::VersionCommand::Command::Revoke do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { double("box_version") }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version) }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#revoke_version" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_version).
|
||||
with(account: account, org: org_name, box: box_name, version: box_version).
|
||||
and_yield(version)
|
||||
allow(version).to receive(:revoke)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
end
|
||||
it "should revoke the version" do
|
||||
expect(version).to receive(:revoke)
|
||||
subject.revoke_version(org_name, box_name, box_version, access_token, options)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
it "should return 0 on success" do
|
||||
result = subject.revoke_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).to eq(0)
|
||||
end
|
||||
|
||||
it "should return non-zero on error" do
|
||||
expect(version).to receive(:revoke).and_raise(VagrantCloud::Error)
|
||||
result = subject.revoke_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "1.0.0"] }
|
||||
|
||||
it "revokes a version" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, nil, client.token).
|
||||
and_return(version)
|
||||
|
||||
expect(version).to receive(:revoke).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, nil, client.token).
|
||||
and_return(version)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
expect(version).to receive(:revoke).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:revoke_version)
|
||||
allow(iso_env.ui).to receive(:ask).
|
||||
and_return("y")
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with box name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "should revoke the version" do
|
||||
expect(subject).to receive(:revoke_version).
|
||||
with(org_name, box_name, version_arg, access_token, anything)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
it "should prompt for confirmation" do
|
||||
expect(iso_env.ui).to receive(:ask).and_return("y")
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with force flag" do
|
||||
before { argv << "--force" }
|
||||
|
||||
it "should not prompt for confirmation" do
|
||||
expect(iso_env.ui).not_to receive(:ask)
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,65 +1,129 @@
|
||||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/cloud/version/update")
|
||||
|
||||
describe VagrantPlugins::CloudCommand::VersionCommand::Command::Update do
|
||||
include_context "unit"
|
||||
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
let(:access_token) { double("token") }
|
||||
let(:org_name) { "my-org" }
|
||||
let(:box_name) { "my-box" }
|
||||
let(:box_version) { double("box_version") }
|
||||
let(:account) { double("account") }
|
||||
let(:organization) { double("organization") }
|
||||
let(:box) { double("box", versions: [version]) }
|
||||
let(:version) { double("version", version: box_version) }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
describe "#update_version" do
|
||||
let(:options) { {} }
|
||||
let(:env) { double("env", ui: ui) }
|
||||
let(:ui) { double("ui") }
|
||||
let(:argv) { [] }
|
||||
|
||||
let(:action_runner) { double("action_runner") }
|
||||
before do
|
||||
allow(ui).to receive(:info)
|
||||
allow(ui).to receive(:warn)
|
||||
allow(ui).to receive(:success)
|
||||
allow(ui).to receive(:error)
|
||||
allow(env).to receive(:ui).and_return(ui)
|
||||
allow(VagrantCloud::Account).to receive(:new).
|
||||
with(custom_server: anything, access_token: access_token).
|
||||
and_return(account)
|
||||
allow(subject).to receive(:with_version).
|
||||
with(account: account, org: org_name, box: box_name, version: box_version).
|
||||
and_yield(version)
|
||||
allow(version).to receive(:save)
|
||||
allow(subject).to receive(:format_box_results)
|
||||
end
|
||||
|
||||
let(:client) { double("client", token: "1234token1234") }
|
||||
let(:box) { double("box") }
|
||||
let(:version) { double("version") }
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results).
|
||||
and_return(true)
|
||||
allow(VagrantCloud::Box).to receive(:new)
|
||||
.with(anything, "box-name", nil, nil, nil, client.token)
|
||||
.and_return(box)
|
||||
end
|
||||
it "should update the version" do
|
||||
expect(version).to receive(:save)
|
||||
subject.update_version(org_name, box_name, box_version, access_token, options)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
it "should return 0 on success" do
|
||||
result = subject.update_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).to eq(0)
|
||||
end
|
||||
|
||||
it "should return non-zero result on error" do
|
||||
expect(version).to receive(:save).and_raise(VagrantCloud::Error)
|
||||
result = subject.update_version(org_name, box_name, box_version, access_token, options)
|
||||
expect(result).not_to eq(0)
|
||||
expect(result).to be_a(Integer)
|
||||
end
|
||||
|
||||
context "with options set" do
|
||||
let(:description) { double("description") }
|
||||
let(:options) { {description: description} }
|
||||
|
||||
it "should set version info before saving" do
|
||||
expect(version).to receive(:description=).with(description)
|
||||
subject.update_version(org_name, box_name, box_version, access_token, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
let (:argv) { ["vagrant/box-name", "1.0.0", "-d", "description"] }
|
||||
|
||||
it "updates a version" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, "description", client.token).
|
||||
and_return(version)
|
||||
|
||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||
expect(version).to receive(:update).and_return({})
|
||||
expect(subject.execute).to eq(0)
|
||||
describe "#execute" do
|
||||
let(:argv) { [] }
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
it "displays an error if encoutering a problem with the request" do
|
||||
allow(VagrantCloud::Version).to receive(:new).
|
||||
with(box, "1.0.0", nil, "description", client.token).
|
||||
and_return(version)
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
allow(version).to receive(:update).
|
||||
and_raise(VagrantCloud::ClientError.new("Fail Message", "Message", 404))
|
||||
expect(subject.execute).to eq(1)
|
||||
let(:action_runner) { double("action_runner") }
|
||||
let(:client) { double("client", token: access_token) }
|
||||
|
||||
before do
|
||||
allow(iso_env).to receive(:action_runner).and_return(action_runner)
|
||||
allow(subject).to receive(:client_login).
|
||||
and_return(client)
|
||||
allow(subject).to receive(:update_version)
|
||||
end
|
||||
|
||||
context "with no arguments" do
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
end
|
||||
|
||||
context "with name argument" do
|
||||
let(:argv) { ["#{org_name}/#{box_name}"] }
|
||||
|
||||
it "shows help" do
|
||||
expect { subject.execute }.
|
||||
to raise_error(Vagrant::Errors::CLIInvalidUsage)
|
||||
end
|
||||
|
||||
context "with version argument" do
|
||||
let(:version_arg) { "1.0.0" }
|
||||
|
||||
before { argv << version_arg }
|
||||
|
||||
it "should update the version" do
|
||||
expect(subject).to receive(:update_version).
|
||||
with(org_name, box_name, version_arg, access_token, anything)
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "with description flag" do
|
||||
let(:description) { "my-description" }
|
||||
|
||||
before { argv.push("--description").push(description) }
|
||||
|
||||
it "should update version with description" do
|
||||
expect(subject).to receive(:update_version).
|
||||
with(org_name, box_name, version_arg, access_token, hash_including(description: description))
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,261 +0,0 @@
|
||||
require File.expand_path("../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/login/command")
|
||||
|
||||
describe VagrantPlugins::LoginCommand::Client do
|
||||
include_context "unit"
|
||||
|
||||
let(:env) { isolated_environment.create_vagrant_env }
|
||||
|
||||
subject(:client) { described_class.new(env) }
|
||||
|
||||
before(:all) do
|
||||
I18n.load_path << Vagrant.source_root.join("plugins/commands/login/locales/en.yml")
|
||||
I18n.reload!
|
||||
end
|
||||
|
||||
before do
|
||||
stub_env("ATLAS_TOKEN" => nil)
|
||||
subject.clear_token
|
||||
end
|
||||
|
||||
describe "#logged_in?" do
|
||||
let(:url) { "#{Vagrant.server_url}/api/v1/authenticate?access_token=#{token}" }
|
||||
let(:headers) { { "Content-Type" => "application/json" } }
|
||||
|
||||
before { allow(subject).to receive(:token).and_return(token) }
|
||||
|
||||
context "when there is no token" do
|
||||
let(:token) { nil }
|
||||
|
||||
it "returns false" do
|
||||
expect(subject.logged_in?).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "when there is a token" do
|
||||
let(:token) { "ABCD1234" }
|
||||
|
||||
it "returns true if the endpoint returns a 200" do
|
||||
stub_request(:get, url)
|
||||
.with(headers: headers)
|
||||
.to_return(body: JSON.pretty_generate("token" => token))
|
||||
expect(subject.logged_in?).to be(true)
|
||||
end
|
||||
|
||||
it "raises an error if the endpoint returns a non-200" do
|
||||
stub_request(:get, url)
|
||||
.with(headers: headers)
|
||||
.to_return(body: JSON.pretty_generate("bad" => true), status: 401)
|
||||
expect(subject.logged_in?).to be(false)
|
||||
end
|
||||
|
||||
it "raises an exception if the server cannot be found" do
|
||||
stub_request(:get, url)
|
||||
.to_raise(SocketError)
|
||||
expect { subject.logged_in? }
|
||||
.to raise_error(VagrantPlugins::LoginCommand::Errors::ServerUnreachable)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#login" do
|
||||
let(:request) {
|
||||
{
|
||||
user: {
|
||||
login: login,
|
||||
password: password,
|
||||
},
|
||||
token: {
|
||||
description: description,
|
||||
},
|
||||
two_factor: {
|
||||
code: nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let(:login) { "foo" }
|
||||
let(:password) { "bar" }
|
||||
let(:description) { "Token description" }
|
||||
|
||||
let(:headers) {
|
||||
{
|
||||
"Accept" => "application/json",
|
||||
"Content-Type" => "application/json",
|
||||
}
|
||||
}
|
||||
let(:response) {
|
||||
{
|
||||
token: "baz"
|
||||
}
|
||||
}
|
||||
|
||||
it "returns the access token after successful login" do
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/authenticate").
|
||||
with(body: JSON.dump(request), headers: headers).
|
||||
to_return(status: 200, body: JSON.dump(response))
|
||||
|
||||
client.username_or_email = login
|
||||
client.password = password
|
||||
|
||||
expect(client.login(description: "Token description")).to eq("baz")
|
||||
end
|
||||
|
||||
context "when 2fa is required" do
|
||||
let(:response) {
|
||||
{
|
||||
two_factor: {
|
||||
default_delivery_method: default_delivery_method,
|
||||
delivery_methods: delivery_methods
|
||||
}
|
||||
}
|
||||
}
|
||||
let(:default_delivery_method) { "app" }
|
||||
let(:delivery_methods) { ["app"] }
|
||||
|
||||
before do
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/authenticate").
|
||||
to_return(status: 406, body: JSON.dump(response))
|
||||
end
|
||||
|
||||
it "raises a two-factor required error" do
|
||||
expect {
|
||||
client.login
|
||||
}.to raise_error(VagrantPlugins::LoginCommand::Errors::TwoFactorRequired)
|
||||
end
|
||||
|
||||
context "when the default delivery method is not app" do
|
||||
let(:default_delivery_method) { "sms" }
|
||||
let(:delivery_methods) { ["app", "sms"] }
|
||||
|
||||
it "requests a code and then raises a two-factor required error" do
|
||||
expect(client)
|
||||
.to receive(:request_code)
|
||||
.with(default_delivery_method)
|
||||
|
||||
expect {
|
||||
client.login
|
||||
}.to raise_error(VagrantPlugins::LoginCommand::Errors::TwoFactorRequired)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "on bad login" do
|
||||
before do
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/authenticate").
|
||||
to_return(status: 401, body: "")
|
||||
end
|
||||
|
||||
it "raises an error" do
|
||||
expect {
|
||||
client.login
|
||||
}.to raise_error(VagrantPlugins::LoginCommand::Errors::Unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
context "if it can't reach the server" do
|
||||
before do
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/authenticate").
|
||||
to_raise(SocketError)
|
||||
end
|
||||
|
||||
it "raises an exception" do
|
||||
expect {
|
||||
subject.login
|
||||
}.to raise_error(VagrantPlugins::LoginCommand::Errors::ServerUnreachable)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#request_code" do
|
||||
let(:request) {
|
||||
{
|
||||
user: {
|
||||
login: login,
|
||||
password: password,
|
||||
},
|
||||
two_factor: {
|
||||
delivery_method: delivery_method
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let(:login) { "foo" }
|
||||
let(:password) { "bar" }
|
||||
let(:delivery_method) { "sms" }
|
||||
|
||||
let(:headers) {
|
||||
{
|
||||
"Accept" => "application/json",
|
||||
"Content-Type" => "application/json"
|
||||
}
|
||||
}
|
||||
|
||||
let(:response) {
|
||||
{
|
||||
two_factor: {
|
||||
obfuscated_destination: "SMS number ending in 1234"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it "displays that the code was sent" do
|
||||
expect(env.ui)
|
||||
.to receive(:success)
|
||||
.with("2FA code sent to SMS number ending in 1234.")
|
||||
|
||||
stub_request(:post, "#{Vagrant.server_url}/api/v1/two-factor/request-code").
|
||||
with(body: JSON.dump(request), headers: headers).
|
||||
to_return(status: 201, body: JSON.dump(response))
|
||||
|
||||
client.username_or_email = login
|
||||
client.password = password
|
||||
|
||||
client.request_code delivery_method
|
||||
end
|
||||
end
|
||||
|
||||
describe "#token" do
|
||||
it "reads ATLAS_TOKEN" do
|
||||
stub_env("ATLAS_TOKEN" => "ABCD1234")
|
||||
expect(subject.token).to eq("ABCD1234")
|
||||
end
|
||||
|
||||
it "reads the stored file" do
|
||||
subject.store_token("EFGH5678")
|
||||
expect(subject.token).to eq("EFGH5678")
|
||||
end
|
||||
|
||||
it "prefers the environment variable" do
|
||||
stub_env("VAGRANT_CLOUD_TOKEN" => "ABCD1234")
|
||||
subject.store_token("EFGH5678")
|
||||
expect(subject.token).to eq("ABCD1234")
|
||||
end
|
||||
|
||||
it "prints a warning if the envvar and stored file are both present" do
|
||||
stub_env("VAGRANT_CLOUD_TOKEN" => "ABCD1234")
|
||||
subject.store_token("EFGH5678")
|
||||
expect(env.ui).to receive(:warn).with(/detected both/)
|
||||
subject.token
|
||||
end
|
||||
|
||||
it "returns nil if there's no token set" do
|
||||
expect(subject.token).to be(nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#store_token, #clear_token" do
|
||||
it "stores the token and can re-access it" do
|
||||
subject.store_token("foo")
|
||||
expect(subject.token).to eq("foo")
|
||||
expect(described_class.new(env).token).to eq("foo")
|
||||
end
|
||||
|
||||
it "deletes the token" do
|
||||
subject.store_token("foo")
|
||||
subject.clear_token
|
||||
expect(subject.token).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,96 +0,0 @@
|
||||
require File.expand_path("../../../../base", __FILE__)
|
||||
|
||||
require Vagrant.source_root.join("plugins/commands/login/command")
|
||||
|
||||
describe VagrantPlugins::LoginCommand::Command do
|
||||
include_context "unit"
|
||||
|
||||
let(:env) { isolated_environment.create_vagrant_env }
|
||||
|
||||
let(:token_path) { env.data_dir.join("vagrant_login_token") }
|
||||
|
||||
let(:stdout) { StringIO.new }
|
||||
let(:stderr) { StringIO.new }
|
||||
|
||||
subject { described_class.new(argv, env) }
|
||||
|
||||
before do
|
||||
stub_env("ATLAS_TOKEN" => "")
|
||||
end
|
||||
|
||||
describe "#execute" do
|
||||
context "with no args" do
|
||||
let(:argv) { [] }
|
||||
end
|
||||
|
||||
context "with --check" do
|
||||
let(:argv) { ["--check"] }
|
||||
|
||||
context "when there is a token" do
|
||||
before do
|
||||
stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate})
|
||||
.to_return(status: 200)
|
||||
end
|
||||
|
||||
before do
|
||||
File.open(token_path, "w+") { |f| f.write("abcd1234") }
|
||||
end
|
||||
|
||||
it "returns 0" do
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when there is no token" do
|
||||
it "returns 1" do
|
||||
expect(subject.execute).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with --logout" do
|
||||
let(:argv) { ["--logout"] }
|
||||
|
||||
it "returns 0" do
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
|
||||
it "clears the token" do
|
||||
subject.execute
|
||||
expect(File.exist?(token_path)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "with --token" do
|
||||
let(:argv) { ["--token", "efgh5678"] }
|
||||
|
||||
context "when the token is valid" do
|
||||
before do
|
||||
stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate})
|
||||
.to_return(status: 200)
|
||||
end
|
||||
|
||||
it "sets the token" do
|
||||
subject.execute
|
||||
token = File.read(token_path).strip
|
||||
expect(token).to eq("efgh5678")
|
||||
end
|
||||
|
||||
it "returns 0" do
|
||||
expect(subject.execute).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the token is invalid" do
|
||||
before do
|
||||
stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate})
|
||||
.to_return(status: 401)
|
||||
end
|
||||
|
||||
it "returns 1" do
|
||||
expect(subject.execute).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -5,7 +5,7 @@ require "vagrant/util/uploader"
|
||||
describe Vagrant::Util::Uploader do
|
||||
let(:destination) { "fake" }
|
||||
let(:file) { "my/file.box" }
|
||||
let(:curl_options) { [destination, "--request", "PUT", "--upload-file", file, {notify: :stderr}] }
|
||||
let(:curl_options) { [destination, "--request", "PUT", "--upload-file", file, "--fail", {notify: :stderr}] }
|
||||
|
||||
let(:subprocess_result) do
|
||||
double("subprocess_result").tap do |result|
|
||||
|
||||
@ -28,9 +28,8 @@ Gem::Specification.new do |s|
|
||||
s.add_dependency "net-sftp", "~> 3.0"
|
||||
s.add_dependency "net-scp", "~> 1.2.0"
|
||||
s.add_dependency "rb-kqueue", "~> 0.2.0"
|
||||
s.add_dependency "rest-client", ">= 1.6.0", "< 3.0"
|
||||
s.add_dependency "rubyzip", "~> 2.0"
|
||||
s.add_dependency "vagrant_cloud", "~> 2.0.3"
|
||||
s.add_dependency "vagrant_cloud", "~> 3.0.2"
|
||||
s.add_dependency "wdm", "~> 0.1.0"
|
||||
s.add_dependency "winrm", ">= 2.3.4", "< 3.0"
|
||||
s.add_dependency "winrm-elevated", ">= 1.2.1", "< 2.0"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user