Add `vagrant port` command

This commit is contained in:
Seth Vargo 2015-11-24 11:08:30 -05:00
parent 4ebf0252a4
commit 063f60e593
3 changed files with 186 additions and 0 deletions

View File

@ -0,0 +1,71 @@
require "optparse"
module VagrantPlugins
module CommandPort
class Command < Vagrant.plugin("2", :command)
def self.synopsis
"displays information about guest port mappings"
end
# @todo support multiple strategies if requested by the community
def execute
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant port [options] [name]"
o.separator ""
o.separator "Options:"
o.separator ""
o.on("--machine-readable", "Display machine-readable output")
end
# Parse the options
argv = parse_options(opts)
return if !argv
@logger.debug("Port command: #{argv.inspect}")
with_target_vms(argv, single_target: true) do |vm|
vm.action_raw(:config_validate,
Vagrant::Action::Builtin::ConfigValidate)
if vm.state.id != :running
@env.ui.error "not running - make this a better error or use the middleware"
return 1
end
# This only works for vbox? should it be everywhere?
# vm.action_raw(:check_running,
# Vagrant::Action::Builtin::CheckRunning)
if !vm.provider.capability?(:forwarded_ports)
@env.ui.error <<-EOH.strip
The #{vm.provider_name} provider does not support listing forwarded ports. This
is most likely a limitation of the provider and not a bug in Vagrant. If you
believe this is a bug in Vagrant, please search existing issues before opening
a new one.
EOH
return 1
end
ports = vm.provider.capability(:forwarded_ports)
if ports.empty?
@env.ui.info("The machine has no configured forwarded ports")
return 0
end
@env.ui.info <<-EOH
The forwarded ports for the machine are listed below. Please note that these
values may differ from values configured in the Vagrantfile if the provider
supports automatic port collision detection and resolution.
EOH
ports.each do |guest, host|
@env.ui.info("#{guest.to_s.rjust(6)} (guest) => #{host} (host)")
@env.ui.machine("forwarded_port", guest, host, target: vm.name.to_s)
end
end
0
end
end
end
end

View File

@ -0,0 +1,17 @@
require "vagrant"
module VagrantPlugins
module CommandPort
class Plugin < Vagrant.plugin("2")
name "port command"
description <<-DESC
The `port` command displays guest port mappings.
DESC
command("port") do
require File.expand_path("../command", __FILE__)
Command
end
end
end
end

View File

@ -0,0 +1,98 @@
require File.expand_path("../../../../base", __FILE__)
require Vagrant.source_root.join("plugins/commands/port/command")
describe VagrantPlugins::CommandPort::Command do
include_context "unit"
include_context "command plugin helpers"
let(:iso_env) { isolated_environment }
let(:env) do
iso_env.vagrantfile(<<-VF)
Vagrant.configure("2") do |config|
config.vm.box = "hashicorp/precise64"
end
VF
iso_env.create_vagrant_env
end
let(:argv) { [] }
let(:pushes) { {} }
let(:state) { double(:state, id: :running) }
let(:machine) { env.machine(env.machine_names[0], :dummy) }
subject { described_class.new(argv, env) }
before do
allow(machine).to receive(:state).and_return(state)
allow(subject).to receive(:with_target_vms) { |&block| block.call(machine) }
end
describe "#execute" do
it "validates the configuration" do
iso_env.vagrantfile <<-EOH
Vagrant.configure("2") do |config|
config.vm.box = "hashicorp/precise64"
config.push.define "noop" do |push|
push.bad = "ham"
end
end
EOH
subject = described_class.new(argv, iso_env.create_vagrant_env)
expect { subject.execute }.to raise_error(Vagrant::Errors::ConfigInvalid) { |err|
expect(err.message).to include("The following settings shouldn't exist: bad")
}
end
it "ensures the vm is running" do
allow(state).to receive(:id).and_return(:stopped)
expect(env.ui).to receive(:error).with { |message, _|
expect(message).to include("make this a better error")
}
expect(subject.execute).to eq(1)
end
it "shows a friendly error when the capability is not supported" do
allow(machine.provider).to receive(:capability?).and_return(false)
expect(env.ui).to receive(:error).with { |message, _|
expect(message).to include("does not support listing forwarded ports")
}
expect(subject.execute).to eq(1)
end
it "returns a friendly message when there are no forwarded ports" do
allow(machine.provider).to receive(:capability?).and_return(true)
allow(machine.provider).to receive(:capability).with(:forwarded_ports)
.and_return([])
expect(env.ui).to receive(:info).with { |message, _|
expect(message).to include("has no configured forwarded ports")
}
expect(subject.execute).to eq(0)
end
it "returns the list of ports" do
allow(machine.provider).to receive(:capability?).and_return(true)
allow(machine.provider).to receive(:capability).with(:forwarded_ports)
.and_return([[2222,22], [1111,11]])
output = ""
allow(env.ui).to receive(:info) do |data|
output << data
end
expect(subject.execute).to eq(0)
expect(output).to include("forwarded ports for the machine")
expect(output).to include("2222 (guest) => 22 (host)")
expect(output).to include("1111 (guest) => 11 (host)")
end
end
end