This code is imported from Ironic with new tests, so that it can
be reused in other projects (I need it for ironic-inspector).
Some small enhancements were made to the imported code:
* Non-capitalized JSON word in names
* Base type can be used on its own
Change-Id: Ic991f34c5b5f091d8627643367cdaa73ad2b1236