Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No operator action required issues #1040

Merged
merged 8 commits into from
Jun 25, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions frontend/src/components/ShootMessageDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ SPDX-License-Identifier: Apache-2.0
<div v-for="(lastErrorDescription, index) in errorDescriptions" :key="index">
<v-divider v-if="index > 0" class="my-2"></v-divider>
<v-alert
v-for="({ description, userError, infraAccountError }) in lastErrorDescription.errorCodeObjects" :key="description"
v-for="({description, userError, infraAccountError}) in lastErrorDescription.errorCodeObjects" :key="description"
color="error"
:icon="userError ? 'mdi-account-alert' : 'mdi-alert'"
:prominent="!!userError ? true : false"
:prominent="!!userError"
>
<h4 v-if="userError">Action required</h4>
<span class="wrap">
Expand Down
11 changes: 5 additions & 6 deletions frontend/src/components/ShootStatus.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0
<div v-on="on">
<v-progress-circular v-if="showProgress" class="vertical-align-middle cursor-pointer" :size="27" :width="3" :value="shootLastOperation.progress" :color="color" :rotate="-90">
<v-icon v-if="isShootStatusHibernated" class="vertical-align-middle progress-icon" :color="color">mdi-sleep</v-icon>
<v-icon v-else-if="isUserError" class="vertical-align-middle progress-icon-user-error" color="error">mdi-account-alert</v-icon>
<v-icon v-else-if="isUserError" class="vertical-align-middle progress-icon-user-error" :color="color">mdi-account-alert</v-icon>
<v-icon v-else-if="isShootLastOperationTypeDelete" class="vertical-align-middle progress-icon" :color="color">mdi-delete</v-icon>
<v-icon v-else-if="isTypeCreate" class="vertical-align-middle progress-icon" :color="color">mdi-plus</v-icon>
<v-icon v-else-if="isTypeReconcile && !isError" class="vertical-align-middle progress-icon-check" :color="color">mdi-check</v-icon>
Expand All @@ -33,8 +33,8 @@ SPDX-License-Identifier: Apache-2.0
<div>
<span class="font-weight-bold">{{tooltip.title}}</span>
<span v-if="tooltip.progress" class="ml-1">({{tooltip.progress}}%)</span>
<div v-for="({ shortDescription }) in tooltip.userErrorCodeObjects" :key="shortDescription">
<v-icon class="mr-1" color="white" small>mdi-account-alert</v-icon>
<div v-for="({ shortDescription, userError }) in tooltip.errorCodeObjects" :key="shortDescription">
<v-icon v-if="userError" class="mr-1" color="white" small>{{ userError ? 'mdi-account-alert' : 'mdi-alert' }}</v-icon>
<span class="font-weight-bold text--lighten-2">{{shortDescription}}</span>
</div>
</div>
Expand All @@ -43,7 +43,7 @@ SPDX-License-Identifier: Apache-2.0
<span v-if="showStatusText" class="d-flex align-center ml-2">{{statusTitle}}</span>
</div>
<template v-if="showStatusText">
<div v-for="({ description }) in tooltip.userErrorCodeObjects" :key="description">
<div v-for="({ description }) in tooltip.errorCodeObjects" :key="description">
<div class="font-weight-bold error--text wrap">{{description}}</div>
</div>
</template>
Expand All @@ -62,7 +62,6 @@ SPDX-License-Identifier: Apache-2.0
<script>
import join from 'lodash/join'
import map from 'lodash/map'
import filter from 'lodash/filter'

