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 {
GlTable,
} from '@gitlab/ui';
import AncestorNotice from './ancestor_notice.vue';
import NodeErrorHelpText from './node_error_help_text.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import { CLUSTER_TYPES, STATUSES } from '../constants';
import { __, sprintf } from '~/locale';
......@@ -26,6 +27,7 @@ export default {
GlSkeletonLoading,
GlSprintf,
GlTable,
NodeErrorHelpText,
},
directives: {
tooltip,
......@@ -231,9 +233,12 @@ export default {
<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">{{
__('Unknown')
}}</small>
<NodeErrorHelpText
v-else-if="item.kubernetes_errors"
:class="contentAlignClasses"
:error-type="item.kubernetes_errors.connection_error"
:popover-id="`nodeSizeError${item.id}`"
/>
</template>
<template #cell(total_cpu)="{ item }">
......@@ -250,6 +255,13 @@ export default {
</span>
<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 #cell(total_memory)="{ item }">
......@@ -266,6 +278,13 @@ export default {
</span>
<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 #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 = {
project_type: __('Project'),
......
......@@ -6,6 +6,7 @@ class ClusterEntity < Grape::Entity
expose :cluster_type
expose :enabled
expose :environment_scope
expose :id
expose :name
expose :nodes
expose :provider_type
......
......@@ -12,6 +12,7 @@ class ClusterSerializer < BaseSerializer
:environment_scope,
:gitlab_managed_apps_logs_path,
:enable_advanced_logs_querying,
:id,
:kubernetes_errors,
:name,
:nodes,
......
......@@ -5374,6 +5374,9 @@ msgstr ""
msgid "ClusterIntegration|An error occurred while trying to fetch zone machine types: %{error}"
msgstr ""
msgid "ClusterIntegration|An unknown error occurred while attempting to connect to Kubernetes."
msgstr ""
msgid "ClusterIntegration|Any project namespaces"
msgstr ""
......@@ -5389,6 +5392,9 @@ msgstr ""
msgid "ClusterIntegration|Authenticate with Amazon Web Services"
msgstr ""
msgid "ClusterIntegration|Authentication Error"
msgstr ""
msgid "ClusterIntegration|Base domain"
msgstr ""
......@@ -5407,6 +5413,15 @@ msgstr ""
msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
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."
msgstr ""
......@@ -5449,6 +5464,9 @@ msgstr ""
msgid "ClusterIntegration|Connect existing cluster"
msgstr ""
msgid "ClusterIntegration|Connection Error"
msgstr ""
msgid "ClusterIntegration|Copy API URL"
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."
msgstr ""
msgid "ClusterIntegration|GitLab failed to authenticate."
msgstr ""
msgid "ClusterIntegration|GitLab failed to connect to the cluster."
msgstr ""
msgid "ClusterIntegration|GitLab-managed cluster"
msgstr ""
......@@ -5626,6 +5650,9 @@ msgstr ""
msgid "ClusterIntegration|Group cluster"
msgstr ""
msgid "ClusterIntegration|HTTP Error"
msgstr ""
msgid "ClusterIntegration|Helm Tiller"
msgstr ""
......@@ -5770,6 +5797,9 @@ msgstr ""
msgid "ClusterIntegration|Machine type"
msgstr ""
msgid "ClusterIntegration|Make sure your API endpoint is correct"
msgstr ""
msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to create Kubernetes clusters"
msgstr ""
......@@ -5821,6 +5851,9 @@ msgstr ""
msgid "ClusterIntegration|No zones matched your search"
msgstr ""
msgid "ClusterIntegration|Node calculations use the Kubernetes Metrics API. Make sure your cluster has metrics installed"
msgstr ""
msgid "ClusterIntegration|Number of nodes"
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."
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"
msgstr ""
......@@ -6115,9 +6151,21 @@ msgstr ""
msgid "ClusterIntegration|To use a new project, first create one on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}."
msgstr ""
msgid "ClusterIntegration|Troubleshooting tips:"
msgstr ""
msgid "ClusterIntegration|Unable to Authenticate"
msgstr ""
msgid "ClusterIntegration|Unable to Connect"
msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
msgid "ClusterIntegration|Unknown Error"
msgstr ""
msgid "ClusterIntegration|Update %{appTitle}"
msgstr ""
......
......@@ -164,18 +164,18 @@ describe('Clusters', () => {
});
it.each`
nodeSize | lineNumber
${'Unknown'} | ${0}
${'1'} | ${1}
${'2'} | ${2}
${'1'} | ${3}
${'1'} | ${4}
${'Unknown'} | ${5}
`('renders node size for each cluster', ({ nodeSize, lineNumber }) => {
nodeText | lineNumber
${'Unable to Authenticate'} | ${0}
${'1'} | ${1}
${'2'} | ${2}
${'1'} | ${3}
${'1'} | ${4}
${'Unknown Error'} | ${5}
`('renders node size for each cluster', ({ nodeText, lineNumber }) => {
const sizes = findTable().findAll('td:nth-child(3)');
const size = sizes.at(lineNumber);
expect(size.text()).toBe(nodeSize);
expect(size.text()).toContain(nodeText);
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 = [
provider_type: 'gcp',
status: 'creating',
nodes: null,
kubernetes_errors: {
connection_error: 'authentication_error',
node_connection_error: 'connection_error',
metrics_connection_error: 'http_error',
},
},
{
name: 'My Cluster 2',
......@@ -19,6 +24,7 @@ export const clusterList = [
usage: { cpu: '246155922n', memory: '1255212Ki' },
},
],
kubernetes_errors: {},
},
{
name: 'My Cluster 3',
......@@ -36,6 +42,7 @@ export const clusterList = [
usage: { cpu: '307051934n', memory: '1379136Ki' },
},
],
kubernetes_errors: {},
},
{
name: 'My Cluster 4',
......@@ -48,6 +55,7 @@ export const clusterList = [
usage: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' },
},
],
kubernetes_errors: {},
},
{
name: 'My Cluster 5',
......@@ -59,12 +67,14 @@ export const clusterList = [
status: { allocatable: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' } },
},
],
kubernetes_errors: {},
},
{
name: 'My Cluster 6',
environment_scope: '*',
cluster_type: 'project_type',
status: 'cleanup_ongoing',
kubernetes_errors: {},
},
];
......
......@@ -13,6 +13,7 @@ RSpec.describe ClusterSerializer do
:cluster_type,
:enabled,
:environment_scope,
:id,
:gitlab_managed_apps_logs_path,
:enable_advanced_logs_querying,
: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