Add Chassis object.
Implements blueprint: ironic-object-model Change-Id: I0e59ee964072d3ae0889a58ec739bc485dee2a87
This commit is contained in:
parent
14dd6ff33f
commit
8b5a467a38
@ -314,6 +314,7 @@ class Connection(api.Connection):
|
||||
if count != 1:
|
||||
raise exception.PortNotFound(port=port)
|
||||
|
||||
@objects.objectify(objects.Chassis)
|
||||
def get_chassis(self, chassis):
|
||||
query = model_query(models.Chassis)
|
||||
query = add_identity_filter(query, chassis)
|
||||
@ -323,12 +324,14 @@ class Connection(api.Connection):
|
||||
except NoResultFound:
|
||||
raise exception.ChassisNotFound(chassis=chassis)
|
||||
|
||||
@objects.objectify(objects.Chassis)
|
||||
def create_chassis(self, values):
|
||||
chassis = models.Chassis()
|
||||
chassis.update(values)
|
||||
chassis.save()
|
||||
return chassis
|
||||
|
||||
@objects.objectify(objects.Chassis)
|
||||
def update_chassis(self, chassis, values):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
|
@ -12,6 +12,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import functools
|
||||
|
||||
from ironic.objects import chassis
|
||||
from ironic.objects import node
|
||||
from ironic.objects import port
|
||||
|
||||
@ -19,6 +22,7 @@ from ironic.objects import port
|
||||
def objectify(klass):
|
||||
"""Decorator to convert database results into specified objects."""
|
||||
def the_decorator(fn):
|
||||
@functools.wraps(fn)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = fn(*args, **kwargs)
|
||||
try:
|
||||
@ -30,9 +34,11 @@ def objectify(klass):
|
||||
return wrapper
|
||||
return the_decorator
|
||||
|
||||
Chassis = chassis.Chassis
|
||||
Node = node.Node
|
||||
Port = port.Port
|
||||
|
||||
__all__ = (Node,
|
||||
__all__ = (Chassis,
|
||||
Node,
|
||||
Port,
|
||||
objectify)
|
||||
|
88
ironic/objects/chassis.py
Normal file
88
ironic/objects/chassis.py
Normal file
@ -0,0 +1,88 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# coding=utf-8
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
|
||||
from ironic.db import api as dbapi
|
||||
from ironic.objects import base
|
||||
from ironic.objects import utils
|
||||
|
||||
|
||||
class Chassis(base.IronicObject):
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'id': int,
|
||||
'uuid': utils.str_or_none,
|
||||
'extra': utils.str_or_none,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(chassis, db_chassis):
|
||||
"""Converts a database entity to a formal :class:`Chassis` object.
|
||||
|
||||
:param chassis: An object of :class:`Chassis`.
|
||||
:param db_chassis: A DB model of a chassis.
|
||||
:return: a :class:`Chassis` object.
|
||||
"""
|
||||
for field in chassis.fields:
|
||||
chassis[field] = db_chassis[field]
|
||||
|
||||
chassis.obj_reset_changes()
|
||||
return chassis
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid=None):
|
||||
"""Find a chassis based on uuid and return a :class:`Chassis` object.
|
||||
|
||||
:param uuid: the uuid of a chassis.
|
||||
:returns: a :class:`Chassis` object.
|
||||
"""
|
||||
db_chassis = cls.dbapi.get_chassis(uuid)
|
||||
return Chassis._from_db_object(cls(), db_chassis)
|
||||
|
||||
@base.remotable
|
||||
def save(self, context):
|
||||
"""Save updates to this Chassis.
|
||||
|
||||
Updates will be made column by column based on the result
|
||||
of self.what_changed(). If expected_task_state is provided,
|
||||
it will be checked against the in-database copy of the chassis
|
||||
before updates are made.
|
||||
|
||||
:param context: Security context
|
||||
"""
|
||||
updates = {}
|
||||
changes = self.obj_what_changed()
|
||||
for field in changes:
|
||||
updates[field] = self[field]
|
||||
self.dbapi.update_chassis(self.uuid, updates)
|
||||
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
def refresh(self, context):
|
||||
"""Loads and applies updates for this Chassis.
|
||||
|
||||
Loads a :class:`Chassis` with the same uuid from the database and
|
||||
checks for updated attributes. Updates are applied from
|
||||
the loaded chassis column by column, if there are any updates.
|
||||
|
||||
:param context: Security context
|
||||
"""
|
||||
current = self.__class__.get_by_uuid(context, uuid=self.uuid)
|
||||
for field in self.fields:
|
||||
if (hasattr(self, base.get_attrname(field)) and
|
||||
self[field] != current[field]):
|
||||
self[field] = current[field]
|
106
ironic/tests/objects/test_chassis.py
Normal file
106
ironic/tests/objects/test_chassis.py
Normal file
@ -0,0 +1,106 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# coding=utf-8
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
|
||||
from ironic.common import context
|
||||
from ironic.db import api as db_api
|
||||
from ironic.db.sqlalchemy import models
|
||||
from ironic import objects
|
||||
from ironic.openstack.common import uuidutils
|
||||
from ironic.tests.db import base
|
||||
from ironic.tests.db import utils
|
||||
|
||||
|
||||
class TestChassisObject(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestChassisObject, self).setUp()
|
||||
self.fake_chassis = utils.get_test_chassis()
|
||||
self.dbapi = db_api.get_instance()
|
||||
self.ctxt = context.get_admin_context()
|
||||
|
||||
def test_load(self):
|
||||
uuid = self.fake_chassis['uuid']
|
||||
|
||||
self.mox.StubOutWithMock(self.dbapi, 'get_chassis')
|
||||
self.dbapi.get_chassis(uuid).AndReturn(self.fake_chassis)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
objects.Chassis.get_by_uuid(self.ctxt, uuid)
|
||||
self.mox.VerifyAll()
|
||||
|
||||
def test_save(self):
|
||||
uuid = self.fake_chassis['uuid']
|
||||
|
||||
self.mox.StubOutWithMock(self.dbapi, 'get_chassis')
|
||||
self.mox.StubOutWithMock(self.dbapi, 'update_chassis')
|
||||
self.dbapi.get_chassis(uuid).AndReturn(self.fake_chassis)
|
||||
|
||||
self.dbapi.update_chassis(uuid, {'extra': '{"test": 123}'})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
c = objects.Chassis.get_by_uuid(self.ctxt, uuid)
|
||||
c.extra = '{"test": 123}'
|
||||
c.save()
|
||||
self.mox.VerifyAll()
|
||||
|
||||
def test_refresh(self):
|
||||
uuid = self.fake_chassis['uuid']
|
||||
new_uuid = uuidutils.generate_uuid()
|
||||
|
||||
self.mox.StubOutWithMock(self.dbapi, 'get_chassis')
|
||||
|
||||
self.dbapi.get_chassis(uuid).AndReturn(
|
||||
dict(self.fake_chassis, uuid=uuid))
|
||||
self.dbapi.get_chassis(uuid).AndReturn(
|
||||
dict(self.fake_chassis, uuid=new_uuid))
|
||||
self.mox.ReplayAll()
|
||||
|
||||
c = objects.Chassis.get_by_uuid(self.ctxt, uuid)
|
||||
self.assertEqual(c.uuid, uuid)
|
||||
c.refresh()
|
||||
self.assertEqual(c.uuid, new_uuid)
|
||||
self.mox.VerifyAll()
|
||||
|
||||
def test_objectify(self):
|
||||
def _get_db_chassis():
|
||||
c = models.Chassis()
|
||||
c.update(self.fake_chassis)
|
||||
return c
|
||||
|
||||
@objects.objectify(objects.Chassis)
|
||||
def _convert_db_chassis():
|
||||
return _get_db_chassis()
|
||||
|
||||
self.assertIsInstance(_get_db_chassis(), models.Chassis)
|
||||
self.assertIsInstance(_convert_db_chassis(), objects.Chassis)
|
||||
|
||||
def test_objectify_many(self):
|
||||
def _get_many_db_chassis():
|
||||
chassis = []
|
||||
for i in xrange(5):
|
||||
c = models.Chassis()
|
||||
c.update(self.fake_chassis)
|
||||
chassis.append(c)
|
||||
return chassis
|
||||
|
||||
@objects.objectify(objects.Chassis)
|
||||
def _convert_many_db_chassis():
|
||||
return _get_many_db_chassis()
|
||||
|
||||
for c in _get_many_db_chassis():
|
||||
self.assertIsInstance(c, models.Chassis)
|
||||
for c in _convert_many_db_chassis():
|
||||
self.assertIsInstance(c, objects.Chassis)
|
Loading…
x
Reference in New Issue
Block a user