From 09df271c9c950fbee2add39c36eef6c961622e08 Mon Sep 17 00:00:00 2001 From: Mark McClain Date: Tue, 12 Apr 2016 16:59:57 -0400 Subject: [PATCH] Ensure router interfaces properly reflect the state This change ensures the interface states matches the underlying interfaces states. Change-Id: I4d15795aadee6ed754799b36b9f9c0e4d9245338 Closes-Bug:1540520 --- astara_neutron/extensions/routerstatus.py | 44 +++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/astara_neutron/extensions/routerstatus.py b/astara_neutron/extensions/routerstatus.py index 2b3c493..d82d66c 100644 --- a/astara_neutron/extensions/routerstatus.py +++ b/astara_neutron/extensions/routerstatus.py @@ -17,9 +17,14 @@ from neutron.api import extensions from neutron.db.l3_db import Router +from neutron.db import models_v2 from astara_neutron.extensions import _authzbase +STATUS_ACTIVE = 'ACTIVE' +STATUS_DOWN = 'DOWN' + + class RouterstatusResource(_authzbase.ResourceDelegate): """This resource is intended as a private API that allows the rug to change a router's status (which is normally a read-only attribute) @@ -52,6 +57,45 @@ class RouterstatusResource(_authzbase.ResourceDelegate): 'status': router['status'] } + def update(self, context, resource, resource_dict): + with context.session.begin(subtransactions=True): + resource.update(resource_dict) + context.session.add(resource) + + # sync logical ports to backing port status + for router_port in resource.attached_ports: + if router_port.port.status != resource.status: + self._update_port_status( + context, + resource, + router_port.port + ) + context.session.add(router_port.port) + return self.make_dict(resource) + + def _update_port_status(self, context, router, port): + # assume port is down until proven otherwise + next_status = STATUS_DOWN + + # find backing ports works with both ASTARA and AKANDA + partial_name = 'A%%:VRRP:%s' % router.id + + query = context.session.query(models_v2.Port) + query = query.filter( + models_v2.Port.network_id == port.network_id, + models_v2.Port.name.like(partial_name) + ) + + for backing_port in query.all(): + if not backing_port.device_owner or not backing_port.device_id: + continue + + next_status = backing_port.status + if next_status != STATUS_ACTIVE: + break + + port.status = next_status + class Routerstatus(extensions.ExtensionDescriptor): """