2014-09-19T17:50:11+08:00http://soulxu.github.io/Octopress2014-09-12T12:37:17+08:00http://soulxu.github.io/blog/2014/09/12/one-option-for-nova-apiClose to Kilo, it is time to think about what next for nova API. Let me
write down some ideas from me at here, although I’m not sure those idea can be
accepted finally, but really hope those can give some help.

For the change of status code, and resource name are really simple to implement.

For semantic changes, there isn’t choice we must provide two version python code
in api layer. We propose method for distinguish different semantic in v2 on v3,
but it have too much magic, so think about to simplify it.

The most of complex part is input and output change. And in v2 on v3 propose,
this part also implement as most complex. We provide method to translate the input
and json-schema, but that make the json-schema hard to maintenance and read.

The new ideas is want to provide simple implementation for input/output change, and
reduce the magic we used.

The frist 3 commits are implement wsgi infrastruct as new ideas.
The last 4 commits are demo the use-case in micro-version.

Let’s take a look at some example

There is fake code for an extension that add new action to server. This fake code
also includes some usual inconsistent and mistake in v2 API that we want to fix in
the future. Anyway most of API code structure looks like as below:

Before wsgi invoke API python code, the decorator ‘v2_translate_body’ should translate
input and json-schema as the old one that make API python code can understand the
request. That means API python code always assume the user request is oldest format.

There are two downsides with this method:

The implementation is complex

Actually not only need translate the request body, also need translate the json-schema
that used to validate the input with new format, and also for the output.

And not only support ‘rename_to’ instruct, also need support ‘move_to’ instruct for
the case like scheduler_hints.

The multiple version json-schema is unreadable and hard to maintenance by dev

When there already doing multiple version changes for the request format, the translation-schema is
dependence on one by one. Except there is json-schema file for the oldest format, other version
json-schema only can get by translation. The dev is no way to get specified version json-schema,
except they runing the code and print it out.

And except the method input/output change, we also provide some magic for distinguish different semantic.
(https://review.openstack.org/82301). But it also make the code hard to read.

The new method for support multiple version

Thinking of the key reason of make those complex thing is the python code also need
input/output format knowledge. Actually, the json-schema already includes those
information.

The idea of new method for input/output change is just eliminate the format knowledge
from python code. Whatever the format it is, python code just need got a flat dict
without any format.

(And other idea is got a nova objects, and I didn’t think out of enough benefit from
using nova object, but this idea is worth to think about. Honestly I’m not familiar
with objects, maybe the POC with nova object is bad)

Then after the input/output format is changed, we just need update the json-schema,
we needn’t any modify for API python code.

Note that with this method, we need json-schema for response also, there already
have plan to move response json-schema into nova. So that won’t be an extra work.

After make the python code only accept a flat dict instead of whole request body,
the code need some simple change as below:

The code looks more. But actually the most of work is just copy the 2.1 json-schema
as 3.0, and change the inconsistent in the 3.0 json-schema. I chose just put the each
version json-schema in the file, and naming with version. That make the json-schema
easy to maintenance and more readable for dev. And the wsgi infrastruct implementation
is more simple.

There are more things need to be explaned.

The mapping info:

1

'ext:mapping':{'result_a':'result_a'}

The wsgi code will use this mapping info to map the input/output into/from flat dict
(or nova objects).

Actually this is also kind of translation. But without format knowledge in the
python code, this reduce the complex in our wsgi infrastruct. We just need implement
tranlsation to mapping the input into flat dict (nova objects). We needn’t support
different kind of instruct, and needn’t to translate the json-schema.

The decorator wsgi.response

1

@wsgi.version(base='2.1',max='3.0')

This decorator means the request version between 2.1 and 3.0 will be routed into
this function. If there isn’t support any version between 2.1 and 3.0, there also
no json-schema for that version, the wsgi code will return error for the user.

We only write new function for same api when we have semantic change. This is
more readable than we execute different version internal function in same api function.
(compare to https://review.openstack.org/82301)

And also easy to maintenance than we add function for each API version (Add function
for each API version come from micro-version discussion previously).

If there are duplicate code between two version some_action function, we just need
move the duplicate code into common function as we share code in normally.

The complete demo for user-case with real API is in the POC last 4 commits.

After we provide separated policy rule for all the API. There is one more thing
we can do. It is about doing the policy enforcemance by wsgi infrastructure.
Currently the each policy enforcement need write one line code in the api layer:

1

authorize(context,target=instance,action="some_action")

We can eliminate this duplicated code.

So hope the wsgi infrasturcture can doing that. For policy enforcement, policy rule
need check with ‘target’. So there need way let wsgi infrastruct to know how to
generate the target for policy checks.