@rancher/shell 3.0.0-rc.9 → 3.0.1-rc.1
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/brand/harvester/favicon.png +0 -0
- package/assets/brand/harvester/metadata.json +3 -0
- package/assets/images/pl/harvester.svg +1 -0
- package/assets/translations/en-us.yaml +37 -15
- package/assets/translations/zh-hans.yaml +2 -5
- package/components/BrandImage.vue +5 -1
- package/components/CopyToClipboardText.vue +2 -0
- package/components/CruResourceFooter.vue +1 -0
- package/components/DetailTop.vue +1 -1
- package/components/EmberPage.vue +0 -8
- package/components/ExplorerMembers.vue +5 -1
- package/components/ExplorerProjectsNamespaces.vue +39 -15
- package/components/HardwareResourceGauge.vue +12 -2
- package/components/InputOrDisplay.vue +6 -2
- package/components/LandingPagePreference.vue +2 -2
- package/components/MessageLink.vue +1 -1
- package/components/ResourceDetail/Masthead.vue +22 -1
- package/components/ResourceDetail/index.vue +2 -8
- package/components/ResourceTable.vue +40 -7
- package/components/ResourceYaml.vue +1 -1
- package/components/SideNav.vue +1 -1
- package/components/SortableTable/actions.js +1 -1
- package/components/SortableTable/index.vue +17 -1
- package/components/SortableTable/selection.js +1 -1
- package/components/SortableTable/sorting.js +11 -3
- package/components/TableDataUserIcon.vue +1 -1
- package/components/fleet/FleetClusters.vue +0 -3
- package/components/fleet/FleetRepos.vue +0 -7
- package/components/form/ArrayList.vue +5 -1
- package/components/form/ArrayListSelect.vue +5 -1
- package/components/form/HookOption.vue +31 -29
- package/components/form/KeyValue.vue +1 -1
- package/components/form/LabeledSelect.vue +26 -7
- package/components/form/LifecycleHooks.vue +2 -2
- package/components/form/Password.vue +7 -1
- package/components/form/UnitInput.vue +10 -1
- package/components/form/__tests__/UnitInput.test.ts +1 -0
- package/components/formatter/ClusterProvider.vue +3 -3
- package/components/formatter/ImagePercentageBar.vue +1 -1
- package/components/formatter/SecretData.vue +1 -1
- package/components/formatter/Si.vue +5 -1
- package/components/formatter/Translate.vue +1 -1
- package/components/nav/Header.vue +38 -17
- package/components/nav/NamespaceFilter.vue +5 -8
- package/components/nav/TopLevelMenu.vue +11 -51
- package/components/nav/WorkspaceSwitcher.vue +0 -1
- package/config/labels-annotations.js +2 -0
- package/config/private-label.js +2 -1
- package/config/router/routes.js +2 -26
- package/config/settings.ts +5 -0
- package/config/table-headers.js +15 -0
- package/config/types.js +3 -0
- package/config/version.js +2 -0
- package/detail/catalog.cattle.io.app.vue +17 -4
- package/detail/fleet.cattle.io.bundle.vue +5 -68
- package/detail/fleet.cattle.io.cluster.vue +11 -9
- package/detail/fleet.cattle.io.gitrepo.vue +3 -2
- package/directives/clean-tooltip.js +4 -4
- package/edit/cis.cattle.io.clusterscan.vue +4 -3
- package/edit/fleet.cattle.io.gitrepo.vue +11 -8
- package/edit/logging-flow/Match.vue +75 -42
- package/edit/logging-flow/index.vue +89 -10
- package/edit/logging.banzaicloud.io.output/index.vue +2 -2
- package/edit/management.cattle.io.project.vue +4 -3
- package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +5 -5
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -1
- package/edit/namespace.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +26 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +63 -149
- package/edit/provisioning.cattle.io.cluster/index.vue +2 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +4 -4
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +7 -2
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +108 -35
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +1 -1
- package/edit/workload/mixins/workload.js +1 -1
- package/list/harvesterhci.io.management.cluster.vue +244 -0
- package/list/namespace.vue +16 -4
- package/mixins/browser-tab-visibility.js +1 -1
- package/mixins/chart.js +6 -2
- package/mixins/metric-poller.js +1 -1
- package/mixins/resource-fetch.js +1 -1
- package/models/__tests__/management.cattle.io.cluster.test.ts +45 -3
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -86
- package/models/catalog.cattle.io.app.js +108 -21
- package/models/cloudcredential.js +4 -4
- package/models/fleet.cattle.io.bundle.js +3 -1
- package/models/fleet.cattle.io.gitrepo.js +51 -63
- package/models/k8s.cni.cncf.io.networkattachmentdefinition.js +88 -0
- package/models/management.cattle.io.cluster.js +39 -7
- package/models/management.cattle.io.project.js +4 -0
- package/models/management.cattle.io.setting.js +25 -0
- package/models/provisioning.cattle.io.cluster.js +6 -16
- package/models/storage.k8s.io.storageclass.js +15 -4
- package/models/workload.js +1 -1
- package/package.json +5 -5
- package/pages/auth/login.vue +3 -2
- package/pages/auth/logout.vue +7 -9
- package/pages/auth/setup.vue +4 -1
- package/pages/c/_cluster/apps/charts/install.vue +11 -3
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +1 -1
- package/pages/c/_cluster/explorer/index.vue +1 -2
- package/pages/c/_cluster/fleet/index.vue +13 -9
- package/pages/c/_cluster/settings/brand.vue +4 -1
- package/pages/c/_cluster/uiplugins/index.vue +4 -2
- package/pages/diagnostic.vue +1 -0
- package/pages/prefs.vue +22 -10
- package/plugins/dashboard-store/resource-class.js +11 -3
- package/plugins/steve/mutations.js +4 -1
- package/plugins/steve/steve-pagination-utils.ts +1 -1
- package/plugins/steve/subscribe.js +3 -4
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -2
- package/store/features.js +1 -0
- package/store/i18n.js +5 -1
- package/store/prefs.js +8 -0
- package/types/resources/fleet.d.ts +40 -0
- package/types/shell/index.d.ts +442 -396
- package/utils/__tests__/object.test.ts +152 -1
- package/utils/auth.js +1 -1
- package/utils/create-yaml.js +1 -1
- package/utils/favicon.js +2 -0
- package/utils/fleet.ts +159 -0
- package/utils/gc/gc.ts +1 -1
- package/utils/object.js +37 -0
- package/utils/string.js +9 -0
- package/utils/v-sphere.ts +31 -0
- package/utils/validators/cron-schedule.js +1 -1
- package/utils/validators/formRules/index.ts +2 -2
- package/config/product/multi-cluster-apps.js +0 -61
|
@@ -10,7 +10,6 @@ import { compare } from '@shell/utils/version';
|
|
|
10
10
|
import { AS, MODE, _VIEW, _YAML } from '@shell/config/query-params';
|
|
11
11
|
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
12
12
|
import { CAPI as CAPI_ANNOTATIONS, NODE_ARCHITECTURE } from '@shell/config/labels-annotations';
|
|
13
|
-
import capitalize from 'lodash/capitalize';
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Class representing Cluster resource.
|
|
@@ -283,19 +282,7 @@ export default class ProvCluster extends SteveModel {
|
|
|
283
282
|
}
|
|
284
283
|
|
|
285
284
|
get isImported() {
|
|
286
|
-
|
|
287
|
-
// in which this.provisioner is `k3s`.
|
|
288
|
-
|
|
289
|
-
const isImportedProvisioner = this.provisioner === 'imported';
|
|
290
|
-
const isImportedSpecialCases = this.mgmt?.providerForEmberParam === 'import' ||
|
|
291
|
-
// when imported cluster is GKE
|
|
292
|
-
!!this.mgmt?.spec?.gkeConfig?.imported ||
|
|
293
|
-
// or AKS
|
|
294
|
-
!!this.mgmt?.spec?.aksConfig?.imported ||
|
|
295
|
-
// or EKS
|
|
296
|
-
!!this.mgmt?.spec?.eksConfig?.imported;
|
|
297
|
-
|
|
298
|
-
return !this.isLocal && (isImportedProvisioner || (!this.isRke2 && !this.mgmt?.machineProvider && isImportedSpecialCases));
|
|
285
|
+
return this.mgmt?.isImported;
|
|
299
286
|
}
|
|
300
287
|
|
|
301
288
|
get isCustom() {
|
|
@@ -331,7 +318,8 @@ export default class ProvCluster extends SteveModel {
|
|
|
331
318
|
}
|
|
332
319
|
|
|
333
320
|
get isRke1() {
|
|
334
|
-
|
|
321
|
+
// rancherKubernetesEngineConfig is not defined on imported RKE1 clusters
|
|
322
|
+
return !!this.mgmt?.spec?.rancherKubernetesEngineConfig || this.mgmt?.labels['provider.cattle.io'] === 'rke';
|
|
335
323
|
}
|
|
336
324
|
|
|
337
325
|
get isHarvester() {
|
|
@@ -408,6 +396,8 @@ export default class ProvCluster extends SteveModel {
|
|
|
408
396
|
provisioner = 'k3s';
|
|
409
397
|
} else if ( this.isImportedRke2 ) {
|
|
410
398
|
provisioner = 'rke2';
|
|
399
|
+
} else if ((this.isImported || this.isLocal) && this.isRke1) {
|
|
400
|
+
provisioner = 'rke';
|
|
411
401
|
}
|
|
412
402
|
|
|
413
403
|
return this.$rootGetters['i18n/withFallback'](`cluster.provider."${ provisioner }"`, null, ucFirst(provisioner));
|
|
@@ -424,7 +414,7 @@ export default class ProvCluster extends SteveModel {
|
|
|
424
414
|
if (!node.metadata?.state?.transitioning) {
|
|
425
415
|
const architecture = node.status?.nodeLabels?.[NODE_ARCHITECTURE];
|
|
426
416
|
|
|
427
|
-
const key = architecture
|
|
417
|
+
const key = architecture || this.t('cluster.architecture.label.unknown');
|
|
428
418
|
|
|
429
419
|
obj[key] = (obj[key] || 0) + 1;
|
|
430
420
|
}
|
|
@@ -112,16 +112,21 @@ export default class extends SteveModel {
|
|
|
112
112
|
return this.patch(data, {}, true, true);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
setDefault() {
|
|
116
|
-
const
|
|
115
|
+
async setDefault() {
|
|
116
|
+
const inStore = this.$rootGetters['currentProduct'].inStore;
|
|
117
|
+
const allStorageClasses = this.$rootGetters[`${ inStore }/all`](STORAGE_CLASS) || [];
|
|
118
|
+
|
|
119
|
+
for (const storageClass of allStorageClasses) {
|
|
120
|
+
await storageClass.resetDefault();
|
|
121
|
+
}
|
|
117
122
|
|
|
118
123
|
allStorageClasses.forEach((storageClass) => storageClass.resetDefault());
|
|
119
124
|
this.updateDefault(true);
|
|
120
125
|
}
|
|
121
126
|
|
|
122
|
-
resetDefault() {
|
|
127
|
+
async resetDefault() {
|
|
123
128
|
if (this.isDefault) {
|
|
124
|
-
this.updateDefault(false);
|
|
129
|
+
await this.updateDefault(false);
|
|
125
130
|
}
|
|
126
131
|
}
|
|
127
132
|
|
|
@@ -146,4 +151,10 @@ export default class extends SteveModel {
|
|
|
146
151
|
|
|
147
152
|
return out;
|
|
148
153
|
}
|
|
154
|
+
|
|
155
|
+
cleanForNew() {
|
|
156
|
+
this.$dispatch(`cleanForNew`, this);
|
|
157
|
+
|
|
158
|
+
delete this?.metadata?.annotations?.[STORAGE.DEFAULT_STORAGE_CLASS];
|
|
159
|
+
}
|
|
149
160
|
}
|
package/models/workload.js
CHANGED
|
@@ -110,7 +110,7 @@ export default class Workload extends WorkloadService {
|
|
|
110
110
|
spec.template = {
|
|
111
111
|
spec: {
|
|
112
112
|
restartPolicy: this.type === WORKLOAD_TYPES.JOB ? 'Never' : 'Always',
|
|
113
|
-
containers: [{ ...defaultContainer }],
|
|
113
|
+
containers: [{ ...structuredClone(defaultContainer) }],
|
|
114
114
|
initContainers: []
|
|
115
115
|
}
|
|
116
116
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rancher/shell",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1-rc.1",
|
|
4
4
|
"description": "Rancher Dashboard Shell",
|
|
5
5
|
"repository": "https://github.com/rancherlabs/dashboard",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"cookie": "0.5.0",
|
|
63
63
|
"cookie-universal": "2.2.2",
|
|
64
64
|
"core-js": "3.25.3",
|
|
65
|
-
"cron-validator": "1.
|
|
66
|
-
"cronstrue": "
|
|
65
|
+
"cron-validator": "1.3.1",
|
|
66
|
+
"cronstrue": "2.50.0",
|
|
67
67
|
"cross-env": "6.0.3",
|
|
68
68
|
"css-loader": "6.7.3",
|
|
69
69
|
"csv-loader": "3.0.3",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"dagre-d3": "0.6.4",
|
|
75
75
|
"dayjs": "1.8.29",
|
|
76
76
|
"diff2html": "3.4.24",
|
|
77
|
-
"dompurify": "2.4
|
|
77
|
+
"dompurify": "2.5.4",
|
|
78
78
|
"element-matches": "^0.1.2",
|
|
79
79
|
"eslint": "7.32.0",
|
|
80
80
|
"eslint-config-standard": "16.0.3",
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"js-yaml": "4.1.0",
|
|
103
103
|
"js-yaml-loader": "1.2.2",
|
|
104
104
|
"jsdiff": "1.1.1",
|
|
105
|
-
"jsonpath-plus": "
|
|
105
|
+
"jsonpath-plus": "10.0.0",
|
|
106
106
|
"jsrsasign": "10.5.25",
|
|
107
107
|
"jszip": "3.8.0",
|
|
108
108
|
"lodash": "4.17.21",
|
package/pages/auth/login.vue
CHANGED
|
@@ -64,7 +64,8 @@ export default {
|
|
|
64
64
|
},
|
|
65
65
|
|
|
66
66
|
computed: {
|
|
67
|
-
...mapGetters(
|
|
67
|
+
...mapGetters(['isStandaloneHarvester']),
|
|
68
|
+
...mapGetters({ t: 'i18n/t', hasMultipleLocales: 'i18n/hasMultipleLocales' }),
|
|
68
69
|
|
|
69
70
|
loggedOutSuccessMsg() {
|
|
70
71
|
if (this.isSlo) {
|
|
@@ -497,7 +498,7 @@ export default {
|
|
|
497
498
|
</div>
|
|
498
499
|
</template>
|
|
499
500
|
<div
|
|
500
|
-
v-if="showLocaleSelector"
|
|
501
|
+
v-if="showLocaleSelector && hasMultipleLocales && !isStandaloneHarvester"
|
|
501
502
|
class="locale-selector"
|
|
502
503
|
>
|
|
503
504
|
<LocaleSelector
|
package/pages/auth/logout.vue
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {
|
|
2
|
+
import { configType } from '@shell/models/management.cattle.io.authconfig';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
5
|
async fetch() {
|
|
6
|
-
const
|
|
6
|
+
const publicAuthProviders = await this.$store.dispatch('auth/getAuthProviders');
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const authProvider = authInfo.enabled[0];
|
|
8
|
+
const samlAuthProvider = publicAuthProviders.find((authProvider) => configType[authProvider.id] === 'saml');
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} = authProvider;
|
|
10
|
+
if (!!samlAuthProvider) {
|
|
11
|
+
const { logoutAllSupported, logoutAllEnabled, logoutAllForced } = samlAuthProvider;
|
|
14
12
|
|
|
15
|
-
if (
|
|
13
|
+
if (logoutAllSupported && logoutAllEnabled && logoutAllForced) {
|
|
16
14
|
// SAML - force SLO (logout from all apps)
|
|
17
15
|
await this.$store.dispatch('auth/logout', {
|
|
18
|
-
force: true, slo: true, provider:
|
|
16
|
+
force: true, slo: true, provider: samlAuthProvider
|
|
19
17
|
}, { root: true });
|
|
20
18
|
} else {
|
|
21
19
|
// simple logout
|
package/pages/auth/setup.vue
CHANGED
|
@@ -141,7 +141,7 @@ export default {
|
|
|
141
141
|
type: MANAGEMENT.FEATURE, id: 'multi-cluster-management', opt: { url: `/v1/${ MANAGEMENT.FEATURE }/multi-cluster-management` }
|
|
142
142
|
});
|
|
143
143
|
|
|
144
|
-
const mcmEnabled = mcmFeature?.spec?.value || mcmFeature?.status?.default;
|
|
144
|
+
const mcmEnabled = (mcmFeature?.spec?.value || mcmFeature?.status?.default) && productName !== 'Harvester';
|
|
145
145
|
|
|
146
146
|
let serverUrl;
|
|
147
147
|
|
|
@@ -496,6 +496,7 @@ export default {
|
|
|
496
496
|
|
|
497
497
|
.span-6 {
|
|
498
498
|
padding: 0 60px;
|
|
499
|
+
margin: 0;
|
|
499
500
|
}
|
|
500
501
|
|
|
501
502
|
.landscape {
|
|
@@ -503,6 +504,7 @@ export default {
|
|
|
503
504
|
margin: 0;
|
|
504
505
|
object-fit: cover;
|
|
505
506
|
padding: 0;
|
|
507
|
+
width: 49%;
|
|
506
508
|
}
|
|
507
509
|
}
|
|
508
510
|
|
|
@@ -512,6 +514,7 @@ export default {
|
|
|
512
514
|
overflow-y: auto;
|
|
513
515
|
position: relative;
|
|
514
516
|
height: 100vh;
|
|
517
|
+
width: 51%;
|
|
515
518
|
|
|
516
519
|
& > div:first-of-type {
|
|
517
520
|
flex:3;
|
|
@@ -294,8 +294,9 @@ export default {
|
|
|
294
294
|
*/
|
|
295
295
|
userValues = diff(this.loadedVersionValues, this.chartValues);
|
|
296
296
|
} else if ( this.existing ) {
|
|
297
|
+
await this.existing.fetchValues(); // In theory this has already been called, but do again to be safe
|
|
297
298
|
/* For an already installed app, use the values from the previous install. */
|
|
298
|
-
userValues = clone(this.existing.
|
|
299
|
+
userValues = clone(this.existing.values || {});
|
|
299
300
|
} else {
|
|
300
301
|
/* For an new app, start empty. */
|
|
301
302
|
userValues = {};
|
|
@@ -1457,6 +1458,7 @@ export default {
|
|
|
1457
1458
|
<Banner
|
|
1458
1459
|
v-if="isNamespaceNew && value.metadata.namespace.length"
|
|
1459
1460
|
color="info"
|
|
1461
|
+
class="namespace-create-banner"
|
|
1460
1462
|
>
|
|
1461
1463
|
<div v-clean-html="t('catalog.install.steps.basics.createNamespace', {namespace: value.metadata.namespace}, true) " />
|
|
1462
1464
|
</Banner>
|
|
@@ -1661,9 +1663,10 @@ export default {
|
|
|
1661
1663
|
class="mt-10"
|
|
1662
1664
|
>
|
|
1663
1665
|
<UnitInput
|
|
1664
|
-
v-model
|
|
1666
|
+
v-model:value="customCmdOpts.timeout"
|
|
1665
1667
|
:label="t('catalog.install.helm.timeout.label')"
|
|
1666
1668
|
:suffix="t('catalog.install.helm.timeout.unit', {value: customCmdOpts.timeout})"
|
|
1669
|
+
type="number"
|
|
1667
1670
|
/>
|
|
1668
1671
|
</div>
|
|
1669
1672
|
<div
|
|
@@ -1672,9 +1675,10 @@ export default {
|
|
|
1672
1675
|
>
|
|
1673
1676
|
<UnitInput
|
|
1674
1677
|
v-if="existing"
|
|
1675
|
-
v-model
|
|
1678
|
+
v-model:value="customCmdOpts.historyMax"
|
|
1676
1679
|
:label="t('catalog.install.helm.historyMax.label')"
|
|
1677
1680
|
:suffix="t('catalog.install.helm.historyMax.unit', {value: customCmdOpts.historyMax})"
|
|
1681
|
+
type="number"
|
|
1678
1682
|
/>
|
|
1679
1683
|
</div>
|
|
1680
1684
|
<div
|
|
@@ -1852,6 +1856,10 @@ export default {
|
|
|
1852
1856
|
.spacer {
|
|
1853
1857
|
line-height: 2;
|
|
1854
1858
|
}
|
|
1859
|
+
|
|
1860
|
+
.namespace-create-banner {
|
|
1861
|
+
margin-bottom: 70px;
|
|
1862
|
+
}
|
|
1855
1863
|
}
|
|
1856
1864
|
&__values {
|
|
1857
1865
|
&__controls {
|
|
@@ -164,7 +164,7 @@ describe('page: cluster dashboard', () => {
|
|
|
164
164
|
['created', 'glance.created', []],
|
|
165
165
|
['architecture', 'mixed', [{ labels: { [NODE_ARCHITECTURE]: 'amd64' } }, { labels: { [NODE_ARCHITECTURE]: 'intel' } }]],
|
|
166
166
|
['architecture', 'mixed', [{ labels: { [NODE_ARCHITECTURE]: 'amd64' } }, { labels: { } }]],
|
|
167
|
-
['architecture', '
|
|
167
|
+
['architecture', 'amd64', [{ labels: { [NODE_ARCHITECTURE]: 'amd64' } }]],
|
|
168
168
|
['architecture', 'unknown', [{ labels: { } }]],
|
|
169
169
|
['architecture', 'glance.architecture', [{ metadata: { state: { transitioning: true } } }]],
|
|
170
170
|
])('should show %p label %p', (label, text, nodes) => {
|
|
@@ -47,7 +47,6 @@ import Certificates from '@shell/components/Certificates';
|
|
|
47
47
|
import { NAME as EXPLORER } from '@shell/config/product/explorer';
|
|
48
48
|
import TabTitle from '@shell/components/TabTitle';
|
|
49
49
|
import { STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';
|
|
50
|
-
import capitalize from 'lodash/capitalize';
|
|
51
50
|
|
|
52
51
|
export const RESOURCES = [NAMESPACE, INGRESS, PV, WORKLOAD_TYPES.DEPLOYMENT, WORKLOAD_TYPES.STATEFUL_SET, WORKLOAD_TYPES.JOB, WORKLOAD_TYPES.DAEMON_SET, SERVICE];
|
|
53
52
|
|
|
@@ -232,7 +231,7 @@ export default {
|
|
|
232
231
|
if (!node.metadata?.state?.transitioning) {
|
|
233
232
|
const architecture = node.labels?.[NODE_ARCHITECTURE];
|
|
234
233
|
|
|
235
|
-
const key = architecture
|
|
234
|
+
const key = architecture || this.t('cluster.architecture.label.unknown');
|
|
236
235
|
|
|
237
236
|
obj[key] = (obj[key] || 0) + 1;
|
|
238
237
|
}
|
|
@@ -12,6 +12,7 @@ import { WORKSPACE_ANNOTATION } from '@shell/config/labels-annotations';
|
|
|
12
12
|
import { filterBy } from '@shell/utils/array';
|
|
13
13
|
import FleetNoWorkspaces from '@shell/components/fleet/FleetNoWorkspaces.vue';
|
|
14
14
|
import { NAME } from '@shell/config/product/fleet';
|
|
15
|
+
import { xOfy } from '@shell/utils/string';
|
|
15
16
|
|
|
16
17
|
export default {
|
|
17
18
|
name: 'FleetDashboard',
|
|
@@ -39,6 +40,7 @@ export default {
|
|
|
39
40
|
allBundles: {
|
|
40
41
|
inStoreType: 'management',
|
|
41
42
|
type: FLEET.BUNDLE,
|
|
43
|
+
opt: { excludeFields: ['metadata.managedFields', 'spec.resources'] },
|
|
42
44
|
},
|
|
43
45
|
gitRepos: {
|
|
44
46
|
inStoreType: 'management',
|
|
@@ -175,7 +177,12 @@ export default {
|
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
if (area === 'clusters') {
|
|
178
|
-
|
|
180
|
+
if (row.clusterInfo?.ready === row.clusterInfo?.total && row.clusterInfo?.ready) {
|
|
181
|
+
return {
|
|
182
|
+
badgeClass: STATES[STATES_ENUM.ACTIVE].color,
|
|
183
|
+
icon: STATES[STATES_ENUM.ACTIVE].compoundIcon
|
|
184
|
+
};
|
|
185
|
+
}
|
|
179
186
|
} else if (area === 'bundles') {
|
|
180
187
|
group = row.bundles;
|
|
181
188
|
} else if (area === 'resources') {
|
|
@@ -223,7 +230,7 @@ export default {
|
|
|
223
230
|
}
|
|
224
231
|
|
|
225
232
|
if (area === 'clusters') {
|
|
226
|
-
group =
|
|
233
|
+
group = '';
|
|
227
234
|
} else if (area === 'bundles') {
|
|
228
235
|
group = row.bundles;
|
|
229
236
|
} else if (area === 'resources') {
|
|
@@ -262,11 +269,11 @@ export default {
|
|
|
262
269
|
}
|
|
263
270
|
|
|
264
271
|
if (area === 'clusters') {
|
|
265
|
-
|
|
272
|
+
return `${ row.clusterInfo.ready }/${ row.clusterInfo.total }`;
|
|
266
273
|
} else if (area === 'bundles') {
|
|
267
|
-
value =
|
|
274
|
+
value = xOfy(row.bundlesReady?.length, row.bundles?.length);
|
|
268
275
|
} else if (area === 'resources') {
|
|
269
|
-
value =
|
|
276
|
+
value = xOfy(row.status?.resourceCounts?.ready, row.status?.resourceCounts?.desiredReady);
|
|
270
277
|
}
|
|
271
278
|
|
|
272
279
|
return value;
|
|
@@ -294,7 +301,7 @@ export default {
|
|
|
294
301
|
</script>
|
|
295
302
|
|
|
296
303
|
<template>
|
|
297
|
-
<div
|
|
304
|
+
<div>
|
|
298
305
|
<Loading v-if="$fetchState.pending" />
|
|
299
306
|
<!-- no git repos -->
|
|
300
307
|
<FleetNoWorkspaces
|
|
@@ -444,9 +451,6 @@ export default {
|
|
|
444
451
|
</template>
|
|
445
452
|
|
|
446
453
|
<style lang="scss" scoped>
|
|
447
|
-
.fleet-dashboard {
|
|
448
|
-
min-height: 100vh;
|
|
449
|
-
}
|
|
450
454
|
.fleet-empty-dashboard {
|
|
451
455
|
flex: 1;
|
|
452
456
|
display: flex;
|
|
@@ -141,6 +141,9 @@ export default {
|
|
|
141
141
|
const schema = this.$store.getters[`management/schemaFor`](MANAGEMENT.SETTING);
|
|
142
142
|
|
|
143
143
|
return schema?.resourceMethods?.includes('PUT') ? _EDIT : _VIEW;
|
|
144
|
+
},
|
|
145
|
+
customLinkColor() {
|
|
146
|
+
return { color: this.uiLinkColor };
|
|
144
147
|
}
|
|
145
148
|
},
|
|
146
149
|
|
|
@@ -564,7 +567,7 @@ export default {
|
|
|
564
567
|
component-testid="link"
|
|
565
568
|
/>
|
|
566
569
|
<span class="col link-example">
|
|
567
|
-
<a>
|
|
570
|
+
<a :style="customLinkColor">
|
|
568
571
|
{{ t('branding.linkColor.example') }}
|
|
569
572
|
</a>
|
|
570
573
|
</span>
|
|
@@ -154,7 +154,8 @@ export default {
|
|
|
154
154
|
},
|
|
155
155
|
|
|
156
156
|
showAddReposBanner() {
|
|
157
|
-
|
|
157
|
+
// because of https://github.com/rancher/rancher/pull/45894 we need to consider other start values
|
|
158
|
+
const hasExtensionReposBannerSetting = this.addExtensionReposBannerSetting?.value === 'true' || this.addExtensionReposBannerSetting?.value === '' || this.addExtensionReposBannerSetting?.value === undefined;
|
|
158
159
|
const uiPluginsRepoNotFound = isRancherPrime() && !this.repos?.find((r) => r.urlDisplay === UI_PLUGINS_REPOS.OFFICIAL.URL);
|
|
159
160
|
const uiPluginsPartnersRepoNotFound = !this.repos?.find((r) => r.urlDisplay === UI_PLUGINS_REPOS.PARTNERS.URL);
|
|
160
161
|
|
|
@@ -615,7 +616,8 @@ export default {
|
|
|
615
616
|
},
|
|
616
617
|
|
|
617
618
|
updateAddReposSetting() {
|
|
618
|
-
|
|
619
|
+
// because of https://github.com/rancher/rancher/pull/45894 we need to consider other start values
|
|
620
|
+
if (this.addExtensionReposBannerSetting?.value === 'true' || this.addExtensionReposBannerSetting?.value === '' || this.addExtensionReposBannerSetting?.value === undefined) {
|
|
619
621
|
this.addExtensionReposBannerSetting.value = 'false';
|
|
620
622
|
this.addExtensionReposBannerSetting.save();
|
|
621
623
|
}
|
package/pages/diagnostic.vue
CHANGED
|
@@ -215,6 +215,7 @@ export default {
|
|
|
215
215
|
'linode',
|
|
216
216
|
'targetRoute', // contains circular references, isn't useful (added later to store)
|
|
217
217
|
'$router', // also contains a circular reference to $store, not useful for diagnostics
|
|
218
|
+
'$route', // also contains a circular reference to $store, not useful for diagnostics
|
|
218
219
|
];
|
|
219
220
|
|
|
220
221
|
const clearListsKeys = [
|
package/pages/prefs.vue
CHANGED
|
@@ -40,6 +40,11 @@ export default {
|
|
|
40
40
|
scalingDownPrompt: mapPref(SCALE_POOL_PROMPT),
|
|
41
41
|
|
|
42
42
|
...mapGetters(['isSingleProduct']),
|
|
43
|
+
...mapGetters({ hasMultipleLocales: 'i18n/hasMultipleLocales' }),
|
|
44
|
+
|
|
45
|
+
isHarvester() {
|
|
46
|
+
return this.isSingleProduct?.productName === 'harvester';
|
|
47
|
+
},
|
|
43
48
|
|
|
44
49
|
theme: {
|
|
45
50
|
get() {
|
|
@@ -182,7 +187,10 @@ export default {
|
|
|
182
187
|
</h1>
|
|
183
188
|
|
|
184
189
|
<!-- Language -->
|
|
185
|
-
<div
|
|
190
|
+
<div
|
|
191
|
+
v-if="hasMultipleLocales && !isHarvester"
|
|
192
|
+
class="mt-10 mb-10"
|
|
193
|
+
>
|
|
186
194
|
<h4 v-t="'prefs.language'" />
|
|
187
195
|
<div class="row">
|
|
188
196
|
<div class="col span-4">
|
|
@@ -194,7 +202,6 @@ export default {
|
|
|
194
202
|
</div>
|
|
195
203
|
<!-- Theme -->
|
|
196
204
|
<div class="mt-10 mb-10">
|
|
197
|
-
<hr>
|
|
198
205
|
<h4 v-t="'prefs.theme.label'" />
|
|
199
206
|
<ButtonGroup
|
|
200
207
|
v-model:value="theme"
|
|
@@ -262,7 +269,10 @@ export default {
|
|
|
262
269
|
</div>
|
|
263
270
|
</div>
|
|
264
271
|
<!-- Confirmation setting -->
|
|
265
|
-
<div
|
|
272
|
+
<div
|
|
273
|
+
v-if="!isSingleProduct"
|
|
274
|
+
class="col adv-features mt-10 mb-10"
|
|
275
|
+
>
|
|
266
276
|
<hr>
|
|
267
277
|
<h4 v-t="'prefs.confirmationSetting.title'" />
|
|
268
278
|
<Checkbox
|
|
@@ -282,13 +292,15 @@ export default {
|
|
|
282
292
|
:label="t('prefs.advFeatures.viewInApi', {}, true)"
|
|
283
293
|
class="mt-10"
|
|
284
294
|
/>
|
|
285
|
-
<
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
295
|
+
<template v-if="!isHarvester">
|
|
296
|
+
<br>
|
|
297
|
+
<Checkbox
|
|
298
|
+
v-model:value="allNamespaces"
|
|
299
|
+
data-testid="prefs__allNamespaces"
|
|
300
|
+
:label="t('prefs.advFeatures.allNamespaces', {}, true)"
|
|
301
|
+
class="mt-20"
|
|
302
|
+
/>
|
|
303
|
+
</template>
|
|
292
304
|
<br>
|
|
293
305
|
<Checkbox
|
|
294
306
|
v-model:value="themeShortcut"
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
AS,
|
|
10
10
|
MODE
|
|
11
11
|
} from '@shell/config/query-params';
|
|
12
|
-
import { VIEW_IN_API } from '@shell/store/prefs';
|
|
12
|
+
import { VIEW_IN_API, DEV } from '@shell/store/prefs';
|
|
13
13
|
import { addObject, addObjects, findBy, removeAt } from '@shell/utils/array';
|
|
14
14
|
import CustomValidators from '@shell/utils/custom-validators';
|
|
15
15
|
import { downloadFile, generateZip } from '@shell/utils/download';
|
|
@@ -84,6 +84,7 @@ export const STATES_ENUM = {
|
|
|
84
84
|
DISCONNECTED: 'disconnected',
|
|
85
85
|
DRAINED: 'drained',
|
|
86
86
|
DRAINING: 'draining',
|
|
87
|
+
ENABLED: 'enabled',
|
|
87
88
|
ERR_APPLIED: 'errapplied',
|
|
88
89
|
ERROR: 'error',
|
|
89
90
|
ERRORING: 'erroring',
|
|
@@ -232,6 +233,9 @@ export const STATES = {
|
|
|
232
233
|
[STATES_ENUM.DRAINING]: {
|
|
233
234
|
color: 'warning', icon: 'tag', label: 'Draining', compoundIcon: 'warning'
|
|
234
235
|
},
|
|
236
|
+
[STATES_ENUM.ENABLED]: {
|
|
237
|
+
color: 'success', icon: 'dot-open', label: 'Enabled', compoundIcon: 'checkmark'
|
|
238
|
+
},
|
|
235
239
|
[STATES_ENUM.ERR_APPLIED]: {
|
|
236
240
|
color: 'error', icon: 'error', label: 'Error Applied', compoundIcon: 'error'
|
|
237
241
|
},
|
|
@@ -997,7 +1001,11 @@ export default class Resource {
|
|
|
997
1001
|
}
|
|
998
1002
|
|
|
999
1003
|
get canViewInApi() {
|
|
1000
|
-
|
|
1004
|
+
try {
|
|
1005
|
+
return this.hasLink('self') && this.$rootGetters['prefs/get'](VIEW_IN_API);
|
|
1006
|
+
} catch {
|
|
1007
|
+
return this.hasLink('self') && this.$rootGetters['prefs/get'](DEV);
|
|
1008
|
+
}
|
|
1001
1009
|
}
|
|
1002
1010
|
|
|
1003
1011
|
get canYaml() {
|
|
@@ -1055,7 +1063,7 @@ export default class Resource {
|
|
|
1055
1063
|
|
|
1056
1064
|
async doActionGrowl(actionName, body, opt = {}) {
|
|
1057
1065
|
try {
|
|
1058
|
-
await this.$dispatch('resourceAction', {
|
|
1066
|
+
return await this.$dispatch('resourceAction', {
|
|
1059
1067
|
resource: this,
|
|
1060
1068
|
actionName,
|
|
1061
1069
|
body,
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { perfLoadAll } from '@shell/plugins/steve/performanceTesting';
|
|
14
14
|
import { classify } from '@shell/plugins/dashboard-store/classify';
|
|
15
15
|
import SteveSchema from '@shell/models/steve-schema';
|
|
16
|
+
import { deepToRaw } from '@shell/utils/object';
|
|
16
17
|
|
|
17
18
|
function registerNamespace(state, namespace) {
|
|
18
19
|
let cache = state.podsByNamespace[namespace];
|
|
@@ -145,7 +146,9 @@ export default {
|
|
|
145
146
|
|
|
146
147
|
if (worker) {
|
|
147
148
|
// Store raw json objects, not the proxies
|
|
148
|
-
|
|
149
|
+
const rawData = deepToRaw(data);
|
|
150
|
+
|
|
151
|
+
worker.postMessage({ loadSchemas: rawData });
|
|
149
152
|
}
|
|
150
153
|
}
|
|
151
154
|
},
|
|
@@ -6,7 +6,7 @@ import { uniq } from '@shell/utils/array';
|
|
|
6
6
|
import {
|
|
7
7
|
CONFIG_MAP, MANAGEMENT, NAMESPACE, NODE, POD
|
|
8
8
|
} from '@shell/config/types';
|
|
9
|
-
import { Schema } from 'plugins/steve/schema';
|
|
9
|
+
import { Schema } from '@shell/plugins/steve/schema';
|
|
10
10
|
|
|
11
11
|
class NamespaceProjectFilters {
|
|
12
12
|
/**
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { addObject, clear, removeObject } from '@shell/utils/array';
|
|
11
|
-
import { get } from '@shell/utils/object';
|
|
11
|
+
import { get, deepToRaw } from '@shell/utils/object';
|
|
12
12
|
import { SCHEMA, MANAGEMENT } from '@shell/config/types';
|
|
13
13
|
import { SETTING } from '@shell/config/settings';
|
|
14
14
|
import { CSRF } from '@shell/config/cookies';
|
|
@@ -35,7 +35,6 @@ import { WORKER_MODES } from './worker';
|
|
|
35
35
|
import acceptOrRejectSocketMessage from './accept-or-reject-socket-message';
|
|
36
36
|
import { BLANK_CLUSTER, STORE } from '@shell/store/store-types.js';
|
|
37
37
|
import paginationUtils from '@shell/utils/pagination-utils';
|
|
38
|
-
import _ from 'lodash';
|
|
39
38
|
|
|
40
39
|
// minimum length of time a disconnect notification is shown
|
|
41
40
|
const MINIMUM_TIME_NOTIFIED = 3000;
|
|
@@ -179,9 +178,9 @@ export async function createWorker(store, ctx) {
|
|
|
179
178
|
|
|
180
179
|
while (workerQueues[storeName]?.length) {
|
|
181
180
|
const message = workerQueues[storeName].shift();
|
|
181
|
+
const safeMessage = deepToRaw(message);
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
store.$workers[storeName].postMessage(_.cloneDeep(message));
|
|
183
|
+
store.$workers[storeName].postMessage(safeMessage);
|
|
185
184
|
}
|
|
186
185
|
}
|
|
187
186
|
|
|
@@ -177,11 +177,16 @@ export default defineComponent({
|
|
|
177
177
|
if (this.type !== 'cron' || !this.value) {
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
|
-
|
|
180
|
+
// refer https://github.com/GuillaumeRochat/cron-validator#readme
|
|
181
|
+
if (!isValidCron(this.value as string, {
|
|
182
|
+
alias: true,
|
|
183
|
+
allowBlankDay: true,
|
|
184
|
+
allowSevenAsSunday: true,
|
|
185
|
+
})) {
|
|
181
186
|
return this.t('generic.invalidCron');
|
|
182
187
|
}
|
|
183
188
|
try {
|
|
184
|
-
const hint = cronstrue.toString(this.value || '');
|
|
189
|
+
const hint = cronstrue.toString(this.value as string || '', { verbose: true });
|
|
185
190
|
|
|
186
191
|
return hint;
|
|
187
192
|
} catch (e) {
|
package/store/features.js
CHANGED
|
@@ -35,6 +35,7 @@ export const HARVESTER_CONTAINER = create('harvester-baremetal-container-workloa
|
|
|
35
35
|
export const FLEET_WORKSPACE_BACK = create('provisioningv2-fleet-workspace-back-population', false);
|
|
36
36
|
export const STEVE_CACHE = create('ui-sql-cache', false);
|
|
37
37
|
export const UIEXTENSION = create('uiextension', true);
|
|
38
|
+
export const PROVISIONING_PRE_BOOTSTRAP = create('provisioningprebootstrap', false);
|
|
38
39
|
|
|
39
40
|
// Not currently used.. no point defining ones we don't use
|
|
40
41
|
// export const EMBEDDED_CLUSTER_API = create('embedded-cluster-api', true);
|
package/store/i18n.js
CHANGED
|
@@ -58,6 +58,10 @@ export const getters = {
|
|
|
58
58
|
return out;
|
|
59
59
|
},
|
|
60
60
|
|
|
61
|
+
hasMultipleLocales(state) {
|
|
62
|
+
return state.available.length > 1;
|
|
63
|
+
},
|
|
64
|
+
|
|
61
65
|
t: (state) => (key, args, language) => {
|
|
62
66
|
if (state.selected === NONE && !language) {
|
|
63
67
|
return `%${ key }%`;
|
|
@@ -333,7 +337,7 @@ export const actions = {
|
|
|
333
337
|
|
|
334
338
|
commit('setSelected', locale);
|
|
335
339
|
|
|
336
|
-
//
|
|
340
|
+
// Only update the preference if the locale changed
|
|
337
341
|
if (currentLocale !== locale) {
|
|
338
342
|
dispatch('prefs/set', {
|
|
339
343
|
key: 'locale',
|