Exemplo n.º 1
0
    def add_children_documents(self, env, project_id, network_id, host,
                               router_doc):

        network_document = self.inv.get_by_id(env, network_id)
        network_name = network_document['name']
        router_id = decode_router_id(router_doc['id'])

        # add port for binding to vservice:router
        subnet_handler = EventSubnetAdd()
        ports_folder = self.inv.get_by_id(env, network_id + '-ports')
        if not ports_folder:
            self.log.info("Ports_folder not found.")
            subnet_handler.add_ports_folder(env, project_id, network_id,
                                            network_name)
        add_port_return = subnet_handler.add_port_document(
            env, router_doc['gw_port_id'], network_name=network_name)

        # add vnics folder and vnic document
        port_handler = EventPortAdd()
        add_vnic_folder = partial(port_handler.add_vnics_folder,
                                  env=env,
                                  host=host,
                                  object_id=router_id,
                                  object_type='router',
                                  network_name=network_name,
                                  router_name=router_doc['name'])
        add_vnic_document = partial(port_handler.add_vnic_document,
                                    env=env,
                                    host=host,
                                    object_id=router_id,
                                    object_type='router',
                                    network_name=network_name,
                                    router_name=router_doc['name'])

        add_vnic_folder()
        if add_port_return:
            add_vnic_return = add_vnic_document()
            if not add_vnic_return:
                self.log.info("Try to add vnic document again.")
                add_vnic_document()
        else:
            # in some cases, port has been created,
            # but port doc cannot be fetched by OpenStack API
            self.log.info("Try to add port document again.")
            # TODO: #AskCheng - this never returns anything!
            add_port_return = add_vnic_folder()
            # TODO: #AskCheng - this will never evaluate to True!
            if add_port_return is False:
                self.log.info("Try to add vnic document again.")
                add_vnic_document()
Exemplo n.º 2
0
    def add_gateway_port(self, env, project, network_name, router_doc,
                         host_id):
        fetcher = CliFetchHostVservice()
        fetcher.setup(env=env, origin=self.origin)
        router_id = router_doc['id']
        router = fetcher.get_vservice(host_id, router_id)
        device_id = decode_router_id(router_id)
        router_doc['gw_port_id'] = router['gw_port_id']

        # add gateway port documents.
        port_doc = EventSubnetAdd().add_port_document(env,
                                                      router_doc['gw_port_id'],
                                                      project_name=project)

        mac_address = port_doc['mac_address'] if port_doc else None

        # add vnic document
        host = self.inv.get_by_id(env, host_id)

        add_vnic_document = partial(EventPortAdd().add_vnic_document,
                                    env=env,
                                    host=host,
                                    object_id=device_id,
                                    object_type='router',
                                    network_name=network_name,
                                    router_name=router_doc['name'],
                                    mac_address=mac_address)

        ret = add_vnic_document()
        if not ret:
            time.sleep(self.delay)
            self.log.info(
                "Wait %s second, and then fetch vnic document again." %
                self.delay)
            add_vnic_document()
Exemplo n.º 3
0
    def test_handle_subnet_add(self, api_fetch_port_class_mock,
                               db_fetch_port_class_mock,
                               event_port_add_class_mock,
                               find_links_for_pnics_class_mock,
                               find_links_for_vnics_class_mock,
                               scanner_class_mock):
        self.values = EVENT_PAYLOAD_SUBNET_ADD
        self.payload = self.values['payload']
        self.subnet = self.payload['subnet']
        self.subnet_id = self.subnet['id']
        self.network_id = self.subnet['network_id']
        self.host_id = self.values["publisher_id"].replace("network.", "", 1)
        self.port_id = PORT_DOC['id']

        db_fetch_port_mock = db_fetch_port_class_mock.return_value
        db_fetch_port_mock.get_id.side_effect = self.get_port_id

        api_fetch_port_mock = api_fetch_port_class_mock.return_value
        api_fetch_port_mock.get.side_effect = self.get_port_docs

        event_port_add_mock = event_port_add_class_mock.return_value
        find_links_for_pnics_mock = find_links_for_pnics_class_mock.return_value
        find_links_for_vnics_mock = find_links_for_vnics_class_mock.return_value
        scanner_mock = scanner_class_mock.return_value

        self.inv.get_by_id.side_effect = self.get_by_id

        if not ApiAccess.regions:
            ApiAccess.regions = EVENT_PAYLOAD_REGION

        res = EventSubnetAdd().handle(self.env, self.values)

        if ApiAccess.regions == EVENT_PAYLOAD_REGION:
            ApiAccess.regions = None

        self.assertTrue(res.result)

        # Assert that subnet has been added to network
        set_call = [
            call[0][0] for call in self.inv.set.call_args_list
            if self.payload['subnet']['id'] in call[0][0].get(
                'subnet_ids', [])
        ]
        self.assertTrue(set_call)

        self.assertTrue(event_port_add_mock.add_network_services_folder.called)
        self.assertTrue(event_port_add_mock.add_dhcp_document.called)
        self.assertTrue(event_port_add_mock.add_vnics_folder.called)
        self.assertTrue(event_port_add_mock.add_vnic_document.called)
        self.assertTrue(find_links_for_pnics_mock.add_links.called)
        self.assertTrue(find_links_for_vnics_mock.add_links.called)
        self.assertTrue(scanner_mock.scan_cliques.called)