import GPopper from '@/components/GPopper'
import RetryOperation from '@/components/RetryOperation'
Expand Down Expand Up @@ -150,7 +149,7 @@ export default {
return {
title: this.statusTitle,
progress: this.showProgress ? this.shootLastOperation.progress : undefined,
userErrorCodeObjects: filter(objectsFromErrorCodes(this.allErrorCodes), { userError: true })
errorCodeObjects: objectsFromErrorCodes(this.allErrorCodes)
}
},
operationType () {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/router/guards.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function ensureDataLoaded (store, localStorage) {
const defaultFilter = {
onlyShootsWithIssues: isAdmin,
progressing: true,
userIssues: isAdmin,
noOperatorAction: isAdmin,
deactivatedReconciliation: isAdmin,
hideTicketsWithLabel: isAdmin
}
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/store/modules/shoots/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
randomMaintenanceBegin,
maintenanceWindowWithBeginAndTimezone
} from '@/utils'
import { isUserError, errorCodesFromArray } from '@/utils/errorCodes'
import { isUserError, isTemporaryError, errorCodesFromArray } from '@/utils/errorCodes'
import find from 'lodash/find'

const uriPattern = /^([^:/?#]+:)?(\/\/[^/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/
Expand Down Expand Up @@ -287,13 +287,15 @@ function setFilteredItems (state, rootState) {
}
items = filter(items, predicate)
}
if (get(state, 'shootListFilters.userIssues', false)) {
if (get(state, 'shootListFilters.noOperatorAction', false)) {
const predicate = item => {
const lastErrors = get(item, 'status.lastErrors', [])
const allLastErrorCodes = errorCodesFromArray(lastErrors)
const conditions = get(item, 'status.conditions', [])
const allConditionCodes = errorCodesFromArray(conditions)
return !isUserError(allLastErrorCodes) && !isUserError(allConditionCodes)
const noUserError = !isUserError(allLastErrorCodes) && !isUserError(allConditionCodes)
const noTemporaryError = !isTemporaryError(allLastErrorCodes)
return noUserError && noTemporaryError
}
items = filter(items, predicate)
}
Expand Down
24 changes: 23 additions & 1 deletion frontend/src/utils/errorCodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ export function isUserError (errorCodesArray) {
return false
}

return find(objectsFromErrorCodes(errorCodesArray), { userError: true })
return !!find(objectsFromErrorCodes(errorCodesArray), 'userError')
}

export function isTemporaryError (errorCodesArray) {
if (isEmpty(errorCodesArray)) {
return false
}

return !!find(objectsFromErrorCodes(errorCodesArray), 'temporaryError')
}

export function objectsFromErrorCodes (errorCodesArray) {
Expand All @@ -34,46 +42,60 @@ const errorCodes = {
ERR_INFRA_UNAUTHORIZED: {
shortDescription: 'Invalid Credentials',
description: 'Invalid cloud provider credentials.',
temporaryError: false,
userError: true,
infraAccountError: true
},
ERR_INFRA_INSUFFICIENT_PRIVILEGES: {
shortDescription: 'Insufficient Privileges',
description: 'Cloud provider credentials have insufficient privileges.',
temporaryError: false,
userError: true,
infraAccountError: true
},
ERR_INFRA_QUOTA_EXCEEDED: {
shortDescription: 'Quota Exceeded',
description: 'Cloud provider quota exceeded. Please request limit increases.',
temporaryError: false,
userError: true,
infraAccountError: true
},
ERR_INFRA_DEPENDENCIES: {
shortDescription: 'Infrastructure Dependencies',
description: 'Infrastructure operation failed as unmanaged resources exist in your cloud provider account. Please delete all manually created resources related to this Shoot.',
temporaryError: false,
userError: true,
infraAccountError: true
},
ERR_CLEANUP_CLUSTER_RESOURCES: {
shortDescription: 'Cleanup Cluster',
description: 'Cleaning up the cluster failed as some resource are stuck in deletion. Please remove these resources properly or a forceful deletion will happen if this error persists.',
temporaryError: false,
userError: true
},
ERR_INFRA_RESOURCES_DEPLETED: {
shortDescription: 'Infrastructure Resources Depleted',
description: 'The underlying infrastructure provider proclaimed that it does not have enough resources to fulfill your request at this point in time. You might want to wait or change your shoot configuration.',
temporaryError: false,
userError: true,
infraAccountError: true
},
ERR_CONFIGURATION_PROBLEM: {
shortDescription: 'Configuration Problem',
description: 'There is a configuration problem that is most likely caused by your Shoot specification. Please double-check the error message and resolve the problem.',
temporaryError: false,
userError: true
},
ERR_RETRYABLE_CONFIGURATION_PROBLEM: {
shortDescription: 'Configuration Problem',
description: 'There is a configuration problem. Please double-check the error message and resolve the problem.',
temporaryError: false,
userError: true
},
ERR_INFRA_REQUEST_THROTTLING: {
shortDescription: 'Rate Limit Exceeded',
description: 'Cloud provider rate limit exceeded. The operation will be retried automatically.',
temporaryError: true,
userError: false
}
}
21 changes: 16 additions & 5 deletions frontend/src/views/ShootList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,13 @@ export default {
const key = value
await this.setShootListFilter({ filter: key, value: !this.getShootListFilters[key] })

this.$localStorage.setObject('project/_all/shoot-list/filter', pick(this.getShootListFilters, ['onlyShootsWithIssues', 'progressing', 'userIssues', 'deactivatedReconciliation', 'hideTicketsWithLabel']))
this.$localStorage.setObject('project/_all/shoot-list/filter', pick(this.getShootListFilters, [
'onlyShootsWithIssues',
'progressing',
'noOperatorAction',
'deactivatedReconciliation',
'hideTicketsWithLabel'
]))

if (key === 'onlyShootsWithIssues') {
this.subscribeShoots()
Expand Down Expand Up @@ -461,10 +467,15 @@ export default {
disabled: this.filtersDisabled
},
{
text: 'Hide user issues',
value: 'userIssues',
selected: this.isFilterActive('userIssues'),
text: 'Hide no operator action required issues',
value: 'noOperatorAction',
selected: this.isFilterActive('noOperatorAction'),
hidden: this.projectScope || !this.isAdmin,
helpTooltip: [
'Hide clusters that do not require action by an operator',
'- Clusters with user issues',
'- Clusters with temporary issues that will be retried automatically'
],
disabled: this.filtersDisabled
},
{
Expand Down Expand Up @@ -516,7 +527,7 @@ export default {
if (this.isFilterActive('progressing')) {
subtitle.push('Progressing Clusters')
}
if (this.isFilterActive('userIssues')) {
if (this.isFilterActive('noOperatorAction')) {
subtitle.push('User Errors')
}
if (this.isFilterActive('deactivatedReconciliation')) {
Expand Down