NSX|V+V3: Octavia driver

Implementing the Octavia support for NSX-V & NSX-T.
Follow up patches will handle the TVD plugin, Status updates,
and migration.

Since Octavia is not (yet?) in the requirements, using a hack to allow unittests
to be skipped.

Co-Authored-by: Adit Sarfaty <asarfaty@vmware.com>
Change-Id: Iadb24e7eadcab658faf3e646cc528c2a8a6976e5
This commit is contained in:
Kobi Samoray 2018-05-24 10:15:26 +03:00 committed by Adit Sarfaty
parent 759f015542
commit 83d9b3abdd
36 changed files with 2090 additions and 104 deletions

View File

@ -131,3 +131,4 @@
- openstack/neutron-dynamic-routing
- openstack/neutron-vpnaas
- openstack/tap-as-a-service
- openstack/octavia

View File

@ -30,7 +30,7 @@ function _nsxv_ini_set {
}
function install_neutron_projects {
pkg_list="networking-l2gw networking-sfc neutron-lbaas neutron-fwaas neutron-dynamic-routing neutron-vpnaas vmware-nsxlib"
pkg_list="networking-l2gw networking-sfc neutron-lbaas neutron-fwaas neutron-dynamic-routing neutron-vpnaas octavia vmware-nsxlib"
for pkg in `echo $pkg_list`
do
if is_plugin_enabled $pkg; then

View File

@ -238,6 +238,30 @@ Add neutron-vpnaas repo as an external repository and configure following flags
[DEFAULT]
api_extensions_path = $DEST/neutron-vpnaas/neutron_vpnaas/extensions
Octavia
~~~~~~~
Add octavia repo as an external repository and configure following flags in ``local.conf``::
[[local|localrc]]
OCTAVIA_NODE=api
DISABLE_AMP_IMAGE_BUILD=True
enable_plugin octavia $GIT_BASE/openstack/octavia.git
enable_plugin octavia-dashboard $GIT_BASE/openstack/octavia-dashboard
enable_service octavia
enable_service o-api
[[post-config|$OCTAVIA_CONF]]
[DEFAULT]
verbose = True
debug = True
[api_settings]
default_provider_driver=vmwareedge
enabled_provider_drivers=vmwareedge:NSX
[oslo_messaging]
topic=vmwarensxv_edge_lb
NSX-TVD
-------

View File

@ -55,6 +55,7 @@ munch==2.1.0
netaddr==0.7.18
netifaces==0.10.4
neutron-lib==1.18.0
octavia==3.0.0
openstackdocstheme==1.18.1
openstacksdk==0.11.2
os-client-config==1.28.0

View File

@ -0,0 +1,6 @@
---
prelude: >
Support Octavia loadbalancer support in NSXv and NSXv3 plugins.
features:
- |
NSXv and NSXv3 plugins now support Octavia loadbalancer.

View File

@ -38,6 +38,7 @@ neutron-fwaas>=12.0.0 # Apache-2.0
neutron-vpnaas>=12.0.0 # Apache-2.0
neutron-dynamic-routing>=12.0.0 # Apache-2.0
vmware-nsxlib>=12.0.0 # Apache-2.0
#octavia>=3.0.0 # Apache-2.0
# The comment below indicates this project repo is current with neutron-lib
# and should receive neutron-lib consumption patches as they are released

View File

@ -94,7 +94,8 @@ vmware_nsx.neutron.nsxv3.housekeeper.jobs =
orphaned_logical_router = vmware_nsx.plugins.nsx_v3.housekeeper.orphaned_logical_router:OrphanedLogicalRouterJob
orphaned_firewall_section = vmware_nsx.plugins.nsx_v3.housekeeper.orphaned_firewall_section:OrphanedFirewallSectionJob
mismatch_logical_port = vmware_nsx.plugins.nsx_v3.housekeeper.mismatch_logical_port:MismatchLogicalportJob
octavia.api.drivers =
vmwareedge = vmware_nsx.services.lbaas.octavia.octavia_driver:NSXOctaviaDriver
[build_sphinx]
source-dir = doc/source
build-dir = doc/build

View File

@ -34,6 +34,7 @@ commands =
pip install -q -e "git+https://git.openstack.org/openstack/neutron-fwaas#egg=neutron_fwaas"
pip install -q -e "git+https://git.openstack.org/openstack/neutron-dynamic-routing#egg=neutron_dynamic_routing"
pip install -q -e "git+https://git.openstack.org/openstack/neutron-vpnaas#egg=neutron_vpnaas"
pip install -q -e "git+https://git.openstack.org/openstack/octavia#egg=octavia"
pip install -q -e "git+https://git.openstack.org/openstack/vmware-nsxlib#egg=vmware_nsxlib"
pip install -q -e "git+https://git.openstack.org/openstack/neutron#egg=neutron"

View File

@ -262,6 +262,10 @@ nsx_common_opts = [
default=[],
help=_("(Optional) List of email addresses for "
"notifications.")),
cfg.IntOpt('octavia_stats_interval',
default=10,
help=_("Interval in seconds for Octavia statistics reporting. "
"0 means no reporting")),
]
nsx_v3_and_p = [

View File

@ -559,6 +559,10 @@ def get_nsx_lbaas_loadbalancer_binding(session, loadbalancer_id):
return
def get_nsx_lbaas_loadbalancer_bindings(session):
return session.query(nsx_models.NsxLbaasLoadbalancer).all()
def get_nsx_lbaas_loadbalancer_binding_by_service(session, lb_service_id):
return session.query(
nsx_models.NsxLbaasLoadbalancer).filter_by(
@ -591,7 +595,8 @@ def get_nsx_lbaas_listener_binding(session, loadbalancer_id, listener_id):
return
def get_nsx_lbaas_listener_binding_by_vs(session, loadbalancer_id, lb_vs_id):
def get_nsx_lbaas_listener_binding_by_lb_and_vs(session, loadbalancer_id,
lb_vs_id):
try:
return session.query(
nsx_models.NsxLbaasListener).filter_by(
@ -601,6 +606,15 @@ def get_nsx_lbaas_listener_binding_by_vs(session, loadbalancer_id, lb_vs_id):
return
def get_nsx_lbaas_listener_binding_by_vs_id(session, lb_vs_id):
try:
return session.query(
nsx_models.NsxLbaasListener).filter_by(
lb_vs_id=lb_vs_id).one()
except exc.NoResultFound:
return
def delete_nsx_lbaas_listener_binding(session, loadbalancer_id, listener_id):
return (session.query(nsx_models.NsxLbaasListener).
filter_by(loadbalancer_id=loadbalancer_id,

View File

@ -1 +1 @@
0dbeda408e41
fc6308289aca

View File

@ -0,0 +1,51 @@
# Copyright 2018 VMware, Inc.
#
# 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.
"""lbaas_no_foreign_key
Revision ID: fc6308289aca
Revises: 0dbeda408e41
Create Date: 2018-06-04 13:47:09.450116
"""
from alembic import op
from sqlalchemy.engine import reflection
from neutron.db import migration
# revision identifiers, used by Alembic.
revision = 'fc6308289aca'
down_revision = '0dbeda408e41'
depends_on = ('717f7f63a219')
def upgrade():
for table_name in ['nsxv3_lbaas_loadbalancers',
'nsxv3_lbaas_listeners',
'nsxv3_lbaas_pools',
'nsxv3_lbaas_monitors',
'nsxv3_lbaas_l7rules',
'nsxv3_lbaas_l7policies',
'nsxv_lbaas_loadbalancer_bindings',
'nsxv_lbaas_listener_bindings',
'nsxv_lbaas_pool_bindings',
'nsxv_lbaas_monitor_bindings',
'nsxv_lbaas_l7policy_bindings']:
if migration.schema_has_table(table_name):
inspector = reflection.Inspector.from_engine(op.get_bind())
fk_constraint = inspector.get_foreign_keys(table_name)[0]
op.drop_constraint(fk_constraint.get('name'), table_name,
type_='foreignkey')

View File

@ -399,12 +399,7 @@ class NsxLbaasLoadbalancer(model_base.BASEV2, models.TimestampMixin):
and NSX logical router id.
"""
__tablename__ = 'nsxv3_lbaas_loadbalancers'
fk_name = 'fk_nsxv3_lbaas_loadbalancers_id'
loadbalancer_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_loadbalancers.id',
name=fk_name,
ondelete="CASCADE"),
primary_key=True)
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
lb_router_id = sa.Column(sa.String(36), nullable=False)
lb_service_id = sa.Column(sa.String(36), nullable=False)
vip_address = sa.Column(sa.String(36), nullable=False)
@ -414,11 +409,7 @@ class NsxLbaasListener(model_base.BASEV2, models.TimestampMixin):
"""Stores the mapping between LBaaS listener and NSX LB virtual server"""
__tablename__ = 'nsxv3_lbaas_listeners'
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
listener_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_listeners.id',
name='fk_nsxv3_lbaas_listeners_id',
ondelete="CASCADE"),
primary_key=True)
listener_id = sa.Column(sa.String(36), primary_key=True)
app_profile_id = sa.Column(sa.String(36), nullable=False)
lb_vs_id = sa.Column(sa.String(36), nullable=False)
@ -427,11 +418,7 @@ class NsxLbaasPool(model_base.BASEV2, models.TimestampMixin):
"""Stores the mapping between LBaaS pool and NSX LB Pool"""
__tablename__ = 'nsxv3_lbaas_pools'
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
pool_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_pools.id',
name='fk_nsxv3_lbaas_pools_id',
ondelete="CASCADE"),
primary_key=True)
pool_id = sa.Column(sa.String(36), primary_key=True)
lb_pool_id = sa.Column(sa.String(36), nullable=False)
lb_vs_id = sa.Column(sa.String(36))
@ -441,11 +428,7 @@ class NsxLbaasMonitor(model_base.BASEV2, models.TimestampMixin):
__tablename__ = 'nsxv3_lbaas_monitors'
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
pool_id = sa.Column(sa.String(36), primary_key=True)
hm_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_healthmonitors.id',
name='fk_nsxv3_lbaas_healthmonitors_id',
ondelete="CASCADE"),
primary_key=True)
hm_id = sa.Column(sa.String(36), primary_key=True)
lb_monitor_id = sa.Column(sa.String(36), nullable=False)
lb_pool_id = sa.Column(sa.String(36), nullable=False)
@ -462,11 +445,7 @@ class NsxLbaasL7Rule(model_base.BASEV2, models.TimestampMixin):
__tablename__ = 'nsxv3_lbaas_l7rules'
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
l7policy_id = sa.Column(sa.String(36), primary_key=True)
l7rule_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_l7rules.id',
name='fk_nsxv3_lbaas_l7rules_id',
ondelete="CASCADE"),
primary_key=True)
l7rule_id = sa.Column(sa.String(36), primary_key=True)
lb_rule_id = sa.Column(sa.String(36), nullable=False)
lb_vs_id = sa.Column(sa.String(36), nullable=False)
@ -474,11 +453,7 @@ class NsxLbaasL7Rule(model_base.BASEV2, models.TimestampMixin):
class NsxLbaasL7Policy(model_base.BASEV2, models.TimestampMixin):
"""Stores the mapping between LBaaS l7policy and NSX LB rule"""
__tablename__ = 'nsxv3_lbaas_l7policies'
l7policy_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_l7policies.id',
name='fk_nsxv3_lbaas_l7policies_id',
ondelete="CASCADE"),
primary_key=True)
l7policy_id = sa.Column(sa.String(36), primary_key=True)
lb_rule_id = sa.Column(sa.String(36), nullable=False)
lb_vs_id = sa.Column(sa.String(36), nullable=False)

View File

@ -684,6 +684,15 @@ def add_nsxv_lbaas_loadbalancer_binding(
return binding
def get_nsxv_lbaas_loadbalancer_bindings(session, filters=None,
like_filters=None):
session = db_api.get_reader_session()
query = session.query(nsxv_models.NsxvLbaasLoadbalancerBinding)
return nsx_db._apply_filters_to_query(
query, nsxv_models.NsxvLbaasLoadbalancerBinding, filters,
like_filters).all()
def get_nsxv_lbaas_loadbalancer_binding(session, loadbalancer_id):
try:
return session.query(
@ -731,6 +740,15 @@ def del_nsxv_lbaas_listener_binding(session, loadbalancer_id, listener_id):
listener_id=listener_id).delete())
def get_nsxv_lbaas_listener_binding_by_vse(session, loadbalancer_id, vse_id):
try:
return session.query(
nsxv_models.NsxvLbaasListenerBinding).filter_by(
loadbalancer_id=loadbalancer_id, vse_id=vse_id).one()
except exc.NoResultFound:
return
def add_nsxv_lbaas_pool_binding(session, loadbalancer_id, pool_id,
edge_pool_id):
with session.begin(subtransactions=True):

View File

@ -252,11 +252,7 @@ class NsxvLbaasLoadbalancerBinding(model_base.BASEV2, models.TimestampMixin):
__tablename__ = 'nsxv_lbaas_loadbalancer_bindings'
loadbalancer_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_loadbalancers.id',
name='fk_lbaas_loadbalancers_id',
ondelete="CASCADE"),
primary_key=True)
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
edge_id = sa.Column(sa.String(36), nullable=False)
edge_fw_rule_id = sa.Column(sa.String(36), nullable=False)
vip_address = sa.Column(sa.String(36), nullable=False)
@ -268,11 +264,7 @@ class NsxvLbaasListenerBinding(model_base.BASEV2, models.TimestampMixin):
__tablename__ = 'nsxv_lbaas_listener_bindings'
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
listener_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_listeners.id',
name='fk_lbaas_listeners_id',
ondelete="CASCADE"),
primary_key=True)
listener_id = sa.Column(sa.String(36), primary_key=True)
app_profile_id = sa.Column(sa.String(36), nullable=False)
vse_id = sa.Column(sa.String(36), nullable=False)
@ -283,11 +275,7 @@ class NsxvLbaasPoolBinding(model_base.BASEV2, models.TimestampMixin):
__tablename__ = 'nsxv_lbaas_pool_bindings'
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
pool_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_pools.id',
name='fk_lbaas_pools_id',
ondelete="CASCADE"),
primary_key=True)
pool_id = sa.Column(sa.String(36), primary_key=True)
edge_pool_id = sa.Column(sa.String(36), nullable=False)
@ -298,11 +286,7 @@ class NsxvLbaasMonitorBinding(model_base.BASEV2, models.TimestampMixin):
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
pool_id = sa.Column(sa.String(36), primary_key=True)
hm_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_healthmonitors.id',
name='fk_lbaas_healthmonitors_id',
ondelete="CASCADE"),
primary_key=True)
hm_id = sa.Column(sa.String(36), primary_key=True)
edge_id = sa.Column(sa.String(36), primary_key=True)
edge_mon_id = sa.Column(sa.String(36), nullable=False)
@ -322,11 +306,7 @@ class NsxvLbaasL7PolicyBinding(model_base.BASEV2, models.TimestampMixin):
__tablename__ = 'nsxv_lbaas_l7policy_bindings'
policy_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_l7policies.id',
name='fk_lbaas_l7policies_id',
ondelete="CASCADE"),
primary_key=True)
policy_id = sa.Column(sa.String(36), primary_key=True)
edge_id = sa.Column(sa.String(36), nullable=False)
edge_app_rule_id = sa.Column(sa.String(36), nullable=False)

View File

@ -16,7 +16,6 @@ from oslo_log import log as logging
from neutron_lib import constants as n_consts
from neutron_lib.db import api as db_api
from neutron_lib.plugins import constants as plugin_const
from vmware_nsx._i18n import _
from vmware_nsx.common import exceptions as nsxv_exc
@ -26,6 +25,7 @@ from vmware_nsx.plugins.nsx_v.drivers import (
abstract_router_driver as router_driver)
from vmware_nsx.plugins.nsx_v import plugin as nsx_v
from vmware_nsx.plugins.nsx_v.vshield import edge_utils
from vmware_nsx.services.lbaas.octavia import constants as oct_const
LOG = logging.getLogger(__name__)
@ -279,9 +279,10 @@ class RouterExclusiveDriver(router_driver.RouterBaseDriver):
def _check_lb_on_subnet(self, context, subnet_id, router_id):
# Check lbaas
dev_owner_v1 = 'neutron:' + plugin_const.LOADBALANCER
dev_owner_v2 = 'neutron:' + plugin_const.LOADBALANCERV2
filters = {'device_owner': [dev_owner_v1, dev_owner_v2],
dev_owner_v1 = n_consts.DEVICE_OWNER_LOADBALANCER
dev_owner_v2 = n_consts.DEVICE_OWNER_LOADBALANCERV2
dev_owner_oct = oct_const.DEVICE_OWNER_OCTAVIA
filters = {'device_owner': [dev_owner_v1, dev_owner_v2, dev_owner_oct],
'fixed_ips': {'subnet_id': [subnet_id]}}
ports = super(nsx_v.NsxVPluginV2, self.plugin).get_ports(
context, filters=filters)

View File

@ -143,6 +143,15 @@ from vmware_nsx.plugins.nsx_v.vshield import securitygroup_utils
from vmware_nsx.plugins.nsx_v.vshield import vcns_driver
from vmware_nsx.services.flowclassifier.nsx_v import utils as fc_utils
from vmware_nsx.services.fwaas.nsx_v import fwaas_callbacks
from vmware_nsx.services.lbaas.nsx_v.implementation import healthmon_mgr
from vmware_nsx.services.lbaas.nsx_v.implementation import l7policy_mgr
from vmware_nsx.services.lbaas.nsx_v.implementation import l7rule_mgr
from vmware_nsx.services.lbaas.nsx_v.implementation import listener_mgr
from vmware_nsx.services.lbaas.nsx_v.implementation import loadbalancer_mgr
from vmware_nsx.services.lbaas.nsx_v.implementation import member_mgr
from vmware_nsx.services.lbaas.nsx_v.implementation import pool_mgr
from vmware_nsx.services.lbaas.octavia import constants as oct_const
from vmware_nsx.services.lbaas.octavia import octavia_listener
LOG = logging.getLogger(__name__)
PORTGROUP_PREFIX = 'dvportgroup'
@ -226,6 +235,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
def __init__(self):
self._is_sub_plugin = tvd_utils.is_tvd_core_plugin()
self.init_is_complete = False
self.octavia_listener = None
self.octavia_stats_collector = None
self.housekeeper = None
super(NsxVPluginV2, self).__init__()
if self._is_sub_plugin:
@ -321,6 +332,10 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# Bind QoS notifications
qos_driver.register(self)
registry.subscribe(self.spawn_complete,
resources.PROCESS,
events.AFTER_SPAWN)
# subscribe the init complete method last, so it will be called only
# if init was successful
registry.subscribe(self.init_complete,
@ -335,6 +350,16 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
def is_tvd_plugin():
return False
def spawn_complete(self, resource, event, trigger, payload=None):
# This method should run only once, but after init_complete
if not self.init_is_complete:
self.init_complete(None, None, None)
self.octavia_stats_collector = (
octavia_listener.NSXOctaviaStatisticsCollector(
self,
listener_mgr.stats_getter))
def init_complete(self, resource, event, trigger, payload=None):
with locking.LockManager.get_lock('plugin-init-complete'):
if self.init_is_complete:
@ -362,6 +387,18 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
hk_readonly=cfg.CONF.nsxv.housekeeping_readonly,
hk_readonly_jobs=cfg.CONF.nsxv.housekeeping_readonly_jobs)
# Init octavia listener and endpoints
self.octavia_listener = octavia_listener.NSXOctaviaListener(
loadbalancer=loadbalancer_mgr.EdgeLoadBalancerManagerFromDict(
self.nsx_v),
listener=listener_mgr.EdgeListenerManagerFromDict(self.nsx_v),
pool=pool_mgr.EdgePoolManagerFromDict(self.nsx_v),
member=member_mgr.EdgeMemberManagerFromDict(self.nsx_v),
healthmonitor=healthmon_mgr.EdgeHealthMonitorManagerFromDict(
self.nsx_v),
l7policy=l7policy_mgr.EdgeL7PolicyManagerFromDict(self.nsx_v),
l7rule=l7rule_mgr.EdgeL7RuleManagerFromDict(self.nsx_v))
self.init_is_complete = True
def _validate_nsx_version(self):
@ -1851,7 +1888,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
def _assert_on_lb_port_admin_state(self, port_data, original_port,
device_owner):
if device_owner == constants.DEVICE_OWNER_LOADBALANCERV2:
if device_owner in [constants.DEVICE_OWNER_LOADBALANCERV2,
oct_const.DEVICE_OWNER_OCTAVIA]:
orig_state = original_port.get("admin_state_up")
new_state = port_data.get("admin_state_up")
if new_state is not None and (orig_state != new_state) and (

View File

@ -116,7 +116,16 @@ from vmware_nsx.plugins.nsx_v3 import utils as v3_utils
from vmware_nsx.services.fwaas.common import utils as fwaas_utils
from vmware_nsx.services.fwaas.nsx_v3 import fwaas_callbacks_v1
from vmware_nsx.services.fwaas.nsx_v3 import fwaas_callbacks_v2
from vmware_nsx.services.lbaas.nsx_v3.implementation import healthmonitor_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import l7policy_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import l7rule_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import listener_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import loadbalancer_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import member_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import pool_mgr
from vmware_nsx.services.lbaas.nsx_v3.v2 import lb_driver_v2
from vmware_nsx.services.lbaas.octavia import constants as oct_const
from vmware_nsx.services.lbaas.octavia import octavia_listener
from vmware_nsx.services.qos.common import utils as qos_com_utils
from vmware_nsx.services.qos.nsx_v3 import driver as qos_driver
from vmware_nsx.services.trunk.nsx_v3 import driver as trunk_driver
@ -211,6 +220,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
self.fwaas_callbacks = None
self._is_sub_plugin = tvd_utils.is_tvd_core_plugin()
self.init_is_complete = False
self.octavia_listener = None
self.octavia_stats_collector = None
nsxlib_utils.set_is_attr_callback(validators.is_attr_set)
self._extend_fault_map()
if self._is_sub_plugin:
@ -293,6 +304,10 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
# Register NSXv3 trunk driver to support trunk extensions
self.trunk_driver = trunk_driver.NsxV3TrunkDriver.create(self)
registry.subscribe(self.spawn_complete,
resources.PROCESS,
events.AFTER_SPAWN)
# subscribe the init complete method last, so it will be called only
# if init was successful
registry.subscribe(self.init_complete,
@ -430,6 +445,16 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
def is_tvd_plugin():
return False
def spawn_complete(self, resource, event, trigger, payload=None):
# This method should run only once, but after init_complete
if not self.init_is_complete:
self.init_complete(None, None, None)
self.octavia_stats_collector = (
octavia_listener.NSXOctaviaStatisticsCollector(
self,
listener_mgr.stats_getter))
def init_complete(self, resource, event, trigger, payload=None):
with locking.LockManager.get_lock('plugin-init-complete'):
if self.init_is_complete:
@ -451,8 +476,25 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
hk_readonly=cfg.CONF.nsx_v3.housekeeping_readonly,
hk_readonly_jobs=cfg.CONF.nsx_v3.housekeeping_readonly_jobs)
# Init octavia listener and endpoints
self._init_octavia()
self.init_is_complete = True
def _init_octavia(self):
if not self.nsxlib.feature_supported(
nsxlib_consts.FEATURE_LOAD_BALANCER):
return
self.octavia_listener = octavia_listener.NSXOctaviaListener(
loadbalancer=loadbalancer_mgr.EdgeLoadBalancerManagerFromDict(),
listener=listener_mgr.EdgeListenerManagerFromDict(),
pool=pool_mgr.EdgePoolManagerFromDict(),
member=member_mgr.EdgeMemberManagerFromDict(),
healthmonitor=healthmonitor_mgr.EdgeHealthMonitorManagerFromDict(),
l7policy=l7policy_mgr.EdgeL7PolicyManagerFromDict(),
l7rule=l7rule_mgr.EdgeL7RuleManagerFromDict())
def _extend_fault_map(self):
"""Extends the Neutron Fault Map.
@ -4479,7 +4521,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
port_data = self.get_port(context, port_id)
device_owner = port_data.get('device_owner')
fip_address = new_fip['floating_ip_address']
if device_owner == const.DEVICE_OWNER_LOADBALANCERV2:
if (device_owner == const.DEVICE_OWNER_LOADBALANCERV2 or
device_owner == oct_const.DEVICE_OWNER_OCTAVIA):
try:
self._update_lb_vip(port_data, fip_address)
except nsx_lib_exc.ManagerError:
@ -4508,7 +4551,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
port_data = self.get_port(context, port_id)
device_owner = port_data.get('device_owner')
fixed_ip_address = fip['fixed_ip_address']
if device_owner == const.DEVICE_OWNER_LOADBALANCERV2:
if (device_owner == const.DEVICE_OWNER_LOADBALANCERV2 or
device_owner == oct_const.DEVICE_OWNER_OCTAVIA):
# If the port is LB VIP port, after deleting the FIP,
# update the virtual server VIP back to fixed IP.
is_lb_port = True
@ -4551,7 +4595,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
old_port_data = self.get_port(context, old_port_id)
old_device_owner = old_port_data['device_owner']
old_fixed_ip = old_fip['fixed_ip_address']
if old_device_owner == const.DEVICE_OWNER_LOADBALANCERV2:
if (old_device_owner == const.DEVICE_OWNER_LOADBALANCERV2 or
old_device_owner == oct_const.DEVICE_OWNER_OCTAVIA):
is_lb_port = True
self._update_lb_vip(old_port_data, old_fixed_ip)
@ -4578,7 +4623,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
new_port_data = self.get_port(context, new_port_id)
new_dev_own = new_port_data['device_owner']
new_fip_address = new_fip['floating_ip_address']
if new_dev_own == const.DEVICE_OWNER_LOADBALANCERV2:
if (new_dev_own == const.DEVICE_OWNER_LOADBALANCERV2 or
new_dev_own == oct_const.DEVICE_OWNER_OCTAVIA):
is_lb_port = True
self._update_lb_vip(new_port_data, new_fip_address)

View File

@ -96,6 +96,10 @@ LB_STATS_MAP = {'active_connections': 'current_sessions',
'bytes_in': 'bytes_in',
'bytes_out': 'bytes_out',
'total_connections': 'total_sessions'}
LB_EMPTY_STATS = {'active_connections': 0,
'bytes_in': 0,
'bytes_out': 0,
'total_connections': 0}
LR_ROUTER_TYPE = 'os-neutron-router-id'
LR_PORT_TYPE = 'os-neutron-rport-id'
LB_CERT_RESOURCE_TYPE = ['certificate_signed', 'certificate_self_signed']

View File

@ -32,12 +32,14 @@ def lb_listener_obj_to_dict(listener):
# Translate the LBaaS listener to a dictionary skipping the some objects
# to avoid recursions
listener_dict = listener.to_dict(loadbalancer=False, default_pool=False)
# Translate the default pool separately without it's internal objects
if listener.default_pool:
listener_dict['default_pool'] = lb_pool_obj_to_dict(
listener.default_pool, with_listeners=False)
else:
listener_dict['default_pool'] = None
if listener.loadbalancer:
listener_dict['loadbalancer'] = lb_loadbalancer_obj_to_dict(
listener.loadbalancer)

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
from oslo_utils import excutils
@ -297,3 +299,45 @@ class EdgeListenerManagerFromDict(base_mgr.EdgeLoadbalancerBaseManager):
listener['id'])
completor(success=True)
def stats_getter(context, core_plugin, ignore_list=None):
"""Update Octavia statistics for each listener (virtual server)"""
stat_list = []
vcns = core_plugin.nsx_v.vcns
# go over all LB edges
bindings = nsxv_db.get_nsxv_lbaas_loadbalancer_bindings(context.session)
for binding in bindings:
lb_id = binding['loadbalancer_id']
if ignore_list and lb_id in ignore_list:
continue
edge_id = binding['edge_id']
try:
lb_stats = vcns.get_loadbalancer_statistics(edge_id)
virtual_servers_stats = lb_stats[1].get('virtualServer', [])
for vs_stats in virtual_servers_stats:
# Get the stats of the virtual server
stats = copy.copy(lb_const.LB_EMPTY_STATS)
stats['bytes_in'] += vs_stats.get('bytesIn', 0)
stats['bytes_out'] += vs_stats.get('bytesOut', 0)
stats['active_connections'] += vs_stats.get('curSessions', 0)
stats['total_connections'] += vs_stats.get('totalSessions', 0)
stats['request_errors'] = 0 # currently unsupported
# Find the listener Id
vs_id = vs_stats.get('virtualServerId')
list_bind = nsxv_db.get_nsxv_lbaas_listener_binding_by_vse(
context.session, lb_id, vs_id)
if not list_bind:
continue
stats['id'] = list_bind['listener_id']
stat_list.append(stats)
except vcns_exc.VcnsApiException as e:
LOG.warning('Failed to read load balancer statistics for %s: %s',
edge_id, e)
return stat_list

View File

@ -31,6 +31,7 @@ from vmware_nsx.plugins.nsx_v.vshield.common import (
from vmware_nsx.plugins.nsx_v.vshield.common import exceptions as nsxv_exc
from vmware_nsx.services.lbaas import base_mgr
from vmware_nsx.services.lbaas.nsx_v import lbaas_common as lb_common
from vmware_nsx.services.lbaas.octavia import constants as oct_const
LOG = logging.getLogger(__name__)
@ -159,33 +160,15 @@ class EdgeLoadBalancerManagerFromDict(base_mgr.EdgeLoadbalancerBaseManager):
completor(success=True)
def refresh(self, context, lb):
# TODO(kobis): implememnt
# TODO(kobis): implement
pass
def stats(self, context, lb):
stats = {'bytes_in': 0,
'bytes_out': 0,
'active_connections': 0,
'total_connections': 0}
binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(context.session,
lb['id'])
try:
lb_stats = self.vcns.get_loadbalancer_statistics(
binding['edge_id'])
except nsxv_exc.VcnsApiException:
msg = (_('Failed to read load balancer statistics, edge: %s') %
binding['edge_id'])
raise n_exc.BadRequest(resource='edge-lbaas', msg=msg)
pools_stats = lb_stats[1].get('pool', [])
for pool_stats in pools_stats:
stats['bytes_in'] += pool_stats.get('bytesIn', 0)
stats['bytes_out'] += pool_stats.get('bytesOut', 0)
stats['active_connections'] += pool_stats.get('curSessions', 0)
stats['total_connections'] += pool_stats.get('totalSessions', 0)
stats = _get_edge_loadbalancer_statistics(self.vcns,
binding['edge_id'])
return stats
@ -208,12 +191,15 @@ class EdgeLoadBalancerManagerFromDict(base_mgr.EdgeLoadbalancerBaseManager):
subnet = self.core_plugin.get_subnet(context.elevated(), subnet_id)
filters = {'fixed_ips': {'subnet_id': [subnet_id]},
'device_owner': [constants.DEVICE_OWNER_LOADBALANCERV2]}
'device_owner': [constants.DEVICE_OWNER_LOADBALANCERV2,
oct_const.DEVICE_OWNER_OCTAVIA]}
lb_ports = self.core_plugin.get_ports(context.elevated(),
filters=filters)
if lb_ports:
for lb_port in lb_ports:
# TODO(asarfaty): for Octavia this code might need to change
# as the device_id is different
if lb_port['device_id']:
edge_bind = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_port['device_id'])
@ -238,3 +224,27 @@ class EdgeLoadBalancerManagerFromDict(base_mgr.EdgeLoadbalancerBaseManager):
if not found:
return False
return True
def _get_edge_loadbalancer_statistics(vcns, edge_id):
stats = {'bytes_in': 0,
'bytes_out': 0,
'active_connections': 0,
'total_connections': 0}
try:
lb_stats = vcns.get_loadbalancer_statistics(edge_id)
except nsxv_exc.VcnsApiException:
msg = (_('Failed to read load balancer statistics, edge: %s') %
edge_id)
raise n_exc.BadRequest(resource='edge-lbaas', msg=msg)
pools_stats = lb_stats[1].get('pool', [])
for pool_stats in pools_stats:
stats['bytes_in'] += pool_stats.get('bytesIn', 0)
stats['bytes_out'] += pool_stats.get('bytesOut', 0)
stats['active_connections'] += pool_stats.get('curSessions', 0)
stats['total_connections'] += pool_stats.get('totalSessions', 0)
return stats

View File

@ -46,6 +46,8 @@ class EdgeL7RuleManagerFromDict(base_mgr.Nsxv3LoadbalancerBaseManager):
lb_rule_id = binding['lb_rule_id']
if delete:
lb_utils.remove_rule_from_policy(rule)
else:
lb_utils.update_rule_in_policy(rule)
rule_body = lb_utils.convert_l7policy_to_lb_rule(
context, rule['policy'])
try:

View File

@ -203,3 +203,8 @@ def convert_l7policy_to_lb_rule(context, policy):
def remove_rule_from_policy(rule):
l7rules = rule['policy']['rules']
rule['policy']['rules'] = [r for r in l7rules if r['id'] != rule['id']]
def update_rule_in_policy(rule):
remove_rule_from_policy(rule)
rule['policy']['rules'].append(rule)

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from neutron_lib import exceptions as n_exc
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
@ -281,3 +283,42 @@ class EdgeListenerManagerFromDict(base_mgr.Nsxv3LoadbalancerBaseManager):
context.session, lb_id, listener['id'])
completor(success=True)
def stats_getter(context, core_plugin, ignore_list=None):
"""Update Octavia statistics for each listener (virtual server)"""
stat_list = []
lb_service_client = core_plugin.nsxlib.load_balancer.service
# Go over all the loadbalancers & services
lb_bindings = nsx_db.get_nsx_lbaas_loadbalancer_bindings(
context.session)
for lb_binding in lb_bindings:
if ignore_list and lb_binding['loadbalancer_id'] in ignore_list:
continue
lb_service_id = lb_binding.get('lb_service_id')
LOG.debug("Getting listeners statistics for NSX lb service %s",
lb_service_id)
try:
# get the NSX statistics for this LB service
rsp = lb_service_client.get_stats(lb_service_id)
if rsp and 'virtual_servers' in rsp:
# Go over each virtual server in the response
for vs in rsp['virtual_servers']:
# look up the virtual server in the DB
vs_bind = nsx_db.get_nsx_lbaas_listener_binding_by_vs_id(
context.session, vs['virtual_server_id'])
if vs_bind:
vs_stats = vs['statistics']
stats = copy.copy(lb_const.LB_EMPTY_STATS)
stats['id'] = vs_bind.listener_id
stats['request_errors'] = 0 # currently unsupported
for stat in lb_const.LB_STATS_MAP:
lb_stat = lb_const.LB_STATS_MAP[stat]
stats[stat] += vs_stats[lb_stat]
stat_list.append(stats)
except nsxlib_exc.ManagerError:
pass
return stat_list

View File

@ -192,10 +192,10 @@ class EdgeLoadBalancerManagerFromDict(base_mgr.Nsxv3LoadbalancerBaseManager):
for vs in vs_statuses.get('results', []):
vs_status = self._nsx_status_to_lb_status(vs.get('status'))
vs_id = vs.get('virtual_server_id')
listener_binding = nsx_db.get_nsx_lbaas_listener_binding_by_vs(
list_binding = nsx_db.get_nsx_lbaas_listener_binding_by_lb_and_vs(
context.session, id, vs_id)
if listener_binding:
listener_id = listener_binding['listener_id']
if list_binding:
listener_id = list_binding['listener_id']
statuses[lb_const.LISTENERS].append(
{'id': listener_id, 'status': vs_status})

View File

@ -65,10 +65,15 @@ class EdgeMemberManagerFromDict(base_mgr.Nsxv3LoadbalancerBaseManager):
tenant_id, context.project_name)
attachment = {'target_id': nsx_router_id,
'target_type': 'LogicalRouter'}
lb_service = service_client.create(display_name=lb_name,
tags=tags,
attachment=attachment,
size=lb_size)
try:
lb_service = service_client.create(display_name=lb_name,
tags=tags,
attachment=attachment,
size=lb_size)
except nsxlib_exc.ManagerError as e:
LOG.error("Failed to create LB service: %s", e)
return
# Update router to enable advertise_lb_vip flag
self.core_plugin.nsxlib.logical_router.update_advertisement(
nsx_router_id, advertise_lb_vip=True)

View File

@ -16,8 +16,8 @@
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib import constants as n_consts
from neutron_lib import exceptions as n_exc
from neutron_lib.plugins import constants as plugin_const
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
@ -33,6 +33,7 @@ from vmware_nsx.services.lbaas.nsx_v3.implementation import listener_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import loadbalancer_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import member_mgr
from vmware_nsx.services.lbaas.nsx_v3.implementation import pool_mgr
from vmware_nsx.services.lbaas.octavia import constants as oct_const
LOG = logging.getLogger(__name__)
@ -108,6 +109,9 @@ class EdgeLoadbalancerDriverV2(base_mgr.LoadbalancerBaseManager):
# Check if there is any LB attachment for the NSX router.
# This callback is subscribed here to prevent router/GW/interface
# deletion if it still has LB service attached to it.
#Note(asarfaty): Those callbacks are used by Octavia as well even
# though they are bound only here
registry.subscribe(self._check_lb_service_on_router,
resources.ROUTER, events.BEFORE_DELETE)
registry.subscribe(self._check_lb_service_on_router,
@ -124,8 +128,9 @@ class EdgeLoadbalancerDriverV2(base_mgr.LoadbalancerBaseManager):
resources.ROUTER_INTERFACE, events.BEFORE_DELETE)
def _get_lb_ports(self, context, subnet_ids):
dev_owner = 'neutron:' + plugin_const.LOADBALANCERV2
filters = {'device_owner': [dev_owner],
dev_owner_v2 = n_consts.DEVICE_OWNER_LOADBALANCERV2
dev_owner_oct = oct_const.DEVICE_OWNER_OCTAVIA
filters = {'device_owner': [dev_owner_v2, dev_owner_oct],
'fixed_ips': {'subnet_id': subnet_ids}}
return self.loadbalancer.core_plugin.get_ports(
context, filters=filters)

View File

@ -0,0 +1,45 @@
# Copyright 2018 VMware, 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.
OCTAVIA_TO_DRIVER_TOPIC = 'vmware_nsx__lb_listener'
DRIVER_TO_OCTAVIA_TOPIC = 'vmware_nsx__driver_listener'
LOADBALANCER = 'loadbalancer'
LISTENER = 'listener'
POOL = 'pool'
HEALTHMONITOR = 'healthmonitor'
MEMBER = 'member'
L7POLICY = 'l7policy'
L7RULE = 'l7rule'
LOADBALANCERS = 'loadbalancers'
LISTENERS = 'listeners'
POOLS = 'pools'
HEALTHMONITORS = 'healthmonitors'
MEMBERS = 'members'
L7POLICIES = 'l7policies'
L7RULES = 'l7rules'
ONLINE = 'ONLINE'
OFFLINE = 'OFFLINE'
ERROR = 'ERROR'
ACTIVE = 'ACTIVE'
DELETED = 'DELETED'
ERROR = 'ERROR'
OPERATING_STATUS = 'operating_status'
PROVISIONING_STATUS = 'provisioning_status'
DEVICE_OWNER_OCTAVIA = 'Octavia'

View File

@ -0,0 +1,507 @@
# Copyright 2018 VMware, 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 copy
import socket
from oslo_config import cfg
from oslo_log import helpers as log_helpers
from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_messaging.rpc import dispatcher
import pecan
from stevedore import driver as stevedore_driver
from octavia.api.drivers import driver_lib
from octavia.api.drivers import exceptions
from octavia.api.drivers import provider_base as driver_base
from octavia.api.drivers import utils as oct_utils
from octavia.db import api as db_apis
from octavia.db import repositories
from vmware_nsx.services.lbaas.octavia import constants as d_const
LOG = logging.getLogger(__name__)
cfg.CONF.import_group('oslo_messaging', 'octavia.common.config')
# List of keys per object type that will not be sent to the listener
unsupported_keys = {'Loadbalancer': ['vip_qos_policy_id'],
'Listener': ['sni_container_refs',
'insert_headers',
'timeout_client_data',
'timeout_member_connect',
'timeout_member_data',
'timeout_tcp_inspect'],
'HealthMonitor': ['expected_codes', 'max_retries_down'],
'Member': ['monitor_address', 'monitor_port', 'backup']}
class NSXOctaviaDriver(driver_base.ProviderDriver):
@log_helpers.log_method_call
def __init__(self):
super(NSXOctaviaDriver, self).__init__()
self._init_rpc_messaging()
self._init_rpc_listener()
self._init_cert_manager()
self.repositories = repositories.Repositories()
@log_helpers.log_method_call
def _init_rpc_messaging(self):
topic = d_const.OCTAVIA_TO_DRIVER_TOPIC
transport = messaging.get_rpc_transport(cfg.CONF)
target = messaging.Target(topic=topic, exchange="common",
namespace='control', fanout=False,
version='1.0')
self.client = messaging.RPCClient(transport, target)
@log_helpers.log_method_call
def _init_rpc_listener(self):
# Initialize RPC listener
topic = d_const.DRIVER_TO_OCTAVIA_TOPIC
server = socket.gethostname()
transport = messaging.get_rpc_transport(cfg.CONF)
target = messaging.Target(topic=topic, server=server,
exchange="common", fanout=False)
endpoints = [NSXOctaviaDriverEndpoint()]
access_policy = dispatcher.DefaultRPCAccessPolicy
self.octavia_server = messaging.get_rpc_server(
transport, target, endpoints, executor='threading',
access_policy=access_policy)
self.octavia_server.start()
@log_helpers.log_method_call
def _init_cert_manager(self):
self.cert_manager = stevedore_driver.DriverManager(
namespace='octavia.cert_manager',
name=cfg.CONF.certificates.cert_manager,
invoke_on_load=True).driver
def get_obj_project_id(self, obj_type, obj_dict):
if obj_dict.get('project_id'):
return obj_dict['project_id']
if obj_dict.get('tenant_id'):
return obj_dict['tenant_id']
# look for the project id of the attached objects
project_id = None
if obj_dict.get('loadbalancer_id'):
db_lb = self.repositories.load_balancer.get(
db_apis.get_session(), id=obj_dict['loadbalancer_id'])
if db_lb:
project_id = db_lb.project_id
if not project_id and obj_dict.get('pool_id'):
db_pool = self.repositories.pool.get(
db_apis.get_session(), id=obj_dict['pool_id'])
if db_pool:
project_id = db_pool.load_balancer.project_id
if not project_id and obj_dict.get('listener_id'):
db_list = self.repositories.listener.get(
db_apis.get_session(), id=obj_dict['listener_id'])
if db_list:
project_id = db_list.load_balancer.project_id
if not project_id and obj_dict.get('l7policy_id'):
db_policy = self.repositories.l7policy.get(
db_apis.get_session(), id=obj_dict['l7policy_id'])
if db_policy:
if db_policy.listener:
db_lb = db_policy.listener.load_balancer
elif db_policy.redirect_pool:
db_lb = db_policy.redirect_pool.load_balancer
if db_lb:
project_id = db_lb.project_id
if not project_id:
LOG.warning("Could bot find the tenant id for %(type)s "
"%(obj)s", {'type': obj_type, 'obj': obj_dict})
return project_id
def _get_load_balancer_dict(self, loadbalancer_id):
if not loadbalancer_id:
return
db_lb = self.repositories.load_balancer.get(
db_apis.get_session(), id=loadbalancer_id)
if not db_lb:
return
lb_dict = {'name': db_lb.name, 'id': loadbalancer_id}
if db_lb.vip:
lb_dict['vip_port_id'] = db_lb.vip.port_id
lb_dict['vip_address'] = db_lb.vip.ip_address
lb_dict['vip_port_id'] = db_lb.vip.port_id
lb_dict['vip_network_id'] = db_lb.vip.network_id
lb_dict['vip_subnet_id'] = db_lb.vip.subnet_id
return lb_dict
def _get_listener_in_pool_dict(self, pool_dict):
if 'listener' not in pool_dict:
if pool_dict.get('listener_id'):
db_listener = self.repositories.listener.get(
db_apis.get_session(), id=pool_dict['listener_id'])
listener_obj = oct_utils.db_listener_to_provider_listener(
db_listener)
listener_dict = listener_obj.to_dict(
recurse=False, render_unsets=True)
listener_dict['id'] = listener_dict['listener_id']
listener_dict['l7_policies'] = listener_dict['l7policies']
pool_dict['listener'] = listener_dict
if 'listeners' not in pool_dict:
# multiple listeners is not really supported yet
pool_dict['listeners'] = [listener_dict]
else:
pool_dict['listener'] = None
if 'listeners' not in pool_dict:
pool_dict['listeners'] = []
def _get_pool_dict(self, pool_id):
if not pool_id:
return
db_pool = self.repositories.pool.get(db_apis.get_session(), id=pool_id)
if not db_pool:
return
pool_obj = oct_utils.db_pool_to_provider_pool(db_pool)
pool_dict = pool_obj.to_dict(recurse=True, render_unsets=True)
pool_dict['id'] = pool_id
# Get the load balancer object
if pool_dict.get('loadbalancer_id'):
# Generate a loadbalancer object
pool_dict['loadbalancer'] = self._get_load_balancer_dict(
pool_dict['loadbalancer_id'])
if 'listener' not in pool_dict:
self._get_listener_in_pool_dict(pool_dict)
return pool_dict
def update_policy_dict(self, policy_dict, policy_obj, is_update=False):
if policy_dict.get('listener_id'):
db_list = self.repositories.listener.get(
db_apis.get_session(), id=policy_dict['listener_id'])
list_obj = oct_utils.db_listener_to_provider_listener(db_list)
list_dict = list_obj.to_dict(recurse=True, render_unsets=True)
list_dict['id'] = policy_dict['listener_id']
policy_dict[