Merge "Metering to OVO"

This commit is contained in:
Jenkins 2017-04-27 15:02:31 +00:00 committed by Gerrit Code Review
commit c910841586
5 changed files with 180 additions and 70 deletions

View File

@ -15,7 +15,6 @@
import netaddr import netaddr
from oslo_db import exception as db_exc from oslo_db import exception as db_exc
from oslo_utils import uuidutils from oslo_utils import uuidutils
from sqlalchemy import orm
from neutron.api.rpc.agentnotifiers import metering_rpc_agent_api from neutron.api.rpc.agentnotifiers import metering_rpc_agent_api
from neutron.common import constants 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 l3 as l3_models
from neutron.db.models import metering as metering_models from neutron.db.models import metering as metering_models
from neutron.extensions import metering 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, class MeteringDbMixin(metering.MeteringPluginBase,
@ -47,50 +48,39 @@ class MeteringDbMixin(metering.MeteringPluginBase,
def create_metering_label(self, context, metering_label): def create_metering_label(self, context, metering_label):
m = metering_label['metering_label'] m = metering_label['metering_label']
with db_api.context_manager.writer.using(context): metering_obj = metering_objs.MeteringLabel(
metering_db = metering_models.MeteringLabel( context, id=uuidutils.generate_uuid(),
id=uuidutils.generate_uuid(), description=m['description'], project_id=m['tenant_id'],
description=m['description'], name=m['name'], shared=m['shared'])
tenant_id=m['tenant_id'], metering_obj.create()
name=m['name'], return self._make_metering_label_dict(metering_obj)
shared=m['shared'])
context.session.add(metering_db)
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): def delete_metering_label(self, context, label_id):
with db_api.context_manager.writer.using(context): deleted = metering_objs.MeteringLabel.delete_objects(
try: context, id=label_id)
label = model_query.get_by_id(context, if not deleted:
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:
raise metering.MeteringLabelNotFound(label_id=label_id) 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, def get_metering_labels(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None, sorts=None, limit=None, marker=None,
page_reverse=False): page_reverse=False):
marker_obj = self._get_marker_obj(context, 'metering_labels', limit, filters = filters or {}
marker) pager = base_obj.Pager(sorts, limit, page_reverse, marker)
return model_query.get_collection(context, metering_labels = metering_objs.MeteringLabel.get_objects(context,
metering_models.MeteringLabel, _pager=pager,
self._make_metering_label_dict, **filters)
filters=filters, fields=fields, return [self._make_metering_label_dict(ml) for ml in metering_labels]
sorts=sorts,
limit=limit,
marker_obj=marker_obj,
page_reverse=page_reverse)
@staticmethod @staticmethod
def _make_metering_label_rule_dict(metering_label_rule, fields=None): 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, def get_metering_label_rules(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None, sorts=None, limit=None, marker=None,
page_reverse=False): page_reverse=False):
marker_obj = self._get_marker_obj(context, 'metering_label_rules', filters = filters or {}
limit, marker) 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, def _get_metering_label_rule(self, context, rule_id):
metering_models.MeteringLabelRule, metering_label_rule = metering_objs.MeteringLabelRule.get_object(
self._make_metering_label_rule_dict, context, id=rule_id)
filters=filters, fields=fields, if not metering_label_rule:
sorts=sorts, raise metering.MeteringLabelRuleNotFound(rule_id=rule_id)
limit=limit, return metering_label_rule
marker_obj=marker_obj,
page_reverse=page_reverse)
def get_metering_label_rule(self, context, rule_id, fields=None): def get_metering_label_rule(self, context, rule_id, fields=None):
try: return self._make_metering_label_rule_dict(
metering_label_rule = model_query.get_by_id( self._get_metering_label_rule(context, rule_id), fields)
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)
def _validate_cidr(self, context, label_id, remote_ip_prefix, def _validate_cidr(self, context, label_id, remote_ip_prefix,
direction, excluded): direction, excluded):
@ -153,28 +140,21 @@ class MeteringDbMixin(metering.MeteringPluginBase,
self._validate_cidr(context, label_id, ip_prefix, direction, self._validate_cidr(context, label_id, ip_prefix, direction,
excluded) excluded)
metering_db = metering_models.MeteringLabelRule( rule = metering_objs.MeteringLabelRule(
id=uuidutils.generate_uuid(), context, id=uuidutils.generate_uuid(),
metering_label_id=label_id, metering_label_id=label_id, direction=direction,
direction=direction,
excluded=m['excluded'], excluded=m['excluded'],
remote_ip_prefix=ip_prefix) remote_ip_prefix=netaddr.IPNetwork(ip_prefix))
context.session.add(metering_db) rule.create()
except db_exc.DBReferenceError: except db_exc.DBReferenceError:
raise metering.MeteringLabelNotFound(label_id=label_id) 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): def delete_metering_label_rule(self, context, rule_id):
with db_api.context_manager.writer.using(context): with db_api.context_manager.writer.using(context):
try: rule = self._get_metering_label_rule(context, rule_id)
rule = model_query.get_by_id(context, rule.delete()
metering_models.MeteringLabelRule,
rule_id)
except orm.exc.NoResultFound:
raise metering.MeteringLabelRuleNotFound(rule_id=rule_id)
context.session.delete(rule)
return self._make_metering_label_rule_dict(rule) return self._make_metering_label_rule_dict(rule)
@ -233,6 +213,7 @@ class MeteringDbMixin(metering.MeteringPluginBase,
metering_models.MeteringLabel).get( metering_models.MeteringLabel).get(
rule['metering_label_id']) rule['metering_label_id'])
# TODO(electrocucaracha) This depends on the Router OVO implementation
if label.shared: if label.shared:
routers = model_query.get_collection_query( routers = model_query.get_collection_query(
context, l3_models.Router) context, l3_models.Router)

