Fix GET for conductors with a port or IPv6 address
Our validation does not expect a host-port pair, not having colons in the hostname. We don't need to verify all possible cases: we will return 404 for a conductor that does not exist. Change-Id: Iea65575f540a89a0de280fb730e430647c5733dc
This commit is contained in:
parent
dcea5f5a1d
commit
e67f716063
@ -102,9 +102,9 @@ class ConductorsController(rest.RestController):
|
||||
|
||||
@METRICS.timer('ConductorsController.get_all')
|
||||
@method.expose()
|
||||
@args.validate(marker=args.name, limit=args.integer, sort_key=args.string,
|
||||
sort_dir=args.string, fields=args.string_list,
|
||||
detail=args.boolean)
|
||||
@args.validate(marker=args.host_port, limit=args.integer,
|
||||
sort_key=args.string, sort_dir=args.string,
|
||||
fields=args.string_list, detail=args.boolean)
|
||||
def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc',
|
||||
fields=None, detail=None):
|
||||
"""Retrieve a list of conductors.
|
||||
@ -139,7 +139,7 @@ class ConductorsController(rest.RestController):
|
||||
|
||||
@METRICS.timer('ConductorsController.get_one')
|
||||
@method.expose()
|
||||
@args.validate(hostname=args.name, fields=args.string_list)
|
||||
@args.validate(hostname=args.host_port, fields=args.string_list)
|
||||
def get_one(self, hostname, fields=None):
|
||||
"""Retrieve information about the given conductor.
|
||||
|
||||
|
@ -14,6 +14,7 @@ import functools
|
||||
import inspect
|
||||
|
||||
import jsonschema
|
||||
from oslo_utils import netutils
|
||||
from oslo_utils import strutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
@ -88,6 +89,18 @@ def name(name, value):
|
||||
return value
|
||||
|
||||
|
||||
def host_port(name, value):
|
||||
if value is None:
|
||||
return
|
||||
try:
|
||||
host, port = netutils.parse_host_port(value)
|
||||
except (ValueError, TypeError) as exc:
|
||||
raise exception.InvalidParameterValue(f'{name}: {exc}')
|
||||
if not host:
|
||||
raise exception.InvalidParameterValue(_('Missing host in %s') % name)
|
||||
return value
|
||||
|
||||
|
||||
def uuid_or_name(name, value):
|
||||
"""Validate that the value is a UUID or logical name
|
||||
|
||||
|
@ -85,6 +85,19 @@ class TestListConductors(test_api_base.BaseApiTest):
|
||||
self.assertEqual(data['hostname'], 'rocky.rocks')
|
||||
self.assertTrue(data['alive'])
|
||||
|
||||
def test_get_one_with_port_and_v6(self):
|
||||
obj_utils.create_test_conductor(self.context, hostname='[::1]:8090')
|
||||
data = self.get_json(
|
||||
'/conductors/[::1]:8090',
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertIn('hostname', data)
|
||||
self.assertIn('drivers', data)
|
||||
self.assertIn('conductor_group', data)
|
||||
self.assertIn('alive', data)
|
||||
self.assertIn('drivers', data)
|
||||
self.assertEqual(data['hostname'], '[::1]:8090')
|
||||
self.assertTrue(data['alive'])
|
||||
|
||||
@mock.patch.object(timeutils, 'utcnow', autospec=True)
|
||||
def test_get_one_conductor_offline(self, mock_utcnow):
|
||||
self.config(heartbeat_timeout=10, group='conductor')
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes getting details of a conductor if it uses a non-standard JSON RPC
|
||||
port or an IPv6 address as the name, e.g.
|
||||
``GET /v1/conductors/[2001:db8::1]:8090``. Previously, it would result in
|
||||
a HTTP error 400.
|
Loading…
Reference in New Issue
Block a user