dashboard-shell-shell 3.0.5-test.41 → 3.0.5-test.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/translations/en-us.yaml +1 -0
- package/assets/translations/zh-hans.yaml +9 -0
- package/components/CruResource.vue +3 -2
- package/components/ResourceTable.vue +6 -0
- package/components/SingleClusterInfo.vue +2 -1
- package/components/auth/Principal.vue +1 -1
- package/components/form/Members/MembershipEditor.vue +1 -1
- package/components/form/Members/ProjectMembershipEditor.vue +1 -1
- package/config/product/explorer.js +1 -1
- package/dialog/RollbackWorkloadDialog.vue +1 -1
- package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +8 -6
- package/mixins/create-edit-view/impl.js +10 -0
- package/package.json +1 -1
- package/pages/c/_cluster/explorer/index.vue +2 -1
- package/plugins/dashboard-store/actions.js +23 -0
- package/rancher-components/Banner/Banner.vue +2 -0
- package/scripts/publish-shell.sh +1 -1
- package/types/shell/index.d.ts +1 -0
- package/utils/error.js +12 -3
- package/utils/errorTranslate.json +12 -0
- package/utils/errorTranslateNew.json +44 -0
|
@@ -6464,6 +6464,7 @@ storageClass:
|
|
|
6464
6464
|
tooltip: By default the default storage class on the host Harvester cluster is used.
|
|
6465
6465
|
|
|
6466
6466
|
tableHeaders:
|
|
6467
|
+
claimedby: claimedby
|
|
6467
6468
|
pod: pod
|
|
6468
6469
|
volumeattributesclass: volumeattributesclass
|
|
6469
6470
|
assuredConcurrencyShares: Assured Concurrency Shares
|
|
@@ -796,6 +796,10 @@ asyncButton:
|
|
|
796
796
|
action: 恢复编排
|
|
797
797
|
success: 已恢复编排
|
|
798
798
|
waiting: 正在恢复编排
|
|
799
|
+
redeploy:
|
|
800
|
+
action: 重新部署
|
|
801
|
+
success: 重新部署成功
|
|
802
|
+
waiting: 正在重新部署工作负载
|
|
799
803
|
rollback:
|
|
800
804
|
action: 回滚
|
|
801
805
|
success: 已回滚
|
|
@@ -4592,6 +4596,10 @@ promptRollback:
|
|
|
4592
4596
|
multipleWorkloadError: "一次只能回滚一个工作负载。"
|
|
4593
4597
|
singleRevisionBanner: 没有可用于回滚的修订版本。
|
|
4594
4598
|
|
|
4599
|
+
promptRedeploy:
|
|
4600
|
+
title: 重新部署 {type}?
|
|
4601
|
+
attemptingToRedeploy: "您正在尝试重新部署 {type} {names} 重新部署将重启所选工作负载,可能导致暂时性服务中断。"
|
|
4602
|
+
|
|
4595
4603
|
promptSaveAsRKETemplate:
|
|
4596
4604
|
title: 将 {cluster} 转换为新的 RKE 模板
|
|
4597
4605
|
name: 集群模板名称
|
|
@@ -5442,6 +5450,7 @@ storageClass:
|
|
|
5442
5450
|
tooltip: 默认使用主机 Cloud 集群上的默认存储类。
|
|
5443
5451
|
|
|
5444
5452
|
tableHeaders:
|
|
5453
|
+
claimedby: 占用者
|
|
5445
5454
|
pod: pod
|
|
5446
5455
|
ip: ip
|
|
5447
5456
|
volumeattributesclass: 卷属性类
|
|
@@ -623,13 +623,14 @@ export default {
|
|
|
623
623
|
/>
|
|
624
624
|
<span v-else>{{ subtype.label }}</span>
|
|
625
625
|
</h5>
|
|
626
|
-
|
|
626
|
+
<!-- 禅道 3541 隐藏 更多信息 -->
|
|
627
|
+
<!-- <a
|
|
627
628
|
v-if="subtype.docLink"
|
|
628
629
|
:href="subtype.docLink"
|
|
629
630
|
target="_blank"
|
|
630
631
|
rel="noopener nofollow"
|
|
631
632
|
class="flex-right"
|
|
632
|
-
>{{ t('generic.moreInfo') }} <i class="icon icon-external-link" /></a>
|
|
633
|
+
>{{ t('generic.moreInfo') }} <i class="icon icon-external-link" /></a> -->
|
|
633
634
|
</div>
|
|
634
635
|
<hr
|
|
635
636
|
v-if="subtype.description"
|
|
@@ -97,7 +97,7 @@ export default {
|
|
|
97
97
|
<div :style="userLogoSize === 79 ? { width: '287px' } : {}" class="avatar">
|
|
98
98
|
<img
|
|
99
99
|
:style="{ width: userLogoSize + 'px', height: userLogoSize + 'px' }"
|
|
100
|
-
src="@shell/assets/images/user.png"
|
|
100
|
+
:src="require('@shell/assets/images/user.png')"
|
|
101
101
|
:class="{'round': principal.roundAvatar}"
|
|
102
102
|
:alt="t('principal.alt.avatar')"
|
|
103
103
|
>
|
|
@@ -170,7 +170,7 @@ export default {
|
|
|
170
170
|
>
|
|
171
171
|
<template #column-headers>
|
|
172
172
|
<div class="box mb-0">
|
|
173
|
-
<div class="column-headers row" style="width: calc(100% - 100px)
|
|
173
|
+
<div class="column-headers row" :style="{ width: (isCreate && i === 0) || isView ? '100%' : 'calc(100% - 100px)' }">
|
|
174
174
|
<div class="col span-6">
|
|
175
175
|
<label class="text-label">{{ t('membershipEditor.user') }}</label>
|
|
176
176
|
</div>
|
|
@@ -655,7 +655,7 @@ export function init(store) {
|
|
|
655
655
|
virtualType({
|
|
656
656
|
label: store.getters['i18n/t'](`typeLabel.${ VIRTUAL_TYPES.PROJECT_SECRETS }`, { count: 2 }),
|
|
657
657
|
group: 'storage',
|
|
658
|
-
icon: '
|
|
658
|
+
icon: 'default',
|
|
659
659
|
namespaced: false,
|
|
660
660
|
ifRancherCluster: true,
|
|
661
661
|
name: VIRTUAL_TYPES.PROJECT_SECRETS,
|
|
@@ -37,15 +37,17 @@ export default {
|
|
|
37
37
|
|
|
38
38
|
<template>
|
|
39
39
|
<div>
|
|
40
|
-
<Banner
|
|
41
|
-
color="info"
|
|
42
|
-
:label="t('podSecurityAdmission.banner.modifications')"
|
|
43
|
-
/>
|
|
44
|
-
|
|
45
40
|
<ResourceTable
|
|
46
41
|
:loading="loading"
|
|
47
42
|
:schema="schema"
|
|
48
43
|
:rows="rows"
|
|
49
|
-
|
|
44
|
+
>
|
|
45
|
+
<template #banner>
|
|
46
|
+
<Banner
|
|
47
|
+
color="info"
|
|
48
|
+
:label="t('podSecurityAdmission.banner.modifications')"
|
|
49
|
+
/>
|
|
50
|
+
</template>
|
|
51
|
+
</ResourceTable>
|
|
50
52
|
</div>
|
|
51
53
|
</template>
|
|
@@ -170,6 +170,16 @@ export default {
|
|
|
170
170
|
} catch (err) {
|
|
171
171
|
// This exception handles errors from the `request` action when it receives a failed http request. The `err` object could be from the action's error handler (raw http response object containing `status`) or thrown later on given the response of the action (a massaged object containing `_status`). TBD why one 409 triggers the error handler and another does not.
|
|
172
172
|
const IS_ERR_409 = err.status === 409 || err._status === 409;
|
|
173
|
+
|
|
174
|
+
const IS_ERR_403 = err.status === 403 || err._status === 403;
|
|
175
|
+
|
|
176
|
+
if (err.message === '' && err.fieldName && err.code) {
|
|
177
|
+
err.message = err.code + ' ' + err.fieldName
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (IS_ERR_403) {
|
|
181
|
+
err.message = '权限不足'
|
|
182
|
+
}
|
|
173
183
|
|
|
174
184
|
// Conflict, the resource being edited has changed since starting editing
|
|
175
185
|
if (IS_ERR_409 && depth === 0 && this.isEdit) {
|
package/package.json
CHANGED
|
@@ -694,7 +694,8 @@ export default {
|
|
|
694
694
|
role="link"
|
|
695
695
|
:aria-label="t('nav.clusterTools')"
|
|
696
696
|
>
|
|
697
|
-
|
|
697
|
+
<!-- 禅道 3539 隐藏集群工具 -->
|
|
698
|
+
<!-- <span>{{ t('nav.clusterTools') }}</span> -->
|
|
698
699
|
</router-link>
|
|
699
700
|
</div>
|
|
700
701
|
<ConfigBadge
|
|
@@ -41,6 +41,26 @@ export async function handleSpoofedRequest(rootGetters, schemaStore, opt, produc
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
export function normalizeSchemaMethods(schema) {
|
|
45
|
+
if (!schema) return schema;
|
|
46
|
+
|
|
47
|
+
const HTTP_METHODS = ["get", "post", "put", "patch", "delete"];
|
|
48
|
+
|
|
49
|
+
if (Array.isArray(schema.resourceMethods)) {
|
|
50
|
+
schema.resourceMethods = schema.resourceMethods.map(m =>
|
|
51
|
+
HTTP_METHODS.includes(m.toLowerCase()) ? m.toUpperCase() : m
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (Array.isArray(schema.collectionMethods)) {
|
|
56
|
+
schema.collectionMethods = schema.collectionMethods.map(m =>
|
|
57
|
+
HTTP_METHODS.includes(m.toLowerCase()) ? m.toUpperCase() : m
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return schema;
|
|
62
|
+
}
|
|
63
|
+
|
|
44
64
|
export async function loadSchemas(ctx, watch = true) {
|
|
45
65
|
const {
|
|
46
66
|
getters, dispatch, commit, rootGetters
|
|
@@ -55,6 +75,9 @@ export async function loadSchemas(ctx, watch = true) {
|
|
|
55
75
|
}
|
|
56
76
|
|
|
57
77
|
res.data.forEach(addSchemaIndexFields);
|
|
78
|
+
|
|
79
|
+
// ✅ 统一处理 HTTP 方法
|
|
80
|
+
res.data.forEach(normalizeSchemaMethods);
|
|
58
81
|
|
|
59
82
|
commit('loadAll', {
|
|
60
83
|
ctx,
|
|
@@ -83,6 +83,8 @@ export default defineComponent({
|
|
|
83
83
|
|
|
84
84
|
if (labelStr === 'waiting for api to be available') {
|
|
85
85
|
labelStr = '等待api可用'
|
|
86
|
+
} else if (labelStr === 'Cluster agent is not connected') {
|
|
87
|
+
labelStr = '集群agent未连接'
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
return !(typeof labelStr === 'string') ? stringify(labelStr) : undefined;
|
package/scripts/publish-shell.sh
CHANGED
package/types/shell/index.d.ts
CHANGED
|
@@ -2687,6 +2687,7 @@ export default class Ingress {
|
|
|
2687
2687
|
|
|
2688
2688
|
declare module '@shell/plugins/dashboard-store/actions' {
|
|
2689
2689
|
export function handleSpoofedRequest(rootGetters: any, schemaStore: any, opt: any, product: any): Promise<any>;
|
|
2690
|
+
export function normalizeSchemaMethods(schema: any): any;
|
|
2690
2691
|
export function loadSchemas(ctx: any, watch?: boolean): Promise<any>;
|
|
2691
2692
|
export const _ALL: "all";
|
|
2692
2693
|
export const _MERGE: "merge";
|
package/utils/error.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isArray } from '@shell/utils/array';
|
|
2
2
|
|
|
3
3
|
import translations from './errorTranslate.json';
|
|
4
|
+
import errorTranslateNew from './errorTranslateNew.json';
|
|
4
5
|
|
|
5
6
|
export class ClusterNotFoundError extends Error {
|
|
6
7
|
static NAME = 'ClusterNotFoundError'
|
|
@@ -49,6 +50,9 @@ export class ApiError extends Error {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
export function stringify(err) {
|
|
53
|
+
|
|
54
|
+
console.log(err, ' err-------------------------------------------------1')
|
|
55
|
+
|
|
52
56
|
let str;
|
|
53
57
|
if ( typeof err === 'string' ) {
|
|
54
58
|
str = err;
|
|
@@ -92,6 +96,8 @@ export function exceptionToErrorsArray(err) {
|
|
|
92
96
|
if ( err?.response?.data ) {
|
|
93
97
|
const body = err.response.data;
|
|
94
98
|
|
|
99
|
+
console.log(err, ' err-------------------------------------------------1')
|
|
100
|
+
|
|
95
101
|
if ( body && body.message ) {
|
|
96
102
|
return [translateError(body.message)];
|
|
97
103
|
} else {
|
|
@@ -147,7 +153,9 @@ export function translateError(error) {
|
|
|
147
153
|
console.log('00044', error);
|
|
148
154
|
|
|
149
155
|
|
|
150
|
-
if (error.includes(
|
|
156
|
+
if (error.includes("a lowercase rfc 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character")) {
|
|
157
|
+
error = "无效的名称不符合 RFC 1123 命名规则。名称只能包含小写字母、数字或 '-',并且必须以字母或数字开头和结尾(例如 'my-name' 或 '123-abc')。"
|
|
158
|
+
} else if (error.includes('spec and status of disks on node') && error.includes('are being syncing and please retry later')) {
|
|
151
159
|
error = error.replace('spec and status of disks on node','').replace('are being syncing and please retry later','')
|
|
152
160
|
error = '节点' + error + '上的硬盘规格和状态正在同步,请稍后重试'
|
|
153
161
|
} else if (error.includes('same granularity as schedule') && error.includes('and offset less than')) {
|
|
@@ -174,7 +182,7 @@ export function translateError(error) {
|
|
|
174
182
|
|
|
175
183
|
error = `子网 '${subnetName}' 配置无效:1) 名称禁止以数字开头;2) 排除IP[${idx}] 不能为空且必须是合法 IPv4/IPv6 地址或地址段`;
|
|
176
184
|
}
|
|
177
|
-
|
|
185
|
+
|
|
178
186
|
// error = error.replace(/admission webhook(.*?)denied the request:/g, (match, p1) => {
|
|
179
187
|
// return '';
|
|
180
188
|
// })
|
|
@@ -187,8 +195,9 @@ export function translateError(error) {
|
|
|
187
195
|
error = error.substring(errorIndex + 4);
|
|
188
196
|
}
|
|
189
197
|
|
|
198
|
+
const translationsList = [...errorTranslateNew.translations, ...translations.translations]
|
|
190
199
|
|
|
191
|
-
for (const translation of
|
|
200
|
+
for (const translation of translationsList) {
|
|
192
201
|
|
|
193
202
|
// if (error.includes(translation.pattern)) {
|
|
194
203
|
// error = error.replace(translation.pattern, translation.replacement);
|
|
@@ -1582,6 +1582,10 @@
|
|
|
1582
1582
|
"pattern": "could not",
|
|
1583
1583
|
"replacement": "无法"
|
|
1584
1584
|
},
|
|
1585
|
+
{
|
|
1586
|
+
"pattern": "MissingRequired",
|
|
1587
|
+
"replacement": "缺少"
|
|
1588
|
+
},
|
|
1585
1589
|
{
|
|
1586
1590
|
"pattern": "cannot",
|
|
1587
1591
|
"replacement": "不能"
|
|
@@ -1742,6 +1746,14 @@
|
|
|
1742
1746
|
"pattern": "replicaset",
|
|
1743
1747
|
"replacement": "副本集"
|
|
1744
1748
|
},
|
|
1749
|
+
{
|
|
1750
|
+
"pattern": "Cluster",
|
|
1751
|
+
"replacement": "名称"
|
|
1752
|
+
},
|
|
1753
|
+
{
|
|
1754
|
+
"pattern": "name",
|
|
1755
|
+
"replacement": "名称"
|
|
1756
|
+
},
|
|
1745
1757
|
{
|
|
1746
1758
|
"pattern": "%",
|
|
1747
1759
|
"replacement": ""
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"translations": [
|
|
3
|
+
{
|
|
4
|
+
"pattern": "virtualmachineimages\\.harvesterhci\\.io.*forbidden.*user.*cannot.*(patch|update|create|delete).*resource.*virtualmachineimages.*harvesterhci\\.io.*namespace",
|
|
5
|
+
"replacement": "权限不足",
|
|
6
|
+
"flags": "gi"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"pattern": "storageclasses\\.storage\\.k8s\\.io.*forbidden.*user.*cannot.*(patch|update|create|delete).*resource.*storageclasses.*storage\\.k8s\\.io.*cluster scope",
|
|
10
|
+
"replacement": "权限不足",
|
|
11
|
+
"flags": "gi"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"pattern": "Cluster agent is not connected",
|
|
15
|
+
"replacement": "集群agent未连接",
|
|
16
|
+
"flags": "gi"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"pattern": "waiting for api to be available",
|
|
20
|
+
"replacement": "等待api可用",
|
|
21
|
+
"flags": "gi"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"pattern": "MissingRequired Cluster name",
|
|
25
|
+
"replacement": "缺少集群名称",
|
|
26
|
+
"flags": "gi"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"pattern": "users\\.management\\.cattle\\.io.*forbidden.*user.*cannot update resource.*users.*management\\.cattle\\.io.*cluster scope",
|
|
30
|
+
"replacement": "权限不足:当前用户无权修改用户资源。",
|
|
31
|
+
"flags": "gi"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"pattern": "Cluster agent is not connected",
|
|
35
|
+
"replacement": "集群agent未连接",
|
|
36
|
+
"flags": "gi"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"pattern": "waiting for api to be available",
|
|
40
|
+
"replacement": "等待api可用",
|
|
41
|
+
"flags": "gi"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|