diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue
index 0b98f9c0101..9b1c45a3a49 100644
--- a/app/assets/javascripts/clusters_list/components/clusters.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters.vue
@@ -43,17 +43,17 @@ export default {
key: 'environment_scope',
label: __('Environment scope'),
},
- // Wait for backend to send these fields
+ {
+ key: 'node_size',
+ label: __('Nodes'),
+ },
+ // Fields are missing calculation methods and not ready to display
// {
- // key: 'size',
- // label: __('Size'),
- // },
- // {
- // key: 'cpu',
+ // key: 'node_cpu',
// label: __('Total cores (vCPUs)'),
// },
// {
- // key: 'memory',
+ // key: 'node_memory',
// label: __('Total memory (GB)'),
// },
{
@@ -111,6 +111,14 @@ export default {
>
+
+
+ {{ item.nodes.length }}
+ {{
+ __('Unknown')
+ }}
+
+
{{ value }}
diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js
index eebcaa086f9..077bf0b8925 100644
--- a/app/assets/javascripts/clusters_list/constants.js
+++ b/app/assets/javascripts/clusters_list/constants.js
@@ -6,6 +6,8 @@ export const CLUSTER_TYPES = {
instance_type: __('Instance'),
};
+export const MAX_REQUESTS = 3;
+
export const STATUSES = {
default: { className: 'bg-white', title: __('Unknown') },
disabled: { className: 'disabled', title: __('Disabled') },
diff --git a/app/assets/javascripts/clusters_list/store/actions.js b/app/assets/javascripts/clusters_list/store/actions.js
index 919625f69b4..5245c307c8c 100644
--- a/app/assets/javascripts/clusters_list/store/actions.js
+++ b/app/assets/javascripts/clusters_list/store/actions.js
@@ -2,10 +2,23 @@ import Poll from '~/lib/utils/poll';
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
+import { MAX_REQUESTS } from '../constants';
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
+import * as Sentry from '@sentry/browser';
import * as types from './mutation_types';
+const allNodesPresent = (clusters, retryCount) => {
+ /*
+ Nodes are coming from external Kubernetes clusters.
+ They may fail for reasons GitLab cannot control.
+ MAX_REQUESTS will ensure this poll stops at some point.
+ */
+ return retryCount > MAX_REQUESTS || clusters.every(cluster => cluster.nodes != null);
+};
+
export const fetchClusters = ({ state, commit }) => {
+ let retryCount = 0;
+
const poll = new Poll({
resource: {
fetchClusters: paginatedEndPoint => axios.get(paginatedEndPoint),
@@ -13,16 +26,40 @@ export const fetchClusters = ({ state, commit }) => {
data: `${state.endpoint}?page=${state.page}`,
method: 'fetchClusters',
successCallback: ({ data, headers }) => {
- if (data.clusters) {
- const normalizedHeaders = normalizeHeaders(headers);
- const paginationInformation = parseIntPagination(normalizedHeaders);
+ retryCount += 1;
- commit(types.SET_CLUSTERS_DATA, { data, paginationInformation });
- commit(types.SET_LOADING_STATE, false);
+ try {
+ if (data.clusters) {
+ const normalizedHeaders = normalizeHeaders(headers);
+ const paginationInformation = parseIntPagination(normalizedHeaders);
+
+ commit(types.SET_CLUSTERS_DATA, { data, paginationInformation });
+ commit(types.SET_LOADING_STATE, false);
+
+ if (allNodesPresent(data.clusters, retryCount)) {
+ poll.stop();
+ }
+ }
+ } catch (error) {
poll.stop();
+
+ Sentry.withScope(scope => {
+ scope.setTag('javascript_clusters_list', 'fetchClustersSuccessCallback');
+ Sentry.captureException(error);
+ });
}
},
- errorCallback: () => flash(__('An error occurred while loading clusters')),
+ errorCallback: response => {
+ poll.stop();
+
+ commit(types.SET_LOADING_STATE, false);
+ flash(__('Clusters|An error occurred while loading clusters'));
+
+ Sentry.withScope(scope => {
+ scope.setTag('javascript_clusters_list', 'fetchClustersErrorCallback');
+ Sentry.captureException(response);
+ });
+ },
});
poll.makeRequest();
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue
index a070cf8866a..9b911f99c83 100644
--- a/app/assets/javascripts/notes/components/comment_form.vue
+++ b/app/assets/javascripts/notes/components/comment_form.vue
@@ -412,7 +412,7 @@ js-gfm-input js-autosize markdown-area js-vue-textarea qa-comment-input"