
My original thinking was that if you're using the exchange name to separate two instances of the applications (so their queues don't collide) then the exchange name is pretty key to transport configuration. In fact, it's really a virtual host that you'd use for this (at least in the case of rabbit and qpid). Also, Nova's cells code has already moved ahead with the assumption that the path specifies a virtual host, so it'd only make sense to deviate from that if there was a really good reason to. Change-Id: Ic8b5dc3538b6b17afec524047acc2efa76366377
112 lines
3.2 KiB
Python
112 lines
3.2 KiB
Python
|
|
# Copyright 2013 Red Hat, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import urlparse
|
|
|
|
|
|
def parse_url(url):
|
|
"""Parse an url.
|
|
|
|
Assuming a URL takes the form of:
|
|
|
|
transport://user:pass@host1:port[,hostN:portN]/virtual_host[?opt=val]
|
|
|
|
then parse the URL and return a dictionary with the following structure:
|
|
|
|
{
|
|
'virtual_host': 'virtual_host',
|
|
'transport': 'transport',
|
|
'hosts': [{'username': 'username',
|
|
'password': 'password'
|
|
'host': 'host1:port1'},
|
|
...],
|
|
'parameters': {'option': 'value'}
|
|
}
|
|
|
|
Netloc is parsed following the sequence bellow:
|
|
|
|
* It is first splitted by ',' in order to support multiple hosts
|
|
* The last parsed username and password will be propagated to the rest
|
|
of hotsts specified:
|
|
|
|
user:passwd@host1:port1,host2:port2
|
|
|
|
[
|
|
{"username": "user", "password": "passwd", "host": "host1:port1"},
|
|
{"username": "user", "password": "passwd", "host": "host2:port2"}
|
|
]
|
|
|
|
* In order to avoid the above propagation, it is possible to alter the
|
|
order in which the hosts are specified or specify a set of fake credentials
|
|
using ",:@host2:port2"
|
|
|
|
|
|
user:passwd@host1:port1,:@host2:port2
|
|
|
|
[
|
|
{"username": "user", "password": "passwd", "host": "host1:port1"},
|
|
{"username": "", "password": "", "host": "host2:port2"}
|
|
]
|
|
|
|
:param url: The URL to parse
|
|
:type url: str
|
|
:returns: A dictionary with the parsed data
|
|
"""
|
|
if not url:
|
|
return None
|
|
|
|
# NOTE(flaper87): Not PY3K compliant
|
|
if not isinstance(url, basestring):
|
|
raise TypeError("Wrong URL type")
|
|
|
|
url = urlparse.urlparse(url)
|
|
|
|
parsed = dict(transport=url.scheme)
|
|
|
|
virtual_host = None
|
|
if url.path.startswith('/'):
|
|
virtual_host = url.path[1:]
|
|
parsed["virtual_host"] = virtual_host
|
|
|
|
# NOTE(flaper87): Parse netloc.
|
|
hosts = []
|
|
username = password = ''
|
|
for host in url.netloc.split(","):
|
|
if not host:
|
|
continue
|
|
|
|
if "@" in host:
|
|
username, host = host.split("@", 1)
|
|
if ":" in username:
|
|
username, password = username.split(":", 1)
|
|
|
|
hosts.append({
|
|
"host": host,
|
|
"username": username,
|
|
"password": password,
|
|
})
|
|
|
|
parsed["hosts"] = hosts
|
|
|
|
parameters = {}
|
|
if url.query:
|
|
# NOTE(flaper87): This returns a dict with
|
|
# key -> [value], those values need to be
|
|
# normalized
|
|
parameters = urlparse.parse_qs(url.query)
|
|
parsed['parameters'] = parameters
|
|
|
|
return parsed
|