import { Component, Input, OnInit, } from '@angular/core'; import { Host, Port, Service } from '@overflow/commons-typescript/model/discovery'; import { TreeNode, Message, Tree } from 'primeng/primeng'; import { ProbeHost } from '@overflow/commons-typescript/model/probe'; import { Anim } from './animation'; import { TargetService } from '@overflow/target/service/target.service'; import { InfraService, InfraHost, MetaTargetHostTypeEnum, toMetaTargetHostType, Infra, MetaInfraTypeEnum, toMetaInfraTypeEnum, toMetaInfraType, InfraZone, Target, Page, PageParams } from '@overflow/commons-typescript'; import { InfraService as InfraRegistService } from '../../infra/service/infra.service'; import { Observable, of, Subscription } from 'rxjs'; import { catchError, map, tap, take } from 'rxjs/operators'; @Component({ selector: 'of-discovery-result', templateUrl: './search-result.component.html', animations: Anim, providers: [ TargetService, InfraRegistService ] }) export class SearchResultComponent implements OnInit { @Input() probeHost: ProbeHost; @Input() filterWord: string; @Input() filterServices: Map; infras: Infra[]; existTargets: Target[]; discoverySubscription: Subscription; zoneNode: TreeNode[] = []; hostNode: TreeNode[] = []; selectedItems = []; msgs: Message[]; error$: Observable; discoveredHosts: Host[] = []; discoveredServices: Service[] = []; infraSaved: boolean; targetSaved: boolean; pending$: Observable; constructor( private infraRegistService: InfraRegistService, private targetService: TargetService ) { } ngOnInit(): void { this.zoneNode.push({ label: this.probeHost.probe.cidr, type: 'ZONE', data: { }, children: this.hostNode, expanded: true }); // this.getExistTarget(); } discoveryStarted(startedAt: Date) { console.log('Discovery Started at: ' + startedAt); } discoveryStopped(stoppedAt: Date) { console.log('Discovery Stopped at: ' + stoppedAt); this.saveDiscoveredInfras(); } getExistTarget() { const pageParams: PageParams = { pageNo: 0, countPerPage: 99999, sortCol: 'id', sortDirection: 'descending' }; this.targetService.readAllByProbeID(this.probeHost.probe.id, pageParams) .pipe( tap(() => { }), map((targetPage: Page) => { this.existTargets = targetPage.content; }), catchError(error => { this.error$ = of(error); return of(); }), tap(() => { }), take(1), ).subscribe(); } // ngOnChanges(changes: SimpleChanges): void { // if (changes['finished'] && changes['finished'].currentValue === true) { // this.saveDiscoveredInfras(); // } // } displayInform() { this.msgs = []; this.msgs.push({ severity: 'success', summary: 'Discovery가 완료되었습니다. 모니터링 대상(들)을 선택 후 저장하세요.', }); } rerenderInfras() { this.hostNode = []; for (const infra of this.infras) { switch (infra.metaInfraType) { // case toMetaInfraType(MetaInfraTypeEnum.ZONE): // const infraZone: InfraZone = infra; // break; case toMetaInfraType(MetaInfraTypeEnum.HOST): const infraHost: InfraHost = infra; this.addInfraHost(infraHost); break; case toMetaInfraType(MetaInfraTypeEnum.SERVICE): const infraService: InfraService = infra; this.addInfraService(infraService) break; default: break; } } } saveDiscoveredInfras() { this.infraRegistService.registDiscoverd( this.probeHost.probe.id, this.discoveredHosts, this.discoveredServices) .pipe( tap(() => { this.infraSaved = false; this.pending$ = of(true); }), map((infras: Infra[]) => { if (infras) { this.infras = infras; this.rerenderInfras(); this.displayInform(); } }), catchError(error => { this.error$ = of(error); return of(); }), tap(() => { this.infraSaved = true; this.pending$ = of(false); }), take(1), ).subscribe(); } addHost(host: Host) { const idx = this.findHostIndex(host); this.hostNode.splice(idx, 0, { type: 'HOST', label: host.address, data: { ip: this.convertIPtoNumber(host.address), mac: host.mac, target: host }, expanded: true, children: [] }); this.discoveredHosts.push(host); } addService(service: Service) { const targetHostNode = this.findHostNodeByService(service.port.host.address); const idx = this.findServiceIndex(targetHostNode.children, service.name); targetHostNode.children.splice(idx, 0, { type: 'SERVICE', label: service.name + ' (' + service.port.portNumber + ')', data: { name: service.name, portType: service.port.metaPortType.key, portNumber: service.port.portNumber, target: service }, }); this.discoveredServices.push(service); } addInfraHost(infraHost: InfraHost) { const host: Host = { address: infraHost.infraHostIPs[0].address, } const idx = this.findHostIndex(host); this.hostNode.splice(idx, 0, { type: 'HOST', label: host.address, data: { ip: this.convertIPtoNumber(host.address), target: infraHost }, expanded: true, children: [] }); } addInfraService(infraService: InfraService) { const targetHostNode = this.findHostNodeByService(infraService.infraHostPort.infraHostIP.address); const idx = this.findServiceIndex(targetHostNode.children, infraService.metaTargetServiceType.name); targetHostNode.children.splice(idx, 0, { type: 'SERVICE', label: infraService.metaTargetServiceType.name + ' (' + infraService.infraHostPort.port + ')', data: { name: infraService.metaTargetServiceType.name, portType: infraService.infraHostPort.metaPortType.name, portNumber: infraService.infraHostPort.port, target: infraService }, }); } onTargetSelect(e, node: TreeNode) { const data = node.data.target; if (e.checked) { this.selectedItems.push(data); } else { const index = this.selectedItems.indexOf(data); this.selectedItems.splice(index, 1); } } findHostIndex(host: Host): number { let index = 0; this.hostNode.forEach(node => { if (node.data.ip < this.convertIPtoNumber(host.address)) { index++; } }); return index; } findServiceIndex(serviceNodes: TreeNode[], serviceName: string) { let index = 0; serviceNodes.forEach(node => { // if (node.data.portNumber < service.port.portNumber) { // index++; // } if (node.data.name.toUpperCase().localeCompare(serviceName.toUpperCase()) === -1) { index++; } }); return index; } findHostNodeByService(serviceAddress: string) { let targetHost = null; this.hostNode.forEach((value, i) => { if (value.data.ip === this.convertIPtoNumber(serviceAddress)) { targetHost = value; return; } }); return targetHost; } convertIPtoNumber(ip: string) { return ip.split('.').map((octet, index, array) => { return parseInt(octet) * Math.pow(256, (array.length - index - 1)); }).reduce((prev, curr) => { return prev + curr; }); } checkHighlight(label: string, type: number) { let highlight = true; if (this.filterWord && (label.toUpperCase().indexOf(this.filterWord.toUpperCase()) < 0)) { highlight = false; } if (type === 1 && this.filterServices[label] === false) { highlight = false; } return highlight; } checkExistTarget(infra: Infra): boolean { if (!this.infraSaved) { return false; } for (const target of this.existTargets) { if (target.infra.id === infra.id) { return true; } } return false; } saveTargets() { const targets: Target[] = []; this.selectedItems.forEach(value => { const infra: Infra = value; let name: string; if (value.metaInfraType === toMetaInfraType(MetaInfraTypeEnum.ZONE)) { const infraZone: InfraZone = value; name = infraZone.network; } else if (value.metaInfraType === toMetaInfraType(MetaInfraTypeEnum.HOST)) { const infraHost: InfraHost = value; name = infraHost.infraHostIPs[0].address; } else if (value.metaInfraType === toMetaInfraType(MetaInfraTypeEnum.SERVICE)) { const infraService: InfraService = value; name = infraService.metaInfraType.name; } const target: Target = { infra: { id: infra.id }, name: name, sensorCount: 0, }; targets.push(target); }); this.targetService.registAll(targets, this.probeHost.probe.id) .pipe( tap(() => { }), map((targets: Target[]) => { if (targets) { this.targetSaved = true; } }), catchError(error => { this.error$ = of(error); return of(); }), tap(() => { }), take(1), ).subscribe(); } }