Metering to OVO
This patch introduces and implements OVO for metering Change-Id: I168e113de6651b3a91183ed148338a26bef663cb Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db Co-Authored-By: Eli Qiao <liyong.qiao@intel.com>
This commit is contained in:
parent
7b7be92bfb
commit
fdc3e8146c
|
@ -15,7 +15,6 @@
|
|||
import netaddr
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_utils import uuidutils
|
||||
from sqlalchemy import orm
|
||||
|
||||
from neutron.api.rpc.agentnotifiers import metering_rpc_agent_api
|
||||
from neutron.common import constants
|
||||
|
@ -27,6 +26,8 @@ from neutron.db import l3_dvr_db
|
|||
from neutron.db.models import l3 as l3_models
|
||||
from neutron.db.models import metering as metering_models
|
||||
from neutron.extensions import metering
|
||||
from neutron.objects import base as base_obj
|
||||
from neutron.objects import metering as metering_objs
|
||||
|
||||
|
||||
class MeteringDbMixin(metering.MeteringPluginBase,
|
||||
|
@ -47,50 +48,39 @@ class MeteringDbMixin(metering.MeteringPluginBase,
|
|||
def create_metering_label(self, context, metering_label):
|
||||
m = metering_label['metering_label']
|
||||
|
||||
with db_api.context_manager.writer.using(context):
|
||||
metering_db = metering_models.MeteringLabel(
|
||||
id=uuidutils.generate_uuid(),
|
||||
description=m['description'],
|
||||
tenant_id=m['tenant_id'],
|
||||
name=m['name'],
|
||||
shared=m['shared'])
|
||||
context.session.add(metering_db)
|
||||
metering_obj = metering_objs.MeteringLabel(
|
||||
context, id=uuidutils.generate_uuid(),
|
||||
description=m['description'], project_id=m['tenant_id'],
|
||||
name=m['name'], shared=m['shared'])
|
||||
metering_obj.create()
|
||||
return self._make_metering_label_dict(metering_obj)
|
||||
|
||||
return self._make_metering_label_dict(metering_db)
|
||||
def _get_metering_label(self, context, label_id):
|
||||
metering_label = metering_objs.MeteringLabel.get_object(context,
|
||||
id=label_id)
|
||||
if not metering_label:
|
||||
raise metering.MeteringLabelNotFound(label_id=label_id)
|
||||
return metering_label
|
||||
|
||||
def delete_metering_label(self, context, label_id):
|
||||
with db_api.context_manager.writer.using(context):
|
||||
try:
|
||||
label = model_query.get_by_id(context,
|
||||
metering_models.MeteringLabel,
|
||||
label_id)
|
||||
except orm.exc.NoResultFound:
|
||||
raise metering.MeteringLabelNotFound(label_id=label_id)
|
||||
|
||||
context.session.delete(label)
|
||||
|
||||
def get_metering_label(self, context, label_id, fields=None):
|
||||
try:
|
||||
metering_label = model_query.get_by_id(
|
||||
context, metering_models.MeteringLabel, label_id)
|
||||
except orm.exc.NoResultFound:
|
||||
deleted = metering_objs.MeteringLabel.delete_objects(
|
||||
context, id=label_id)
|
||||
if not deleted:
|
||||
raise metering.MeteringLabelNotFound(label_id=label_id)
|
||||
|
||||
return self._make_metering_label_dict(metering_label, fields)
|
||||
def get_metering_label(self, context, label_id, fields=None):
|
||||
return self._make_metering_label_dict(
|
||||
self._get_metering_label(context, label_id), fields)
|
||||
|
||||
def get_metering_labels(self, context, filters=None, fields=None,
|
||||
sorts=None, limit=None, marker=None,
|
||||
page_reverse=False):
|
||||
marker_obj = self._get_marker_obj(context, 'metering_labels', limit,
|
||||
marker)
|
||||
return model_query.get_collection(context,
|
||||
metering_models.MeteringLabel,
|
||||
self._make_metering_label_dict,
|
||||
filters=filters, fields=fields,
|
||||
sorts=sorts,
|
||||
limit=limit,
|
||||
marker_obj=marker_obj,
|
||||
page_reverse=page_reverse)
|
||||
filters = filters or {}
|
||||
pager = base_obj.Pager(sorts, limit, page_reverse, marker)
|
||||
metering_labels = metering_objs.MeteringLabel.get_objects(context,
|
||||
_pager=pager,
|
||||
**filters)
|
||||
return [self._make_metering_label_dict(ml) for ml in metering_labels]
|
||||
|
||||
@staticmethod
|
||||
def _make_metering_label_rule_dict(metering_label_rule, fields=None):
|
||||
|
@ -104,26 +94,23 @@ class MeteringDbMixin(metering.MeteringPluginBase,
|
|||
def get_metering_label_rules(self, context, filters=None, fields=None,
|
||||
sorts=None, limit=None, marker=None,
|
||||
page_reverse=False):
|
||||
marker_obj = self._get_marker_obj(context, 'metering_label_rules',
|
||||
limit, marker)
|
||||
filters = filters or {}
|
||||
pager = base_obj.Pager(sorts, limit, page_reverse, marker)
|
||||
metering_label_rules = metering_objs.MeteringLabelRule.get_objects(
|
||||
context, _pager=pager, **filters)
|
||||
return [self._make_metering_label_rule_dict(mlr)
|
||||
for mlr in metering_label_rules]
|
||||
|
||||
return model_query.get_collection(context,
|
||||
metering_models.MeteringLabelRule,
|
||||
self._make_metering_label_rule_dict,
|
||||
filters=filters, fields=fields,
|
||||
sorts=sorts,
|
||||
limit=limit,
|
||||
marker_obj=marker_obj,
|
||||
page_reverse=page_reverse)
|
||||
def _get_metering_label_rule(self, context, rule_id):
|
||||
metering_label_rule = metering_objs.MeteringLabelRule.get_object(
|
||||
context, id=rule_id)
|
||||
if not metering_label_rule:
|
||||
raise metering.MeteringLabelRuleNotFound(rule_id=rule_id)
|
||||
return metering_label_rule
|
||||
|
||||
def get_metering_label_rule(self, context, rule_id, fields=None):
|
||||
try:
|
||||
metering_label_rule = model_query.get_by_id(
|
||||
context, metering_models.MeteringLabelRule, rule_id)
|
||||
except orm.exc.NoResultFound:
|
||||
raise metering.MeteringLabelRuleNotFound(rule_id=rule_id)
|
||||
|
||||
return self._make_metering_label_rule_dict(metering_label_rule, fields)
|
||||
return self._make_metering_label_rule_dict(
|
||||
self._get_metering_label_rule(context, rule_id), fields)
|
||||
|
||||
def _validate_cidr(self, context, label_id, remote_ip_prefix,
|
||||
direction, excluded):
|
||||
|
@ -153,28 +140,21 @@ class MeteringDbMixin(metering.MeteringPluginBase,
|
|||
|
||||
self._validate_cidr(context, label_id, ip_prefix, direction,
|
||||
excluded)
|
||||
metering_db = metering_models.MeteringLabelRule(
|
||||
id=uuidutils.generate_uuid(),
|
||||
metering_label_id=label_id,
|
||||
direction=direction,
|
||||
rule = metering_objs.MeteringLabelRule(
|
||||
context, id=uuidutils.generate_uuid(),
|
||||
metering_label_id=label_id, direction=direction,
|
||||
excluded=m['excluded'],
|
||||
remote_ip_prefix=ip_prefix)
|
||||
context.session.add(metering_db)
|
||||
|
||||
remote_ip_prefix=netaddr.IPNetwork(ip_prefix))
|
||||
rule.create()
|
||||
except db_exc.DBReferenceError:
|
||||
raise metering.MeteringLabelNotFound(label_id=label_id)
|
||||
|
||||
return self._make_metering_label_rule_dict(metering_db)
|
||||
return self._make_metering_label_rule_dict(rule)
|
||||
|
||||
def delete_metering_label_rule(self, context, rule_id):
|
||||
with db_api.context_manager.writer.using(context):
|
||||
try:
|
||||
rule = model_query.get_by_id(context,
|
||||
metering_models.MeteringLabelRule,
|
||||
rule_id)
|
||||
except orm.exc.NoResultFound:
|
||||
raise metering.MeteringLabelRuleNotFound(rule_id=rule_id)
|
||||
context.session.delete(rule)
|
||||
rule = self._get_metering_label_rule(context, rule_id)
|
||||
rule.delete()
|
||||
|
||||
return self._make_metering_label_rule_dict(rule)
|
||||
|
||||
|
@ -233,6 +213,7 @@ class MeteringDbMixin(metering.MeteringPluginBase,
|
|||
metering_models.MeteringLabel).get(
|
||||
rule['metering_label_id'])
|
||||
|
||||
# TODO(electrocucaracha) This depends on the Router OVO implementation
|
||||
if label.shared:
|
||||
routers = model_query.get_collection_query(
|
||||
context, l3_models.Router)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
# Copyright (c) 2016 Intel Corporation.
|
||||
#
|
||||
# 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.common import utils
|
||||
from neutron.db.models import metering as metering_models
|
||||
from neutron.objects import base
|
||||
from neutron.objects import common_types
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class MeteringLabelRule(base.NeutronDbObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
db_model = metering_models.MeteringLabelRule
|
||||
|
||||
foreign_keys = {'MeteringLabel': {'metering_label_id': 'id'}}
|
||||
|
||||
fields = {
|
||||
'id': common_types.UUIDField(),
|
||||
'direction': common_types.FlowDirectionEnumField(nullable=True),
|
||||
'remote_ip_prefix': common_types.IPNetworkField(nullable=True),
|
||||
'metering_label_id': common_types.UUIDField(),
|
||||
'excluded': obj_fields.BooleanField(default=False),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def modify_fields_from_db(cls, db_obj):
|
||||
result = super(MeteringLabelRule, cls).modify_fields_from_db(db_obj)
|
||||
if 'remote_ip_prefix' in result:
|
||||
result['remote_ip_prefix'] = utils.AuthenticIPNetwork(
|
||||
result['remote_ip_prefix'])
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def modify_fields_to_db(cls, fields):
|
||||
result = super(MeteringLabelRule, cls).modify_fields_to_db(fields)
|
||||
if 'remote_ip_prefix' in result:
|
||||
result['remote_ip_prefix'] = cls.filter_to_str(
|
||||
result['remote_ip_prefix'])
|
||||
return result
|
||||
|
||||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class MeteringLabel(base.NeutronDbObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
db_model = metering_models.MeteringLabel
|
||||
synthetic_fields = ['rules']
|
||||
|
||||
fields = {
|
||||
'id': common_types.UUIDField(),
|
||||
'project_id': obj_fields.StringField(nullable=True),
|
||||
'name': obj_fields.StringField(),
|
||||
'description': obj_fields.StringField(),
|
||||
'rules': obj_fields.ListOfObjectsField('MeteringLabelRule',
|
||||
nullable=True),
|
||||
'shared': obj_fields.BooleanField(default=False),
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
# Copyright (c) 2016 Intel Corporation.
|
||||
#
|
||||
# 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 neutron.objects import metering
|
||||
from neutron.tests.unit.objects import test_base as obj_test_base
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
|
||||
class MeteringLabelRuleObjectTestCase(obj_test_base.BaseObjectIfaceTestCase):
|
||||
|
||||
_test_class = metering.MeteringLabelRule
|
||||
|
||||
|
||||
class MeteringLabelRuleDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = metering.MeteringLabelRule
|
||||
|
||||
def _create_test_metering_label_id(self, **attrs):
|
||||
attrs = self.get_random_object_fields(metering.MeteringLabel)
|
||||
metering_label = metering.MeteringLabel(self.context, **attrs)
|
||||
metering_label.create()
|
||||
return metering_label.id
|
||||
|
||||
def setUp(self):
|
||||
super(MeteringLabelRuleDbObjectTestCase, self).setUp()
|
||||
self.update_obj_fields(
|
||||
{'metering_label_id': self._create_test_metering_label_id})
|
||||
|
||||
|
||||
class MeteringLabelObjectTestCase(obj_test_base.BaseObjectIfaceTestCase):
|
||||
|
||||
_test_class = metering.MeteringLabel
|
||||
|
||||
|
||||
class MeteringLabelDbObjectTestCase(obj_test_base.BaseDbObjectTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
|
||||
_test_class = metering.MeteringLabel
|
|
@ -48,6 +48,8 @@ object_data = {
|
|||
'IpamAllocation': '1.0-ace65431abd0a7be84cc4a5f32d034a3',
|
||||
'IpamAllocationPool': '1.0-c4fa1460ed1b176022ede7af7d1510d5',
|
||||
'IpamSubnet': '1.0-713de401682a70f34891e13af645fa08',
|
||||
'MeteringLabel': '1.0-cc4b620a3425222447cbe459f62de533',
|
||||
'MeteringLabelRule': '1.0-b5c5717e7bab8d1af1623156012a5842',
|
||||
'Network': '1.0-f2f6308f79731a767b92b26b0f4f3849',
|
||||
'NetworkDNSDomain': '1.0-420db7910294608534c1e2e30d6d8319',
|
||||
'NetworkPortSecurity': '1.0-b30802391a87945ee9c07582b4ff95e3',
|
||||
|
|
|
@ -18,6 +18,7 @@ from neutron_lib.plugins import directory
|
|||
from oslo_utils import uuidutils
|
||||
|
||||
from neutron.api.v2 import attributes as attr
|
||||
from neutron.common import utils
|
||||
from neutron.db import api as db_api
|
||||
from neutron.db.metering import metering_rpc
|
||||
from neutron.db.models import agent as agent_model
|
||||
|
@ -247,7 +248,8 @@ class TestMeteringPlugin(test_db_base_plugin_v2.NeutronDbPluginV2TestCase,
|
|||
'tenant_id': self.tenant_id,
|
||||
'_metering_labels': [
|
||||
{'rule': {
|
||||
'remote_ip_prefix': '10.0.0.0/24',
|
||||
'remote_ip_prefix': utils.AuthenticIPNetwork(
|
||||
'10.0.0.0/24'),
|
||||
'direction': 'ingress',
|
||||
'metering_label_id': self.uuid,
|
||||
'excluded': False,
|
||||
|
@ -263,7 +265,8 @@ class TestMeteringPlugin(test_db_base_plugin_v2.NeutronDbPluginV2TestCase,
|
|||
'tenant_id': self.tenant_id,
|
||||
'_metering_labels': [
|
||||
{'rule': {
|
||||
'remote_ip_prefix': '10.0.0.0/24',
|
||||
'remote_ip_prefix': utils.AuthenticIPNetwork(
|
||||
'10.0.0.0/24'),
|
||||
'direction': 'ingress',
|
||||
'metering_label_id': self.uuid,
|
||||
'excluded': False,
|
||||
|
|
Loading…
Reference in New Issue