Skip to content

Commit f89fc1e

Browse files
committed
Fix address parsing for server ssh command
There seem to be three formats for the server address field and the old code only supported the old format. This code adds a parser for all three formats. Change-Id: I7f12d2c69ff70556907ea6f31a0e0bba91b68b49 Closes-Bug: #1469843
1 parent f07f716 commit f89fc1e

2 files changed

Lines changed: 91 additions & 15 deletions

File tree

openstackclient/compute/v2/server.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,39 @@ def _format_servers_list_networks(networks):
5555
return '; '.join(output)
5656

5757

58+
def _get_ip_address(addresses, address_type, ip_address_family):
59+
# Old style addresses
60+
if address_type in addresses:
61+
for addy in addresses[address_type]:
62+
if int(addy['version']) in ip_address_family:
63+
return addy['addr']
64+
65+
# New style addresses
66+
new_address_type = address_type
67+
if address_type == 'public':
68+
new_address_type = 'floating'
69+
if address_type == 'private':
70+
new_address_type = 'fixed'
71+
for network in addresses:
72+
for addy in addresses[network]:
73+
# Case where it is list of strings
74+
if isinstance(addy, six.string_types):
75+
if new_address_type == 'fixed':
76+
return addresses[network][0]
77+
else:
78+
return addresses[network][-1]
79+
# Case where it is a dict
80+
if 'OS-EXT-IPS:type' not in addy:
81+
continue
82+
if addy['OS-EXT-IPS:type'] == new_address_type:
83+
if int(addy['version']) in ip_address_family:
84+
return addy['addr']
85+
raise exceptions.CommandError(
86+
"ERROR: No %s IP version %s address found" %
87+
(address_type, ip_address_family)
88+
)
89+
90+
5891
def _prep_server_detail(compute_client, server):
5992
"""Prepare the detailed server dict for printing
6093
@@ -1283,6 +1316,7 @@ def get_parser(self, prog_name):
12831316
)
12841317
parser.add_argument(
12851318
'-l',
1319+
dest='login',
12861320
metavar='<login-name>',
12871321
help=argparse.SUPPRESS,
12881322
)
@@ -1381,13 +1415,6 @@ def take_action(self, parsed_args):
13811415
# Build the command
13821416
cmd = "ssh"
13831417

1384-
# Look for address type
1385-
if parsed_args.address_type:
1386-
address_type = parsed_args.address_type
1387-
if address_type not in server.addresses:
1388-
raise SystemExit("ERROR: No %s IP address found" % address_type)
1389-
1390-
# Set up desired address family
13911418
ip_address_family = [4, 6]
13921419
if parsed_args.ipv4:
13931420
ip_address_family = [4]
@@ -1396,14 +1423,6 @@ def take_action(self, parsed_args):
13961423
ip_address_family = [6]
13971424
cmd += " -6"
13981425

1399-
# Grab the first matching IP address
1400-
ip_address = None
1401-
for addr in server.addresses[address_type]:
1402-
if int(addr['version']) in ip_address_family:
1403-
ip_address = addr['addr']
1404-
if not ip_address:
1405-
raise SystemExit("ERROR: No IP address found")
1406-
14071426
if parsed_args.port:
14081427
cmd += " -p %d" % parsed_args.port
14091428
if parsed_args.identity:
@@ -1418,6 +1437,9 @@ def take_action(self, parsed_args):
14181437
cmd += " -v"
14191438

14201439
cmd += " %s@%s"
1440+
ip_address = _get_ip_address(server.addresses,
1441+
parsed_args.address_type,
1442+
ip_address_family)
14211443
self.log.debug("ssh command: %s", (cmd % (login, ip_address)))
14221444
os.system(cmd % (login, ip_address))
14231445

openstackclient/tests/compute/v2/test_server.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
import copy
1717
import mock
18+
import testtools
1819

20+
from openstackclient.common import exceptions
1921
from openstackclient.common import utils as common_utils
2022
from openstackclient.compute.v2 import server
2123
from openstackclient.tests.compute.v2 import fakes as compute_fakes
@@ -580,3 +582,55 @@ def test_server_resize_revert(self):
580582
self.servers_mock.revert_resize.assert_called_with(
581583
self.servers_get_return_value,
582584
)
585+
586+
587+
class TestServerGeneral(testtools.TestCase):
588+
OLD = {
589+
'private': [
590+
{
591+
'addr': '192.168.0.3',
592+
'version': 4,
593+
},
594+
]
595+
}
596+
NEW = {
597+
'foo': [
598+
{
599+
'OS-EXT-IPS-MAC:mac_addr': 'fa:16:3e:93:b3:01',
600+
'version': 4,
601+
'addr': '10.10.1.2',
602+
'OS-EXT-IPS:type': 'fixed',
603+
},
604+
{
605+
'OS-EXT-IPS-MAC:mac_addr': 'fa:16:3e:93:b3:02',
606+
'version': 6,
607+
'addr': '0:0:0:0:0:ffff:a0a:103',
608+
'OS-EXT-IPS:type': 'floating',
609+
},
610+
]
611+
}
612+
ODD = {'jenkins': ['10.3.3.18', '124.12.125.4']}
613+
614+
def test_get_ip_address(self):
615+
self.assertEqual("192.168.0.3",
616+
server._get_ip_address(self.OLD, 'private', [4, 6]))
617+
self.assertEqual("10.10.1.2",
618+
server._get_ip_address(self.NEW, 'fixed', [4, 6]))
619+
self.assertEqual("10.10.1.2",
620+
server._get_ip_address(self.NEW, 'private', [4, 6]))
621+
self.assertEqual("0:0:0:0:0:ffff:a0a:103",
622+
server._get_ip_address(self.NEW, 'public', [6]))
623+
self.assertEqual("0:0:0:0:0:ffff:a0a:103",
624+
server._get_ip_address(self.NEW, 'floating', [6]))
625+
self.assertEqual("124.12.125.4",
626+
server._get_ip_address(self.ODD, 'public', [4, 6]))
627+
self.assertEqual("10.3.3.18",
628+
server._get_ip_address(self.ODD, 'private', [4, 6]))
629+
self.assertRaises(exceptions.CommandError,
630+
server._get_ip_address, self.NEW, 'public', [4])
631+
self.assertRaises(exceptions.CommandError,
632+
server._get_ip_address, self.NEW, 'admin', [4])
633+
self.assertRaises(exceptions.CommandError,
634+
server._get_ip_address, self.OLD, 'public', [4, 6])
635+
self.assertRaises(exceptions.CommandError,
636+
server._get_ip_address, self.OLD, 'private', [6])

0 commit comments

Comments
 (0)