193 lines
8.1 KiB
Python
193 lines
8.1 KiB
Python
# Copyright 2014 A10 Networks
|
|
#
|
|
# 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 abc
|
|
from neutron.plugins.common import constants
|
|
from oslo_log import log as logging
|
|
import six
|
|
|
|
from neutron_lbaas.db.loadbalancer import models
|
|
from neutron_lbaas.services.loadbalancer import constants as lb_const
|
|
from neutron_lbaas.services.loadbalancer import data_models
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class BaseManagerMixin(object):
|
|
|
|
def __init__(self, driver):
|
|
self.driver = driver
|
|
|
|
@abc.abstractproperty
|
|
def db_delete_method(self):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def create(self, context, obj):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def update(self, context, obj_old, obj):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete(self, context, obj):
|
|
pass
|
|
|
|
def successful_completion(self, context, obj, delete=False,
|
|
lb_create=False):
|
|
"""
|
|
Sets the provisioning_status of the load balancer and obj to
|
|
ACTIVE. Should be called last in the implementor's BaseManagerMixin
|
|
methods for successful runs.
|
|
|
|
:param context: neutron context
|
|
:param obj: instance of a
|
|
neutron_lbaas.services.loadbalancer.data_model
|
|
:param delete: set True if being called from a delete method. Will
|
|
most likely result in the obj being deleted from the db.
|
|
:param lb_create: set True if this is being called after a successful
|
|
load balancer create.
|
|
"""
|
|
LOG.debug("Starting successful_completion method after a successful "
|
|
"driver action.")
|
|
obj_sa_cls = data_models.DATA_MODEL_TO_SA_MODEL_MAP[obj.__class__]
|
|
if delete:
|
|
# Check if driver is responsible for vip allocation. If the driver
|
|
# is responsible, then it is also responsible for cleaning it up.
|
|
# At this point, the VIP should already be cleaned up, so we are
|
|
# just doing neutron lbaas db cleanup.
|
|
if (obj == obj.root_loadbalancer and
|
|
self.driver.load_balancer.allocates_vip):
|
|
# NOTE(blogan): this is quite dumb to do but it is necessary
|
|
# so that a false negative pep8 error does not get thrown. An
|
|
# "unexpected-keyword-argument" pep8 error occurs bc
|
|
# self.db_delete_method is a @property method that returns a
|
|
# method.
|
|
kwargs = {'delete_vip_port': False}
|
|
self.db_delete_method(context, obj.id, **kwargs)
|
|
else:
|
|
self.db_delete_method(context, obj.id)
|
|
if obj == obj.root_loadbalancer and delete:
|
|
# Load balancer was deleted and no longer exists
|
|
return
|
|
lb_op_status = None
|
|
lb_p_status = constants.ACTIVE
|
|
if obj == obj.root_loadbalancer:
|
|
# only set the status to online if this an operation on the
|
|
# load balancer
|
|
lb_op_status = lb_const.ONLINE
|
|
|
|
# Update the load balancer's vip address and vip port id if the driver
|
|
# was responsible for allocating the vip.
|
|
if (self.driver.load_balancer.allocates_vip and lb_create and
|
|
isinstance(obj, data_models.LoadBalancer)):
|
|
self.driver.plugin.db.update_loadbalancer(
|
|
context, obj.id, {'vip_address': obj.vip_address,
|
|
'vip_port_id': obj.vip_port_id})
|
|
if delete:
|
|
# We cannot update the status of obj if it was deleted but if the
|
|
# obj is not a load balancer, the root load balancer should be
|
|
# updated
|
|
if not isinstance(obj, data_models.LoadBalancer):
|
|
self.driver.plugin.db.update_status(
|
|
context, models.LoadBalancer, obj.root_loadbalancer.id,
|
|
provisioning_status=lb_p_status,
|
|
operating_status=lb_op_status)
|
|
return
|
|
obj_op_status = lb_const.ONLINE
|
|
if isinstance(obj, data_models.HealthMonitor):
|
|
# Health Monitor does not have an operating status
|
|
obj_op_status = None
|
|
LOG.debug("Updating object of type {0} with id of {1} to "
|
|
"provisioning_status = {2}, operating_status = {3}".format(
|
|
obj.__class__, obj.id, constants.ACTIVE, obj_op_status))
|
|
self.driver.plugin.db.update_status(
|
|
context, obj_sa_cls, obj.id,
|
|
provisioning_status=constants.ACTIVE,
|
|
operating_status=obj_op_status)
|
|
if not isinstance(obj, data_models.LoadBalancer):
|
|
# Only update the status of the root_loadbalancer if the previous
|
|
# update was not the root load balancer so we are not updating
|
|
# it twice.
|
|
self.driver.plugin.db.update_status(
|
|
context, models.LoadBalancer, obj.root_loadbalancer.id,
|
|
provisioning_status=lb_p_status,
|
|
operating_status=lb_op_status)
|
|
|
|
def failed_completion(self, context, obj):
|
|
"""
|
|
Sets the provisioning status of the obj to ERROR. If obj is a
|
|
loadbalancer it will be set to ERROR, otherwise set to ACTIVE. Should
|
|
be called whenever something goes wrong (raised exception) in an
|
|
implementor's BaseManagerMixin methods.
|
|
|
|
:param context: neutron context
|
|
:param obj: instance of a
|
|
neutron_lbaas.services.loadbalancer.data_model
|
|
"""
|
|
LOG.debug("Starting failed_completion method after a failed driver "
|
|
"action.")
|
|
if isinstance(obj, data_models.LoadBalancer):
|
|
LOG.debug("Updating load balancer {0} to provisioning_status = "
|
|
"{1}, operating_status = {2}.".format(
|
|
obj.root_loadbalancer.id, constants.ERROR,
|
|
lb_const.OFFLINE))
|
|
self.driver.plugin.db.update_status(
|
|
context, models.LoadBalancer, obj.root_loadbalancer.id,
|
|
provisioning_status=constants.ERROR,
|
|
operating_status=lb_const.OFFLINE)
|
|
return
|
|
obj_sa_cls = data_models.DATA_MODEL_TO_SA_MODEL_MAP[obj.__class__]
|
|
LOG.debug("Updating object of type {0} with id of {1} to "
|
|
"provisioning_status = {2}, operating_status = {3}".format(
|
|
obj.__class__, obj.id, constants.ERROR,
|
|
lb_const.OFFLINE))
|
|
self.driver.plugin.db.update_status(
|
|
context, obj_sa_cls, obj.id,
|
|
provisioning_status=constants.ERROR,
|
|
operating_status=lb_const.OFFLINE)
|
|
LOG.debug("Updating load balancer {0} to "
|
|
"provisioning_status = {1}".format(obj.root_loadbalancer.id,
|
|
constants.ACTIVE))
|
|
self.driver.plugin.db.update_status(
|
|
context, models.LoadBalancer, obj.root_loadbalancer.id,
|
|
provisioning_status=constants.ACTIVE)
|
|
|
|
def update_vip(self, context, loadbalancer_id, vip_address,
|
|
vip_port_id=None):
|
|
lb_update = {'vip_address': vip_address}
|
|
if vip_port_id:
|
|
lb_update['vip_port_id'] = vip_port_id
|
|
self.driver.plugin.db.update_loadbalancer(context, loadbalancer_id,
|
|
lb_update)
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class BaseRefreshMixin(object):
|
|
|
|
@abc.abstractmethod
|
|
def refresh(self, context, obj):
|
|
pass
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class BaseStatsMixin(object):
|
|
|
|
@abc.abstractmethod
|
|
def stats(self, context, obj):
|
|
pass
|