Well, first versioned objects in the tree.
Binding to networks and ports is not implemented.
No tests. Checked manually.
blueprint quantum-qos-api
Co-Authored-By: vikram.choudhary <vikram.choudhary@huawei.com>
Change-Id: I9b6cacfda4f40230d746222bed5b6c490be63743
from oslo_config import cfg
from oslo_db import exception as os_db_exception
from oslo_db.sqlalchemy import session
+from oslo_utils import uuidutils
from sqlalchemy import exc
from sqlalchemy import orm
+from neutron.db import common_db_mixin
+
_FACADE = None
except self.to_catch as e:
raise os_db_exception.RetryRequest(e)
return wrapper
+
+
+# Common database operation implementations
+def get_object(context, model, id):
+ with context.session.begin(subtransactions=True):
+ return (common_db_mixin.model_query(context, model)
+ .filter_by(id=id)
+ .one())
+
+
+def get_objects(context, model):
+ with context.session.begin(subtransactions=True):
+ return common_db_mixin.model_query(context, model).all()
+
+
+def create_object(context, model, values):
+ with context.session.begin(subtransactions=True):
+ if 'id' not in values:
+ values['id'] = uuidutils.generate_uuid()
+ db_obj = model(**values)
+ context.session.add(db_obj)
+ return db_obj.__dict__
+
+
+def update_object(context, model, id, values):
+ with context.session.begin(subtransactions=True):
+ db_obj = get_object(context, model, id)
+ db_obj.update(values)
+ db_obj.save(session=context.session)
+ return db_obj.__dict__
+
+
+def delete_object(context, model, id):
+ with context.session.begin(subtransactions=True):
+ db_obj = get_object(context, model, id)
+ db_obj.delete()
--- /dev/null
+# 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 abc
+
+from oslo_versionedobjects import base as obj_base
+import six
+
+from neutron.db import api as db_api
+
+
+# TODO(QoS): revisit dict compatibility and how we can isolate dict behavior
+
+
+@six.add_metaclass(abc.ABCMeta)
+class NeutronObject(obj_base.VersionedObject,
+ obj_base.VersionedObjectDictCompat):
+
+ # should be overridden for all persistent objects
+ db_model = None
+
+ def from_db_object(self, *objs):
+ for field in self.fields:
+ for db_obj in objs:
+ if field in db_obj:
+ setattr(self, field, db_obj[field])
+ break
+ self.obj_reset_changes()
+
+ @classmethod
+ def get_by_id(cls, context, id):
+ db_obj = db_api.get_object(context, cls.db_model, id)
+ return cls(context, **db_obj)
+
+ @classmethod
+ def get_objects(cls, context):
+ db_objs = db_api.get_objects(context, cls.db_model)
+ objs = [cls(context, **db_obj) for db_obj in db_objs]
+ return objs
+
+ def create(self):
+ fields = self.obj_get_changes()
+ db_obj = db_api.create_object(self._context, self.db_model, fields)
+ self.from_db_object(db_obj)
+
+ def update(self):
+ updates = self.obj_get_changes()
+ db_obj = db_api.update_object(self._context, self.db_model,
+ self.id, updates)
+ self.from_db_object(self, db_obj)
+
+ def delete(self):
+ db_api.delete_object(self._context, self.db_model, self.id)
--- /dev/null
+# Copyright 2015 Red Hat, Inc.
+# All Rights Reserved.
+#
+# 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 oslo_versionedobjects import base as obj_base
+from oslo_versionedobjects import fields as obj_fields
+
+from neutron.db.qos import models as qos_db_model
+from neutron.objects import base
+
+
+# TODO(QoS): add rule lists to object fields
+# TODO(QoS): implement something for binding networks and ports with policies
+
+
+@obj_base.VersionedObjectRegistry.register
+class QosPolicy(base.NeutronObject):
+
+ db_model = qos_db_model.QosPolicy
+
+ fields = {
+ 'id': obj_fields.UUIDField(),
+ 'tenant_id': obj_fields.UUIDField(),
+ 'name': obj_fields.StringField(),
+ 'description': obj_fields.StringField(),
+ 'shared': obj_fields.BooleanField()
+ }
--- /dev/null
+# Copyright 2015 Huawei Technologies India Pvt Ltd, Inc.
+# All Rights Reserved.
+#
+# 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 abc
+
+from oslo_versionedobjects import base as obj_base
+from oslo_versionedobjects import fields as obj_fields
+import six
+
+from neutron.db import api as db_api
+from neutron.db.qos import models as qos_db_model
+from neutron.objects import base
+
+
+@six.add_metaclass(abc.ABCMeta)
+class QosRule(base.NeutronObject):
+
+ base_db_model = qos_db_model.QosRule
+
+ fields = {
+ 'id': obj_fields.UUIDField(),
+ 'tenant_id': obj_fields.UUIDField(),
+ 'type': obj_fields.StringField(),
+ 'qos_policy_id': obj_fields.UUIDField()
+ }
+
+ _core_fields = list(fields.keys())
+
+ @classmethod
+ def _is_core_field(cls, field):
+ return field in cls._core_fields
+
+ @staticmethod
+ def _filter_fields(fields, func):
+ return {
+ key: val for key, val in fields.items()
+ if func(key)
+ }
+
+ # TODO(QoS): reimplement get_by_id to merge both core and addn fields
+
+ def _get_changed_core_fields(self):
+ fields = self.obj_get_changes()
+ return self._filter_fields(fields, self._is_core_field)
+
+ def _get_changed_addn_fields(self):
+ fields = self.obj_get_changes()
+ return self._filter_fields(
+ fields, lambda key: not self._is_core_field(key))
+
+ # TODO(QoS): create and update are not transactional safe
+ def create(self):
+
+ # create base qos_rule
+ core_fields = self._get_changed_core_fields()
+ base_db_obj = db_api.create_object(
+ self._context, self.base_db_model, core_fields)
+
+ # create type specific qos_..._rule
+ addn_fields = self._get_changed_addn_fields()
+ addn_fields['qos_rule_id'] = base_db_obj.id
+ addn_db_obj = db_api.create_object(
+ self._context, self.db_model, addn_fields)
+
+ # merge two db objects into single neutron one
+ self.from_db_object(self._context, self, base_db_obj, addn_db_obj)
+
+ def update(self):
+ updated_db_objs = []
+
+ # update base qos_rule, if needed
+ core_fields = self._get_changed_core_fields()
+ if core_fields:
+ base_db_obj = db_api.create_object(
+ self._context, self.base_db_model, core_fields)
+ updated_db_objs.append(base_db_obj)
+
+ addn_fields = self._get_changed_addn_fields()
+ if addn_fields:
+ addn_db_obj = db_api.update_object(
+ self._context, self.base_db_model, self.id, addn_fields)
+ updated_db_objs.append(addn_db_obj)
+
+ # update neutron object with values from both database objects
+ self.from_db_object(self._context, self, *updated_db_objs)
+
+ # delete is the same, additional rule object cleanup is done thru cascading
+
+
+@obj_base.VersionedObjectRegistry.register
+class QosBandwidthLimitRule(QosRule):
+
+ db_model = qos_db_model.QosBandwidthLimitRule
+
+ fields = {
+ 'max_kbps': obj_fields.IntegerField(),
+ 'max_burst_kbps': obj_fields.IntegerField()
+ }
oslo.serialization>=1.4.0 # Apache-2.0
oslo.service>=0.1.0 # Apache-2.0
oslo.utils>=1.6.0 # Apache-2.0
+oslo.versionedobjects>=0.3.0,!=0.5.0
python-novaclient>=2.22.0