Beispiel #1
0
 def setUp(self, klass=aim_universe.AimDbUniverse):
     super(TestAimDbUniverseBase, self).setUp()
     self.klass = klass
     self.universe = self.klass().initialize(
         aim_cfg.ConfigManager(self.ctx, ''), [])
     self.tree_mgr = tree_manager.HashTreeManager()
     self.monitor_universe = False
Beispiel #2
0
def hashtree(ctx):
    aim_ctx = context.AimContext(store=api.get_store(expire_on_commit=True))
    tree_mgr = tree_manager.HashTreeManager()
    manager = aim_manager.AimManager()
    ctx.obj['manager'] = manager
    ctx.obj['tree_mgr'] = tree_mgr
    ctx.obj['aim_ctx'] = aim_ctx
Beispiel #3
0
    def test_cleanup_state(self, tree_type=tree_manager.CONFIG_TREE):
        tree_mgr = tree_manager.HashTreeManager()
        aim_mgr = aim_manager.AimManager()
        aim_mgr.create(self.ctx, resource.Tenant(name='t1'))
        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')

        aim_mgr.create(self.ctx, bd1)
        aim_mgr.set_fault(self.ctx, bd1, bd1_fault)
        self.assertRaises(Exception, self.universe.cleanup_state, 'tn-t1')

        trees = tree_mgr.find(self.ctx, tree=tree_type)
        # tenant still there, trees not empty.
        self.assertEqual(1, len(trees))
        aim_mgr.clear_fault(self.ctx, bd1_fault)
        aim_mgr.delete(self.ctx, resource.Tenant(name='t1'), cascade=True)
        self.universe.cleanup_state(self.ctx, 'tn-t1')
        trees = tree_mgr.find(self.ctx, tree=tree_type)
        self.assertEqual(0, len(trees))
Beispiel #4
0
    def __init__(self, conf):
        self.run_daemon_loop = True
        self.host = conf.aim.aim_service_identifier

        aim_ctx = context.AimContext(store=api.get_store())
        # This config manager is shared between multiple threads. Therefore
        # all DB activity through this config manager will use the same
        # DB session which can result in conflicts.
        # TODO(amitbose) Fix ConfigManager to not use cached AimContext
        self.conf_manager = aim_cfg.ConfigManager(aim_ctx, self.host)
        self.k8s_watcher = None
        self.single_aid = False
        if conf.aim.aim_store == 'k8s':
            self.single_aid = True
            self.k8s_watcher = k8s_watcher.K8sWatcher()
            self.k8s_watcher.run()

        self.multiverse = []
        # Define multiverse pairs, First position is desired state
        self.multiverse += [
            # Configuration Universe (AIM to ACI)
            {DESIRED: aim_universe.AimDbUniverse().initialize(
                self.conf_manager, self.multiverse),
             CURRENT: aci_universe.AciUniverse().initialize(
                 self.conf_manager, self.multiverse)},
            # Operational Universe (ACI to AIM)
            {DESIRED: aci_universe.AciOperationalUniverse().initialize(
                self.conf_manager, self.multiverse),
             CURRENT: aim_universe.AimDbOperationalUniverse().initialize(
                 self.conf_manager, self.multiverse)},
            # Monitored Universe (ACI to AIM)
            {DESIRED: aci_universe.AciMonitoredUniverse().initialize(
                self.conf_manager, self.multiverse),
             CURRENT: aim_universe.AimDbMonitoredUniverse().initialize(
                 self.conf_manager, self.multiverse)},
        ]
        # Operational Universes. ACI operational info will be synchronized into
        # AIM's
        self.manager = aim_manager.AimManager()
        self.tree_manager = tree_manager.HashTreeManager()
        self.agent_id = 'aid-%s' % self.host
        self.agent = resource.Agent(id=self.agent_id, agent_type=AGENT_TYPE,
                                    host=self.host, binary_file=AGENT_BINARY,
                                    description=AGENT_DESCRIPTION,
                                    version=AGENT_VERSION)
        # Register agent
        self.agent = self.manager.create(aim_ctx, self.agent, overwrite=True)
        # Report procedure should happen asynchronously
        self.polling_interval = self.conf_manager.get_option_and_subscribe(
            self._change_polling_interval, 'agent_polling_interval',
            group='aim')
        self.report_interval = self.conf_manager.get_option_and_subscribe(
            self._change_report_interval, 'agent_report_interval', group='aim')
        self.squash_time = self.conf_manager.get_option_and_subscribe(
            self._change_squash_time, 'agent_event_squash_time', group='aim')
        self._spawn_heartbeat_loop()
        self.events = event_handler.EventHandler().initialize(
            self.conf_manager)
        self.max_down_time = 4 * self.report_interval
