discovery
This commit is contained in:
parent
853141dd0f
commit
aa810aef68
|
@ -24,7 +24,7 @@ export const Anim = [
|
||||||
trigger('discoveryResultAnim', [
|
trigger('discoveryResultAnim', [
|
||||||
transition('void => *', [
|
transition('void => *', [
|
||||||
query('*', style({ opacity: 0 }), { optional: true }),
|
query('*', style({ opacity: 0 }), { optional: true }),
|
||||||
query('*', stagger('30ms', [
|
query('*', stagger('60ms', [
|
||||||
animate('0.08s ease-in', keyframes([
|
animate('0.08s ease-in', keyframes([
|
||||||
style({ opacity: 0, transform: 'translateX(-95%)', offset: 0 }),
|
style({ opacity: 0, transform: 'translateX(-95%)', offset: 0 }),
|
||||||
style({ opacity: .5, transform: 'translateX(95px)', offset: 0.3 }),
|
style({ opacity: .5, transform: 'translateX(95px)', offset: 0.3 }),
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<of-error-message [error]="error$ | async" [closable]="false"></of-error-message>
|
||||||
|
<of-block-progressbar [target]="content" [pending]="pending$ | async"></of-block-progressbar>
|
||||||
|
|
||||||
|
<p-panel #content [showHeader]="false" class="block-panel">
|
||||||
|
|
||||||
|
<p-messages [(value)]="msgs"></p-messages>
|
||||||
|
|
||||||
|
<p-tree [value]="zoneNode" layout="vertical">
|
||||||
|
<!-- ZONE node template -->
|
||||||
|
<ng-template let-node pTemplate="ZONE">
|
||||||
|
<!-- 이미 저장된 Infra인 Node-->
|
||||||
|
<div *ngIf="node.data.date">
|
||||||
|
<p-toggleButton [disabled]="node.data.target" onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check" offIcon="fa-square"
|
||||||
|
[style]="{'width':'200px'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton> {{node.data.date | date: 'yy/MM/dd'}}
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<!-- HOST node template -->
|
||||||
|
<ng-template let-node pTemplate="HOST">
|
||||||
|
<!-- 이미 저장된 Infra인 Node-->
|
||||||
|
<div *ngIf="node.data.date">
|
||||||
|
<p-toggleButton [disabled]="node.data.target" onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check" offIcon="fa-square"
|
||||||
|
[style]="{'width':'200px'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton> {{node.data.date | date: 'yy/MM/dd'}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="!node.data.date" @discoveryResultAnim>
|
||||||
|
<p-toggleButton onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check" offIcon="fa-square" [style]="{'width':'200px'}"
|
||||||
|
(onChange)="onTargetSelect($event, node)"></p-toggleButton> New!!
|
||||||
|
</div>
|
||||||
|
<!-- <div @discoveryResultAnim>
|
||||||
|
<div *ngIf="checkHighlight(node.label, 0) else unhighlightHost">
|
||||||
|
<p-toggleButton [disabled]="checkExistTarget(node.data.target)" onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check"
|
||||||
|
offIcon="fa-square" [style]="{'width':'200px'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #unhighlightHost>
|
||||||
|
<p-toggleButton [disabled]="checkExistTarget(node.data.target)" onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check"
|
||||||
|
offIcon="fa-square" [style]="{'width':'200px', 'opacity': '0.2'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton>
|
||||||
|
</ng-template>
|
||||||
|
</div> -->
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<!-- SERVICE node template -->
|
||||||
|
<ng-template let-node pTemplate="SERVICE">
|
||||||
|
<!-- 이미 저장된 Infra인 Node-->
|
||||||
|
<div *ngIf="node.data.date">
|
||||||
|
<p-toggleButton [disabled]="node.data.target" onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check" offIcon="fa-square"
|
||||||
|
[style]="{'width':'400px'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton> {{node.data.date | date: 'yy/MM/dd'}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="!node.data.date" @discoveryResultAnim>
|
||||||
|
<p-toggleButton onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check" offIcon="fa-square" [style]="{'width':'200px'}"
|
||||||
|
(onChange)="onTargetSelect($event, node)"></p-toggleButton> New!!
|
||||||
|
</div>
|
||||||
|
<!-- <div @discoveryResultAnim>
|
||||||
|
<div *ngIf="checkHighlight(node.data.name, 1) else unhighlightServ">
|
||||||
|
<p-toggleButton [disabled]="checkExistTarget(node.data.target)" onLabel="{{node.label}} {{node.data.portType}}" offLabel="{{node.label}} {{node.data.portType}} {{node.data.portNumber}}"
|
||||||
|
onIcon="fa-check" offIcon="fa-square" [style]="{'width':'300px'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #unhighlightServ>
|
||||||
|
<p-toggleButton [disabled]="checkExistTarget(node.data.target)" onLabel="{{node.label}} {{node.data.portType}}" offLabel="{{node.label}} {{node.data.portType}} {{node.data.portNumber}}"
|
||||||
|
onIcon="fa-check" offIcon="fa-square" [style]="{'width':'300px', 'opacity': '0.2'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton>
|
||||||
|
</ng-template>
|
||||||
|
</div> -->
|
||||||
|
</ng-template>
|
||||||
|
</p-tree>
|
||||||
|
|
||||||
|
<button class="ui-button-width-fit ui-float-right ui-top-space-10" [disabled]="selectedItems.length === 0" type="button"
|
||||||
|
label="Save" icon="ui-icon-close" pButton (click)="saveTargets()"></button>
|
||||||
|
|
||||||
|
</p-panel>
|
||||||
|
|
||||||
|
|
||||||
|
<p-dialog header="Title" [(visible)]="targetSaved" [modal]="true" [responsive]="true" [width]="600" [minWidth]="200" [minY]="70"
|
||||||
|
[closeOnEscape]="false">
|
||||||
|
<span>Target 지정이 완료되었습니다. 이어서 Sensor를 등록하시면 좋겠다능</span>
|
||||||
|
<p-footer>
|
||||||
|
<button type="button" pButton label="메인으로"></button>
|
||||||
|
<button type="button" pButton label="Target으로"></button>
|
||||||
|
<button type="button" pButton label="InfraMap으로"></button>
|
||||||
|
</p-footer>
|
||||||
|
</p-dialog>
|
420
@overflow/discovery/component/discovery-infra-tree.component.ts
Normal file
420
@overflow/discovery/component/discovery-infra-tree.component.ts
Normal file
|
@ -0,0 +1,420 @@
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
Input,
|
||||||
|
OnChanges,
|
||||||
|
SimpleChanges,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Host, 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, Infra, MetaInfraTypeEnum, toMetaInfraTypeEnum, toMetaInfraType, InfraZone, Target, Page, PageParams } from '@overflow/commons-typescript';
|
||||||
|
import { InfraService as InfraManageService } from '../../infra/service/infra.service';
|
||||||
|
import { Observable, of, Subscription } from 'rxjs';
|
||||||
|
import { catchError, map, tap, take } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'of-discovery-infra-tree',
|
||||||
|
templateUrl: './discovery-infra-tree.component.html',
|
||||||
|
animations: Anim,
|
||||||
|
providers: [
|
||||||
|
TargetService,
|
||||||
|
InfraManageService
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class DiscoveryInfraTreeComponent implements OnChanges {
|
||||||
|
|
||||||
|
@Input() probeHost: ProbeHost;
|
||||||
|
@Input() filterWord: string;
|
||||||
|
@Input() filterServices: Map<string, boolean>;
|
||||||
|
|
||||||
|
targets: Target[];
|
||||||
|
infraZones: InfraZone[];
|
||||||
|
infraHosts: InfraHost[];
|
||||||
|
infraServices: InfraService[];
|
||||||
|
|
||||||
|
zoneNode: TreeNode[];
|
||||||
|
hostNode: TreeNode[];
|
||||||
|
selectedItems: TreeNode[] = [];
|
||||||
|
msgs: Message[];
|
||||||
|
|
||||||
|
savedInfras: Infra[];
|
||||||
|
|
||||||
|
discoveredHosts: Host[] = [];
|
||||||
|
discoveredServices: Service[] = [];
|
||||||
|
infraSaved: boolean;
|
||||||
|
targetSaved: boolean;
|
||||||
|
|
||||||
|
pending$: Observable<boolean>;
|
||||||
|
error$: Observable<any>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private infraManageService: InfraManageService,
|
||||||
|
private targetService: TargetService
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if (changes['probeHost']) {
|
||||||
|
this.getTargets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getInfras() {
|
||||||
|
const pageParams: PageParams = {
|
||||||
|
pageNo: 0,
|
||||||
|
countPerPage: 99999,
|
||||||
|
sortCol: 'id',
|
||||||
|
sortDirection: 'descending'
|
||||||
|
};
|
||||||
|
this.infraManageService.readAllByProbeID(this.probeHost.probe.id, pageParams)
|
||||||
|
.pipe(
|
||||||
|
tap(() => {
|
||||||
|
this.pending$ = of(true);
|
||||||
|
}),
|
||||||
|
map((infraPage: Page<Infra>) => {
|
||||||
|
this.generateTree(infraPage.content);
|
||||||
|
}),
|
||||||
|
catchError(error => {
|
||||||
|
this.error$ = of(error);
|
||||||
|
return of();
|
||||||
|
}),
|
||||||
|
tap(() => {
|
||||||
|
this.pending$ = of(false);
|
||||||
|
}),
|
||||||
|
take(1),
|
||||||
|
).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
getTargets() {
|
||||||
|
const pageParams: PageParams = {
|
||||||
|
pageNo: 0,
|
||||||
|
countPerPage: 99999,
|
||||||
|
sortCol: 'id',
|
||||||
|
sortDirection: 'descending'
|
||||||
|
};
|
||||||
|
this.targetService.readAllByProbeID(this.probeHost.probe.id, pageParams)
|
||||||
|
.pipe(
|
||||||
|
tap(() => {
|
||||||
|
this.pending$ = of(true);
|
||||||
|
}),
|
||||||
|
map((targetPage: Page<Target>) => {
|
||||||
|
this.targets = targetPage.content;
|
||||||
|
this.getInfras();
|
||||||
|
}),
|
||||||
|
catchError(error => {
|
||||||
|
this.error$ = of(error);
|
||||||
|
return of();
|
||||||
|
}),
|
||||||
|
tap(() => {
|
||||||
|
this.pending$ = of(false);
|
||||||
|
}),
|
||||||
|
take(1),
|
||||||
|
).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
generateTree(infras: Infra[]) {
|
||||||
|
this.zoneNode = [];
|
||||||
|
this.hostNode = [];
|
||||||
|
this.infraZones = [];
|
||||||
|
this.infraHosts = [];
|
||||||
|
this.infraServices = [];
|
||||||
|
|
||||||
|
for (const infra of infras) {
|
||||||
|
if (infra.metaInfraType.key === toMetaInfraType(MetaInfraTypeEnum.ZONE).key) {
|
||||||
|
this.infraZones.push(infra);
|
||||||
|
} else if (infra.metaInfraType.key === toMetaInfraType(MetaInfraTypeEnum.HOST).key) {
|
||||||
|
this.infraHosts.push(infra);
|
||||||
|
} else if (infra.metaInfraType.key === toMetaInfraType(MetaInfraTypeEnum.SERVICE).key) {
|
||||||
|
this.infraServices.push(infra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.infraZones.forEach(infraZone => {
|
||||||
|
this.addInfraZone(infraZone);
|
||||||
|
});
|
||||||
|
this.infraHosts.forEach(infraHost => {
|
||||||
|
this.addInfraHost(infraHost);
|
||||||
|
});
|
||||||
|
this.infraServices.forEach(infraService => {
|
||||||
|
this.addInfraService(infraService);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addInfraZone(infraZone: InfraZone) {
|
||||||
|
const target: Target = this.checkAlreadyTarget(infraZone.id);
|
||||||
|
this.zoneNode.push({
|
||||||
|
label: this.probeHost.probe.cidr,
|
||||||
|
type: 'ZONE',
|
||||||
|
data: {
|
||||||
|
target: target,
|
||||||
|
date: infraZone.createDate,
|
||||||
|
object: infraZone,
|
||||||
|
infraID: infraZone.id,
|
||||||
|
},
|
||||||
|
children: this.hostNode,
|
||||||
|
expanded: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addInfraHost(infraHost: InfraHost) {
|
||||||
|
const target: Target = this.checkAlreadyTarget(infraHost.id);
|
||||||
|
const ip = infraHost.infraHostIPs[0].address
|
||||||
|
const idx = this.findHostIndex(ip);
|
||||||
|
this.hostNode.splice(idx, 0, {
|
||||||
|
type: 'HOST',
|
||||||
|
label: ip,
|
||||||
|
data: {
|
||||||
|
target: target,
|
||||||
|
date: infraHost.createDate,
|
||||||
|
ip: this.convertIPtoNumber(ip),
|
||||||
|
object: infraHost,
|
||||||
|
infraID: infraHost.id,
|
||||||
|
},
|
||||||
|
expanded: true,
|
||||||
|
children: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addInfraService(infraService: InfraService) {
|
||||||
|
console.log(infraService);
|
||||||
|
const target: Target = this.checkAlreadyTarget(infraService.id);
|
||||||
|
const targetHostNode = this.findHostNodeByService(infraService.infraHostPort.infraHostIP.address);
|
||||||
|
// const idx = this.findServiceIndex(targetHostNode.children, infraService.metaTargetServiceType.name);
|
||||||
|
targetHostNode.children.push({
|
||||||
|
type: 'SERVICE',
|
||||||
|
label: 'metaTargetServiceType이 현재 null ' + ' (' + infraService.infraHostPort.port + ')',
|
||||||
|
data: {
|
||||||
|
target: target,
|
||||||
|
date: infraService.createDate,
|
||||||
|
portType: infraService.infraHostPort.metaPortType.name,
|
||||||
|
portNumber: infraService.infraHostPort.port,
|
||||||
|
object: infraService,
|
||||||
|
infraID: infraService.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAlreadyTarget(infraID: number): Target {
|
||||||
|
return this.targets.find(target => target.infra.id === infraID);
|
||||||
|
}
|
||||||
|
|
||||||
|
discoveryStarted(startedAt: Date) {
|
||||||
|
console.log('Discovery Started at: ' + startedAt);
|
||||||
|
this.pending$ = of(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
discoveryStopped(stoppedAt: Date) {
|
||||||
|
console.log('Discovery Stopped at: ' + stoppedAt);
|
||||||
|
this.saveDiscoveredInfras();
|
||||||
|
this.pending$ = of(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
saveDiscoveredInfras() {
|
||||||
|
this.infraManageService.registDiscoverd(
|
||||||
|
this.probeHost.probe.id,
|
||||||
|
this.discoveredHosts,
|
||||||
|
this.discoveredServices)
|
||||||
|
.pipe(
|
||||||
|
tap(() => {
|
||||||
|
this.infraSaved = false;
|
||||||
|
this.pending$ = of(true);
|
||||||
|
}),
|
||||||
|
map((infras: Infra[]) => {
|
||||||
|
if (infras) {
|
||||||
|
this.savedInfras = infras;
|
||||||
|
this.msgs = [];
|
||||||
|
this.msgs.push({
|
||||||
|
severity: 'success',
|
||||||
|
summary: infras.length + '개의 Infra가 새로 저장되었습니다. 모니터링 대상(들)을 선택 후 저장하세요.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.pending$ = of(false);
|
||||||
|
}),
|
||||||
|
catchError(error => {
|
||||||
|
this.error$ = of(error);
|
||||||
|
return of();
|
||||||
|
}),
|
||||||
|
tap(() => {
|
||||||
|
this.infraSaved = true;
|
||||||
|
}),
|
||||||
|
take(1),
|
||||||
|
).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
addHost(host: Host) {
|
||||||
|
let exist = false;
|
||||||
|
this.infraHosts.forEach(infraHost => {
|
||||||
|
if (infraHost.infraHostIPs[0].address === host.address) {
|
||||||
|
exist = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (exist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const idx = this.findHostIndex(host.address);
|
||||||
|
this.hostNode.splice(idx, 0, {
|
||||||
|
type: 'HOST',
|
||||||
|
label: host.address,
|
||||||
|
data: {
|
||||||
|
target: null,
|
||||||
|
date: null,
|
||||||
|
ip: this.convertIPtoNumber(host.address),
|
||||||
|
object: host,
|
||||||
|
infraID: null,
|
||||||
|
},
|
||||||
|
expanded: true,
|
||||||
|
children: []
|
||||||
|
});
|
||||||
|
this.discoveredHosts.push(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
addService(service: Service) {
|
||||||
|
let exist = false;
|
||||||
|
this.infraServices.forEach(infraService => {
|
||||||
|
if (//infraService.metaTargetServiceType.name === service.name &&
|
||||||
|
infraService.infraHostPort.port === service.port.portNumber &&
|
||||||
|
infraService.infraHostPort.infraHostIP.address === service.port.host.address
|
||||||
|
) {
|
||||||
|
exist = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (exist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetHostNode = this.findHostNodeByService(service.port.host.address);
|
||||||
|
// const idx = this.findServiceIndex(targetHostNode.children, infraService.metaTargetServiceType.name);
|
||||||
|
targetHostNode.children.push({
|
||||||
|
type: 'SERVICE',
|
||||||
|
label: service.name + ' (' + service.port.portNumber + ')',
|
||||||
|
data: {
|
||||||
|
target: null,
|
||||||
|
date: null,
|
||||||
|
portType: service.port.metaPortType.name,
|
||||||
|
portNumber: service.port.portNumber,
|
||||||
|
object: service,
|
||||||
|
InfraID: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.discoveredServices.push(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
findHostIndex(hostIP: string): number {
|
||||||
|
let index = 0;
|
||||||
|
this.hostNode.forEach(node => {
|
||||||
|
if (node.data.ip < this.convertIPtoNumber(hostIP)) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
onTargetSelect(e, node: TreeNode) {
|
||||||
|
if (e.checked) {
|
||||||
|
this.selectedItems.push(node);
|
||||||
|
} else {
|
||||||
|
const index = this.selectedItems.indexOf(node);
|
||||||
|
this.selectedItems.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTargets() {
|
||||||
|
const targets: Target[] = [];
|
||||||
|
this.selectedItems.forEach(node => {
|
||||||
|
const infraID = node.data.infraID;
|
||||||
|
if (null === infraID) { // 새로 발견된 Host / Service
|
||||||
|
|
||||||
|
}
|
||||||
|
// 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: infraID
|
||||||
|
},
|
||||||
|
name: '',
|
||||||
|
sensorCount: 0,
|
||||||
|
};
|
||||||
|
targets.push(target);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(targets);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
<h1>Discovery</h1>
|
<h1>Discovery</h1>
|
||||||
<div class="ui-g">
|
<div class="ui-g">
|
||||||
<div class="ui-g-12">
|
<div class="ui-g-12">
|
||||||
<of-probe-selector [probeHostID]="probeHostID" (select)="selectedProbe=$event"></of-probe-selector>
|
<of-probe-selector [probeHostID]="probeHostID" (select)="selectedProbe = $event"></of-probe-selector>
|
||||||
<of-probe-summary *ngIf="selectedProbe" @discoveryFilterAnim [probeHost]="selectedProbe"></of-probe-summary>
|
<of-probe-summary *ngIf="selectedProbe" @discoveryFilterAnim [probeHost]="selectedProbe"></of-probe-summary>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,19 +10,19 @@
|
||||||
<p-accordion [multiple]="true">
|
<p-accordion [multiple]="true">
|
||||||
<p-accordionTab header="Discovery Settings" [selected]="true">
|
<p-accordionTab header="Discovery Settings" [selected]="true">
|
||||||
<span *ngIf="!selectedProbe">Choose a Probe to perform Discovery.</span>
|
<span *ngIf="!selectedProbe">Choose a Probe to perform Discovery.</span>
|
||||||
<of-discovery-search-config *ngIf="!requested && selectedProbe" @discoveryFilterAnim [probeHost]="selectedProbe" (requestDiscovery)="onRequestDiscovery($event)"></of-discovery-search-config>
|
<of-discovery-search-config *ngIf="startDate === null && selectedProbe" @discoveryFilterAnim [probeHost]="selectedProbe"
|
||||||
|
(requestDiscovery)="onRequestDiscovery($event)"></of-discovery-search-config>
|
||||||
<of-discovery-request-summary *ngIf="discoverZone" @discoveryFilterAnim [discoverZone]="discoverZone"></of-discovery-request-summary>
|
<of-discovery-request-summary *ngIf="discoverZone" @discoveryFilterAnim [discoverZone]="discoverZone"></of-discovery-request-summary>
|
||||||
</p-accordionTab>
|
</p-accordionTab>
|
||||||
<p-accordionTab header="Filter" [selected]="requested" [disabled]="!requested">
|
<p-accordionTab header="Filter" [selected]="startDate !== null" [disabled]="startDate === null">
|
||||||
<of-discovery-search-filter #discoveryFilter (search)="filterWord=$event" (serviceSelect)="filterServices=$event"></of-discovery-search-filter>
|
<of-discovery-search-filter #filter (search)="filterWord=$event" (serviceSelect)="filterServices=$event"></of-discovery-search-filter>
|
||||||
</p-accordionTab>
|
</p-accordionTab>
|
||||||
</p-accordion>
|
</p-accordion>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ui-g-12 ui-md-9">
|
<div class="ui-g-12 ui-md-9">
|
||||||
<!-- <button class="ui-button-danger ui-button-width-fit" type="button" label="Stop" icon="ui-icon-close" pButton (click)="onRequestStop()"></button> -->
|
<of-discovery-infra-tree #infraTree *ngIf="selectedProbe" [probeHost]="selectedProbe" [filterWord]="filterWord" [filterServices]="filterServices"></of-discovery-infra-tree>
|
||||||
<of-discovery-result #discoveryResult *ngIf="requested else info" [probeHost]="selectedProbe" [filterWord]="filterWord" [filterServices]="filterServices"
|
<!-- <of-discovery-result *ngIf="requested else info" [probeHost]="selectedProbe" [filterWord]="filterWord" [filterServices]="filterServices"></of-discovery-result> -->
|
||||||
[finished]="finished"></of-discovery-result>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import {
|
import {
|
||||||
Component, Input, OnDestroy, ViewChild,
|
Component, Input, OnDestroy, OnInit, ViewChild,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
import { Observable, of, Subscription } from 'rxjs';
|
import { Observable, of, Subscription } from 'rxjs';
|
||||||
import { catchError, map } from 'rxjs/operators';
|
import { catchError, map, tap, take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { ProbeHost } from '@overflow/commons-typescript/model/probe';
|
import { ProbeHost } from '@overflow/commons-typescript/model/probe';
|
||||||
import { DiscoverZone, Zone, Host, Port, Service } from '@overflow/commons-typescript/model/discovery';
|
import { DiscoverZone, Zone, Host, Port, Service } from '@overflow/commons-typescript/model/discovery';
|
||||||
|
@ -12,40 +12,46 @@ import { DiscoverZone, Zone, Host, Port, Service } from '@overflow/commons-types
|
||||||
import { Anim } from './animation';
|
import { Anim } from './animation';
|
||||||
import { DiscoveryService } from '../service/discovery.service';
|
import { DiscoveryService } from '../service/discovery.service';
|
||||||
import { DiscoverySubscriber, DiscoveryNotify } from '../subscriber/discovery.subscriber';
|
import { DiscoverySubscriber, DiscoveryNotify } from '../subscriber/discovery.subscriber';
|
||||||
import { SearchResultComponent } from './search-result.component';
|
|
||||||
import { SearchFilterComponent } from './search-filter.component';
|
import { SearchFilterComponent } from './search-filter.component';
|
||||||
|
import { DiscoveryInfraTreeComponent } from './discovery-infra-tree.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'of-discovery',
|
selector: 'of-discovery',
|
||||||
templateUrl: './discovery.component.html',
|
templateUrl: './discovery.component.html',
|
||||||
animations: Anim,
|
animations: Anim,
|
||||||
})
|
})
|
||||||
export class DiscoveryComponent implements OnDestroy {
|
|
||||||
|
export class DiscoveryComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input() probeHostID;
|
@Input() probeHostID;
|
||||||
pending$: Observable<boolean>;
|
pending$: Observable<boolean>;
|
||||||
error$: Observable<any>;
|
error$: Observable<any>;
|
||||||
discoverySubscription: Subscription;
|
discoverySubscription: Subscription;
|
||||||
|
|
||||||
selectedProbe: ProbeHost;
|
selectedProbe: ProbeHost;
|
||||||
requested: boolean;
|
|
||||||
discoverZone: DiscoverZone;
|
discoverZone: DiscoverZone;
|
||||||
finished: boolean;
|
|
||||||
|
startDate: Date;
|
||||||
|
stopDate: Date;
|
||||||
|
|
||||||
filterWord: string;
|
filterWord: string;
|
||||||
filterServices: Service[];
|
filterServices: Service[];
|
||||||
|
|
||||||
@ViewChild('discoveryResult') discoveryResult: SearchResultComponent;
|
@ViewChild('infraTree') infraTree: DiscoveryInfraTreeComponent;
|
||||||
@ViewChild('discoveryFilter') discoveryFilter: SearchFilterComponent;
|
@ViewChild('filter') filter: SearchFilterComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private discoveryService: DiscoveryService,
|
private discoveryService: DiscoveryService,
|
||||||
private discoverySubscriber: DiscoverySubscriber,
|
private discoverySubscriber: DiscoverySubscriber,
|
||||||
) {
|
) {
|
||||||
this.discoverySubscription = null;
|
this.discoverySubscription = null;
|
||||||
this.finished = false;
|
this.startDate = null;
|
||||||
|
this.stopDate = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
if (null !== this.discoverySubscription) {
|
if (null !== this.discoverySubscription) {
|
||||||
this.discoverySubscription.unsubscribe();
|
this.discoverySubscription.unsubscribe();
|
||||||
|
@ -53,9 +59,7 @@ export class DiscoveryComponent implements OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
onRequestDiscovery(dz: DiscoverZone) {
|
onRequestDiscovery(dz: DiscoverZone) {
|
||||||
this.requested = true;
|
|
||||||
this.discoverZone = dz;
|
this.discoverZone = dz;
|
||||||
|
|
||||||
const zone: Zone = {
|
const zone: Zone = {
|
||||||
network: this.selectedProbe.infraHost.infraZone.network, // this.selectedProbe.probe.cidr
|
network: this.selectedProbe.infraHost.infraZone.network, // this.selectedProbe.probe.cidr
|
||||||
address: this.selectedProbe.infraHost.infraZone.address.split('/')[0],
|
address: this.selectedProbe.infraHost.infraZone.address.split('/')[0],
|
||||||
|
@ -71,16 +75,16 @@ export class DiscoveryComponent implements OnDestroy {
|
||||||
switch (discoveryNotify.method) {
|
switch (discoveryNotify.method) {
|
||||||
case 'DiscoveryService.discoveryStart': {
|
case 'DiscoveryService.discoveryStart': {
|
||||||
const startDate = discoveryNotify.params as Date;
|
const startDate = discoveryNotify.params as Date;
|
||||||
|
this.startDate = startDate;
|
||||||
|
this.infraTree.discoveryStarted(startDate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'DiscoveryService.discoveryStop': {
|
case 'DiscoveryService.discoveryStop': {
|
||||||
const stopDate = discoveryNotify.params as Date;
|
const stopDate = discoveryNotify.params as Date;
|
||||||
|
this.stopDate = stopDate;
|
||||||
this.finished = true;
|
|
||||||
this.discoverySubscription.unsubscribe();
|
this.discoverySubscription.unsubscribe();
|
||||||
this.discoverySubscription = null;
|
this.discoverySubscription = null;
|
||||||
|
this.infraTree.discoveryStopped(stopDate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'DiscoveryService.discoveredZone': {
|
case 'DiscoveryService.discoveredZone': {
|
||||||
|
@ -89,7 +93,7 @@ export class DiscoveryComponent implements OnDestroy {
|
||||||
}
|
}
|
||||||
case 'DiscoveryService.discoveredHost': {
|
case 'DiscoveryService.discoveredHost': {
|
||||||
const host = discoveryNotify.params as Host;
|
const host = discoveryNotify.params as Host;
|
||||||
this.discoveryResult.addHost(host);
|
this.infraTree.addHost(host);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'DiscoveryService.discoveredPort': {
|
case 'DiscoveryService.discoveredPort': {
|
||||||
|
@ -99,8 +103,8 @@ export class DiscoveryComponent implements OnDestroy {
|
||||||
}
|
}
|
||||||
case 'DiscoveryService.discoveredService': {
|
case 'DiscoveryService.discoveredService': {
|
||||||
const service = discoveryNotify.params as Service;
|
const service = discoveryNotify.params as Service;
|
||||||
this.discoveryFilter.addService(service);
|
this.infraTree.addService(service);
|
||||||
this.discoveryResult.addService(service);
|
this.filter.addService(service);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -114,9 +118,4 @@ export class DiscoveryComponent implements OnDestroy {
|
||||||
).subscribe();
|
).subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
onRequestStop() {
|
|
||||||
this.discoverZone = null;
|
|
||||||
this.requested = false;
|
|
||||||
this.discoveryService.stopDiscovery(this.selectedProbe.probe.probeKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,16 @@ import { ServiceSelectorComponent } from './service-selector.component';
|
||||||
import { DiscoveryComponent } from './discovery.component';
|
import { DiscoveryComponent } from './discovery.component';
|
||||||
import { SearchConfigComponent } from './search-config.component';
|
import { SearchConfigComponent } from './search-config.component';
|
||||||
import { SearchFilterComponent } from './search-filter.component';
|
import { SearchFilterComponent } from './search-filter.component';
|
||||||
import { SearchResultComponent } from './search-result.component';
|
|
||||||
import { IpInputComponent } from './ip-input.component';
|
import { IpInputComponent } from './ip-input.component';
|
||||||
import { RequestSummaryComponent } from './request-summary.component';
|
import { RequestSummaryComponent } from './request-summary.component';
|
||||||
|
import { DiscoveryInfraTreeComponent } from './discovery-infra-tree.component';
|
||||||
|
|
||||||
export const COMPONENTS = [
|
export const COMPONENTS = [
|
||||||
ServiceSelectorComponent,
|
ServiceSelectorComponent,
|
||||||
DiscoveryComponent,
|
DiscoveryComponent,
|
||||||
SearchConfigComponent,
|
SearchConfigComponent,
|
||||||
SearchFilterComponent,
|
SearchFilterComponent,
|
||||||
SearchResultComponent,
|
|
||||||
IpInputComponent,
|
IpInputComponent,
|
||||||
RequestSummaryComponent,
|
RequestSummaryComponent,
|
||||||
|
DiscoveryInfraTreeComponent
|
||||||
];
|
];
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="ui-g">
|
<div class="ui-g">
|
||||||
<div *ngFor="let service of services">
|
<div *ngFor="let service of services">
|
||||||
<p-toggleButton offLabel="{{service.name}}" onLabel="{{service.name}}" [style]="{'width':'100px'}" (onChange)="onServiceFilter($event, service)"
|
<p-toggleButton offLabel="{{service.name}}" onLabel="{{service.name}}" [style]="{'width':'100px'}" (onChange)="onServiceFilter($event, service)"
|
||||||
[(ngModel)]="filterServices[service.serviceName]"></p-toggleButton>
|
[(ngModel)]="filterServices[service.name]"></p-toggleButton>
|
||||||
|
|
||||||
<!-- <p-checkbox [(ngModel)]="filterServices" label="{{service.serviceName}}" value="{{service.serviceName}}"></p-checkbox> -->
|
<!-- <p-checkbox [(ngModel)]="filterServices" label="{{service.serviceName}}" value="{{service.serviceName}}"></p-checkbox> -->
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import {
|
import {
|
||||||
Component, Input,
|
Component, Input,
|
||||||
SimpleChanges,
|
|
||||||
OnInit,
|
OnInit,
|
||||||
OnChanges,
|
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { Host, Port, Service } from '@overflow/commons-typescript/model/discovery';
|
import { Host, Port, Service } from '@overflow/commons-typescript/model/discovery';
|
||||||
import { TreeNode, Message, Tree } from 'primeng/primeng';
|
import { TreeNode, Message, Tree } from 'primeng/primeng';
|
||||||
|
@ -23,12 +21,11 @@ import { catchError, map, tap, take } from 'rxjs/operators';
|
||||||
InfraRegistService
|
InfraRegistService
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SearchResultComponent implements OnInit, OnChanges {
|
export class SearchResultComponent implements OnInit {
|
||||||
|
|
||||||
@Input() probeHost: ProbeHost;
|
@Input() probeHost: ProbeHost;
|
||||||
@Input() filterWord: string;
|
@Input() filterWord: string;
|
||||||
@Input() filterServices: Map<string, boolean>;
|
@Input() filterServices: Map<string, boolean>;
|
||||||
@Input() finished: boolean;
|
|
||||||
|
|
||||||
infras: Infra[];
|
infras: Infra[];
|
||||||
existTargets: Target[];
|
existTargets: Target[];
|
||||||
|
@ -62,7 +59,16 @@ export class SearchResultComponent implements OnInit, OnChanges {
|
||||||
children: this.hostNode,
|
children: this.hostNode,
|
||||||
expanded: true
|
expanded: true
|
||||||
});
|
});
|
||||||
this.getExistTarget();
|
// this.getExistTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
discoveryStarted(startedAt: Date) {
|
||||||
|
console.log('Discovery Started at: ' + startedAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
discoveryStopped(stoppedAt: Date) {
|
||||||
|
console.log('Discovery Stopped at: ' + stoppedAt);
|
||||||
|
this.saveDiscoveredInfras();
|
||||||
}
|
}
|
||||||
|
|
||||||
getExistTarget() {
|
getExistTarget() {
|
||||||
|
@ -89,11 +95,11 @@ export class SearchResultComponent implements OnInit, OnChanges {
|
||||||
).subscribe();
|
).subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
// ngOnChanges(changes: SimpleChanges): void {
|
||||||
if (changes['finished'] && changes['finished'].currentValue === true) {
|
// if (changes['finished'] && changes['finished'].currentValue === true) {
|
||||||
this.saveDiscoveredInfras();
|
// this.saveDiscoveredInfras();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
displayInform() {
|
displayInform() {
|
||||||
this.msgs = [];
|
this.msgs = [];
|
||||||
|
@ -107,9 +113,9 @@ export class SearchResultComponent implements OnInit, OnChanges {
|
||||||
this.hostNode = [];
|
this.hostNode = [];
|
||||||
for (const infra of this.infras) {
|
for (const infra of this.infras) {
|
||||||
switch (infra.metaInfraType) {
|
switch (infra.metaInfraType) {
|
||||||
case toMetaInfraType(MetaInfraTypeEnum.ZONE):
|
// case toMetaInfraType(MetaInfraTypeEnum.ZONE):
|
||||||
const infraZone: InfraZone = infra;
|
// const infraZone: InfraZone = infra;
|
||||||
break;
|
// break;
|
||||||
case toMetaInfraType(MetaInfraTypeEnum.HOST):
|
case toMetaInfraType(MetaInfraTypeEnum.HOST):
|
||||||
const infraHost: InfraHost = infra;
|
const infraHost: InfraHost = infra;
|
||||||
this.addInfraHost(infraHost);
|
this.addInfraHost(infraHost);
|
||||||
|
|
35
@overflow/discovery/component2/animation.ts
Normal file
35
@overflow/discovery/component2/animation.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { trigger, state, transition, style, animate, query, stagger, keyframes } from '@angular/animations';
|
||||||
|
|
||||||
|
export const Anim = [
|
||||||
|
trigger('discoveryFilterAnim', [
|
||||||
|
transition('void => *', [
|
||||||
|
query('*', style({ opacity: 0 }), { optional: true }),
|
||||||
|
query('*', stagger('3ms', [
|
||||||
|
animate('0.08s ease-in', keyframes([
|
||||||
|
style({ opacity: 0, transform: 'translateY(-75%)', offset: 0 }),
|
||||||
|
style({ opacity: .5, transform: 'translateY(35px)', offset: 0.3 }),
|
||||||
|
style({ opacity: 1, transform: 'translateY(0)', offset: 1.0 }),
|
||||||
|
]))]), { optional: true }),
|
||||||
|
]),
|
||||||
|
// transition('* => void', [
|
||||||
|
// query('*', style({ opacity: 1 }), { optional: true }),
|
||||||
|
// query('*', stagger('5ms', [
|
||||||
|
// animate('0.08s ease-in', keyframes([
|
||||||
|
// style({ opacity: 1, transform: 'translateY(0)', offset: 0 }),
|
||||||
|
// style({ opacity: .5, transform: 'translateY(35px)', offset: 0.3 }),
|
||||||
|
// style({ opacity: 0, transform: 'translateY(-75%)', offset: 1.0 }),
|
||||||
|
// ]))]), { optional: true }),
|
||||||
|
// ])
|
||||||
|
]),
|
||||||
|
trigger('discoveryResultAnim', [
|
||||||
|
transition('void => *', [
|
||||||
|
query('*', style({ opacity: 0 }), { optional: true }),
|
||||||
|
query('*', stagger('30ms', [
|
||||||
|
animate('0.08s ease-in', keyframes([
|
||||||
|
style({ opacity: 0, transform: 'translateX(-95%)', offset: 0 }),
|
||||||
|
style({ opacity: .5, transform: 'translateX(95px)', offset: 0.3 }),
|
||||||
|
style({ opacity: 1, transform: 'translateX(0)', offset: 1.0 }),
|
||||||
|
]))]), { optional: true }),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
];
|
34
@overflow/discovery/component2/discovery.component.html
Normal file
34
@overflow/discovery/component2/discovery.component.html
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<h1>Discovery</h1>
|
||||||
|
<div class="ui-g">
|
||||||
|
<div class="ui-g-12">
|
||||||
|
<of-probe-selector [probeHostID]="probeHostID" (select)="selectedProbe=$event"></of-probe-selector>
|
||||||
|
<of-probe-summary *ngIf="selectedProbe" @discoveryFilterAnim [probeHost]="selectedProbe"></of-probe-summary>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g">
|
||||||
|
<div class="ui-g-12 ui-md-3">
|
||||||
|
<p-accordion [multiple]="true">
|
||||||
|
<p-accordionTab header="Discovery Settings" [selected]="true">
|
||||||
|
<span *ngIf="!selectedProbe">Choose a Probe to perform Discovery.</span>
|
||||||
|
<of-discovery-search-config *ngIf="!requested && selectedProbe" @discoveryFilterAnim [probeHost]="selectedProbe" (requestDiscovery)="onRequestDiscovery($event)"></of-discovery-search-config>
|
||||||
|
<of-discovery-request-summary *ngIf="discoverZone" @discoveryFilterAnim [discoverZone]="discoverZone"></of-discovery-request-summary>
|
||||||
|
</p-accordionTab>
|
||||||
|
<p-accordionTab header="Filter" [selected]="requested" [disabled]="!requested">
|
||||||
|
<of-discovery-search-filter #discoveryFilter (search)="filterWord=$event" (serviceSelect)="filterServices=$event"></of-discovery-search-filter>
|
||||||
|
</p-accordionTab>
|
||||||
|
</p-accordion>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui-g-12 ui-md-9">
|
||||||
|
<!-- <button class="ui-button-danger ui-button-width-fit" type="button" label="Stop" icon="ui-icon-close" pButton (click)="onRequestStop()"></button> -->
|
||||||
|
<of-discovery-result #discoveryResult *ngIf="requested else info" [probeHost]="selectedProbe" [filterWord]="filterWord" [filterServices]="filterServices"></of-discovery-result>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #info>
|
||||||
|
<p-panel [showHeader]="false">
|
||||||
|
<div style="min-height: 98px">
|
||||||
|
Network Discovery 설명 페이지
|
||||||
|
</div>
|
||||||
|
</p-panel>
|
||||||
|
</ng-template>
|
121
@overflow/discovery/component2/discovery.component.ts
Normal file
121
@overflow/discovery/component2/discovery.component.ts
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
import {
|
||||||
|
Component, Input, OnDestroy, ViewChild,
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
import { Observable, of, Subscription } from 'rxjs';
|
||||||
|
import { catchError, map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { ProbeHost } from '@overflow/commons-typescript/model/probe';
|
||||||
|
import { DiscoverZone, Zone, Host, Port, Service } from '@overflow/commons-typescript/model/discovery';
|
||||||
|
|
||||||
|
import { Anim } from './animation';
|
||||||
|
import { DiscoveryService } from '../service/discovery.service';
|
||||||
|
import { DiscoverySubscriber, DiscoveryNotify } from '../subscriber/discovery.subscriber';
|
||||||
|
import { SearchResultComponent } from './search-result.component';
|
||||||
|
import { SearchFilterComponent } from './search-filter.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'of-discovery',
|
||||||
|
templateUrl: './discovery.component.html',
|
||||||
|
animations: Anim,
|
||||||
|
})
|
||||||
|
export class DiscoveryComponent implements OnDestroy {
|
||||||
|
|
||||||
|
@Input() probeHostID;
|
||||||
|
pending$: Observable<boolean>;
|
||||||
|
error$: Observable<any>;
|
||||||
|
discoverySubscription: Subscription;
|
||||||
|
|
||||||
|
selectedProbe: ProbeHost;
|
||||||
|
requested: boolean;
|
||||||
|
discoverZone: DiscoverZone;
|
||||||
|
|
||||||
|
filterWord: string;
|
||||||
|
filterServices: Service[];
|
||||||
|
|
||||||
|
startDate: Date;
|
||||||
|
stopDate: Date;
|
||||||
|
|
||||||
|
@ViewChild('discoveryResult') discoveryResult: SearchResultComponent;
|
||||||
|
@ViewChild('discoveryFilter') discoveryFilter: SearchFilterComponent;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private discoveryService: DiscoveryService,
|
||||||
|
private discoverySubscriber: DiscoverySubscriber,
|
||||||
|
) {
|
||||||
|
this.discoverySubscription = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (null !== this.discoverySubscription) {
|
||||||
|
this.discoverySubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onRequestDiscovery(dz: DiscoverZone) {
|
||||||
|
this.requested = true;
|
||||||
|
this.discoverZone = dz;
|
||||||
|
|
||||||
|
const zone: Zone = {
|
||||||
|
network: this.selectedProbe.infraHost.infraZone.network, // this.selectedProbe.probe.cidr
|
||||||
|
address: this.selectedProbe.infraHost.infraZone.address.split('/')[0],
|
||||||
|
iface: this.selectedProbe.infraHost.infraZone.iface,
|
||||||
|
mac: this.selectedProbe.infraHost.infraZone.mac,
|
||||||
|
metaIPType: this.selectedProbe.infraHost.infraZone.metaIPType,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.discoveryService.discoverHost(this.selectedProbe.probe.probeKey, zone, dz.discoverHost);
|
||||||
|
|
||||||
|
this.discoverySubscription = this.discoverySubscriber.observable().pipe(
|
||||||
|
map((discoveryNotify: DiscoveryNotify) => {
|
||||||
|
switch (discoveryNotify.method) {
|
||||||
|
case 'DiscoveryService.discoveryStart': {
|
||||||
|
const startDate = discoveryNotify.params as Date;
|
||||||
|
this.discoveryResult.discoveryStarted(startDate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'DiscoveryService.discoveryStop': {
|
||||||
|
const stopDate = discoveryNotify.params as Date;
|
||||||
|
this.discoveryResult.discoveryStopped(stopDate);
|
||||||
|
this.discoverySubscription.unsubscribe();
|
||||||
|
this.discoverySubscription = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'DiscoveryService.discoveredZone': {
|
||||||
|
const _zone = discoveryNotify.params as Zone;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'DiscoveryService.discoveredHost': {
|
||||||
|
const host = discoveryNotify.params as Host;
|
||||||
|
this.discoveryResult.addHost(host);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'DiscoveryService.discoveredPort': {
|
||||||
|
const port = discoveryNotify.params as Port;
|
||||||
|
// this.discoveryResult.addPort(port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'DiscoveryService.discoveredService': {
|
||||||
|
const service = discoveryNotify.params as Service;
|
||||||
|
this.discoveryFilter.addService(service);
|
||||||
|
this.discoveryResult.addService(service);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
catchError(error => {
|
||||||
|
return of();
|
||||||
|
}),
|
||||||
|
).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
onRequestStop() {
|
||||||
|
this.discoverZone = null;
|
||||||
|
this.requested = false;
|
||||||
|
this.discoveryService.stopDiscovery(this.selectedProbe.probe.probeKey);
|
||||||
|
}
|
||||||
|
}
|
17
@overflow/discovery/component2/index.ts
Normal file
17
@overflow/discovery/component2/index.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { ServiceSelectorComponent } from './service-selector.component';
|
||||||
|
import { DiscoveryComponent } from './discovery.component';
|
||||||
|
import { SearchConfigComponent } from './search-config.component';
|
||||||
|
import { SearchFilterComponent } from './search-filter.component';
|
||||||
|
import { SearchResultComponent } from './search-result.component';
|
||||||
|
import { IpInputComponent } from './ip-input.component';
|
||||||
|
import { RequestSummaryComponent } from './request-summary.component';
|
||||||
|
|
||||||
|
export const COMPONENTS = [
|
||||||
|
ServiceSelectorComponent,
|
||||||
|
DiscoveryComponent,
|
||||||
|
SearchConfigComponent,
|
||||||
|
SearchFilterComponent,
|
||||||
|
SearchResultComponent,
|
||||||
|
IpInputComponent,
|
||||||
|
RequestSummaryComponent,
|
||||||
|
];
|
11
@overflow/discovery/component2/ip-input.component.html
Normal file
11
@overflow/discovery/component2/ip-input.component.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<div class="ui-inputgroup">
|
||||||
|
<span style="margin-right: 18px">{{title}} </span>
|
||||||
|
<input [disabled]="fixed >= 0"type="text" pInputText placeholder="127" maxlength="3" [(ngModel)]="first" value="{{first}}" (keyup)="onIpInput($event)">
|
||||||
|
<span class="ui-inputgroup-addon" style="min-width: 5px !important">.</span>
|
||||||
|
<input [disabled]="fixed > 1" type="text" pInputText placeholder="0" maxlength="3" [(ngModel)]="second" value="{{second}}" (keyup)="onIpInput($event)">
|
||||||
|
<span class="ui-inputgroup-addon" style="min-width: 5px !important">.</span>
|
||||||
|
<input [disabled]="fixed > 2" type="text" pInputText placeholder="0" maxlength="3" [(ngModel)]="third" value="{{third}}" (keyup)="onIpInput($event)">
|
||||||
|
<span class="ui-inputgroup-addon" style="min-width: 5px !important">.</span>
|
||||||
|
<input type="text" pInputText placeholder="1" maxlength="3" [(ngModel)]="fourth" value="{{fourth}}" (keyup)="onIpInput($event)">
|
||||||
|
</div>
|
||||||
|
|
57
@overflow/discovery/component2/ip-input.component.ts
Normal file
57
@overflow/discovery/component2/ip-input.component.ts
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import {
|
||||||
|
AfterContentInit,
|
||||||
|
Component,
|
||||||
|
EventEmitter,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
OnInit,
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'of-ip-input',
|
||||||
|
templateUrl: './ip-input.component.html',
|
||||||
|
})
|
||||||
|
export class IpInputComponent implements OnInit, AfterContentInit {
|
||||||
|
|
||||||
|
first: string;
|
||||||
|
second: string;
|
||||||
|
third: string;
|
||||||
|
fourth: string;
|
||||||
|
|
||||||
|
@Input() hostIp: string;
|
||||||
|
@Input() title: string;
|
||||||
|
@Input() fixed: number;
|
||||||
|
@Output() inputIp = new EventEmitter();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
if (this.hostIp !== '' && this.hostIp !== null && this.hostIp !== undefined) {
|
||||||
|
const tempIp = this.hostIp.split('.');
|
||||||
|
|
||||||
|
this.first = tempIp[0];
|
||||||
|
this.second = tempIp[1];
|
||||||
|
this.third = tempIp[2];
|
||||||
|
this.fourth = tempIp[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterContentInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onIpInput(event) {
|
||||||
|
if (
|
||||||
|
(this.first !== '' && this.first !== undefined) &&
|
||||||
|
(this.second !== '' && this.second !== undefined) &&
|
||||||
|
(this.third !== '' && this.third !== undefined) &&
|
||||||
|
(this.fourth !== '' && this.fourth !== undefined) ) {
|
||||||
|
event.value = this.first + '.' + this.second + '.' + this.third + '.' + this.fourth;
|
||||||
|
this.inputIp.emit(event);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
<div *ngIf="discoverZone" class="ui-key-value ui-left-info2">
|
||||||
|
<div class="ui-g">
|
||||||
|
<of-key-value [key]="'Host Range'" [value]="hostRange"></of-key-value>
|
||||||
|
<of-key-value [key]="'Port Range'" [value]="portRange"></of-key-value>
|
||||||
|
<div class="of-key-value-div">
|
||||||
|
<span>Port type</span>
|
||||||
|
<span class="ng-star-inserted ui-nopad">
|
||||||
|
<span *ngIf="discoverZone.discoverHost.discoverPort.includeTCP">TCP</span>
|
||||||
|
<span *ngIf="discoverZone.discoverHost.discoverPort.includeUDP">UDP</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div *ngIf="services && services.length > 0" class="ui-g-12 ui-top-border-1" style="text-align: right">
|
||||||
|
<p-overlayPanel #op>
|
||||||
|
<div *ngFor="let service of services">
|
||||||
|
{{service}}
|
||||||
|
</div>
|
||||||
|
</p-overlayPanel>
|
||||||
|
|
||||||
|
<a style="cursor: pointer" (click)="op.toggle($event)">{{services.length}} services has selected.</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
33
@overflow/discovery/component2/request-summary.component.ts
Normal file
33
@overflow/discovery/component2/request-summary.component.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import {
|
||||||
|
Component, Input, OnChanges, SimpleChanges,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { DiscoverZone } from '@overflow/commons-typescript/model/discovery';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'of-discovery-request-summary',
|
||||||
|
templateUrl: './request-summary.component.html',
|
||||||
|
})
|
||||||
|
export class RequestSummaryComponent implements OnChanges {
|
||||||
|
|
||||||
|
@Input() discoverZone: DiscoverZone;
|
||||||
|
hostRange: string;
|
||||||
|
hostExclude: string;
|
||||||
|
portRange: string;
|
||||||
|
portExclude: string;
|
||||||
|
services: string[];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
this.hostRange = this.discoverZone.discoverHost.firstScanRange
|
||||||
|
+ ' ~ '
|
||||||
|
+ this.discoverZone.discoverHost.lastScanRange;
|
||||||
|
this.portRange = this.discoverZone.discoverHost.discoverPort.firstScanRange
|
||||||
|
+ ' ~ '
|
||||||
|
+ this.discoverZone.discoverHost.discoverPort.lastScanRange;
|
||||||
|
this.services = this.discoverZone.discoverHost.discoverPort.discoverService.includeServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
106
@overflow/discovery/component2/search-config.component.html
Normal file
106
@overflow/discovery/component2/search-config.component.html
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
<div class="ui-g" *ngIf="probeHost">
|
||||||
|
<div>
|
||||||
|
<label>IP Version</label>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-bottom-space-20">
|
||||||
|
<div class="ui-g-6 ui-g-nopad">
|
||||||
|
<p-radioButton name="group1" value="V4" label="IPv4" [(ngModel)]="ipType"></p-radioButton>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-6 ui-g-nopad">
|
||||||
|
<p-radioButton [disabled]="!SUPPORT_V6" name="group1" value="V6" label="IPv6" [(ngModel)]="ipVer"></p-radioButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="ipVer === 'v4' else V6" class="ui-g-12">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<p-checkbox value="host" label="Host" [(ngModel)]="hostChecked" binary="true" [disabled]="true"></p-checkbox>
|
||||||
|
</div>
|
||||||
|
<label>Range</label>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12">
|
||||||
|
<of-ip-input [hostIp]="startIP" (inputIp)="onInputIP($event, 0)" [title]="'From'" [fixed]="fixedIPrange"></of-ip-input>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12">
|
||||||
|
<of-ip-input [hostIp]="endIP" (inputIp)="onInputIP($event, 1)" [title]="'To'" [fixed]="fixedIPrange"></of-ip-input>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12">
|
||||||
|
<p-multiSelect (onFocus)="onIPExcludeFocus()" [options]="ipArray" optionLabel="ip" [(ngModel)]="excludeIPs" [panelStyle]="{minWidth:'12em'}"
|
||||||
|
selectedItemsLabel="{0} hosts are excluded." maxSelectedLabels="2" defaultLabel="Add exclude IP"></p-multiSelect>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="ipErrMsg" class="ui-message ui-messages-error ui-corner-all">
|
||||||
|
{{ipErrMsg}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #V6>
|
||||||
|
<!-- TODO -->
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<div class="ui-g-12">
|
||||||
|
<div>
|
||||||
|
<p-checkbox #portCheckbox value="port" label="Port" [(ngModel)]="portChecked" binary="true" (onChange)="onPortCheckChange(serviceCheckbox, $event)"></p-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-bottom-space-20">
|
||||||
|
<div class="ui-g-6 ui-g-nopad">
|
||||||
|
TCP
|
||||||
|
<p-inputSwitch [(ngModel)]="tcpChecked" [disabled]="!portChecked" binary="true" (onChange)="onPortTypeCheck(portCheckbox, serviceCheckbox)"></p-inputSwitch>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-6 ui-g-nopad">
|
||||||
|
UDP
|
||||||
|
<p-inputSwitch [(ngModel)]="udpChecked" [disabled]="!portChecked" binary="true" (onChange)="onPortTypeCheck(portCheckbox, serviceCheckbox)"></p-inputSwitch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui-g-12">
|
||||||
|
<label>Range</label>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-g-nopad ui-bottom-space-20">
|
||||||
|
<div class="ui-g-6">
|
||||||
|
<input #startPort id="float-input" type="number" maxlength="5" min="1" max="65535" pInputText [disabled]="!portChecked" value="1"
|
||||||
|
(keyup)="onInputPort(startPort.value, 0)">
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-6">
|
||||||
|
<input #endPort id="float-input" type="number" maxlength="5" min="1" max="65535" pInputText [disabled]="!portChecked" value="1024"
|
||||||
|
(keyup)="onInputPort(endPort.value, 1)">
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-g-nopad" style="margin-left: 0.5em">
|
||||||
|
<a style="cursor: pointer" (click)="portExcludeDisplay = true">
|
||||||
|
<span *ngIf="excludePorts.length === 0">Add Exclude Ports</span>
|
||||||
|
<span *ngIf="excludePorts.length > 0">{{excludePorts.length}} ports are excluded.</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="portErrMsg" class="ui-message ui-messages-error ui-corner-all">
|
||||||
|
{{portErrMsg}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui-g-12">
|
||||||
|
<div>
|
||||||
|
<p-checkbox #serviceCheckbox value="service" label="Service" [(ngModel)]="serviceChecked" (onChange)="onServiceCheckChange(portCheckbox, $event)"
|
||||||
|
binary="true"></p-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui-g-12 ui-g-nopad">
|
||||||
|
<of-service-selector [disabled]="!serviceChecked" (change)="includeServices = $event"></of-service-selector>
|
||||||
|
<!-- <of-meta-service-type-selector [disabled]="!serviceChecked" (change)="includeServices = $event"></of-meta-service-type-selector> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui-g-12" dir="rtl">
|
||||||
|
<button type="submit" [disabled]="!validation" label="Discovery Start" pButton class="ui-button-width-fit" (click)="onRequestDiscovery()"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p-dialog [(visible)]="portExcludeDisplay" [modal]="true" [responsive]="true" [width]="400">
|
||||||
|
<p-header>
|
||||||
|
Add Ports to exclude.
|
||||||
|
</p-header>
|
||||||
|
<p-chips [(ngModel)]="portChips" [addOnTab]="true" [allowDuplicate]="false" (onAdd)="onAddExcludePort($event)" (onRemove)="onRemoveExcludePort($event)"
|
||||||
|
[max]="20" placeholder="e.g. 1025~65535"></p-chips>
|
||||||
|
<p-footer>
|
||||||
|
<button type="button" pButton icon="fa-check" (click)="portExcludeDisplay=false" label="Done"></button>
|
||||||
|
</p-footer>
|
||||||
|
</p-dialog>
|
311
@overflow/discovery/component2/search-config.component.ts
Normal file
311
@overflow/discovery/component2/search-config.component.ts
Normal file
|
@ -0,0 +1,311 @@
|
||||||
|
import {
|
||||||
|
Component, EventEmitter, Input,
|
||||||
|
Output, OnChanges, SimpleChanges
|
||||||
|
} from '@angular/core';
|
||||||
|
import { ProbeHost } from '@overflow/commons-typescript/model/probe';
|
||||||
|
import * as CIDR from 'ip-cidr';
|
||||||
|
import * as ipRangeCheck from 'ip-range-check';
|
||||||
|
import { DiscoverPort, DiscoverService, DiscoverZone } from '@overflow/commons-typescript/model/discovery';
|
||||||
|
import { Checkbox } from 'primeng/primeng';
|
||||||
|
import { MetaIPTypeEnum, toMetaIPType } from '@overflow/commons-typescript/model/meta';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'of-discovery-search-config',
|
||||||
|
templateUrl: './search-config.component.html',
|
||||||
|
})
|
||||||
|
export class SearchConfigComponent implements OnChanges {
|
||||||
|
|
||||||
|
SUPPORT_V6 = false;
|
||||||
|
|
||||||
|
@Input() probeHost: ProbeHost;
|
||||||
|
@Output() requestDiscovery = new EventEmitter<DiscoverZone>();
|
||||||
|
|
||||||
|
ipType: MetaIPTypeEnum;
|
||||||
|
startIP: string;
|
||||||
|
endIP: string;
|
||||||
|
startPort: string;
|
||||||
|
endPort: string;
|
||||||
|
excludeIPs = [];
|
||||||
|
excludePorts = [];
|
||||||
|
includeServices = [];
|
||||||
|
|
||||||
|
hostChecked = true;
|
||||||
|
portChecked = true;
|
||||||
|
serviceChecked = true;
|
||||||
|
tcpChecked = true;
|
||||||
|
udpChecked = true;
|
||||||
|
|
||||||
|
validation = false;
|
||||||
|
ipErrMsg: string;
|
||||||
|
portErrMsg: string;
|
||||||
|
|
||||||
|
fixedIPrange: number;
|
||||||
|
ipArray = [];
|
||||||
|
portExcludeDisplay = false;
|
||||||
|
portChips = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
if (changes['probeHost']) {
|
||||||
|
this.initByProbe();
|
||||||
|
}
|
||||||
|
this.validation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
initByProbe() {
|
||||||
|
const cidr = new CIDR(this.probeHost.probe.cidr);
|
||||||
|
if (!cidr.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.ipType = MetaIPTypeEnum.V4;
|
||||||
|
this.startIP = cidr.start();
|
||||||
|
this.endIP = cidr.end();
|
||||||
|
this.startPort = '1';
|
||||||
|
this.endPort = '1024';
|
||||||
|
// TODO: Initialize services
|
||||||
|
|
||||||
|
this.checkEditableIPrange(cidr);
|
||||||
|
}
|
||||||
|
|
||||||
|
onIPExcludeFocus() {
|
||||||
|
const cidr = new CIDR(this.probeHost.probe.cidr);
|
||||||
|
this.ipArray = cidr.toArray().filter((value) => {
|
||||||
|
return this.inRange(value) || this.excludeIPs.find(obj => obj.ip === value);
|
||||||
|
}).map(value => {
|
||||||
|
return { ip: value };
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inRange(value) {
|
||||||
|
const min = this.startIP;
|
||||||
|
const max = this.endIP;
|
||||||
|
if (this.ipToNum(min) <= this.ipToNum(value) && this.ipToNum(max) >= this.ipToNum(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ipToNum(ip) {
|
||||||
|
return Number(
|
||||||
|
ip.split('.')
|
||||||
|
.map(d => ('000' + d).substr(-3))
|
||||||
|
.join('')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRequestDiscovery() {
|
||||||
|
let discoverPort: DiscoverPort = null;
|
||||||
|
let discoverService: DiscoverService = null;
|
||||||
|
|
||||||
|
if (this.serviceChecked) {
|
||||||
|
const services = [];
|
||||||
|
for (const service of this.includeServices) {
|
||||||
|
services.push(service.key);
|
||||||
|
}
|
||||||
|
discoverService = {
|
||||||
|
includeServices: services,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (this.portChecked) {
|
||||||
|
discoverPort = {
|
||||||
|
firstScanRange: Number(this.startPort),
|
||||||
|
lastScanRange: Number(this.endPort),
|
||||||
|
includeTCP: this.tcpChecked,
|
||||||
|
includeUDP: this.udpChecked,
|
||||||
|
excludePorts: this.excludePorts,
|
||||||
|
discoverService: discoverService
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const discoverZone: DiscoverZone = {
|
||||||
|
discoverHost: {
|
||||||
|
metaIPType: toMetaIPType(this.ipType),
|
||||||
|
firstScanRange: this.startIP,
|
||||||
|
lastScanRange: this.endIP,
|
||||||
|
discoverPort: discoverPort,
|
||||||
|
excludeHosts: this.excludeIPs,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(discoverZone);
|
||||||
|
this.requestDiscovery.emit(discoverZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEditableIPrange(cidr) {
|
||||||
|
const startIPArray = cidr.addressStart.parsedAddress;
|
||||||
|
const endIPArray = cidr.addressEnd.parsedAddress;
|
||||||
|
let count = 0;
|
||||||
|
endIPArray.forEach((element, idx) => {
|
||||||
|
if (element === startIPArray[idx]) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.fixedIPrange = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
onPortCheckChange(serviceCheckbox: Checkbox, checked: boolean) {
|
||||||
|
if (!checked) {
|
||||||
|
serviceCheckbox.checked = false;
|
||||||
|
this.serviceChecked = false;
|
||||||
|
} else {
|
||||||
|
if (!this.tcpChecked && !this.udpChecked) {
|
||||||
|
this.tcpChecked = true;
|
||||||
|
this.udpChecked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onServiceCheckChange(portCheckbox: Checkbox, checked: boolean) {
|
||||||
|
if (checked) {
|
||||||
|
portCheckbox.checked = true;
|
||||||
|
this.portChecked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPortTypeCheck(portCheckbox: Checkbox, serviceCheckbox: Checkbox): void {
|
||||||
|
if (!this.tcpChecked && !this.udpChecked) {
|
||||||
|
this.portChecked = false;
|
||||||
|
portCheckbox.checked = false;
|
||||||
|
this.serviceChecked = false;
|
||||||
|
serviceCheckbox.checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onInputIP(e, idx: number) {
|
||||||
|
const value = e.value;
|
||||||
|
if (idx === 0) {
|
||||||
|
this.startIP = value;
|
||||||
|
} else {
|
||||||
|
this.endIP = value;
|
||||||
|
}
|
||||||
|
this.ipErrMsg = this.validateIP(value, idx);
|
||||||
|
|
||||||
|
if (this.ipErrMsg) {
|
||||||
|
this.validation = false;
|
||||||
|
} else {
|
||||||
|
this.validation = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validateIP(value: string, idx): string {
|
||||||
|
if (!this.isValidIPregex(value)) {
|
||||||
|
return 'Not valid IP format.';
|
||||||
|
}
|
||||||
|
if (!ipRangeCheck(value, this.probeHost.probe.cidr)) {
|
||||||
|
return 'Not valid IP range.';
|
||||||
|
}
|
||||||
|
const ipArray = [this.startIP, this.endIP];
|
||||||
|
const sortedIpArray = this.sortIP([this.startIP, this.endIP]);
|
||||||
|
if (ipArray[0] !== sortedIpArray[0]) {
|
||||||
|
return 'Not valiad range';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
isValidIPregex(ip: string): boolean {
|
||||||
|
if (this.ipType === MetaIPTypeEnum.V4) {
|
||||||
|
return /^(?=\d+\.\d+\.\d+\.\d+$)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.?){4}$/.test(ip);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sortIP(ipAddressArray) {
|
||||||
|
return ipAddressArray.sort((a, b) => {
|
||||||
|
a = a.split('.');
|
||||||
|
b = b.split('.');
|
||||||
|
for (let i = 0; i < a.length; i++) {
|
||||||
|
// tslint:disable-next-line:radix
|
||||||
|
if ((a[i] = parseInt(a[i])) < (b[i] = parseInt(b[i]))) {
|
||||||
|
return -1;
|
||||||
|
} else if (a[i] > b[i]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onInputPort(portNum: string, idx: number) {
|
||||||
|
if (idx === 0) {
|
||||||
|
this.startPort = portNum;
|
||||||
|
} else {
|
||||||
|
this.endPort = portNum;
|
||||||
|
}
|
||||||
|
this.portErrMsg = this.validatePort(portNum);
|
||||||
|
|
||||||
|
if (this.portErrMsg) {
|
||||||
|
this.validation = false;
|
||||||
|
} else {
|
||||||
|
this.validation = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validatePort(portNum): string {
|
||||||
|
if (Number(this.startPort) > Number(this.endPort)) {
|
||||||
|
return 'Not valid port range.';
|
||||||
|
}
|
||||||
|
if (Number(portNum) <= 0 || Number(portNum) > 65535) {
|
||||||
|
return 'Not valid port range.';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onAddExcludePort(event) {
|
||||||
|
const port = event.value.replace(/\s/g, '');
|
||||||
|
if (port.indexOf('~') > 0) { // e.g. 1~3000
|
||||||
|
const splited = port.split('~');
|
||||||
|
this.portChips.pop();
|
||||||
|
const from = Number(splited[0]);
|
||||||
|
const to = Number(splited[1]);
|
||||||
|
if (this.checkInvalidPort(from)
|
||||||
|
|| this.checkInvalidPort(to)
|
||||||
|
|| !Number.isInteger(from)
|
||||||
|
|| !Number.isInteger(to)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const chipItem = 'All ' + from + ' ~ ' + to;
|
||||||
|
this.portChips.push(chipItem);
|
||||||
|
for (let i = from; i <= to; i++) {
|
||||||
|
this.excludePorts.push(String(i));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const num = Number(event.value);
|
||||||
|
if (!Number.isInteger(num) || this.checkInvalidPort(num) || this.checkExistExcludePort(event.value)) {
|
||||||
|
this.portChips.pop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.excludePorts.push(event.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemoveExcludePort(event) {
|
||||||
|
if (event.value.indexOf('~') > 0) {
|
||||||
|
// e.g. 'All 1 ~ 30'
|
||||||
|
const splited = event.value.replace(/\s/g, '').replace('All', '').split('~');
|
||||||
|
for (let i = Number(splited[0]); i <= Number(splited[1]); i++) {
|
||||||
|
console.log(String(i));
|
||||||
|
const index = this.excludePorts.indexOf(String(i));
|
||||||
|
this.excludePorts.splice(index, 1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const idx = this.excludePorts.indexOf(event.value);
|
||||||
|
this.excludePorts.splice(idx, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkExistExcludePort(portNum) {
|
||||||
|
return this.excludePorts.find((value) => {
|
||||||
|
return value === portNum;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checkInvalidPort(port) {
|
||||||
|
return port <= 0 || port > 65535;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
@overflow/discovery/component2/search-filter.component.html
Normal file
15
@overflow/discovery/component2/search-filter.component.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="ui-g">
|
||||||
|
<input type="text" pInputText placeholder="Search..." [(ngModel)]="filterWord" (keyup)="onSearch($event)">
|
||||||
|
|
||||||
|
<div class="ui-g">
|
||||||
|
<div *ngFor="let service of services">
|
||||||
|
<p-toggleButton offLabel="{{service.name}}" onLabel="{{service.name}}" [style]="{'width':'100px'}" (onChange)="onServiceFilter($event, service)"
|
||||||
|
[(ngModel)]="filterServices[service.serviceName]"></p-toggleButton>
|
||||||
|
|
||||||
|
<!-- <p-checkbox [(ngModel)]="filterServices" label="{{service.serviceName}}" value="{{service.serviceName}}"></p-checkbox> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
68
@overflow/discovery/component2/search-filter.component.ts
Normal file
68
@overflow/discovery/component2/search-filter.component.ts
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
Output,
|
||||||
|
EventEmitter
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Anim } from './animation';
|
||||||
|
import { Service } from '@overflow/commons-typescript/model/discovery';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'of-discovery-search-filter',
|
||||||
|
templateUrl: './search-filter.component.html',
|
||||||
|
animations: Anim
|
||||||
|
})
|
||||||
|
export class SearchFilterComponent implements OnInit {
|
||||||
|
|
||||||
|
services: Service[] = [];
|
||||||
|
filterWord: string;
|
||||||
|
filterServices = new Map<string, boolean>();
|
||||||
|
|
||||||
|
@Output() search = new EventEmitter<string>();
|
||||||
|
@Output() serviceSelect = new EventEmitter<Map<string, boolean>>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearch(e) {
|
||||||
|
if (e.key !== 'Enter') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.search.emit(this.filterWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
addService(service: Service) {
|
||||||
|
if (service.name.indexOf('Not Supported Service') >= 0) {
|
||||||
|
const tempName = service.name.split('Perhaps ')[1].split('[')[0];
|
||||||
|
service.name = '*' + tempName;
|
||||||
|
}
|
||||||
|
let exist = false;
|
||||||
|
this.services.forEach(value => {
|
||||||
|
if (value.name === service.name) {
|
||||||
|
exist = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!exist) {
|
||||||
|
this.services.push(service);
|
||||||
|
this.filterServices[service.name] = true;
|
||||||
|
}
|
||||||
|
this.serviceSelect.emit(this.filterServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
onServiceFilter(e, service: Service) {
|
||||||
|
// if (e.checked) {
|
||||||
|
// this.filterServices.push(service);
|
||||||
|
// } else {
|
||||||
|
// const index = this.filterServices.indexOf(service);
|
||||||
|
// this.filterServices.splice(index, 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
this.serviceSelect.emit(this.filterServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
61
@overflow/discovery/component2/search-result.component.html
Normal file
61
@overflow/discovery/component2/search-result.component.html
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<of-block-progressbar [target]="content" [pending]="!finished"></of-block-progressbar>
|
||||||
|
|
||||||
|
<p-panel #content [showHeader]="false" class="block-panel">
|
||||||
|
|
||||||
|
<p-messages [(value)]="msgs"></p-messages>
|
||||||
|
|
||||||
|
<p-tree [value]="zoneNode" layout="vertical">
|
||||||
|
<!-- ZONE node template -->
|
||||||
|
<ng-template let-node pTemplate="ZONE">
|
||||||
|
<div>
|
||||||
|
{{node.label}}
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<!-- HOST node template -->
|
||||||
|
<ng-template let-node pTemplate="HOST">
|
||||||
|
<div @discoveryResultAnim>
|
||||||
|
<div *ngIf="checkHighlight(node.label, 0) else unhighlightHost">
|
||||||
|
<p-toggleButton [disabled]="checkExistTarget(node.data.target)" onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check"
|
||||||
|
offIcon="fa-square" [style]="{'width':'200px'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #unhighlightHost>
|
||||||
|
<p-toggleButton [disabled]="checkExistTarget(node.data.target)" onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check"
|
||||||
|
offIcon="fa-square" [style]="{'width':'200px', 'opacity': '0.2'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton>
|
||||||
|
</ng-template>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<!-- SERVICE node template -->
|
||||||
|
<ng-template let-node pTemplate="SERVICE">
|
||||||
|
<div @discoveryResultAnim>
|
||||||
|
<div *ngIf="checkHighlight(node.data.name, 1) else unhighlightServ">
|
||||||
|
<p-toggleButton [disabled]="checkExistTarget(node.data.target)" onLabel="{{node.label}} {{node.data.portType}}" offLabel="{{node.label}} {{node.data.portType}} {{node.data.portNumber}}"
|
||||||
|
onIcon="fa-check" offIcon="fa-square" [style]="{'width':'300px'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #unhighlightServ>
|
||||||
|
<p-toggleButton [disabled]="checkExistTarget(node.data.target)" onLabel="{{node.label}} {{node.data.portType}}" offLabel="{{node.label}} {{node.data.portType}} {{node.data.portNumber}}"
|
||||||
|
onIcon="fa-check" offIcon="fa-square" [style]="{'width':'300px', 'opacity': '0.2'}" (onChange)="onTargetSelect($event, node)"></p-toggleButton>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</p-tree>
|
||||||
|
|
||||||
|
<button class="ui-button-width-fit ui-float-right ui-top-space-10" [disabled]="selectedItems.length === 0" type="button"
|
||||||
|
label="Save" icon="ui-icon-close" pButton (click)="saveTargets()"></button>
|
||||||
|
|
||||||
|
</p-panel>
|
||||||
|
|
||||||
|
|
||||||
|
<p-dialog header="Title" [(visible)]="targetSaved" [modal]="true" [responsive]="true" [width]="600" [minWidth]="200" [minY]="70"
|
||||||
|
[closeOnEscape]="false">
|
||||||
|
<span>Target 지정이 완료되었습니다. 이어서 Sensor를 등록하시면 좋겠다능</span>
|
||||||
|
<p-footer>
|
||||||
|
<button type="button" pButton label="메인으로"></button>
|
||||||
|
<button type="button" pButton label="Target으로"></button>
|
||||||
|
<button type="button" pButton label="InfraMap으로"></button>
|
||||||
|
</p-footer>
|
||||||
|
</p-dialog>
|
348
@overflow/discovery/component2/search-result.component.ts
Normal file
348
@overflow/discovery/component2/search-result.component.ts
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
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<string, boolean>;
|
||||||
|
|
||||||
|
infras: Infra[];
|
||||||
|
existTargets: Target[];
|
||||||
|
|
||||||
|
discoverySubscription: Subscription;
|
||||||
|
zoneNode: TreeNode[] = [];
|
||||||
|
hostNode: TreeNode[] = [];
|
||||||
|
selectedItems = [];
|
||||||
|
msgs: Message[];
|
||||||
|
error$: Observable<any>;
|
||||||
|
|
||||||
|
discoveredHosts: Host[] = [];
|
||||||
|
discoveredServices: Service[] = [];
|
||||||
|
infraSaved: boolean;
|
||||||
|
targetSaved: boolean;
|
||||||
|
|
||||||
|
pending$: Observable<boolean>;
|
||||||
|
|
||||||
|
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<Target>) => {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<div *ngIf="!disabled">
|
||||||
|
<of-error-message [error]="error$ | async" [closable]="false"></of-error-message>
|
||||||
|
<of-block-progressbar [target]="content" [pending]="pending$ | async"></of-block-progressbar>
|
||||||
|
<p-panel #content [showHeader]="false" class="block-panel">
|
||||||
|
<div class="ui-g" dir="rtl">
|
||||||
|
<button pButton type="button" class="ui-button-secondary ui-button-width-fit ui-s-button" label="Unselect All" style="margin-bottom: 3px;"
|
||||||
|
(click)="onUnselectAll()"></button>
|
||||||
|
<button pButton type="button" class="ui-button-secondary ui-button-width-fit ui-s-button" label="Select All" style="margin-bottom: 3px;"
|
||||||
|
(click)="onSelectAll()"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p-table selectionMode="multiple" [scrollable]="true" scrollHeight="200px" [value]="metaCrawlers" [(selection)]="includeServices"
|
||||||
|
dataKey="id" (onRowSelect)="onSelect($event.data)" (onRowUnselect)="onUnselect($event.data)">
|
||||||
|
<ng-template pTemplate="body" let-rowData let-columns="columns">
|
||||||
|
<tr [pSelectableRow]="rowData">
|
||||||
|
<!-- <td>
|
||||||
|
<p-tableCheckbox [value]="rowData"></p-tableCheckbox>
|
||||||
|
</td> -->
|
||||||
|
<td>
|
||||||
|
<p-tableCheckbox [value]="rowData"></p-tableCheckbox>
|
||||||
|
{{rowData.name}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
</p-panel>
|
||||||
|
</div>
|
90
@overflow/discovery/component2/service-selector.component.ts
Normal file
90
@overflow/discovery/component2/service-selector.component.ts
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
Input,
|
||||||
|
AfterContentInit,
|
||||||
|
Output,
|
||||||
|
EventEmitter,
|
||||||
|
OnDestroy
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Store, select, StateObservable } from '@ngrx/store';
|
||||||
|
import { Observable, of } from 'rxjs';
|
||||||
|
import { catchError, exhaustMap, map, tap, take } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { RPCClientError } from '@loafer/ng-rpc';
|
||||||
|
import { MetaCrawler } from '@overflow/commons-typescript/model/meta';
|
||||||
|
|
||||||
|
import { MetaCrawlerService } from '@overflow/meta/service/meta-crawler.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'of-service-selector',
|
||||||
|
templateUrl: './service-selector.component.html',
|
||||||
|
})
|
||||||
|
export class ServiceSelectorComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
|
includeServices: MetaCrawler[];
|
||||||
|
|
||||||
|
@Output() change = new EventEmitter<MetaCrawler[]>();
|
||||||
|
@Input() disabled: boolean;
|
||||||
|
|
||||||
|
metaCrawlers: MetaCrawler[];
|
||||||
|
pending$: Observable<boolean>;
|
||||||
|
error$: Observable<any>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected store: Store<any>,
|
||||||
|
protected metaCrawlerService: MetaCrawlerService,
|
||||||
|
) {
|
||||||
|
this.includeServices = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.metaCrawlerService.readAll()
|
||||||
|
.pipe(
|
||||||
|
tap(() => {
|
||||||
|
this.pending$ = of(true);
|
||||||
|
}),
|
||||||
|
map((metaCrawlers: MetaCrawler[]) => {
|
||||||
|
this.metaCrawlers = metaCrawlers;
|
||||||
|
}),
|
||||||
|
catchError(error => {
|
||||||
|
this.error$ = of(error);
|
||||||
|
return of(null);
|
||||||
|
}),
|
||||||
|
tap(() => {
|
||||||
|
this.pending$ = of(false);
|
||||||
|
this.includeServices = this.metaCrawlers.slice();
|
||||||
|
this.change.emit(this.includeServices);
|
||||||
|
}),
|
||||||
|
take(1),
|
||||||
|
).subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterContentInit() {
|
||||||
|
// this.listStore.dispatch(new ListStore.ReadAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectAll() {
|
||||||
|
this.includeServices = [];
|
||||||
|
this.metaCrawlers.forEach((value) => {
|
||||||
|
this.includeServices.push(value);
|
||||||
|
});
|
||||||
|
this.change.emit(this.includeServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnselectAll() {
|
||||||
|
this.includeServices = [];
|
||||||
|
this.change.emit(this.includeServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelect(crawler: MetaCrawler) {
|
||||||
|
this.change.emit(this.includeServices);
|
||||||
|
}
|
||||||
|
onUnselect(crawler: MetaCrawler) {
|
||||||
|
this.change.emit(this.includeServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,10 +3,9 @@ import {
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { InfraService, InfraHost, InfraZone, Infra } from '@overflow/commons-typescript/model/infra';
|
import { InfraService, InfraHost, InfraZone, Infra } from '@overflow/commons-typescript/model/infra';
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { catchError, exhaustMap, map, tap, take } from 'rxjs/operators';
|
import { catchError, map, tap, take } from 'rxjs/operators';
|
||||||
import { TreeNode, MenuItem, ContextMenu } from 'primeng/primeng';
|
import { TreeNode, MenuItem, ContextMenu } from 'primeng/primeng';
|
||||||
import { PageParams, Page } from '@overflow/commons-typescript/core/model';
|
import { ProbeHost, MetaInfraTypeEnum, toMetaInfraType } from '@overflow/commons-typescript';
|
||||||
import { ProbeHost, MetaInfraTypeEnum } from '@overflow/commons-typescript';
|
|
||||||
import { InfraService as InfraManageService } from '../service/infra.service';
|
import { InfraService as InfraManageService } from '../service/infra.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -17,7 +16,10 @@ export class InfraTreeComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
@Input() probeHost: ProbeHost;
|
@Input() probeHost: ProbeHost;
|
||||||
|
|
||||||
infras: Infra[];
|
infraZones: InfraZone[];
|
||||||
|
infraHosts: InfraHost[];
|
||||||
|
infraServices: InfraService[];
|
||||||
|
|
||||||
pending$: Observable<boolean>;
|
pending$: Observable<boolean>;
|
||||||
error$: Observable<any>;
|
error$: Observable<any>;
|
||||||
|
|
||||||
|
@ -46,7 +48,11 @@ export class InfraTreeComponent implements OnInit, OnChanges {
|
||||||
this.contextMenuZone = [
|
this.contextMenuZone = [
|
||||||
{ label: 'Zone Menu', command: (event) => this.cmZone.hide() },
|
{ label: 'Zone Menu', command: (event) => this.cmZone.hide() },
|
||||||
{ separator: true },
|
{ separator: true },
|
||||||
{ label: 'Discovery', icon: 'fa-plus', command: (event) => alert('Discovery') },
|
{
|
||||||
|
label: 'Discovery', icon: 'fa-plus', command: (event) => {
|
||||||
|
alert('discovery');
|
||||||
|
}
|
||||||
|
},
|
||||||
];
|
];
|
||||||
this.contextMenuHost = [
|
this.contextMenuHost = [
|
||||||
{ label: 'Host Menu', command: (event) => this.cmHost.hide() },
|
{ label: 'Host Menu', command: (event) => this.cmHost.hide() },
|
||||||
|
@ -66,26 +72,36 @@ export class InfraTreeComponent implements OnInit, OnChanges {
|
||||||
if (changes['probeHost'].isFirstChange) {
|
if (changes['probeHost'].isFirstChange) {
|
||||||
this.zoneNode = [];
|
this.zoneNode = [];
|
||||||
this.hostNode = [];
|
this.hostNode = [];
|
||||||
this.getInfras();
|
this.getInfraWithInfraTypeKey(toMetaInfraType(MetaInfraTypeEnum.ZONE).key);
|
||||||
|
this.getInfraWithInfraTypeKey(toMetaInfraType(MetaInfraTypeEnum.HOST).key);
|
||||||
|
this.getInfraWithInfraTypeKey(toMetaInfraType(MetaInfraTypeEnum.SERVICE).key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getInfras() {
|
getInfraWithInfraTypeKey(metaInfraTypeKey: string) {
|
||||||
const pageParams: PageParams = {
|
this.infraService.readAllByMetaInfraTypeKeyAndProbeID(
|
||||||
pageNo: 0,
|
metaInfraTypeKey, this.probeHost.probe.id)
|
||||||
countPerPage: 99999,
|
|
||||||
sortCol: 'id',
|
|
||||||
sortDirection: 'descending'
|
|
||||||
};
|
|
||||||
this.infraService.readAllByProbeID(this.probeHost.probe.id, pageParams)
|
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(() => {
|
tap(() => {
|
||||||
this.pending$ = of(true);
|
this.pending$ = of(true);
|
||||||
}),
|
}),
|
||||||
map((infraPage: Page<Infra>) => {
|
map((infras: Infra[]) => {
|
||||||
this.infras = infraPage.content;
|
switch (metaInfraTypeKey) {
|
||||||
console.log(this.infras);
|
case toMetaInfraType(MetaInfraTypeEnum.ZONE).key:
|
||||||
this.generateTreeData(this.infras);
|
this.infraZones = infras;
|
||||||
|
break;
|
||||||
|
case toMetaInfraType(MetaInfraTypeEnum.HOST).key:
|
||||||
|
this.infraHosts = infras;
|
||||||
|
break;
|
||||||
|
case toMetaInfraType(MetaInfraTypeEnum.SERVICE).key:
|
||||||
|
this.infraServices = infras;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.infraZones && this.infraHosts && this.infraServices) {
|
||||||
|
this.generateTreeData();
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
catchError(error => {
|
catchError(error => {
|
||||||
this.error$ = of(error);
|
this.error$ = of(error);
|
||||||
|
@ -98,21 +114,24 @@ export class InfraTreeComponent implements OnInit, OnChanges {
|
||||||
).subscribe();
|
).subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
generateTreeData(infras: Infra[]) {
|
generateTreeData() {
|
||||||
infras.forEach(infra => {
|
if (null === this.infraZones) {
|
||||||
switch (infra.metaInfraType.key) {
|
return;
|
||||||
case MetaInfraTypeEnum.ZONE:
|
|
||||||
this.addZone(infra);
|
|
||||||
break;
|
|
||||||
case MetaInfraTypeEnum.HOST:
|
|
||||||
this.addHost(infra);
|
|
||||||
break;
|
|
||||||
case MetaInfraTypeEnum.HOST:
|
|
||||||
this.addService(infra);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
this.infraZones.forEach(infraZone => {
|
||||||
|
this.addZone(infraZone);
|
||||||
|
});
|
||||||
|
if (null === this.infraHosts) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.infraHosts.forEach(infraHost => {
|
||||||
|
this.addHost(infraHost);
|
||||||
|
});
|
||||||
|
if (null === this.infraServices) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.infraServices.forEach(infraService => {
|
||||||
|
this.addService(infraService);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,4 +48,9 @@ export class InfraService {
|
||||||
public readAllInfraZoneByProbeDomainID(probeDomainID: number): Observable<Infra[]> {
|
public readAllInfraZoneByProbeDomainID(probeDomainID: number): Observable<Infra[]> {
|
||||||
return this.rpcService.call<Infra[]>('InfraService.readAllInfraZoneByProbeDomainID', probeDomainID);
|
return this.rpcService.call<Infra[]>('InfraService.readAllInfraZoneByProbeDomainID', probeDomainID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readAllByMetaInfraTypeKeyAndProbeID(metaInfraTypeKey: string, probeID: number): Observable<Infra[]> {
|
||||||
|
return this.rpcService.call<Infra[]>('InfraService.readAllByMetaInfraTypeKeyAndProbeID', metaInfraTypeKey, probeID);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user