@rancher/shell 2.0.2 → 2.0.3
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 +9 -1
- package/components/ResourceDetail/index.vue +2 -1
- package/components/SideNav.vue +1 -1
- package/components/TableDataUserIcon.vue +1 -1
- package/components/fleet/FleetRepos.vue +0 -7
- package/components/formatter/ClusterProvider.vue +3 -3
- package/components/nav/TopLevelMenu.vue +12 -12
- package/config/labels-annotations.js +1 -0
- package/core/types-provisioning.ts +5 -0
- package/core/types.ts +26 -1
- package/detail/fleet.cattle.io.bundle.vue +5 -68
- package/detail/fleet.cattle.io.gitrepo.vue +2 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +109 -24
- package/edit/provisioning.cattle.io.cluster/index.vue +10 -4
- package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -3
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +177 -26
- package/models/__tests__/management.cattle.io.cluster.test.ts +3 -3
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -86
- package/models/fleet.cattle.io.bundle.js +3 -1
- package/models/fleet.cattle.io.gitrepo.js +46 -48
- package/models/management.cattle.io.cluster.js +2 -5
- package/models/provisioning.cattle.io.cluster.js +25 -12
- package/package.json +1 -1
- package/pages/c/_cluster/fleet/index.vue +1 -0
- package/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +0 -2
- package/scripts/extension/parse-tag-name +21 -12
- package/scripts/publish-shell.sh +7 -0
- package/scripts/typegen.sh +3 -1
- package/store/features.js +1 -0
- package/types/resources/fleet.d.ts +40 -0
- package/types/shell/index.d.ts +97 -0
- package/utils/auth.js +1 -1
- package/utils/fleet.ts +159 -0
- package/utils/v-sphere.ts +31 -0
- package/vue.config.js +3 -3
|
@@ -1467,6 +1467,14 @@ cluster:
|
|
|
1467
1467
|
placeholder: A unique name for the cluster
|
|
1468
1468
|
directoryConfig:
|
|
1469
1469
|
title: Data directory configuration
|
|
1470
|
+
banner: Data directory configuration can not be changed once the cluster has been created
|
|
1471
|
+
radioInput:
|
|
1472
|
+
defaultLabel: Use default data directory configuration
|
|
1473
|
+
commonLabel: Use a common base directory for data directory configuration (sub-directories will be used for the system-agent, provisioning and distro paths)
|
|
1474
|
+
customLabel: Use custom data directories
|
|
1475
|
+
common:
|
|
1476
|
+
label: Data directory base path
|
|
1477
|
+
tooltip: Data directory base path. We will append the sub-directories appropriate for each directory (/agent, /provisioning and either /rke2 or /k3s)
|
|
1470
1478
|
systemAgent:
|
|
1471
1479
|
label: System-agent directory path
|
|
1472
1480
|
tooltip: Data directory for the system-agent connection info and plans
|
|
@@ -1954,7 +1962,7 @@ cluster:
|
|
|
1954
1962
|
pinganyunecs: Pinganyun ECS
|
|
1955
1963
|
pnap: phoenixNAP
|
|
1956
1964
|
rackspace: RackSpace
|
|
1957
|
-
rancherkubernetesengine:
|
|
1965
|
+
rancherkubernetesengine: RKE1
|
|
1958
1966
|
rke2: RKE2
|
|
1959
1967
|
rke: RKE1
|
|
1960
1968
|
rkeWindows: Windows (RKE1 only)
|
package/components/SideNav.vue
CHANGED
|
@@ -480,7 +480,7 @@ export default {
|
|
|
480
480
|
<template v-else>
|
|
481
481
|
<span
|
|
482
482
|
v-if="isVirtualCluster && isExplorer"
|
|
483
|
-
v-tooltip="{content: harvesterVersion, placement: 'top'}"
|
|
483
|
+
v-clean-tooltip="{content: harvesterVersion, placement: 'top'}"
|
|
484
484
|
class="clip text-muted ml-5"
|
|
485
485
|
>
|
|
486
486
|
(Harvester-{{ harvesterVersion }})
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
FLEET_REPO_PER_CLUSTER_STATE
|
|
17
17
|
|
|
18
18
|
} from '@shell/config/table-headers';
|
|
19
|
-
import { FLEET } from '@shell/config/labels-annotations';
|
|
20
19
|
import { STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';
|
|
21
20
|
|
|
22
21
|
// i18n-ignore repoDisplay
|
|
@@ -118,12 +117,6 @@ export default {
|
|
|
118
117
|
parseTargetMode(row) {
|
|
119
118
|
return row.targetInfo?.mode === 'clusterGroup' ? this.t('fleet.gitRepo.warningTooltip.clusterGroup') : this.t('fleet.gitRepo.warningTooltip.cluster');
|
|
120
119
|
},
|
|
121
|
-
|
|
122
|
-
clusterViewResourceStatus(row) {
|
|
123
|
-
return row.clusterResourceStatus.find((c) => {
|
|
124
|
-
return c.metadata?.labels[FLEET.CLUSTER_NAME] === this.clusterId;
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
120
|
},
|
|
128
121
|
};
|
|
129
122
|
</script>
|
|
@@ -25,12 +25,12 @@ export default {
|
|
|
25
25
|
{{ row.machineProviderDisplay }}
|
|
26
26
|
</span>
|
|
27
27
|
</template>
|
|
28
|
-
<template v-else-if="row.isCustom">
|
|
29
|
-
{{ t('cluster.provider.custom') }}
|
|
30
|
-
</template>
|
|
31
28
|
<template v-else-if="row.isImported">
|
|
32
29
|
{{ t('cluster.provider.imported') }}
|
|
33
30
|
</template>
|
|
31
|
+
<template v-else-if="row.isCustom">
|
|
32
|
+
{{ t('cluster.provider.custom') }}
|
|
33
|
+
</template>
|
|
34
34
|
<div class="text-muted">
|
|
35
35
|
{{ row.provisionerDisplay }}
|
|
36
36
|
</div>
|
|
@@ -558,7 +558,7 @@ export default {
|
|
|
558
558
|
:to="{ name: 'home' }"
|
|
559
559
|
>
|
|
560
560
|
<svg
|
|
561
|
-
v-tooltip="getTooltipConfig(t('nav.home'))"
|
|
561
|
+
v-clean-tooltip="getTooltipConfig(t('nav.home'))"
|
|
562
562
|
xmlns="http://www.w3.org/2000/svg"
|
|
563
563
|
height="24"
|
|
564
564
|
viewBox="0 0 24 24"
|
|
@@ -672,13 +672,13 @@ export default {
|
|
|
672
672
|
@shortkey="handleKeyComboClick"
|
|
673
673
|
>
|
|
674
674
|
<ClusterIconMenu
|
|
675
|
-
v-tooltip="getTooltipConfig(c, true)"
|
|
675
|
+
v-clean-tooltip="getTooltipConfig(c, true)"
|
|
676
676
|
:cluster="c"
|
|
677
677
|
:route-combo="routeCombo"
|
|
678
678
|
class="rancher-provider-icon"
|
|
679
679
|
/>
|
|
680
680
|
<div
|
|
681
|
-
v-tooltip="getTooltipConfig(c)"
|
|
681
|
+
v-clean-tooltip="getTooltipConfig(c)"
|
|
682
682
|
class="cluster-name"
|
|
683
683
|
>
|
|
684
684
|
<p>{{ c.label }}</p>
|
|
@@ -699,12 +699,12 @@ export default {
|
|
|
699
699
|
:data-testid="`pinned-menu-cluster-disabled-${ c.id }`"
|
|
700
700
|
>
|
|
701
701
|
<ClusterIconMenu
|
|
702
|
-
v-tooltip="getTooltipConfig(c, true)"
|
|
702
|
+
v-clean-tooltip="getTooltipConfig(c, true)"
|
|
703
703
|
:cluster="c"
|
|
704
704
|
class="rancher-provider-icon"
|
|
705
705
|
/>
|
|
706
706
|
<div
|
|
707
|
-
v-tooltip="getTooltipConfig(c)"
|
|
707
|
+
v-clean-tooltip="getTooltipConfig(c)"
|
|
708
708
|
class="cluster-name"
|
|
709
709
|
>
|
|
710
710
|
<p>{{ c.label }}</p>
|
|
@@ -747,13 +747,13 @@ export default {
|
|
|
747
747
|
@shortkey="handleKeyComboClick"
|
|
748
748
|
>
|
|
749
749
|
<ClusterIconMenu
|
|
750
|
-
v-tooltip="getTooltipConfig(c, true)"
|
|
750
|
+
v-clean-tooltip="getTooltipConfig(c, true)"
|
|
751
751
|
:cluster="c"
|
|
752
752
|
:route-combo="routeCombo"
|
|
753
753
|
class="rancher-provider-icon"
|
|
754
754
|
/>
|
|
755
755
|
<div
|
|
756
|
-
v-tooltip="getTooltipConfig(c)"
|
|
756
|
+
v-clean-tooltip="getTooltipConfig(c)"
|
|
757
757
|
class="cluster-name"
|
|
758
758
|
>
|
|
759
759
|
<p>{{ c.label }}</p>
|
|
@@ -775,12 +775,12 @@ export default {
|
|
|
775
775
|
:data-testid="`menu-cluster-disabled-${ c.id }`"
|
|
776
776
|
>
|
|
777
777
|
<ClusterIconMenu
|
|
778
|
-
v-tooltip="getTooltipConfig(c, true)"
|
|
778
|
+
v-clean-tooltip="getTooltipConfig(c, true)"
|
|
779
779
|
:cluster="c"
|
|
780
780
|
class="rancher-provider-icon"
|
|
781
781
|
/>
|
|
782
782
|
<div
|
|
783
|
-
v-tooltip="getTooltipConfig(c)"
|
|
783
|
+
v-clean-tooltip="getTooltipConfig(c)"
|
|
784
784
|
class="cluster-name"
|
|
785
785
|
>
|
|
786
786
|
<p>{{ c.label }}</p>
|
|
@@ -847,7 +847,7 @@ export default {
|
|
|
847
847
|
:to="a.to"
|
|
848
848
|
>
|
|
849
849
|
<IconOrSvg
|
|
850
|
-
v-tooltip="getTooltipConfig(a.label)"
|
|
850
|
+
v-clean-tooltip="getTooltipConfig(a.label)"
|
|
851
851
|
:icon="a.icon"
|
|
852
852
|
:src="a.svg"
|
|
853
853
|
/>
|
|
@@ -875,7 +875,7 @@ export default {
|
|
|
875
875
|
:to="a.to"
|
|
876
876
|
>
|
|
877
877
|
<IconOrSvg
|
|
878
|
-
v-tooltip="getTooltipConfig(a.label)"
|
|
878
|
+
v-clean-tooltip="getTooltipConfig(a.label)"
|
|
879
879
|
:icon="a.icon"
|
|
880
880
|
:src="a.svg"
|
|
881
881
|
/>
|
|
@@ -905,7 +905,7 @@ export default {
|
|
|
905
905
|
:to="a.to"
|
|
906
906
|
>
|
|
907
907
|
<IconOrSvg
|
|
908
|
-
v-tooltip="getTooltipConfig(a.label)"
|
|
908
|
+
v-clean-tooltip="getTooltipConfig(a.label)"
|
|
909
909
|
:icon="a.icon"
|
|
910
910
|
:src="a.svg"
|
|
911
911
|
/>
|
|
@@ -111,6 +111,7 @@ export const FLEET = {
|
|
|
111
111
|
CLUSTER_NAME: 'management.cattle.io/cluster-name',
|
|
112
112
|
BUNDLE_ID: 'fleet.cattle.io/bundle-id',
|
|
113
113
|
MANAGED: 'fleet.cattle.io/managed',
|
|
114
|
+
CLUSTER_NAMESPACE: 'fleet.cattle.io/cluster-namespace',
|
|
114
115
|
CLUSTER: 'fleet.cattle.io/cluster'
|
|
115
116
|
};
|
|
116
117
|
|
|
@@ -106,6 +106,11 @@ export interface IClusterProvisioner {
|
|
|
106
106
|
*/
|
|
107
107
|
disabled?: boolean;
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Hide the cluster provider card
|
|
111
|
+
*/
|
|
112
|
+
hidden?: boolean;
|
|
113
|
+
|
|
109
114
|
/**
|
|
110
115
|
* Custom Dashboard route to navigate to when the cluster provider card is clicked
|
|
111
116
|
*/
|
package/core/types.ts
CHANGED
|
@@ -237,6 +237,16 @@ export interface ProductOptions {
|
|
|
237
237
|
*/
|
|
238
238
|
to?: Location;
|
|
239
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Alternative to the icon property. Uses require
|
|
242
|
+
*/
|
|
243
|
+
svg?: Function;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Product name
|
|
247
|
+
*/
|
|
248
|
+
name?: string;
|
|
249
|
+
|
|
240
250
|
/**
|
|
241
251
|
* Leaving these here for completeness but I don't think these should be advertised as useable to plugin creators.
|
|
242
252
|
*/
|
|
@@ -373,10 +383,25 @@ export interface ConfigureTypeOptions {
|
|
|
373
383
|
}
|
|
374
384
|
|
|
375
385
|
export interface ConfigureVirtualTypeOptions extends ConfigureTypeOptions {
|
|
386
|
+
/**
|
|
387
|
+
* Only load the product if the type is present
|
|
388
|
+
*/
|
|
389
|
+
ifHave?: string;
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Only load the product if the type is present
|
|
393
|
+
*/
|
|
394
|
+
ifHaveType?: string | RegExp | Object;
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* The label that this type should display
|
|
398
|
+
*/
|
|
399
|
+
label?: string;
|
|
400
|
+
|
|
376
401
|
/**
|
|
377
402
|
* The translation key displayed anywhere this type is referenced
|
|
378
403
|
*/
|
|
379
|
-
labelKey
|
|
404
|
+
labelKey?: string;
|
|
380
405
|
|
|
381
406
|
/**
|
|
382
407
|
* An identifier that should be unique across all types
|
|
@@ -1,77 +1,25 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { FLEET } from '@shell/config/types';
|
|
3
2
|
import FleetBundleResources from '@shell/components/fleet/FleetBundleResources.vue';
|
|
4
|
-
import
|
|
3
|
+
import FleetUtils from '@shell/utils/fleet';
|
|
5
4
|
|
|
6
5
|
export default {
|
|
7
6
|
name: 'FleetBundleDetail',
|
|
8
7
|
|
|
9
|
-
components: {
|
|
10
|
-
|
|
11
|
-
SortableTable,
|
|
12
|
-
},
|
|
13
|
-
props: {
|
|
8
|
+
components: { FleetBundleResources },
|
|
9
|
+
props: {
|
|
14
10
|
value: {
|
|
15
11
|
type: Object,
|
|
16
12
|
required: true,
|
|
17
13
|
}
|
|
18
14
|
},
|
|
19
15
|
|
|
20
|
-
data() {
|
|
21
|
-
return { repo: null };
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
async fetch() {
|
|
25
|
-
const { namespace, labels } = this.value.metadata;
|
|
26
|
-
const repoName = `${ namespace }/${ labels['fleet.cattle.io/repo-name'] }`;
|
|
27
|
-
|
|
28
|
-
if (this.hasRepoLabel) {
|
|
29
|
-
this.repo = await this.$store.dispatch('management/find', { type: FLEET.GIT_REPO, id: repoName });
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
|
|
33
16
|
computed: {
|
|
34
|
-
hasRepoLabel() {
|
|
35
|
-
return !!(this.value?.metadata?.labels && this.value?.metadata?.labels['fleet.cattle.io/repo-name']);
|
|
36
|
-
},
|
|
37
17
|
bundleResources() {
|
|
38
|
-
|
|
39
|
-
const bundleResourceIds = this.bundleResourceIds;
|
|
40
|
-
|
|
41
|
-
return this.repo?.status?.resources?.filter((resource) => {
|
|
42
|
-
return bundleResourceIds.includes(resource.name);
|
|
43
|
-
});
|
|
44
|
-
} else if (this.value?.spec?.resources?.length) {
|
|
45
|
-
return this.value?.spec?.resources.map((item) => {
|
|
46
|
-
return {
|
|
47
|
-
content: item.content,
|
|
48
|
-
name: item.name.includes('.') ? item.name.split('.')[0] : item.name
|
|
49
|
-
};
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return [];
|
|
54
|
-
},
|
|
55
|
-
resourceHeaders() {
|
|
56
|
-
return [
|
|
57
|
-
{
|
|
58
|
-
name: 'name',
|
|
59
|
-
value: 'name',
|
|
60
|
-
sort: ['name'],
|
|
61
|
-
labelKey: 'tableHeaders.name',
|
|
62
|
-
},
|
|
63
|
-
];
|
|
18
|
+
return FleetUtils.resourcesFromBundleStatus(this.value?.status);
|
|
64
19
|
},
|
|
65
20
|
resourceCount() {
|
|
66
|
-
return
|
|
21
|
+
return this.bundleResources.length;
|
|
67
22
|
},
|
|
68
|
-
bundleResourceIds() {
|
|
69
|
-
if (this.value.status?.resourceKey) {
|
|
70
|
-
return this.value?.status?.resourceKey.map((item) => item.name);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return [];
|
|
74
|
-
}
|
|
75
23
|
}
|
|
76
24
|
};
|
|
77
25
|
|
|
@@ -84,19 +32,8 @@ export default {
|
|
|
84
32
|
<span>{{ resourceCount }}</span>
|
|
85
33
|
</div>
|
|
86
34
|
<FleetBundleResources
|
|
87
|
-
v-if="hasRepoLabel"
|
|
88
35
|
:value="bundleResources"
|
|
89
36
|
/>
|
|
90
|
-
<SortableTable
|
|
91
|
-
v-else
|
|
92
|
-
:rows="bundleResources"
|
|
93
|
-
:headers="resourceHeaders"
|
|
94
|
-
:table-actions="false"
|
|
95
|
-
:row-actions="false"
|
|
96
|
-
key-field="tableKey"
|
|
97
|
-
default-sort-by="state"
|
|
98
|
-
:paged="true"
|
|
99
|
-
/>
|
|
100
37
|
</div>
|
|
101
38
|
</template>
|
|
102
39
|
|
|
@@ -80,7 +80,8 @@ export default {
|
|
|
80
80
|
const allDispatches = await checkSchemasForFindAllHash({
|
|
81
81
|
allBundles: {
|
|
82
82
|
inStoreType: 'management',
|
|
83
|
-
type: FLEET.BUNDLE
|
|
83
|
+
type: FLEET.BUNDLE,
|
|
84
|
+
opt: { excludeFields: ['metadata.managedFields', 'spec.resources'] },
|
|
84
85
|
},
|
|
85
86
|
|
|
86
87
|
allBundleDeployments: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { nextTick } from 'vue';
|
|
1
2
|
/* eslint-disable jest/no-hooks */
|
|
2
3
|
import { mount, Wrapper } from '@vue/test-utils';
|
|
3
|
-
import DirectoryConfig from '@shell/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue';
|
|
4
|
+
import DirectoryConfig, { DATA_DIR_RADIO_OPTIONS, DEFAULT_SUBDIRS } from '@shell/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue';
|
|
4
5
|
import { _EDIT, _CREATE } from '@shell/config/query-params';
|
|
5
6
|
import { clone } from '@shell/utils/object';
|
|
6
7
|
|
|
@@ -14,7 +15,8 @@ describe('component: DirectoryConfig', () => {
|
|
|
14
15
|
provisioning: '',
|
|
15
16
|
k8sDistro: '',
|
|
16
17
|
},
|
|
17
|
-
|
|
18
|
+
k8sVersion: 'k3s',
|
|
19
|
+
mode: _CREATE,
|
|
18
20
|
},
|
|
19
21
|
mocks: {
|
|
20
22
|
$store: {
|
|
@@ -33,48 +35,88 @@ describe('component: DirectoryConfig', () => {
|
|
|
33
35
|
);
|
|
34
36
|
|
|
35
37
|
const title = wrapper.find('h3');
|
|
38
|
+
const radioInput = wrapper.find('[data-testid="rke2-directory-config-radio-input"]');
|
|
39
|
+
const commonInput = wrapper.find('[data-testid="rke2-directory-config-common-data-dir"]');
|
|
36
40
|
const systemAgentInput = wrapper.find('[data-testid="rke2-directory-config-systemAgent-data-dir"]');
|
|
37
41
|
const provisioningInput = wrapper.find('[data-testid="rke2-directory-config-provisioning-data-dir"]');
|
|
38
42
|
const k8sDistroInput = wrapper.find('[data-testid="rke2-directory-config-k8sDistro-data-dir"]');
|
|
39
43
|
|
|
40
44
|
expect(title.exists()).toBe(true);
|
|
45
|
+
expect(radioInput.exists()).toBe(true);
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
expect(
|
|
44
|
-
|
|
47
|
+
// for the default config, the default radio input should be "default"
|
|
48
|
+
expect(wrapper.vm.dataConfigRadioValue).toBe(DATA_DIR_RADIO_OPTIONS.DEFAULT);
|
|
49
|
+
|
|
50
|
+
// since we have all of the vars empty, then the inputs should not be there
|
|
51
|
+
expect(commonInput.exists()).toBe(false);
|
|
52
|
+
expect(systemAgentInput.exists()).toBe(false);
|
|
53
|
+
expect(provisioningInput.exists()).toBe(false);
|
|
54
|
+
expect(k8sDistroInput.exists()).toBe(false);
|
|
45
55
|
});
|
|
46
56
|
|
|
47
|
-
it('updating
|
|
57
|
+
it('updating common base directory should set the correct values on each data dir variable', async() => {
|
|
58
|
+
const newMountOptions = clone(mountOptions);
|
|
59
|
+
|
|
48
60
|
wrapper = mount(
|
|
49
61
|
DirectoryConfig,
|
|
50
|
-
|
|
62
|
+
{
|
|
63
|
+
...newMountOptions,
|
|
64
|
+
// couldn't use setData, so this is the next best solution
|
|
65
|
+
data() {
|
|
66
|
+
return { dataConfigRadioValue: DATA_DIR_RADIO_OPTIONS.COMMON };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
51
69
|
);
|
|
52
70
|
|
|
53
71
|
const inputPath = 'some-data-dir';
|
|
72
|
+
const commonInput = wrapper.find('[data-testid="rke2-directory-config-common-data-dir"]');
|
|
73
|
+
|
|
74
|
+
// update base dir value
|
|
75
|
+
expect(commonInput.exists()).toBe(true);
|
|
76
|
+
commonInput.setValue(inputPath);
|
|
77
|
+
await nextTick();
|
|
78
|
+
|
|
79
|
+
expect(wrapper.vm.value.systemAgent).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.AGENT }`);
|
|
80
|
+
expect(wrapper.vm.value.provisioning).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.PROVISIONING }`);
|
|
81
|
+
expect(wrapper.vm.value.k8sDistro).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.K8S_DISTRO_K3S }`);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('updating each individual data dir should set the correct values on each data dir variable', async() => {
|
|
85
|
+
const newMountOptions = clone(mountOptions);
|
|
86
|
+
|
|
87
|
+
wrapper = mount(
|
|
88
|
+
DirectoryConfig,
|
|
89
|
+
{
|
|
90
|
+
...newMountOptions,
|
|
91
|
+
// couldn't use setData, so this is the next best solution
|
|
92
|
+
data() {
|
|
93
|
+
return { dataConfigRadioValue: DATA_DIR_RADIO_OPTIONS.CUSTOM };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
const inputPath = 'some-data-dir';
|
|
98
|
+
const agentValue = `${ inputPath }/${ DEFAULT_SUBDIRS.AGENT }`;
|
|
99
|
+
const provisioningValue = `${ inputPath }/${ DEFAULT_SUBDIRS.PROVISIONING }`;
|
|
100
|
+
const k8sDistroValue = `${ inputPath }/${ DEFAULT_SUBDIRS.K8S_DISTRO_RKE2 }`;
|
|
54
101
|
|
|
55
102
|
const systemAgentInput = wrapper.find('[data-testid="rke2-directory-config-systemAgent-data-dir"]');
|
|
56
103
|
const provisioningInput = wrapper.find('[data-testid="rke2-directory-config-provisioning-data-dir"]');
|
|
57
104
|
const k8sDistroInput = wrapper.find('[data-testid="rke2-directory-config-k8sDistro-data-dir"]');
|
|
58
105
|
|
|
59
|
-
systemAgentInput.setValue(
|
|
60
|
-
provisioningInput.setValue(
|
|
61
|
-
k8sDistroInput.setValue(
|
|
62
|
-
await
|
|
106
|
+
systemAgentInput.setValue(agentValue);
|
|
107
|
+
provisioningInput.setValue(provisioningValue);
|
|
108
|
+
k8sDistroInput.setValue(k8sDistroValue);
|
|
109
|
+
await nextTick();
|
|
63
110
|
|
|
64
|
-
expect(wrapper.vm.value.systemAgent).toStrictEqual(
|
|
65
|
-
expect(wrapper.vm.value.provisioning).toStrictEqual(
|
|
66
|
-
expect(wrapper.vm.value.k8sDistro).toStrictEqual(
|
|
111
|
+
expect(wrapper.vm.value.systemAgent).toStrictEqual(agentValue);
|
|
112
|
+
expect(wrapper.vm.value.provisioning).toStrictEqual(provisioningValue);
|
|
113
|
+
expect(wrapper.vm.value.k8sDistro).toStrictEqual(k8sDistroValue);
|
|
67
114
|
});
|
|
68
115
|
|
|
69
|
-
it('
|
|
116
|
+
it('should render the component with configuration being an empty object, without errors and radio be of value DATA_DIR_RADIO_OPTIONS.CUSTOM (edit scenario)', () => {
|
|
70
117
|
const newMountOptions = clone(mountOptions);
|
|
71
|
-
const inputPath1 = 'some-data-dir1';
|
|
72
|
-
const inputPath2 = 'some-data-dir2';
|
|
73
|
-
const inputPath3 = 'some-data-dir3';
|
|
74
118
|
|
|
75
|
-
newMountOptions.propsData.value
|
|
76
|
-
newMountOptions.propsData.value.provisioning = inputPath2;
|
|
77
|
-
newMountOptions.propsData.value.k8sDistro = inputPath3;
|
|
119
|
+
newMountOptions.propsData.value = {};
|
|
78
120
|
newMountOptions.propsData.mode = _EDIT;
|
|
79
121
|
|
|
80
122
|
wrapper = mount(
|
|
@@ -82,16 +124,59 @@ describe('component: DirectoryConfig', () => {
|
|
|
82
124
|
newMountOptions
|
|
83
125
|
);
|
|
84
126
|
|
|
127
|
+
const title = wrapper.find('h3');
|
|
128
|
+
const radioInput = wrapper.find('[data-testid="rke2-directory-config-radio-input"]');
|
|
85
129
|
const systemAgentInput = wrapper.find('[data-testid="rke2-directory-config-systemAgent-data-dir"]');
|
|
86
130
|
const provisioningInput = wrapper.find('[data-testid="rke2-directory-config-provisioning-data-dir"]');
|
|
87
131
|
const k8sDistroInput = wrapper.find('[data-testid="rke2-directory-config-k8sDistro-data-dir"]');
|
|
88
132
|
|
|
133
|
+
expect(title.exists()).toBe(true);
|
|
134
|
+
expect(radioInput.isVisible()).toBe(false);
|
|
135
|
+
|
|
136
|
+
expect(wrapper.vm.dataConfigRadioValue).toBe(DATA_DIR_RADIO_OPTIONS.CUSTOM);
|
|
137
|
+
|
|
138
|
+
// since we have all of the vars empty, then the inputs should not be there
|
|
89
139
|
expect(systemAgentInput.exists()).toBe(true);
|
|
90
140
|
expect(provisioningInput.exists()).toBe(true);
|
|
91
141
|
expect(k8sDistroInput.exists()).toBe(true);
|
|
92
142
|
|
|
93
|
-
expect(systemAgentInput.attributes(
|
|
94
|
-
expect(provisioningInput.attributes(
|
|
95
|
-
expect(k8sDistroInput.attributes(
|
|
143
|
+
expect(systemAgentInput.attributes().disabled).toBeDefined();
|
|
144
|
+
expect(provisioningInput.attributes().disabled).toBeDefined();
|
|
145
|
+
expect(k8sDistroInput.attributes().disabled).toBeDefined();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('radio input should be set to DATA_DIR_RADIO_OPTIONS.CUSTOM with all data dir values existing and different (edit scenario)', () => {
|
|
149
|
+
const newMountOptions = clone(mountOptions);
|
|
150
|
+
const inputPath = 'some-data-dir';
|
|
151
|
+
|
|
152
|
+
newMountOptions.propsData.value.systemAgent = `${ inputPath }/${ DEFAULT_SUBDIRS.AGENT }`;
|
|
153
|
+
newMountOptions.propsData.value.provisioning = `${ inputPath }/${ DEFAULT_SUBDIRS.PROVISIONING }`;
|
|
154
|
+
newMountOptions.propsData.value.k8sDistro = `${ inputPath }/${ DEFAULT_SUBDIRS.K8S_DISTRO_K3S }`;
|
|
155
|
+
newMountOptions.propsData.mode = _EDIT;
|
|
156
|
+
|
|
157
|
+
wrapper = mount(
|
|
158
|
+
DirectoryConfig,
|
|
159
|
+
newMountOptions
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
expect(wrapper.vm.dataConfigRadioValue).toBe(DATA_DIR_RADIO_OPTIONS.CUSTOM);
|
|
163
|
+
|
|
164
|
+
const radioInput = wrapper.find('[data-testid="rke2-directory-config-radio-input"]');
|
|
165
|
+
const systemAgentInput = wrapper.find('[data-testid="rke2-directory-config-systemAgent-data-dir"]');
|
|
166
|
+
const provisioningInput = wrapper.find('[data-testid="rke2-directory-config-provisioning-data-dir"]');
|
|
167
|
+
const k8sDistroInput = wrapper.find('[data-testid="rke2-directory-config-k8sDistro-data-dir"]');
|
|
168
|
+
|
|
169
|
+
expect(radioInput.isVisible()).toBe(false);
|
|
170
|
+
expect(systemAgentInput.isVisible()).toBe(true);
|
|
171
|
+
expect(provisioningInput.isVisible()).toBe(true);
|
|
172
|
+
expect(k8sDistroInput.isVisible()).toBe(true);
|
|
173
|
+
|
|
174
|
+
expect(systemAgentInput.attributes().disabled).toBeDefined();
|
|
175
|
+
expect(provisioningInput.attributes().disabled).toBeDefined();
|
|
176
|
+
expect(k8sDistroInput.attributes().disabled).toBeDefined();
|
|
177
|
+
|
|
178
|
+
expect(wrapper.vm.value.systemAgent).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.AGENT }`);
|
|
179
|
+
expect(wrapper.vm.value.provisioning).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.PROVISIONING }`);
|
|
180
|
+
expect(wrapper.vm.value.k8sDistro).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.K8S_DISTRO_K3S }`);
|
|
96
181
|
});
|
|
97
182
|
});
|
|
@@ -203,8 +203,9 @@ export default {
|
|
|
203
203
|
|
|
204
204
|
emberLink() {
|
|
205
205
|
if (this.value) {
|
|
206
|
+
// set subtype if editing EKS/GKE/AKS cluster -- this ensures that the component provided by extension is loaded instead of iframing old ember ui
|
|
206
207
|
if (this.value.provisioner) {
|
|
207
|
-
const matchingSubtype = this.subTypes.find((st) =>
|
|
208
|
+
const matchingSubtype = this.subTypes.find((st) => DRIVER_TO_IMPORT[st.id.toLowerCase()] === this.value.provisioner.toLowerCase());
|
|
208
209
|
|
|
209
210
|
if (matchingSubtype) {
|
|
210
211
|
this.selectType(matchingSubtype.id, false);
|
|
@@ -395,7 +396,8 @@ export default {
|
|
|
395
396
|
disabled: ext.disabled || false,
|
|
396
397
|
link: ext.link,
|
|
397
398
|
tag: ext.tag,
|
|
398
|
-
component: ext.component
|
|
399
|
+
component: ext.component,
|
|
400
|
+
hidden: ext.hidden,
|
|
399
401
|
};
|
|
400
402
|
|
|
401
403
|
out.push(subtype);
|
|
@@ -440,10 +442,14 @@ export default {
|
|
|
440
442
|
}
|
|
441
443
|
},
|
|
442
444
|
|
|
445
|
+
filteredSubTypes() {
|
|
446
|
+
return this.subTypes.filter((subtype) => !subtype.hidden);
|
|
447
|
+
},
|
|
448
|
+
|
|
443
449
|
groupedSubTypes() {
|
|
444
450
|
const out = {};
|
|
445
451
|
|
|
446
|
-
for ( const row of this.
|
|
452
|
+
for ( const row of this.filteredSubTypes ) {
|
|
447
453
|
const name = row.group;
|
|
448
454
|
let entry = out[name];
|
|
449
455
|
|
|
@@ -605,7 +611,7 @@ export default {
|
|
|
605
611
|
<div
|
|
606
612
|
v-for="(obj, i) in groupedSubTypes"
|
|
607
613
|
:key="obj.id"
|
|
608
|
-
class="
|
|
614
|
+
:class="{'mt-5': i === 0, 'mt-20': i !== 0 }"
|
|
609
615
|
style="width: 100%;"
|
|
610
616
|
>
|
|
611
617
|
<h4>
|
|
@@ -64,14 +64,12 @@ import AddOnConfig from '@shell/edit/provisioning.cattle.io.cluster/tabs/AddOnCo
|
|
|
64
64
|
import Advanced from '@shell/edit/provisioning.cattle.io.cluster/tabs/Advanced';
|
|
65
65
|
import ClusterAppearance from '@shell/components/form/ClusterAppearance';
|
|
66
66
|
import AddOnAdditionalManifest from '@shell/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest';
|
|
67
|
-
import VsphereUtils from '@shell/utils/v-sphere';
|
|
67
|
+
import VsphereUtils, { VMWARE_VSPHERE } from '@shell/utils/v-sphere';
|
|
68
68
|
|
|
69
69
|
const HARVESTER = 'harvester';
|
|
70
70
|
const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
|
|
71
71
|
const NETBIOS_TRUNCATION_LENGTH = 15;
|
|
72
72
|
|
|
73
|
-
const VMWARE_VSPHERE = 'vmwarevsphere';
|
|
74
|
-
|
|
75
73
|
/**
|
|
76
74
|
* Classes to be adopted by the node badges in Machine pools
|
|
77
75
|
*/
|