Пример #1
0
 def discoverTopologyNodes(self, vertex, parentDo=None):
     r'@types: hana_topology.VertexDescriptor[C] -> list[TopologyNode[C]] or None'
     dataObjects, warning = self.discoverDo(vertex, parentDo)
     if dataObjects:
         res = []
         for do in iteratortools.flatten((dataObjects, )):
             for pdo in iteratortools.flatten((self.buildPdo(vertex, do), )):
                 res.append(Vertex(vertex, do, self.buildOsh(vertex, pdo)))
         return res, None
     return None, warning
Пример #2
0
 def discoverTopologyNodes(self, vertex, parentDo=None):
     r'@types: hana_topology.VertexDescriptor[C] -> list[TopologyNode[C]] or None'
     dataObjects, warning = self.discoverDo(vertex, parentDo)
     if dataObjects:
         res = []
         for do in iteratortools.flatten((dataObjects, )):
             for pdo in iteratortools.flatten((self.buildPdo(vertex,
                                                             do), )):
                 res.append(Vertex(vertex, do, self.buildOsh(vertex, pdo)))
         return res, None
     return None, warning
Пример #3
0
def _reportSystems(servedSystems,
                   processOsh,
                   shell,
                   connectionIp,
                   applicationOsh=None):
    resolveEndpoint = _getEndpResolveFn(shell, connectionIp)
    vector = ObjectStateHolderVector()

    softwareBuilder = sap.SoftwareBuilder()
    softwareReporter = sap.SoftwareReporter(softwareBuilder)
    linkR = sap.LinkReporter()

    #x) report details of served systems and relation with web-dispatcher
    for servedSystem in servedSystems:
        # report endpoints of external servers
        endpoints = servedSystem.getExternalServersEndpoints()
        endpoints = flatten(keep(resolveEndpoint, endpoints))
        results = (_reportServerEndp(e, processOsh, applicationOsh)
                   for e in endpoints)
        vector.addAll(map(third, results))

        # report message server endpoint (metadata-source)
        #        and application servers of served system
        sources = servedSystem.getMetadataSources()
        msgSources, sources = partition(isMessageServerSource, sources)
        logger.debug("Report %s msg sources" % len(msgSources))
        logger.debug("Report %s other sources" % len(sources))

        # process message server, report message server
        endpoints = keep(sap_webdisp.HasEndpoint.getEndpoint, msgSources)
        msgBuilder = sap.MessageServerBuilder()
        msgReporter = sap.CentralComponentReporter(msgBuilder)
        for e in flatten(keep(resolveEndpoint, endpoints)):
            e = netutils.createTcpEndpoint(e.getAddress(), e.getPort())
            endpOsh, hostOsh, eVector = _reportServerEndp(e, processOsh)
            vector.addAll(eVector)
            msgOsh = msgReporter.reportAnonymous(hostOsh)
            vector.add(msgOsh)
            vector.add(linkR.reportUsage(msgOsh, endpOsh))

        # process non message server sources
        sources = ifilter(isSourceWithEndpoint, sources)
        endpoints = keep(sap_webdisp.HasEndpoint.getEndpoint, sources)
        endpoints.extend(servedSystem.getApplicationServersEndpoints())
        endpoints = flatten(keep(resolveEndpoint, endpoints))
        for result in (_reportServerEndp(e, processOsh) for e in endpoints):
            endpOsh, hostOsh, eVector = result
            vector.addAll(eVector)
            appServerOsh = softwareReporter.reportUknownSoftware(hostOsh)
            vector.add(appServerOsh)
            vector.add(linkR.reportUsage(appServerOsh, endpOsh))
    return vector
Пример #4
0
def discoverAllInstances(client, config):
    r''' Can be only applied for discovery by JMX due to deserialization
    limitatations of WebServices client
    @types: BaseSapJmxClient, DiscoveryConfig -> oshv'''
    discoverer = sap_jee_discoverer.ClusterDiscoverer(client)
    clusterInfo = discoverer.getClusterInfo()
    cluster = clusterInfo.cluster
    instances = clusterInfo.instances
    system = sap.System(cluster.getName())
    systemOsh, clusterOsh, vector = _reportSapSystem(system)
    linkReporter = sap.LinkReporter()
    ipsPerInst = zip(map(_resolveInstInfoHostname, instances), instances)
    hasResolvedIps = first
    endReporter = netutils.EndpointReporter(netutils.ServiceEndpointBuilder())
    for ips, instInfo in filter(hasResolvedIps, ipsPerInst):
        inst = instInfo.instance
        instOsh, hostOsh, iVector = reportInst(inst, system, systemOsh,
                                           clusterOsh, ips, reportInstName=True)
        vector.addAll(iVector)
        resolve = sap_jee_discoverer._resolvedEndpointAddress
        for endp in flatten(keep(resolve, instInfo.endpoints)):
            endpOsh = endReporter.reportEndpoint(endp, hostOsh)
            vector.add(endpOsh)
            vector.add(linkReporter.reportUsage(instOsh, endpOsh))
    return vector
