Commit db674e2d authored by Miguel Rincon's avatar Miguel Rincon Committed by Paul Slaughter

Moved entire dashboard to Vuex state

Currently only the panel groups are kept in the store
and other dashboard information is discarted.

In order for the information to be preserved by the client
it must be saved to the store.
parent 3a2c1c59
...@@ -39,7 +39,7 @@ export const requestMetricsDashboard = ({ commit }) => { ...@@ -39,7 +39,7 @@ export const requestMetricsDashboard = ({ commit }) => {
}; };
export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response, params }) => { export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response, params }) => {
commit(types.SET_ALL_DASHBOARDS, response.all_dashboards); commit(types.SET_ALL_DASHBOARDS, response.all_dashboards);
commit(types.RECEIVE_METRICS_DATA_SUCCESS, response.dashboard.panel_groups); commit(types.RECEIVE_METRICS_DATA_SUCCESS, response.dashboard);
return dispatch('fetchPrometheusMetrics', params); return dispatch('fetchPrometheusMetrics', params);
}; };
export const receiveMetricsDashboardFailure = ({ commit }, error) => { export const receiveMetricsDashboardFailure = ({ commit }, error) => {
......
...@@ -84,23 +84,26 @@ export default { ...@@ -84,23 +84,26 @@ export default {
state.emptyState = 'loading'; state.emptyState = 'loading';
state.showEmptyState = true; state.showEmptyState = true;
}, },
[types.RECEIVE_METRICS_DATA_SUCCESS](state, groupData) { [types.RECEIVE_METRICS_DATA_SUCCESS](state, dashboard) {
state.dashboard.panel_groups = groupData.map((group, i) => { state.dashboard = {
const key = `${slugify(group.group || 'default')}-${i}`; ...dashboard,
let { panels = [] } = group; panel_groups: dashboard.panel_groups.map((group, i) => {
const key = `${slugify(group.group || 'default')}-${i}`;
// each panel has metric information that needs to be normalized let { panels = [] } = group;
panels = panels.map(panel => ({
...panel, // each panel has metric information that needs to be normalized
metrics: normalizePanelMetrics(panel.metrics, panel.y_label), panels = panels.map(panel => ({
})); ...panel,
metrics: normalizePanelMetrics(panel.metrics, panel.y_label),
return { }));
...group,
panels, return {
key, ...group,
}; panels,
}); key,
};
}),
};
if (!state.dashboard.panel_groups.length) { if (!state.dashboard.panel_groups.length) {
state.emptyState = 'noData'; state.emptyState = 'noData';
......
...@@ -345,7 +345,7 @@ describe('Dashboard', () => { ...@@ -345,7 +345,7 @@ describe('Dashboard', () => {
it('metrics can be swapped', done => { it('metrics can be swapped', done => {
const firstDraggable = findDraggables().at(0); const firstDraggable = findDraggables().at(0);
const mockMetrics = [...metricsGroupsAPIResponse[1].panels]; const mockMetrics = [...metricsGroupsAPIResponse.panel_groups[1].panels];
const firstTitle = mockMetrics[0].title; const firstTitle = mockMetrics[0].title;
const secondTitle = mockMetrics[1].title; const secondTitle = mockMetrics[1].title;
......
...@@ -331,77 +331,80 @@ export const mockedQueryResultPayloadCoresTotal = { ...@@ -331,77 +331,80 @@ export const mockedQueryResultPayloadCoresTotal = {
], ],
}; };
export const metricsGroupsAPIResponse = [ export const metricsGroupsAPIResponse = {
{ dashboard: 'Environment metrics',
group: 'Response metrics (NGINX Ingress VTS)', panel_groups: [
priority: 10, {
panels: [ group: 'Response metrics (NGINX Ingress VTS)',
{ priority: 10,
metrics: [ panels: [
{ {
id: 'response_metrics_nginx_ingress_throughput_status_code', metrics: [
label: 'Status Code', {
metric_id: 1, id: 'response_metrics_nginx_ingress_throughput_status_code',
prometheus_endpoint_path: label: 'Status Code',
'/root/autodevops-deploy/environments/32/prometheus/api/v1/query_range?query=sum%28rate%28nginx_upstream_responses_total%7Bupstream%3D~%22%25%7Bkube_namespace%7D-%25%7Bci_environment_slug%7D-.%2A%22%7D%5B2m%5D%29%29+by+%28status_code%29', metric_id: 1,
query_range: prometheus_endpoint_path:
'sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) by (status_code)', '/root/autodevops-deploy/environments/32/prometheus/api/v1/query_range?query=sum%28rate%28nginx_upstream_responses_total%7Bupstream%3D~%22%25%7Bkube_namespace%7D-%25%7Bci_environment_slug%7D-.%2A%22%7D%5B2m%5D%29%29+by+%28status_code%29',
unit: 'req / sec', query_range:
}, 'sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) by (status_code)',
], unit: 'req / sec',
title: 'Throughput', },
type: 'area-chart', ],
weight: 1, title: 'Throughput',
y_label: 'Requests / Sec', type: 'area-chart',
}, weight: 1,
], y_label: 'Requests / Sec',
}, },
{ ],
group: 'System metrics (Kubernetes)', },
priority: 5, {
panels: [ group: 'System metrics (Kubernetes)',
{ priority: 5,
title: 'Memory Usage (Pod average)', panels: [
type: 'area-chart', {
y_label: 'Memory Used per Pod', title: 'Memory Usage (Pod average)',
weight: 2, type: 'area-chart',
metrics: [ y_label: 'Memory Used per Pod',
{ weight: 2,
id: 'system_metrics_kubernetes_container_memory_average', metrics: [
query_range: {
'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024', id: 'system_metrics_kubernetes_container_memory_average',
label: 'Pod average', query_range:
unit: 'MB', 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024',
metric_id: 17, label: 'Pod average',
prometheus_endpoint_path: unit: 'MB',
'/root/autodevops-deploy/environments/32/prometheus/api/v1/query_range?query=avg%28sum%28container_memory_usage_bytes%7Bcontainer_name%21%3D%22POD%22%2Cpod_name%3D~%22%5E%25%7Bci_environment_slug%7D-%28%5B%5Ec%5D.%2A%7Cc%28%5B%5Ea%5D%7Ca%28%5B%5En%5D%7Cn%28%5B%5Ea%5D%7Ca%28%5B%5Er%5D%7Cr%5B%5Ey%5D%29%29%29%29.%2A%7C%29-%28.%2A%29%22%2Cnamespace%3D%22%25%7Bkube_namespace%7D%22%7D%29+by+%28job%29%29+without+%28job%29+%2F+count%28avg%28container_memory_usage_bytes%7Bcontainer_name%21%3D%22POD%22%2Cpod_name%3D~%22%5E%25%7Bci_environment_slug%7D-%28%5B%5Ec%5D.%2A%7Cc%28%5B%5Ea%5D%7Ca%28%5B%5En%5D%7Cn%28%5B%5Ea%5D%7Ca%28%5B%5Er%5D%7Cr%5B%5Ey%5D%29%29%29%29.%2A%7C%29-%28.%2A%29%22%2Cnamespace%3D%22%25%7Bkube_namespace%7D%22%7D%29+without+%28job%29%29+%2F1024%2F1024', metric_id: 17,
appearance: { prometheus_endpoint_path:
line: { '/root/autodevops-deploy/environments/32/prometheus/api/v1/query_range?query=avg%28sum%28container_memory_usage_bytes%7Bcontainer_name%21%3D%22POD%22%2Cpod_name%3D~%22%5E%25%7Bci_environment_slug%7D-%28%5B%5Ec%5D.%2A%7Cc%28%5B%5Ea%5D%7Ca%28%5B%5En%5D%7Cn%28%5B%5Ea%5D%7Ca%28%5B%5Er%5D%7Cr%5B%5Ey%5D%29%29%29%29.%2A%7C%29-%28.%2A%29%22%2Cnamespace%3D%22%25%7Bkube_namespace%7D%22%7D%29+by+%28job%29%29+without+%28job%29+%2F+count%28avg%28container_memory_usage_bytes%7Bcontainer_name%21%3D%22POD%22%2Cpod_name%3D~%22%5E%25%7Bci_environment_slug%7D-%28%5B%5Ec%5D.%2A%7Cc%28%5B%5Ea%5D%7Ca%28%5B%5En%5D%7Cn%28%5B%5Ea%5D%7Ca%28%5B%5Er%5D%7Cr%5B%5Ey%5D%29%29%29%29.%2A%7C%29-%28.%2A%29%22%2Cnamespace%3D%22%25%7Bkube_namespace%7D%22%7D%29+without+%28job%29%29+%2F1024%2F1024',
width: 2, appearance: {
line: {
width: 2,
},
}, },
}, },
}, ],
], },
}, {
{ title: 'Core Usage (Total)',
title: 'Core Usage (Total)', type: 'area-chart',
type: 'area-chart', y_label: 'Total Cores',
y_label: 'Total Cores', weight: 3,
weight: 3, metrics: [
metrics: [ {
{ id: 'system_metrics_kubernetes_container_cores_total',
id: 'system_metrics_kubernetes_container_cores_total', query_range:
query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job)',
'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job)', label: 'Total',
label: 'Total', unit: 'cores',
unit: 'cores', metric_id: 13,
metric_id: 13, },
}, ],
], },
}, ],
], },
}, ],
]; };
export const environmentData = [ export const environmentData = [
{ {
......
...@@ -298,7 +298,7 @@ describe('Monitoring store actions', () => { ...@@ -298,7 +298,7 @@ describe('Monitoring store actions', () => {
); );
expect(commit).toHaveBeenCalledWith( expect(commit).toHaveBeenCalledWith(
types.RECEIVE_METRICS_DATA_SUCCESS, types.RECEIVE_METRICS_DATA_SUCCESS,
metricsDashboardResponse.dashboard.panel_groups, metricsDashboardResponse.dashboard,
); );
expect(dispatch).toHaveBeenCalledWith('fetchPrometheusMetrics', params); expect(dispatch).toHaveBeenCalledWith('fetchPrometheusMetrics', params);
}); });
...@@ -441,7 +441,7 @@ describe('Monitoring store actions', () => { ...@@ -441,7 +441,7 @@ describe('Monitoring store actions', () => {
beforeEach(() => { beforeEach(() => {
state = storeState(); state = storeState();
[metric] = metricsDashboardResponse.dashboard.panel_groups[0].panels[0].metrics; [metric] = metricsDashboardResponse.dashboard.panel_groups[0].panels[0].metrics;
[data] = metricsGroupsAPIResponse[0].panels[0].metrics; [data] = metricsGroupsAPIResponse.panel_groups[0].panels[0].metrics;
}); });
it('commits result', done => { it('commits result', done => {
......
...@@ -100,12 +100,12 @@ describe('Monitoring mutations', () => { ...@@ -100,12 +100,12 @@ describe('Monitoring mutations', () => {
values: [[0, 1], [1, 1], [1, 3]], values: [[0, 1], [1, 1], [1, 3]],
}, },
]; ];
const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups; const { dashboard } = metricsDashboardResponse;
const getMetric = () => stateCopy.dashboard.panel_groups[0].panels[0].metrics[0]; const getMetric = () => stateCopy.dashboard.panel_groups[0].panels[0].metrics[0];
describe('REQUEST_METRIC_RESULT', () => { describe('REQUEST_METRIC_RESULT', () => {
beforeEach(() => { beforeEach(() => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups); mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboard);
}); });
it('stores a loading state on a metric', () => { it('stores a loading state on a metric', () => {
expect(stateCopy.showEmptyState).toBe(true); expect(stateCopy.showEmptyState).toBe(true);
...@@ -128,7 +128,7 @@ describe('Monitoring mutations', () => { ...@@ -128,7 +128,7 @@ describe('Monitoring mutations', () => {
describe('RECEIVE_METRIC_RESULT_SUCCESS', () => { describe('RECEIVE_METRIC_RESULT_SUCCESS', () => {
beforeEach(() => { beforeEach(() => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups); mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboard);
}); });
it('clears empty state', () => { it('clears empty state', () => {
expect(stateCopy.showEmptyState).toBe(true); expect(stateCopy.showEmptyState).toBe(true);
...@@ -161,7 +161,7 @@ describe('Monitoring mutations', () => { ...@@ -161,7 +161,7 @@ describe('Monitoring mutations', () => {
describe('RECEIVE_METRIC_RESULT_FAILURE', () => { describe('RECEIVE_METRIC_RESULT_FAILURE', () => {
beforeEach(() => { beforeEach(() => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups); mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboard);
}); });
it('maintains the loading state when a metric fails', () => { it('maintains the loading state when a metric fails', () => {
expect(stateCopy.showEmptyState).toBe(true); expect(stateCopy.showEmptyState).toBe(true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment