Merge pull request #4473 from rtkrruvinskiy/https_metadata
Add HTTPS download options to `box update` and `box outdated`
This commit is contained in:
commit
1ccd91aada
|
@ -37,13 +37,23 @@ module Vagrant
|
|||
end
|
||||
|
||||
constraints = machine.config.vm.box_version
|
||||
# Have download options specified in the environment override
|
||||
# options specified for the machine.
|
||||
download_options = {
|
||||
ca_cert: env[:ca_cert] || machine.config.vm.box_download_ca_cert,
|
||||
ca_path: env[:ca_path] || machine.config.vm.box_download_ca_path,
|
||||
client_cert: env[:client_cert] ||
|
||||
machine.config.vm.box_download_client_cert,
|
||||
insecure: !env[:insecure].nil? ?
|
||||
env[:insecure] : machine.config.vm.box_download_insecure
|
||||
}
|
||||
|
||||
env[:ui].output(I18n.t(
|
||||
"vagrant.box_outdated_checking_with_refresh",
|
||||
name: box.name))
|
||||
update = nil
|
||||
begin
|
||||
update = box.has_update?(constraints)
|
||||
update = box.has_update?(constraints, download_options: download_options)
|
||||
rescue Errors::BoxMetadataDownloadError => e
|
||||
env[:ui].warn(I18n.t(
|
||||
"vagrant.box_outdated_metadata_download_error",
|
||||
|
|
|
@ -115,8 +115,9 @@ module Vagrant
|
|||
# Loads the metadata URL and returns the latest metadata associated
|
||||
# with this box.
|
||||
#
|
||||
# @param [Hash] download_options Options to pass to the downloader.
|
||||
# @return [BoxMetadata]
|
||||
def load_metadata
|
||||
def load_metadata(**download_options)
|
||||
tf = Tempfile.new("vagrant")
|
||||
tf.close
|
||||
|
||||
|
@ -127,7 +128,7 @@ module Vagrant
|
|||
url = "file:#{url}"
|
||||
end
|
||||
|
||||
opts = { headers: ["Accept: application/json"] }
|
||||
opts = { headers: ["Accept: application/json"] }.merge(download_options)
|
||||
Util::Downloader.new(url, tf.path, **opts).download!
|
||||
BoxMetadata.new(File.open(tf.path, "r"))
|
||||
rescue Errors::DownloaderError => e
|
||||
|
@ -148,7 +149,7 @@ module Vagrant
|
|||
# satisfy. If nil, the version constrain defaults to being a
|
||||
# larger version than this box.
|
||||
# @return [Array]
|
||||
def has_update?(version=nil)
|
||||
def has_update?(version=nil, download_options: {})
|
||||
if !@metadata_url
|
||||
raise Errors::BoxUpdateNoMetadata, name: @name
|
||||
end
|
||||
|
@ -156,7 +157,7 @@ module Vagrant
|
|||
version += ", " if version
|
||||
version ||= ""
|
||||
version += "> #{@version}"
|
||||
md = self.load_metadata
|
||||
md = self.load_metadata(download_options)
|
||||
newer = md.version(version, provider: @provider)
|
||||
return nil if !newer
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
require 'optparse'
|
||||
|
||||
require_relative 'download_mixins'
|
||||
|
||||
module VagrantPlugins
|
||||
module CommandBox
|
||||
module Command
|
||||
class Add < Vagrant.plugin("2", :command)
|
||||
include DownloadMixins
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
|
@ -21,22 +25,7 @@ module VagrantPlugins
|
|||
options[:force] = f
|
||||
end
|
||||
|
||||
o.on("--insecure", "Do not validate SSL certificates") do |i|
|
||||
options[:insecure] = i
|
||||
end
|
||||
|
||||
o.on("--cacert FILE", String, "CA certificate for SSL download") do |c|
|
||||
options[:ca_cert] = c
|
||||
end
|
||||
|
||||
o.on("--capath DIR", String, "CA certificate directory for SSL download") do |c|
|
||||
options[:ca_path] = c
|
||||
end
|
||||
|
||||
o.on("--cert FILE", String,
|
||||
"A client SSL cert, if needed") do |c|
|
||||
options[:client_cert] = c
|
||||
end
|
||||
build_download_options(o, options)
|
||||
|
||||
o.on("--location-trusted", "Trust 'Location' header from HTTP redirects and use the same credentials for subsequent urls as for the initial one") do |l|
|
||||
options[:location_trusted] = l
|
||||
|
@ -97,7 +86,7 @@ module VagrantPlugins
|
|||
box_force: options[:force],
|
||||
box_download_ca_cert: options[:ca_cert],
|
||||
box_download_ca_path: options[:ca_path],
|
||||
box_download_client_cert: options[:client_cert],
|
||||
box_client_cert: options[:client_cert],
|
||||
box_download_insecure: options[:insecure],
|
||||
box_download_location_trusted: options[:location_trusted],
|
||||
ui: Vagrant::UI::Prefixed.new(@env.ui, "box"),
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
module VagrantPlugins
|
||||
module CommandBox
|
||||
module DownloadMixins
|
||||
# This adds common download command line flags to the given
|
||||
# OptionParser, storing the result in the `options` dictionary.
|
||||
#
|
||||
# @param [OptionParser] parser
|
||||
# @param [Hash] options
|
||||
def build_download_options(parser, options)
|
||||
# Add the options
|
||||
parser.on("--insecure", "Do not validate SSL certificates") do |i|
|
||||
options[:insecure] = i
|
||||
end
|
||||
|
||||
parser.on("--cacert FILE", String, "CA certificate for SSL download") do |c|
|
||||
options[:ca_cert] = c
|
||||
end
|
||||
|
||||
parser.on("--capath DIR", String, "CA certificate directory for SSL download") do |c|
|
||||
options[:ca_path] = c
|
||||
end
|
||||
|
||||
parser.on("--cert FILE", String, "A client SSL cert, if needed") do |c|
|
||||
options[:client_cert] = c
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,11 +1,16 @@
|
|||
require 'optparse'
|
||||
|
||||
require_relative 'download_mixins'
|
||||
|
||||
module VagrantPlugins
|
||||
module CommandBox
|
||||
module Command
|
||||
class Outdated < Vagrant.plugin("2", :command)
|
||||
include DownloadMixins
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
download_options = {}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant box outdated [options]"
|
||||
|
@ -20,6 +25,8 @@ module VagrantPlugins
|
|||
o.on("--global", "Check all boxes installed") do |g|
|
||||
options[:global] = g
|
||||
end
|
||||
|
||||
build_download_options(o, download_options)
|
||||
end
|
||||
|
||||
argv = parse_options(opts)
|
||||
|
@ -27,7 +34,7 @@ module VagrantPlugins
|
|||
|
||||
# If we're checking the boxes globally, then do that.
|
||||
if options[:global]
|
||||
outdated_global
|
||||
outdated_global(download_options)
|
||||
return 0
|
||||
end
|
||||
|
||||
|
@ -37,11 +44,11 @@ module VagrantPlugins
|
|||
box_outdated_refresh: true,
|
||||
box_outdated_success_ui: true,
|
||||
machine: machine,
|
||||
})
|
||||
}.merge(download_options))
|
||||
end
|
||||
end
|
||||
|
||||
def outdated_global
|
||||
def outdated_global(download_options)
|
||||
boxes = {}
|
||||
@env.boxes.all.reverse.each do |name, version, provider|
|
||||
next if boxes[name]
|
||||
|
@ -58,7 +65,7 @@ module VagrantPlugins
|
|||
|
||||
md = nil
|
||||
begin
|
||||
md = box.load_metadata
|
||||
md = box.load_metadata(download_options)
|
||||
rescue Vagrant::Errors::DownloaderError => e
|
||||
@env.ui.error(I18n.t(
|
||||
"vagrant.box_outdated_metadata_error",
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
require 'optparse'
|
||||
|
||||
require_relative 'download_mixins'
|
||||
|
||||
module VagrantPlugins
|
||||
module CommandBox
|
||||
module Command
|
||||
class Update < Vagrant.plugin("2", :command)
|
||||
include DownloadMixins
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
download_options = {}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant box update [options]"
|
||||
|
@ -27,21 +32,23 @@ module VagrantPlugins
|
|||
o.on("--provider PROVIDER", String, "Update box with specific provider") do |p|
|
||||
options[:provider] = p.to_sym
|
||||
end
|
||||
|
||||
build_download_options(o, download_options)
|
||||
end
|
||||
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
|
||||
if options[:box]
|
||||
update_specific(options[:box], options[:provider])
|
||||
update_specific(options[:box], options[:provider], download_options)
|
||||
else
|
||||
update_vms(argv, options[:provider])
|
||||
update_vms(argv, options[:provider], download_options)
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
def update_specific(name, provider)
|
||||
def update_specific(name, provider, download_options)
|
||||
boxes = {}
|
||||
@env.boxes.all.each do |n, v, p|
|
||||
boxes[n] ||= {}
|
||||
|
@ -74,11 +81,11 @@ module VagrantPlugins
|
|||
|
||||
to_update.each do |n, p, v|
|
||||
box = @env.boxes.find(n, p, v)
|
||||
box_update(box, "> #{v}", @env.ui)
|
||||
box_update(box, "> #{v}", @env.ui, download_options)
|
||||
end
|
||||
end
|
||||
|
||||
def update_vms(argv, provider)
|
||||
def update_vms(argv, provider, download_options)
|
||||
with_target_vms(argv, provider: provider) do |machine|
|
||||
if !machine.config.vm.box
|
||||
machine.ui.output(I18n.t(
|
||||
|
@ -95,17 +102,25 @@ module VagrantPlugins
|
|||
|
||||
box = machine.box
|
||||
version = machine.config.vm.box_version
|
||||
box_update(box, version, machine.ui)
|
||||
# Get download options from machine configuration if not specified
|
||||
# on the command line.
|
||||
download_options[:ca_cert] ||= machine.config.vm.box_download_ca_cert
|
||||
download_options[:ca_path] ||= machine.config.vm.box_download_ca_path
|
||||
download_options[:client_cert] ||= machine.config.vm.box_download_client_cert
|
||||
if download_options[:insecure].nil?
|
||||
download_options[:insecure] = machine.config.vm.box_download_insecure
|
||||
end
|
||||
box_update(box, version, machine.ui, download_options)
|
||||
end
|
||||
end
|
||||
|
||||
def box_update(box, version, ui)
|
||||
def box_update(box, version, ui, download_options)
|
||||
ui.output(I18n.t("vagrant.box_update_checking", name: box.name))
|
||||
ui.detail("Latest installed version: #{box.version}")
|
||||
ui.detail("Version constraints: #{version}")
|
||||
ui.detail("Provider: #{box.provider}")
|
||||
|
||||
update = box.has_update?(version)
|
||||
update = box.has_update?(version, download_options: download_options)
|
||||
if !update
|
||||
ui.success(I18n.t(
|
||||
"vagrant.box_up_to_date_single",
|
||||
|
@ -124,6 +139,10 @@ module VagrantPlugins
|
|||
box_provider: update[2].name,
|
||||
box_version: update[1].version,
|
||||
ui: ui,
|
||||
box_client_cert: download_options[:client_cert],
|
||||
box_download_ca_cert: download_options[:ca_cert],
|
||||
box_download_ca_path: download_options[:ca_path],
|
||||
box_download_insecure: download_options[:insecure]
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,6 +19,11 @@ describe VagrantPlugins::CommandBox::Command::Update do
|
|||
let(:action_runner) { double("action_runner") }
|
||||
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
|
||||
|
||||
let(:download_options) { ["--insecure",
|
||||
"--cacert", "foo",
|
||||
"--capath", "bar",
|
||||
"--cert", "baz"] }
|
||||
|
||||
subject { described_class.new(argv, iso_env) }
|
||||
|
||||
before do
|
||||
|
@ -86,6 +91,10 @@ describe VagrantPlugins::CommandBox::Command::Update do
|
|||
expect(opts[:box_url]).to eq(metadata_url.to_s)
|
||||
expect(opts[:box_provider]).to eq("virtualbox")
|
||||
expect(opts[:box_version]).to eq("1.1")
|
||||
expect(opts[:box_download_ca_path]).to be_nil
|
||||
expect(opts[:box_download_ca_cert]).to be_nil
|
||||
expect(opts[:box_client_cert]).to be_nil
|
||||
expect(opts[:box_download_insecure]).to be_nil
|
||||
end
|
||||
|
||||
opts
|
||||
|
@ -158,6 +167,50 @@ describe VagrantPlugins::CommandBox::Command::Update do
|
|||
end
|
||||
end
|
||||
|
||||
context "download options are specified" do
|
||||
let(:argv) { ["--box", "foo" ].concat(download_options) }
|
||||
|
||||
it "passes down download options" do
|
||||
metadata_url.open("w") do |f|
|
||||
f.write(<<-RAW)
|
||||
{
|
||||
"name": "foo",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.0"
|
||||
},
|
||||
{
|
||||
"version": "1.1",
|
||||
"providers": [
|
||||
{
|
||||
"name": "virtualbox",
|
||||
"url": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
RAW
|
||||
end
|
||||
|
||||
action_called = false
|
||||
allow(action_runner).to receive(:run) do |action, opts|
|
||||
if opts[:box_provider]
|
||||
action_called = true
|
||||
expect(opts[:box_download_ca_cert]).to eq("foo")
|
||||
expect(opts[:box_download_ca_path]).to eq("bar")
|
||||
expect(opts[:box_client_cert]).to eq("baz")
|
||||
expect(opts[:box_download_insecure]).to be_true
|
||||
end
|
||||
|
||||
opts
|
||||
end
|
||||
|
||||
subject.execute
|
||||
expect(action_called).to be_true
|
||||
end
|
||||
end
|
||||
|
||||
context "with a box that doesn't exist" do
|
||||
let(:argv) { ["--box", "nope"] }
|
||||
|
||||
|
@ -192,7 +245,10 @@ describe VagrantPlugins::CommandBox::Command::Update do
|
|||
it "doesn't update boxes if they're up-to-date" do
|
||||
machine.stub(box: box)
|
||||
expect(box).to receive(:has_update?).
|
||||
with(machine.config.vm.box_version).
|
||||
with(machine.config.vm.box_version,
|
||||
{download_options:
|
||||
{ca_cert: nil, ca_path: nil, client_cert: nil,
|
||||
insecure: false}}).
|
||||
and_return(nil)
|
||||
|
||||
expect(action_runner).to receive(:run).never
|
||||
|
@ -200,41 +256,101 @@ describe VagrantPlugins::CommandBox::Command::Update do
|
|||
subject.execute
|
||||
end
|
||||
|
||||
it "updates boxes if they have an update" do
|
||||
md = Vagrant::BoxMetadata.new(StringIO.new(<<-RAW))
|
||||
{
|
||||
"name": "foo",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.0"
|
||||
},
|
||||
{
|
||||
"version": "1.1",
|
||||
"providers": [
|
||||
{
|
||||
"name": "virtualbox",
|
||||
"url": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
RAW
|
||||
|
||||
machine.stub(box: box)
|
||||
expect(box).to receive(:has_update?).
|
||||
with(machine.config.vm.box_version).
|
||||
and_return([md, md.version("1.1"), md.version("1.1").provider("virtualbox")])
|
||||
|
||||
expect(action_runner).to receive(:run).with { |action, opts|
|
||||
expect(opts[:box_url]).to eq(box.metadata_url)
|
||||
expect(opts[:box_provider]).to eq("virtualbox")
|
||||
expect(opts[:box_version]).to eq("1.1")
|
||||
expect(opts[:ui]).to equal(machine.ui)
|
||||
true
|
||||
context "boxes have an update" do
|
||||
let(:md) {
|
||||
md = Vagrant::BoxMetadata.new(StringIO.new(<<-RAW))
|
||||
{
|
||||
"name": "foo",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.0"
|
||||
},
|
||||
{
|
||||
"version": "1.1",
|
||||
"providers": [
|
||||
{
|
||||
"name": "virtualbox",
|
||||
"url": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
RAW
|
||||
}
|
||||
|
||||
subject.execute
|
||||
before { machine.stub(box: box) }
|
||||
|
||||
it "updates boxes" do
|
||||
expect(box).to receive(:has_update?).
|
||||
with(machine.config.vm.box_version,
|
||||
{download_options:
|
||||
{ca_cert: nil, ca_path: nil, client_cert: nil,
|
||||
insecure: false}}).
|
||||
and_return([md, md.version("1.1"), md.version("1.1").provider("virtualbox")])
|
||||
|
||||
expect(action_runner).to receive(:run).with { |action, opts|
|
||||
expect(opts[:box_url]).to eq(box.metadata_url)
|
||||
expect(opts[:box_provider]).to eq("virtualbox")
|
||||
expect(opts[:box_version]).to eq("1.1")
|
||||
expect(opts[:ui]).to equal(machine.ui)
|
||||
true
|
||||
}
|
||||
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "machine has download options" do
|
||||
before do
|
||||
machine.config.vm.box_download_ca_cert = "oof"
|
||||
machine.config.vm.box_download_ca_path = "rab"
|
||||
machine.config.vm.box_download_client_cert = "zab"
|
||||
machine.config.vm.box_download_insecure = false
|
||||
end
|
||||
|
||||
it "uses download options from machine" do
|
||||
expect(box).to receive(:has_update?).
|
||||
with(machine.config.vm.box_version,
|
||||
{download_options:
|
||||
{ca_cert: "oof", ca_path: "rab", client_cert: "zab",
|
||||
insecure: false}}).
|
||||
and_return([md, md.version("1.1"), md.version("1.1").provider("virtualbox")])
|
||||
|
||||
expect(action_runner).to receive(:run).with { |action, opts|
|
||||
expect(opts[:box_download_ca_cert]).to eq("oof")
|
||||
expect(opts[:box_download_ca_path]).to eq("rab")
|
||||
expect(opts[:box_client_cert]).to eq("zab")
|
||||
expect(opts[:box_download_insecure]).to be_false
|
||||
true
|
||||
}
|
||||
|
||||
subject.execute
|
||||
end
|
||||
|
||||
context "download options are specified on the command line" do
|
||||
let(:argv) { download_options }
|
||||
|
||||
it "overrides download options from machine with options from CLI" do
|
||||
expect(box).to receive(:has_update?).
|
||||
with(machine.config.vm.box_version,
|
||||
{download_options:
|
||||
{ca_cert: "foo", ca_path: "bar", client_cert: "baz",
|
||||
insecure: true}}).
|
||||
and_return([md, md.version("1.1"),
|
||||
md.version("1.1").provider("virtualbox")])
|
||||
|
||||
expect(action_runner).to receive(:run).with { |action, opts|
|
||||
expect(opts[:box_download_ca_cert]).to eq("foo")
|
||||
expect(opts[:box_download_ca_path]).to eq("bar")
|
||||
expect(opts[:box_client_cert]).to eq("baz")
|
||||
expect(opts[:box_download_insecure]).to be_true
|
||||
true
|
||||
}
|
||||
|
||||
subject.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -117,7 +117,9 @@ describe Vagrant::Action::Builtin::BoxCheckOutdated do
|
|||
}
|
||||
RAW
|
||||
|
||||
expect(box).to receive(:has_update?).with(machine.config.vm.box_version).
|
||||
expect(box).to receive(:has_update?).with(machine.config.vm.box_version,
|
||||
{download_options:
|
||||
{ca_cert: nil, ca_path: nil, client_cert: nil, insecure: false}}).
|
||||
and_return([md, md.version("1.1"), md.version("1.1").provider("virtualbox")])
|
||||
|
||||
expect(app).to receive(:call).with(env).once
|
||||
|
@ -180,5 +182,38 @@ describe Vagrant::Action::Builtin::BoxCheckOutdated do
|
|||
|
||||
expect { subject.call(env) }.to_not raise_error
|
||||
end
|
||||
|
||||
context "when machine download options are specified" do
|
||||
before do
|
||||
machine.config.vm.box_download_ca_cert = "foo"
|
||||
machine.config.vm.box_download_ca_path = "bar"
|
||||
machine.config.vm.box_download_client_cert = "baz"
|
||||
machine.config.vm.box_download_insecure = true
|
||||
end
|
||||
|
||||
it "uses download options from machine" do
|
||||
expect(box).to receive(:has_update?).with(machine.config.vm.box_version,
|
||||
{download_options:
|
||||
{ca_cert: "foo", ca_path: "bar", client_cert: "baz", insecure: true}})
|
||||
|
||||
expect(app).to receive(:call).with(env).once
|
||||
|
||||
subject.call(env)
|
||||
end
|
||||
|
||||
it "overrides download options from machine with options from env" do
|
||||
expect(box).to receive(:has_update?).with(machine.config.vm.box_version,
|
||||
{download_options:
|
||||
{ca_cert: "oof", ca_path: "rab", client_cert: "zab", insecure: false}})
|
||||
|
||||
env[:ca_cert] = "oof"
|
||||
env[:ca_path] = "rab"
|
||||
env[:client_cert] = "zab"
|
||||
env[:insecure] = false
|
||||
expect(app).to receive(:call).with(env).once
|
||||
|
||||
subject.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue