104 lines
3.5 KiB
Python
104 lines
3.5 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import six
|
|
import sqlalchemy as sa
|
|
|
|
from placement.db.sqlalchemy import models
|
|
from placement import db_api
|
|
from placement import resource_class_cache as rc_cache
|
|
|
|
|
|
_INV_TBL = models.Inventory.__table__
|
|
|
|
|
|
class Inventory(object):
|
|
|
|
# kwargs included because some constructors pass resource_class_id
|
|
# but it is not used.
|
|
def __init__(self, id=None, resource_provider=None, resource_class=None,
|
|
total=None, reserved=0, min_unit=1, max_unit=1, step_size=1,
|
|
allocation_ratio=1.0, updated_at=None, created_at=None,
|
|
**kwargs):
|
|
self.id = id
|
|
self.resource_provider = resource_provider
|
|
self.resource_class = resource_class
|
|
self.total = total
|
|
self.reserved = reserved
|
|
self.min_unit = min_unit
|
|
self.max_unit = max_unit
|
|
self.step_size = step_size
|
|
self.allocation_ratio = allocation_ratio
|
|
self.updated_at = updated_at
|
|
self.created_at = created_at
|
|
|
|
@property
|
|
def capacity(self):
|
|
"""Inventory capacity, adjusted by allocation_ratio."""
|
|
return int((self.total - self.reserved) * self.allocation_ratio)
|
|
|
|
|
|
def find(inventories, res_class):
|
|
"""Return the inventory record from the list of Inventory records that
|
|
matches the supplied resource class, or None.
|
|
|
|
:param inventories: A list of Inventory objects.
|
|
:param res_class: An integer or string representing a resource
|
|
class. If the value is a string, the method first
|
|
looks up the resource class identifier from the
|
|
string.
|
|
"""
|
|
if not isinstance(res_class, six.string_types):
|
|
raise ValueError
|
|
|
|
for inv_rec in inventories:
|
|
if inv_rec.resource_class == res_class:
|
|
return inv_rec
|
|
|
|
|
|
def get_all_by_resource_provider(context, rp):
|
|
db_inv = _get_inventory_by_provider_id(context, rp.id)
|
|
# Build up a list of Inventory objects, setting the Inventory object
|
|
# fields to the same-named database record field we got from
|
|
# _get_inventory_by_provider_id(). We already have the ResourceProvider
|
|
# object so we just pass that object to the Inventory object
|
|
# constructor as-is
|
|
inv_list = [
|
|
Inventory(
|
|
resource_provider=rp,
|
|
resource_class=rc_cache.RC_CACHE.string_from_id(
|
|
rec['resource_class_id']),
|
|
**rec)
|
|
for rec in db_inv
|
|
]
|
|
return inv_list
|
|
|
|
|
|
@db_api.placement_context_manager.reader
|
|
def _get_inventory_by_provider_id(ctx, rp_id):
|
|
inv = sa.alias(_INV_TBL, name="i")
|
|
cols = [
|
|
inv.c.resource_class_id,
|
|
inv.c.total,
|
|
inv.c.reserved,
|
|
inv.c.min_unit,
|
|
inv.c.max_unit,
|
|
inv.c.step_size,
|
|
inv.c.allocation_ratio,
|
|
inv.c.updated_at,
|
|
inv.c.created_at,
|
|
]
|
|
sel = sa.select(cols)
|
|
sel = sel.where(inv.c.resource_provider_id == rp_id)
|
|
|
|
return [dict(r) for r in ctx.session.execute(sel)]
|