def _update_router_db(self, context, router_id, data): router_db = self._get_router(context, router_id) original_distributed_state = router_db.extra_attributes.distributed original_ha_state = router_db.extra_attributes.ha requested_ha_state = data.pop('ha', None) requested_distributed_state = data.get('distributed', None) # cvr to dvrha if not original_distributed_state and not original_ha_state: if (requested_ha_state is True and requested_distributed_state is True): raise l3_ha.UpdateToDvrHamodeNotSupported() # cvrha to any dvr... elif not original_distributed_state and original_ha_state: if requested_distributed_state is True: raise l3_ha.DVRmodeUpdateOfHaNotSupported() # dvr to any ha... elif original_distributed_state and not original_ha_state: if requested_ha_state is True: raise l3_ha.HAmodeUpdateOfDvrNotSupported() #dvrha to any cvr... elif original_distributed_state and original_ha_state: if requested_distributed_state is False: raise l3_ha.DVRmodeUpdateOfDvrHaNotSupported() #elif dvrha to dvr if requested_ha_state is False: raise l3_ha.HAmodeUpdateOfDvrHaNotSupported() ha_changed = (requested_ha_state is not None and requested_ha_state != original_ha_state) if ha_changed: if router_db.admin_state_up: msg = _('Cannot change HA attribute of active routers. Please ' 'set router admin_state_up to False prior to upgrade.') raise n_exc.BadRequest(resource='router', msg=msg) # set status to ALLOCATING so this router is no longer # provided to agents while its interfaces are being re-configured. # Keep in mind that if we want conversion to be hitless, this # status cannot be used because agents treat hidden routers as # deleted routers. data['status'] = constants.ROUTER_STATUS_ALLOCATING with context.session.begin(subtransactions=True): router_db = super(L3_HA_NAT_db_mixin, self)._update_router_db(context, router_id, data) if not ha_changed: return router_db ha_network = self.get_ha_network(context, router_db.tenant_id) router_db.extra_attributes.ha = requested_ha_state if not requested_ha_state: self._delete_vr_id_allocation( context, ha_network, router_db.extra_attributes.ha_vr_id) router_db.extra_attributes.ha_vr_id = None # The HA attribute has changed. First unbind the router from agents # to force a proper re-scheduling to agents. # TODO(jschwarz): This will have to be more selective to get HA + DVR # working (Only unbind from dvr_snat nodes). self._unbind_ha_router(context, router_id) if requested_ha_state: ha_network = self._create_ha_interfaces_and_ensure_network( context, router_db)[1] self._set_vr_id(context, router_db, ha_network) else: self._delete_ha_interfaces(context, router_db.id) self.schedule_router(context, router_id) router_db = super(L3_HA_NAT_db_mixin, self)._update_router_db( context, router_id, {'status': constants.ROUTER_STATUS_ACTIVE}) self._notify_ha_interfaces_updated(context, router_db.id, schedule_routers=False) return router_db
def _update_router_db(self, context, router_id, data): router_db = self._get_router(context, router_id) original_distributed_state = router_db.extra_attributes.distributed original_ha_state = router_db.extra_attributes.ha requested_ha_state = data.pop('ha', None) requested_distributed_state = data.get('distributed', None) # cvr to dvrha if not original_distributed_state and not original_ha_state: if (requested_ha_state is True and requested_distributed_state is True): raise l3_ha.UpdateToDvrHamodeNotSupported() # cvrha to any dvr... elif not original_distributed_state and original_ha_state: if requested_distributed_state is True: raise l3_ha.DVRmodeUpdateOfHaNotSupported() # dvr to any ha... elif original_distributed_state and not original_ha_state: if requested_ha_state is True: raise l3_ha.HAmodeUpdateOfDvrNotSupported() #dvrha to any cvr... elif original_distributed_state and original_ha_state: if requested_distributed_state is False: raise l3_ha.DVRmodeUpdateOfDvrHaNotSupported() #elif dvrha to dvr if requested_ha_state is False: raise l3_ha.HAmodeUpdateOfDvrHaNotSupported() with context.session.begin(subtransactions=True): router_db = super(L3_HA_NAT_db_mixin, self)._update_router_db( context, router_id, data) ha_not_changed = (requested_ha_state is None or requested_ha_state == original_ha_state) if ha_not_changed: return router_db if router_db.admin_state_up: msg = _('Cannot change HA attribute of active routers. Please ' 'set router admin_state_up to False prior to upgrade.') raise n_exc.BadRequest(resource='router', msg=msg) ha_network = self.get_ha_network(context, router_db.tenant_id) router_db.extra_attributes.ha = requested_ha_state if not requested_ha_state: self._delete_vr_id_allocation( context, ha_network, router_db.extra_attributes.ha_vr_id) router_db.extra_attributes.ha_vr_id = None # The HA attribute has changed. First unbind the router from agents # to force a proper re-scheduling to agents. # TODO(jschwarz): This will have to be more selective to get HA + DVR # working (Only unbind from dvr_snat nodes). self._unbind_ha_router(context, router_id) if requested_ha_state: if not ha_network: ha_network = self._create_ha_network(context, router_db.tenant_id) self._set_vr_id(context, router_db, ha_network) self._create_ha_interfaces(context, router_db, ha_network) self._notify_ha_interfaces_updated(context, router_db.id) else: self._delete_ha_interfaces(context, router_db.id) self._notify_ha_interfaces_updated(context, router_db.id) return router_db