View File

@ -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),
}

View File

@ -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

View File

@ -48,6 +48,8 @@ object_data = {
'IpamAllocation': '1.0-ace65431abd0a7be84cc4a5f32d034a3', 'IpamAllocation': '1.0-ace65431abd0a7be84cc4a5f32d034a3',
'IpamAllocationPool': '1.0-c4fa1460ed1b176022ede7af7d1510d5', 'IpamAllocationPool': '1.0-c4fa1460ed1b176022ede7af7d1510d5',
'IpamSubnet': '1.0-713de401682a70f34891e13af645fa08', 'IpamSubnet': '1.0-713de401682a70f34891e13af645fa08',
'MeteringLabel': '1.0-cc4b620a3425222447cbe459f62de533',
'MeteringLabelRule': '1.0-b5c5717e7bab8d1af1623156012a5842',
'Network': '1.0-f2f6308f79731a767b92b26b0f4f3849', 'Network': '1.0-f2f6308f79731a767b92b26b0f4f3849',
'NetworkDNSDomain': '1.0-420db7910294608534c1e2e30d6d8319', 'NetworkDNSDomain': '1.0-420db7910294608534c1e2e30d6d8319',
'NetworkPortSecurity': '1.0-b30802391a87945ee9c07582b4ff95e3', 'NetworkPortSecurity': '1.0-b30802391a87945ee9c07582b4ff95e3',

View File

@ -18,6 +18,7 @@ from neutron_lib.plugins import directory
from oslo_utils import uuidutils from oslo_utils import uuidutils
from neutron.api.v2 import attributes as attr from neutron.api.v2 import attributes as attr
from neutron.common import utils
from neutron.db import api as db_api from neutron.db import api as db_api
from neutron.db.metering import metering_rpc from neutron.db.metering import metering_rpc
from neutron.db.models import agent as agent_model 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, 'tenant_id': self.tenant_id,
'_metering_labels': [ '_metering_labels': [
{'rule': { {'rule': {
'remote_ip_prefix': '10.0.0.0/24', 'remote_ip_prefix': utils.AuthenticIPNetwork(
'10.0.0.0/24'),
'direction': 'ingress', 'direction': 'ingress',
'metering_label_id': self.uuid, 'metering_label_id': self.uuid,
'excluded': False, 'excluded': False,
@ -263,7 +265,8 @@ class TestMeteringPlugin(test_db_base_plugin_v2.NeutronDbPluginV2TestCase,
'tenant_id': self.tenant_id, 'tenant_id': self.tenant_id,
'_metering_labels': [ '_metering_labels': [
{'rule': { {'rule': {
'remote_ip_prefix': '10.0.0.0/24', 'remote_ip_prefix': utils.AuthenticIPNetwork(
'10.0.0.0/24'),
'direction': 'ingress', 'direction': 'ingress',
'metering_label_id': self.uuid, 'metering_label_id': self.uuid,
'excluded': False, 'excluded': False,