dashboard-shell-shell 3.0.5-tsh.8 → 3.0.5-tsh.9

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.
@@ -7648,6 +7648,10 @@ typeDescription:
7648
7648
  management.cattle.io.setting: 统一配置平台基础选项与全局设置,支持CA证书、密码规则、域名、Token时效等核心配置。
7649
7649
  management.cattle.io.user: 用于管理用户账号,支持创建、维护用户信息,可设置用户权限、管理密码等,保障系统资源仅由授权用户访问,提升系统安全性。
7650
7650
  harvesterhci.io.management.cluster: 提供虚拟化集群的实时健康状态监控、版本号管理及资源负载管理,支持批量导入/删除集群、配置调优与权限分级功能,实现高效运维管控。
7651
+ harvesterhci.io.logging.clusterflow: 集群流用于展示集群内的事件与操作日志,帮助您实时监控集群状态、追踪资源变更,提升问题排查与运维效率。
7652
+ harvesterhci.io.logging.clusteroutput: 集群输出用于集中展示集群运行过程中的日志与输出信息,帮助您分析系统行为、定位问题并优化集群性能。
7653
+ harvesterhci.io.logging.flow: 流用于实时展示系统内各类事件与操作记录,帮助您监控资源变化、追踪操作过程,提升系统可观测性与运维效率。
7654
+ harvesterhci.io.logging.output: 输出用于查看系统或服务运行产生的日志与结果信息,帮助您及时了解运行状态并进行故障排查。
7651
7655
  typeLabel:
7652
7656
  management.cattle.io.oidcclient: |-
7653
7657
  {count, plural,
@@ -3264,6 +3264,18 @@ members:
3264
3264
  viewClusterCatalogs: 查看集群应用商店
3265
3265
  viewClusterMembers: 查看集群成员
3266
3266
  viewNodes: 查看节点
3267
+ safe-admin:
3268
+ label: 安全管理员
3269
+ description: 负责用户、角色及基础配置管理,保障系统权限与安全策略的合规性。
3270
+ project-tenant:
3271
+ label: 租户
3272
+ description: 租户可管理资源组及其中的虚机、网络等资源。
3273
+ cluster-tenant:
3274
+ label: 租户
3275
+ description: 租户可管理资源组及其中的虚机、网络等资源。
3276
+ tenant:
3277
+ label: 租户
3278
+ description: 租户可管理资源组及其中的虚机、网络等资源。
3267
3279
  owner:
3268
3280
  label: 所有者
3269
3281
  description: 所有者对集群和集群内的所有资源拥有完全的控制权。
@@ -4502,6 +4514,12 @@ projectMembers:
4502
4514
  description: 控制用户对项目的访问权限
4503
4515
  noDescription: 已创建用户 - 没有描述
4504
4516
  searchForMember: 搜索需要向其提供项目访问权限的成员
4517
+ safe-admin:
4518
+ label: 安全管理员
4519
+ description: 负责用户、角色及基础配置管理,保障系统权限与安全策略的合规性。
4520
+ tenant:
4521
+ label: 租户
4522
+ description: 租户可管理资源组及其中的虚机、网络等资源。
4505
4523
  owner:
4506
4524
  label: 所有者
4507
4525
  description: 所有者对项目和项目内的所有资源拥有完全的控制权限。
@@ -4765,6 +4783,9 @@ rbac:
4765
4783
  description: 无描述
4766
4784
  assignOnlyRole: 已分配该角色
4767
4785
  role:
4786
+ cluster-tenant:
4787
+ label: 租户
4788
+ description: 租户可管理资源组及其中的虚机、网络等资源。
4768
4789
  admin:
4769
4790
  label: 管理员
4770
4791
  description: 管理员可以完全控制整个安装以及所有集群中的所有资源。
@@ -4774,6 +4795,12 @@ rbac:
4774
4795
  user-base:
4775
4796
  label: User-Base 用户
4776
4797
  description: User-Base 用户只拥有登录权限。
4798
+ tenant:
4799
+ label: 租户
4800
+ description: 租户可管理资源组及其中的虚机、网络等资源。
4801
+ safe-admin:
4802
+ label: 安全管理员
4803
+ description: 负责用户、角色及基础配置管理,保障系统权限与安全策略的合规性。
4777
4804
  clusters-create:
4778
4805
  label: 创建集群
4779
4806
  description: 允许用户创建集群,并成为该集群的所有者(owner)。普通用户默认拥有此权限。
@@ -6544,6 +6571,7 @@ model:
6544
6571
  label: Service Account 用户名
6545
6572
  projectMember:
6546
6573
  role:
6574
+ tenant: 租户
6547
6575
  member: 成员
6548
6576
  owner: 所有者
6549
6577
  readonly: 只读用户
@@ -6639,6 +6667,10 @@ typeDescription:
6639
6667
  batch.cronjob: CronJob 创建 Job,然后按照重复调度来运行 Pod。该调度以标准的 Unix cron 格式表示,并使用 Kubernetes Control Plane 的时区(通常是 UTC)。
6640
6668
  batch.job: Job 创建一个或多个 Pod。 Job 通过运行 Pod 直到其成功退出,以可靠执行一次性任务。失败的 Pod 会自动被替换,直到达到指定的完成运行次数。Job 还可以并行运行多个 Pod,或作为批处理工作队列。
6641
6669
  pod: Pod 是你可以在 Kubernetes 中创建和管理的最小可部署计算单元。Pod 是一个或多个容器,具有共享的存储和网络资源以及运行容器的规范。
6670
+ harvesterhci.io.logging.clusterflow: 集群流用于展示集群内的事件与操作日志,帮助您实时监控集群状态、追踪资源变更,提升问题排查与运维效率。
6671
+ harvesterhci.io.logging.clusteroutput: 集群输出用于集中展示集群运行过程中的日志与输出信息,帮助您分析系统行为、定位问题并优化集群性能。
6672
+ harvesterhci.io.logging.flow: 流用于实时展示系统内各类事件与操作记录,帮助您监控资源变化、追踪操作过程,提升系统可观测性与运维效率。
6673
+ harvesterhci.io.logging.output: 输出用于查看系统或服务运行产生的日志与结果信息,帮助您及时了解运行状态并进行故障排查。
6642
6674
  typeLabel:
6643
6675
  management.cattle.io.project: |-
6644
6676
  {count, plural,
@@ -8087,3 +8119,13 @@ component:
8087
8119
  keyValue:
8088
8120
  noRows: 此资源上没有配置{propertyName}.
8089
8121
  showConfiguration: 显示配置
8122
+
8123
+
8124
+
8125
+ customConversion:
8126
+ Tenant: 租户
8127
+ Cluster Owner: 所有者
8128
+ Project Owner: 项目负责人
8129
+
8130
+
8131
+
@@ -103,21 +103,36 @@ export default {
103
103
  this.sortedRoles.global.push(...remainingGlobalRoles);
104
104
  // End sort of global roles
105
105
 
106
- delete this.sortedRoles.builtin
107
- delete this.sortedRoles.custom
106
+ if (!(sessionStorage.getItem('TOPLEVELPERMISSIONS') && sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin')) {
107
+ delete this.sortedRoles.builtin
108
+ delete this.sortedRoles.custom
109
+ }
108
110
 
109
111
  this.update();
110
112
  }
111
113
  } catch (e) { }
112
114
  },
113
115
  data() {
114
- return {
115
- // This not only identifies global roles but the order here is the order we want to display them in the UI
116
- globalPermissions: [
116
+
117
+ let globalPermissions = [
118
+ 'admin',
119
+ 'safe-admin',
120
+ 'tenant',
121
+ ]
122
+
123
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
124
+ globalPermissions = [
117
125
  'admin',
126
+ 'safe-admin',
118
127
  'user',
119
128
  'user-base',
120
- ],
129
+ 'tenant',
130
+ ]
131
+ }
132
+
133
+ return {
134
+ // This not only identifies global roles but the order here is the order we want to display them in the UI
135
+ globalPermissions,
121
136
  globalRoleBindings: null,
122
137
  sortedRoles: null,
123
138
  selectedRoles: [],
@@ -143,30 +143,46 @@ export default {
143
143
  return [this.permissionGroup];
144
144
  },
145
145
  options() {
146
+
146
147
  const customRoles = this.customRoles.map((role) => ({
147
148
  label: role.nameDisplay,
148
149
  description: role.description || role.metadata?.annotations?.[DESCRIPTION] || this.t('members.clusterPermissions.noDescription'),
149
150
  value: role.id
150
151
  }));
151
152
 
152
- return [
153
- {
154
- label: this.t('members.clusterPermissions.owner.label'),
155
- description: this.t('members.clusterPermissions.owner.description'),
156
- value: 'owner'
157
- },
158
- {
159
- label: this.t('members.clusterPermissions.member.label'),
160
- description: this.t('members.clusterPermissions.member.description'),
161
- value: 'member'
162
- },
163
- ...customRoles,
164
- // {
165
- // label: this.t('members.clusterPermissions.custom.label'),
166
- // description: this.t('members.clusterPermissions.custom.description'),
167
- // value: 'custom'
168
- // }
169
- ];
153
+ let optionList = [{
154
+ label: this.t('members.clusterPermissions.cluster-tenant.label'),
155
+ description: this.t('members.clusterPermissions.cluster-tenant.description'),
156
+ value: 'cluster-tenant'
157
+ }];
158
+
159
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
160
+ optionList = [
161
+ {
162
+ label: this.t('members.clusterPermissions.cluster-tenant.label'),
163
+ description: this.t('members.clusterPermissions.cluster-tenant.description'),
164
+ value: 'cluster-tenant'
165
+ },
166
+ {
167
+ label: this.t('members.clusterPermissions.owner.label'),
168
+ description: this.t('members.clusterPermissions.owner.description'),
169
+ value: 'owner'
170
+ },
171
+ {
172
+ label: this.t('members.clusterPermissions.member.label'),
173
+ description: this.t('members.clusterPermissions.member.description'),
174
+ value: 'member'
175
+ },
176
+ ...customRoles,
177
+ {
178
+ label: this.t('members.clusterPermissions.custom.label'),
179
+ description: this.t('members.clusterPermissions.custom.description'),
180
+ value: 'custom'
181
+ }
182
+ ];
183
+ }
184
+
185
+ return optionList
170
186
  },
171
187
  principal() {
172
188
  const principalId = this.principalId.replace(/\//g, '%2F');
@@ -191,7 +191,7 @@ export default {
191
191
  :data-testid="`role-item-${i}`"
192
192
  class="col span-6 role"
193
193
  >
194
- {{ row.value.roleDisplay }}
194
+ {{ $store.getters['i18n/withFallback'](`customConversion.${row.value.roleDisplay}`, row.value.roleDisplay) }}
195
195
  </div>
196
196
  </div>
197
197
  </template>
@@ -514,9 +514,8 @@ export default {
514
514
  </div>
515
515
 
516
516
  <!-- 自定义插槽,可插入额外内容 -->
517
- <div :class=" isDialog? 'namespace-item-row mb-20': 'col span-6'">
518
- <slot name="customize" />
519
- </div>
517
+ <slot name="customize" />
518
+
520
519
  <!-- <div
521
520
  v-show="!descriptionHidden"
522
521
  :data-testid="componentTestid + '-description'"
@@ -166,29 +166,44 @@ export default {
166
166
  value: this.purifyOption(role.id),
167
167
  }));
168
168
 
169
- return [
170
- {
171
- label: this.t('projectMembers.projectPermissions.owner.label'),
172
- description: this.t('projectMembers.projectPermissions.owner.description'),
173
- value: 'owner'
174
- },
175
- {
176
- label: this.t('projectMembers.projectPermissions.member.label'),
177
- description: this.t('projectMembers.projectPermissions.member.description'),
178
- value: 'member'
179
- },
180
- {
181
- label: this.t('projectMembers.projectPermissions.readOnly.label'),
182
- description: this.t('projectMembers.projectPermissions.readOnly.description'),
183
- value: 'read-only'
184
- },
185
- ...customRoles,
186
- {
187
- label: this.t('projectMembers.projectPermissions.custom.label'),
188
- description: this.t('projectMembers.projectPermissions.custom.description'),
189
- value: 'custom'
190
- }
191
- ];
169
+ let optionList = [{
170
+ label: this.t('members.clusterPermissions.project-tenant.label'),
171
+ description: this.t('members.clusterPermissions.project-tenant.description'),
172
+ value: 'project-tenant'
173
+ }];
174
+
175
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
176
+ optionList = [
177
+ {
178
+ label: this.t('members.clusterPermissions.project-tenant.label'),
179
+ description: this.t('members.clusterPermissions.project-tenant.description'),
180
+ value: 'project-tenant'
181
+ },
182
+ {
183
+ label: this.t('projectMembers.projectPermissions.owner.label'),
184
+ description: this.t('projectMembers.projectPermissions.owner.description'),
185
+ value: 'owner'
186
+ },
187
+ {
188
+ label: this.t('projectMembers.projectPermissions.member.label'),
189
+ description: this.t('projectMembers.projectPermissions.member.description'),
190
+ value: 'member'
191
+ },
192
+ {
193
+ label: this.t('projectMembers.projectPermissions.readOnly.label'),
194
+ description: this.t('projectMembers.projectPermissions.readOnly.description'),
195
+ value: 'read-only'
196
+ },
197
+ ...customRoles,
198
+ {
199
+ label: this.t('projectMembers.projectPermissions.custom.label'),
200
+ description: this.t('projectMembers.projectPermissions.custom.description'),
201
+ value: 'custom'
202
+ }
203
+ ];
204
+ }
205
+
206
+ return optionList
192
207
  },
193
208
  customPermissionsUpdate() {
194
209
  return this.customPermissions.reduce((acc, customPermissionsItem) => {
@@ -5,14 +5,17 @@ export const NAME = 'uiplugins';
5
5
  export function init(store) {
6
6
  const { product } = DSL(store, NAME);
7
7
 
8
- // Add a product for UI Plugins - will appear in the top-level menu
9
- product({
10
- ifHave: IF_HAVE.ADMIN, // Only admins can see the UI Plugin Custom Resource by default
11
- inStore: 'management',
12
- icon: 'extension',
13
- removable: false,
14
- showClusterSwitcher: false,
15
- category: 'configuration',
16
- weight: 50,
17
- });
8
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') && sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
9
+ // Add a product for UI Plugins - will appear in the top-level menu
10
+ product({
11
+ ifHave: IF_HAVE.ADMIN, // Only admins can see the UI Plugin Custom Resource by default
12
+ inStore: 'management',
13
+ icon: 'extension',
14
+ removable: false,
15
+ showClusterSwitcher: false,
16
+ category: 'configuration',
17
+ weight: 50,
18
+ });
19
+ }
20
+
18
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dashboard-shell-shell",
3
- "version": "3.0.5-tsh.8",
3
+ "version": "3.0.5-tsh.9",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -311,7 +311,7 @@ export default {
311
311
  this.$store.dispatch('auth/setInitialPass', this.password);
312
312
  this.$router.push({ name: 'auth-setup' });
313
313
  } else {
314
- this.$router.push({ name: 'home' });
314
+ this.$router.push({ name: 'index' });
315
315
  }
316
316
  } catch (err) {
317
317
  // 登录失败处理
@@ -7,6 +7,7 @@ import Loading from '@shell/components/Loading';
7
7
  import { SUBTYPE_MAPPING, CREATE_VERBS } from '@shell/models/management.cattle.io.roletemplate';
8
8
  import { NAME } from '@shell/config/product/auth';
9
9
  import { BLANK_CLUSTER } from '@shell/store/store-types.js';
10
+ import { globalRoleFilteringfn, clusterRoleFilteringfn, projectRoleFilteringfn } from '@shell/utils/roleFiltering'
10
11
 
11
12
  const GLOBAL = SUBTYPE_MAPPING.GLOBAL.key;
12
13
  const CLUSTER = SUBTYPE_MAPPING.CLUSTER.key;
@@ -99,15 +100,38 @@ export default {
99
100
 
100
101
  computed: {
101
102
  globalResources() {
102
- return this.globalRoles;
103
+
104
+ let rolesList = globalRoleFilteringfn(this.globalRoles)
105
+
106
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
107
+ rolesList = this.globalRoles
108
+ }
109
+
110
+ return rolesList
103
111
  },
104
112
 
105
113
  clusterResources() {
106
- return this.roleTemplates.filter((r) => r.context === SUBTYPE_MAPPING.CLUSTER.context);
114
+ const roleList = this.roleTemplates.filter((r) => r.context === SUBTYPE_MAPPING.CLUSTER.context);
115
+
116
+ let rolesList = clusterRoleFilteringfn(roleList)
117
+
118
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
119
+ rolesList = roleList
120
+ }
121
+
122
+ return rolesList
107
123
  },
108
124
 
109
125
  namespaceResources() {
110
- return this.roleTemplates.filter((r) => r.context === SUBTYPE_MAPPING.NAMESPACE.context);
126
+ const roleList = this.roleTemplates.filter((r) => r.context === SUBTYPE_MAPPING.NAMESPACE.context);
127
+
128
+ let rolesList = projectRoleFilteringfn(roleList)
129
+
130
+ if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
131
+ rolesList = roleList
132
+ }
133
+
134
+ return rolesList
111
135
  },
112
136
 
113
137
  type() {
@@ -4354,6 +4354,14 @@ export function deferred(name: any): {
4354
4354
  export function setPromiseResult(promise: any, obj: any, key: any, label: any): void;
4355
4355
  }
4356
4356
 
4357
+ // @shell/utils/roleFiltering
4358
+
4359
+ declare module '@shell/utils/roleFiltering' {
4360
+ export function globalRoleFilteringfn(ary: any): any;
4361
+ export function clusterRoleFilteringfn(ary: any): any;
4362
+ export function projectRoleFilteringfn(ary: any): any;
4363
+ }
4364
+
4357
4365
  // @shell/utils/router
4358
4366
 
4359
4367
  declare module '@shell/utils/router' {
@@ -0,0 +1,33 @@
1
+ export function globalRoleFilteringfn (ary) {
2
+ const roleList = ['admin', 'tenant', 'safe-admin']
3
+ if (ary && ary.length > 0) {
4
+ return ary.filter(item => { return roleList.includes(item.id) })
5
+ }
6
+ return []
7
+ }
8
+
9
+ export function clusterRoleFilteringfn (ary) {
10
+ const roleList = ['cluster-tenant']
11
+ if (ary && ary.length > 0) {
12
+ ary.map(m => {
13
+ if (m.id === 'cluster-tenant') {
14
+ m['displayName'] = '租户'
15
+ }
16
+ })
17
+ return ary.filter(item => { return roleList.includes(item.id) })
18
+ }
19
+ return []
20
+ }
21
+
22
+ export function projectRoleFilteringfn (ary) {
23
+ const roleList = ['project-tenant']
24
+ ary.map(m => {
25
+ if (m.id === 'project-tenant') {
26
+ m['displayName'] = '租户'
27
+ }
28
+ })
29
+ if (ary && ary.length > 0) {
30
+ return ary.filter(item => { return roleList.includes(item.id) })
31
+ }
32
+ return []
33
+ }