def test_basic_dep_track(self): reaction_map = { "red": { 'self': ['blue', 'green'], }, "blue": { 'self': [], 'red': [], }, "green": { 'self': [], 'red': [], }, "purple": { 'self': [], }, } dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, reaction_map) red = RedSM.locate("fake-red-uuid") blue = BlueSM.locate("fake-blue-uuid") green = GreenSM.locate("fake-green-uuid") dependency_tracker.evaluate('red', red) self.assertEqual(len(dependency_tracker.resources), 3) self.assertTrue("red" in dependency_tracker.resources) self.assertTrue("blue" in dependency_tracker.resources) self.assertTrue("green" in dependency_tracker.resources) self.assertEqual(dependency_tracker.resources["red"], ["fake-red-uuid"]) self.assertEqual(dependency_tracker.resources["blue"], ["fake-blue-uuid"]) self.assertEqual(dependency_tracker.resources["green"], ["fake-green-uuid"]) RedSM.delete("fake-red-uuid") GreenSM.delete("fake-green-uuid") BlueSM.delete("fake-blue-uuid")
def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: self.obj.update() except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids))
def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker(self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: self.obj.update() except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids))
def test_basic_dep_track_1(self): reaction_map = { "red": { 'self': [], }, "blue": { 'self': ['green'], }, "green": { 'self': [], 'blue': [], }, "purple": { 'self': [], }, } GreenSM._object_db.object_read = self.green_read_with_refs BlueSM._object_db.object_read = self.blue_read_with_multi_refs dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, reaction_map) RedSM.locate("fake-red-uuid") blue = BlueSM.locate("fake-blue-uuid") GreenSM.locate("fake-green-uuid") dependency_tracker.evaluate('blue', blue) self.assertEqual(len(dependency_tracker.resources), 2) self.assertTrue("blue" in dependency_tracker.resources) self.assertTrue("green" in dependency_tracker.resources) self.assertEqual(dependency_tracker.resources["blue"], ["fake-blue-uuid"]) self.assertEqual(dependency_tracker.resources["green"], ["fake-green-uuid"]) RedSM.delete("fake-red-uuid") GreenSM.delete("fake-green-uuid") BlueSM.delete("fake-blue-uuid")
def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker(self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: if self.obj.update() == False: # If update returns a False it indicates nothing has changed. # If it returns True or None, then some change was detected. # If no change, then terminate dependency tracker return except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids))
def test_basic_dep_track_2(self): reaction_map = { "red": { 'self': [], }, "blue": { 'self': ['green'], }, "green": { 'self': [], 'blue': [], }, "purple": { 'self': [], }, } GreenSM._object_db.object_read = self.green_read_with_refs BlueSM._object_db.object_read = self.blue_read_with_multi_refs dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, reaction_map) red = RedSM.locate("fake-red-uuid") blue = BlueSM.locate("fake-blue-uuid") GreenSM.locate("fake-green-uuid-0") GreenSM.locate("fake-green-uuid-1") dependency_tracker.evaluate('blue', blue) self.assertEqual(len(dependency_tracker.resources), 2) self.assertTrue("blue" in dependency_tracker.resources) self.assertTrue("green" in dependency_tracker.resources) self.assertEqual(dependency_tracker.resources["green"], ["fake-green-uuid-1", "fake-green-uuid-0"]) self.assertEqual(dependency_tracker.resources["blue"], ["fake-blue-uuid"]) RedSM.delete("fake-red-uuid") GreenSM.delete("fake-green-uuid-0") GreenSM.delete("fake-green-uuid-1") BlueSM.delete("fake-blue-uuid")
def test_basic_dep_track_update_1(self): reaction_map = { "red": { 'self': ['green', 'blue'], }, "blue": { 'self': ['green'], 'red': ['blue'], 'purple': ['green'], 'green': [], }, "green": { 'self': ['white'], 'blue': ['white'], 'red': ['blue'], }, "white": { 'self': ['purple'], 'green': ['purple'], }, "purple": { 'self': ['blue'], 'white': ['blue'], }, } GreenSM._object_db.object_read = self.green_read_with_refs WhiteSM._object_db.object_read = self.white_read_with_refs BlueSM._object_db.object_read = self.purple_read_with_multi_refs BlueSM._object_db.object_read = self.blue_read_with_multi_refs dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, reaction_map) red = RedSM.locate("fake-red-uuid") blue = BlueSM.locate("fake-blue-uuid") green = GreenSM.locate("fake-green-uuid-0") GreenSM.locate("fake-green-uuid-1") white = WhiteSM.locate("fake-white-uuid") purple = PurpleSM.locate("fake-purple-uuid") dependency_tracker.evaluate('red', red) GreenSM.delete("fake-green-uuid-0") GreenSM.delete("fake-green-uuid-1") GreenSM.locate("fake-green-uuid-2") GreenSM.locate("fake-green-uuid-3") BlueSM._object_db.object_read = self.blue_read_with_new_refs blue.update() dependency_tracker.resources = {} dependency_tracker.evaluate('red', red) self.assertEqual(len(dependency_tracker.resources), 3) self.assertTrue("blue" in dependency_tracker.resources) self.assertTrue("green" in dependency_tracker.resources) self.assertTrue("red" in dependency_tracker.resources) self.assertEqual(set(dependency_tracker.resources["green"]), set(["fake-green-uuid-2", "fake-green-uuid-3"])) self.assertEqual(dependency_tracker.resources["blue"], ["fake-blue-uuid"]) self.assertEqual(dependency_tracker.resources["red"], ["fake-red-uuid"]) RedSM.delete("fake-red-uuid") GreenSM.delete("fake-green-uuid-2") GreenSM.delete("fake-green-uuid-3") BlueSM.delete("fake-blue-uuid") WhiteSM.delete("fake-white-uuid") PurpleSM.delete("fake-purple-uuid")
def test_basic_dep_track_update_2(self): reaction_map = { "red": { 'self': ['green', 'blue'], }, "blue": { 'self': ['green'], 'red': ['blue'], 'purple': ['green'], 'green': [], }, "green": { 'self': ['white'], 'blue': ['white'], 'red': ['blue'], }, "white": { 'self': ['purple'], 'green': ['purple'], }, "purple": { 'self': ['blue'], 'white': ['blue'], }, } GreenSM._object_db.object_read = self.green_read_with_refs WhiteSM._object_db.object_read = self.white_read_with_refs BlueSM._object_db.object_read = self.purple_read_with_multi_refs BlueSM._object_db.object_read = self.blue_read_with_multi_refs dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, reaction_map) RedSM.locate("fake-red-uuid") blue = BlueSM.locate("fake-blue-uuid") GreenSM.locate("fake-green-uuid-0") GreenSM.locate("fake-green-uuid-1") WhiteSM.locate("fake-white-uuid") PurpleSM.locate("fake-purple-uuid") dependency_tracker.evaluate('blue', blue) GreenSM.delete("fake-green-uuid-0") GreenSM.delete("fake-green-uuid-1") GreenSM.locate("fake-green-uuid-2") GreenSM.locate("fake-green-uuid-3") BlueSM._object_db.object_read = self.blue_read_with_new_refs blue.update() dependency_tracker.resources = {} dependency_tracker.evaluate('blue', blue) self.assertEqual(len(dependency_tracker.resources), 2) self.assertTrue("blue" in dependency_tracker.resources) self.assertTrue("green" in dependency_tracker.resources) self.assertItemsEqual(dependency_tracker.resources["green"], ["fake-green-uuid-2", "fake-green-uuid-3"]) self.assertEqual(dependency_tracker.resources["blue"], ["fake-blue-uuid"]) RedSM.delete("fake-red-uuid") GreenSM.delete("fake-green-uuid-2") GreenSM.delete("fake-green-uuid-3") BlueSM.delete("fake-blue-uuid") WhiteSM.delete("fake-white-uuid") PurpleSM.delete("fake-purple-uuid")
def test_basic_dep_track_7(self): reaction_map = { "red": { 'self': ['green', 'blue'], }, "blue": { 'self': ['green'], 'red': [], 'purple': ['green'], }, "green": { 'self': ['white'], 'blue': ['white'], 'red': [], }, "white": { 'self': ['purple'], 'green': ['purple'], }, "purple": { 'self': ['blue'], 'white': ['blue'], }, } GreenSM._object_db.object_read = self.green_read_with_refs WhiteSM._object_db.object_read = self.white_read_with_refs BlueSM._object_db.object_read = self.purple_read_with_multi_refs BlueSM._object_db.object_read = self.blue_read_with_multi_refs dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, reaction_map) red = RedSM.locate("fake-red-uuid") blue = BlueSM.locate("fake-blue-uuid") green = GreenSM.locate("fake-green-uuid-0") GreenSM.locate("fake-green-uuid-1") white = WhiteSM.locate("fake-white-uuid") purple = PurpleSM.locate("fake-purple-uuid") dependency_tracker.evaluate('purple', purple) self.assertEqual(len(dependency_tracker.resources), 4) self.assertTrue("blue" in dependency_tracker.resources) self.assertTrue("green" in dependency_tracker.resources) self.assertTrue("white" in dependency_tracker.resources) self.assertTrue("purple" in dependency_tracker.resources) self.assertEqual(set(dependency_tracker.resources["green"]), set(["fake-green-uuid-1", "fake-green-uuid-0"])) self.assertEqual(dependency_tracker.resources["blue"], ["fake-blue-uuid"]) self.assertEqual(dependency_tracker.resources["white"], ["fake-white-uuid"]) self.assertEqual(dependency_tracker.resources["purple"], ["fake-purple-uuid"]) RedSM.delete("fake-red-uuid") GreenSM.delete("fake-green-uuid-0") GreenSM.delete("fake-green-uuid-1") BlueSM.delete("fake-blue-uuid") WhiteSM.delete("fake-white-uuid") PurpleSM.delete("fake-purple-uuid")
def test_basic_dep_track_3(self): reaction_map = { "red": { 'self': ['green', 'blue'], }, "blue": { 'self': ['green'], 'red': [], }, "green": { 'self': ['white'], 'blue': ['white'], 'red': [], }, "white": { 'self': ['purple'], 'green': ['purple'], }, "purple": { 'self': ['blue'], 'white': ['blue'], }, } GreenSM._cassandra.object_read = self.green_read_with_refs WhiteSM._cassandra.object_read = self.white_read_with_refs BlueSM._cassandra.object_read = self.purple_read_with_multi_refs BlueSM._cassandra.object_read = self.blue_read_with_multi_refs dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, reaction_map) red = RedSM.locate("fake-red-uuid") blue = BlueSM.locate("fake-blue-uuid") GreenSM.locate("fake-green-uuid-0") GreenSM.locate("fake-green-uuid-1") white = WhiteSM.locate("fake-white-uuid") purple = PurpleSM.locate("fake-purple-uuid") dependency_tracker.evaluate('blue', blue) self.assertEqual(len(dependency_tracker.resources), 4) self.assertTrue("blue" in dependency_tracker.resources) self.assertTrue("green" in dependency_tracker.resources) self.assertTrue("white" in dependency_tracker.resources) self.assertTrue("purple" in dependency_tracker.resources) self.assertEqual(dependency_tracker.resources["green"], ["fake-green-uuid-1", "fake-green-uuid-0"]) self.assertEqual(dependency_tracker.resources["blue"], ["fake-blue-uuid"]) self.assertEqual(dependency_tracker.resources["purple"], ["fake-purple-uuid"]) self.assertEqual(dependency_tracker.resources["white"], ["fake-white-uuid"]) RedSM.delete("fake-red-uuid") GreenSM.delete("fake-green-uuid-0") GreenSM.delete("fake-green-uuid-1") BlueSM.delete("fake-blue-uuid") WhiteSM.delete("fake-white-uuid") PurpleSM.delete("fake-purple-uuid")
def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBaseDM._OBJ_TYPE_MAP.get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE': obj_dict = oper_info['obj_dict'] obj_id = obj_dict['uuid'] obj = obj_class.locate(obj_id, obj_dict) dependency_tracker = DependencyTracker(DBBaseDM._OBJ_TYPE_MAP, self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'UPDATE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) dependency_tracker = DependencyTracker(DBBaseDM._OBJ_TYPE_MAP, self._REACTION_MAP) if obj is not None: dependency_tracker.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker(DBBaseDM._OBJ_TYPE_MAP, self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.config_log('Unknown operation %s' % oper_info['oper'], level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % ( obj_type, obj_id)) return except Exception: string_buf = cStringIO.StringIO() cgitb.Hook(file=string_buf, format="text").handle(sys.exc_info()) self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR) for pr_id in dependency_tracker.resources.get('physical_router', []): pr = PhysicalRouterDM.get(pr_id) if pr is not None: pr.push_config()
def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: ret = self.obj.update() if ret is not None and not ret: # If update returns None, the function may not support a # return value, hence treat it as if something might have # changed. If a value is returned, use its truth value. # If it True, then some change was detected. # If no change, then terminate dependency tracker return except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids))
def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker(self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: self._set_meta() ret = self.obj.update() if ret is not None and not ret: # If update returns None, the function may not support a # return value, hence treat it as if something might have # changed. If a value is returned, use its truth value. # If it True, then some change was detected. # If no change, then terminate dependency tracker return except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in list(old_dt.resources.items()): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids))
def _vnc_subscribe_callback(self, oper_info): import pdb;pdb.set_trace() self._db_resync_done.wait() try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBase._OBJ_TYPE_MAP.get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE' or oper_info['oper'] == 'UPDATE': dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is not None: dependency_tracker.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.config_log('Unknown operation %s' % oper_info['oper'], level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % ( obj_type, obj_id)) return except Exception: string_buf = cStringIO.StringIO() cgitb.Hook(file=string_buf, format="text").handle(sys.exc_info()) self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR) for lb_pool_id in dependency_tracker.resources.get('loadbalancer_pool', []): lb_pool = LoadbalancerPoolSM.get(lb_pool_id) if lb_pool is not None: lb_pool.add()
class VncAmqpHandle(object): def __init__(self, logger, db_cls, reaction_map, q_name_prefix, args=None): self.logger = logger self.db_cls = db_cls self.reaction_map = reaction_map self.q_name_prefix = q_name_prefix self._db_resync_done = gevent.event.Event() self._args = args def establish(self): q_name = '.'.join([self.q_name_prefix, socket.gethostname()]) self._vnc_kombu = VncKombuClient( self._args.rabbit_server, self._args.rabbit_port, self._args.rabbit_user, self._args.rabbit_password, self._args.rabbit_vhost, self._args.rabbit_ha_mode, q_name, self._vnc_subscribe_callback, self.logger.log, rabbit_use_ssl=self._args.rabbit_use_ssl, kombu_ssl_version=self._args.kombu_ssl_version, kombu_ssl_keyfile=self._args.kombu_ssl_keyfile, kombu_ssl_certfile=self._args.kombu_ssl_certfile, kombu_ssl_ca_certs=self._args.kombu_ssl_ca_certs) def msgbus_store_err_msg(self, msg): self.msg_tracer.error = msg def msgbus_trace_msg(self): self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf', sandesh=self.logger._sandesh) def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() try: self.oper_info = oper_info self.vnc_subscribe_actions() except Exception: string_buf = cStringIO.StringIO() cgitb_hook(file=string_buf, format="text") self.logger.error(string_buf.getvalue()) self.msgbus_store_err_msg(string_buf.getvalue()) try: with open(self._args.trace_file, 'a') as err_file: err_file.write(string_buf.getvalue()) except IOError: pass finally: try: self.msgbus_trace_msg() except Exception: pass del self.oper_info del self.obj_type del self.obj_class del self.obj del self.dependency_tracker def create_msgbus_trace(self, request_id, oper, uuid): self.msg_tracer = MessageBusNotifyTrace(request_id=request_id, operation=oper, uuid=uuid) def vnc_subscribe_actions(self): msg = "Notification Message: %s" % (pformat(self.oper_info)) self.logger.debug(msg) self.obj = None self.dependency_tracker = None self.obj_type = self.oper_info['type'].replace('-', '_') self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type) if self.obj_class is None: return oper = self.oper_info['oper'] obj_id = self.oper_info['uuid'] self.create_msgbus_trace(self.oper_info.get('request_id'), oper, obj_id) if oper == 'CREATE': self.handle_create() elif oper == 'UPDATE': self.handle_update() elif oper == 'DELETE': self.handle_delete() else: self.handle_unknown() return if self.obj is None: self.logger.error('Error while accessing %s uuid %s' % ( self.obj_type, obj_id)) return self.evaluate_dependency() def handle_create(self): obj_dict = self.oper_info['obj_dict'] obj_key = self.db_cls.get_key_from_dict(obj_dict) obj_id = self.oper_info['uuid'] obj_fq_name = obj_dict['fq_name'] self.db_cls._object_db.cache_uuid_to_fq_name_add( obj_id, obj_fq_name, self.obj_type) self.obj = self.obj_class.locate(obj_key) if self.obj is None: self.logger.info('%s id %s fq_name %s not found' % ( self.obj_type, obj_id, obj_fq_name)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: self.obj.update() except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids)) def handle_delete(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id) if self.obj is None: return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) obj_key = self.db_cls.get_key_from_dict(self.oper_info['obj_dict']) self.obj_class.delete(obj_key) def handle_unknown(self): # unknown operation self.logger.error('Unknown operation %s' % self.oper_info['oper']) def init_msgbus_fq_name(self): self.msg_tracer.fq_name = self.obj.name def init_msgbus_dtr(self): self.msg_tracer.dependency_tracker_resources = [] def add_msgbus_dtr(self, res_type, res_id_list): dtr = DependencyTrackerResource(obj_type=res_type, obj_keys=res_id_list) self.msg_tracer.dependency_tracker_resources.append(dtr) def evaluate_dependency(self): if not self.dependency_tracker: return self.init_msgbus_fq_name() self.init_msgbus_dtr() for res_type, res_id_list in self.dependency_tracker.resources.items(): if not res_id_list: continue self.add_msgbus_dtr(res_type, res_id_list) cls = self.db_cls.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: res_obj.evaluate() def close(self): self._vnc_kombu.shutdown()
def _vnc_subscribe_actions(self, oper_info): try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBase._OBJ_TYPE_MAP.get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE' or oper_info['oper'] == 'UPDATE': dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is not None: dependency_tracker.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.config_log('Unknown operation %s' % oper_info['oper'], level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % ( obj_type, obj_id)) return except Exception: cgitb_error_log(self) for sas_id in dependency_tracker.resources.get('service_appliance_set', []): sas_obj = ServiceApplianceSetSM.get(sas_id) if sas_obj is not None: sas_obj.add() for lb_pool_id in dependency_tracker.resources.get('loadbalancer_pool', []): lb_pool = LoadbalancerPoolSM.get(lb_pool_id) if lb_pool is not None: lb_pool.add() for si_id in dependency_tracker.resources.get('service_instance', []): si = ServiceInstanceSM.get(si_id) if si: self._create_service_instance(si) else: for vm_id in dependency_tracker.resources.get( 'virtual_machine', []): vm = VirtualMachineSM.get(vm_id) self._delete_service_instance(vm) for vn_id in dependency_tracker.resources.get('virtual_network', []): vn = VirtualNetworkSM.get(vn_id) if vn: for si_id in ServiceInstanceSM: si = ServiceInstanceSM.get(si_id) if (':').join(vn.fq_name) in si.params.values(): self._create_service_instance(si) for vmi_id in dependency_tracker.resources.get('virtual_machine_interface', []): vmi = VirtualMachineInterfaceSM.get(vmi_id) if vmi: for vm_id in dependency_tracker.resources.get( 'virtual_machine', []): vm = VirtualMachineSM.get(vm_id) if vm: self.check_link_si_to_vm(vm, vmi) else: for irt_id in dependency_tracker.resources.get( 'interface_route_table', []): self._delete_interface_route_table(irt_id) for fip_id in dependency_tracker.resources.get('floating_ip', []): fip = FloatingIpSM.get(fip_id) if fip: for vmi_id in fip.virtual_machine_interfaces: vmi = VirtualMachineInterfaceSM.get(vmi_id) if vmi and vmi.virtual_ip: self.netns_manager.add_fip_to_vip_vmi(vmi, fip)
class VncAmqpHandle(object): def __init__(self, logger, db_cls, reaction_map, q_name_prefix, args=None): self.logger = logger self.db_cls = db_cls self.reaction_map = reaction_map self.q_name_prefix = q_name_prefix self._db_resync_done = gevent.event.Event() self._args = args def establish(self): q_name = '.'.join([self.q_name_prefix, socket.gethostname()]) self._vnc_kombu = VncKombuClient( self._args.rabbit_server, self._args.rabbit_port, self._args.rabbit_user, self._args.rabbit_password, self._args.rabbit_vhost, self._args.rabbit_ha_mode, q_name, self._vnc_subscribe_callback, self.logger.log, rabbit_use_ssl=self._args.rabbit_use_ssl, kombu_ssl_version=self._args.kombu_ssl_version, kombu_ssl_keyfile=self._args.kombu_ssl_keyfile, kombu_ssl_certfile=self._args.kombu_ssl_certfile, kombu_ssl_ca_certs=self._args.kombu_ssl_ca_certs) def msgbus_store_err_msg(self, msg): self.msg_tracer.error = msg def msgbus_trace_msg(self): self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf', sandesh=self.logger._sandesh) def log_exception(self): string_buf = cStringIO.StringIO() cgitb_hook(file=string_buf, format="text") self.logger.error(string_buf.getvalue()) self.msgbus_store_err_msg(string_buf.getvalue()) try: with open(self._args.trace_file, 'a') as err_file: err_file.write(string_buf.getvalue()) except IOError: pass def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() try: self.oper_info = oper_info self.vnc_subscribe_actions() except ConnectionError: try: # retry write during api-server ConnectionError self.vnc_subscribe_actions() except ConnectionError: # log the exception, and exit during api-server # ConnectionError on retry to let standby to become active. self.log_exception() self.logger.error("Api-server connection lost. Exiting") self.close() raise SystemExit except Exception: self.log_exception() except Exception: self.log_exception() finally: try: self.msgbus_trace_msg() except Exception: pass del self.oper_info del self.obj_type del self.obj_class del self.obj del self.dependency_tracker def create_msgbus_trace(self, request_id, oper, uuid): self.msg_tracer = MessageBusNotifyTrace(request_id=request_id, operation=oper, uuid=uuid) def vnc_subscribe_actions(self): msg = "Notification Message: %s" % (pformat(self.oper_info)) self.logger.debug(msg) self.obj = None self.dependency_tracker = None self.obj_type = self.oper_info['type'].replace('-', '_') self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type) if self.obj_class is None: return oper = self.oper_info['oper'] obj_id = self.oper_info['uuid'] self.create_msgbus_trace(self.oper_info.get('request_id'), oper, obj_id) if oper == 'CREATE': self.handle_create() elif oper == 'UPDATE': self.handle_update() elif oper == 'DELETE': self.handle_delete() else: self.handle_unknown() return if self.obj is None: self.logger.warning( "Object %s uuid %s was not found for operation %s" % (self.obj_type, obj_id, oper)) return self.evaluate_dependency() def _get_key_from_oper_info(self): if self.db_cls._indexed_by_name: return ':'.join(self.oper_info['fq_name']) return self.oper_info['uuid'] def handle_create(self): obj_key = self._get_key_from_oper_info() obj_id = self.oper_info['uuid'] obj_fq_name = self.oper_info['fq_name'] self.db_cls._object_db.cache_uuid_to_fq_name_add( obj_id, obj_fq_name, self.obj_type) self.obj = self.obj_class.locate(obj_key) if self.obj is None: self.logger.info('%s id %s fq_name %s not found' % (self.obj_type, obj_id, obj_fq_name)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker(self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: ret = self.obj.update() if ret is not None and not ret: # If update returns None, the function may not support a # return value, hence treat it as if something might have # changed. If a value is returned, use its truth value. # If it True, then some change was detected. # If no change, then terminate dependency tracker return except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids)) def handle_delete(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id) if self.obj is None: return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) obj_key = self._get_key_from_oper_info() self.obj_class.delete(obj_key) def handle_unknown(self): # unknown operation self.logger.error('Unknown operation %s' % self.oper_info['oper']) def init_msgbus_fq_name(self): self.msg_tracer.fq_name = self.obj.name def init_msgbus_dtr(self): self.msg_tracer.dependency_tracker_resources = [] def add_msgbus_dtr(self, res_type, res_id_list): dtr = DependencyTrackerResource(obj_type=res_type, obj_keys=res_id_list) self.msg_tracer.dependency_tracker_resources.append(dtr) def evaluate_dependency(self): if not self.dependency_tracker: return self.init_msgbus_fq_name() self.init_msgbus_dtr() for res_type, res_id_list in self.dependency_tracker.resources.items(): if not res_id_list: continue self.add_msgbus_dtr(res_type, res_id_list) cls = self.db_cls.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: res_obj.evaluate() def close(self): self._vnc_kombu.shutdown()
def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBase._OBJ_TYPE_MAP.get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE': obj_dict = oper_info['obj_dict'] obj_id = obj_dict['uuid'] obj = obj_class.locate(obj_id, obj_dict) dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'UPDATE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) old_dt = None if obj is not None: old_dt = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) old_dt.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in dependency_tracker.resources: dependency_tracker.resources[resource] = ids else: dependency_tracker.resources[resource] = list( set(dependency_tracker.resources[resource]) | set(ids)) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.config_log('Unknown operation %s' % oper_info['oper'], level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % (obj_type, obj_id)) return except Exception: string_buf = cStringIO.StringIO() cgitb.Hook(file=string_buf, format="text").handle(sys.exc_info()) self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR) for pr_id in dependency_tracker.resources.get('physical_router', []): pr = PhysicalRouterDM.get(pr_id) if pr is not None: pr.push_config()
def _vnc_subscribe_actions(self, oper_info): msg = "Notification Message: %s" % (pformat(oper_info)) self.logger.debug(msg) obj_type = oper_info["type"].replace("-", "_") obj_class = DBBaseSM.get_obj_type_map().get(obj_type) if obj_class is None: return if oper_info["oper"] == "CREATE": obj_dict = oper_info["obj_dict"] obj_id = oper_info["uuid"] obj = obj_class.locate(obj_id) if obj is not None: dependency_tracker = DependencyTracker(DBBaseSM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) elif oper_info["oper"] == "UPDATE": obj_id = oper_info["uuid"] obj = obj_class.get(obj_id) old_dt = None if obj is not None: old_dt = DependencyTracker(DBBaseSM.get_obj_type_map(), self._REACTION_MAP) old_dt.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) if obj is not None: try: obj.update() except NoIdError: self.logger.warning("%s uuid %s has vanished" % (obj_type, obj_id)) return dependency_tracker = DependencyTracker(DBBaseSM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in dependency_tracker.resources: dependency_tracker.resources[resource] = ids else: dependency_tracker.resources[resource] = list( set(dependency_tracker.resources[resource]) | set(ids) ) elif oper_info["oper"] == "DELETE": obj_id = oper_info["uuid"] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker(DBBaseSM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.logger.error("Unknown operation %s" % oper_info["oper"]) return if obj is None: self.logger.warning("%s uuid %s has vanished" % (obj_type, obj_id)) return for res_type, res_id_list in dependency_tracker.resources.items(): if not res_id_list: continue cls = DBBaseSM.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: res_obj.evaluate()
class VncAmqpHandle(object): def __init__(self, sandesh, logger, db_cls, reaction_map, q_name_prefix, rabbitmq_cfg, host_ip, trace_file=None, timer_obj=None, register_handler=True): self.sandesh = sandesh self.logger = logger self.db_cls = db_cls self.reaction_map = reaction_map self.q_name_prefix = q_name_prefix self._db_resync_done = gevent.event.Event() self._rabbitmq_cfg = rabbitmq_cfg self._trace_file = trace_file self.timer = timer_obj self.host_ip = host_ip self.register_handler = register_handler self._vnc_kombu = None def establish(self): q_name = '.'.join([self.q_name_prefix, socket.getfqdn(self.host_ip)]) self._vnc_kombu = VncKombuClient( self._rabbitmq_cfg['servers'], self._rabbitmq_cfg['port'], self._rabbitmq_cfg['user'], self._rabbitmq_cfg['password'], self._rabbitmq_cfg['vhost'], self._rabbitmq_cfg['ha_mode'], q_name, self._vnc_subscribe_callback, self.logger.log, rabbit_use_ssl=self._rabbitmq_cfg['use_ssl'], kombu_ssl_version=self._rabbitmq_cfg['ssl_version'], kombu_ssl_keyfile=self._rabbitmq_cfg['ssl_keyfile'], kombu_ssl_certfile=self._rabbitmq_cfg['ssl_certfile'], kombu_ssl_ca_certs=self._rabbitmq_cfg['ssl_ca_certs'], register_handler=self.register_handler) def msgbus_store_err_msg(self, msg): self.msg_tracer.error = msg def msgbus_trace_msg(self): self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf', sandesh=self.sandesh) def log_exception(self): string_buf = StringIO() cgitb_hook(file=string_buf, format="text") self.logger.error(string_buf.getvalue()) self.msgbus_store_err_msg(string_buf.getvalue()) if not self._trace_file: return try: with open(self._trace_file, 'a') as err_file: err_file.write(string_buf.getvalue()) except IOError: pass def log_ignored_errors(self, obj_class): if not self._trace_file: return try: with open(self._trace_file, 'a') as err_file: for err_msg, tb in obj_class._ignored_errors.items(): err_file.write("\nIGNORING: %s\n%s" % (err_msg, tb)) except IOError: pass finally: obj_class.clear_ignored_errors() def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() try: self.oper_info = oper_info self.vnc_subscribe_actions() except ConnectionError: try: # retry write during api-server ConnectionError self.vnc_subscribe_actions() except ConnectionError: # log the exception, and exit during api-server # ConnectionError on retry to let standby to become active. self.log_exception() self.logger.error("Api-server connection lost. Exiting") self.close() raise SystemExit except Exception: self.log_exception() except Exception: self.log_exception() finally: try: self.msgbus_trace_msg() except Exception: pass del self.oper_info del self.obj_type del self.obj_class del self.obj del self.dependency_tracker def create_msgbus_trace(self, request_id, oper, uuid): self.msg_tracer = MessageBusNotifyTrace(request_id=request_id, operation=oper, uuid=uuid) def vnc_subscribe_actions(self): msg = "Notification Message: %s" % (pformat(self.oper_info)) self.logger.debug(msg) self.obj = None self.dependency_tracker = None self.obj_type = self.oper_info['type'].replace('-', '_') self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type) if self.obj_class is None: return oper = self.oper_info['oper'] obj_id = self.oper_info['uuid'] self.create_msgbus_trace(self.oper_info.get('request_id'), oper, obj_id) if oper == 'CREATE': self.handle_create() elif oper == 'UPDATE': self.handle_update() elif oper == 'DELETE': self.handle_delete() elif oper == 'UPDATE-IMPLICIT': # Ignore this operation return else: self.handle_unknown() return if self.obj is None: self.logger.warning( "Object %s uuid %s was not found for operation %s" % (self.obj_type, obj_id, oper)) return self.evaluate_dependency() def _get_key_from_oper_info(self): if self.db_cls._indexed_by_name: return ':'.join(self.oper_info['fq_name']) return self.oper_info['uuid'] def _set_meta(self): self.db_cls.set_meta({ 'request_id': self.oper_info.get('request-id'), 'oper': self.oper_info.get('oper') }) def handle_create(self): obj_key = self._get_key_from_oper_info() obj_id = self.oper_info['uuid'] obj_fq_name = self.oper_info['fq_name'] self.db_cls._object_db.cache_uuid_to_fq_name_add( obj_id, obj_fq_name, self.obj_type) self._set_meta() try: self.obj = self.obj_class.locate(obj_key) finally: self.log_ignored_errors(self.obj_class) if self.obj is None: self.logger.info('%s id %s fq_name %s not found' % (self.obj_type, obj_id, obj_fq_name)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker(self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: self._set_meta() ret = self.obj.update() if ret is not None and not ret: # If update returns None, the function may not support a # return value, hence treat it as if something might have # changed. If a value is returned, use its truth value. # If it True, then some change was detected. # If no change, then terminate dependency tracker return except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in list(old_dt.resources.items()): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids)) def handle_delete(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id) if self.obj is None: return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) obj_key = self._get_key_from_oper_info() self._set_meta() self.obj_class.delete(obj_key) def handle_unknown(self): # unknown operation self.logger.error('Unknown operation %s' % self.oper_info['oper']) def init_msgbus_fq_name(self): self.msg_tracer.fq_name = self.obj.name def init_msgbus_dtr(self): self.msg_tracer.dependency_tracker_resources = [] def add_msgbus_dtr(self, res_type, res_id_list): dtr = DependencyTrackerResource(obj_type=res_type, obj_keys=res_id_list) self.msg_tracer.dependency_tracker_resources.append(dtr) def evaluate_dependency(self): if not self.dependency_tracker: return self.init_msgbus_fq_name() self.init_msgbus_dtr() evaluate_kwargs = {} if self.timer and self.timer.yield_in_evaluate: evaluate_kwargs['timer'] = self.timer for res_type, res_id_list in list( self.dependency_tracker.resources.items()): if not res_id_list: continue self.add_msgbus_dtr(res_type, res_id_list) cls = self.db_cls.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: try: if evaluate_kwargs: res_obj.evaluate(**evaluate_kwargs) else: res_obj.evaluate() finally: self.log_ignored_errors(res_obj) if self.timer: self.timer.timed_yield() def close(self): if self._vnc_kombu is not None: # VncKombuClient is instancied when calling 'establish()', # if for some reasons (mostly related to cleanup after # exception handling) we call `close()` we should consider # a no-op. self._vnc_kombu.shutdown()
def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBase._OBJ_TYPE_MAP.get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE' or oper_info['oper'] == 'UPDATE': dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is not None: dependency_tracker.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker(DBBase._OBJ_TYPE_MAP, self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.config_log('Unknown operation %s' % oper_info['oper'], level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % (obj_type, obj_id)) return except Exception: string_buf = cStringIO.StringIO() cgitb.Hook(file=string_buf, format="text").handle(sys.exc_info()) self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR) for sas_id in dependency_tracker.resources.get('service_appliance_set', []): sas_obj = ServiceApplianceSetSM.get(sas_id) if sas_obj is not None: sas_obj.add() for lb_pool_id in dependency_tracker.resources.get( 'loadbalancer_pool', []): lb_pool = LoadbalancerPoolSM.get(lb_pool_id) if lb_pool is not None: lb_pool.add() for si_id in dependency_tracker.resources.get('service_instance', []): si = ServiceInstanceSM.get(si_id) if si: self._create_service_instance(si) else: for vm_id in dependency_tracker.resources.get( 'virtual_machine', []): vm = VirtualMachineSM.get(vm_id) self._delete_service_instance(vm) for vn_id in dependency_tracker.resources.get('virtual_network', []): vn = VirtualNetworkSM.get(vn_id) if vn: for si_id in ServiceInstanceSM: si = ServiceInstanceSM.get(si_id) if (':').join(vn.fq_name) in si.params.values(): self._create_service_instance(si) for vmi_id in dependency_tracker.resources.get( 'virtual_machine_interface', []): vmi = VirtualMachineInterfaceSM.get(vmi_id) if vmi: for vm_id in dependency_tracker.resources.get( 'virtual_machine', []): vm = VirtualMachineSM.get(vm_id) if vm: self.check_link_si_to_vm(vm, vmi) else: for irt_id in dependency_tracker.resources.get( 'interface_route_table', []): self._delete_interface_route_table(irt_id) for fip_id in dependency_tracker.resources.get('floating_ip', []): fip = FloatingIpSM.get(fip_id) if fip: for vmi_id in fip.virtual_machine_interfaces: vmi = VirtualMachineInterfaceSM.get(vmi_id) if vmi and vmi.virtual_ip: self.netns_manager.add_fip_to_vip_vmi(vmi, fip)
def _vnc_subscribe_actions(self, oper_info): msg = "Notification Message: %s" % (pformat(oper_info)) self.logger.debug(msg) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBaseSM.get_obj_type_map().get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE': obj_dict = oper_info['obj_dict'] obj_id = oper_info['uuid'] obj = obj_class.locate(obj_id) dependency_tracker = DependencyTracker( DBBaseSM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'UPDATE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) old_dt = None if obj is not None: old_dt = DependencyTracker( DBBaseSM.get_obj_type_map(), self._REACTION_MAP) old_dt.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker = DependencyTracker( DBBaseSM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in dependency_tracker.resources: dependency_tracker.resources[resource] = ids else: dependency_tracker.resources[resource] = list( set(dependency_tracker.resources[resource]) | set(ids)) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker( DBBaseSM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.logger.error('Unknown operation %s' % oper_info['oper']) return if obj is None: self.logger.error('Error while accessing %s uuid %s' % ( obj_type, obj_id)) return for res_type, res_id_list in dependency_tracker.resources.items(): if not res_id_list: continue cls = DBBaseSM.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: res_obj.evaluate()
class VncAmqpHandle(object): def __init__(self, logger, db_cls, reaction_map, q_name_prefix, args=None): self.logger = logger self.db_cls = db_cls self.reaction_map = reaction_map self.q_name_prefix = q_name_prefix self._db_resync_done = gevent.event.Event() self._args = args def establish(self): q_name = '.'.join([self.q_name_prefix, socket.gethostname()]) self._vnc_kombu = VncKombuClient( self._args.rabbit_server, self._args.rabbit_port, self._args.rabbit_user, self._args.rabbit_password, self._args.rabbit_vhost, self._args.rabbit_ha_mode, q_name, self._vnc_subscribe_callback, self.logger.log, rabbit_use_ssl=self._args.rabbit_use_ssl, kombu_ssl_version=self._args.kombu_ssl_version, kombu_ssl_keyfile=self._args.kombu_ssl_keyfile, kombu_ssl_certfile=self._args.kombu_ssl_certfile, kombu_ssl_ca_certs=self._args.kombu_ssl_ca_certs) def msgbus_store_err_msg(self, msg): self.msg_tracer.error = msg def msgbus_trace_msg(self): self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf', sandesh=self.logger._sandesh) def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() try: self.oper_info = oper_info self.vnc_subscribe_actions() except Exception: string_buf = cStringIO.StringIO() cgitb_hook(file=string_buf, format="text") self.logger.error(string_buf.getvalue()) self.msgbus_store_err_msg(string_buf.getvalue()) try: with open(self._args.trace_file, 'a') as err_file: err_file.write(string_buf.getvalue()) except IOError: pass finally: try: self.msgbus_trace_msg() except Exception: pass del self.oper_info del self.obj_type del self.obj_class del self.obj del self.dependency_tracker def create_msgbus_trace(self, request_id, oper, uuid): self.msg_tracer = MessageBusNotifyTrace(request_id=request_id, operation=oper, uuid=uuid) def vnc_subscribe_actions(self): msg = "Notification Message: %s" % (pformat(self.oper_info)) self.logger.debug(msg) self.obj = None self.dependency_tracker = None self.obj_type = self.oper_info['type'].replace('-', '_') self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type) if self.obj_class is None: return oper = self.oper_info['oper'] obj_id = self.oper_info['uuid'] self.create_msgbus_trace(self.oper_info.get('request_id'), oper, obj_id) if oper == 'CREATE': self.handle_create() elif oper == 'UPDATE': self.handle_update() elif oper == 'DELETE': self.handle_delete() else: self.handle_unknown() return if self.obj is None: self.logger.error('Error while accessing %s uuid %s' % (self.obj_type, obj_id)) return self.evaluate_dependency() def handle_create(self): obj_dict = self.oper_info['obj_dict'] obj_key = self.db_cls.get_key_from_dict(obj_dict) obj_id = self.oper_info['uuid'] obj_fq_name = obj_dict['fq_name'] self.db_cls._object_db.cache_uuid_to_fq_name_add( obj_id, obj_fq_name, self.obj_type) self.obj = self.obj_class.locate(obj_key) if self.obj is None: self.logger.info('%s id %s fq_name %s not found' % (self.obj_type, obj_id, obj_fq_name)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker(self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: self.obj.update() except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids)) def handle_delete(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id) if self.obj is None: return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) obj_key = self.db_cls.get_key_from_dict(self.oper_info['obj_dict']) self.obj_class.delete(obj_key) def handle_unknown(self): # unknown operation self.logger.error('Unknown operation %s' % self.oper_info['oper']) def init_msgbus_fq_name(self): self.msg_tracer.fq_name = self.obj.name def init_msgbus_dtr(self): self.msg_tracer.dependency_tracker_resources = [] def add_msgbus_dtr(self, res_type, res_id_list): dtr = DependencyTrackerResource(obj_type=res_type, obj_keys=res_id_list) self.msg_tracer.dependency_tracker_resources.append(dtr) def evaluate_dependency(self): if not self.dependency_tracker: return self.init_msgbus_fq_name() self.init_msgbus_dtr() for res_type, res_id_list in self.dependency_tracker.resources.items(): if not res_id_list: continue self.add_msgbus_dtr(res_type, res_id_list) cls = self.db_cls.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: res_obj.evaluate() def close(self): self._vnc_kombu.shutdown()
def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() dependency_tracker = None try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBaseDM.get_obj_type_map().get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE': obj_dict = oper_info['obj_dict'] obj_id = obj_dict['uuid'] self._cassandra.cache_uuid_to_fq_name_add( obj_id, obj_dict['fq_name'], obj_type) obj = obj_class.locate(obj_id, obj_dict) dependency_tracker = DependencyTracker( DBBaseDM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'UPDATE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) old_dt = None if obj is not None: old_dt = DependencyTracker(DBBaseDM.get_obj_type_map(), self._REACTION_MAP) old_dt.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) try: if not obj: raise NoIdError(obj_id) obj.update() except NoIdError: self.config_log('update: object not found <%s, %s>' % (obj_type, obj_id), level=SandeshLevel.SYS_INFO) return dependency_tracker = DependencyTracker( DBBaseDM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in dependency_tracker.resources: dependency_tracker.resources[resource] = ids else: dependency_tracker.resources[resource] = list( set(dependency_tracker.resources[resource]) | set(ids)) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] self._cassandra.cache_uuid_to_fq_name_del(obj_id) obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker( DBBaseDM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.config_log('Unknown operation %s' % oper_info['oper'], level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % (obj_type, obj_id)) return except Exception: string_buf = cStringIO.StringIO() cgitb_hook(file=string_buf, format="text") self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR) if not dependency_tracker: return for vn_id in dependency_tracker.resources.get('virtual_network', []): vn = VirtualNetworkDM.get(vn_id) if vn is not None: vn.update_instance_ip_map() for pr_id in dependency_tracker.resources.get('physical_router', []): pr = PhysicalRouterDM.get(pr_id) if pr is not None: pr.set_config_state()
def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() dependency_tracker = None try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBaseST.get_obj_type_map().get(obj_type) if obj_class is None: return oper = oper_info['oper'] obj_id = oper_info['uuid'] notify_trace = MessageBusNotifyTrace( request_id=oper_info.get('request_id'), operation=oper, uuid=obj_id) if oper == 'CREATE': obj_dict = oper_info['obj_dict'] obj_fq_name = ':'.join(obj_dict['fq_name']) obj = obj_class.locate(obj_fq_name) if obj is None: self.config_log('%s id %s fq_name %s not found' % (obj_type, obj_id, obj_fq_name), level=SandeshLevel.SYS_INFO) return dependency_tracker = DependencyTracker( DBBaseST.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) elif oper == 'UPDATE': obj = obj_class.get_by_uuid(obj_id) old_dt = None if obj is not None: old_dt = DependencyTracker(DBBaseST.get_obj_type_map(), self._REACTION_MAP) old_dt.evaluate(obj_type, obj) else: self.config_log('%s id %s not found' % (obj_type, obj_id), level=SandeshLevel.SYS_INFO) return try: obj.update() except NoIdError: self.config_log('%s id %s update caused NoIdError' % (obj_type, obj_id), level=SandeshLevel.SYS_INFO) return dependency_tracker = DependencyTracker( DBBaseST.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in dependency_tracker.resources: dependency_tracker.resources[resource] = ids else: dependency_tracker.resources[resource] = list( set(dependency_tracker.resources[resource]) | set(ids)) elif oper == 'DELETE': obj = obj_class.get_by_uuid(obj_id) if obj is None: return dependency_tracker = DependencyTracker( DBBaseST.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj.name) else: # unknown operation self.config_log('Unknown operation %s' % oper, level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % (obj_type, obj_id)) return notify_trace.fq_name = obj.name if not dependency_tracker: return notify_trace.dependency_tracker_resources = [] for res_type, res_id_list in dependency_tracker.resources.items(): if not res_id_list: continue dtr = DependencyTrackerResource(obj_type=res_type, obj_keys=res_id_list) notify_trace.dependency_tracker_resources.append(dtr) cls = DBBaseST.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: res_obj.evaluate() for vn_id in dependency_tracker.resources.get( 'virtual_network', []): vn = VirtualNetworkST.get(vn_id) if vn is not None: vn.uve_send() # end for vn_id except Exception as e: string_buf = cStringIO.StringIO() cgitb_hook(file=string_buf, format="text") notify_trace.error = string_buf.getvalue() try: with open(self._args.trace_file, 'a') as err_file: err_file.write(string_buf.getvalue()) except IOError: self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR) finally: try: notify_trace.trace_msg(name='MessageBusNotifyTraceBuf', sandesh=self._sandesh) except Exception: pass
def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() dependency_tracker = None try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBaseST.get_obj_type_map().get(obj_type) if obj_class is None: return oper = oper_info['oper'] obj_id = oper_info['uuid'] notify_trace = MessageBusNotifyTrace( request_id=oper_info.get('request_id'), operation=oper, uuid=obj_id) if oper == 'CREATE': obj_dict = oper_info['obj_dict'] obj_fq_name = ':'.join(obj_dict['fq_name']) obj = obj_class.locate(obj_fq_name) if obj is None: self.config_log('%s id %s fq_name %s not found' % ( obj_type, obj_id, obj_fq_name), level=SandeshLevel.SYS_INFO) return dependency_tracker = DependencyTracker( DBBaseST.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) elif oper == 'UPDATE': obj = obj_class.get_by_uuid(obj_id) old_dt = None if obj is not None: old_dt = DependencyTracker( DBBaseST.get_obj_type_map(), self._REACTION_MAP) old_dt.evaluate(obj_type, obj) else: self.config_log('%s id %s not found' % (obj_type, obj_id), level=SandeshLevel.SYS_INFO) return try: obj.update() except NoIdError: self.config_log('%s id %s update caused NoIdError' % (obj_type, obj_id), level=SandeshLevel.SYS_INFO) return dependency_tracker = DependencyTracker( DBBaseST.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in dependency_tracker.resources: dependency_tracker.resources[resource] = ids else: dependency_tracker.resources[resource] = list( set(dependency_tracker.resources[resource]) | set(ids)) elif oper == 'DELETE': obj = obj_class.get_by_uuid(obj_id) if obj is None: return dependency_tracker = DependencyTracker( DBBaseST.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj.name) else: # unknown operation self.config_log('Unknown operation %s' % oper, level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % ( obj_type, obj_id)) return notify_trace.fq_name = obj.name if not dependency_tracker: return notify_trace.dependency_tracker_resources = [] for res_type, res_id_list in dependency_tracker.resources.items(): if not res_id_list: continue dtr = DependencyTrackerResource(obj_type=res_type, obj_keys=res_id_list) notify_trace.dependency_tracker_resources.append(dtr) cls = DBBaseST.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: res_obj.evaluate() for vn_id in dependency_tracker.resources.get('virtual_network', []): vn = VirtualNetworkST.get(vn_id) if vn is not None: vn.uve_send() # end for vn_id except Exception as e: string_buf = cStringIO.StringIO() cgitb_hook(file=string_buf, format="text") notify_trace.error = string_buf.getvalue() try: with open(self._args.trace_file, 'a') as err_file: err_file.write(string_buf.getvalue()) except IOError: self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR) finally: try: notify_trace.trace_msg(name='MessageBusNotifyTraceBuf', sandesh=self._sandesh) except Exception: pass
def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() dependency_tracker = None try: msg = "Notification Message: %s" % (pformat(oper_info)) self.config_log(msg, level=SandeshLevel.SYS_DEBUG) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBaseDM.get_obj_type_map().get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE': obj_dict = oper_info['obj_dict'] obj_id = obj_dict['uuid'] obj = obj_class.locate(obj_id, obj_dict) dependency_tracker = DependencyTracker( DBBaseDM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'UPDATE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) old_dt = None if obj is not None: old_dt = DependencyTracker( DBBaseDM.get_obj_type_map(), self._REACTION_MAP) old_dt.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker = DependencyTracker( DBBaseDM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in dependency_tracker.resources: dependency_tracker.resources[resource] = ids else: dependency_tracker.resources[resource] = list( set(dependency_tracker.resources[resource]) | set(ids)) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker( DBBaseDM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.config_log('Unknown operation %s' % oper_info['oper'], level=SandeshLevel.SYS_ERR) return if obj is None: self.config_log('Error while accessing %s uuid %s' % ( obj_type, obj_id)) return except Exception: string_buf = cStringIO.StringIO() cgitb.Hook(file=string_buf, format="text").handle(sys.exc_info()) self.config_log(string_buf.getvalue(), level=SandeshLevel.SYS_ERR) if not dependency_tracker: return for vn_id in dependency_tracker.resources.get('virtual_network', []): vn = VirtualNetworkDM.get(vn_id) if vn is not None: vn.update_instance_ip_map() for pr_id in dependency_tracker.resources.get('physical_router', []): pr = PhysicalRouterDM.get(pr_id) if pr is not None: pr.set_config_state()
def _vnc_subscribe_actions(self, oper_info): try: msg = "Notification Message: %s" % (pformat(oper_info)) self.logger.log_debug(msg) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBaseSM.get_obj_type_map().get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE' or oper_info['oper'] == 'UPDATE': dependency_tracker = DependencyTracker( DBBaseSM.get_obj_type_map(), self._REACTION_MAP) obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is not None: dependency_tracker.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker( DBBaseSM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.logger.log_error('Unknown operation %s' % oper_info['oper']) return if obj is None: self.logger.log_error('Error while accessing %s uuid %s' % (obj_type, obj_id)) return except Exception: cgitb_error_log(self) for sas_id in dependency_tracker.resources.get('service_appliance_set', []): sas_obj = ServiceApplianceSetSM.get(sas_id) if sas_obj is not None: sas_obj.add() for lb_pool_id in dependency_tracker.resources.get( 'loadbalancer_pool', []): lb_pool = LoadbalancerPoolSM.get(lb_pool_id) if lb_pool is not None: lb_pool.add() for si_id in dependency_tracker.resources.get('service_instance', []): si = ServiceInstanceSM.get(si_id) if si: si.state = 'launch' self._create_service_instance(si) else: self.logger.log_info("Deleting SI %s" % si_id) for vm_id in dependency_tracker.resources.get( 'virtual_machine', []): vm = VirtualMachineSM.get(vm_id) self._delete_service_instance(vm) self.logger.log_info("SI %s deletion succeed" % si_id) for vn_id in dependency_tracker.resources.get('virtual_network', []): vn = VirtualNetworkSM.get(vn_id) if vn: for si_id in ServiceInstanceSM: si = ServiceInstanceSM.get(si_id) intf_list = [] if si.params: intf_list = si.params.get('interface_list', []) for intf in intf_list: if (':').join(vn.fq_name) in intf.values(): self._create_service_instance(si) for vmi_id in dependency_tracker.resources.get( 'virtual_machine_interface', []): vmi = VirtualMachineInterfaceSM.get(vmi_id) if vmi: for vm_id in dependency_tracker.resources.get( 'virtual_machine', []): vm = VirtualMachineSM.get(vm_id) if vm: self.check_link_si_to_vm(vm, vmi) else: for irt_id in dependency_tracker.resources.get( 'interface_route_table', []): self._delete_interface_route_table(irt_id) for fip_id in dependency_tracker.resources.get('floating_ip', []): fip = FloatingIpSM.get(fip_id) if fip: for vmi_id in fip.virtual_machine_interfaces: vmi = VirtualMachineInterfaceSM.get(vmi_id) if vmi and vmi.virtual_ip: self.netns_manager.add_fip_to_vip_vmi(vmi, fip) for lr_id in dependency_tracker.resources.get('logical_router', []): lr = LogicalRouterSM.get(lr_id) if lr: self.snat_agent.update_snat_instance(lr)
def _vnc_subscribe_actions(self, oper_info): try: msg = "Notification Message: %s" % (pformat(oper_info)) self.logger.log_debug(msg) obj_type = oper_info['type'].replace('-', '_') obj_class = DBBaseSM.get_obj_type_map().get(obj_type) if obj_class is None: return if oper_info['oper'] == 'CREATE' or oper_info['oper'] == 'UPDATE': dependency_tracker = DependencyTracker( DBBaseSM.get_obj_type_map(), self._REACTION_MAP) obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is not None: dependency_tracker.evaluate(obj_type, obj) else: obj = obj_class.locate(obj_id) obj.update() dependency_tracker.evaluate(obj_type, obj) elif oper_info['oper'] == 'DELETE': obj_id = oper_info['uuid'] obj = obj_class.get(obj_id) if obj is None: return dependency_tracker = DependencyTracker( DBBaseSM.get_obj_type_map(), self._REACTION_MAP) dependency_tracker.evaluate(obj_type, obj) obj_class.delete(obj_id) else: # unknown operation self.logger.log_error('Unknown operation %s' % oper_info['oper']) return if obj is None: self.logger.log_error('Error while accessing %s uuid %s' % ( obj_type, obj_id)) return except Exception: cgitb_error_log(self) for sas_id in dependency_tracker.resources.get( 'service_appliance_set', []): sas_obj = ServiceApplianceSetSM.get(sas_id) if sas_obj is not None: sas_obj.add() for lb_pool_id in dependency_tracker.resources.get( 'loadbalancer_pool', []): lb_pool = LoadbalancerPoolSM.get(lb_pool_id) if lb_pool is not None: lb_pool.add() for si_id in dependency_tracker.resources.get('service_instance', []): si = ServiceInstanceSM.get(si_id) if si: si.state = 'launch' self._create_service_instance(si) else: self.logger.log_info("Deleting SI %s" % si_id) for vm_id in dependency_tracker.resources.get( 'virtual_machine', []): vm = VirtualMachineSM.get(vm_id) self._delete_service_instance(vm) self.logger.log_info("SI %s deletion succeed" % si_id) for vn_id in dependency_tracker.resources.get('virtual_network', []): vn = VirtualNetworkSM.get(vn_id) if vn: for si_id in ServiceInstanceSM: si = ServiceInstanceSM.get(si_id) intf_list = [] if si.params: intf_list = si.params.get('interface_list', []) for intf in intf_list: if (':').join(vn.fq_name) in intf.values(): self._create_service_instance(si) for vmi_id in dependency_tracker.resources.get( 'virtual_machine_interface', []): vmi = VirtualMachineInterfaceSM.get(vmi_id) if vmi: for vm_id in dependency_tracker.resources.get( 'virtual_machine', []): vm = VirtualMachineSM.get(vm_id) self.port_delete_or_si_link(vm, vmi) else: for irt_id in dependency_tracker.resources.get( 'interface_route_table', []): self._delete_interface_route_table(irt_id) for fip_id in dependency_tracker.resources.get('floating_ip', []): fip = FloatingIpSM.get(fip_id) if fip: for vmi_id in fip.virtual_machine_interfaces: vmi = VirtualMachineInterfaceSM.get(vmi_id) if vmi and vmi.virtual_ip: self.netns_manager.add_fip_to_vip_vmi(vmi, fip) for lr_id in dependency_tracker.resources.get('logical_router', []): lr = LogicalRouterSM.get(lr_id) if lr: self.snat_agent.update_snat_instance(lr)
class VncAmqpHandle(object): def __init__(self, sandesh, logger, db_cls, reaction_map, q_name_prefix, rabbitmq_cfg, trace_file=None): self.sandesh = sandesh self.logger = logger self.db_cls = db_cls self.reaction_map = reaction_map self.q_name_prefix = q_name_prefix self._db_resync_done = gevent.event.Event() self._rabbitmq_cfg = rabbitmq_cfg self._trace_file = trace_file def establish(self): q_name = '.'.join([self.q_name_prefix, socket.gethostname()]) self._vnc_kombu = VncKombuClient( self._rabbitmq_cfg['servers'], self._rabbitmq_cfg['port'], self._rabbitmq_cfg['user'], self._rabbitmq_cfg['password'], self._rabbitmq_cfg['vhost'], self._rabbitmq_cfg['ha_mode'], q_name, self._vnc_subscribe_callback, self.logger.log, rabbit_use_ssl=self._rabbitmq_cfg['use_ssl'], kombu_ssl_version=self._rabbitmq_cfg['ssl_version'], kombu_ssl_keyfile=self._rabbitmq_cfg['ssl_keyfile'], kombu_ssl_certfile=self._rabbitmq_cfg['ssl_certfile'], kombu_ssl_ca_certs=self._rabbitmq_cfg['ssl_ca_certs']) def msgbus_store_err_msg(self, msg): self.msg_tracer.error = msg def msgbus_trace_msg(self): self.msg_tracer.trace_msg(name='MessageBusNotifyTraceBuf', sandesh=self.sandesh) def log_exception(self): string_buf = cStringIO.StringIO() cgitb_hook(file=string_buf, format="text") self.logger.error(string_buf.getvalue()) self.msgbus_store_err_msg(string_buf.getvalue()) if not self._trace_file: return try: with open(self._trace_file, 'a') as err_file: err_file.write(string_buf.getvalue()) except IOError: pass def _vnc_subscribe_callback(self, oper_info): self._db_resync_done.wait() try: self.oper_info = oper_info self.vnc_subscribe_actions() except ConnectionError: try: # retry write during api-server ConnectionError self.vnc_subscribe_actions() except ConnectionError: # log the exception, and exit during api-server # ConnectionError on retry to let standby to become active. self.log_exception() self.logger.error("Api-server connection lost. Exiting") self.close() raise SystemExit except Exception: self.log_exception() except Exception: self.log_exception() finally: try: self.msgbus_trace_msg() except Exception: pass del self.oper_info del self.obj_type del self.obj_class del self.obj del self.dependency_tracker def create_msgbus_trace(self, request_id, oper, uuid): self.msg_tracer = MessageBusNotifyTrace(request_id=request_id, operation=oper, uuid=uuid) def vnc_subscribe_actions(self): msg = "Notification Message: %s" % (pformat(self.oper_info)) self.logger.debug(msg) self.obj = None self.dependency_tracker = None self.obj_type = self.oper_info['type'].replace('-', '_') self.obj_class = self.db_cls.get_obj_type_map().get(self.obj_type) if self.obj_class is None: return oper = self.oper_info['oper'] obj_id = self.oper_info['uuid'] self.create_msgbus_trace(self.oper_info.get('request_id'), oper, obj_id) if oper == 'CREATE': self.handle_create() elif oper == 'UPDATE': self.handle_update() elif oper == 'DELETE': self.handle_delete() elif oper == 'UPDATE-IMPLICIT': # Ignore this operation return else: self.handle_unknown() return if self.obj is None: self.logger.warning( "Object %s uuid %s was not found for operation %s" % (self. obj_type, obj_id, oper)) return self.evaluate_dependency() def _get_key_from_oper_info(self): if self.db_cls._indexed_by_name: return ':'.join(self.oper_info['fq_name']) return self.oper_info['uuid'] def handle_create(self): obj_key = self._get_key_from_oper_info() obj_id = self.oper_info['uuid'] obj_fq_name = self.oper_info['fq_name'] self.db_cls._object_db.cache_uuid_to_fq_name_add( obj_id, obj_fq_name, self.obj_type) self.obj = self.obj_class.locate(obj_key) if self.obj is None: self.logger.info('%s id %s fq_name %s not found' % ( self.obj_type, obj_id, obj_fq_name)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) def handle_update(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) old_dt = None if self.obj is not None: old_dt = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) old_dt.evaluate(self.obj_type, self.obj) else: self.logger.info('%s id %s not found' % (self.obj_type, obj_id)) return try: ret = self.obj.update() if ret is not None and not ret: # If update returns None, the function may not support a # return value, hence treat it as if something might have # changed. If a value is returned, use its truth value. # If it True, then some change was detected. # If no change, then terminate dependency tracker return except NoIdError: obj_id = self.oper_info['uuid'] self.logger.warning('%s uuid %s update caused NoIdError' % (self.obj_type, obj_id)) return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) if old_dt: for resource, ids in old_dt.resources.items(): if resource not in self.dependency_tracker.resources: self.dependency_tracker.resources[resource] = ids else: self.dependency_tracker.resources[resource] = list( set(self.dependency_tracker.resources[resource]) | set(ids)) def handle_delete(self): obj_id = self.oper_info['uuid'] self.obj = self.obj_class.get_by_uuid(obj_id) self.db_cls._object_db.cache_uuid_to_fq_name_del(obj_id) if self.obj is None: return self.dependency_tracker = DependencyTracker( self.db_cls.get_obj_type_map(), self.reaction_map) self.dependency_tracker.evaluate(self.obj_type, self.obj) obj_key = self._get_key_from_oper_info() self.obj_class.delete(obj_key) def handle_unknown(self): # unknown operation self.logger.error('Unknown operation %s' % self.oper_info['oper']) def init_msgbus_fq_name(self): self.msg_tracer.fq_name = self.obj.name def init_msgbus_dtr(self): self.msg_tracer.dependency_tracker_resources = [] def add_msgbus_dtr(self, res_type, res_id_list): dtr = DependencyTrackerResource(obj_type=res_type, obj_keys=res_id_list) self.msg_tracer.dependency_tracker_resources.append(dtr) def evaluate_dependency(self): if not self.dependency_tracker: return self.init_msgbus_fq_name() self.init_msgbus_dtr() for res_type, res_id_list in self.dependency_tracker.resources.items(): if not res_id_list: continue self.add_msgbus_dtr(res_type, res_id_list) cls = self.db_cls.get_obj_type_map().get(res_type) if cls is None: continue for res_id in res_id_list: res_obj = cls.get(res_id) if res_obj is not None: res_obj.evaluate() def close(self): self._vnc_kombu.shutdown()