def _reportSystems(servedSystems, processOsh, shell, connectionIp, applicationOsh=None):
    resolveEndpoint = _getEndpResolveFn(shell, connectionIp)
    vector = ObjectStateHolderVector()

    softwareBuilder = sap.SoftwareBuilder()
    softwareReporter = sap.SoftwareReporter(softwareBuilder)
    linkR = sap.LinkReporter()

    #x) report details of served systems and relation with web-dispatcher
    for servedSystem in servedSystems:
        # report endpoints of external servers
        endpoints = servedSystem.getExternalServersEndpoints()
        endpoints = flatten(keep(resolveEndpoint, endpoints))
        results = (_reportServerEndp(e, processOsh, applicationOsh) for e in endpoints)
        vector.addAll(map(third, results))

        # report message server endpoint (metadata-source)
        #        and application servers of served system
        sources = servedSystem.getMetadataSources()
        msgSources, sources = partition(isMessageServerSource, sources)
        logger.debug("Report %s msg sources" % len(msgSources))
        logger.debug("Report %s other sources" % len(sources))

        # process message server, report message server
        endpoints = keep(sap_webdisp.HasEndpoint.getEndpoint, msgSources)
        msgBuilder = sap.MessageServerBuilder()
        msgReporter = sap.CentralComponentReporter(msgBuilder)
        for e in flatten(keep(resolveEndpoint, endpoints)):
            e = netutils.createTcpEndpoint(e.getAddress(), e.getPort())
            endpOsh, hostOsh, eVector = _reportServerEndp(e, processOsh)
            vector.addAll(eVector)
            msgOsh = msgReporter.reportAnonymous(hostOsh)
            vector.add(msgOsh)
            vector.add(linkR.reportUsage(msgOsh, endpOsh))

        # process non message server sources
        sources = ifilter(isSourceWithEndpoint, sources)
        endpoints = keep(sap_webdisp.HasEndpoint.getEndpoint, sources)
        endpoints.extend(servedSystem.getApplicationServersEndpoints())
        endpoints = flatten(keep(resolveEndpoint, endpoints))
        for result in (_reportServerEndp(e, processOsh) for e in endpoints):
            endpOsh, hostOsh, eVector = result
            vector.addAll(eVector)
            appServerOsh = softwareReporter.reportUknownSoftware(hostOsh)
            vector.add(appServerOsh)
            vector.add(linkR.reportUsage(appServerOsh, endpOsh))
    return vector
Пример #6
0
def _pg_name_to_partition_numbers(buffer_pools, partition_nr_to_pg_name_pairs):
    partition_nrs_by_pg_name = groupby(partition_nr_to_pg_name_pairs, second,
                                       first)
    all_partition_names = set(flatten(partition_nrs_by_pg_name.values()))

    return ((bp, partition_nrs_by_pg_name[pg_name]
             if pg_name else all_partition_names)
            for bp, pg_name in buffer_pools)
Пример #7
0
    def reportConfigFiles(self, config_files, parent_osh):
        oshs = imap(self._builder.buildConfigFile, config_files)
        func = partial(self.__set_container, parentOsh=parent_osh)
        oshs = map(func, oshs)

        db_sources = flatten(imap(attrgetter('db_sources'), config_files))
        oshs.extend(self.reportDatabaseSources(db_sources, parent_osh))
        return oshs
Пример #8
0
    def __getConfigurationsIterator(self):
        ''' Get suitable configurations based on credentialsId or passed ports and protocol name
        @types: -> iterator(Config)'''
        if self.__configurationsIterator:
            return self.__configurationsIterator

        configurations = iteratortools.flatten(map(self.__spec.getConnectionConfigs, self.__protocols))
        self.__configurationsIterator = iteratortools.iterator(configurations)
        return self.__configurationsIterator