Exemplo n.º 4
0
    def handle(self, env, values):
        interface = values['payload']['router_interface']
        project_id = values['_context_project_id']
        project = values['_context_project_name']
        host_id = values["publisher_id"].replace("network.", "", 1)
        port_id = interface['port_id']
        subnet_id = interface['subnet_id']
        router_id = encode_router_id(interface['id'])

        network_document = self.inv.get_by_field(env,
                                                 "network",
                                                 "subnet_ids",
                                                 subnet_id,
                                                 get_single=True)
        if not network_document:
            self.log.info(
                "network document not found, aborting interface adding")
            return EventResult(result=False, retry=True)
        network_name = network_document['name']
        network_id = network_document['id']

        # add router-interface port document.
        if not ApiAccess.regions:
            fetcher = ApiFetchRegions()
            fetcher.setup(env=env, origin=self.origin)
            fetcher.get(project_id)
        port_doc = EventSubnetAdd().add_port_document(
            env, port_id, network_name=network_name)

        mac_address = port_doc['mac_address'] if port_doc else None

        # add vnic document
        host = self.inv.get_by_id(env, host_id)
        router_doc = self.inv.get_by_id(env, router_id)

        add_vnic_document = partial(EventPortAdd().add_vnic_document,
                                    env=env,
                                    host=host,
                                    object_id=interface['id'],
                                    object_type='router',
                                    network_name=network_name,
                                    router_name=router_doc['name'],
                                    mac_address=mac_address)

        ret = add_vnic_document()
        if ret is False:
            # try it again to fetch vnic document, vnic will be created a little bit late before CLI fetch.
            time.sleep(self.delay)
            self.log.info(
                "Wait {} seconds, and then fetch vnic document again.".format(
                    self.delay))
            add_vnic_document()

        # update the router document: gw_port_id, network.
        self.update_router(env, project, network_id, network_name, router_doc,
                           host_id)

        # update vservice-vnic, vnic-network,
        FindLinksForVserviceVnics().add_links(search={"parent_id": router_id})
        scanner = Scanner()
        scanner.setup(env=env, origin=self.origin)

        scanner.scan_cliques()
        self.log.info("Finished router-interface added.")

        return EventResult(result=True,
                           related_object=interface['id'],
                           display_context=network_id)
Exemplo n.º 5
0
    def handle(self, env, notification):
        # check for network document.
        subnet = notification['payload']['subnet']
        project_id = notification['_context_project_id']
        project = notification['_context_project_name']
        host_id = notification['publisher_id'].replace('network.', '', 1)
        subnet_id = subnet['id']
        network_id = subnet['network_id']
        network_document = self.inv.get_by_id(env, network_id)
        if not network_document:
            self.log.info(
                'network document does not exist, aborting subnet update')
            return EventResult(result=False, retry=True)

        # update network document.
        subnets = network_document['subnets']
        key = next(filter(lambda k: subnets[k]['id'] == subnet_id, subnets),
                   None)

        if key:
            if subnet['enable_dhcp'] and subnets[key]['enable_dhcp'] is False:
                # scan DHCP namespace to add related document.
                # add dhcp vservice document.
                host = self.inv.get_by_id(env, host_id)
                port_handler = EventPortAdd()
                port_handler.add_dhcp_document(env, host, network_id,
                                               network_document['name'])

                # make sure that self.regions is not empty.
                if not ApiAccess.regions:
                    fetcher = ApiFetchRegions()
                    fetcher.setup(env=env, origin=self.origin)
                    fetcher.get(project_id)

                self.log.info("add port binding to DHCP server.")
                port_id = DbFetchPort(). \
                    get_id_by_field(network_id,
                                    """device_owner LIKE "%dhcp" """)
                port = EventSubnetAdd(). \
                    add_port_document(env, port_id,
                                      network_name=network_document['name'],
                                      project_name=project)
                if port:
                    port_handler. \
                        add_vnic_document(env, host, network_id,
                                          network_name=network_document['name'],
                                          mac_address=port['mac_address'])
                    # add link for vservice - vnic
                    FindLinksForVserviceVnics().add_links(
                        search={"id": "qdhcp-%s" % network_id})
                    scanner = Scanner()
                    scanner.setup(env=env, origin=self.origin)
                    scanner.scan_cliques()
                    FindLinksForVserviceVnics(). \
                        add_links(search={"id": "qdhcp-%s" % network_id})
                    scanner = Scanner()
                    scanner.setup(env=env, origin=self.origin)
                    scanner.scan_cliques()

            if subnet['enable_dhcp'] is False and subnets[key]['enable_dhcp']:
                # delete existed related DHCP documents.
                self.inv.delete("inventory",
                                {'id': "qdhcp-%s" % subnet['network_id']})
                self.log.info("delete DHCP document: qdhcp-%s" %
                              subnet['network_id'])

                port = self.inv.find_items(
                    {
                        'network_id': subnet['network_id'],
                        'device_owner': 'network:dhcp'
                    },
                    get_single=True)
                if 'id' in port:
                    EventPortDelete().delete_port(env, port['id'])
                    self.log.info("delete port binding to DHCP server.")

            if subnet['name'] == subnets[key]['name']:
                subnets[key] = subnet
            else:
                del subnets[key]
                subnets[subnet['name']] = subnet

            self.inv.set(network_document)
            return EventResult(result=True,
                               related_object=subnet['id'],
                               display_context=network_id)
        else:
            self.log.info('subnet not in network, aborting subnet update')
            return EventResult(result=False, retry=False)