METRON-1548 Remove hardcoded source:type from Alerts UI (sardell via justinleet) closes apache/metron#1010
Project: http://git-wip-us.apache.org/repos/asf/metron/repo Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/a99cadb0 Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/a99cadb0 Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/a99cadb0 Branch: refs/heads/master Commit: a99cadb018b96cf96955df4b6e4acade28530a41 Parents: 4458085 Author: Shane Ardell <[email protected]> Authored: Mon May 7 13:19:42 2018 +0200 Committer: justinjleet <[email protected]> Committed: Fri May 18 13:32:29 2018 -0400 ---------------------------------------------------------------------- metron-interface/metron-alerts/README.md | 6 +++ .../alert-details/alert-details.component.ts | 2 +- .../alert-details/alerts-details.routing.ts | 2 +- .../alerts/alerts-list/alerts-list.component.ts | 25 ++++++++-- .../table-view/table-view.component.ts | 32 +++++++++++-- .../tree-view/tree-view.component.ts | 17 +++++-- .../alerts/meta-alerts/meta-alerts.component.ts | 20 ++++++-- .../metron-alerts/src/app/app.module.ts | 4 +- .../src/app/model/search-request.ts | 2 +- .../src/app/service/authentication.service.ts | 10 +++- .../service/elasticsearch-localstorage-impl.ts | 6 ++- .../src/app/service/global-config.service.ts | 50 ++++++++++++++++++++ .../src/app/service/update.service.ts | 10 +++- .../metron-alerts/src/app/utils/constants.ts | 4 +- .../metron-alerts/src/app/utils/utils.ts | 7 +-- metron-platform/metron-common/README.md | 15 +++--- 16 files changed, 174 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/README.md ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/README.md b/metron-interface/metron-alerts/README.md index 0cc2fba..2d34505 100644 --- a/metron-interface/metron-alerts/README.md +++ b/metron-interface/metron-alerts/README.md @@ -99,6 +99,12 @@ rest: port: REST applciation port ``` +## Global Configuration Properties + +### `source.type.field` + +The source type format used. Defaults to `source:type`. + ## Usage After configuration is complete, the Management UI can be managed as a service: http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts index 8335ad7..e1c1685 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts @@ -124,7 +124,7 @@ export class AlertDetailsComponent implements OnInit { ngOnInit() { this.activatedRoute.params.subscribe(params => { this.alertId = params['guid']; - this.alertSourceType = params['sourceType']; + this.alertSourceType = params['source.type.field']; this.alertIndex = params['index']; this.isMetaAlert = (this.alertIndex === META_ALERTS_INDEX && this.alertSourceType !== META_ALERTS_SENSOR_TYPE) ? true : false; this.getData(); http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/alerts/alert-details/alerts-details.routing.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alerts-details.routing.ts b/metron-interface/metron-alerts/src/app/alerts/alert-details/alerts-details.routing.ts index 0cb9c9c..c4080b8 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alerts-details.routing.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alerts-details.routing.ts @@ -20,5 +20,5 @@ import { RouterModule } from '@angular/router'; import {AlertDetailsComponent} from './alert-details.component'; export const routing: ModuleWithProviders = RouterModule.forChild([ - { path: 'details/:sourceType/:guid/:index', component: AlertDetailsComponent, outlet: 'dialog'} + { path: 'details/:source.type.field/:guid/:index', component: AlertDetailsComponent, outlet: 'dialog'} ]); http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts index 138606e..776a083 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts @@ -42,6 +42,7 @@ import {Pagination} from '../../model/pagination'; import {META_ALERTS_SENSOR_TYPE, META_ALERTS_INDEX} from '../../utils/constants'; import {MetaAlertService} from '../../service/meta-alert.service'; import {Facets} from '../../model/facets'; +import { GlobalConfigService } from '../../service/global-config.service'; @Component({ selector: 'app-alerts-list', @@ -75,6 +76,8 @@ export class AlertsListComponent implements OnInit, OnDestroy { pagination: Pagination = new Pagination(); alertChangedSubscription: Subscription; groupFacets: Facets; + globalConfig: {} = {}; + configSubscription: Subscription; constructor(private router: Router, private searchService: SearchService, @@ -84,7 +87,8 @@ export class AlertsListComponent implements OnInit, OnDestroy { private clusterMetaDataService: ClusterMetaDataService, private saveSearchService: SaveSearchService, private metronDialogBox: MetronDialogBox, - private metaAlertsService: MetaAlertService) { + private metaAlertsService: MetaAlertService, + private globalConfigService: GlobalConfigService) { router.events.subscribe(event => { if (event instanceof NavigationStart && event.url === '/alerts-list') { this.selectedAlerts = []; @@ -171,9 +175,20 @@ export class AlertsListComponent implements OnInit, OnDestroy { ngOnDestroy() { this.tryStopPolling(); this.removeAlertChangedListner(); + this.configSubscription.unsubscribe(); } ngOnInit() { + this.configSubscription = this.globalConfigService.get().subscribe((config: {}) => { + this.globalConfig = config; + if (this.globalConfig['source.type.field']) { + let filteredAlertsColumns = this.alertsColumns.filter(colName => colName.name !== 'source:type'); + if (filteredAlertsColumns.length < this.alertsColumns.length) { + this.alertsColumns = filteredAlertsColumns; + this.alertsColumns.splice(2, 0, new ColumnMetadata(this.globalConfig['source.type.field'], 'string')); + } + } + }); this.getAlertColumnNames(true); this.addAlertColChangedListner(); this.addLoadSavedSearchListner(); @@ -367,8 +382,8 @@ export class AlertsListComponent implements OnInit, OnDestroy { private createGroupFacets(results: SearchResponse) { this.groupFacets = JSON.parse(JSON.stringify(results.facetCounts)); - if (this.groupFacets['source:type']) { - delete this.groupFacets['source:type']['metaalert']; + if (this.groupFacets[this.globalConfig['source.type.field']]) { + delete this.groupFacets[this.globalConfig['source.type.field']]['metaalert']; } } @@ -381,8 +396,8 @@ export class AlertsListComponent implements OnInit, OnDestroy { this.selectedAlerts = []; this.selectedAlerts = [alert]; this.saveRefreshState(); - let sourceType = (alert.index === META_ALERTS_INDEX && !alert.source['source:type']) - ? META_ALERTS_SENSOR_TYPE : alert.source['source:type']; + let sourceType = (alert.index === META_ALERTS_INDEX && !alert.source[this.globalConfig['source.type.field']]) + ? META_ALERTS_SENSOR_TYPE : alert.source[this.globalConfig['source.type.field']]; let url = '/alerts-list(dialog:details/' + sourceType + '/' + alert.source.guid + '/' + alert.index + ')'; this.router.navigateByUrl(url); } http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts index 91489b8..0176ff0 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/table-view/table-view.component.ts @@ -16,8 +16,9 @@ * limitations under the License. */ -import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core'; +import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, OnInit, OnDestroy } from '@angular/core'; import {Router} from '@angular/router'; +import { Subscription } from 'rxjs/Rx'; import {Pagination} from '../../../model/pagination'; import {SortEvent} from '../../../shared/metron-table/metron-table.directive'; @@ -36,6 +37,7 @@ import {META_ALERTS_INDEX} from '../../../utils/constants'; import {MetaAlertService} from '../../../service/meta-alert.service'; import {MetaAlertAddRemoveRequest} from '../../../model/meta-alert-add-remove-request'; import {GetRequest} from '../../../model/get-request'; +import { GlobalConfigService } from '../../../service/global-config.service'; export enum MetronAlertDisplayState { COLLAPSE, EXPAND @@ -47,7 +49,7 @@ export enum MetronAlertDisplayState { styleUrls: ['./table-view.component.scss'] }) -export class TableViewComponent implements OnChanges { +export class TableViewComponent implements OnInit, OnChanges, OnDestroy { threatScoreFieldName = 'threat:triage:score'; @@ -59,6 +61,9 @@ export class TableViewComponent implements OnChanges { metaAlertService: MetaAlertService; metaAlertsDisplayState: {[key: string]: MetronAlertDisplayState} = {}; metronAlertDisplayState = MetronAlertDisplayState; + globalConfig: {} = {}; + globalConfigService: GlobalConfigService; + configSubscription: Subscription; @Input() alerts: Alert[] = []; @Input() queryBuilder: QueryBuilder; @@ -77,12 +82,27 @@ export class TableViewComponent implements OnChanges { searchService: SearchService, metronDialogBox: MetronDialogBox, updateService: UpdateService, - metaAlertService: MetaAlertService) { + metaAlertService: MetaAlertService, + globalConfigService: GlobalConfigService) { this.router = router; this.searchService = searchService; this.metronDialogBox = metronDialogBox; this.updateService = updateService; this.metaAlertService = metaAlertService; + this.globalConfigService = globalConfigService; + } + + ngOnInit() { + this.configSubscription = this.globalConfigService.get().subscribe((config: {}) => { + this.globalConfig = config; + if (this.globalConfig['source.type.field']) { + let filteredAlertsColumnsToDisplay = this.alertsColumnsToDisplay.filter(colName => colName.name !== 'source:type'); + if (filteredAlertsColumnsToDisplay.length < this.alertsColumnsToDisplay.length) { + this.alertsColumnsToDisplay = filteredAlertsColumnsToDisplay; + this.alertsColumnsToDisplay.splice(2, 0, new ColumnMetadata(this.globalConfig['source.type.field'], 'string')); + } + } + }); } ngOnChanges(changes: SimpleChanges) { @@ -96,6 +116,10 @@ export class TableViewComponent implements OnChanges { } } + ngOnDestroy() { + this.configSubscription.unsubscribe(); + } + updateExpandedStateForChangedData(expandedMetaAlerts: string[]) { this.alerts.forEach(alert => { if (alert.source.alert && alert.source.alert.length > 0) { @@ -249,7 +273,7 @@ export class TableViewComponent implements OnChanges { let alertToRemove = alert.source.alert[metaAlertIndex]; let metaAlertAddRemoveRequest = new MetaAlertAddRemoveRequest(); metaAlertAddRemoveRequest.metaAlertGuid = alert.source.guid; - metaAlertAddRemoveRequest.alerts = [new GetRequest(alertToRemove.guid, alertToRemove['source:type'], '')]; + metaAlertAddRemoveRequest.alerts = [new GetRequest(alertToRemove.guid, alertToRemove[this.globalConfig['source.type.field']], '')]; this.metaAlertService.removeAlertsFromMetaAlert(metaAlertAddRemoveRequest).subscribe(() => { }); http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts index bb2b174..7660783 100644 --- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/tree-view/tree-view.component.ts @@ -37,6 +37,7 @@ import {INDEXES, MAX_ALERTS_IN_META_ALERTS} from '../../../utils/constants'; import {UpdateService} from '../../../service/update.service'; import {PatchRequest} from '../../../model/patch-request'; import {GetRequest} from '../../../model/get-request'; +import { GlobalConfigService } from '../../../service/global-config.service'; @Component({ selector: 'app-tree-view', @@ -51,13 +52,16 @@ export class TreeViewComponent extends TableViewComponent implements OnInit, OnC groupResponse: GroupResponse = new GroupResponse(); treeGroupSubscriptionMap: {[key: string]: TreeAlertsSubscription } = {}; alertsChangedSubscription: Subscription; + globalConfig: {} = {}; + configSubscription: Subscription; constructor(router: Router, searchService: SearchService, metronDialogBox: MetronDialogBox, updateService: UpdateService, - metaAlertService: MetaAlertService) { - super(router, searchService, metronDialogBox, updateService, metaAlertService); + metaAlertService: MetaAlertService, + globalConfigService: GlobalConfigService) { + super(router, searchService, metronDialogBox, updateService, metaAlertService, globalConfigService); } addAlertChangedListner() { @@ -182,10 +186,14 @@ export class TreeViewComponent extends TableViewComponent implements OnInit, OnC ngOnInit() { this.addAlertChangedListner(); + this.configSubscription = this.globalConfigService.get().subscribe((config: {}) => { + this.globalConfig = config; + }); } ngOnDestroy(): void { this.removeAlertChangedLister(); + this.configSubscription.unsubscribe(); } searchGroup(selectedGroup: TreeGroupData, searchRequest: SearchRequest): Subscription { @@ -363,13 +371,14 @@ export class TreeViewComponent extends TableViewComponent implements OnInit, OnC } createGetRequestArray(searchResponse: SearchResponse): any { - return searchResponse.results.map(alert => new GetRequest(alert.source.guid, alert.source['source:type'], alert.index)); + return searchResponse.results.map(alert => + new GetRequest(alert.source.guid, alert.source[this.globalConfig['source.type.field']], alert.index)); } getAllAlertsForSlectedGroup(group: TreeGroupData): Observable<SearchResponse> { let dashRowKey = Object.keys(group.groupQueryMap); let searchRequest = new SearchRequest(); - searchRequest.fields = ['guid', 'source:type']; + searchRequest.fields = ['guid', this.globalConfig['source.type.field']]; searchRequest.from = 0; searchRequest.indices = INDEXES; searchRequest.query = this.createQuery(group); http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/alerts/meta-alerts/meta-alerts.component.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/alerts/meta-alerts/meta-alerts.component.ts b/metron-interface/metron-alerts/src/app/alerts/meta-alerts/meta-alerts.component.ts index 18a20da..762d56c 100644 --- a/metron-interface/metron-alerts/src/app/alerts/meta-alerts/meta-alerts.component.ts +++ b/metron-interface/metron-alerts/src/app/alerts/meta-alerts/meta-alerts.component.ts @@ -15,8 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, OnDestroy } from '@angular/core'; import {Router} from '@angular/router'; +import { Subscription } from 'rxjs/Rx'; import {MetaAlertService} from '../../service/meta-alert.service'; import {UpdateService} from '../../service/update.service'; @@ -28,22 +29,26 @@ import { META_ALERTS_SENSOR_TYPE } from '../../utils/constants'; import {MetronDialogBox} from '../../shared/metron-dialog-box'; import {MetaAlertAddRemoveRequest} from '../../model/meta-alert-add-remove-request'; import {GetRequest} from '../../model/get-request'; +import { GlobalConfigService } from '../../service/global-config.service'; @Component({ selector: 'app-meta-alerts', templateUrl: './meta-alerts.component.html', styleUrls: ['./meta-alerts.component.scss'] }) -export class MetaAlertsComponent implements OnInit { +export class MetaAlertsComponent implements OnInit, OnDestroy { selectedMetaAlert = ''; searchResponse: SearchResponse = new SearchResponse(); + globalConfig: {} = {}; + configSubscription: Subscription; constructor(private router: Router, private metaAlertService: MetaAlertService, private updateService: UpdateService, private searchService: SearchService, - private metronDialogBox: MetronDialogBox) { + private metronDialogBox: MetronDialogBox, + private globalConfigService: GlobalConfigService) { } goBack() { @@ -61,11 +66,18 @@ export class MetaAlertsComponent implements OnInit { searchRequest.sort = [new SortField('threat:triage:score', 'desc')]; this.searchService.search(searchRequest).subscribe(resp => this.searchResponse = resp); + this.configSubscription = this.globalConfigService.get().subscribe((config: {}) => { + this.globalConfig = config; + }); + } + + ngOnDestroy() { + this.configSubscription.unsubscribe(); } addAlertToMetaAlert() { let getRequest = this.metaAlertService.selectedAlerts.map(alert => - new GetRequest(alert.source.guid, alert.source['source:type'], alert.index)); + new GetRequest(alert.source.guid, alert.source[this.globalConfig['source.type.field']], alert.index)); let metaAlertAddRemoveRequest = new MetaAlertAddRemoveRequest(); metaAlertAddRemoveRequest.metaAlertGuid = this.selectedMetaAlert; metaAlertAddRemoveRequest.alerts = getRequest; http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/app.module.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/app.module.ts b/metron-interface/metron-alerts/src/app/app.module.ts index bd34e82..227eaab 100644 --- a/metron-interface/metron-alerts/src/app/app.module.ts +++ b/metron-interface/metron-alerts/src/app/app.module.ts @@ -45,6 +45,7 @@ import {UpdateService} from './service/update.service'; import {MetaAlertService} from './service/meta-alert.service'; import {MetaAlertsModule} from './alerts/meta-alerts/meta-alerts.module'; import {SearchService} from './service/search.service'; +import { GlobalConfigService } from './service/global-config.service'; @@ -82,7 +83,8 @@ export function initConfig(config: ColumnNamesService) { MetronDialogBox, ColumnNamesService, UpdateService, - MetaAlertService], + MetaAlertService, + GlobalConfigService], bootstrap: [AppComponent] }) http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/model/search-request.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/model/search-request.ts b/metron-interface/metron-alerts/src/app/model/search-request.ts index ad174cf..6b54666 100644 --- a/metron-interface/metron-alerts/src/app/model/search-request.ts +++ b/metron-interface/metron-alerts/src/app/model/search-request.ts @@ -16,7 +16,7 @@ * limitations under the License. */ import {SortField} from './sort-field'; -import {DEFAULT_FACETS, DEFAULT_GROUPS, INDEXES} from '../utils/constants'; +import { INDEXES } from '../utils/constants'; export class SearchRequest { fields: string[]; http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/service/authentication.service.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/authentication.service.ts b/metron-interface/metron-alerts/src/app/service/authentication.service.ts index e66725d..33beb31 100644 --- a/metron-interface/metron-alerts/src/app/service/authentication.service.ts +++ b/metron-interface/metron-alerts/src/app/service/authentication.service.ts @@ -19,6 +19,8 @@ import {Injectable, EventEmitter} from '@angular/core'; import {Http, Headers, RequestOptions, Response} from '@angular/http'; import {Router} from '@angular/router'; import {Observable} from 'rxjs/Observable'; +import { GlobalConfigService } from './global-config.service'; +import { DataSource } from './data-source'; @Injectable() export class AuthenticationService { @@ -30,7 +32,10 @@ export class AuthenticationService { defaultHeaders = {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'}; onLoginEvent: EventEmitter<boolean> = new EventEmitter<boolean>(); - constructor(private http: Http, private router: Router) { + constructor(private http: Http, + private router: Router, + private globalConfigService: GlobalConfigService, + private dataSource: DataSource) { this.init(); } @@ -39,6 +44,7 @@ export class AuthenticationService { this.currentUser = response.text(); if (this.currentUser) { this.onLoginEvent.emit(true); + this.dataSource.getDefaultAlertTableColumnNames(); } }, error => { this.onLoginEvent.emit(false); @@ -53,6 +59,8 @@ export class AuthenticationService { this.currentUser = response.text(); this.router.navigateByUrl('/alerts-list'); this.onLoginEvent.emit(true); + this.globalConfigService.get(); + this.dataSource.getDefaultAlertTableColumnNames(); }, error => { onError(error); http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts b/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts index 7982102..fd4843a 100644 --- a/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts +++ b/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts @@ -17,7 +17,7 @@ */ import {Observable} from 'rxjs/Rx'; import {Headers, RequestOptions} from '@angular/http'; - +import { Injectable } from '@angular/core'; import {HttpUtil} from '../utils/httpUtil'; import {DataSource} from './data-source'; import {ColumnMetadata} from '../model/column-metadata'; @@ -34,8 +34,12 @@ import {SearchResponse} from '../model/search-response'; import {SearchRequest} from '../model/search-request'; import {AlertSource} from '../model/alert-source'; +@Injectable() export class ElasticSearchLocalstorageImpl extends DataSource { + globalConfig: {} = {}; + sourceType: 'source:type'; + private defaultColumnMetadata = [ new ColumnMetadata('id', 'string'), new ColumnMetadata('timestamp', 'date'), http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/service/global-config.service.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/global-config.service.ts b/metron-interface/metron-alerts/src/app/service/global-config.service.ts new file mode 100644 index 0000000..cdb8b34 --- /dev/null +++ b/metron-interface/metron-alerts/src/app/service/global-config.service.ts @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import {Injectable, Inject} from '@angular/core'; +import {Http, Headers, RequestOptions, Response, ResponseOptions} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {HttpUtil} from '../utils/httpUtil'; + +@Injectable() +export class GlobalConfigService { + url = 'api/v1/global/config'; + defaultHeaders = {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'}; + + private globalConfig = {}; + + constructor(private http: Http) {} + + public get(): Observable<{}> { + return this.http.get(this.url , new RequestOptions({headers: new Headers(this.defaultHeaders)})) + .map((res: Response): any => { + let body = res.json(); + this.setDefaultSourceType(body); + return body || {}; + }) + .catch(HttpUtil.handleError); + } + + private setDefaultSourceType(globalConfig) { + let sourceType: {} = {}; + if(!globalConfig['source.type.field']) { + sourceType = Object.assign({}, globalConfig, {'source.type.field': 'source:type'}); + return sourceType; + } + } + +} http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/service/update.service.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/service/update.service.ts b/metron-interface/metron-alerts/src/app/service/update.service.ts index 68d9fc0..24b55f0 100644 --- a/metron-interface/metron-alerts/src/app/service/update.service.ts +++ b/metron-interface/metron-alerts/src/app/service/update.service.ts @@ -30,6 +30,7 @@ import {PatchRequest} from '../model/patch-request'; import {Utils} from '../utils/utils'; import {Patch} from '../model/patch'; import {META_ALERTS_INDEX, META_ALERTS_SENSOR_TYPE} from '../utils/constants'; +import { GlobalConfigService } from './global-config.service'; @Injectable() export class UpdateService { @@ -38,8 +39,13 @@ export class UpdateService { alertChangedSource = new Subject<PatchRequest>(); alertChanged$ = this.alertChangedSource.asObservable(); + sourceType = 'source:type'; - constructor(private http: Http) { } + constructor(private http: Http, private globalConfigService: GlobalConfigService) { + this.globalConfigService.get().subscribe((config: {}) => { + this.sourceType = config['source.type.field']; + }); + } public patch(patchRequest: PatchRequest, fireChangeListener = true): Observable<{}> { let url = '/api/v1/update/patch'; @@ -57,7 +63,7 @@ export class UpdateService { let patchRequests: PatchRequest[] = alerts.map(alert => { let patchRequest = new PatchRequest(); patchRequest.guid = alert.source.guid; - patchRequest.sensorType = Utils.getAlertSensorType(alert); + patchRequest.sensorType = Utils.getAlertSensorType(alert, this.sourceType); patchRequest.patch = [new Patch('add', '/alert_status', state)]; if (patchRequest.sensorType === META_ALERTS_SENSOR_TYPE) { patchRequest.index = META_ALERTS_INDEX; http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/utils/constants.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/utils/constants.ts b/metron-interface/metron-alerts/src/app/utils/constants.ts index 6fcea2b..b7a9298 100644 --- a/metron-interface/metron-alerts/src/app/utils/constants.ts +++ b/metron-interface/metron-alerts/src/app/utils/constants.ts @@ -16,7 +16,7 @@ * limitations under the License. */ -import {environment} from '../../environments/environment'; +import { environment } from '../../environments/environment'; export const META_ALERTS_SENSOR_TYPE = 'metaalert'; export const META_ALERTS_INDEX = 'metaalert_index'; @@ -35,8 +35,6 @@ export let DEFAULT_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH:mm:ss'; export let CUSTOMM_DATE_RANGE_LABEL = 'Date Range'; export let TREE_SUB_GROUP_SIZE = 5; -export let DEFAULT_FACETS = ['source:type', 'ip_src_addr', 'ip_dst_addr', 'host', 'enrichments:geo:ip_dst_addr:country']; -export let DEFAULT_GROUPS = ['source:type', 'ip_src_addr', 'ip_dst_addr', 'host', 'enrichments:geo:ip_dst_addr:country']; export let INDEXES = environment.indices ? environment.indices.split(',') : []; export let MAX_ALERTS_IN_META_ALERTS = 350; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-interface/metron-alerts/src/app/utils/utils.ts ---------------------------------------------------------------------- diff --git a/metron-interface/metron-alerts/src/app/utils/utils.ts b/metron-interface/metron-alerts/src/app/utils/utils.ts index 34d2241..61cc45b 100644 --- a/metron-interface/metron-alerts/src/app/utils/utils.ts +++ b/metron-interface/metron-alerts/src/app/utils/utils.ts @@ -20,6 +20,7 @@ import * as moment from 'moment/moment'; import {DEFAULT_TIMESTAMP_FORMAT, META_ALERTS_SENSOR_TYPE} from './constants'; import {Alert} from '../model/alert'; import {DateFilterValue} from '../model/date-filter-value'; +import { environment } from 'environments/environment'; export class Utils { public static escapeESField(field: string): string { @@ -33,9 +34,9 @@ export class Utils { .replace(/\&\&/g, '\\&&'); // replace && } - public static getAlertSensorType(alert: Alert): string { - if (alert.source['source:type'] && alert.source['source:type'].length > 0) { - return alert.source['source:type']; + public static getAlertSensorType(alert: Alert, sourceType: string): string { + if (alert.source[sourceType] && alert.source[sourceType].length > 0) { + return alert.source[sourceType]; } else { return META_ALERTS_SENSOR_TYPE; } http://git-wip-us.apache.org/repos/asf/metron/blob/a99cadb0/metron-platform/metron-common/README.md ---------------------------------------------------------------------- diff --git a/metron-platform/metron-common/README.md b/metron-platform/metron-common/README.md index b25fbc8..c741e72 100644 --- a/metron-platform/metron-common/README.md +++ b/metron-platform/metron-common/README.md @@ -29,14 +29,14 @@ limitations under the License. For a variety of components (threat intelligence triage and field transformations) we have the need to do simple computation and -transformation using the data from messages as variables. -For those purposes, there exists a simple, scaled down DSL +transformation using the data from messages as variables. +For those purposes, there exists a simple, scaled down DSL created to do simple computation and transformation. The query language supports the following: * Referencing fields in the enriched JSON * String literals are quoted with either `'` or `"`, and -support escaping for `'`, `"`, `\t`, `\r`, `\n`, and backslash +support escaping for `'`, `"`, `\t`, `\r`, `\n`, and backslash * Simple boolean operations: `and`, `not`, `or` * Boolean expressions are short-circuited (e.g. `true or FUNC()` would never execute `FUNC`) * Simple arithmetic operations: `*`, `/`, `+`, `-` on real numbers or integers @@ -46,7 +46,7 @@ support escaping for `'`, `"`, `\t`, `\r`, `\n`, and backslash * Determining whether a field exists (via `exists`) * An `in` operator that works like the `in` in Python * The ability to have parenthesis to make order of operations explicit -* User defined functions, including Lambda expressions +* User defined functions, including Lambda expressions For documentation of Stellar, please see the [Stellar README](../../metron-stellar/stellar-common/README.md). @@ -71,7 +71,7 @@ This configuration is stored in zookeeper, but looks something like "config" : { "type" : "IPV4" } - } + } ] } ``` @@ -95,6 +95,7 @@ but a convenient index is provided here: | [`update.hbase.table`](../metron-indexing#updatehbasetable) | REST/Indexing | String | `update_hbase_table` | | [`update.hbase.cf`](../metron-indexing#updatehbasecf) | REST/Indexing | String | `update_hbase_cf` | | [`geo.hdfs.file`](../metron-enrichment#geohdfsfile) | Enrichment | String | `geo_hdfs_file` | +| [`source.type.field`](../../metron-interface/metron-alerts#sourcetypefield) | UI | String | N/A | ## Note Configs in Ambari If a field is managed via ambari, you should change the field via @@ -106,7 +107,7 @@ overwritten. Inside of the global configuration, there is a validation framework in place that enables the validation that messages coming from all parsers are valid. This is done in the form of validation plugins where -assertions about fields or whole messages can be made. +assertions about fields or whole messages can be made. The format for this is a `fieldValidations` field inside of global config. This is associated with an array of field validation objects @@ -344,7 +345,7 @@ Each topology can be configured to send error messages to a specific Kafka topic ``` Error topics for enrichment and threat intel errors are passed into the enrichment topology as flux properties named `enrichment.error.topic` and `threat.intel.error.topic`. These properties can be found in `$METRON_HOME/config/enrichment.properties`. - + The error topic for indexing errors is passed into the indexing topology as a flux property named `index.error.topic`. This property can be found in either `$METRON_HOME/config/elasticsearch.properties` or `$METRON_HOME/config/solr.properties` depending on the search engine selected. By default all error messages are sent to the `indexing` topic so that they are indexed and archived, just like other messages. The indexing config for error messages can be found at `$METRON_HOME/config/zookeeper/indexing/error.json`.
