<div dir="ltr"><div><div>[This is Horizon-related but affects every service in OpenStack, hence no</div><div>filter in the subject]</div><div><br></div><div><div>I would like for OpenStack to support browser-based Javascript API clients.</div><div>Currently this is not possible because of cross-origin resource blocking in</div><div>Javascript clients - that is, given some Javascript hosted on</div><div>"<a href="https://horizon.company.com/">https://horizon.company.com/</a>" you cannot, for example, call from that</div><div>Javascript code to an API on "<a href="https://apis.company.com:5000/v2.0/tokens">https://apis.company.com:5000/v2.0/tokens</a>" to</div><div>authenticate with Keystone.</div></div><div><br></div><div>There are three solutions to this problem:</div><div><br></div><div>1. the Horizon solution, in which those APIs are proxied by a very thick</div><div>   layer of additional Python API, plus some Python view code with some</div><div>   Javascript on the top only calling the Horizon view code,</div><div>2. add CORS support to all the OpenStack APIs though a new WSGI middleware</div><div>   (for example oslo.middleware.cors) and configured into each of the API</div><div>   services individually since they all exist on different "origin"</div><div>   host:port combinations, or</div><div>3. a new web service that proxies all the APIs and serves the static</div><div>   Javascript (etc) content from the one origin (host). APIs are then served</div><div>   from new URL roots "/name/" where the name is from the serviceCatalog</div><div>   entry. Static content can be served from "/static/". The serviceCatalog from</div><div>   keystone will be rewritten on the fly to point the API publicURLs at the</div><div>   new service. Requests are no longer cross-origin.</div><div><br></div><div>I have implemented options 2 and 3 as an exercise to see how horrid each one<br></div><div>is.</div><div><br></div><div><br></div><div>== CORS Middleware ==</div><div><br></div><div><div>For those wanting a bit of background, I have written up a spec for oslo that</div><div>talks about how this could work: <a href="https://review.openstack.org/#/c/119485/">https://review.openstack.org/#/c/119485/</a></div></div><div><br></div><div>The middleware option results in a reasonably nice bit of middleware. It's</div><div>short and relatively easy to test. The big problem with it comes in</div><div>configuring it in all the APIs. The configuration for the middleware takes</div><div>two forms:</div><div><br></div><div>1. hooking oslo.middleware.cors into the WSGI pipeline (there's more than</div><div>   one in each API),</div><div>2. adding the CORS configuration itself for the middleware in the API's main</div><div>   configuration file (eg. keystone.conf or nova.conf).</div><div><br></div><div>So for each service, that's two configuration files *and* the kicker is that</div><div>the paste configuration file is non-trivially different in almost every case.</div><div><br></div><div>That's a lot of work, and confusing for deployers. Configuration management</div><div>tools can ease *some* of this burden (the *.conf files) but those paste files</div><div>are a bit of a mess :(</div><div><br></div><div>Once the config change is in place, it works (well, except for an issue I ran</div><div>into relating to oslo.middleware.sizelimit which I'll go into in another</div><div>place).</div><div><br></div><div>The implementation hasn't been pushed up for review as I'm not sure it should</div><div>be. I can do this if people wish me to.</div><div><br></div><div><br></div><div>== New Single-Point API Service ==</div><div><br></div><div>Actually, this is not horrid in any way - unless that publicURL rewriting</div><div>gives you the heebie-jeebies.</div><div><br></div><div>It works, and offers us some nice additional features like being able to host</div><div>the service behind SSL without needing to get a bazillion certificates. And</div><div>maybe load balancing. And maybe API access filtering.</div><div><br></div><div>I note that <a href="https://openrepose.org">https://openrepose.org</a> already exists to be *something* like</div><div>this, but it's not *precisely* what I'm proposing. Also Java euwww ;)</div><div><br></div><div><br></div><div>So, I propose that the idea of CORS-in-all-the-things as an idea be</div><div>put aside as unworkable.</div><div><br></div><div>I intend to pursue the single-point API service that I have described as a</div><div>way of moving forward in prototyping a pure-Javascript OpenStack Dashboard.</div></div><div><br></div>















</div>