Пример #9
0
def _pg_name_to_partition_numbers(buffer_pools,
                                             partition_nr_to_pg_name_pairs):
    partition_nrs_by_pg_name = groupby(partition_nr_to_pg_name_pairs,
                                      second, first)
    all_partition_names = set(flatten(partition_nrs_by_pg_name.values()))

    return ((bp, partition_nrs_by_pg_name[pg_name]
                  if pg_name else
                 all_partition_names) for bp, pg_name in buffer_pools)
Пример #10
0
def _buildJavaInstance(system, dlgInstance):
    r'@types: System, SapJEEMonitoringXmlParser.DialogInstance -> sap.Instance'
    paths = []
    workers = _getInstanceWorkers(dlgInstance)
    paths.extend(flatten(map(_getPathsWithInstanceBasePath, workers)))
    _parseInstance = partiallyApply(parseInstFromHomeDir, system, fptools._)
    _, inst = untilFirstTruth(safeFunc(_parseInstance), paths)
    if not inst:
        raise Exception("Not enough information to build instance")
    hostname = _getDlgInstanceHostname(dlgInstance)
    return sap.Instance(inst.name, inst.number, hostname)
Пример #11
0
    def reportTopology(self, app_pools_list, web_sites_list, parentOsh, iis_version=None, webservice_ext_filter=[]):
        """

        :param web_sites_list: List of WebSites which was discovered
        :type web_sites_list: list[iis.Site]
        :param parentOsh: parent OSH for each website
        :type parentOsh: ObjectStateHolder
        :return: list[ObjectStateHolder]
        :rtype: list[ObjectStateHolder]
        """
        result = []
        apppool_map = self.reportAppPools(app_pools_list, parentOsh)
        sites_map = self.reportWebSites(web_sites_list, parentOsh, iis_version)
        result.extend(sites_map.values())
        result.extend(apppool_map.values())

        # report VirtualDir and WebDirs(WebApplication)
        for site in web_sites_list:
            web_site_osh = sites_map.get(site.name)
            if not site.is_ftp():
                # report root web dir
                root_web_dir = iis.WebApplication("Root", "/", site.path, site.config_files)
                root_osh = self._builder.buildApplication(root_web_dir)
                root_osh.setContainer(web_site_osh)
                result.append(root_osh)
                if apppool_map:
                    app_pool_osh = apppool_map.get(site.app_pool.name)
                    if app_pool_osh:
                        result.append(modeling.createLinkOSH("deployed", root_osh, app_pool_osh))

                # report config files
                result.extend(self.reportConfigFiles(site.config_files, root_osh))

                # report virtual dirs
                report_virtual_dirs = partial(self.reportVirtualDir, parent_osh=root_osh)
                result.extend(iflatten(ifilter(None, imap(report_virtual_dirs, site.virtual_dirs))))

                # report Webdirs = WebApplications
                report_web_application = partial(self.reportWebDir, parent_osh=root_osh, app_pools_map=apppool_map, webservice_ext_filter=webservice_ext_filter)
                result.extend(iflatten(ifilter(None, imap(report_web_application, site.web_applications))))

            bindings = flatten(
                ifilter(None, imap(lambda binding: binding[1].lower() in ['http', 'https', 'ftp'] and binding[2],
                                   site.bindings)))
            result.extend(self.reportBindings(bindings, web_site_osh, parentOsh))

        return result
def _reportWdEndpoints(instPf, serverOsh, shell, connectionIp):
    #x) report end-points of web-dispatcher itself and resolve them
    dispatcherEndpoints = instPf.getDispatcherEndpoints()
    resolveEndpointAddress = _getEndpResolveFn(shell, connectionIp)
    endpoints = flatten(keep(resolveEndpointAddress, dispatcherEndpoints))

    vector = ObjectStateHolderVector()

    builder = netutils.ServiceEndpointBuilder()
    endpointReporter = netutils.EndpointReporter(builder)
    linkReporter = sap.LinkReporter()

    for endpoint in endpoints:
        hostOsh = endpointReporter.reportHostFromEndpoint(endpoint)
        vector.add(hostOsh)
        endpointOsh = endpointReporter.reportEndpoint(endpoint, hostOsh)
        vector.add(endpointOsh)
        vector.add(linkReporter.reportUsage(serverOsh, endpointOsh))
    return vector
