Integrate the Extra Dhcp Opt VersionedObject in Neutron

This patch is dependent on commit I45b54b80d994f7e7f06128f73256b94675db97b2
which introduces the Extra Dhcp Opt OVO.
This patch integrates the VersionedObject with the existing code.

Change-Id: I0e01831b2b869fbd1ef90bd72a5b63173f554e66
Partial-Bug: #1541928
This commit is contained in:
Martin Hickey 2016-02-26 16:02:22 +00:00
parent a8ea95f1e4
commit 7ed3cb2ca1
5 changed files with 65 additions and 49 deletions

View File

View File

@ -0,0 +1,45 @@
# 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 sqlalchemy as sa
from sqlalchemy import orm
from neutron.db import model_base
from neutron.db import models_v2
class ExtraDhcpOpt(model_base.BASEV2, model_base.HasId):
"""Represent a generic concept of extra options associated to a port.
Each port may have none to many dhcp opts associated to it that can
define specifically different or extra options to DHCP clients.
These will be written to the <network_id>/opts files, and each option's
tag will be referenced in the <network_id>/host file.
"""
port_id = sa.Column(sa.String(36),
sa.ForeignKey('ports.id', ondelete="CASCADE"),
nullable=False)
opt_name = sa.Column(sa.String(64), nullable=False)
opt_value = sa.Column(sa.String(255), nullable=False)
ip_version = sa.Column(sa.Integer, server_default='4', nullable=False)
__table_args__ = (sa.UniqueConstraint(
'port_id',
'opt_name',
'ip_version',
name='uniq_extradhcpopts0portid0optname0ipversion'),
model_base.BASEV2.__table_args__,)
# Add a relationship to the Port model in order to instruct SQLAlchemy to
# eagerly load extra_dhcp_opts bindings
ports = orm.relationship(
models_v2.Port,
backref=orm.backref("dhcp_opts", lazy='joined', cascade='delete'))

View File

