예제 #1
0
    def handle(self, env, values):
        router = values['payload']['router']
        host_id = values["publisher_id"].replace("network.", "", 1)
        project_id = values['_context_project_id']
        router_id = encode_router_id(router['id'])
        host = self.inv.get_by_id(env, host_id)

        fetcher = CliFetchHostVservice()
        fetcher.setup(env=env, origin=self.origin)
        router_doc = fetcher.get_vservice(host_id, router_id)
        gateway_info = router['external_gateway_info']

        if gateway_info:
            network_id = gateway_info['network_id']
            self.add_router_document(env, network_id, router_doc, host)
            self.add_children_documents(env, project_id, network_id, host,
                                        router_doc)
        else:
            self.add_router_document(env, None, router_doc, host)

        # scan links and cliques
        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 added.")

        return EventResult(result=True,
                           related_object=router_id,
                           display_context=router_id)
예제 #2
0
    def handle(self, env, values):
        # find the host, to serve as parent
        instance_id = values['payload']['instance_id']
        host_id = values['payload']['host']
        instances_root_id = host_id + '-instances'
        instances_root = self.inv.get_by_id(env, instances_root_id)
        if not instances_root:
            self.log.info('instances root not found, aborting instance add')
            return EventResult(result=False, retry=True)

        # scan instance
        scanner = Scanner()
        scanner.setup(env=env, origin=self.origin)
        scanner.scan("ScanInstancesRoot",
                     instances_root,
                     limit_to_child_id=instance_id,
                     limit_to_child_type='instance')
        scanner.scan_from_queue()

        # scan host
        host = self.inv.get_by_id(env, host_id)
        scanner.scan(
            'ScanHost',
            host,
            limit_to_child_type=['vconnectors_folder', 'vedges_folder'])
        scanner.scan_from_queue()
        scanner.scan_links()
        scanner.scan_cliques()

        return EventResult(result=True,
                           related_object=instance_id,
                           display_context=instance_id)
예제 #3
0
    def handle(self, env, notification):
        # check for network document.
        subnet = notification['payload']['subnet']
        project_id = subnet['tenant_id']
        network_id = subnet['network_id']
        if 'id' not in subnet:
            self.log.info('Subnet payload doesn\'t have id, aborting subnet add')
            return EventResult(result=False, retry=False)

        network_document = self.inv.get_by_id(env, network_id)
        if not network_document:
            self.log.info('network document does not exist, aborting subnet add')
            return EventResult(result=False, retry=True)
        network_name = network_document['name']

        # build subnet document for adding network
        if subnet['cidr'] not in network_document['cidrs']:
            network_document['cidrs'].append(subnet['cidr'])
        if not network_document.get('subnets'):
            network_document['subnets'] = {}

        network_document['subnets'][subnet['name']] = subnet
        if subnet['id'] not in network_document['subnet_ids']:
            network_document['subnet_ids'].append(subnet['id'])
        self.inv.set(network_document)

        # Check DHCP enable, if true, scan network.
        if subnet['enable_dhcp'] is True:
            # update network
            if not ApiAccess.regions:
                fetcher = ApiFetchRegions()
                fetcher.setup(env=env, origin=self.origin)
                fetcher.get(project_id)

            self.log.info("add new subnet.")
            host_id = notification["publisher_id"].replace("network.", "", 1)
            self.add_children_documents(env, project_id, network_id, network_name, host_id)

        # scan links and cliques
        self.log.info("scanning for links")
        FindLinksForPnics().add_links()
        FindLinksForVserviceVnics().add_links(search={"parent_id": "qdhcp-%s-vnics" % network_id})

        scanner = Scanner()
        scanner.setup(env=env, origin=self.origin)
        scanner.scan_cliques()
        self.log.info("Finished subnet added.")
        return EventResult(result=True,
                           related_object=subnet['id'],
                           display_context=network_id)
