import { Component, OnInit, AfterViewInit, AfterContentInit, ViewChild } from '@angular/core'; import { Router } from '@angular/router'; import { TreeNode, MenuItem, ContextMenu } from 'primeng/primeng'; import { Store, select } from '@ngrx/store'; import * as ListStore from '../../store/list'; import { ListSelector } from '../../store'; import { Page, PageParams } from 'app/commons/model'; import { RPCClientError } from '@loafer/ng-rpc/protocol'; import { Target } from 'packages/target/model'; import { Infra, InfraHost, InfraOSApplication, InfraService } from '../../model'; import { Domain } from 'packages/domain/model'; import { AuthSelector } from 'packages/member/store'; import { sensorListSelector } from 'packages/sensor/store'; import * as SensorListStore from 'packages/sensor/store/list'; import { Sensor } from 'packages/sensor/model'; import * as _ from 'lodash'; interface HostData { id: string; target?: Target; host: InfraHost; services: InfraService[]; } @Component({ selector: 'of-infra-map', templateUrl: './map.component.html' }) export class MapComponent implements OnInit, AfterContentInit { infraTree: TreeNode[] = []; infras$ = this.listStore.pipe(select(ListSelector.select('page'))); sensors$ = this.sensorListStore.pipe(select(sensorListSelector.select('page'))); display = false; loading = false; renameProbeVisible = false; totalList: Infra[]; hostDataList: HostData[] = new Array(); sensorMap: Map> = new Map(); targetTreeMap: Map = new Map(); DEFAULT_EXPANDED: Boolean = true; contextMenuProbe: MenuItem[]; contextMenuHost: MenuItem[]; contextMenuService: MenuItem[]; contextMenuSensor: MenuItem[]; @ViewChild('cmProbe') cmProbe: ContextMenu; @ViewChild('cmHost') cmHost: ContextMenu; @ViewChild('cmService') cmService: ContextMenu; @ViewChild('cmSensor') cmSensor: ContextMenu; selectedNode: TreeNode = null; sensorSettingDisplay = false; target: Target = null; constructor(private router: Router, private listStore: Store, private sensorListStore: Store ) { } ngAfterContentInit() { this.listStore.select(AuthSelector.select('domain')).subscribe( (domain: Domain) => { const pageParams: PageParams = { pageNo: '0', countPerPage: '99999', sortCol: 'id', sortDirection: 'descending' }; this.listStore.dispatch(new ListStore.ReadAllByDomain({ domain: domain, pageParams: pageParams })); }, (error) => { console.log(error); } ); } ngOnInit() { this.infras$.subscribe( (page: Page) => { if (page !== null) { this.totalList = page.content; this.infraTree = this.generateInfraHostData(); } }, (error: RPCClientError) => { console.log(error.response.message); }); this.sensors$.subscribe( (page: Page) => { if (page !== null) { const sensorList = page.content; this.addTreeForSensor(sensorList); } }, (error: RPCClientError) => { console.log(error.response.message); } ); this.initContextMenu(); } initContextMenu() { this.contextMenuProbe = [ { label: 'Probe Menu', command: (event) => this.closeContextMenu() }, { label: 'View this Probe', icon: 'fa-plus', command: (event) => this.viewInfo() }, { label: 'Discovery', icon: 'fa-plus', command: (event) => this.discovery() }, { label: 'Edit Alias', icon: 'fa-plus', command: (event) => this.editProbeAlias() }, ]; this.contextMenuHost = [ { label: 'Host Menu', command: (event) => this.closeContextMenu() }, { label: 'View this Host', icon: 'fa-plus', command: (event) => this.viewInfo() }, { label: 'Add sensor', icon: 'fa-plus', command: (event) => this.addSensorWithTarget() }, { label: 'Traceroute', icon: 'fa-plus', command: (event) => this.testTraceroute() }, { label: 'ARP Test', icon: 'fa-plus', command: (event) => this.testARP() }, { label: 'Ping Test', icon: 'fa-plus', command: (event) => this.testPing() }, ]; this.contextMenuService = [ { label: 'Service Menu', command: (event) => this.closeContextMenu() }, { label: 'View this Service', icon: 'fa-plus', command: (event) => this.viewInfo() }, { label: 'Add sensor', icon: 'fa-plus', command: (event) => this.addSensorWithTarget() }, ]; this.contextMenuSensor = [ { label: 'Sensor Menu', command: (event) => this.closeContextMenu() }, { label: 'View this Sensor', icon: 'fa-plus', command: (event) => this.viewInfo() }, { label: 'Edit', icon: 'fa-plus', command: (event) => this.editSensor() }, { label: 'Remove', icon: 'fa-plus', command: (event) => this.removeSensor() }, ]; } closeContextMenu() { this.cmProbe.hide(); this.cmHost.hide(); this.cmService.hide(); this.cmSensor.hide(); } searchObj(treeList: any[], target: Target, searchList: any[]) { if (treeList === undefined || treeList === null) { return; } for (const t of treeList) { if (t.obj !== undefined && t.obj == null) { if (t.obj.target.id === target.id) { searchList.push(t); } else { this.searchObj(t.children, target, searchList); } } } } addTreeForSensor(sensorList: Array) { if (sensorList === undefined || sensorList === null || sensorList.length <= 0) { return; } // const tInfraTree = _.clone(this.infraTree); // const it = tInfraTree[0]; // const it = this.infraTree[0]; // // for (const it of this.infraTree) { // if (it.children === null || it.children === undefined) { // it.children = []; // } // for (const itt of this.infraTree) { // } // } for (const sensor of sensorList) { const st = { label: 'Sensors - ' + sensor.crawler.name, type: 'sensor', obj: sensor, expanded: true }; // FIXME:: target test id .... const tt = this.targetTreeMap.get(4); // const tt = this.targetTreeMap.get(sensor.target.id); if (tt !== undefined && tt !== null) { tt.children.push(st); } // it.children.push(st); } // this.infraTree = tInfraTree; } generateInfraHostData(filterStr?: string): TreeNode[] { const itl: TreeNode[] = []; const probeMap: Map = new Map(); const hostMap: Map = new Map(); this.loading = true; this.sortInfraToMap(probeMap, hostMap, filterStr); this.targetTreeMap.clear(); const infraTree: TreeNode = this.generateInfraTree(probeMap, hostMap); for (const infra of this.totalList) { this.getSensorByInfra(infra); } this.loading = false; itl.push(infraTree); return itl; } generateInfraTree(probeMap: Map, hostMap: Map): TreeNode { const infraTree = { label: 'Infra', type: 'infra', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [], }; probeMap.forEach((ifhl: InfraHost[], key: number) => { const tp = { label: ifhl[0].probe.displayName, type: 'probe', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: this.DEFAULT_EXPANDED.valueOf(), obj: { id: key }, children: [], }; ifhl.map((ih: InfraHost, idx: number) => { const th = { label: 'Host - ' + ih.ipv4, type: 'host', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: this.DEFAULT_EXPANDED.valueOf(), obj: ih, children: [], }; this.targetTreeMap.set(ih.target.id, th); if (hostMap.has(ih.ipv4)) { const ifsl = hostMap.get(ih.ipv4); for (let i = 0; i < ifsl.length; ++i) { const ts = { label: 'Service - ' + ifsl[i].vendor.name, type: 'service', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: this.DEFAULT_EXPANDED.valueOf(), obj: ifsl[i], children: [], }; this.targetTreeMap.set(ifsl[i].target.id, ts); th.children.push(ts); } } tp.children.push(th); }); // ProbeTree.children.push(tp); infraTree.children.push(tp); }); return infraTree; } sortInfraToMap(probeMap: Map, hostMap: Map, filterStr: string) { for (const infra of this.totalList) { const infraType = infra.infraType.name; if (infraType === 'HOST') { const infraHost: InfraHost = infra; if (filterStr && String(infraHost.ipv4).indexOf(filterStr) < 0) { continue; } if (probeMap.has(infraHost.probe.id) === false) { probeMap.set(infraHost.probe.id, []); } const ihl: InfraHost[] = probeMap.get(infraHost.probe.id); ihl.push(infraHost); probeMap.set(infraHost.probe.id, ihl); } else if (infraType === 'OS_SERVICE') { const infraService: InfraService = infra; if (filterStr && this.checkFilterString(infraService, filterStr)) { continue; } if (hostMap.has(infraService.host.ipv4) === false) { hostMap.set(infraService.host.ipv4, []); } const isl = hostMap.get(infraService.host.ipv4); isl.push(infraService); } } } getSensorByInfra(infra: Infra) { const pageParams: PageParams = { pageNo: '0', countPerPage: '10', sortCol: 'id', sortDirection: 'descending' }; this.sensorListStore.dispatch(new SensorListStore.ReadAllByInfra({ id: String(infra.id), pageParams: pageParams })); } checkFilterString(infraService: InfraService, filterStr: string) { const upperCased = filterStr.toUpperCase().toUpperCase(); if (infraService.vendor.name.toUpperCase().indexOf(upperCased) < 0 && String(infraService.port).toUpperCase().indexOf(upperCased) < 0 && infraService.portType.toUpperCase().indexOf(upperCased)) { return true; } return false; } getExistHost(infraHost: InfraHost): HostData { let node = null; for (const data of this.hostDataList) { if (data.host.ipv4 === infraHost.ipv4) { node = data; } } return node; } showDialog() { this.display = true; } closeDialog() { this.display = false; } expandAll() { this.infraTree.forEach(node => { this.expandRecursive(node, true); }); } collapseAll() { this.infraTree.forEach(node => { this.expandRecursive(node, false); }); } private expandRecursive(node: TreeNode, isExpand: boolean) { node.expanded = isExpand; if (node.children) { node.children.forEach(childNode => { this.expandRecursive(childNode, isExpand); }); } } onNodeSelect(event) { const nodeType = event.node.type; this.selectedNode = event.node; if (nodeType === 'probe') { this.router.navigate(['probe', event.node.obj.id, 'info']); } else if (nodeType === 'host' || nodeType === 'service') { this.router.navigate(['target', event.node.obj.id, 'info']); } else if (nodeType === 'sensor') { this.router.navigate(['sensor', event.node.obj.id, 'info']); } } viewInfo() { this.onNodeSelect({ node : this.selectedNode, }); } nodeMenu(event: MouseEvent, node: any) { this.selectedNode = node; this.cmProbe.hide(); this.cmHost.hide(); this.cmService.hide(); this.cmSensor.hide(); if (node.type === 'probe') { this.cmProbe.show(event); } else if (node.type === 'host') { this.cmHost.show(event); } else if (node.type === 'service') { this.cmService.show(event); } else if (node.type === 'sensor') { this.cmSensor.show(event); } return false; } testTraceroute() { } testARP() { } testPing() { } editProbeAlias() { this.renameProbeVisible = true; } editSensor() { } removeSensor() { } discovery() { this.display = true; } addSensorWithTarget() { this.target = this.selectedNode['obj'].target; this.sensorSettingDisplay = true; } onSensorSettingClose() { this.target = null; this.sensorSettingDisplay = false; } onSaveProbeName(value) { const probeName = this.selectedNode.label; console.log(probeName); } } const testInfraList = [ { label: 'Infra', type: 'infra', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Zone - 192.168.1.0/24', type: 'zone', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Host - 192.168.1.106 - Snoop Host', type: 'host', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - WMI, SSH, SNMP', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true }, { label: 'Service - FTP(21)', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - FTP, Sensor', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true } ] } ] }, { label: 'Host - 192.168.1.103 - Geek Host', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - WMI, SSH, SNMP', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true }, { label: 'Service - MySQL(3306)', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - MySQL, PING', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true } ] }, { label: 'Service - PostgreSQL(5555)', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - PostgreSQL, PING', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true } ] } ] } ] }, { label: 'Zone - 192.168.10.0/24', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Host - 192.168.10.106 - Snoop Host', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - WMI, SSH, SNMP', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true }, { label: 'Service - FTP(21)', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - FTP, Sensor', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true } ] } ] }, { label: 'Host - 192.168.10.103 - Geek Host', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - WMI, SSH, SNMP', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true }, { label: 'Service - MySQL(3306)', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - MySQL, PING', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true } ] }, { label: 'Service - PostgreSQL(5555)', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true, children: [ { label: 'Sensors - PostgreSQL, PING', expandedIcon: 'fa-folder-open', collapsedIcon: 'fa-folder', expanded: true } ] } ] } ] } ] } ];