Пример #13
0
def _reportWdEndpoints(instPf, serverOsh, shell, connectionIp):
    #x) report end-points of web-dispatcher itself and resolve them
    dispatcherEndpoints = instPf.getDispatcherEndpoints()
    resolveEndpointAddress = _getEndpResolveFn(shell, connectionIp)
    endpoints = flatten(keep(resolveEndpointAddress, dispatcherEndpoints))

    vector = ObjectStateHolderVector()

    builder = netutils.ServiceEndpointBuilder()
    endpointReporter = netutils.EndpointReporter(builder)
    linkReporter = sap.LinkReporter()

    for endpoint in endpoints:
        hostOsh = endpointReporter.reportHostFromEndpoint(endpoint)
        vector.add(hostOsh)
        endpointOsh = endpointReporter.reportEndpoint(endpoint, hostOsh)
        vector.add(endpointOsh)
        vector.add(linkReporter.reportUsage(serverOsh, endpointOsh))
    return vector
Пример #14
0
def reportRfcConfigs(rfcConfigs, resolver, hostOsh):
    '@types: list[RfcConfiguration], DnsResolver, osh -> iterable[osh]'
    return flatten(reportRfcConfig(c, hostOsh, resolver) for c in rfcConfigs)
Пример #15
0
def reportRfcConfigs(rfcConfigs, resolver, hostOsh):
    '@types: list[RfcConfiguration], DnsResolver, osh -> iterable[osh]'
    return flatten(reportRfcConfig(c, hostOsh, resolver) for c in rfcConfigs)
Пример #16
0
            # create platform trait based on server version
            platformTrait = jee_discoverer.getPlatformTrait(version, platform)
            serverDiscoverer = weblogic_discoverer.createServerDiscovererByJmx(jmxProvider, platformTrait)
            appDiscoverer = weblogic_discoverer.createApplicationDiscovererByJmx(jmxProvider, platformTrait)
            jmsDiscoverer = weblogic_discoverer.createJmsDiscovererByJmx(jmxProvider, platformTrait)

            # DOMAIN TOPOLOGY DISCOVERY
            logger.info("Start domain topology discovery")
            domain = serverDiscoverer.discoverRunningServersInDomain()
            if not domain:
                Framework.reportError("Failed to find domain information")
                return
            # set administrative IP address for the domain
            # next step to find domain administrative IP address, which is actually admin-server IP
            import iteratortools
            allservers = iteratortools.flatten(
                map(jee.Node.getServers, domain.getNodes()) )
            domainIpAddresses = discoverDomainAdministrativeIps(allservers, dnsResolver)
            if domainIpAddresses:
                domain.setIp(domainIpAddresses[0])
            else:
                logger.warn("Failed to find administrative server")


            logger.info("Found %s" % domain)
            domainVector = ObjectStateHolderVector()
            domainVector.addAll( serverTopologyReporter.reportNodesInDomain(domain, *domain.getNodes()) )
            _sendVectorImmediately(Framework, domainVector, forceVectorClear = 0)

            # CLUSTER DISCOVERY
            logger.info("Start cluster discovery")
            clusters = []
Пример #17
0
                jmxProvider, platformTrait)
            appDiscoverer = weblogic_discoverer.createApplicationDiscovererByJmx(
                jmxProvider, platformTrait)
            jmsDiscoverer = weblogic_discoverer.createJmsDiscovererByJmx(
                jmxProvider, platformTrait)

            # DOMAIN TOPOLOGY DISCOVERY
            logger.info("Start domain topology discovery")
            domain = serverDiscoverer.discoverRunningServersInDomain()
            if not domain:
                Framework.reportError("Failed to find domain information")
                return
            # set administrative IP address for the domain
            # next step to find domain administrative IP address, which is actually admin-server IP
            import iteratortools
            allservers = iteratortools.flatten(
                map(jee.Node.getServers, domain.getNodes()))
            domainIpAddresses = discoverDomainAdministrativeIps(
                allservers, dnsResolver)
            if domainIpAddresses:
                domain.setIp(domainIpAddresses[0])
            else:
                logger.warn("Failed to find administrative server")

            logger.info("Found %s" % domain)
            domainVector = ObjectStateHolderVector()
            domainVector.addAll(
                serverTopologyReporter.reportNodesInDomain(
                    domain, *domain.getNodes()))
            _sendVectorImmediately(Framework, domainVector, forceVectorClear=0)

            # CLUSTER DISCOVERY
Пример #18
0
def _discoverEc2Topology(framework, ec2Service, account):
    r'@types: Framework, Ec2Service, aws.Account'

    logger.info('Discover REGIONS')
    # first of all get information about available Regions and Availability Zones
    regions = _discoverRegionsWithZones(ec2Service)

    # get information about running instances in our account
    vector = ObjectStateHolderVector()
    for region in regions:
        # Discovery collects instances information from each available region.
        # So we establish connection to
        # each of them.
        ec2Service.setEndpoint(region.getEndpointHostName())
        instances = _discoverRunningEc2AmiInstances(ec2Service)

        # every instance has mapped devices (currently we are interested in EBS)
        # to get more detailed information about volumes we have to gather all
        # their uniq IDs
        def getInstanceEbsIds(instance):
            r'@types: ec2.Ami.Instance -> list[str]'
            return map(lambda e: e.getVolume().getId(),
                       instance.getMappedDevices())

        ids = _applySet(
            _toItself, iteratortools.flatten(map(getInstanceEbsIds,
                                                 instances)))
        # get VOLUMES by IDs
        volumes = ids and _discoverVolumesByIds(ec2Service, ids) or ()
        logger.debug(str(volumes))
        # having volumes on hands we can get information about corresponding

        # snapshots by IDs so again - gather unique IDs
        ids = filter(None, _applySet(aws_store.Ebs.getSnapshotId, volumes))
        snapshots = ids and map(
            _partialFunc(_discoverVolumeSnapshotById, ec2Service, _),
            ids) or ()
        snapshots = filter(None, snapshots)
        logger.debug(str(snapshots))
        logger.info("Discovered %s snapshots" % len(snapshots))

        # Get images for the running instances by IDs
        # gather unique IDs
        ids = _applySet(ec2.Ami.Instance.getImageId, instances)

        # discover AMIs by IDs
        amis = ids and _discoverEc2AmisByIds(ec2Service, ids) or ()
        # for further lookup create mapping of AMI to ID
        amiById = _applyMapping(ec2.Ami.getId, amis)
        instancesByAmiId = _groupBy(ec2.Ami.Instance.getImageId, instances)
        # Discover available elastic IPs and group them by instance id to which they
        # belong. Before grouping performing filtering by non-empty instance ID
        ec2Discoverer = Ec2Discoverer(ec2Service)
        elasticIpsByInstanceId = _groupBy(
            ec2.ElasticIp.getInstanceId,
            filter(
                ec2.ElasticIp.getInstanceId,
                warnException(ec2Discoverer.getElasticIps, (),
                              message="Failed to get elastic IPs")()))

        logger.info('REPORT DATA')

        try:
            # First of all we have to prepare reporters for each domain
            awsReporter = aws.Reporter(aws.Builder())
            ec2Reporter = ec2.Reporter(ec2.Builder())
            storeReporter = aws_store.Reporter(aws_store.Builder())
            # report Account information
            vector.add(awsReporter.reportAccount(account))
            # mapping of built availability zone to its name
            zoneByName = {}
            # Regions and corresponding availability zones
            try:
                vector.addAll(awsReporter.reportRegion(region))
            except Exception:
                logger.warnException("Failed to report %s" % region)
            else:
                for zone in region.getZones():
                    try:
                        vector.addAll(
                            awsReporter.reportAvailabilityZoneInRegion(
                                region, zone))
                        zoneByName[zone.getName()] = zone
                    except Exception:
                        logger.warnException("Failed to report %s" % zone)

            volumeById = _applyMapping(aws_store.Ebs.getId, volumes)
            # group snapshots by volume ID
            snapshotsById = _groupBy(aws_store.Ebs.Snapshot.getId, snapshots)
            # report running Instances with mapped devices, IPs and configurations
            # report only instances which AMI detailed information available
            for amiId in filter(amiById.has_key, instancesByAmiId.keys()):
                for instance in instancesByAmiId.get(amiId):
                    try:
                        # report AMI instances
                        ami = amiById.get(amiId)
                        vector.addAll(
                            ec2Reporter.reportAmiInstance(
                                account, ami, instance))
                        # report link to the availability zone
                        zone = zoneByName.get(instance.availabilityZoneName)
                        if zone and zone.getOsh():
                            vector.addAll(
                                ec2Reporter.linkAmiInstanceToAvailabilityZone(
                                    instance, zone.getOsh()))
                        else:
                            logger.warn(
                                "Failed to find zone %s for %s" %
                                (instance.availabilityZoneName, instance))
                        # report mapped devices
                        devices = instance.getMappedDevices()
                        logger.info(
                            "Report mapped devices (%s) for instance %s" %
                            (len(devices), instance.getId()))
                        containerOsh = ec2Reporter.buildInstanceNode(instance)

                        # report elastic IP as usual public IP address in AWS account
                        for elasticIp in elasticIpsByInstanceId.get(
                                instance.getId(), ()):
                            vector.addAll(
                                ec2Reporter.reportPublicIpAddress(
                                    account, elasticIp.getIp(), containerOsh))

                        for mappedVolume in devices:
                            volume = volumeById.get(
                                mappedVolume.getVolume().getId())
                            if volume:
                                mappedVolume = aws_store.MappedVolume(
                                    mappedVolume.getName(), volume)
                            volumeOsh = storeReporter.reportMappedVolume(
                                mappedVolume, containerOsh)
                            vector.add(volumeOsh)
                            # report link between availability zone and EBS
                            zoneName = mappedVolume.getVolume(
                            ).getAvailabilityZoneName()
                            if zoneByName.has_key(zoneName):
                                zoneOsh = zoneByName[zoneName].getOsh()
                                vector.add(
                                    storeReporter.
                                    linkMappedVolumeToAvailabilityZone(
                                        volumeOsh, zoneOsh))
                            # report related snapshots if exist
                            volumeSnapshots = snapshotsById.get(
                                volume.getSnapshotId()) or ()
                            logger.info(
                                "Report %s snapshots for the mapped volume %s"
                                % (len(volumeSnapshots), volume.getId()))
                            for snapshot in volumeSnapshots:
                                snapshotOsh = storeReporter.reportSnapshot(
                                    snapshot, account.getOsh())
                                vector.add(snapshotOsh)
                                vector.add(
                                    storeReporter.linkSnapshotAndMappedVolume(
                                        snapshotOsh, volumeOsh))
                    except Exception:
                        logger.warnException("Failed to report %s" % instance)
        except (JException, Exception):
            logger.warnException("Failed to report topology")
    return vector