@ -13,42 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import sqlalchemy as sa
from sqlalchemy import orm
from neutron.api.v2 import attributes
from neutron.db import db_base_plugin_v2
from neutron.db import model_base
from neutron.db import models_v2
from neutron.extensions import extra_dhcp_opt as edo_ext
class ExtraDhcpOpt(model_base.BASEV2, model_base.HasId):
"""Represent a generic concept of extra options associated to a port.
Each port may have none to many dhcp opts associated to it that can
define specifically different or extra options to DHCP clients.
These will be written to the <network_id>/opts files, and each option's
tag will be referenced in the <network_id>/host file.
"""
port_id = sa.Column(sa.String(36),
sa.ForeignKey('ports.id', ondelete="CASCADE"),
nullable=False)
opt_name = sa.Column(sa.String(64), nullable=False)
opt_value = sa.Column(sa.String(255), nullable=False)
ip_version = sa.Column(sa.Integer, server_default='4', nullable=False)
__table_args__ = (sa.UniqueConstraint(
'port_id',
'opt_name',
'ip_version',
name='uniq_extradhcpopts0portid0optname0ipversion'),
model_base.BASEV2.__table_args__,)
# Add a relationship to the Port model in order to instruct SQLAlchemy to
# eagerly load extra_dhcp_opts bindings
ports = orm.relationship(
models_v2.Port,
backref=orm.backref("dhcp_opts", lazy='joined', cascade='delete'))
from neutron.objects.port.extensions import extra_dhcp_opt as obj_extra_dhcp
class ExtraDhcpOptMixin(object):
@ -57,7 +25,6 @@ class ExtraDhcpOptMixin(object):
"""
def _is_valid_opt_value(self, opt_name, opt_value):
# If the dhcp opt is blank-able, it shouldn't be saved to the DB in
# case that the value is None
if opt_name in edo_ext.VALID_BLANK_EXTRA_DHCP_OPTS:
@ -76,12 +43,13 @@ class ExtraDhcpOptMixin(object):
if self._is_valid_opt_value(dopt['opt_name'],
dopt['opt_value']):
ip_version = dopt.get('ip_version', 4)
db = ExtraDhcpOpt(
extra_dhcp_obj = obj_extra_dhcp.ExtraDhcpOpt(
context,
port_id=port['id'],
opt_name=dopt['opt_name'],
opt_value=dopt['opt_value'],
ip_version=ip_version)
context.session.add(db)
extra_dhcp_obj.create()
return self._extend_port_extra_dhcp_opts_dict(context, port)
def _extend_port_extra_dhcp_opts_dict(self, context, port):
@ -89,11 +57,13 @@ class ExtraDhcpOptMixin(object):
context, port['id'])
def _get_port_extra_dhcp_opts_binding(self, context, port_id):
query = self._model_query(context, ExtraDhcpOpt)
binding = query.filter(ExtraDhcpOpt.port_id == port_id)
opts = obj_extra_dhcp.ExtraDhcpOpt.get_objects(
context, port_id=port_id)
# TODO(mhickey): When port serilization is available then
# the object list should be returned instead
return [{'opt_name': r.opt_name, 'opt_value': r.opt_value,
'ip_version': r.ip_version}
for r in binding]
for r in opts]
def _update_extra_dhcp_opts_on_port(self, context, id, port,
updated_port=None):
@ -102,39 +72,40 @@ class ExtraDhcpOptMixin(object):
dopts = port['port'].get(edo_ext.EXTRADHCPOPTS)
if dopts:
opt_db = self._model_query(
context, ExtraDhcpOpt).filter_by(port_id=id).all()
opts = obj_extra_dhcp.ExtraDhcpOpt.get_objects(
context, port_id=id)
# if there are currently no dhcp_options associated to
# this port, Then just insert the new ones and be done.
with context.session.begin(subtransactions=True):
for upd_rec in dopts:
for opt in opt_db:
for opt in opts:
if (opt['opt_name'] == upd_rec['opt_name']
and opt['ip_version'] == upd_rec.get(
'ip_version', 4)):
# to handle deleting of a opt from the port.
if upd_rec['opt_value'] is None:
context.session.delete(opt)
opt.delete()
else:
if (self._is_valid_opt_value(
opt['opt_name'],
upd_rec['opt_value']) and
opt['opt_value'] !=
upd_rec['opt_value']):
opt.update(
{'opt_value': upd_rec['opt_value']})
opt['opt_value'] = upd_rec['opt_value']
opt.update()
break
else:
if self._is_valid_opt_value(
upd_rec['opt_name'],
upd_rec['opt_value']):
ip_version = upd_rec.get('ip_version', 4)
db = ExtraDhcpOpt(
extra_dhcp_obj = obj_extra_dhcp.ExtraDhcpOpt(
context,
port_id=id,
opt_name=upd_rec['opt_name'],
opt_value=upd_rec['opt_value'],
ip_version=ip_version)
context.session.add(db)
extra_dhcp_obj.create()
if updated_port:
edolist = self._get_port_extra_dhcp_opts_binding(context, id)

View File

@ -30,7 +30,7 @@ from neutron.db import bgp_dragentscheduler_db # noqa
from neutron.db import dns_db # noqa
from neutron.db import dvr_mac_db # noqa
from neutron.db import external_net_db # noqa
from neutron.db import extradhcpopt_db # noqa
from neutron.db.extra_dhcp_opt import models # noqa
from neutron.db import extraroute_db # noqa
from neutron.db import flavors_db # noqa
from neutron.db import l3_agentschedulers_db # noqa

View File

@ -13,7 +13,7 @@
from oslo_versionedobjects import base as obj_base
from oslo_versionedobjects import fields as obj_fields
from neutron.db import extradhcpopt_db as models
from neutron.db.extra_dhcp_opt import models
from neutron.objects import base