Merge "Metering to OVO"
This commit is contained in:
commit
c910841586
|
@ -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)
|
||||||
|
|
|
@ -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',
|
'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',
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue