@rancher/shell 3.0.5-rc.6 → 3.0.5-rc.8

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.
Files changed (243) hide show
  1. package/assets/brand/classic/metadata.json +3 -0
  2. package/assets/styles/app.scss +1 -0
  3. package/assets/styles/base/_color.scss +16 -0
  4. package/assets/styles/base/_helpers.scss +10 -0
  5. package/assets/styles/base/_variables.scss +18 -12
  6. package/assets/styles/fonts/_icons.scss +1 -32
  7. package/assets/styles/global/_layout.scss +1 -1
  8. package/assets/styles/themes/_dark.scss +262 -258
  9. package/assets/styles/themes/_light.scss +538 -509
  10. package/assets/styles/themes/_modern.scss +914 -0
  11. package/assets/translations/en-us.yaml +110 -29
  12. package/chart/__tests__/S3.test.ts +2 -1
  13. package/cloud-credential/generic.vue +18 -10
  14. package/cloud-credential/harvester.vue +1 -9
  15. package/components/AdvancedSection.vue +8 -0
  16. package/components/ChartReadme.vue +17 -7
  17. package/components/CodeMirror.vue +1 -1
  18. package/components/Drawer/Chrome.vue +0 -1
  19. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +27 -28
  20. package/components/Drawer/ResourceDetailDrawer/composables.ts +4 -24
  21. package/components/Drawer/ResourceDetailDrawer/index.vue +18 -4
  22. package/components/InstallHelmCharts.vue +656 -0
  23. package/components/LazyImage.vue +60 -4
  24. package/components/Loading.vue +1 -1
  25. package/components/LocaleSelector.vue +7 -2
  26. package/components/Markdown.vue +4 -0
  27. package/components/PaginatedResourceTable.vue +46 -1
  28. package/components/PromptRestore.vue +22 -44
  29. package/components/Resource/Detail/Masthead/composable.ts +16 -0
  30. package/components/Resource/Detail/Masthead/index.vue +37 -0
  31. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +10 -2
  32. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +26 -7
  33. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +8 -1
  34. package/components/Resource/Detail/Metadata/KeyValue.vue +12 -10
  35. package/components/Resource/Detail/Metadata/Rectangle.vue +3 -1
  36. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +10 -17
  37. package/components/Resource/Detail/Metadata/composables.ts +9 -7
  38. package/components/Resource/Detail/Metadata/index.vue +17 -2
  39. package/components/Resource/Detail/Page.vue +35 -21
  40. package/components/Resource/Detail/SpacedRow.vue +1 -1
  41. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +8 -9
  42. package/components/Resource/Detail/TitleBar/composables.ts +5 -5
  43. package/components/Resource/Detail/TitleBar/index.vue +12 -3
  44. package/components/ResourceDetail/Masthead/legacy.vue +1 -1
  45. package/components/ResourceDetail/index.vue +569 -72
  46. package/components/ResourceList/index.vue +1 -0
  47. package/components/ResourceTable.vue +6 -1
  48. package/components/ResourceYaml.vue +1 -1
  49. package/components/RichTranslation.vue +106 -0
  50. package/components/SlideInPanelManager.vue +13 -10
  51. package/components/SortableTable/index.vue +5 -5
  52. package/components/SortableTable/selection.js +0 -1
  53. package/components/Tabbed/index.vue +35 -4
  54. package/components/__tests__/LazyImage.spec.ts +121 -0
  55. package/components/__tests__/PromptRestore.test.ts +1 -65
  56. package/components/__tests__/RichTranslation.test.ts +115 -0
  57. package/components/fleet/FleetStatus.vue +4 -0
  58. package/components/fleet/dashboard/ResourcePanel.vue +2 -1
  59. package/components/form/ClusterAppearance.vue +5 -0
  60. package/components/form/FileImageSelector.vue +1 -1
  61. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  62. package/components/form/NameNsDescription.vue +1 -0
  63. package/components/form/Networking.vue +24 -19
  64. package/components/form/ProjectMemberEditor.vue +1 -1
  65. package/components/form/ResourceLabeledSelect.vue +22 -8
  66. package/components/form/ResourceTabs/index.vue +20 -0
  67. package/components/form/SecretSelector.vue +9 -0
  68. package/components/form/SelectOrCreateAuthSecret.vue +6 -3
  69. package/components/form/__tests__/Networking.test.ts +116 -0
  70. package/components/form/labeled-select-utils/labeled-select-pagination.ts +3 -38
  71. package/components/formatter/FleetApplicationSource.vue +25 -17
  72. package/components/formatter/PodImages.vue +1 -1
  73. package/components/formatter/__tests__/LiveDate.test.ts +10 -2
  74. package/components/google/AccountAccess.vue +44 -46
  75. package/components/nav/Favorite.vue +4 -0
  76. package/components/nav/Group.vue +4 -1
  77. package/components/nav/NotificationCenter/Notification.vue +1 -27
  78. package/components/nav/WindowManager/index.vue +3 -3
  79. package/composables/resources.ts +2 -2
  80. package/config/labels-annotations.js +3 -2
  81. package/config/pagination-table-headers.js +8 -1
  82. package/config/product/explorer.js +27 -2
  83. package/config/product/manager.js +0 -1
  84. package/config/query-params.js +10 -0
  85. package/config/router/routes.js +21 -1
  86. package/config/system-namespaces.js +1 -1
  87. package/config/table-headers.js +30 -1
  88. package/config/types.js +1 -1
  89. package/config/version.js +1 -1
  90. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +11 -0
  91. package/detail/__tests__/workload.test.ts +164 -0
  92. package/detail/configmap.vue +33 -75
  93. package/detail/projectsecret.vue +11 -0
  94. package/detail/provisioning.cattle.io.cluster.vue +351 -369
  95. package/detail/secret.vue +49 -308
  96. package/detail/workload/index.vue +38 -21
  97. package/dialog/InstallExtensionDialog.vue +8 -5
  98. package/dialog/RotateEncryptionKeyDialog.vue +10 -30
  99. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  100. package/edit/auth/ldap/__tests__/config.test.ts +14 -0
  101. package/edit/auth/ldap/config.vue +24 -0
  102. package/edit/compliance.cattle.io.clusterscan.vue +1 -1
  103. package/edit/configmap.vue +4 -1
  104. package/edit/fleet.cattle.io.gitrepo.vue +5 -6
  105. package/edit/fleet.cattle.io.helmop.vue +78 -56
  106. package/edit/logging.banzaicloud.io.output/index.vue +1 -1
  107. package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +5 -6
  108. package/edit/networking.k8s.io.ingress/Certificate.vue +20 -22
  109. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +8 -3
  110. package/edit/networking.k8s.io.ingress/Rule.vue +2 -5
  111. package/edit/networking.k8s.io.ingress/RulePath.vue +17 -11
  112. package/edit/networking.k8s.io.ingress/__tests__/Certificate.test.ts +165 -0
  113. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +11 -10
  114. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -3
  115. package/edit/networking.k8s.io.networkpolicy/index.vue +17 -17
  116. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +3 -2
  117. package/edit/provisioning.cattle.io.cluster/rke2.vue +123 -61
  118. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +9 -7
  119. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +22 -13
  120. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +10 -12
  121. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +39 -38
  122. package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +41 -19
  123. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +16 -3
  124. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +32 -33
  125. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +9 -10
  126. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -3
  127. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue +16 -9
  128. package/edit/secret/basic.vue +1 -0
  129. package/edit/secret/index.vue +126 -15
  130. package/edit/workload/index.vue +5 -14
  131. package/list/projectsecret.vue +345 -0
  132. package/list/provisioning.cattle.io.cluster.vue +1 -69
  133. package/list/secret.vue +109 -0
  134. package/machine-config/__tests__/vmwarevsphere.test.ts +5 -7
  135. package/machine-config/google.vue +9 -1
  136. package/machine-config/vmwarevsphere.vue +7 -17
  137. package/mixins/__tests__/brand.spec.ts +2 -2
  138. package/mixins/chart.js +0 -2
  139. package/mixins/create-edit-view/impl.js +10 -1
  140. package/mixins/resource-fetch-api-pagination.js +11 -12
  141. package/mixins/resource-fetch.js +3 -1
  142. package/models/__tests__/chart.test.ts +111 -80
  143. package/models/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  144. package/models/__tests__/node.test.ts +7 -63
  145. package/models/catalog.cattle.io.app.js +1 -1
  146. package/models/catalog.cattle.io.operation.js +1 -1
  147. package/models/chart.js +36 -20
  148. package/models/cloudcredential.js +2 -163
  149. package/models/cluster/node.js +7 -7
  150. package/models/cluster.x-k8s.io.machine.js +3 -3
  151. package/models/cluster.x-k8s.io.machinedeployment.js +11 -2
  152. package/models/compliance.cattle.io.clusterscan.js +2 -2
  153. package/models/configmap.js +4 -0
  154. package/models/constraints.gatekeeper.sh.constraint.js +1 -1
  155. package/models/fleet-application.js +0 -17
  156. package/models/fleet.cattle.io.cluster.js +2 -2
  157. package/models/fleet.cattle.io.gitrepo.js +15 -1
  158. package/models/fleet.cattle.io.helmop.js +26 -22
  159. package/models/management.cattle.io.setting.js +4 -0
  160. package/models/persistentvolumeclaim.js +1 -1
  161. package/models/pod.js +2 -2
  162. package/models/provisioning.cattle.io.cluster.js +39 -67
  163. package/models/rke.cattle.io.etcdsnapshot.js +1 -1
  164. package/models/secret.js +161 -2
  165. package/models/storage.k8s.io.storageclass.js +2 -2
  166. package/models/workload.js +3 -3
  167. package/package.json +11 -10
  168. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +1 -0
  169. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +4 -1
  170. package/pages/c/_cluster/apps/charts/__tests__/AppChartCardFooter.spec.js +41 -0
  171. package/pages/c/_cluster/apps/charts/chart.vue +422 -174
  172. package/pages/c/_cluster/apps/charts/index.vue +46 -35
  173. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  174. package/pages/c/_cluster/explorer/projectsecret.vue +24 -0
  175. package/pages/c/_cluster/fleet/__tests__/index.test.ts +608 -314
  176. package/pages/c/_cluster/fleet/index.vue +103 -45
  177. package/pages/c/_cluster/manager/cloudCredential/index.vue +2 -59
  178. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +10 -3
  179. package/pages/c/_cluster/uiplugins/index.vue +36 -25
  180. package/plugins/dashboard-store/__tests__/normalize.test.ts +223 -0
  181. package/plugins/dashboard-store/__tests__/resource-class.test.ts +191 -0
  182. package/plugins/dashboard-store/__tests__/utils/normalize-usecases.ts +1526 -0
  183. package/plugins/dashboard-store/actions.js +42 -22
  184. package/plugins/dashboard-store/normalize.js +29 -17
  185. package/plugins/dashboard-store/resource-class.js +83 -17
  186. package/plugins/steve/__tests__/getters.test.ts +1 -1
  187. package/plugins/steve/__tests__/subscribe.spec.ts +259 -1
  188. package/plugins/steve/getters.js +8 -2
  189. package/plugins/steve/resourceWatcher.js +10 -3
  190. package/plugins/steve/steve-pagination-utils.ts +14 -3
  191. package/plugins/steve/subscribe.js +192 -19
  192. package/plugins/steve/worker/web-worker.advanced.js +2 -0
  193. package/rancher-components/Card/Card.vue +0 -18
  194. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.test.ts +15 -0
  195. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +65 -0
  196. package/rancher-components/Pill/RcStatusBadge/index.ts +2 -0
  197. package/rancher-components/Pill/RcStatusBadge/types.ts +5 -0
  198. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.test.ts +33 -0
  199. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +75 -0
  200. package/rancher-components/Pill/RcStatusIndicator/index.ts +2 -0
  201. package/rancher-components/Pill/RcStatusIndicator/types.ts +7 -0
  202. package/rancher-components/Pill/types.ts +2 -0
  203. package/rancher-components/RcButton/RcButton.vue +1 -1
  204. package/rancher-components/RcDropdown/RcDropdown.test.ts +98 -0
  205. package/rancher-components/RcDropdown/RcDropdown.vue +5 -0
  206. package/rancher-components/RcDropdown/RcDropdownItem.vue +7 -1
  207. package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +2 -1
  208. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +2 -1
  209. package/rancher-components/RcDropdown/useDropdownContext.ts +21 -0
  210. package/rancher-components/RcDropdown/useDropdownItem.ts +30 -1
  211. package/rancher-components/RcItemCard/RcItemCard.test.ts +20 -0
  212. package/rancher-components/RcItemCard/RcItemCard.vue +40 -6
  213. package/store/__tests__/catalog.test.ts +93 -1
  214. package/store/aws.js +19 -8
  215. package/store/catalog.js +8 -3
  216. package/types/kube/kube-api.ts +12 -0
  217. package/types/resources/settings.d.ts +1 -1
  218. package/types/shell/index.d.ts +643 -585
  219. package/types/store/pagination.types.ts +16 -6
  220. package/types/uiplugins.ts +73 -0
  221. package/utils/__tests__/back-off.test.ts +354 -0
  222. package/utils/__tests__/create-yaml.test.ts +235 -0
  223. package/utils/__tests__/kontainer.test.ts +19 -0
  224. package/utils/__tests__/uiplugins.test.ts +84 -0
  225. package/utils/back-off.ts +176 -0
  226. package/utils/create-yaml.js +103 -9
  227. package/utils/dynamic-importer.js +8 -0
  228. package/utils/kontainer.ts +3 -5
  229. package/utils/pagination-utils.ts +18 -0
  230. package/utils/style.ts +3 -0
  231. package/utils/uiplugins.ts +29 -2
  232. package/utils/validators/__tests__/setting.test.js +92 -0
  233. package/utils/validators/formRules/__tests__/index.test.ts +88 -7
  234. package/utils/validators/formRules/index.ts +83 -8
  235. package/utils/validators/setting.js +17 -0
  236. package/cloud-credential/__tests__/harvester.test.ts +0 -18
  237. package/components/ResourceDetail/__tests__/index.test.ts +0 -135
  238. package/components/ResourceDetail/legacy.vue +0 -562
  239. package/components/formatter/CloudCredExpired.vue +0 -69
  240. package/models/etcdbackup.js +0 -45
  241. package/pages/explorer/resource/detail/configmap.vue +0 -42
  242. package/pages/explorer/resource/detail/secret.vue +0 -50
  243. package/utils/aws.js +0 -0
@@ -0,0 +1,345 @@
1
+ <script lang="ts">
2
+ import Masthead from '@shell/components/ResourceList/Masthead';
3
+ import { SECRET_SCOPE, SECRET_QUERY_PARAMS } from '@shell/config/query-params';
4
+ import { MANAGEMENT, SECRET, VIRTUAL_TYPES } from '@shell/config/types';
5
+ import { STORE } from '@shell/store/store-types';
6
+ import PaginatedResourceTable from '@shell/components/PaginatedResourceTable';
7
+ import { PaginationArgs, PaginationFilterField, PaginationParamFilter } from '@shell/types/store/pagination.types';
8
+ import Secret from '@shell/models/secret';
9
+ import { TableColumn } from '@shell/types/store/type-map';
10
+ import { mapGetters } from 'vuex';
11
+ import { GROUP_RESOURCES, mapPref } from '@shell/store/prefs';
12
+ import { DEFAULT_PROJECT, SYSTEM_PROJECT, UI_PROJECT_SECRET, UI_PROJECT_SECRET_COPY } from '@shell/config/labels-annotations';
13
+ import { RancherKubeMetadata } from '@shell/types/kube/kube-api';
14
+ import {
15
+ AGE, SECRET_DATA, STATE, SUB_TYPE, NAME as NAME_COL,
16
+ } from '@shell/config/table-headers';
17
+ import { STEVE_AGE_COL, STEVE_NAME_COL, STEVE_STATE_COL } from '@shell/config/pagination-table-headers';
18
+ import { escapeHtml } from '@shell/utils/string';
19
+
20
+ const findSystemDefaultProjects = (projects: any[], currentClusterId: string): { systemProject?: any, defaultProject?: any } => {
21
+ let systemProject;
22
+ let defaultProject;
23
+
24
+ for (let i = 0; i < projects.length; i++) {
25
+ const p = projects[i];
26
+
27
+ if (p.metadata.namespace === currentClusterId) {
28
+ if (p.isSystem) {
29
+ systemProject = p;
30
+ }
31
+
32
+ if (p.isDefault) {
33
+ defaultProject = p;
34
+ }
35
+
36
+ if (systemProject && defaultProject) {
37
+ break;
38
+ }
39
+ }
40
+ }
41
+
42
+ return { systemProject, defaultProject };
43
+ };
44
+
45
+ export default {
46
+ name: 'ListProjectScopedSecrets',
47
+ components: { Masthead, PaginatedResourceTable },
48
+ props: {
49
+ resource: {
50
+ type: String,
51
+ required: true,
52
+ },
53
+
54
+ useQueryParamsForSimpleFiltering: {
55
+ type: Boolean,
56
+ default: false
57
+ }
58
+ },
59
+
60
+ data() {
61
+ return {
62
+ escapeHtml,
63
+ SECRET,
64
+ PROJECT_SECRETS: VIRTUAL_TYPES.PROJECT_SECRETS,
65
+ STORE,
66
+ schema: this.$store.getters[`${ STORE.MANAGEMENT }/schemaFor`](SECRET),
67
+ clusterSchema: this.$store.getters[`${ STORE.CLUSTER }/schemaFor`](SECRET),
68
+ inStore: STORE.MANAGEMENT,
69
+
70
+ projectedScopedHeaders: [] as TableColumn[],
71
+ projectedScopedHeadersSsp: [] as TableColumn[],
72
+
73
+ mastheadLabel: '',
74
+ groupOptions: [{
75
+ tooltipKey: 'resourceTable.groupBy.none',
76
+ icon: 'icon-list-flat',
77
+ value: 'none',
78
+ }, {
79
+ icon: 'icon-folder',
80
+ value: 'project',
81
+ field: 'groupByProject',
82
+ hideColumn: 'project',
83
+ groupLabelKey: 'groupByProject',
84
+ tooltipKey: 'resourceTable.groupBy.project'
85
+ }],
86
+
87
+ // these are the fields that sort will be applied on, either remotely by vai, or locally
88
+ sortFields: {
89
+ local: `groupByProject`, // would be nicer to user '`metadata.labels."${ UI_PROJECT_SECRET }"`', but that's invalid for ssp
90
+ vai: `metadata.labels[${ UI_PROJECT_SECRET }]`,
91
+ },
92
+
93
+ systemProject: undefined,
94
+ defaultProject: undefined,
95
+ };
96
+ },
97
+
98
+ async fetch() {
99
+ // Upstream pss's created in default and system namespaces don't follow the usual naming convention of <cluster>-<project>
100
+ // we use that pattern to filter out pss from other clusters
101
+ // in order to not also filter upstream default and system namespace also search for their exact namespace
102
+ // this finding them...
103
+ if (this.currentCluster.isLocal) {
104
+ // First check if we already have them
105
+ const projects = this.$store.getters[`${ STORE.MANAGEMENT }/all`](MANAGEMENT.PROJECT);
106
+ const res = findSystemDefaultProjects(projects, this.currentCluster.id);
107
+
108
+ this.defaultProject = res.defaultProject;
109
+ this.systemProject = res.systemProject;
110
+
111
+ if (!this.systemProject || !this.defaultProject) {
112
+ // If not, make a http fetch (this is blocking, but should rarely happen, and should be super quick)
113
+ const url = this.$store.getters[`${ STORE.MANAGEMENT }/urlFor`](MANAGEMENT.PROJECT, null, { namespaced: this.currentCluster.id });
114
+ const response = await this.$store.dispatch(`${ STORE.MANAGEMENT }/request`, {
115
+ type: MANAGEMENT.PROJECT,
116
+ opt: { url: `${ url }&filter=metadata.labels[${ DEFAULT_PROJECT }]=true,metadata.labels[${ SYSTEM_PROJECT }]=true` }
117
+ });
118
+ const projects = await this.$store.dispatch(`${ STORE.MANAGEMENT }/createMany`, response.data);
119
+ const res = findSystemDefaultProjects(projects, this.currentCluster.id);
120
+
121
+ this.defaultProject = this.defaultProject || res.defaultProject;
122
+ this.systemProject = this.systemProject || res.systemProject;
123
+ }
124
+ }
125
+ },
126
+
127
+ async created() {
128
+ this.projectedScopedHeaders = [
129
+ STATE,
130
+ NAME_COL, {
131
+ name: 'project',
132
+ label: this.t('tableHeaders.project'),
133
+ value: 'project.nameDisplay',
134
+ search: `project.nameDisplay`,
135
+ sort: ['projectNameSort', 'nameSort'],
136
+ },
137
+ SUB_TYPE,
138
+ SECRET_DATA,
139
+ AGE
140
+ ];
141
+
142
+ this.projectedScopedHeadersSsp = [
143
+ STEVE_STATE_COL,
144
+ STEVE_NAME_COL, {
145
+ name: 'project',
146
+ label: this.t('tableHeaders.project'),
147
+ value: 'project.nameDisplay',
148
+ // blocked on https://github.com/rancher/rancher/issues/51001
149
+ // search: `metadata.labels[${ UI_PROJECT_SECRET }]`,
150
+ sort: `metadata.labels[${ UI_PROJECT_SECRET }]`,
151
+ }, {
152
+ ...SUB_TYPE,
153
+ value: 'metadata.fields.1',
154
+ sort: 'metadata.fields.1',
155
+ search: 'metadata.fields.1',
156
+ }, {
157
+ ...SECRET_DATA,
158
+ sort: false,
159
+ search: false,
160
+ },
161
+ STEVE_AGE_COL
162
+ ];
163
+
164
+ this.mastheadLabel = this.t(`typeLabel."${ this.resource }"`, { count: this.row?.length || 0 });
165
+ },
166
+
167
+ computed: {
168
+ ...mapGetters(['currentCluster']),
169
+
170
+ createLocation() {
171
+ return {
172
+ name: 'c-cluster-product-resource-create',
173
+ params: { resource: SECRET },
174
+ query: { [SECRET_SCOPE]: SECRET_QUERY_PARAMS.PROJECT_SCOPED }
175
+ };
176
+ },
177
+
178
+ groupPreference: mapPref(GROUP_RESOURCES),
179
+
180
+ groupSort() {
181
+ return this.sortFields.local;
182
+ },
183
+
184
+ },
185
+
186
+ methods: {
187
+ /**
188
+ * Locally filter out secrets that are...
189
+ * - not project-scoped
190
+ * - not in current cluster (mgmt secrets are global)
191
+ */
192
+ filterRowsLocal(rows: Secret[]) {
193
+ return rows.filter((r: Secret) => {
194
+ const metadata = r.metadata as RancherKubeMetadata; // Secrets will always have metadata, but hybrid-class does nasty things which breaks typing
195
+
196
+ // Filter in pss but not the copies
197
+ if (!r.isProjectScoped) {
198
+ return;
199
+ }
200
+
201
+ // Filter in if this cluster
202
+ if (metadata.namespace.startsWith(this.currentCluster.id)) {
203
+ return true;
204
+ }
205
+
206
+ // Filter in if upstream and default/system
207
+ if (this.currentCluster.isLocal && (r.project?.isSystem || r.project?.isDefault)) {
208
+ return true;
209
+ }
210
+
211
+ return false;
212
+ });
213
+ },
214
+
215
+ /**
216
+ * Remotely filter out secrets that are..
217
+ * - not project-scoped
218
+ * - not in current cluster (mgmt secrets are global)
219
+ */
220
+ filterRowsApi(pagination: PaginationArgs): PaginationArgs {
221
+ const sort = pagination.sort.find((s) => s.field === this.sortFields.local);
222
+
223
+ if (sort) {
224
+ sort.field = this.sortFields.vai;
225
+ }
226
+
227
+ if (!pagination.filters) {
228
+ pagination.filters = [];
229
+ }
230
+
231
+ // Filter in pss (and annoyingly their copies)
232
+ const labelFilter = PaginationParamFilter.createSingleField({
233
+ field: `metadata.labels[${ UI_PROJECT_SECRET }]`,
234
+ exists: true,
235
+ });
236
+
237
+ // Filter out their copies
238
+ const annotationFilter = PaginationParamFilter.createSingleField({
239
+ field: `metadata.annotations[${ UI_PROJECT_SECRET_COPY }]`,
240
+ value: `true`,
241
+ equals: false,
242
+ exact: true,
243
+ });
244
+
245
+ // Filter in the current clusters pss
246
+ const nsFields: PaginationFilterField[] = [{
247
+ field: 'metadata.namespace',
248
+ value: `${ this.currentCluster.id }-`,
249
+ equals: true,
250
+ exact: false,
251
+ }];
252
+
253
+ let namespaceFilter;
254
+
255
+ if (this.currentCluster.isLocal) {
256
+ // See where these are populated, but basically filter in upstream system and default projects
257
+ if (this.systemProject) {
258
+ nsFields.push({
259
+ field: 'metadata.namespace',
260
+ value: this.systemProject.metadata.name,
261
+ equals: true,
262
+ exact: true,
263
+ });
264
+ }
265
+
266
+ if (this.defaultProject) {
267
+ nsFields.push({
268
+ field: 'metadata.namespace',
269
+ value: this.defaultProject.metadata.name,
270
+ equals: true,
271
+ exact: true,
272
+ });
273
+ }
274
+
275
+ namespaceFilter = PaginationParamFilter.createMultipleFields(nsFields);
276
+ } else {
277
+ namespaceFilter = PaginationParamFilter.createSingleField(nsFields[0]);
278
+ }
279
+
280
+ let foundLabelFilter = false;
281
+ let foundAnnotationFilter = false;
282
+ let foundNsFilter = false;
283
+
284
+ for (let i = 0; i < pagination.filters.length; i++) {
285
+ const filter = pagination.filters[i];
286
+
287
+ if (filter.param === namespaceFilter.fields[0].field) {
288
+ // 1. strip out all ns filters, this includes the one that hides resources in system namespaces...... which we need
289
+ // 2. use the ns filter to find upstream project scoped secrets that are in this cluster
290
+ pagination.filters[i] = namespaceFilter;
291
+ foundNsFilter = true;
292
+ } else {
293
+ if (!!filter.fields.find((f) => f.field === annotationFilter.fields[0].field)) {
294
+ foundAnnotationFilter = true;
295
+ } else if (!!filter.fields.find((f) => f.field === labelFilter.fields[0].field)) {
296
+ foundLabelFilter = true;
297
+ }
298
+ }
299
+ }
300
+
301
+ if (!foundLabelFilter) {
302
+ pagination.filters.push(labelFilter);
303
+ }
304
+
305
+ if (!foundAnnotationFilter) {
306
+ pagination.filters.push(annotationFilter);
307
+ }
308
+
309
+ if (!foundNsFilter) {
310
+ pagination.filters.push(namespaceFilter);
311
+ }
312
+
313
+ return pagination;
314
+ },
315
+
316
+ }
317
+ };
318
+ </script>
319
+
320
+ <template>
321
+ <div v-if="!$fetchState.pending">
322
+ <Masthead
323
+ component-testid="secrets-list"
324
+ :schema="schema"
325
+ :typeDisplay="mastheadLabel"
326
+ :resource="SECRET"
327
+ :favoriteResource="PROJECT_SECRETS"
328
+ :create-location="createLocation"
329
+ :isCreatable="true"
330
+ />
331
+ <PaginatedResourceTable
332
+ :groupSort="groupSort"
333
+ :groupable="true"
334
+ :groupOptions="groupOptions"
335
+ :schema="schema"
336
+ :headers="projectedScopedHeaders"
337
+ :namespaced="false"
338
+ :pagination-headers="projectedScopedHeadersSsp"
339
+ :local-filter="filterRowsLocal"
340
+ :api-filter="filterRowsApi"
341
+ :use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
342
+ :overrideInStore="STORE.MANAGEMENT"
343
+ />
344
+ </div>
345
+ </template>
@@ -10,11 +10,10 @@ import { mapFeature, HARVESTER as HARVESTER_FEATURE } from '@shell/store/feature
10
10
  import { NAME as EXPLORER } from '@shell/config/product/explorer';
11
11
  import ResourceFetch from '@shell/mixins/resource-fetch';
12
12
  import { BadgeState } from '@components/BadgeState';
13
- import CloudCredExpired from '@shell/components/formatter/CloudCredExpired';
14
13
 
15
14
  export default {
16
15
  components: {
17
- Banner, ResourceTable, Masthead, BadgeState, CloudCredExpired
16
+ Banner, ResourceTable, Masthead, BadgeState
18
17
  },
19
18
  mixins: [ResourceFetch],
20
19
  props: {
@@ -42,8 +41,6 @@ export default {
42
41
  mgmtClusters: this.$fetchType(MANAGEMENT.CLUSTER),
43
42
  };
44
43
 
45
- this.$store.dispatch('rancher/findAll', { type: NORMAN.CLOUD_CREDENTIAL });
46
-
47
44
  if ( this.$store.getters['management/canList'](SNAPSHOT) ) {
48
45
  hash.etcdSnapshots = this.$fetchType(SNAPSHOT);
49
46
  }
@@ -156,28 +153,6 @@ export default {
156
153
  return this.filteredRows.some((c) => c.metadata.namespace !== 'fleet-local' && c.metadata.namespace !== 'fleet-default');
157
154
  },
158
155
 
159
- tokenExpiredData() {
160
- const counts = this.rows.reduce((res, provCluster) => {
161
- const expireData = provCluster.cloudCredential?.expireData;
162
-
163
- if (expireData?.expiring) {
164
- res.expiring++;
165
- }
166
- if (expireData?.expired) {
167
- res.expired++;
168
- }
169
-
170
- return res;
171
- }, {
172
- expiring: 0,
173
- expired: 0
174
- });
175
-
176
- return {
177
- expiring: counts.expiring ? this.t('cluster.cloudCredentials.banners.expiring', { count: counts.expiring }) : '',
178
- expired: counts.expired ? this.t('cluster.cloudCredentials.banners.expired', { count: counts.expired }) : '',
179
- };
180
- }
181
156
  },
182
157
 
183
158
  $loadingResources() {
@@ -225,17 +200,6 @@ export default {
225
200
  </template>
226
201
  </Masthead>
227
202
 
228
- <Banner
229
- v-if="tokenExpiredData.expiring"
230
- color="warning"
231
- :label="tokenExpiredData.expiring"
232
- />
233
- <Banner
234
- v-if="tokenExpiredData.expired"
235
- color="error"
236
- :label="tokenExpiredData.expired"
237
- />
238
-
239
203
  <ResourceTable
240
204
  :schema="schema"
241
205
  :rows="filteredRows"
@@ -244,7 +208,6 @@ export default {
244
208
  :use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
245
209
  :data-testid="'cluster-list'"
246
210
  :force-update-live-and-delayed="forceUpdateLiveAndDelayed"
247
- :sub-rows="true"
248
211
  >
249
212
  <!-- Why are state column and subrow overwritten here? -->
250
213
  <!-- for rke1 clusters, where they try to use the mgmt cluster stateObj instead of prov cluster stateObj, -->
@@ -256,37 +219,6 @@ export default {
256
219
  :label="row.stateDisplay"
257
220
  />
258
221
  </template>
259
- <template #sub-row="{fullColspan, row, keyField, componentTestid, i, onRowMouseEnter, onRowMouseLeave}">
260
- <tr
261
- :key="row[keyField] + '-description'"
262
- :data-testid="componentTestid + '-' + i + '-row-description'"
263
- class="state-description sub-row"
264
- @mouseenter="onRowMouseEnter"
265
- @mouseleave="onRowMouseLeave"
266
- >
267
- <td v-if="row.cloudCredentialWarning || row.stateDescription">
268
- &nbsp;
269
- </td>
270
- <td
271
- v-if="row.cloudCredentialWarning || row.stateDescription"
272
- :colspan="fullColspan - 1"
273
- >
274
- <CloudCredExpired
275
- v-if="row.cloudCredentialWarning"
276
- :value="row.cloudCredential.expires"
277
- :row="row.cloudCredential"
278
- :verbose="true"
279
- :class="{'mb-10': row.stateDescription}"
280
- />
281
- <div
282
- v-if="row.stateDescription"
283
- :class="{ 'text-error' : row.stateObj.error }"
284
- >
285
- {{ row.stateDescription }}
286
- </div>
287
- </td>
288
- </tr>
289
- </template>
290
222
  <template #cell:summary="{row}">
291
223
  <span v-if="!row.stateParts.length">{{ row.nodes.length }}</span>
292
224
  </template>
@@ -0,0 +1,109 @@
1
+ <script lang="ts">
2
+ import Masthead from '@shell/components/ResourceList/Masthead';
3
+ import { SECRET_SCOPE, SECRET_QUERY_PARAMS } from '@shell/config/query-params';
4
+ import { MANAGEMENT, SECRET } from '@shell/config/types';
5
+ import { STORE } from '@shell/store/store-types';
6
+ import PaginatedResourceTable from '@shell/components/PaginatedResourceTable';
7
+ import { TableColumn } from '@shell/types/store/type-map';
8
+ import ResourceFetch from '@shell/mixins/resource-fetch';
9
+ import { mapGetters } from 'vuex';
10
+ import { SECRET_CLONE, SECRET_PROJECT_SCOPED } from '@shell/config/table-headers';
11
+ import { STEVE_SECRET_CLONE } from '@shell/config/pagination-table-headers';
12
+
13
+ export default {
14
+ name: 'ListSecret',
15
+
16
+ components: {
17
+ Masthead,
18
+ PaginatedResourceTable
19
+ },
20
+ props: {
21
+ resource: {
22
+ type: String,
23
+ required: true,
24
+ },
25
+
26
+ schema: {
27
+ type: Object,
28
+ required: true,
29
+ },
30
+
31
+ useQueryParamsForSimpleFiltering: {
32
+ type: Boolean,
33
+ default: false
34
+ }
35
+ },
36
+
37
+ mixins: [ResourceFetch],
38
+
39
+ data() {
40
+ return {
41
+ canViewProjects: false,
42
+ activeTab: SECRET_QUERY_PARAMS.NAMESPACED,
43
+ SECRET_TABS: SECRET_QUERY_PARAMS,
44
+ managementSchema: undefined,
45
+
46
+ STORE,
47
+
48
+ namespacedHeaders: [] as TableColumn[],
49
+ namespacedHeadersSsp: [] as TableColumn[],
50
+ };
51
+ },
52
+
53
+ async created() {
54
+ this.canViewProjects = this.$store.getters[`${ STORE.MANAGEMENT }/schemaFor`](MANAGEMENT.PROJECT);
55
+ this.managementSchema = this.$store.getters[`${ STORE.MANAGEMENT }/schemaFor`](SECRET);
56
+ this.namespacedHeaders = this.$store.getters['type-map/headersFor'](this.schema, false) as TableColumn[];
57
+ this.namespacedHeadersSsp = this.$store.getters['type-map/headersFor'](this.schema, true) as TableColumn[];
58
+
59
+ const headers = this.namespacedHeaders.slice(0, -1);
60
+ const headersSSP = this.namespacedHeadersSsp.slice(0, -1);
61
+
62
+ if (this.canViewProjects) {
63
+ // if the user can see projects, add a column to let them know if it's a secret from a project scoped secret
64
+ headers.push(SECRET_CLONE);
65
+ headersSSP.push(STEVE_SECRET_CLONE);
66
+ if (this.currentCluster.isLocal) {
67
+ // if the user is on the local cluster, add a column to let them know if it's a project scoped secret (from another cluster)
68
+ headers.push(SECRET_PROJECT_SCOPED);
69
+ headersSSP.push(SECRET_PROJECT_SCOPED);
70
+ }
71
+ }
72
+
73
+ headers.push(this.namespacedHeaders[this.namespacedHeaders.length - 1]);
74
+ headersSSP.push(this.namespacedHeadersSsp[this.namespacedHeadersSsp.length - 1]);
75
+
76
+ this.namespacedHeaders = headers;
77
+ this.namespacedHeadersSsp = headersSSP;
78
+ },
79
+
80
+ computed: {
81
+ createLocation() {
82
+ return {
83
+ name: 'c-cluster-product-resource-create',
84
+ query: { [SECRET_SCOPE]: SECRET_QUERY_PARAMS.NAMESPACED }
85
+ };
86
+ },
87
+
88
+ ...mapGetters(['currentCluster']),
89
+ },
90
+
91
+ };
92
+ </script>
93
+
94
+ <template>
95
+ <div>
96
+ <Masthead
97
+ component-testid="secrets-list"
98
+ :schema="schema"
99
+ :resource="resource"
100
+ :create-location="createLocation"
101
+ />
102
+ <PaginatedResourceTable
103
+ :schema="schema"
104
+ :headers="namespacedHeaders"
105
+ :pagination-headers="namespacedHeadersSsp"
106
+ :use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
107
+ />
108
+ </div>
109
+ </template>
@@ -255,8 +255,8 @@ describe('component: vmwarevsphere', () => {
255
255
  });
256
256
  });
257
257
 
258
- describe('syncNetworkValueForLegacyLabels', () => {
259
- it('should update the current network value properly', () => {
258
+ describe('network name backwards compatibility', () => {
259
+ it('should NOT update the current network value to use MOID instead of name', async() => {
260
260
  const legacyName = 'legacy_name';
261
261
  const legacyValue = 'legacy_value';
262
262
  const networkLabel = 'network_label';
@@ -291,12 +291,10 @@ describe('component: vmwarevsphere', () => {
291
291
  }
292
292
  });
293
293
 
294
- // check the current network before updating
295
- expect(wrapper.vm.value.network).toStrictEqual([legacyName]);
296
-
297
- wrapper.vm.syncNetworkValueForLegacyLabels();
294
+ await wrapper.vm.loadNetworks();
295
+ await wrapper.vm.$nextTick();
298
296
 
299
- expect(wrapper.vm.value.network).toStrictEqual([legacyValue]);
297
+ expect(wrapper.vm.value.network).toStrictEqual([legacyName]);
300
298
  });
301
299
  });
302
300
  });
@@ -38,7 +38,8 @@ const defaultConfig = Object.freeze({
38
38
  vmLabels: '',
39
39
  username: 'docker-user',
40
40
  setInternalFirewallRulePrefix: true,
41
- setExternalFirewallRulePrefix: false
41
+ setExternalFirewallRulePrefix: false,
42
+ preemptible: false
42
43
  });
43
44
 
44
45
  export default {
@@ -537,6 +538,13 @@ export default {
537
538
  class="span-3"
538
539
  />
539
540
  </div>
541
+ <Checkbox
542
+ v-model:value="value.preemptible"
543
+ :mode="mode"
544
+ :label="t('cluster.machineConfig.gce.preemptible.label')"
545
+ :tooltip="t('cluster.machineConfig.gce.preemptible.tooltip')"
546
+ class="mt-20"
547
+ />
540
548
 
541
549
  <ArrayList
542
550
  v-model:value="scopes"
@@ -340,9 +340,15 @@ export default {
340
340
 
341
341
  gracefulShutdownTimeout: integerString('value.gracefulShutdownTimeout'),
342
342
 
343
+ // as of 2.10.0 Rancher uses network MOID instead of network name
344
+ // if users have a vsphere cluster using network names instead of MOID, the UI should still display both name and MOID in the network dropdown
345
+ // this getter will check each value in network and, if it matches a network name (ie is not a MOID), will find the associated MOID and return that instead
346
+ // this does not automatically update the cluster spec to use MOID instead of name, just the display
343
347
  network: {
344
348
  get() {
345
- return this.value.network || [];
349
+ const selectedNetworks = this.value.network || [];
350
+
351
+ return selectedNetworks.map((n) => this.networks.find((nw) => nw.name === n)?.value || n);
346
352
  },
347
353
  set(newValue) {
348
354
  set(this.value, 'network', newValue);
@@ -558,7 +564,6 @@ export default {
558
564
  this.resetValueIfNecessary('network', content, options, true);
559
565
 
560
566
  set(this, 'networksResults', content);
561
- this.syncNetworkValueForLegacyLabels();
562
567
  this.vappMode = this.getInitialVappMode(this.value);
563
568
  },
564
569
 
@@ -670,21 +675,6 @@ export default {
670
675
  }
671
676
  },
672
677
 
673
- // Network labels have been updated to include the MOID.
674
- // To ensure previously selected networks remain consistent with this change,
675
- // we update the current network value to allow correct selection from the network list.
676
- syncNetworkValueForLegacyLabels() {
677
- const currentNetwork = this.value.network[0];
678
-
679
- if (this.mode !== _CREATE && currentNetwork) {
680
- const networkMatch = this.networks.find((network) => currentNetwork === network.name && currentNetwork !== network.label);
681
-
682
- if (networkMatch) {
683
- this.value.network = [networkMatch.value];
684
- }
685
- }
686
- },
687
-
688
678
  mapPathOptionsToContent(pathOptions) {
689
679
  return (pathOptions || []).map((pathOption) => {
690
680
  return {
@@ -99,9 +99,9 @@ describe('brandMixin', () => {
99
99
  filters: [{
100
100
  equals: true,
101
101
  fields: [{
102
- equals: true, exact: true, field: 'metadata.name', value: 'rancher-csp-adapter'
102
+ equals: true, exact: true, exists: false, field: 'metadata.name', value: 'rancher-csp-adapter'
103
103
  }, {
104
- equals: true, exact: true, field: 'metadata.name', value: 'rancher-csp-billing-adapter'
104
+ equals: true, exact: true, exists: false, field: 'metadata.name', value: 'rancher-csp-billing-adapter'
105
105
  }],
106
106
  param: 'filter'
107
107
  }],
package/mixins/chart.js CHANGED
@@ -63,7 +63,6 @@ export default {
63
63
  label: version.version,
64
64
  version: version.version,
65
65
  originalVersion: version.version,
66
- shortLabel: version.version.length > 16 ? `${ version.version.slice(0, 15) }...` : version.version,
67
66
  id: version.version,
68
67
  created: version.created,
69
68
  disabled: false,
@@ -93,7 +92,6 @@ export default {
93
92
  out.unshift({
94
93
  label: selectedVersion,
95
94
  originalVersion: selectedVersion,
96
- shortLabel: selectedVersion.length > 16 ? `${ selectedVersion.slice(0, 15) }...` : selectedVersion,
97
95
  id: selectedVersion,
98
96
  created: null,
99
97
  disabled: false,