Merge pull request #1659 from vimniky/alert-logging

Alert: Fixed sorting & searching and filtering bugs.
This commit is contained in:
Vincent Fiduccia 2018-02-25 00:12:19 -07:00 committed by GitHub
commit fceefdd8c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 131 additions and 62 deletions

View File

@ -21,8 +21,8 @@ const headers = [
{
translationKey: 'alertPage.index.table.target',
name: 'target',
searchField: ['target', 'displayTargetType'],
sort: ['target', 'id'],
searchField: ['nodeName', 'resourceKind', 'displayTargetType'],
sort: ['nodeName', 'id', 'resourceKind'],
},
{
translationKey: 'alertPage.index.table.condition',
@ -33,14 +33,16 @@ const headers = [
{
translationKey: 'alertPage.index.table.recipients',
name: 'recipients',
searchField: ['recipient'],
sort: ['recipients'],
searchField: ['recipient', 'firstRecipient'],
sort: ['recipients', 'firstRecipient'],
},
];
export default Component.extend({
pageScope: reads('scope.currentPageScope'),
scope: service(),
clusterId: reads('scope.currentCluster.id'),
projectId: reads('scope.currentProject.id'),
pageScope: reads('scope.currentPageScope'),
// input
model: null,
@ -54,7 +56,19 @@ export default Component.extend({
search: true,
searchText: null,
filteredNotifiers: function() {
const clusterId = get(this, 'clusterId');
return get(this, 'notifiers').filterBy('clusterId', clusterId);
}.property('clusterId', 'notifiers.@each.{clusterId}'),
filteredAlerts: function() {
return get(this, 'model');
}.property('model.[]'),
const clusterId = get(this, 'clusterId');
const projectId = get(this, 'projectId');
const ps = get(this, 'pageScope');
if (ps === 'cluster') {
return get(this, 'alerts').filterBy('clusterId', clusterId);
} else {
return get(this, 'alerts').filterBy('projectId', projectId);
}
}.property('alerts.@each.{clusterId,projectId}', 'clusterId', 'projectId', 'pageScope'),
});

View File

@ -9,14 +9,13 @@
searchText=searchText
headers=headers
body=filteredAlerts
fullRows=fullRows
as |sortable kind row dt|
}}
{{#if (eq kind "row")}}
{{#if (eq pageScope 'cluster')}}
{{cluster-alert-row notifiers=notifiers model=row}}
{{cluster-alert-row notifiers=filteredNotifiers model=row}}
{{else if (eq pageScope 'project')}}
{{project-alert-row notifiers=notifiers model=row}}
{{project-alert-row notifiers=filteredNotifiers model=row}}
{{else}}
<div>Oops, it's impossible</div>
{{/if}}

View File

@ -1,5 +1,7 @@
import { get, set } from '@ember/object';
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { reads } from '@ember/object/computed';
const SYSTEM_SERVICES = [
{label: 'Etcd', value: 'etcd'},
@ -16,6 +18,9 @@ const RESOURCE_KINDS = [
{label: 'Daemonset', value: 'Daemonset'},
];
export default Component.extend({
globalStore: service(),
scope: service(),
clusterId: reads('scope.currentCluster.id'),
init(...args) {
this._super(...args);
@ -23,6 +28,11 @@ export default Component.extend({
this.set('resourceKinds', RESOURCE_KINDS);
},
nodes: function() {
const clusterId = get(this, 'clusterId');
return get(this, 'globalStore').all('node').filterBy('clusterId', clusterId);
}.property('clusterId'),
isEventTarget: function() {
const t = get(this, 'model._targetType');
return t === 'warningEvent' || t === 'normalEvent';

View File

@ -50,7 +50,7 @@
</div>
<div class="col span-9 mt-0">
{{searchable-select
content=resourceMap.nodes
content=nodes
class="form-control"
value=model.targetNode.nodeId
optionValuePath="id"

View File

@ -1,4 +1,6 @@
import { get, set } from '@ember/object';
import { inject as service } from '@ember/service';
import { reads } from '@ember/object/computed';
import Component from '@ember/component';
const WORLOAD_TYPES = [
@ -8,6 +10,10 @@ const WORLOAD_TYPES = [
];
export default Component.extend({
globalStore: service(),
scope: service(),
clusterId: reads('scope.currentCluster.id'),
projectId: reads('scope.currentProject.id'),
restartIntervalSeconds: null,
@ -19,6 +25,26 @@ export default Component.extend({
set(this, 'model.targetPod.restartIntervalSeconds', n * 60);
},
pods: function() {
const clusterId = get(this, 'clusterId');
return get(this, 'store').all('pod').filterBy('clusterId', clusterId);
}.property('clusterId'),
deployments: function() {
const projectId = get(this, 'projectId');
return get(this, 'store').all('deployment').filterBy('projectId', projectId);
}.property('projectId'),
daemonsets: function() {
const projectId = get(this, 'projectId');
return get(this, 'store').all('daemonset').filterBy('projectId', projectId);
}.property('projectId'),
statefulsets: function() {
const projectId = get(this, 'projectId');
return get(this, 'store').all('statefulset').filterBy('projectId', projectId);
}.property('projectId'),
restartIntervalSecondsChanged: function() {
const n = +get(this, 'restartIntervalSeconds') || 5;
set(this, 'model.targetPod.restartIntervalSeconds', n * 60);
@ -27,15 +53,15 @@ export default Component.extend({
workloads: function() {
const t = get(this, 'model.targetWorkload.workloadType');
if (t === 'deployment') {
return get(this, 'resourceMap.deployments');
return get(this, 'deployments');
}
if (t === 'daemonset') {
return get(this, 'resourceMap.daemonsets');
return get(this, 'daemonsets');
}
if (t === 'statefulset') {
return get(this, 'resourceMap.statefulsets');
return get(this, 'statefulsets');
}
}.property('resourceMap.deployments.[]', 'resourceMap.daemonsets.[]', 'resourceMap.statefulsets.[]', 'model.targetWorkload.workloadType'),
}.property('deployments.[]', 'daemonsets.[]', 'statefulsets.[]', 'model.targetWorkload.workloadType'),
actions: {
// todo, don't know that this is needed

View File

@ -14,7 +14,7 @@
</div>
<div class="col span-8 mt-0">
{{searchable-select
content=resourceMap.pods
content=pods
class="form-control"
value=model.targetPod.podId
optionValuePath="id"

View File

@ -4,6 +4,7 @@ import { reads } from '@ember/object/computed';
import Component from '@ember/component';
export default Component.extend({
globalStore: service(),
scope: service(),
clusterId: reads('scope.currentCluster.id'),
@ -20,6 +21,11 @@ export default Component.extend({
get(this, 'model.recipients').pushObject(nue);
},
notifiers: function() {
const clusterId = get(this, 'clusterId');
return get(this, 'globalStore').all('notifier').filterBy('clusterId', clusterId);
}.property('clusterId'),
disableRemove: function() {
return get(this, 'model.recipients.length') <= 1;
}.property('model.recipients.length'),

View File

@ -16,7 +16,6 @@
<div class="">
{{# if (eq pageScope 'cluster')}}
{{alert/form-cluster-rules
resourceMap=resourceMap
pageScope=pageScope
isCreate=isCreate
model=newAlert
@ -24,7 +23,6 @@
{{else if (eq pageScope 'project')}}
{{alert/form-project-rules
pageScope=pageScope
resourceMap=resourceMap
isCreate=isCreate
model=newAlert
}}
@ -35,7 +33,6 @@
{{alert/form-recipients
pageScope=pageScope
isCreate=isCreate
notifiers=resourceMap.notifiers
model=newAlert
}}
</div>

View File

@ -11,12 +11,6 @@ export default Component.extend(notifierMixin, {
classNames: 'main-row',
bulkActions: true,
resourceKind: function() {
const rk = get(this, 'model.targetEvent.resourceKind');
return get(this, 'intl').t(`alertPage.resourceKinds.${rk}`);
}.property('model.targetEvent.resourceKind'),
selectorList: function() {
const t = get(this, 'model.targetType');
if (t === 'nodeSelector') {

View File

@ -36,7 +36,7 @@
{{/if}}
{{else if (eq model.targetType 'node')}}
<div class="text-muted text-small">
{{model.targetNode.nodeId}}
{{model.nodeName}}
</div>
{{else if (eq model.targetType 'systemService')}}
<div class="text-muted text-small">
@ -44,7 +44,7 @@
</div>
{{else if (eq model.targetType 'event')}}
<div class="text-muted text-small">
<span class="text-capicalize">{{resourceKind}}</span> {{t 'alertPage.targetTypes.event'}}
<span class="text-capicalize">{{model.resourceKind}}</span> {{t 'alertPage.targetTypes.event'}}
</div>
{{/if}}
</td>
@ -58,9 +58,10 @@
{{#if (eq model.recipients.length 1)}}
<div class="clip">
<div class="text-capitalize">{{item.notifierType}}</div>
{{#if firstRecipient}}
{{firstRecipient.name}}
{{#if model.firstRecipient}}
{{model.firstRecipient}}
{{else}}
{{t 'alertPage.na'}}
{{/if}}
</div>
{{else if (gt model.recipients.length 1)}}

View File

@ -18,13 +18,6 @@ export default Component.extend(notifierMixin, {
return t === 'pod' && c === 'restarts';
}.property('model.targetType', 'model.targetPod.condition'),
displayTargetType: function() {
const t = get(this, 'model.targetType');
const intl = get(this, 'intl');
return intl.t(`alertPage.targetTypes.${t}`);
}.property('model.targetType'),
selectorList: function() {
const t = get(this, 'model.targetType');
if (t === 'workloadSelector') {

View File

@ -59,8 +59,8 @@
{{#if (eq model.recipients.length 1)}}
<div class="clip">
<div class="text-capitalize">{{item.notifierType}}</div>
{{#if firstRecipient}}
{{firstRecipient.name}}
{{#if model.firstRecipient}}
{{model.firstRecipient}}
{{else}}
{{t 'alertPage.na'}}
{{/if}}

View File

@ -15,9 +15,7 @@ export default Route.extend({
const opt = {
filter: {clusterId},
};
const notifiers = gs.findAll('notifier', opt).then(() => {
return gs.all('notifier');
});
const notifiers = gs.findAll('notifier', opt);
const alerts = gs.findAll('clusterAlert', opt).then(() => {
return gs.all('clusterAlert');
});
@ -28,9 +26,7 @@ export default Route.extend({
},
loadProjectResource({clusterId, projectId}) {
let gs = get(this, 'globalStore');
const notifiers = gs.findAll('notifier', {filter: {clusterId}}).then(() => {
return gs.all('notifier');
});
const notifiers = gs.findAll('notifier', {filter: {clusterId}});
const alerts = gs.findAll('projectAlert', {filter: {projectId}}).then(() => {
return gs.all('projectAlert');
});

View File

@ -5,8 +5,4 @@
</div>
</section>
{{alert-table
pageScope=pageScope
notifiers=notifiers
model=alerts
}}
{{alert-table alerts=model.alerts notifiers=model.notifiers}}

View File

@ -5,7 +5,9 @@ import { reads } from '@ember/object/computed';
export default Mixin.create({
router: service(),
globalStore: service(),
scope: service(),
intl: service(),
pageScope: reads('scope.currentPageScope'),
relevantState: function() {
@ -22,6 +24,45 @@ export default Mixin.create({
this.constructor.stateMap = stateMap
},
displayTargetType: function() {
const t = get(this, 'targetType');
const intl = get(this, 'intl');
return intl.t(`alertPage.targetTypes.${t}`);
}.property('targetType'),
resourceKind: function() {
const rk = get(this, 'targetEvent.resourceKind');
return get(this, 'intl').t(`alertPage.resourceKinds.${rk}`);
}.property('targetEvent.resourceKind'),
firstRecipient: function() {
const recipient = (get(this, 'recipients') || []).get('firstObject');
if (recipient && get(recipient, 'notifierId')) {
const notifierId = get(recipient, 'notifierId');
if (!notifierId) return null;
const notifier = get(this, 'globalStore').all('notifier').filterBy('id', notifierId).get('firstObject');
if (!notifier) {
return null;
}
return notifier.get('displayName');
}
return null;
}.property('recipients.length'),
nodeName: function() {
const id = get(this, 'targetNode.nodeId');
if (!id) {
return null;
}
const node = get(this, 'globalStore').all('node').filterBy('id', id).get('firstObject');
if (!node) {
return null;
}
return node.get('displayName');
}.property('targetNode.nodeId'),
actions: {
edit() {
const ps = get(this, 'pageScope');

View File

@ -11,15 +11,6 @@ export default Mixin.create({
return notifiers.filterBy('id', id).get('firstObject');
},
firstRecipient: function() {
const recipient = get(this, 'model.recipients').get('firstObject');
if (recipient && get(recipient, 'notifierId')) {
const notifierId = get(recipient, 'notifierId');
return this.getNotifierById(notifierId)
}
return null;
}.property('model.recipients.length'),
recipientsTip: function() {
const recipients = get(this, 'model.recipients') || [];
const out = recipients.map(recipient => {

View File

@ -76,7 +76,6 @@ export default Route.extend({
const globalStore = get(this, 'globalStore');
const newAlert = this.getNewProjectAlert(projectId);
const opt = {filter: {projectId}};
return hash({
pods: store.findAll('pod', opt),
statefulsets: store.findAll('statefulset', opt),

View File

@ -1,4 +1,7 @@
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { reads } from '@ember/object/computed';
import { get } from '@ember/object';
import layout from './template';
const headers = [
@ -30,6 +33,8 @@ const headers = [
];
export default Component.extend({
scope: service(),
clusterId: reads('scope.currentCluster.id'),
layout,
// input
model: null,
@ -37,7 +42,8 @@ export default Component.extend({
headers,
filteredNotifiers: function() {
const notifiers = this.get('model') || [];
return notifiers;
}.property('model.[]'),
const data = this.get('model') || [];
const clusterId = get(this, 'clusterId')
return data.filterBy('clusterId', clusterId);
}.property('model.@each.{clusterId}', 'clusterId'),
});