<div dir="ltr">Hi there!<div><br></div><div>The most recent version of the CORS middleware (~2.4) no longer requires the use of Oslo.config, and supports pastedeploy. While using oslo.config provides far better features - such as multiple origins - it doesn't prevent you from using it in the paste pipeline. The documentation has been updated to reflect this.</div><div><br></div><div>As for the "How do we proceed" question, I feel your question can be better asked as: Do we support developers, or do we support operators? The developer stance is that of architectural purity, of minimizing dependencies, and of staying as true to default as possible. The Operator's stance is that of simplified configuration, performance, good documentation, and reliability.</div><div><br></div><div>I fall on the operators side, and as a result feel that we should be using oslo.config for everything. One single configuration method across services, consistent naming conventions, autogenerated with sane options, with tooling and testing that makes it reliable. Special Snowflakes really just add cognitive friction, documentation overhead, and noise.</div><div><br></div><div>I'm not saying oslo is perfect. I'm not saying that how oslo is used is always correct. But we're fixing it, and consistency, in my mind, always trumps ideology.</div><div><br></div><div>Michael</div><div><br></div><div class="gmail_quote"><div dir="ltr">On Thu, Aug 6, 2015 at 9:02 AM Mehdi Abaakouk <<a href="mailto:sileht@sileht.net" target="_blank">sileht@sileht.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I want to share with you some problems I have recently encountered with<br>
openstack middlewares and oslo.config.<br>
<br>
The issues<br>
----------<br>
<br>
In project Gnocchi, I would use oslo.middleware.cors, I have expected to<br>
just put the name of the middleware to the wsgi pipeline, but I can't.<br>
The middlewares only works if you pass the oslo_config.cfg.ConfigOpts()<br>
object or via 'paste-deploy'... Gnocchi doesn't use paste-deploy, so<br>
I have to modify the code to load it...<br>
(For the keystonemiddleware, Gnocchi already have a special<br>
handling/hack to load it [1] and [2]).<br>
I don't want to write the same hack for each openstack middlewares.<br>
<br>
<br>
In project Aodh (ceilometer-alarm), we recently got an issue with<br>
keystonemiddleware since we remove the usage of the global object<br>
oslo_config.cfg.CONF. The middleware doesn't load its options from the<br>
config file of aodh anymore. Our authentication is broken.<br>
We can still pass them through paste-deploy configuration but this looks<br>
a method of the past. I still don't want to write a hack for each<br>
openstack middlewares.<br>
<br>
<br>
Then I have digged into other middlewares and applications to see how<br>
they handle their conf.<br>
<br>
oslo_middlewarre.sizelimit and oslo_middlewarre.ssl take options only<br>
via the global oslo_config.cfg.CONF. So they are unusable for application<br>
that doesn't use this global object.<br>
<br>
oslo_middleware.healthcheck take options as dict like any other python<br>
middleware. This is suitable for 'paste-deploy'. But doesn't allow<br>
configuration via oslo.config, doesn't have a strong config options<br>
type checking and co.<br>
<br>
Zaqar seems got same kind of issue about keystonemiddleware, and just<br>
write a hack to workaround the issue (monkeypatch the cfg.CONF of<br>
keystonemiddleware with their local version of the object [3] and then<br>
transform the loaded options into a dict to pass them via the legacy<br>
middleware dict options [4]) .<br>
<br>
Most applications, just still use the global object for the<br>
configuration and don't, yet, see those issues.<br>
<br>
<br>
All of that is really not consistent.<br>
<br>
This is confusing for developer to have some middlewares that need pre-setup,<br>
enforce them to rely on global python object, and some others not.<br>
This is confusing for deployer their can't do the configuration of<br>
middlewares in the same way for each middlewares and each projects.<br>
<br>
But keystonemiddleware, oslo.middleware.cors,... are supposed to be wsgi<br>
middlewares, something that is independant of the app.<br>
And this is not really the case.<br>
<br>
>From my point of view and what wsgi looks like generally in python, the<br>
middleware object should be just MyMiddleware(app, options_as_dict),<br>
if the middleware want to rely to another configuration system it should<br>
do the setup/initialisation itself.<br>
<br>
<br>
<br>
So, how to solve that ?<br>
------------------------<br>
<br>
Do you agree:<br>
<br>
* all openstack middlewares should load their options with oslo.config ?<br>
this permits type checking and all other features it provides, it's cool :)<br>
configuration in paste-deploy conf is thing of past<br>
<br>
* we must support local AND global oslo.config object ?<br>
This is an application choice not something enforced by middleware.<br>
The deployer experience should be the same in both case.<br>
<br>
* the middleware must be responsible of the section name in the oslo.config ?<br>
Gnocchi/Zaqar hack have to hardcode the section name in their code,<br>
this doesn't looks good.<br>
<br>
* we must support legacy python signature for WSGI object,<br>
MyMiddleware(app, options_as_dict) ? To be able to use paste for<br>
application/deployer that want it and not break already deployed things.<br>
<br>
<br>
I really think all our middlewares should be consistent:<br>
<br>
* to be usable by all applications without enforcing them to write crap around them.<br>
* and to made the deployer life easier.<br>
<br>
<br>
Possible solution:<br>
------------------<br>
<br>
I have already started to work on something that do all of that for all<br>
middlewares [5], [6]<br>
<br>
The idea is, the middleware should create a oslo_config.cfg.ConfigOpts()<br>
(instead of rely on the global one) and load the configuration file of the<br>
application in. oslo.config will discover the file location just with the<br>
name of application as usual.<br>
<br>
So the middleware can now be loaded like this:<br>
<br>
code example:<br>
<br>
app = MyMiddleware(app, {"oslo_config_project": "aodh"})<br>
<br>
paste-deploy example:<br>
<br>
[filter:foobar]<br>
paste.filter_factory = foobar:MyMiddleware.filter_factory<br>
oslo_config_project = aodh<br>
<br>
oslo_config.cfg.ConfigOpts() will easly find the /etc/aodh/aodh.conf,<br>
This cut the hidden links between middleware and the application<br>
(through the global object).<br>
<br>
And of course if oslo_config_project is not provided, the middleware<br>
fallback the global oslo.config object.<br>
The middleware options can still be passed via the legacy dict.<br>
The backward compatibility is conserved.<br>
<br>
I have already tested that in Gnocchi and Aodh, and that solves all of<br>
my issues. Remove all hacks, the application doesn't need special pre<br>
setup. All our middleware become normal middleware but still can use<br>
oslo.config.<br>
<br>
<br>
WDYT ?<br>
<br>
<br>
Cheers,<br>
<br>
[1] <a href="https://github.com/openstack/gnocchi/blob/master/gnocchi/rest/app.py#L140" rel="noreferrer" target="_blank">https://github.com/openstack/gnocchi/blob/master/gnocchi/rest/app.py#L140</a><br>
[2] <a href="https://github.com/openstack/gnocchi/blob/master/gnocchi/service.py#L64-L73" rel="noreferrer" target="_blank">https://github.com/openstack/gnocchi/blob/master/gnocchi/service.py#L64-L73</a><br>
[3] <a href="https://github.com/openstack/zaqar/blob/87fd1aa93dafb64097f731dbd416c2eeb697d403/zaqar/transport/auth.py#L63" rel="noreferrer" target="_blank">https://github.com/openstack/zaqar/blob/87fd1aa93dafb64097f731dbd416c2eeb697d403/zaqar/transport/auth.py#L63</a><br>
[4] <a href="https://github.com/openstack/zaqar/blob/87fd1aa93dafb64097f731dbd416c2eeb697d403/zaqar/transport/auth.py#L70" rel="noreferrer" target="_blank">https://github.com/openstack/zaqar/blob/87fd1aa93dafb64097f731dbd416c2eeb697d403/zaqar/transport/auth.py#L70</a><br>
[5] <a href="https://review.openstack.org/#/c/208965/" rel="noreferrer" target="_blank">https://review.openstack.org/#/c/208965/</a><br>
[6] <a href="https://review.openstack.org/#/c/209817/" rel="noreferrer" target="_blank">https://review.openstack.org/#/c/209817/</a><br>
<br>
<br>
--<br>
Mehdi Abaakouk<br>
mail: <a href="mailto:sileht@sileht.net" target="_blank">sileht@sileht.net</a><br>
irc: sileht<br>
<br>
__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" rel="noreferrer" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev<br></a>W
</blockquote></div></div>