[openstack-dev] [oaktree] Follow up to Multi-cloud Management in OpenStack Summit session
mordred at inaugust.com
Tue Nov 28 21:20:10 UTC 2017
I've CC'd everyone who listed interest directly, just in case you're not
already on the openstack-dev list. If you aren't, and you are in fact
interested in this topic, please subscribe and make sure to watch for
[oaktree] subject headings.
We had a great session in Sydney about the needs of managing resources
across multiple clouds. During the session I pointed out the work that
had been started in the Oaktree project  and offered that if the
people who were interested in the topic thought we'd make progress best
by basing the work on oaktree, that we should bootstrap a new core team
and kick off some weekly meetings. This is, therefore, the kickoff email
to get that off the ground.
All of the below is thoughts from me and a description of where we're at
right now. It should all be considered up for debate, except for two things:
- gRPC API
- backend implementation based on shade
As those are the two defining characteristics of the project. For those
who weren't in the room, justifications for those two characteristics are:
There are several reasons why gRPC.
* Make it clear this is not a competing REST API.
OpenStack has a REST API already. This is more like a 'federation' API
that knows how to talk to one or more clouds (similar to the kubernetes
* Streaming and async built in
One of the most costly things in using the OpenStack API is polling.
gRPC is based on HTTP/2 and thus supports streaming and other exciting
things. This means an oaktree running in or on a cloud can do its
polling loops over the local network and the client can just either wait
on a streaming call until the resource is ready, or can fire an async
call and deal with it later on a notification channel.
* Network efficiency
Protobuf over HTTP/2 is a super-streamlined binary protocol, which
should actually be really nice for our friends in Telco land who are
using OpenStack for Edge-related tasks in 1000s of sites. All those
roundtrips add up at scale.
* Multi-language out of the box
gRPC allows us to directly generate consistent consumption libs for a
bunch of languages - or people can grab the proto files and integrate
those into their own build if they prefer.
* The cool kids are doing it
To be fair, Jay Pipes and I tried to push OpenStack to use Protobuf
instead of JSON for service-to-service communication back in 2010 - so
it's not ACTUALLY a new idea... but with Google pushing it and support
from the CNCF, gRPC is actually catching on broadly. If we're writing a
new thing, let's lean forward into it.
Backend implementation in shade
If the service is defined by gRPC protos, why not implement the service
itself in Go or C++?
* Business logic to deal with cloud differences
Adding a federation API isn't going to magically make all of those
clouds work the same. We've got that fairly well sorted out in shade and
would need to reimplement basically all of shade in other other language.
* shade is battle tested at scale
shade is what Infra's nodepool uses. In terms of high-scale API
consumption, we've learned a TON of lessons. Much of the design inside
of shade is the result of real-world scaling issues. It's Open Source,
so we could obviously copy all of that elsewhere - but why? It exists
and it works, and oaktree itself should be a scale-out shared-nothing
kind of service anyway.
The hard bits here aren't making API calls to 3 different clouds, the
hard bits are doing that against 3 *different* clouds and presenting the
results sanely and consistently to the original user.
As the originator of the project, I'll take on the initial PTL role.
When the next PTL elections roll around, we should do a real election.
Initial Core Team
oaktree is still small enough that I don't think we need to be super
protective - so I think if you're interested in working on it and you
think you'll have the bandwidth to pay attention, let me know and I'll
add you to the team.
General rules of thumb I try to follow on top of normal OpenStack
* Review should mostly be about suitability of design/approach. Style
issues should be handled by pep8/hacking (with one exception, see
below). Functional issues should be handled with tests. Let the machines
be machines and humans be humans.
* Use followup patches to fix minor things rather than causing an
existing patch to get re-spun and need to be re-reviewed.
The one style exception ... I'm a big believer in not using visual
indentation - but I can't seem to get pep8 or hacking to complain about
its use. This isn't just about style - visual indentation causes more
lines to be touched during a refactor than are necessary making the
impact of a change harder to see.
x = some_function(
x = some_function(with_some,
If anyone can figure out how to write a hacking rule that enforces that
I'll buy you a herd of chickens.
Let's give it a week or so to see who is interested in being in the
initial core team so that we can figure out what timezones folks are in
and pick a time that works for the maximum number of people.
oaktree development is closely related to shade development which is now
in #openstack-sdks, so let's stay there until we get kicked out.
oaktree uses storyboard 
oaktree tech overview
oaktree is a service that presents a gRPC API and that uses shade as its
OpenStack connectivity layer. It's organized into two repos at the
moment, oaktreemodel and oaktree. The intent is that anyone should be
able to use the gRPC/protobuf definitions to create a client
implementation. It is explicitly not the intent that there be more than
one server implementation, since that would require reimplementing all
of the hairy business logic that's in shade already.
oaktreemodel contains the protobuf definitions, as well as the generated
golang code. It is intended to provide a library that is easily pip
installable by anyone who wants to build a client without them needing
to add protoc steps. It contains build tooling to produce python, golang
and C++. The C++ and python files are generated and included in the
source sdist artifacts. Since golang uses git for consumption, the
generated golang files are committed to the oaktreemodel repo.
oaktreemodel has a more complex build toolchain, but is organized so
that only oaktreemodel devs need to deal with it. People consuming
oaktreemodel should not need to know anything about how it's built - pip
install oaktreemodel or go get
https://git.openstack.org/openstack/oaktreemodel should Just Work with
no additional effort on the part of the programmer.
oaktree contains the server implementation and depends on oaktreemodel.
It's mostly a thin shim layer mapping gRPC stubs to shade calls. Much of
the logic that needs to exist for oaktree to work wants to live in
shade, but I'm sure we'll find places where that's not true.
Ultra Short-Term TODO/in-progress
Fix Gate jobs for Zuul v3 (mordred)
We have devstack functional gate jobs - but they haven't been updated
since the Zuul v3 migration. Duong Ha-Quang submitted a patch  to
migrate the legacy jobs to in-tree. We need to get that fixed up, then
migrate the job to use the new fancy devstack base job.
I'll get this all fixed ASAP so that it's easy for folks to start
hacking on patches.
I'm working on this one.
A patch for oaktreemodel is in flight . We still needs a patch to
oaktree to follow up, which I have half-finished. I'll get it up once
the oaktreemodel patch is green.
Expose more things
shade has *way* more capabilities than oaktree, which is mostly a matter
of writing some proto definitions for resources that match the 'strict'
version of shade's data model. In some cases it might mean that we need
to define a data model contract in shade too... but by and large picking
things and adding them is a great way to get familiar with all the
pieces and how things flow together.
We should also consider whether or not we can do any meta-programming to
map shade calls into oaktree calls automatically. For now I think we
should be fine with just having copy-pasta boilerplate until we
understand enough about the patterns to abstract them - but we SHOULD be
able to do some work to reduce the boilerplate.
Write better tests
There are gate jobs at the moment and a tiny smoke-test script. We
should add some functional tests for python, go and C++ in the
I'm not sure a TON of unittests in oaktreemodel will be super useful -
however, some simple tests that verify we haven't borked something in
the protos that cause code to be generated improperly would be great. We
can do those just making sure we can create the proto objects and
whatnot without needing an actual server running.
Unittests in oaktree itself are likely to have very little value. We can
always add more requests-mock unittests to shade/python-openstacksdk. I
think we should focus more on functional tests and on making sure those
tests can run against not just devstack.
Shift calling interface from shade to python-openstacksdk
oaktree doesn't need historical compat, so we can go ahead and start
using python-openstacksdk. Our tests will be cross-testing with master
branch commits rather than releases right now anyway.
Add Java and Ruby build plumbing to oaktree model
Protobuf/gRPC has support for java and ruby as well, we should plumb
them through as well.
Parallel Multicloud APIs
The existing APIs allow for multi-cloud consumption from the same
connection via a Location object used as a parameter to calls.
Additionally, shade adds a Location property to every object returned,
so all shade objects carry the information needed to verify uniqueness.
However, when considering actions like:
"I want a list of all of my servers on all of my clouds"
the answer is currently an end-user for-loop. We should add calls to
shade for each of the list/search/get API calls that fetch from all of
the available cloud regions in parallel and then combine the results
into a single result list.
We should also think about a design for multi-cloud creates and which
calls they make sense for. Things like image and flavor immediately come
to mind, as having consistent image and flavors across cloud regions is
Both of those are desired features at the shade layer, so designing and
implementing them will work great there ... but working on adding them
to shade and exposing them in oaktree at the same time will help inform
what shape of API at the shade layer serves the oaktree layer the best.
Add REST escape hatch
There are PLENTY of things that will never get added to oaktree
directly- especially things that are deployment/vendor-backend specific.
One of the things discussed in Sydney was adding an API call to oaktree
that would return a Protobuf that contains the root URL for a given
service along with either a token, a list of HTTP Headers to be used for
auth or both. So something like:
conn = oaktreemodel.Connect()
rest_info = conn.get_rest_info(
servers = requests.get(
rest_info.url + '/servers',
or, maybe that's the gRPC call and there is a call in each language's
client lib that returns a properly constructed rest client...
conn = oaktreemodel.Connect()
compute = conn.get_adapter(
servers = compute.get('/servers').json()
*waves hands* - needs to be thought about, designed and implemented.
Medium Term TODOs
oaktree is currently not authenticated. It works great on a laptop or in
a location that's locked down through some other means, which should be
fine for the first steps of the telco/edge use case, as well as for the
developer use case getting started with it - but it's obviously not
suitable for a multi-user service. The thinking thusfar has been to NOT
use keystone for auth, since that introduces the need for having a gRPC
auth plugin for clients, as well as doing some sort of REST/gRPC dance.
BUT - whether that's the right choice and what the right choice actually
is is an open question on purpose - getting input from the operators on
what mechanism works best is important. Maybe making a keystone gRPC
auth driver and using keystone is the right choice. Maybe it isn't.
Let's talk about it.
Since it's currently only a single-user service, it operates off of a
pre-existing local clouds.yaml to define which clouds it has access to.
Long-term one can imagine that one would want to authorize an oaktree to
talk to a particular cloud-region in some manner. This needs to be designed.
oaktree currently uses the caching support in shade for its caching.
Although it is based on dogpile.cache which means it has support for
shared backends like redis or memcached, it hasn't really been vetted
for multi-user sharing a single cache. It'll be fine for the next 6-9
months, but once we go multi-user I'd be concerned about it - so we
should consider the caching layer design.
shade oaktreemodel backend
In an ultimate fit of snake eating its own tail, we should add support
to shade for making client connections to an oaktree if one exists. This
should obviously be pretty direct passthrough. That would mean that an
oaktree talking to another oaktree would be able to do so via the gRPC
layer without any intermediate protobuf-to-dict translation steps.
That leads us to potentially just using the oaktreemodel protobuf
objects as the basis for the in-memory resource objects inside of
sdk/shade - but that's inception-y enough that we should just skip it
for now. If protobuf->json translations are what's killing us, that's a
great problem to have.
I think we should aim for having something that's usable/discussable for
the single/trusted-user use case for real work (install an oaktree
yourself pointed at a clouds.yaml file and talk to it locally without
auth) by the Dublin PTG. It doesn't have to do everything, but we should
at least have a sense of whether this will solve the needs of the people
who were interested in this topic so that we'll know whether figuring
out the auth story is worth-while or if this is all a terrible idea.
I think it's TOTALLY reasonable that by Vancouver we should have a thing
that's legit usable for folks who have the pain point today (given the
If that works out, discuss auth in Vancouver and aim to have it figured
out and implemented by Berlin so that we can actually start pushing
clouds to include oaktree in their deployments.
Ok. That's the braindump from me. Let me know if you wanna dive in,
we'll get a core team fleshed out and an IRC meeting set up and folks
can start cranking.
More information about the OpenStack-dev