Commit f20dcfad authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '220182-cluster-error-tooltip' into 'master'

Add Cluster Error Messages

See merge request gitlab-org/gitlab!35669
parents 1777188d f1367c56
...@@ -10,6 +10,7 @@ import { ...@@ -10,6 +10,7 @@ import {
GlTable, GlTable,
} from '@gitlab/ui'; } from '@gitlab/ui';
import AncestorNotice from './ancestor_notice.vue'; import AncestorNotice from './ancestor_notice.vue';
import NodeErrorHelpText from './node_error_help_text.vue';
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
import { CLUSTER_TYPES, STATUSES } from '../constants'; import { CLUSTER_TYPES, STATUSES } from '../constants';
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
...@@ -26,6 +27,7 @@ export default { ...@@ -26,6 +27,7 @@ export default {
GlSkeletonLoading, GlSkeletonLoading,
GlSprintf, GlSprintf,
GlTable, GlTable,
NodeErrorHelpText,
}, },
directives: { directives: {
tooltip, tooltip,
...@@ -231,9 +233,12 @@ export default { ...@@ -231,9 +233,12 @@ export default {
<gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" /> <gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" />
<small v-else class="gl-font-sm gl-font-style-italic gl-text-gray-200">{{ <NodeErrorHelpText
__('Unknown') v-else-if="item.kubernetes_errors"
}}</small> :class="contentAlignClasses"
:error-type="item.kubernetes_errors.connection_error"
:popover-id="`nodeSizeError${item.id}`"
/>
</template> </template>
<template #cell(total_cpu)="{ item }"> <template #cell(total_cpu)="{ item }">
...@@ -250,6 +255,13 @@ export default { ...@@ -250,6 +255,13 @@ export default {
</span> </span>
<gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" /> <gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" />
<NodeErrorHelpText
v-else-if="item.kubernetes_errors"
:class="contentAlignClasses"
:error-type="item.kubernetes_errors.node_connection_error"
:popover-id="`nodeCpuError${item.id}`"
/>
</template> </template>
<template #cell(total_memory)="{ item }"> <template #cell(total_memory)="{ item }">
...@@ -266,6 +278,13 @@ export default { ...@@ -266,6 +278,13 @@ export default {
</span> </span>
<gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" /> <gl-skeleton-loading v-else-if="loadingNodes" :lines="1" :class="contentAlignClasses" />
<NodeErrorHelpText
v-else-if="item.kubernetes_errors"
:class="contentAlignClasses"
:error-type="item.kubernetes_errors.metrics_connection_error"
:popover-id="`nodeMemoryError${item.id}`"
/>
</template> </template>
<template #cell(cluster_type)="{value}"> <template #cell(cluster_type)="{value}">
......
<script>
import { GlIcon, GlPopover } from '@gitlab/ui';
import { CLUSTER_ERRORS } from '../constants';
export default {
components: {
GlIcon,
GlPopover,
},
props: {
errorType: {
type: String,
required: false,
default: '',
},
popoverId: {
type: String,
required: true,
},
},
computed: {
errorContent() {
return CLUSTER_ERRORS[this.errorType] || CLUSTER_ERRORS.default;
},
},
};
</script>
<template>
<div :id="popoverId">
<span class="gl-font-style-italic">
{{ errorContent.tableText }}
</span>
<gl-icon name="status_warning" :size="24" class="gl-p-2" />
<gl-popover :container="popoverId" :target="popoverId" placement="top" triggers="hover focus">
<template #title>
<span class="gl-display-block gl-text-left">{{ errorContent.title }}</span>
</template>
<p class="gl-text-left">{{ errorContent.description }}</p>
<p class="gl-text-left">{{ s__('ClusterIntegration|Troubleshooting tips:') }}</p>
<ul class="gl-text-left">
<li v-for="tip in errorContent.troubleshootingTips" :key="tip">
{{ tip }}
</li>
</ul>
</gl-popover>
</div>
</template>
import { __ } from '~/locale'; import { __, s__ } from '~/locale';
export const CLUSTER_ERRORS = {
default: {
tableText: s__('ClusterIntegration|Unknown Error'),
title: s__('ClusterIntegration|Unknown Error'),
description: s__(
'ClusterIntegration|An unknown error occurred while attempting to connect to Kubernetes.',
),
troubleshootingTips: [
s__('ClusterIntegration|Check your cluster status'),
s__('ClusterIntegration|Make sure your API endpoint is correct'),
s__(
'ClusterIntegration|Node calculations use the Kubernetes Metrics API. Make sure your cluster has metrics installed',
),
],
},
authentication_error: {
tableText: s__('ClusterIntegration|Unable to Authenticate'),
title: s__('ClusterIntegration|Authentication Error'),
description: s__('ClusterIntegration|GitLab failed to authenticate.'),
troubleshootingTips: [
s__('ClusterIntegration|Check your token'),
s__('ClusterIntegration|Check your CA certificate'),
],
},
connection_error: {
tableText: s__('ClusterIntegration|Unable to Connect'),
title: s__('ClusterIntegration|Connection Error'),
description: s__('ClusterIntegration|GitLab failed to connect to the cluster.'),
troubleshootingTips: [
s__('ClusterIntegration|Check your cluster status'),
s__('ClusterIntegration|Make sure your API endpoint is correct'),
],
},
http_error: {
tableText: s__('ClusterIntegration|Unable to Connect'),
title: s__('ClusterIntegration|HTTP Error'),
description: s__('ClusterIntegration|There was an HTTP error when connecting to your cluster.'),
troubleshootingTips: [s__('ClusterIntegration|Check your cluster status')],
},
};
export const CLUSTER_TYPES = { export const CLUSTER_TYPES = {
project_type: __('Project'), project_type: __('Project'),
......
...@@ -6,6 +6,7 @@ class ClusterEntity < Grape::Entity ...@@ -6,6 +6,7 @@ class ClusterEntity < Grape::Entity
expose :cluster_type expose :cluster_type
expose :enabled expose :enabled
expose :environment_scope expose :environment_scope
expose :id
expose :name expose :name
expose :nodes expose :nodes
expose :provider_type expose :provider_type
......
...@@ -12,6 +12,7 @@ class ClusterSerializer < BaseSerializer ...@@ -12,6 +12,7 @@ class ClusterSerializer < BaseSerializer
:environment_scope, :environment_scope,
:gitlab_managed_apps_logs_path, :gitlab_managed_apps_logs_path,
:enable_advanced_logs_querying, :enable_advanced_logs_querying,
:id,
:kubernetes_errors, :kubernetes_errors,
:name, :name,
:nodes, :nodes,
......
...@@ -5374,6 +5374,9 @@ msgstr "" ...@@ -5374,6 +5374,9 @@ msgstr ""
msgid "ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}" msgid "ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}"
msgstr "" msgstr ""
msgid "ClusterIntegration|An unknown error occurred while attempting to connect to Kubernetes."
msgstr ""
msgid "ClusterIntegration|Any project namespaces" msgid "ClusterIntegration|Any project namespaces"
msgstr "" msgstr ""
...@@ -5389,6 +5392,9 @@ msgstr "" ...@@ -5389,6 +5392,9 @@ msgstr ""
msgid "ClusterIntegration|Authenticate with Amazon Web Services" msgid "ClusterIntegration|Authenticate with Amazon Web Services"
msgstr "" msgstr ""
msgid "ClusterIntegration|Authentication Error"
msgstr ""
msgid "ClusterIntegration|Base domain" msgid "ClusterIntegration|Base domain"
msgstr "" msgstr ""
...@@ -5407,6 +5413,15 @@ msgstr "" ...@@ -5407,6 +5413,15 @@ msgstr ""
msgid "ClusterIntegration|Certificate Authority bundle (PEM format)" msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
msgstr "" msgstr ""
msgid "ClusterIntegration|Check your CA certificate"
msgstr ""
msgid "ClusterIntegration|Check your cluster status"
msgstr ""
msgid "ClusterIntegration|Check your token"
msgstr ""
msgid "ClusterIntegration|Choose the %{startLink}security group %{externalLinkIcon} %{endLink} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets." msgid "ClusterIntegration|Choose the %{startLink}security group %{externalLinkIcon} %{endLink} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets."
msgstr "" msgstr ""
...@@ -5449,6 +5464,9 @@ msgstr "" ...@@ -5449,6 +5464,9 @@ msgstr ""
msgid "ClusterIntegration|Connect existing cluster" msgid "ClusterIntegration|Connect existing cluster"
msgstr "" msgstr ""
msgid "ClusterIntegration|Connection Error"
msgstr ""
msgid "ClusterIntegration|Copy API URL" msgid "ClusterIntegration|Copy API URL"
msgstr "" msgstr ""
...@@ -5605,6 +5623,12 @@ msgstr "" ...@@ -5605,6 +5623,12 @@ msgstr ""
msgid "ClusterIntegration|GitLab Runner connects to the repository and executes CI/CD jobs, pushing results back and deploying applications to production." msgid "ClusterIntegration|GitLab Runner connects to the repository and executes CI/CD jobs, pushing results back and deploying applications to production."
msgstr "" msgstr ""
msgid "ClusterIntegration|GitLab failed to authenticate."
msgstr ""
msgid "ClusterIntegration|GitLab failed to connect to the cluster."
msgstr ""
msgid "ClusterIntegration|GitLab-managed cluster" msgid "ClusterIntegration|GitLab-managed cluster"
msgstr "" msgstr ""
...@@ -5626,6 +5650,9 @@ msgstr "" ...@@ -5626,6 +5650,9 @@ msgstr ""
msgid "ClusterIntegration|Group cluster" msgid "ClusterIntegration|Group cluster"
msgstr "" msgstr ""
msgid "ClusterIntegration|HTTP Error"
msgstr ""
msgid "ClusterIntegration|Helm Tiller" msgid "ClusterIntegration|Helm Tiller"
msgstr "" msgstr ""
...@@ -5770,6 +5797,9 @@ msgstr "" ...@@ -5770,6 +5797,9 @@ msgstr ""
msgid "ClusterIntegration|Machine type" msgid "ClusterIntegration|Machine type"
msgstr "" msgstr ""
msgid "ClusterIntegration|Make sure your API endpoint is correct"
msgstr ""
msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to create Kubernetes clusters" msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to create Kubernetes clusters"
msgstr "" msgstr ""
...@@ -5821,6 +5851,9 @@ msgstr "" ...@@ -5821,6 +5851,9 @@ msgstr ""
msgid "ClusterIntegration|No zones matched your search" msgid "ClusterIntegration|No zones matched your search"
msgstr "" msgstr ""
msgid "ClusterIntegration|Node calculations use the Kubernetes Metrics API. Make sure your cluster has metrics installed"
msgstr ""
msgid "ClusterIntegration|Number of nodes" msgid "ClusterIntegration|Number of nodes"
msgstr "" msgstr ""
...@@ -6088,6 +6121,9 @@ msgstr "" ...@@ -6088,6 +6121,9 @@ msgstr ""
msgid "ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid." msgid "ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid."
msgstr "" msgstr ""
msgid "ClusterIntegration|There was an HTTP error when connecting to your cluster."
msgstr ""
msgid "ClusterIntegration|This account must have permissions to create a Kubernetes cluster in the %{link_to_container_project} specified below" msgid "ClusterIntegration|This account must have permissions to create a Kubernetes cluster in the %{link_to_container_project} specified below"
msgstr "" msgstr ""
...@@ -6115,9 +6151,21 @@ msgstr "" ...@@ -6115,9 +6151,21 @@ msgstr ""
msgid "ClusterIntegration|To use a new project, first create one on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}." msgid "ClusterIntegration|To use a new project, first create one on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}."
msgstr "" msgstr ""
msgid "ClusterIntegration|Troubleshooting tips:"
msgstr ""
msgid "ClusterIntegration|Unable to Authenticate"
msgstr ""
msgid "ClusterIntegration|Unable to Connect"
msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}" msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr "" msgstr ""
msgid "ClusterIntegration|Unknown Error"
msgstr ""
msgid "ClusterIntegration|Update %{appTitle}" msgid "ClusterIntegration|Update %{appTitle}"
msgstr "" msgstr ""
......
...@@ -164,18 +164,18 @@ describe('Clusters', () => { ...@@ -164,18 +164,18 @@ describe('Clusters', () => {
}); });
it.each` it.each`
nodeSize | lineNumber nodeText | lineNumber
${'Unknown'} | ${0} ${'Unable to Authenticate'} | ${0}
${'1'} | ${1} ${'1'} | ${1}
${'2'} | ${2} ${'2'} | ${2}
${'1'} | ${3} ${'1'} | ${3}
${'1'} | ${4} ${'1'} | ${4}
${'Unknown'} | ${5} ${'Unknown Error'} | ${5}
`('renders node size for each cluster', ({ nodeSize, lineNumber }) => { `('renders node size for each cluster', ({ nodeText, lineNumber }) => {
const sizes = findTable().findAll('td:nth-child(3)'); const sizes = findTable().findAll('td:nth-child(3)');
const size = sizes.at(lineNumber); const size = sizes.at(lineNumber);
expect(size.text()).toBe(nodeSize); expect(size.text()).toContain(nodeText);
expect(size.find(GlSkeletonLoading).exists()).toBe(false); expect(size.find(GlSkeletonLoading).exists()).toBe(false);
}); });
}); });
......
import { shallowMount } from '@vue/test-utils';
import { GlPopover } from '@gitlab/ui';
import NodeErrorHelpText from '~/clusters_list/components/node_error_help_text.vue';
describe('NodeErrorHelpText', () => {
let wrapper;
const createWrapper = propsData => {
wrapper = shallowMount(NodeErrorHelpText, { propsData, stubs: { GlPopover } });
return wrapper.vm.$nextTick();
};
const findPopover = () => wrapper.find(GlPopover);
afterEach(() => {
wrapper.destroy();
});
it.each`
errorType | wrapperText | popoverText
${'authentication_error'} | ${'Unable to Authenticate'} | ${'GitLab failed to authenticate'}
${'connection_error'} | ${'Unable to Connect'} | ${'GitLab failed to connect to the cluster'}
${'http_error'} | ${'Unable to Connect'} | ${'There was an HTTP error when connecting to your cluster'}
${'default'} | ${'Unknown Error'} | ${'An unknown error occurred while attempting to connect to Kubernetes.'}
${'unknown_error_type'} | ${'Unknown Error'} | ${'An unknown error occurred while attempting to connect to Kubernetes.'}
${null} | ${'Unknown Error'} | ${'An unknown error occurred while attempting to connect to Kubernetes.'}
`('displays error text', ({ errorType, wrapperText, popoverText }) => {
return createWrapper({ errorType, popoverId: 'id' }).then(() => {
expect(wrapper.text()).toContain(wrapperText);
expect(findPopover().text()).toContain(popoverText);
});
});
});
...@@ -6,6 +6,11 @@ export const clusterList = [ ...@@ -6,6 +6,11 @@ export const clusterList = [
provider_type: 'gcp', provider_type: 'gcp',
status: 'creating', status: 'creating',
nodes: null, nodes: null,
kubernetes_errors: {
connection_error: 'authentication_error',
node_connection_error: 'connection_error',
metrics_connection_error: 'http_error',
},
}, },
{ {
name: 'My Cluster 2', name: 'My Cluster 2',
...@@ -19,6 +24,7 @@ export const clusterList = [ ...@@ -19,6 +24,7 @@ export const clusterList = [
usage: { cpu: '246155922n', memory: '1255212Ki' }, usage: { cpu: '246155922n', memory: '1255212Ki' },
}, },
], ],
kubernetes_errors: {},
}, },
{ {
name: 'My Cluster 3', name: 'My Cluster 3',
...@@ -36,6 +42,7 @@ export const clusterList = [ ...@@ -36,6 +42,7 @@ export const clusterList = [
usage: { cpu: '307051934n', memory: '1379136Ki' }, usage: { cpu: '307051934n', memory: '1379136Ki' },
}, },
], ],
kubernetes_errors: {},
}, },
{ {
name: 'My Cluster 4', name: 'My Cluster 4',
...@@ -48,6 +55,7 @@ export const clusterList = [ ...@@ -48,6 +55,7 @@ export const clusterList = [
usage: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' }, usage: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' },
}, },
], ],
kubernetes_errors: {},
}, },
{ {
name: 'My Cluster 5', name: 'My Cluster 5',
...@@ -59,12 +67,14 @@ export const clusterList = [ ...@@ -59,12 +67,14 @@ export const clusterList = [
status: { allocatable: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' } }, status: { allocatable: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' } },
}, },
], ],
kubernetes_errors: {},
}, },
{ {
name: 'My Cluster 6', name: 'My Cluster 6',
environment_scope: '*', environment_scope: '*',
cluster_type: 'project_type', cluster_type: 'project_type',
status: 'cleanup_ongoing', status: 'cleanup_ongoing',
kubernetes_errors: {},
}, },
]; ];
......
...@@ -13,6 +13,7 @@ RSpec.describe ClusterSerializer do ...@@ -13,6 +13,7 @@ RSpec.describe ClusterSerializer do
:cluster_type, :cluster_type,
:enabled, :enabled,
:environment_scope, :environment_scope,
:id,
:gitlab_managed_apps_logs_path, :gitlab_managed_apps_logs_path,
:enable_advanced_logs_querying, :enable_advanced_logs_querying,
:kubernetes_errors, :kubernetes_errors,
......
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