Skip to content

Commit

Permalink
Enhance IP resolution for SSH
Browse files Browse the repository at this point in the history
* Implement network preference (fix ggiamarchi#194)
* Always read IP from nova even if a specific floating
  IP is set in the provider's attribute 'floating_ip'
  • Loading branch information
ggiamarchi authored and Sharpie committed Jul 31, 2016
1 parent 4df278e commit c17d097
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 26 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ end

* `floating_ip_pool_always_allocate` - if set to true, vagrant will always allocate floating ip instead of trying to reuse unassigned ones

__N.B.__
> If the instance have a floating IP, this IP will be used to SSH into the instance.
#### Networks

* `networks` - Network list the server must be connected on. Can be omitted if only one private network exists
Expand Down Expand Up @@ -176,6 +179,10 @@ config.vm.provider :openstack do |os|
end
```

__N.B.__
> If the instance does not have a floating IP, the IP of the
> first network in the list will be used to SSH into the instance
#### Volumes

* `volumes` - Volume list that have to be attached to the server. You can provide volume id or name. However, in Openstack
Expand Down
17 changes: 11 additions & 6 deletions source/lib/vagrant-openstack-provider/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ def initialize
end

def get_ip_address(env)
return env[:machine].provider_config.floating_ip unless env[:machine].provider_config.floating_ip.nil?
details = env[:openstack_client].nova.get_server_details(env, env[:machine].id)
details['addresses'].each do |network|
network[1].each do |network_detail|
addresses = env[:openstack_client].nova.get_server_details(env, env[:machine].id)['addresses']
addresses.each do |_, network|
network.each do |network_detail|
return network_detail['addr'] if network_detail['OS-EXT-IPS:type'] == 'floating'
end
end
return details['addresses'].first[1][0]['addr'] if details['addresses'].size >= 1 && details['addresses'].first[1].size >= 1
fail Errors::UnableToResolveIP
fail Errors::UnableToResolveIP if addresses.size == 0
if addresses.size == 1
net_addresses = addresses.first[1]
else
net_addresses = addresses[env[:machine].provider_config.networks[0]]
end
fail Errors::UnableToResolveIP if net_addresses.size == 0
net_addresses[0]['addr']
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,17 @@

let(:nova) do
double('nova').tap do |nova|
nova.stub(:get_all_floating_ips).with(anything) do
[FloatingIP.new('80.81.82.83', 'pool-1', nil), FloatingIP.new('30.31.32.33', 'pool-2', '1234')]
nova.stub(:get_server_details).with(env, '1234') do
{
'addresses' => {
'net' => [
{
'addr' => '80.80.80.80',
'OS-EXT-IPS:type' => 'floating'
}
]
}
}
end
end
end
Expand Down Expand Up @@ -136,7 +145,19 @@
config.stub(:floating_ip) { '80.80.80.80' }
config.stub(:keypair_name) { nil }
config.stub(:public_key_path) { nil }
nova.stub(:get_server_details) { { 'key_name' => 'my_keypair_name' } }
nova.stub(:get_server_details) do
{
'key_name' => 'my_keypair_name',
'addresses' => {
'net' => [
{
'addr' => '80.80.80.80',
'OS-EXT-IPS:type' => 'floating'
}
]
}
}
end
expect(nova).to receive(:get_server_details).with(env, '1234')
@action.read_ssh_info(env).should eq(
host: '80.80.80.80',
Expand Down
34 changes: 17 additions & 17 deletions source/spec/vagrant-openstack-provider/utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
nova.stub(:get_server_details).with(env, '1234id') do
{
'addresses' => {
'toto' => [{
'net' => [{
'addr' => '13.13.13.13'
}, {
'addr' => '12.12.12.12',
Expand All @@ -55,13 +55,13 @@
end

context 'without floating ip in nova details' do
context 'with on single ip in nova details' do
context 'with a single ip in nova details' do
it 'returns the single ip' do
config.stub(:floating_ip) { nil }
nova.stub(:get_server_details).with(env, '1234id') do
{
'addresses' => {
'toto' => [{
'net' => [{
'addr' => '13.13.13.13',
'OS-EXT-IPS:type' => 'fixed'
}]
Expand All @@ -73,21 +73,28 @@
end

context 'with multiple ips in nova details' do
it 'fails' do
it 'return the one corresponding to the first network in the Vagrantfile' do
config.stub(:floating_ip) { nil }
config.stub(:networks) { %w(net-2 net-1 net-3) }
nova.stub(:get_server_details).with(env, '1234id') do
{
'addresses' => {
'toto' => [{
'addr' => '13.13.13.13'
}, {
'net-1' => [{
'addr' => '11.11.11.11',
'OS-EXT-IPS:type' => 'fixed'
}],
'net-2' => [{
'addr' => '12.12.12.12',
'OS-EXT-IPS:type' => 'private'
'OS-EXT-IPS:type' => 'fixed'
}],
'net-3' => [{
'addr' => '13.13.13.13',
'OS-EXT-IPS:type' => 'fixed'
}]
}
}
end
expect(@action.get_ip_address(env)).to eq('13.13.13.13')
expect(@action.get_ip_address(env)).to eq('12.12.12.12')
end
end

Expand All @@ -97,7 +104,7 @@
nova.stub(:get_server_details).with(env, '1234id') do
{
'addresses' => {
'toto' => []
'net' => []
}
}
end
Expand All @@ -118,12 +125,5 @@
end
end
end

context 'with config.floating_ip' do
it 'returns floating_ip' do
config.stub(:floating_ip) { '1.2.3.4' }
@action.get_ip_address(env).should eq('1.2.3.4')
end
end
end
end

0 comments on commit c17d097

Please sign in to comment.