Пример #19
0
def _discoverEc2Topology(framework, ec2Service, account):
    r"@types: Framework, Ec2Service, aws.Account"

    logger.info("Discover REGIONS")
    # first of all get information about available Regions and Availability Zones
    regions = _discoverRegionsWithZones(ec2Service)

    # get information about running instances in our account
    vector = ObjectStateHolderVector()
    for region in regions:
        # Discovery collects instances information from each available region.
        # So we establish connection to
        # each of them.
        ec2Service.setEndpoint(region.getEndpointHostName())
        instances = _discoverRunningEc2AmiInstances(ec2Service)

        # every instance has mapped devices (currently we are interested in EBS)
        # to get more detailed information about volumes we have to gather all
        # their uniq IDs
        def getInstanceEbsIds(instance):
            r"@types: ec2.Ami.Instance -> list[str]"
            return map(lambda e: e.getVolume().getId(), instance.getMappedDevices())

        ids = _applySet(_toItself, iteratortools.flatten(map(getInstanceEbsIds, instances)))
        # get VOLUMES by IDs
        volumes = ids and _discoverVolumesByIds(ec2Service, ids) or ()
        logger.debug(str(volumes))
        # having volumes on hands we can get information about corresponding

        # snapshots by IDs so again - gather unique IDs
        ids = filter(None, _applySet(aws_store.Ebs.getSnapshotId, volumes))
        snapshots = ids and map(_partialFunc(_discoverVolumeSnapshotById, ec2Service, _), ids) or ()
        snapshots = filter(None, snapshots)
        logger.debug(str(snapshots))
        logger.info("Discovered %s snapshots" % len(snapshots))

        # Get images for the running instances by IDs
        # gather unique IDs
        ids = _applySet(ec2.Ami.Instance.getImageId, instances)

        # discover AMIs by IDs
        amis = ids and _discoverEc2AmisByIds(ec2Service, ids) or ()
        # for further lookup create mapping of AMI to ID
        amiById = _applyMapping(ec2.Ami.getId, amis)
        instancesByAmiId = _groupBy(ec2.Ami.Instance.getImageId, instances)
        # Discover available elastic IPs and group them by instance id to which they
        # belong. Before grouping performing filtering by non-empty instance ID
        ec2Discoverer = Ec2Discoverer(ec2Service)
        elasticIpsByInstanceId = _groupBy(
            ec2.ElasticIp.getInstanceId,
            filter(
                ec2.ElasticIp.getInstanceId,
                warnException(ec2Discoverer.getElasticIps, (), message="Failed to get elastic IPs")(),
            ),
        )

        logger.info("REPORT DATA")

        try:
            # First of all we have to prepare reporters for each domain
            awsReporter = aws.Reporter(aws.Builder())
            ec2Reporter = ec2.Reporter(ec2.Builder())
            storeReporter = aws_store.Reporter(aws_store.Builder())
            # report Account information
            vector.add(awsReporter.reportAccount(account))
            # mapping of built availability zone to its name
            zoneByName = {}
            # Regions and corresponding availability zones
            try:
                vector.addAll(awsReporter.reportRegion(region))
            except Exception:
                logger.warnException("Failed to report %s" % region)
            else:
                for zone in region.getZones():
                    try:
                        vector.addAll(awsReporter.reportAvailabilityZoneInRegion(region, zone))
                        zoneByName[zone.getName()] = zone
                    except Exception:
                        logger.warnException("Failed to report %s" % zone)

            volumeById = _applyMapping(aws_store.Ebs.getId, volumes)
            # group snapshots by volume ID
            snapshotsById = _groupBy(aws_store.Ebs.Snapshot.getId, snapshots)
            # report running Instances with mapped devices, IPs and configurations
            # report only instances which AMI detailed information available
            for amiId in filter(amiById.has_key, instancesByAmiId.keys()):
                for instance in instancesByAmiId.get(amiId):
                    try:
                        # report AMI instances
                        ami = amiById.get(amiId)
                        vector.addAll(ec2Reporter.reportAmiInstance(account, ami, instance))
                        # report link to the availability zone
                        zone = zoneByName.get(instance.availabilityZoneName)
                        if zone and zone.getOsh():
                            vector.addAll(ec2Reporter.linkAmiInstanceToAvailabilityZone(instance, zone.getOsh()))
                        else:
                            logger.warn("Failed to find zone %s for %s" % (instance.availabilityZoneName, instance))
                        # report mapped devices
                        devices = instance.getMappedDevices()
                        logger.info("Report mapped devices (%s) for instance %s" % (len(devices), instance.getId()))
                        containerOsh = ec2Reporter.buildInstanceNode(instance)

                        # report elastic IP as usual public IP address in AWS account
                        for elasticIp in elasticIpsByInstanceId.get(instance.getId(), ()):
                            vector.addAll(ec2Reporter.reportPublicIpAddress(account, elasticIp.getIp(), containerOsh))

                        for mappedVolume in devices:
                            volume = volumeById.get(mappedVolume.getVolume().getId())
                            if volume:
                                mappedVolume = aws_store.MappedVolume(mappedVolume.getName(), volume)
                            volumeOsh = storeReporter.reportMappedVolume(mappedVolume, containerOsh)
                            vector.add(volumeOsh)
                            # report link between availability zone and EBS
                            zoneName = mappedVolume.getVolume().getAvailabilityZoneName()
                            if zoneByName.has_key(zoneName):
                                zoneOsh = zoneByName[zoneName].getOsh()
                                vector.add(storeReporter.linkMappedVolumeToAvailabilityZone(volumeOsh, zoneOsh))
                            # report related snapshots if exist
                            volumeSnapshots = snapshotsById.get(volume.getSnapshotId()) or ()
                            logger.info(
                                "Report %s snapshots for the mapped volume %s" % (len(volumeSnapshots), volume.getId())
                            )
                            for snapshot in volumeSnapshots:
                                snapshotOsh = storeReporter.reportSnapshot(snapshot, account.getOsh())
                                vector.add(snapshotOsh)
                                vector.add(storeReporter.linkSnapshotAndMappedVolume(snapshotOsh, volumeOsh))
                    except Exception:
                        logger.warnException("Failed to report %s" % instance)
        except (JException, Exception):
            logger.warnException("Failed to report topology")
    return vector