Merge "[placement] make PUT inventory consistent with GET"
This commit is contained in:
commit
09870549c9
@ -22,7 +22,7 @@ from nova.api.openstack.placement import util
|
|||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import objects
|
from nova import objects
|
||||||
|
|
||||||
|
RESOURCE_CLASS_IDENTIFIER = "^[A-Z0-9_]+$"
|
||||||
BASE_INVENTORY_SCHEMA = {
|
BASE_INVENTORY_SCHEMA = {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -57,10 +57,12 @@ BASE_INVENTORY_SCHEMA = {
|
|||||||
POST_INVENTORY_SCHEMA = copy.deepcopy(BASE_INVENTORY_SCHEMA)
|
POST_INVENTORY_SCHEMA = copy.deepcopy(BASE_INVENTORY_SCHEMA)
|
||||||
POST_INVENTORY_SCHEMA['properties']['resource_class'] = {
|
POST_INVENTORY_SCHEMA['properties']['resource_class'] = {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^[A-Z0-9_]+$"
|
"pattern": RESOURCE_CLASS_IDENTIFIER,
|
||||||
}
|
}
|
||||||
POST_INVENTORY_SCHEMA['required'].append('resource_class')
|
POST_INVENTORY_SCHEMA['required'].append('resource_class')
|
||||||
POST_INVENTORY_SCHEMA['required'].remove('resource_provider_generation')
|
POST_INVENTORY_SCHEMA['required'].remove('resource_provider_generation')
|
||||||
|
PUT_INVENTORY_RECORD_SCHEMA = copy.deepcopy(BASE_INVENTORY_SCHEMA)
|
||||||
|
PUT_INVENTORY_RECORD_SCHEMA['required'].remove('resource_provider_generation')
|
||||||
PUT_INVENTORY_SCHEMA = {
|
PUT_INVENTORY_SCHEMA = {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -68,8 +70,10 @@ PUT_INVENTORY_SCHEMA = {
|
|||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"inventories": {
|
"inventories": {
|
||||||
"type": "array",
|
"type": "object",
|
||||||
"items": POST_INVENTORY_SCHEMA
|
"patternProperties": {
|
||||||
|
RESOURCE_CLASS_IDENTIFIER: PUT_INVENTORY_RECORD_SCHEMA,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -130,17 +134,17 @@ def _extract_inventories(body, schema):
|
|||||||
"""Extract and validate multiple inventories from JSON body."""
|
"""Extract and validate multiple inventories from JSON body."""
|
||||||
data = _extract_json(body, schema)
|
data = _extract_json(body, schema)
|
||||||
|
|
||||||
inventories = []
|
inventories = {}
|
||||||
for raw_inventory in data['inventories']:
|
for res_class, raw_inventory in data['inventories'].items():
|
||||||
inventory_data = copy.copy(INVENTORY_DEFAULTS)
|
inventory_data = copy.copy(INVENTORY_DEFAULTS)
|
||||||
inventory_data.update(raw_inventory)
|
inventory_data.update(raw_inventory)
|
||||||
inventories.append(inventory_data)
|
inventories[res_class] = inventory_data
|
||||||
|
|
||||||
data['inventories'] = inventories
|
data['inventories'] = inventories
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def _make_inventory_object(resource_provider, **data):
|
def _make_inventory_object(resource_provider, resource_class, **data):
|
||||||
"""Single place to catch malformed Inventories."""
|
"""Single place to catch malformed Inventories."""
|
||||||
# TODO(cdent): Some of the validation checks that are done here
|
# TODO(cdent): Some of the validation checks that are done here
|
||||||
# could be done via JSONschema (using, for example, "minimum":
|
# could be done via JSONschema (using, for example, "minimum":
|
||||||
@ -148,11 +152,12 @@ def _make_inventory_object(resource_provider, **data):
|
|||||||
# duplication or decoupling so leaving it as this for now.
|
# duplication or decoupling so leaving it as this for now.
|
||||||
try:
|
try:
|
||||||
inventory = objects.Inventory(
|
inventory = objects.Inventory(
|
||||||
resource_provider=resource_provider, **data)
|
resource_provider=resource_provider,
|
||||||
|
resource_class=resource_class, **data)
|
||||||
except (ValueError, TypeError) as exc:
|
except (ValueError, TypeError) as exc:
|
||||||
raise webob.exc.HTTPBadRequest(
|
raise webob.exc.HTTPBadRequest(
|
||||||
'Bad inventory %s for resource provider %s: %s'
|
'Bad inventory %s for resource provider %s: %s'
|
||||||
% (data['resource_class'], resource_provider.uuid, exc),
|
% (resource_class, resource_provider.uuid, exc),
|
||||||
json_formatter=util.json_error_formatter)
|
json_formatter=util.json_error_formatter)
|
||||||
return inventory
|
return inventory
|
||||||
|
|
||||||
@ -210,8 +215,11 @@ def create_inventory(req):
|
|||||||
resource_provider = objects.ResourceProvider.get_by_uuid(
|
resource_provider = objects.ResourceProvider.get_by_uuid(
|
||||||
context, uuid)
|
context, uuid)
|
||||||
data = _extract_inventory(req.body, POST_INVENTORY_SCHEMA)
|
data = _extract_inventory(req.body, POST_INVENTORY_SCHEMA)
|
||||||
|
resource_class = data.pop('resource_class')
|
||||||
|
|
||||||
inventory = _make_inventory_object(resource_provider, **data)
|
inventory = _make_inventory_object(resource_provider,
|
||||||
|
resource_class,
|
||||||
|
**data)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resource_provider.add_inventory(inventory)
|
resource_provider.add_inventory(inventory)
|
||||||
@ -228,7 +236,7 @@ def create_inventory(req):
|
|||||||
|
|
||||||
response = req.response
|
response = req.response
|
||||||
response.location = util.inventory_url(
|
response.location = util.inventory_url(
|
||||||
req.environ, resource_provider, data['resource_class'])
|
req.environ, resource_provider, resource_class)
|
||||||
return _send_inventory(response, resource_provider, inventory,
|
return _send_inventory(response, resource_provider, inventory,
|
||||||
status=201)
|
status=201)
|
||||||
|
|
||||||
@ -335,9 +343,9 @@ def set_inventories(req):
|
|||||||
json_formatter=util.json_error_formatter)
|
json_formatter=util.json_error_formatter)
|
||||||
|
|
||||||
inv_list = []
|
inv_list = []
|
||||||
for inventory_data in data['inventories']:
|
for res_class, inventory_data in data['inventories'].items():
|
||||||
inventory = _make_inventory_object(
|
inventory = _make_inventory_object(
|
||||||
resource_provider, **inventory_data)
|
resource_provider, res_class, **inventory_data)
|
||||||
inv_list.append(inventory)
|
inv_list.append(inventory)
|
||||||
inventories = objects.InventoryList(objects=inv_list)
|
inventories = objects.InventoryList(objects=inv_list)
|
||||||
|
|
||||||
@ -383,8 +391,9 @@ def update_inventory(req):
|
|||||||
'resource provider generation conflict',
|
'resource provider generation conflict',
|
||||||
json_formatter=util.json_error_formatter)
|
json_formatter=util.json_error_formatter)
|
||||||
|
|
||||||
data['resource_class'] = resource_class
|
inventory = _make_inventory_object(resource_provider,
|
||||||
inventory = _make_inventory_object(resource_provider, **data)
|
resource_class,
|
||||||
|
**data)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resource_provider.update_inventory(inventory)
|
resource_provider.update_inventory(inventory)
|
||||||
|
@ -266,9 +266,9 @@ tests:
|
|||||||
# of other changes
|
# of other changes
|
||||||
resource_provider_generation: 0
|
resource_provider_generation: 0
|
||||||
inventories:
|
inventories:
|
||||||
- resource_class: VCPU
|
VCPU:
|
||||||
total: 32
|
total: 32
|
||||||
- resource_class: DISK_GB
|
DISK_GB:
|
||||||
total: 10
|
total: 10
|
||||||
|
|
||||||
- name: set inventory on rp2
|
- name: set inventory on rp2
|
||||||
@ -280,9 +280,9 @@ tests:
|
|||||||
# of other changes
|
# of other changes
|
||||||
resource_provider_generation: 0
|
resource_provider_generation: 0
|
||||||
inventories:
|
inventories:
|
||||||
- resource_class: VCPU
|
VCPU:
|
||||||
total: 16
|
total: 16
|
||||||
- resource_class: DISK_GB
|
DISK_GB:
|
||||||
total: 20
|
total: 20
|
||||||
status: 200
|
status: 200
|
||||||
|
|
||||||
|
@ -160,6 +160,8 @@ tests:
|
|||||||
resource_class: NO_CLASS_14
|
resource_class: NO_CLASS_14
|
||||||
total: 2048
|
total: 2048
|
||||||
status: 400
|
status: 400
|
||||||
|
response_strings:
|
||||||
|
- Bad inventory NO_CLASS_14 for resource provider $ENVIRON['RP_UUID']
|
||||||
|
|
||||||
- name: post inventory duplicated resource class
|
- name: post inventory duplicated resource class
|
||||||
desc: DISK_GB was already created above
|
desc: DISK_GB was already created above
|
||||||
@ -258,9 +260,9 @@ tests:
|
|||||||
data:
|
data:
|
||||||
resource_provider_generation: 0
|
resource_provider_generation: 0
|
||||||
inventories:
|
inventories:
|
||||||
- resource_class: IPV4_ADDRESS
|
IPV4_ADDRESS:
|
||||||
total: 253
|
total: 253
|
||||||
- resource_class: DISK_GB
|
DISK_GB:
|
||||||
total: 1024
|
total: 1024
|
||||||
status: 200
|
status: 200
|
||||||
response_json_paths:
|
response_json_paths:
|
||||||
@ -287,7 +289,7 @@ tests:
|
|||||||
data:
|
data:
|
||||||
resource_provider_generation: 99
|
resource_provider_generation: 99
|
||||||
inventories:
|
inventories:
|
||||||
- resource_class: IPV4_ADDRESS
|
IPV4_ADDRESS:
|
||||||
total: 253
|
total: 253
|
||||||
status: 409
|
status: 409
|
||||||
response_strings:
|
response_strings:
|
||||||
@ -302,7 +304,7 @@ tests:
|
|||||||
data:
|
data:
|
||||||
resource_provider_generation: 6
|
resource_provider_generation: 6
|
||||||
inventories:
|
inventories:
|
||||||
- resource_class: IPV4_ADDRESS
|
IPV4_ADDRESS:
|
||||||
total: 253
|
total: 253
|
||||||
reserved: 512
|
reserved: 512
|
||||||
status: 400
|
status: 400
|
||||||
|
Loading…
Reference in New Issue
Block a user