def aim_res_to_nodes(aim_res):
     result = {}
     aim_res_dn = AimHashTreeMaker._extract_dn(aim_res)
     is_error = getattr(aim_res, '_error', False)
     is_monitored = (getattr(aim_res, 'monitored', False)
                     or getattr(aim_res, 'pre_existing', False))
     pending = getattr(aim_res, '_pending', None)
     to_aci = converter.AimToAciModelConverter()
     for obj in to_aci.convert([aim_res]):
         for mo, v in obj.items():
             attr = v.get('attributes', {})
             dn = attr.pop('dn', None)
             key = AimHashTreeMaker._build_hash_tree_key_from_dn(dn, mo)
             if key:
                 attr['_metadata'] = {
                     'monitored': is_monitored,
                     'attributes': copy.copy(attr)
                 }
                 if dn != aim_res_dn:
                     attr['_metadata']['related'] = True
                 if pending is not None:
                     attr['_metadata']['pending'] = pending
                 attr['_error'] = is_error
                 result[key] = attr
     return result
    def _objects_transaction_create(self,
                                    objs,
                                    create=True,
                                    tag=None,
                                    top_send=True):
        tag = tag or self.sys_id
        result = []
        for obj in objs:
            conversion = converter.AimToAciModelConverter().convert([obj])
            transaction = apic_client.Transaction(mock.Mock(),
                                                  top_send=top_send)
            tags = []
            if create:
                for item in conversion:
                    dn = item.values()[0]['attributes']['dn']
                    dn += '/tag-%s' % tag
                    tags.append({
                        "tagInst__%s" % item.keys()[0]: {
                            "attributes": {
                                "dn": dn
                            }
                        }
                    })

            for item in conversion + tags:
                getattr(transaction,
                        item.keys()[0]).add(
                            *self._extract_rns(
                                item.values()[0]['attributes'].pop('dn'),
                                item.keys()[0]),
                            **item.values()[0]['attributes'])
            result.append(transaction)
        return result
    def _prepare_aim_resource(self, tree, aim_res):
        result = {}
        is_error = getattr(aim_res, '_error', False)
        is_monitored = (getattr(aim_res, 'monitored', False)
                        or getattr(aim_res, 'pre_existing', False))
        pending = getattr(aim_res, '_pending', None)
        to_aci = converter.AimToAciModelConverter()
        aim_res_dn = AimHashTreeMaker._extract_dn(aim_res)
        if not aim_res_dn:
            return result

        # Remove "related" child-nodes
        aim_res_key = AimHashTreeMaker._build_hash_tree_key(aim_res)
        node = tree.find(aim_res_key) if aim_res_key else None
        self._clean_related(tree, node)

        for obj in to_aci.convert([aim_res]):
            for mo, v in obj.iteritems():
                attr = v.get('attributes', {})
                dn = attr.pop('dn', None)
                key = AimHashTreeMaker._build_hash_tree_key_from_dn(dn, mo)
                if key:
                    attr['_metadata'] = {
                        'monitored': is_monitored,
                        'attributes': copy.copy(attr)
                    }
                    if dn != aim_res_dn:
                        attr['_metadata']['related'] = True
                    if pending is not None:
                        attr['_metadata']['pending'] = pending
                    attr['_error'] = is_error
                    result[key] = attr
        return result
 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 test_squash_operations_no_key(self):
     aim_converter = converter.AimToAciModelConverter()
     tn = a_res.Tenant(name='tn1', display_name='foo')
     bd = a_res.BridgeDomain(tenant_name='tn1',
                             name='bd1',
                             display_name='bar')
     vrf = a_res.VRF(tenant_name='tn1', name='vrf1', display_name='pippo')
     self.manager.push_aim_resources({'create': [tn, bd]})
     self.manager.push_aim_resources(
         {'delete': aim_converter.convert([vrf])})
     self.assertEqual(2, len(self.manager.object_backlog.queue))
Example #6
0
    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(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 test_squash_operations(self):
     # Craft some objects and push them
     aim_converter = converter.AimToAciModelConverter()
     tn = a_res.Tenant(name='tn1', display_name='foo')
     bd = a_res.BridgeDomain(tenant_name='tn1',
                             name='bd1',
                             display_name='bar')
     vrf = a_res.VRF(tenant_name='tn1', name='vrf1', display_name='pippo')
     self.manager.push_aim_resources({
         'create': [tn, bd],
         'delete': aim_converter.convert([vrf])
     })
     self.assertEqual(1, len(self.manager.object_backlog.queue))
     old = self.manager.object_backlog.queue[0]
     # Idempotent
     self.manager.push_aim_resources({
         'create': [tn, bd],
         'delete': aim_converter.convert([vrf])
     })
     self.assertEqual(1, len(self.manager.object_backlog.queue))
     curr = self.manager.object_backlog.queue[0]
     self.assertEqual(old, curr)
     # Now replace something
     bd2 = a_res.BridgeDomain(tenant_name='tn1',
                              name='bd2',
                              display_name='bar')
     bd = copy.deepcopy(bd)
     bd.display_name = 'foobar'
     self.manager.push_aim_resources({'create': [bd2, bd], 'delete': []})
     self.assertEqual(2, len(self.manager.object_backlog.queue))
     self.assertEqual({
         'create': [bd2],
         'delete': []
     }, self.manager.object_backlog.queue[1])
     self.assertEqual(
         'foobar',
         self.manager.object_backlog.queue[0]['create'][1].display_name)
     # Add something completely different
     vrf2 = a_res.VRF(tenant_name='tn1', name='vrf2', display_name='pippo')
     self.manager.push_aim_resources({
         'create': [vrf2],
         'delete': aim_converter.convert([bd])
     })
     self.assertEqual(
         {
             'create': [vrf2],
             'delete': aim_converter.convert([bd])
         }, self.manager.object_backlog.queue[2])
    def clear(self, tree, resources):
        """Set AIM resources to dummy in tree

        :param tree:
        :param items:
        :return:
        """
        to_aci = converter.AimToAciModelConverter()
        for obj in to_aci.convert(resources):
            for mo, v in obj.items():
                attr = v.get('attributes', {})
                dn = attr.pop('dn', None)
                key = AimHashTreeMaker._build_hash_tree_key_from_dn(dn, mo)
                if key:
                    tree.clear(key)
        return tree
Example #10
0
    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)