24e93461d0
The driver is loaded, then terminated whenever a request is issued. This behavior causes termination of the Octavia listener which is responsible to the processing of the driver status updates and statistics processing. The following change implements an agent which will execute the listener. Change-Id: I566aaa65df4ba7455577a539aa9eebb6cc36a099
597 lines
24 KiB
Python
597 lines
24 KiB
Python
# 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
|
|
import time
|
|
|
|
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 utils as oct_utils
|
|
from octavia.db import api as db_apis
|
|
from octavia.db import repositories
|
|
from octavia_lib.api.drivers import driver_lib
|
|
from octavia_lib.api.drivers import exceptions
|
|
|
|
from octavia_lib.api.drivers import provider_base as driver_base
|
|
|
|
from vmware_nsx.services.lbaas.octavia import constants as d_const
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
cfg.CONF.import_group('oslo_messaging', 'octavia.common.config')
|
|
|
|
TRANSPORT = None
|
|
RPC_SERVER = None
|
|
|
|
|
|
def get_transport():
|
|
global TRANSPORT
|
|
if not TRANSPORT:
|
|
TRANSPORT = messaging.get_rpc_transport(cfg.CONF)
|
|
return TRANSPORT
|
|
|
|
|
|
def get_rpc_server(target, endpoints, access_policy):
|
|
global RPC_SERVER
|
|
if not RPC_SERVER:
|
|
RPC_SERVER = messaging.get_rpc_server(
|
|
TRANSPORT, target, endpoints, executor='threading',
|
|
access_policy=access_policy)
|
|
return RPC_SERVER
|
|
|
|
|
|
# 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': ['max_retries_down'],
|
|
'Member': ['monitor_address', 'monitor_port']}
|
|
|
|
|
|
class NSXOctaviaDriver(driver_base.ProviderDriver):
|
|
@log_helpers.log_method_call
|
|
def __init__(self):
|
|
super(NSXOctaviaDriver, self).__init__()
|
|
self._init_rpc_messaging()
|
|
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 = get_transport()
|
|
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_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, is_update):
|
|
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']
|
|
# Add the loadbalancer to the listener dict
|
|
if pool_dict.get('loadbalancer_id'):
|
|
# Generate a loadbalancer object
|
|
listener_dict['loadbalancer'] = (
|
|
self._get_load_balancer_dict(
|
|
pool_dict['loadbalancer_id']))
|
|
pool_dict['listener'] = listener_dict
|
|
if 'listeners' not in pool_dict:
|
|
# multiple listeners is not really supported yet
|
|
pool_dict['listeners'] = [listener_dict]
|
|
# Do not add listener in update situation, as we want to use
|
|
# the original listener of this pool
|
|
elif not is_update:
|
|
pool_dict['listener'] = None
|
|
if 'listeners' not in pool_dict:
|
|
pool_dict['listeners'] = []
|
|
|
|
def _get_pool_dict(self, pool_id, is_update, parent_project_id=None):
|
|
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, is_update)
|
|
# make sure this pool has a project id
|
|
if not pool_dict.get('project_id'):
|
|
project_id = self.get_obj_project_id('Pool', pool_dict)
|
|
if project_id is None:
|
|
project_id = parent_project_id
|
|
pool_dict['tenant_id'] = pool_dict['project_id'] = project_id
|
|
|
|
return pool_dict
|
|
|
|
def _get_hm_dict(self, hm_id, is_update):
|
|
if not hm_id:
|
|
return {}
|
|
db_hm = self.repositories.health_monitor.get(
|
|
db_apis.get_session(), id=hm_id)
|
|
if not db_hm:
|
|
return {}
|
|
hm_obj = oct_utils.db_HM_to_provider_HM(db_hm)
|
|
hm_dict = hm_obj.to_dict(recurse=True, render_unsets=True)
|
|
hm_dict['id'] = hm_id
|
|
# Get the pol object
|
|
if hm_dict.get('pool_id'):
|
|
hm_dict['pool'] = self._get_pool_dict(
|
|
hm_dict['pool_id'], is_update)
|
|
return hm_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['listener'] = list_dict
|
|
if policy_obj.rules:
|
|
policy_dict['rules'] = []
|
|
for rule in policy_obj.rules:
|
|
if isinstance(rule, dict):
|
|
rule_dict = rule
|
|
else:
|
|
rule_dict = rule.to_dict(recurse=False, render_unsets=True)
|
|
rule_dict['id'] = rule_dict['l7rule_id']
|
|
policy_dict['rules'].append(rule_dict)
|
|
elif not is_update:
|
|
policy_dict['rules'] = []
|
|
|
|
def _remove_unsupported_keys(self, obj_type, obj_dict):
|
|
for key in unsupported_keys.get(obj_type, []):
|
|
if key in obj_dict:
|
|
if obj_dict.get(key):
|
|
LOG.warning("Ignoring %(key)s:%(val)s in %(type)s as the "
|
|
"NSX plugin does not currently support it",
|
|
{'key': key, 'val': obj_dict[key],
|
|
'type': obj_type})
|
|
del obj_dict[key]
|
|
|
|
def obj_to_dict(self, obj, is_update=False, project_id=None):
|
|
obj_type = obj.__class__.__name__
|
|
# create a dictionary out of the object
|
|
render_unsets = False if is_update else True
|
|
obj_dict = obj.to_dict(recurse=True, render_unsets=render_unsets)
|
|
|
|
# Update the dictionary to match what the nsx driver expects
|
|
if not project_id:
|
|
project_id = self.get_obj_project_id(obj_type, obj_dict)
|
|
obj_dict['tenant_id'] = obj_dict['project_id'] = project_id
|
|
|
|
if 'id' not in obj_dict:
|
|
obj_dict['id'] = obj_dict.get('%s_id' % obj_type.lower())
|
|
|
|
if not obj_dict.get('name') and not is_update:
|
|
obj_dict['name'] = ""
|
|
|
|
self._remove_unsupported_keys(obj_type, obj_dict)
|
|
|
|
if obj_type == 'LoadBalancer':
|
|
# clean listeners and pools for update case:
|
|
if 'listeners' in obj_dict:
|
|
if is_update and not obj_dict['listeners']:
|
|
del obj_dict['listeners']
|
|
else:
|
|
if obj_dict['listeners'] is None:
|
|
obj_dict['listeners'] = []
|
|
for listener in obj_dict['listeners']:
|
|
listener['id'] = listener['listener_id']
|
|
for policy in listener.get('l7policies', []):
|
|
policy['id'] = policy['l7policy_id']
|
|
for rule in policy.get('rules', []):
|
|
rule['id'] = rule['l7rule_id']
|
|
if 'pools' in obj_dict:
|
|
if is_update and not obj_dict['pools']:
|
|
del obj_dict['pools']
|
|
else:
|
|
if obj_dict['pools'] is None:
|
|
obj_dict['pools'] = []
|
|
for pool in obj_dict['pools']:
|
|
pool['id'] = pool['pool_id']
|
|
for member in pool.get('members', []):
|
|
member['id'] = member['member_id']
|
|
if pool.get('healthmonitor'):
|
|
pool['healthmonitor'] = self._get_hm_dict(
|
|
pool['healthmonitor']['healthmonitor_id'],
|
|
is_update)
|
|
pool['tenant_id'] = project_id
|
|
|
|
elif obj_type == 'Listener':
|
|
if 'l7policies' in obj_dict:
|
|
obj_dict['l7_policies'] = obj_dict['l7policies']
|
|
if obj_dict.get('loadbalancer_id'):
|
|
# Generate a loadbalancer object
|
|
obj_dict['loadbalancer'] = self._get_load_balancer_dict(
|
|
obj_dict['loadbalancer_id'])
|
|
if obj_dict.get('default_pool_id'):
|
|
# Generate the default pool object
|
|
obj_dict['default_pool'] = self._get_pool_dict(
|
|
obj_dict['default_pool_id'], is_update, project_id)
|
|
# TODO(asarfaty): add default_tls_container_id
|
|
|
|
elif obj_type == 'Pool':
|
|
if 'listener' not in obj_dict:
|
|
self._get_listener_in_pool_dict(obj_dict, is_update)
|
|
if obj_dict.get('healthmonitor'):
|
|
obj_dict['healthmonitor']['id'] = obj_dict[
|
|
'healthmonitor']['healthmonitor_id']
|
|
|
|
elif obj_type == 'Member':
|
|
# Get the pool object
|
|
if obj_dict.get('pool_id'):
|
|
obj_dict['pool'] = self._get_pool_dict(
|
|
obj_dict['pool_id'], is_update)
|
|
obj_dict['loadbalancer'] = None
|
|
if 'loadbalancer' in obj_dict['pool']:
|
|
obj_dict['loadbalancer'] = obj_dict['pool']['loadbalancer']
|
|
if not obj_dict.get('subnet_id'):
|
|
# Use the parent vip_subnet_id instead
|
|
obj_dict['subnet_id'] = obj_dict['loadbalancer'][
|
|
'vip_subnet_id']
|
|
elif not is_update:
|
|
# Do not set pool & LB if in update situation, as we want to
|
|
# use the original data of this member
|
|
obj_dict['pool'] = None
|
|
obj_dict['loadbalancer'] = None
|
|
|
|
elif obj_type == 'HealthMonitor':
|
|
# Get the pool object
|
|
if obj_dict.get('pool_id'):
|
|
obj_dict['pool'] = self._get_pool_dict(
|
|
obj_dict['pool_id'], is_update)
|
|
|
|
elif obj_type == 'L7Policy':
|
|
self.update_policy_dict(obj_dict, obj, is_update=is_update)
|
|
|
|
elif obj_type == 'L7Rule':
|
|
# Get the L7 policy object
|
|
if obj_dict.get('l7policy_id'):
|
|
db_policy = self.repositories.l7policy.get(
|
|
db_apis.get_session(), id=obj_dict['l7policy_id'])
|
|
policy_obj = oct_utils.db_l7policy_to_provider_l7policy(
|
|
db_policy)
|
|
policy_dict = policy_obj.to_dict(
|
|
recurse=True, render_unsets=True)
|
|
policy_dict['id'] = obj_dict['l7policy_id']
|
|
self.update_policy_dict(
|
|
policy_dict, policy_obj, is_update=is_update)
|
|
obj_dict['policy'] = policy_dict
|
|
|
|
LOG.debug("Translated %(type)s to dictionary: %(obj)s",
|
|
{'type': obj_type, 'obj': obj_dict})
|
|
return obj_dict
|
|
|
|
# Load Balancer
|
|
@log_helpers.log_method_call
|
|
def create_vip_port(self, loadbalancer_id, project_id, vip_dictionary):
|
|
raise exceptions.NotImplementedError()
|
|
|
|
@log_helpers.log_method_call
|
|
def loadbalancer_create(self, loadbalancer):
|
|
kw = {'loadbalancer': self.obj_to_dict(loadbalancer)}
|
|
self.client.cast({}, 'loadbalancer_create', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def loadbalancer_delete(self, loadbalancer, cascade=False):
|
|
kw = {'loadbalancer': self.obj_to_dict(loadbalancer),
|
|
'cascade': cascade}
|
|
self.client.cast({}, 'loadbalancer_delete', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def loadbalancer_failover(self, loadbalancer_id):
|
|
LOG.error('Loadbalancer failover is handled by platform')
|
|
raise exceptions.NotImplementedError()
|
|
|
|
@log_helpers.log_method_call
|
|
def loadbalancer_update(self, old_loadbalancer, new_loadbalancer):
|
|
old_dict = self.obj_to_dict(old_loadbalancer)
|
|
new_dict = copy.deepcopy(old_dict)
|
|
new_dict.update(self.obj_to_dict(
|
|
new_loadbalancer, is_update=True,
|
|
project_id=old_dict.get('project_id')))
|
|
kw = {'old_loadbalancer': old_dict,
|
|
'new_loadbalancer': new_dict}
|
|
self.client.cast({}, 'loadbalancer_update', **kw)
|
|
|
|
# Listener
|
|
@log_helpers.log_method_call
|
|
def listener_create(self, listener):
|
|
cert = None
|
|
dict_list = self.obj_to_dict(listener)
|
|
if dict_list.get('tls_certificate_id'):
|
|
context = pecan.request.context.get('octavia_context')
|
|
cert = self.cert_manager.get_cert(context,
|
|
dict_list['tls_certificate_id'])
|
|
kw = {'listener': dict_list, 'cert': cert}
|
|
self.client.cast({}, 'listener_create', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def listener_delete(self, listener):
|
|
kw = {'listener': self.obj_to_dict(listener)}
|
|
self.client.cast({}, 'listener_delete', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def listener_update(self, old_listener, new_listener):
|
|
old_dict = self.obj_to_dict(old_listener)
|
|
new_dict = copy.deepcopy(old_dict)
|
|
new_dict.update(self.obj_to_dict(
|
|
new_listener, is_update=True,
|
|
project_id=old_dict.get('project_id')))
|
|
cert = None
|
|
if new_dict.get('tls_certificate_id'):
|
|
context = pecan.request.context.get('octavia_context')
|
|
cert = self.cert_manager.get_cert(context,
|
|
new_dict['tls_certificate_id'])
|
|
kw = {'old_listener': old_dict,
|
|
'new_listener': new_dict,
|
|
'cert': cert}
|
|
self.client.cast({}, 'listener_update', **kw)
|
|
|
|
# Pool
|
|
@log_helpers.log_method_call
|
|
def pool_create(self, pool):
|
|
kw = {'pool': self.obj_to_dict(pool)}
|
|
self.client.cast({}, 'pool_create', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def pool_delete(self, pool):
|
|
kw = {'pool': self.obj_to_dict(pool)}
|
|
self.client.cast({}, 'pool_delete', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def pool_update(self, old_pool, new_pool):
|
|
old_dict = self.obj_to_dict(old_pool)
|
|
new_dict = copy.deepcopy(old_dict)
|
|
new_pool_dict = self.obj_to_dict(
|
|
new_pool, is_update=True, project_id=old_dict.get('project_id'))
|
|
new_dict.update(new_pool_dict)
|
|
kw = {'old_pool': old_dict,
|
|
'new_pool': new_dict}
|
|
self.client.cast({}, 'pool_update', **kw)
|
|
|
|
# Member
|
|
@log_helpers.log_method_call
|
|
def member_create(self, member):
|
|
kw = {'member': self.obj_to_dict(member)}
|
|
self.client.cast({}, 'member_create', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def member_delete(self, member):
|
|
kw = {'member': self.obj_to_dict(member)}
|
|
self.client.cast({}, 'member_delete', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def member_update(self, old_member, new_member):
|
|
old_dict = self.obj_to_dict(old_member)
|
|
new_dict = copy.deepcopy(old_dict)
|
|
new_dict.update(self.obj_to_dict(
|
|
new_member, is_update=True, project_id=old_dict.get('project_id')))
|
|
kw = {'old_member': old_dict,
|
|
'new_member': new_dict}
|
|
self.client.cast({}, 'member_update', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def member_batch_update(self, members):
|
|
raise NotImplementedError()
|
|
|
|
# Health Monitor
|
|
@log_helpers.log_method_call
|
|
def health_monitor_create(self, healthmonitor):
|
|
kw = {'healthmonitor': self.obj_to_dict(healthmonitor)}
|
|
self.client.cast({}, 'healthmonitor_create', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def health_monitor_delete(self, healthmonitor):
|
|
kw = {'healthmonitor': self.obj_to_dict(healthmonitor)}
|
|
self.client.cast({}, 'healthmonitor_delete', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def health_monitor_update(self, old_healthmonitor, new_healthmonitor):
|
|
old_dict = self.obj_to_dict(old_healthmonitor)
|
|
new_dict = copy.deepcopy(old_dict)
|
|
new_dict.update(self.obj_to_dict(
|
|
new_healthmonitor, is_update=True,
|
|
project_id=old_dict.get('project_id')))
|
|
kw = {'old_healthmonitor': old_dict,
|
|
'new_healthmonitor': new_dict}
|
|
self.client.cast({}, 'healthmonitor_update', **kw)
|
|
|
|
# L7 Policy
|
|
@log_helpers.log_method_call
|
|
def l7policy_create(self, l7policy):
|
|
kw = {'l7policy': self.obj_to_dict(l7policy)}
|
|
self.client.cast({}, 'l7policy_create', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def l7policy_delete(self, l7policy):
|
|
kw = {'l7policy': self.obj_to_dict(l7policy)}
|
|
self.client.cast({}, 'l7policy_delete', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def l7policy_update(self, old_l7policy, new_l7policy):
|
|
old_dict = self.obj_to_dict(old_l7policy)
|
|
new_dict = copy.deepcopy(old_dict)
|
|
new_dict.update(self.obj_to_dict(
|
|
new_l7policy, is_update=True,
|
|
project_id=old_dict.get('project_id')))
|
|
kw = {'old_l7policy': old_dict,
|
|
'new_l7policy': new_dict}
|
|
self.client.cast({}, 'l7policy_update', **kw)
|
|
|
|
# L7 Rule
|
|
@log_helpers.log_method_call
|
|
def l7rule_create(self, l7rule):
|
|
kw = {'l7rule': self.obj_to_dict(l7rule)}
|
|
self.client.cast({}, 'l7rule_create', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def l7rule_delete(self, l7rule):
|
|
kw = {'l7rule': self.obj_to_dict(l7rule)}
|
|
self.client.cast({}, 'l7rule_delete', **kw)
|
|
|
|
@log_helpers.log_method_call
|
|
def l7rule_update(self, old_l7rule, new_l7rule):
|
|
old_dict = self.obj_to_dict(old_l7rule)
|
|
new_dict = copy.deepcopy(old_dict)
|
|
new_dict.update(self.obj_to_dict(
|
|
new_l7rule, is_update=True, project_id=old_dict.get('project_id')))
|
|
kw = {'old_l7rule': old_dict,
|
|
'new_l7rule': new_dict}
|
|
self.client.cast({}, 'l7rule_update', **kw)
|
|
|
|
# Flavor
|
|
@log_helpers.log_method_call
|
|
def get_supported_flavor_metadata(self):
|
|
raise exceptions.NotImplementedError()
|
|
|
|
@log_helpers.log_method_call
|
|
def validate_flavor(self, flavor_metadata):
|
|
raise exceptions.NotImplementedError()
|
|
|
|
|
|
class NSXOctaviaDriverEndpoint(driver_lib.DriverLibrary):
|
|
target = messaging.Target(namespace="control", version='1.0')
|
|
|
|
@log_helpers.log_method_call
|
|
def update_loadbalancer_status(self, ctxt, status):
|
|
# refresh the driver lib session
|
|
self.db_session = db_apis.get_session()
|
|
try:
|
|
return super(NSXOctaviaDriverEndpoint,
|
|
self).update_loadbalancer_status(status)
|
|
except exceptions.UpdateStatusError as e:
|
|
LOG.error("Failed to update Octavia loadbalancer status. "
|
|
"Status %s, Error %s", status, e.fault_string)
|
|
|
|
@log_helpers.log_method_call
|
|
def update_listener_statistics(self, ctxt, statistics):
|
|
# refresh the driver lib session
|
|
self.db_session = db_apis.get_session()
|
|
try:
|
|
return super(NSXOctaviaDriverEndpoint,
|
|
self).update_listener_statistics(statistics)
|
|
except exceptions.UpdateStatisticsError as e:
|
|
LOG.error("Failed to update Octavia listener statistics. "
|
|
"Stats %s, Error %s", statistics, e.fault_string)
|
|
|
|
|
|
@log_helpers.log_method_call
|
|
def vmware_nsx_provider_agent(exit_event):
|
|
# Initialize RPC listener
|
|
topic = d_const.DRIVER_TO_OCTAVIA_TOPIC
|
|
server = socket.gethostname()
|
|
target = messaging.Target(topic=topic, server=server,
|
|
exchange="common", fanout=False)
|
|
endpoints = [NSXOctaviaDriverEndpoint()]
|
|
access_policy = dispatcher.DefaultRPCAccessPolicy
|
|
get_transport()
|
|
octavia_server = get_rpc_server(target, endpoints, access_policy)
|
|
octavia_server.start()
|
|
|
|
LOG.info('VMware NSX Octavia provider agent has started.')
|
|
while not exit_event.is_set():
|
|
time.sleep(1)
|
|
LOG.info('VMware NSX Octavia provider agent is exiting.')
|