def _remove_data_from_tree(self, data, state): aim_res = converter.AciToAimModelConverter().convert(data) by_root = {} for res in aim_res: by_root.setdefault(res.root, []).append(res) for root, updates in by_root.iteritems(): tree_manager.AimHashTreeMaker().delete( state.setdefault(root, structured_tree.StructuredHashTree()), updates)
def initialize(self, store, conf_mgr, multiverse): super(AimDbUniverse, self).initialize(store, conf_mgr, multiverse) self.tree_manager = tree_manager.HashTreeManager() self.context = context.AimContext(store=store) self._converter = converter.AciToAimModelConverter() self._converter_aim_to_aci = converter.AimToAciModelConverter() self._served_tenants = set() self._monitored_state_update_failures = 0 self._max_monitored_state_update_failures = 5 return self
def __init__(self, tenant_name, apic_config, apic_session, ws_context, creation_succeeded=None, creation_failed=None, aim_system_id=None, get_resources=None, *args, **kwargs): super(AciTenantManager, self).__init__(*args, **kwargs) LOG.info("Init manager for tenant %s" % tenant_name) self.get_resources = get_resources self.apic_config = apic_config # Each tenant has its own sessions self.aci_session = apic_session self.dn_manager = apic_client.DNManager() self.tenant_name = tenant_name children_mos = get_children_mos(self.aci_session, self.tenant_name) ws_subscription_to = self.apic_config.get_option( 'websocket_subscription_timeout', 'aim') or DEFAULT_WS_TO self.tenant = Root(self.tenant_name, filtered_children=children_mos, rn=self.tenant_name, ws_subscription_to=ws_subscription_to) self._state = structured_tree.StructuredHashTree() self._operational_state = structured_tree.StructuredHashTree() self._monitored_state = structured_tree.StructuredHashTree() self.polling_yield = self.apic_config.get_option( 'aci_tenant_polling_yield', 'aim') self.to_aim_converter = converter.AciToAimModelConverter() self.to_aci_converter = converter.AimToAciModelConverter() self._reset_object_backlog() self.tree_builder = tree_manager.HashTreeBuilder(None) self.tag_name = aim_system_id or self.apic_config.get_option( 'aim_system_id', 'aim') self.tag_set = set() self.failure_log = {} def noop(*args, **kwargs): pass self.creation_succeeded = creation_succeeded or noop self.creation_failed = creation_failed or noop # Warm bit to avoid rushed synchronization before receiving the first # batch of APIC events self._warm = False self.ws_context = ws_context self.recovery_retries = None self.max_retries = 5 self.error_handler = error.APICAPIErrorHandler() # For testing purposes self.num_loop_runs = float('inf')
def initialize(self, conf_mgr, multiverse): super(AciUniverse, self).initialize(conf_mgr, multiverse) self._aim_converter = converter.AciToAimModelConverter() self.aci_session = self.establish_aci_session(self.conf_manager) # Initialize children MOS here so that it globally fails if there's # any bug or network partition. aci_tenant.get_children_mos(self.aci_session, 'tn-common') aci_tenant.get_children_mos(self.aci_session, 'pod-1') self.ws_context = get_websocket_context(self.conf_manager) self.aim_system_id = self.conf_manager.get_option( 'aim_system_id', 'aim') return self
def initialize(self, conf_mgr, multiverse): super(AimDbUniverse, self).initialize(conf_mgr, multiverse) self.tree_manager = tree_manager.HashTreeManager() self._converter = converter.AciToAimModelConverter() self._converter_aim_to_aci = converter.AimToAciModelConverter() self._served_tenants = set() self._monitored_state_update_failures = 0 self._max_monitored_state_update_failures = 5 self._recovery_interval = conf_mgr.get_option( 'error_state_recovery_interval', 'aim') self.schedule_next_recovery() return self
def get_resources(self, resource_keys, desired_state=None): if resource_keys: LOG.debug("Requesting resource keys in %s: %s", self.name, resource_keys) # NOTE(ivar): state is a copy at the current iteration that was created # through the observe() method. desired_state = desired_state or self.get_relevant_state_for_read() result = [] id_set = set() monitored_set = set() for key in resource_keys: if key not in id_set: attr = self._fill_node(key, desired_state) if not attr: continue monitored = attr.pop('monitored', None) related = attr.pop('related', False) attr = attr.get('attributes', {}) aci_object = self._keys_to_bare_aci_objects([key])[0] aci_object.values()[0]['attributes'].update(attr) dn = aci_object.values()[0]['attributes']['dn'] # Capture related objects if desired_state: self._fill_related_nodes(resource_keys, key, desired_state) if related: self._fill_parent_node(resource_keys, key, desired_state) result.append(aci_object) if monitored: if related: try: monitored_set.add( converter.AciToAimModelConverter().convert( [aci_object])[0].dn) except IndexError: pass else: monitored_set.add(dn) id_set.add(key) if resource_keys: result = self._convert_get_resources_result(result, monitored_set) LOG.debug("Result for keys %s\n in %s:\n %s" % (resource_keys, self.name, result)) return result
def test_get_aim_resources(self, tree_type=tree_manager.CONFIG_TREE): tree_mgr = tree_manager.HashTreeManager() aim_mgr = aim_manager.AimManager() t1 = resource.Tenant(name='t1') t2 = resource.Tenant(name='t2') t1_fault = aim_status.AciFault( fault_code='101', external_identifier='uni/tn-t1/fault-101', description='failure101') t2_fault = aim_status.AciFault( fault_code='102', external_identifier='uni/tn-t2/fault-102', description='failure102') # Create Resources on a couple of tenants bd1 = resource.BridgeDomain( tenant_name='t1', name='bd1', display_name='somestuff', vrf_name='vrf') bd1_fault = aim_status.AciFault( fault_code='901', external_identifier='uni/tn-t1/BD-bd1/fault-901', description='failure901') bd1_fault2 = aim_status.AciFault( fault_code='902', external_identifier='uni/tn-t1/BD-bd1/fault-902', description='failure902') bd2 = resource.BridgeDomain( tenant_name='t2', name='bd1', display_name='somestuff', vrf_name='vrf2') dc1 = aim_service_graph.DeviceCluster( tenant_name='t1', name='clus1', devices=[{'name': '1'}]) dc1_fault = aim_status.AciFault( fault_code='901', external_identifier='uni/tn-t1/lDevVip-clus1/fault-901', description='failure901') sg1 = aim_service_graph.ServiceGraph( tenant_name='t1', name='gr1', linear_chain_nodes=[{'name': 'N1', 'device_cluster_name': 'cl1'}]) sg1_fault = aim_status.AciFault( fault_code='901', external_identifier='uni/tn-t1/AbsGraph-gr1/fault-901', description='failure901') srp1 = aim_service_graph.ServiceRedirectPolicy( tenant_name='t1', name='srp1', destinations=[{'ip': '1.1.1.1', 'mac': 'aa:bb:cc:dd:ee:ff'}]) srp1_fault = aim_status.AciFault( fault_code='901', external_identifier=('uni/tn-t1/svcCont/svcRedirectPol-srp1' '/fault-901'), description='failure901') dc_ctx1 = aim_service_graph.DeviceClusterContext( tenant_name='t1', contract_name='contract1', service_graph_name='graph1', node_name='N1', device_cluster_name='cluster1', device_cluster_tenant_name='common', bridge_domain_name='svc_bd', service_redirect_policy_name='srp1') dc_ctx1_fault = aim_status.AciFault( fault_code='901', external_identifier=('uni/tn-t1/ldevCtx-c-contract1-' 'g-graph1-n-N1/fault-901'), description='failure901') if tree_type == tree_manager.MONITORED_TREE: bd1.monitored = True bd2.monitored = True t1.monitored = True t2.monitored = True dc1.monitored = True sg1.monitored = True srp1.monitored = True dc_ctx1.monitored = True aim_mgr.create(self.ctx, t1) aim_mgr.create(self.ctx, t2) aim_mgr.create(self.ctx, bd1) aim_mgr.set_fault(self.ctx, t1, t1_fault) aim_mgr.set_fault(self.ctx, t2, t2_fault) aim_mgr.set_fault(self.ctx, bd1, bd1_fault) aim_mgr.set_fault(self.ctx, bd1, bd1_fault2) aim_mgr.create(self.ctx, bd2) aim_mgr.set_resource_sync_synced(self.ctx, t1) aim_mgr.set_resource_sync_synced(self.ctx, t2) aim_mgr.set_resource_sync_synced(self.ctx, bd2) aim_mgr.set_resource_sync_synced(self.ctx, bd1) aim_mgr.create(self.ctx, dc1) aim_mgr.create(self.ctx, sg1) aim_mgr.create(self.ctx, srp1) aim_mgr.create(self.ctx, dc_ctx1) aim_mgr.set_fault(self.ctx, dc1, dc1_fault) aim_mgr.set_fault(self.ctx, sg1, sg1_fault) aim_mgr.set_fault(self.ctx, srp1, srp1_fault) aim_mgr.set_fault(self.ctx, dc_ctx1, dc_ctx1_fault) aim_mgr.set_resource_sync_synced(self.ctx, dc1) aim_mgr.set_resource_sync_synced(self.ctx, sg1) aim_mgr.set_resource_sync_synced(self.ctx, srp1) aim_mgr.set_resource_sync_synced(self.ctx, dc_ctx1) # Two trees exist trees = tree_mgr.find(self.ctx, tree=tree_type) self.assertEqual(2, len(trees)) # Calculate the different with empty trees to retrieve missing keys diff_tn_1 = trees[0].diff(tree.StructuredHashTree()) diff_tn_2 = trees[1].diff(tree.StructuredHashTree()) self.universe.get_relevant_state_for_read = mock.Mock( return_value=[{'tn-t1': trees[0], 'tn-t2': trees[1]}]) result = self.universe.get_resources(diff_tn_1.get('add', []) + diff_tn_1.get('remove', []) + diff_tn_2.get('add', []) + diff_tn_2.get('remove', [])) converted = converter.AciToAimModelConverter().convert( converter.AimToAciModelConverter().convert( [bd1, bd2, dc1, sg1, srp1, dc_ctx1, t1, t2])) if tree_type == tree_manager.MONITORED_TREE: for x in converted: x.monitored = True if tree_type in [tree_manager.CONFIG_TREE, tree_manager.MONITORED_TREE]: self.assertEqual(len(converted), len(result)) for item in converted: self.assertTrue(item in result) elif tree_type == tree_manager.OPERATIONAL_TREE: self.assertEqual(8, len(result)) self.assertTrue(bd1_fault in result) self.assertTrue(bd1_fault2 in result) self.assertTrue(dc1_fault in result) self.assertTrue(sg1_fault in result) self.assertTrue(srp1_fault in result) self.assertTrue(dc_ctx1_fault in result)
def _convert_get_resources_result(self, result, monitored_set): result = converter.AciToAimModelConverter().convert(result) for item in result: if item.dn in monitored_set: item.monitored = True return result