Beispiel #5
0
    def setUp(self, initialize_hooks=True):
        super(TestAimDBBase, self).setUp()
        self.test_id = uuidutils.generate_uuid()
        aim_cfg.OPTION_SUBSCRIBER_MANAGER = None
        aci_universe.ws_context = None
        if not os.environ.get(K8S_STORE_VENV):
            CONF.set_override('aim_store', 'sql', 'aim')
            self.engine = api.get_engine()
            if not TestAimDBBase._TABLES_ESTABLISHED:
                model_base.Base.metadata.create_all(self.engine)
                TestAimDBBase._TABLES_ESTABLISHED = True

            # Uncomment the line below to log SQL statements. Additionally, to
            # log results of queries, change INFO to DEBUG
            #
            # logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)

            def clear_tables():
                with self.engine.begin() as conn:
                    for table in reversed(
                            model_base.Base.metadata.sorted_tables):
                        conn.execute(table.delete())

            self.addCleanup(clear_tables)
            self.old_add_commit_hook = (
                aim_store.SqlAlchemyStore.add_commit_hook)
            aim_store.SqlAlchemyStore.add_commit_hook = _add_commit_hook

            def restore_commit_hook():
                aim_store.SqlAlchemyStore.add_commit_hook = (
                    self.old_add_commit_hook)

            self.addCleanup(restore_commit_hook)
            aim_store.SqlAlchemyStore._after_transaction_end_2 = (
                _after_transaction_end_2)
        else:
            CONF.set_override('aim_store', 'k8s', 'aim')
            CONF.set_override('k8s_namespace', self.test_id, 'aim_k8s')
            k8s_config_path = os.environ.get(K8S_CONFIG_ENV)
            if k8s_config_path:
                CONF.set_override('k8s_config_path', k8s_config_path,
                                  'aim_k8s')
            aim_store.K8sStore._post_delete = _k8s_post_delete
            aim_store.K8sStore._post_create = _k8s_post_create
            global k8s_watcher_instance
            k8s_watcher_instance = k8s_watcher.K8sWatcher()
            k8s_watcher_instance.event_handler = mock.Mock()
            k8s_watcher_instance._renew_klient_watch = mock.Mock()
            self.addCleanup(self._cleanup_objects)

        self.store = api.get_store(expire_on_commit=True,
                                   initialize_hooks=initialize_hooks)
        self.ctx = context.AimContext(store=self.store)
        self.cfg_manager = aim_cfg.ConfigManager(self.ctx, '')
        self.tt_mgr = tree_manager.HashTreeManager()
        resource.ResourceBase.__eq__ = resource_equal
        self.cfg_manager.replace_all(CONF)
        self.sys_id = self.cfg_manager.get_option('aim_system_id', 'aim')
 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 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
Beispiel #8
0
    def __init__(self, ctx=None, *args, **kwargs):
        self.ctx = ctx or context.AimContext(store=api.get_store())
        if 'streaming' not in self.ctx.store.features:
            # TODO(ivar) raise something meaningful
            raise Exception
        self.mgr = aim_manager.AimManager()
        self.tt_mgr = tree_manager.HashTreeManager()
        self.tt_maker = tree_manager.AimHashTreeMaker()
        self.tt_builder = tree_manager.HashTreeBuilder(self.mgr)
        self.klient = self.ctx.store.klient
        self.namespace = self.ctx.store.namespace
        self.trees = {}
        self.q = queue.Queue()
        self.event_handler = event_handler.EventHandler
        self._stop = False
        self._http_resp = None
        # Tenants whose trees need to be saved in AIM
        self.affected_tenants = set()
        self._observe_thread_state = {}

        self._k8s_types_to_observe = set([])
        self._k8s_aim_type_map = {}
        self._k8s_kinds = set([])
        self._needs_init = True

        for aim_res in aim_manager.AimManager.aim_resources:
            if issubclass(aim_res, resource.AciResourceBase):
                k8s_type = self.ctx.store.resource_to_db_type(aim_res)
                for ktype in ([k8s_type] + k8s_type.aux_objects.values()):
                    self._k8s_types_to_observe.add(ktype)
                    self._k8s_kinds.add(ktype.kind)
                    if ktype != api_v1.AciContainersObject:
                        self._k8s_aim_type_map[ktype.kind] = (aim_res,
                                                              k8s_type)

        self._event_filters = {
            api_v1.Pod: self._pod_event_filter,
            api_v1.Endpoints: self._endpoints_event_filter
        }
Beispiel #9
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)
 def setUp(self):
     super(TestHashTreeDbListenerNoMockStore, self).setUp(mock_store=False)
     self.tt_mgr = tree_manager.HashTreeManager()
     self.mgr = aim_manager.AimManager()
     self.db_l = ht_db_l.HashTreeDbListener(aim_manager.AimManager())
 def setUp(self):
     super(TestHashTreeDbListener, self).setUp()
     self.tt_mgr = tree_manager.HashTreeManager()
     self.mgr = aim_manager.AimManager()
     self.db_l = ht_db_l.HashTreeDbListener(aim_manager.AimManager())
Beispiel #12
0
 def __init__(self, aim_manager):
     self.aim_manager = aim_manager
     self.tt_mgr = tree_manager.HashTreeManager()
     self.tt_maker = tree_manager.AimHashTreeMaker()
     self.tt_builder = tree_manager.HashTreeBuilder(self.aim_manager)