In the bug, a user tried setting a devstack password with a "@" in it.
As it turns out, sqlalchmey turns the connection-string into a
sqlalchemy.engine.url.URL object [1] which returns a RFC1738 quoted
string.
However, alembic's set_main_option [2] uses python
string-interpolation which interprets '%' characters. This means you
end up with an interpolation traceback when using any quoted character
(':@/') in a user/password (more likely password).
Avoid this by ensuring the URL is safe for python interpolation in
set_main_option by replacing '%' -> '%%'.
I convinced myself this is safe because sqlalchemy correctly parses
the quoted and unquoted versions just the same
---
>>> str(sqlalchemy.engine.url.make_url('mysql+pymysql://foo:crazy:@/pw@/moo'))
'mysql+pymysql://foo:crazy%3A%40%2Fpw@/moo'
>>> str(sqlalchemy.engine.url.make_url('mysql+pymysql://foo:crazy%3A%40%2Fpw@/moo'))
'mysql+pymysql://foo:crazy%3A%40%2Fpw@/moo'
---
A test is added
[1] https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/engine/url.py
[2] http://alembic.zzzcomputing.com/en/latest/api/config.html#alembic.config.Config.set_main_option
Change-Id: I3ef7e3e539e35ce040573f2044ab6eb3c990200a
Closes-Bug: #1695299