<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 14 Jun 2016, at 07:34, Morgan Fainberg <<a href="mailto:morgan.fainberg@gmail.com" class="">morgan.fainberg@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><br class="Apple-interchange-newline"><br class=""><div class="gmail_quote">On Mon, Jun 13, 2016 at 3:30 PM, Henry Nash<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:henrynash9@mac.com" target="_blank" class="">henrynash9@mac.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class="">So, I think it depends what level of compatibility we are aiming at. Let me articulate them, and we can agree which we want:<div class=""><br class=""></div><div class="">C1) In all version of the our APIs today (v2 and v3.0 to v3.6), you have been able to issue an auth request which used project/tenant name as the scoping directive (with v3 you need a domain component as well, but that’s not relevant for this discussion). In these APIs, we absolutely expect that if you could issue an auth request to. say project “test”, in, say, v3.X, then you could absolutely issue the exact same command at V3.(X+1). This has remained true, even when we introduced project hierarchies, i.e.: if I create:</div><div class=""><br class=""></div><div class="">/development/myproject/test</div><div class=""><br class=""></div><div class="">...then I can still scope directly to the test project by simply specifying “test” as the project name (since, of course, all project names must still be unique in the domain). We never want to break this for so long as we formally support any APIs that once allowed this.</div><div class=""><br class=""></div><div class="">C2) To aid you issuing an auth request scoped by project (either name or id), we support a special API as part of the auth url (GET/auth/projects) that lists the projects the caller *could* scope to (i.e. those they have any kind of role on). You can take the “name” or “id” returned by this API and plug it directly into the auth request. Again for any API we currently support, we can’t break this.</div><div class=""><br class=""></div><div class="">C3) The name attribute of a project is its node-name in the hierarchy. If we decide to change this in a future API, we would not want a client using the existing API to get surprised and suddenly receive a path instead of the just the node-name (e.g. what if this was a UI of some type). </div><div class=""><br class=""></div><div class="">Given all the above, there is no solution that can keep the above all true and allow more than one project of the same name in, say, v3.7 of the API. Even if we relaxed C2 and C2 -  C1 can never be guaranteed to be still supported. Neither of the original proposed solutions can address this (since it is a data modelling problem, not an API problem).</div><div class=""><br class=""></div><div class="">However, given that we will have, for the first time, the ability to microversion the Identity API starting with 3.7, there are things we can do to start us down this path. Let me re-articulate the options I am proposing:</div><div class=""><br class=""></div><div class="">Option 1A) In v3.7 we add a ‘path_name' attribute to a project entity, which is hence returned by any API that returns a project entity. The ‘path_name' attribute will contain the full path name, including the project itself. (Note that clients speaking 3.6 and earlier will not see this new attribute). Further, for clients speaking 3.7 and later, we add support to allow a ‘path_name' (as an alternative to ‘name' or ‘id') to be used in auth scoping. We do not (yet) relax any uniqueness constraints, but mark API 3.6 and earlier as deprecated, as well as using the ‘name’ attribute in the auth request. (we still support all these, we just mark them as deprecated). At some time in the future (e.g. 3.8), we remove support for using ‘name’ for auth, insisting on the use of ‘path_name’ instead. Sometime later (e.g. 3.10) we remove support for 3.8 and earlier. Then and only then, do we relax the uniqueness constraint allowing projects with duplicate node-names (but with different parents).</div><div class=""><br class=""></div></div></blockquote><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""></div><div class="">Option 1B) The same as 1A, but we insist on path_name use in auth in v3.7 (i.e. no grace-period for still using just ’name', instead relying on the fact that 3.6 clients will still work just fine). Then later (e.g. perhaps v3.9), we remove support for v3.6 and before…and relax the uniqueness constraint.</div><div class=""><br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">Let say the assumption that we are "removing" 3.6 should be stopped right now. I don't want to embark on the "when we remove this" as an option or discuss how we remove previous versions. Please lets assume for the sake of this conversation unless we have a major API version increase (API v4 and do not expose v4 projects via v3 API) this is unlikely happen. Deprecated or not, planning the removal of current supported API auth functionality is not on the table. In v3 we are not going to "relax" the uniqueness constraint in the foreseeable future. Just assume v3.6 is going to live forever for now and we can revisit when/if limits on microversion lower bounds is addressed in OpenStack with TC direction/guidance.<br class=""></div></div></div></div></div></blockquote><div><br class=""></div>Why should we not be able to remove a microversion (once keystone properly supports microversioning, as we will in 3.7)? The cross project guidelines (see: <a href="https://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html" class="">https://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html</a>), clearly gives example of how we would support the dropping of support for earlier microversions. If there is a TC resolution that has changed this, then disregard this comment - but it’s not something I’ve been aware of (and we should probably change the documentation on microversions if that’s the case)</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""></div><div class="">Option 2A) In 3.7 the meaning of the ‘name' attribute of project entity is redefined to be the full path name (note that clients speaking 3.6 will continue to see ’name’ just be the node-name without a path). We do not (yet) relax any uniqueness constraints. For clients speaking 3.7 and later, we return the full path name where the project entity ‘name’ attribute is returned. For auth, we allow a full path name to specified in the ‘name’ scope attribute - but we also still support just a name without a path (which we can guarantee to honour, since, so far, we haven’t relaxed the uniqueness constraint - however we mark that support as deprecated). At some time in the future (e.g. 3.8), we remove support for using an un-pathed ‘name’ for auth. Sometime later (e..g. 3.10) we remove support for 3.8 and earlier. Then and only then, do we relax the uniqueness constraint allowing projects with duplicate node-names (but with different parents).</div><div class=""><br class=""></div><div class="">Option 2B) The same as 2A, but we insist on using ‘name’ with a full path use in auth in v3.7 (i.e. no grace-period for still using an un-pathed  ’name', instead relying on the fact that 3.6 clients will still work just fine). Then later (e.g. perhaps v3.9), we remove support for v3.6 and before…and relax the uniqueness constraint.</div><div class=""><br class=""></div><div class="">The downside for option 2A and 2B is that a client must do work to not be “surprised” by 3.7 (since the ‘name’ attribute of a project entity may not contain what they expect). For 1A no changes are required at all for a client to work with 3.7 and maintain the current experience, although changes ARE of course required to start moving away from using the non-pathed ‘name’ attribute, but that doesn’t have to be done straight away, we give them a grace cycle. For 1B, you need to make changes to support 3.7 (since a path is required for auth).</div><div class=""><br class=""></div><div class="">As I have said before, my preference is Option 1, since I think it results in a more logical end position, and neither 1 or 2 get us there any more quickly. For option 1, I prefer the more gradual approach of 1A, just so that we give clients a grace period. Given we need multiple cycles to achieve any of the options, let’s decide the final conceptual model we want - and then move towards it. Options 1's conceptual mode is that ‘name’ remains the same, and we add separate ‘path’ attribute, Option 2’s other redefines ‘name’ to always be a full path.</div><span class=""><font color="#888888" class=""><div class=""><br class=""></div><div class="">Henry</div></font></span><div class=""><div class="h5"><div class=""><br class=""></div><div class=""><br class=""></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I gave an alternative to this whole mess that would work and get the non-unique requirements for a specific project. I'll go over the only viable option (see my comment above, uniqueness constraint cannot go away in the forseeable future; not in v3.10, not in v3.11, etc).</div><div class=""><br class=""></div><div class="">* For all projects created in v3.7 or later, the "name" is explicitly the full path. This keeps compatibility with v3.6 (you can auth, use the project's "name" which is now the full path).</div></div></div></div></div></blockquote><div><br class=""></div>My problem with your suggestion is, that I couldn’t see how this satisfies compatibility requirement C1 in my email. In 3.6 I could issue auth request to project “test”. The server I am talking to is now upgraded to Newton and a second project called “test” is created somewhere in the hierarchy. Using my (unmodified) client, I then re-issue my auth request to “test”….we can no longer satisfy this request. I am not talking about client code that pulls the name of the project from GET /auth/projects and plugs it into auth, rather a user sitting at a UI (that uses 3.6) and types in the project they want in their auth scope.</div><div><br class=""></div><div>However, maybe what you suggesting is that we use the fact that we can know that a project was created in 3.7 or later (rather than 3.6) to differentiate? If so, would that mean that you wouldn’t actually return projects created in 3.7 to a client 3.6 at all? I.e. if you do a list projects in a 3.6 client, would you only see projects that were created prior to 3.7? (since, presumably you would want to not show path names to a 3.6 client, and hence would show projects that they could not auth to).</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><div class="">* All projects get a way to map the full path (full_path attr, as you said for option 2[A/B]). We can support authentication with *either* full path or name, the advantage of full_path is you never need to supply domain identification for the "user friendly" name -- keep in mind, this also will need to explore (at least documentation around) what occurs if a project name is "changed" as project names are mutable, it would change the path; should project names become immutable?</div><div class=""><br class=""></div><div class="">All of this means that current auth workflows *and* new "full_path" workflows play nicely and no compatibility is broken. We aren't re-defining anything here as redefining things will break current workflows.</div></div></div></div></div></blockquote><div><br class=""></div>Well, clients that display something to the user may need to change (e.g. I’m displaying a hierarchy of projects, suddenly all my project names become full paths and my display looks really silly).</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">In short, do not expect an api break/compat break is going to be possible in v3 for older API versions.</div><div class=""><br class=""></div><div class="">--Morgan</div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class="h5"><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On 10 Jun 2016, at 18:48, Morgan Fainberg <<a href="mailto:morgan.fainberg@gmail.com" target="_blank" class="">morgan.fainberg@gmail.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_extra"><br class=""><br class=""><div class="gmail_quote">On Fri, Jun 10, 2016 at 6:37 AM, Henry Nash<span class=""> </span><span dir="ltr" class=""><<a href="mailto:henrynash9@mac.com" target="_blank" class="">henrynash9@mac.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class="">On further reflection, it seems to me that we can never simply enable either of these approaches in a single release. Even a v4.0 version of the API doesn’t help - since presumably a sever supporting v4 would want to be able to support v3.x for a signification time; and, already discussed, as soon as you allow multiple none-names to have the same name, you can no longer guarantee to support the current API.<div class=""><br class=""></div><div class="">Hence the only thing I think we can do (if we really do want to change the current functionality) is to do this over several releases with a typical deprecation cycle, e.g.</div><div class=""><br class=""></div><div class="">1) At release 3.7 we allow you to (optionally) specify path names for auth….but make no changes to the uniqueness constraints. We also change the GET /auth/projects to return a path name. However, you can still auth exactly the way we do today (since there will always only be a single project of a given node-name). If however, you do auth without a path (to a project that isn’t a top level project), we log a warning to say this is deprecated (2 cycles, 4 cycles?)</div><div class="">2) If you connect with a 3.6 client, then you get the same as today for GET /auth/projects and cannot use a path name to auth.</div><div class="">3) At sometime in the future, we deprecate the “auth without a path” capability. We can debate as to whether this has to be a major release.</div><div class=""><br class=""></div><div class="">If we take this gradual approach, I would be pushing for the “relax project name constraints” approach…since I believe this leads to a cleaner eventual solution (and there is no particular advantage with the hierarchical naming approach) - and (until the end of the deprecation) there is no break to the existing API.</div><span class=""><font color="#888888" class=""><div class=""><br class=""></div></font></span><div class=""><span class=""><font color="#888888" class="">Henry</font></span><div class=""><div class=""><br class=""></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">How do you handle relaxed project name constraints without completely breaking 3.6 auth - regardless of future microversion that requires the full path. This is a major api change and will result in very complex matrix of project name mapping (old projects that can be accessed without the full path, new that must always have the path)?</div><div class=""><br class=""></div><div class="">Simply put, I do not see relaxing project name constraints as viable without a major API change and projects that simply are unavailable for scoping a token to under the base api version (pre-microversions) of 3.6</div><div class=""><br class=""></div><div class="">I am certain that if all projects post API version 3.6 are created with the full-path name only and that is how they are represented to the user for auth, we get both things for free. Old projects pre-full-path would need optional compatibility for deconstructing a full-path for them.  Basically you end up with "path" and "name", in old projects these differ, in new projects they are the same.  No conflicts, not breaking "currently working auth", no "major API version" needed.</div><div class=""><br class=""></div><div class="">--Morgan</div><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On 7 Jun 2016, at 09:47, Henry Nash <<a href="mailto:henrynash9@mac.com" target="_blank" class="">henrynash9@mac.com</a>> wrote:</div><br class=""><div class=""><div style="word-wrap: break-word;" class="">OK, so thanks for the feedback - understand the message.<div class=""><br class=""></div><div class="">However, in terms of compatibility, the one thing that concerns me about the hierarchical naming approach is that even with microversioing, we might still surprise a client. An unmodified client (i.e. doesn’t understand 3.7) would still see a change in the data being returned (the project names have suddenly become full path names). We have to return this even if they don’t ask for 3.7, since otherwise there is no difference between this approach and relaxing the project naming in terms of trying to prevent auth breakages.</div><div class=""><br class=""></div><div class="">In more detail:</div><div class=""><br class=""></div><div class="">1) Both approaches were planned to return the path name (instead of the node name) in GET /auth/projects - i.e. the API you are meant to use to find out what you can scope to</div><div class="">2) Both approaches were planned to accept the path name in the auth request block</div><div class="">3) The difference in hierarchical naming is the if I do a regular GET /project(s) I also see the full path name as the “project name”</div><div class=""><br class=""></div><div class="">if we don’t do 3), then code that somehow authenticates, and then uses the regular GET /project(s) calls to find a project name and then re-scopes (or re-auths) to that name, will fail if the project they want is not a top level project. However, the flip side is that if there is code that uses these same calls to, say, display projects to the user (e.g. a home grown UI) - then it might get confused until it supports 3.7 (i.e. asking for the old microversion won’t help it) since all the names include the hierarchical path.</div><div class=""><br class=""></div><div class="">Just want to make sure we understand the implications….</div><div class=""><br class=""></div><div class="">Henry</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="">On 4 Jun 2016, at 08:34, Monty Taylor <<a href="mailto:mordred@inaugust.com" target="_blank" class="">mordred@inaugust.com</a>> wrote:</div><br class=""><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">On 06/04/2016 01:53 AM, Morgan Fainberg wrote:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br class="">On Jun 3, 2016 12:42, "Lance Bragstad" <<a href="mailto:lbragstad@gmail.com" target="_blank" class="">lbragstad@gmail.com</a><br class=""><<a href="mailto:lbragstad@gmail.com" target="_blank" class="">mailto:lbragstad@gmail.com</a>>> wrote:<br class=""><blockquote type="cite" class=""><br class=""><br class=""><br class="">On Fri, Jun 3, 2016 at 11:20 AM, Henry Nash <<a href="mailto:henrynash9@mac.com" target="_blank" class="">henrynash9@mac.com</a><br class=""></blockquote><<a href="mailto:henrynash9@mac.com" target="_blank" class="">mailto:henrynash9@mac.com</a>>> wrote:<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""><br class=""><blockquote type="cite" class="">On 3 Jun 2016, at 16:38, Lance Bragstad <<a href="mailto:lbragstad@gmail.com" target="_blank" class="">lbragstad@gmail.com</a><br class=""></blockquote></blockquote></blockquote><<a href="mailto:lbragstad@gmail.com" target="_blank" class="">mailto:lbragstad@gmail.com</a>>> wrote:<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""><br class=""><br class="">On Fri, Jun 3, 2016 at 3:20 AM, Henry Nash <<a href="mailto:henrynash9@mac.com" target="_blank" class="">henrynash9@mac.com</a><br class=""></blockquote></blockquote></blockquote><<a href="mailto:henrynash9@mac.com" target="_blank" class="">mailto:henrynash9@mac.com</a>>> wrote:<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""><br class=""><blockquote type="cite" class="">On 3 Jun 2016, at 01:22, Adam Young <<a href="mailto:ayoung@redhat.com" target="_blank" class="">ayoung@redhat.com</a><br class=""></blockquote></blockquote></blockquote></blockquote></blockquote><<a href="mailto:ayoung@redhat.com" target="_blank" class="">mailto:ayoung@redhat.com</a>>> wrote:<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">On 06/02/2016 07:22 PM, Henry Nash wrote:<br class=""><blockquote type="cite" class=""><br class="">Hi<br class=""><br class="">As you know, I have been working on specs that change the way we<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>handle the uniqueness of project names in Newton. The goal of this is to<br class="">better support project hierarchies, which as they stand today are<br class="">restrictive in that all project names within a domain must be unique,<br class="">irrespective of where in the hierarchy that projects sits (unlike, say,<br class="">the unix directory structure where a node name only has to be unique<br class="">within its parent). Such a restriction is particularly problematic when<br class="">enterprise start modelling things like test, QA and production as<br class="">branches of a project hierarchy, e.g.:<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">/mydivsion/projectA/dev<br class="">/mydivsion/projectA/QA<br class="">/mydivsion/projectA/prod<br class="">/mydivsion/projectB/dev<br class="">/mydivsion/projectB/QA<br class="">/mydivsion/projectB/prod<br class=""><br class="">Obviously the idea of a project name (née tenant) being unique<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>has been around since near the beginning of (OpenStack) time, so we must<br class="">be cautions. There are two alternative specs proposed:<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">1) Relax project name<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>constraints:<span class=""> </span><a href="https://review.openstack.org/#/c/310048/" target="_blank" class="">https://review.openstack.org/#/c/310048/</a><span class=""> </span><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">2) Hierarchical project<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>naming:<span class=""> </span><a href="https://review.openstack.org/#/c/318605/" target="_blank" class="">https://review.openstack.org/#/c/318605/</a><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">First, here’s what they have in common:<br class=""><br class="">a) They both solve the above problem<br class="">b) They both allow an authorization scope to use a path rather<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>than just a simple name, hence allowing you to address a project<br class="">anywhere in the hierarchy<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">c) Neither have any impact if you are NOT using a hierarchy -<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>i.e. if you just have a flat layer of projects in a domain, then they<br class="">have no API or semantic impact (since both ensure that a project’s name<br class="">must still be unique within a parent)<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">Here’s how the differ:<br class=""><br class="">- Relax project name constraints (1), keeps the meaning of the<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>‘name’ attribute of a project to be its node-name in the hierarchy, but<br class="">formally relaxes the uniqueness constraint to say that it only has to be<br class="">unique within its parent. In other words, let’s really model this a bit<br class="">like a unix directory tree.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">I think I lean towards relaxing the project name constraint. The<br class=""></blockquote></blockquote></blockquote>reason is because we already expose `domain_id`, `parent_id`, and `name`<br class="">of a project. By relaxing the constraint we can give the user everything<br class="">the need to know about a project without really changing any of these.<br class="">When using 3.7, you know what domain your project is in, you know the<br class="">identifier of the parent project, and you know that your project name is<br class="">unique within the parent.  <br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">- Hierarchical project naming (2), formally changes the meaning<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>of the ‘name’ attribute to include the path to the node as well as the<br class="">node name, and hence ensures that the (new) value of the name attribute<br class="">remains unique.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">Do we intend to *store* the full path as the name, or just build it<br class=""></blockquote></blockquote></blockquote>out on demand? If we do store the full path, we will have to think about<br class="">our current data model since the depth of the organization or domain<br class="">would be limited by the max possible name length. Will performance be<br class="">something to think about building the full path on every request?   <br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">I now mention this issue in the spec for hierarchical project naming<br class=""></blockquote></blockquote>(the relax naming approach does not suffer this issue). As you say,<br class="">we’ll have to change the DB (today it is only 64 chars) if we do store<br class="">the full path . This is slightly problematic since the maximum depth of<br class="">hierarchy is controlled by a config option, and hence could be changed.<br class="">We will absolutely have be able to build the path on-the-fly in order to<br class="">support legacy drivers (who won’t be able to store more than 64 chars).<br class="">We may need to do some performance tests to ascertain if we can get away<br class="">with building the path on-the-fly in all cases and avoid changing the<br class="">table.  One additional point is that, of course, the API will return<br class="">this path whenever it returns a project - so clients will need to be<br class="">aware of this increase in size.<span class=""> </span><br class=""><blockquote type="cite" class=""><br class=""><br class="">These are all good points that continue to push me towards relaxing<br class=""></blockquote>the project naming constraint :)<span class=""> </span><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""><br class="">While whichever approach we chose would only be included in a new<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>microversion (3.7) of the Identity API, although some relevant APIs can<br class="">remain unaffected for a client talking 3.6 to a Newton server, not all<br class="">can be. As pointed out be jamielennox, this is a data modelling problem<br class="">- if a Newton server has created multiple projects called “dev” in the<br class="">hierarchy, a 3.6 client trying to scope a token simply to “dev” cannot<br class="">be answered correctly (and it is proposed we would have to return an<br class="">HTTP 409 Conflict error if multiple nodes with the same name were<br class="">detected). This is true for both approaches.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">Other comments on the approaches:<br class=""><br class="">- Having a full path as the name seems duplicative with the<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>current project entity - since we already return the parent_id (hence<br class="">parent_id + name is, today, sufficient to place a project in the hierarchy).<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""><br class="">The one thing I like is the ability to specify just the full path<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote>for the OS_PROJECT_NAME env var, but we could make that a separate<br class="">variable.  Just as DOMAIN_ID + PROJECT_NAME is unique today,<br class="">OS_PROJECT_PATH should be able to fully specify a project<br class="">unambiguously.  I'm not sure which would have a larger impact on users.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""></blockquote>Agreed - and this could be done for both approaches (since this is<br class=""></blockquote></blockquote></blockquote></blockquote>all part of the “auth data flow").<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""><br class=""><blockquote type="cite" class="">- In the past, we have been concerned about the issue of what we<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>do if there is a project further up the tree that we do not have any<br class="">roles on. In such cases, APIs like list project parents will not display<br class="">anything other than the project ID for such projects. In the case of<br class="">making the name the full path, we would be effectively exposing the name<br class="">of all projects above us, irrespective of whether we had roles on them.<br class="">Maybe this is OK, maybe it isn’t.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""><br class="">I think it is OK.  If this info needs to be hidden from a user,<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote>the project should probably be in a different domain.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">- While making the name the path keeps it unique, this is fine if<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>clients blindly use this attribute to plug back into another API to<br class="">call. However if, for example, you are Horizon and are displaying them<br class="">in a UI then you need to start breaking down the path into its<br class="">components, where you don’t today.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">- One area where names as the hierarchical path DOES look right<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>is calling the /auth/projects API - where what the caller wants is a<br class="">list of projects they can scope to - so you WANT this to be the path you<br class="">can put in an auth request.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">Given that neither can fully protect a 3.6 client, my personal<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>preference is to go with the cleaner logical approach which I believe is<br class="">the Relax project name constraints (1), with the addition of changing<br class="">GET /auth/projects to return the path (since this is a specialised API<br class="">that happens before authentication) - but I am open to persuasion (as<br class="">the song goes).<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">There are those that might say that perhaps we just can’t change<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>this. I would argue that since this ONLY affects people who actually<br class="">create hierarchies and that today such hierarchical use is in its<br class="">infancy, then now IS the time to change this. If we leave it too long,<br class="">then it will become really hard to change what will by then have become<br class="">a tough restriction.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">Henry<br class=""><br class=""><br class=""><br class=""><br class=""><br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote>__________________________________________________________________________<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">OpenStack Development Mailing List (not for usage questions)<br class="">Unsubscribe:<br class=""></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" class="">OpenStack-dev-request@lists.openstack.org</a>?subject:unsubscribe<br class=""><<a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" target="_blank" class="">http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a>><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""></blockquote><br class=""><br class=""><br class=""></blockquote></blockquote></blockquote></blockquote></blockquote>__________________________________________________________________________<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">OpenStack Development Mailing List (not for usage questions)<br class=""><br class=""></blockquote></blockquote></blockquote></blockquote></blockquote>Unsubscribe:<span class=""> </span><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" class="">OpenStack-dev-request@lists.openstack.org</a>?subject:unsubscribe<br class=""><<a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" target="_blank" class="">http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a>><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""></blockquote><br class=""><br class=""><br class=""><br class=""></blockquote></blockquote></blockquote></blockquote>__________________________________________________________________________<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">OpenStack Development Mailing List (not for usage questions)<br class=""><br class=""></blockquote></blockquote></blockquote></blockquote>Unsubscribe:<span class=""> </span><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" class="">OpenStack-dev-request@lists.openstack.org</a>?subject:unsubscribe<br class=""><<a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" target="_blank" class="">http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a>><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""><br class=""></blockquote><br class=""><br class=""></blockquote></blockquote></blockquote>__________________________________________________________________________<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">OpenStack Development Mailing List (not for usage questions)<br class=""><br class=""></blockquote></blockquote></blockquote>Unsubscribe:<span class=""> </span><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" class="">OpenStack-dev-request@lists.openstack.org</a>?subject:unsubscribe<br class=""><<a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" target="_blank" class="">http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a>><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""></blockquote><br class=""><br class=""><br class=""><br class=""></blockquote></blockquote>__________________________________________________________________________<br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">OpenStack Development Mailing List (not for usage questions)<br class="">Unsubscribe:<br class=""></blockquote></blockquote><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" class="">OpenStack-dev-request@lists.openstack.org</a>?subject:unsubscribe<br class=""><<a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" target="_blank" class="">http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a>><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""><br class=""></blockquote><br class=""><br class="">__________________________________________________________________________<br class="">OpenStack Development Mailing List (not for usage questions)<br class="">Unsubscribe:<br class=""></blockquote><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" class="">OpenStack-dev-request@lists.openstack.org</a>?subject:unsubscribe<br class=""><<a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" target="_blank" class="">http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a>><br class=""><blockquote type="cite" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""><br class=""></blockquote><br class="">My main concern with relaxing the uniqueness is you now have a<br class="">significant issue with auth changing. Fundamentally you cannot scope to<br class="">a project under a domain by name and domain name alone. This will break<br class="">current auth paths and auth mechanisms.<br class=""><br class="">I personally think we are a bit wedged even with microversions without<br class="">providing the full path as a name for projects created as such (and<br class="">current projects retaining the uniqueness or if created via the old api<br class="">maintaining the uniqueness constraint and new api projects not being<br class="">represented at all).<br class=""><br class="">So in short, I am strongly against relaxing uniqueness.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">I agree.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">This would break code that exists currently. A microversion is fine for</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">creating a new api call. A microversion is not ok for fundamentally</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">breaking the semantics of an existing API. This would be a major API</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">version bump. It would break existing users with existing code, and</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">since there _is_ another option on the table that does not break</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">existing users with existing code, I believe that it is imperative to</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">select the non-breaking option.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">New (microversion) would make projects that are only represented by full<br class="">path. Old projects could be represented either way. (For auth/crud that<br class="">uses project names).<br class=""><br class="">Old microversion api (today) would require uniqueness constraint and not<br class="">show/allow full pathname projects.<br class=""><br class="">This way we do not break auth that works today.<br class=""><br class="">Most everyone consumes and stores by id (nova, cinder, etc) so we likely<br class="">won't break much with extended project names.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">End users work by name - but yes, I agree the impact cross-openstack is</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">unlikely.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">__________________________________________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">OpenStack Development Mailing List (not for usage questions)</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">Unsubscribe:<span class=""> </span></span><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">OpenStack-dev-request@lists.openstack.org</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">?subject:unsubscribe</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a></div></blockquote></div><br class=""></div>__________________________________________________________________________<br class="">OpenStack Development Mailing List (not for usage questions)<br class="">Unsubscribe:<span class=""> </span><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" class="">OpenStack-dev-request@lists.openstack.org</a>?subject:unsubscribe<br class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""></div></blockquote></div><br class=""></div></div></div></div><br class="">__________________________________________________________________________<br class="">OpenStack Development Mailing List (not for usage questions)<br class="">Unsubscribe:<span class=""> </span><a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" rel="noreferrer" target="_blank" class="">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""><br class=""></blockquote></div><br class=""></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">__________________________________________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">OpenStack Development Mailing List (not for usage questions)</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">Unsubscribe:<span class=""> </span></span><a href="mailto:OpenStack-dev-request@lists.openstack.org" target="_blank" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">OpenStack-dev-request@lists.openstack.org</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">?subject:unsubscribe</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a></div></blockquote></div><br class=""></div></div></div></div></div><br class="">__________________________________________________________________________<br class="">OpenStack Development Mailing List (not for usage questions)<br class="">Unsubscribe:<span class="Apple-converted-space"> </span><a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" rel="noreferrer" target="_blank" class="">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""><br class=""></blockquote></div><br class=""></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">__________________________________________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">OpenStack Development Mailing List (not for usage questions)</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Unsubscribe:<span class="Apple-converted-space"> </span></span><a href="mailto:OpenStack-dev-request@lists.openstack.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">OpenStack-dev-request@lists.openstack.org</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">?subject:unsubscribe</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a></div></blockquote></div><br class=""></body></html>