예제 #4
0
    def handle(self, env, notification):
        project = notification['_context_project_name']
        project_id = notification['_context_project_id']
        payload = notification['payload']
        port = payload['port']
        network_id = port['network_id']
        network_name = self.get_name_by_id(network_id)
        mac_address = port['mac_address']

        # check ports folder document.
        ports_folder = self.inv.get_by_id(env, network_id + '-ports')
        if not ports_folder:
            self.log.info("ports folder not found, add ports folder first.")
            self.add_ports_folder(env, project_id, network_id, network_name)
        self.add_port_document(env, project, project_id, network_name,
                               network_id, port)

        # update the port related documents.
        if 'compute' in port['device_owner']:
            # update the instance related document.
            host_id = port['binding:host_id']
            instance_id = port['device_id']
            old_instance_doc = self.inv.get_by_id(env, instance_id)
            instances_root_id = host_id + '-instances'
            instances_root = self.inv.get_by_id(env, instances_root_id)
            if not instances_root:
                self.log.info(
                    'instance document not found, aborting port adding')
                return EventResult(result=False, retry=True)

            # update instance
            instance_fetcher = ApiFetchHostInstances()
            instance_fetcher.setup(env=env, origin=self.origin)
            instance_docs = instance_fetcher.get(host_id + '-')
            instance = next(
                filter(lambda i: i['id'] == instance_id, instance_docs), None)

            if instance:
                old_instance_doc['network_info'] = instance['network_info']
                old_instance_doc['network'] = instance['network']
                if old_instance_doc.get('mac_address') is None:
                    old_instance_doc['mac_address'] = mac_address

                self.inv.set(old_instance_doc)
                self.log.info("update instance document")

            # add vnic document.
            if port['binding:vif_type'] == 'vpp':
                vnic_fetcher = CliFetchInstanceVnicsVpp()
            else:
                # set ovs as default type.
                vnic_fetcher = CliFetchInstanceVnics()

            vnic_fetcher.setup(env=env, origin=self.origin)
            vnic_docs = vnic_fetcher.get(instance_id + '-')
            vnic = next(
                filter(lambda vnic: vnic['mac_address'] == mac_address,
                       vnic_docs), None)

            if vnic:
                vnic['environment'] = env
                vnic['type'] = 'vnic'
                vnic['name_path'] = old_instance_doc[
                    'name_path'] + '/vNICs/' + vnic['name']
                vnic['id_path'] = '{}/{}/{}'.format(
                    old_instance_doc['id_path'], old_instance_doc['id'],
                    vnic['name'])
                self.inv.set(vnic)
                self.log.info(
                    "add instance-vnic document, mac_address: {}".format(
                        mac_address))

            self.log.info("scanning for links")
            fetchers_implementing_add_links = [
                FindLinksForInstanceVnics(),
                FindLinksForVedges()
            ]
            for fetcher in fetchers_implementing_add_links:
                fetcher.add_links()
            scanner = Scanner()
            scanner.setup(env=env, origin=self.origin)
            scanner.scan_cliques()

        port_document = self.inv.get_by_id(env, port['id'])
        if not port_document:
            self.log.error("Port {} failed to add".format(port['id']))
            return EventResult(result=False, retry=True)

        return EventResult(result=True,
                           related_object=port['id'],
                           display_context=network_id)
예제 #5
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)
예제 #6
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)
예제 #7
0
    def handle(self, env, values):
        payload = values['payload']
        router = payload['router']

        project_id = values['_context_project_id']
        host_id = values["publisher_id"].replace("network.", "", 1)
        router_id = payload['id'] if 'id' in payload else router['id']

        router_full_id = encode_router_id(router_id)
        router_doc = self.inv.get_by_id(env, router_full_id)
        if not router_doc:
            self.log.info(
                "Router document not found, aborting router updating")
            return EventResult(result=False, retry=True)

        router_doc['admin_state_up'] = router['admin_state_up']
        router_doc['name'] = router['name']
        gateway_info = router.get('external_gateway_info')
        if gateway_info is None:
            # when delete gateway, need to delete the port relate document.
            port_doc = {}
            if router_doc.get('gw_port_id'):
                port_doc = self.inv.get_by_id(env, router_doc['gw_port_id'])
                EventPortDelete().delete_port(env, router_doc['gw_port_id'])

            if router_doc.get('network'):
                if port_doc:
                    router_doc['network'].remove(port_doc['network_id'])
                router_doc['gw_port_id'] = None

                # remove related links
                self.inv.delete('links', {'source_id': router_full_id})
        else:
            if 'network' in router_doc:
                if gateway_info['network_id'] not in router_doc['network']:
                    router_doc['network'].append(gateway_info['network_id'])
            else:
                router_doc['network'] = [gateway_info['network_id']]
            # update static route
            router_doc['routes'] = router['routes']

            # add gw_port_id info and port document.
            fetcher = CliFetchHostVservice()
            fetcher.setup(env=env, origin=self.origin)
            router_vservice = fetcher.get_vservice(host_id, router_full_id)
            if router_vservice.get('gw_port_id'):
                router_doc['gw_port_id'] = router_vservice['gw_port_id']

            host = self.inv.get_by_id(env, host_id)
            EventRouterAdd().add_children_documents(env, project_id,
                                                    gateway_info['network_id'],
                                                    host, router_doc)

            # rescan the vnic links.
            FindLinksForVserviceVnics().add_links(
                search={'parent_id': router_full_id + '-vnics'})
        self.inv.set(router_doc)

        # update the cliques.
        scanner = Scanner()
        scanner.setup(env=env, origin=self.origin)
        scanner.scan_cliques()
        self.log.info("Finished router update.")
        return EventResult(result=True,
                           related_object=router_full_id,
                           display_context=router_full_id)
예제 #8
0
파일: scan.py 프로젝트: opnfv/calipso
    def run(self, args: dict = None):
        args = setup_args(args, self.DEFAULTS, self.get_args)
        # After this setup we assume args dictionary has all keys
        # defined in self.DEFAULTS
        self.log.set_loglevel(args['loglevel'])

        try:
            MongoAccess.set_config_file(args['mongo_config'])
            self.inv = InventoryMgr()
            self.inv.log.set_loglevel(args['loglevel'])
            self.inv.set_collections(args['inventory'])
            self.conf = Configuration()
        except FileNotFoundError as e:
            return False, 'Mongo configuration file not found: {}'\
                .format(str(e))

        scan_plan = self.get_scan_plan(args)
        if scan_plan.clear or scan_plan.clear_all:
            self.inv.clear(scan_plan)
        self.conf.log.set_loglevel(scan_plan.loglevel)

        env_name = scan_plan.env
        self.conf.use_env(env_name)

        # generate ScanObject Class and instance.
        origin = ScanOrigin(origin_id=args['_id'],
                            origin_type=ScanOrigins.SCHEDULED
                            if args["scheduled"] else ScanOrigins.MANUAL)
        scanner = Scanner()
        scanner.log.set_loglevel(args['loglevel'])
        scanner.setup(env=env_name, origin=origin)
        scanner.found_errors[env_name] = False

        # decide what scanning operations to do
        inventory_only = scan_plan.inventory_only
        links_only = scan_plan.links_only
        cliques_only = scan_plan.cliques_only
        monitoring_setup_only = scan_plan.monitoring_setup_only
        run_all = False if inventory_only or links_only or cliques_only \
            or monitoring_setup_only else True

        # setup monitoring server
        monitoring = \
            self.inv.is_feature_supported(env_name,
                                          EnvironmentFeatures.MONITORING)
        if monitoring:
            self.inv.monitoring_setup_manager = \
                MonitoringSetupManager(env_name)
            self.inv.monitoring_setup_manager.server_setup()

        # do the actual scanning
        try:
            if inventory_only or run_all:
                scanner.run_scan(scan_plan.scanner_type, scan_plan.obj,
                                 scan_plan.id_field, scan_plan.child_id,
                                 scan_plan.child_type)
            if links_only or run_all:
                scanner.scan_links()
            if cliques_only or run_all:
                scanner.scan_cliques()
            if monitoring:
                if monitoring_setup_only:
                    self.inv.monitoring_setup_manager.simulate_track_changes()
                if not (inventory_only or links_only or cliques_only):
                    scanner.deploy_monitoring_setup()
        except ScanError as e:
            return False, "scan error: " + str(e)
        SshConnection.disconnect_all()
        status = 'ok' if not scanner.found_errors.get(env_name, False) \
            else 'errors detected'
        if status == 'ok' and scan_plan.object_type == "environment":
            self.mark_env_scanned(scan_plan.env)
        self.log.info('Scan completed, status: {}'.format(status))
        return True, status