@rancher/shell 2.0.2-rc.1 → 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 +53 -31
- package/components/PromptRemove.vue +8 -3
- package/components/ResourceDetail/Masthead.vue +1 -0
- package/components/ResourceDetail/index.vue +2 -1
- package/components/SideNav.vue +1 -1
- package/components/TableDataUserIcon.vue +1 -1
- package/components/fleet/FleetClusters.vue +0 -3
- package/components/fleet/FleetRepos.vue +0 -7
- package/components/formatter/CloudCredExpired.vue +69 -0
- package/components/formatter/ClusterProvider.vue +3 -3
- package/components/formatter/Date.vue +1 -1
- package/components/nav/Header.vue +9 -5
- package/components/nav/TopLevelMenu.vue +127 -63
- package/components/nav/__tests__/TopLevelMenu.test.ts +53 -27
- package/config/labels-annotations.js +3 -0
- package/core/types-provisioning.ts +5 -0
- package/core/types.ts +26 -1
- 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/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 +13 -2
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +177 -26
- package/list/provisioning.cattle.io.cluster.vue +56 -5
- package/mixins/chart.js +6 -2
- package/models/__tests__/management.cattle.io.cluster.test.ts +3 -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 +159 -2
- package/models/fleet.cattle.io.bundle.js +3 -1
- package/models/fleet.cattle.io.gitrepo.js +50 -61
- package/models/management.cattle.io.cluster.js +15 -7
- package/models/provisioning.cattle.io.cluster.js +62 -15
- package/package.json +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +2 -1
- 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 +12 -5
- package/pages/c/_cluster/manager/cloudCredential/index.vue +68 -4
- package/pages/c/_cluster/uiplugins/index.vue +4 -2
- package/pages/home.vue +1 -0
- package/scripts/extension/bundle +1 -1
- 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 +10 -4
- package/scripts/typegen.sh +27 -22
- package/store/features.js +1 -0
- package/types/resources/fleet.d.ts +40 -0
- package/types/shell/index.d.ts +4692 -0
- package/utils/auth.js +1 -1
- package/utils/cluster.js +1 -1
- package/utils/fleet.ts +159 -0
- package/utils/string.js +9 -0
- package/utils/v-sphere.ts +282 -0
- package/vue.config.js +3 -3
- package/shell/types/shell/index.d.ts +0 -2
|
@@ -9,7 +9,8 @@ import RelatedResources from '@shell/components/RelatedResources';
|
|
|
9
9
|
import jsyaml from 'js-yaml';
|
|
10
10
|
import merge from 'lodash/merge';
|
|
11
11
|
import { CATALOG } from '@shell/config/types';
|
|
12
|
-
import { sortBy } from '
|
|
12
|
+
import { sortBy } from '@shell/utils/sort';
|
|
13
|
+
import { allHash } from '@shell/utils/promise';
|
|
13
14
|
|
|
14
15
|
export default {
|
|
15
16
|
name: 'DetailRelease',
|
|
@@ -30,9 +31,15 @@ export default {
|
|
|
30
31
|
},
|
|
31
32
|
|
|
32
33
|
async fetch() {
|
|
33
|
-
|
|
34
|
+
const promises = {
|
|
35
|
+
catalog: this.$store.dispatch('catalog/load'),
|
|
36
|
+
allOperations: this.$store.dispatch('cluster/findAll', { type: CATALOG.OPERATION }),
|
|
37
|
+
secrets: this.value.fetchValues(true),
|
|
38
|
+
};
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
const res = await allHash(promises);
|
|
41
|
+
|
|
42
|
+
this.allOperations = res.allOperations;
|
|
36
43
|
},
|
|
37
44
|
|
|
38
45
|
computed: {
|
|
@@ -45,7 +52,7 @@ export default {
|
|
|
45
52
|
},
|
|
46
53
|
|
|
47
54
|
valuesYaml() {
|
|
48
|
-
const combined = merge(merge({}, this.value?.
|
|
55
|
+
const combined = merge(merge({}, this.value?.chartValues || {}), this.value?.values || {});
|
|
49
56
|
|
|
50
57
|
return jsyaml.dump(combined);
|
|
51
58
|
},
|
|
@@ -95,6 +102,12 @@ export default {
|
|
|
95
102
|
}
|
|
96
103
|
},
|
|
97
104
|
},
|
|
105
|
+
|
|
106
|
+
watch: {
|
|
107
|
+
'value.secretId'(neu, old) {
|
|
108
|
+
this.value.fetchValues(true);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
98
111
|
};
|
|
99
112
|
</script>
|
|
100
113
|
|
|
@@ -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
|
|
|
@@ -6,6 +6,7 @@ import ResourceTabs from '@shell/components/form/ResourceTabs';
|
|
|
6
6
|
import Tab from '@shell/components/Tabbed/Tab';
|
|
7
7
|
import { MANAGEMENT, FLEET } from '@shell/config/types';
|
|
8
8
|
import { FLEET as FLEET_LABELS } from '@shell/config/labels-annotations';
|
|
9
|
+
import { allHash } from 'utils/promise';
|
|
9
10
|
|
|
10
11
|
export default {
|
|
11
12
|
name: 'FleetDetailCluster',
|
|
@@ -27,17 +28,18 @@ export default {
|
|
|
27
28
|
|
|
28
29
|
async fetch() {
|
|
29
30
|
const clusterId = this.value?.metadata?.labels[FLEET_LABELS.CLUSTER_NAME];
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
const hash = await allHash({
|
|
32
|
+
rancherCluster: this.$store.dispatch('management/find', {
|
|
33
|
+
type: MANAGEMENT.CLUSTER,
|
|
34
|
+
id: clusterId
|
|
35
|
+
}),
|
|
36
|
+
repos: this.$store.dispatch('management/findAll', { type: FLEET.GIT_REPO }),
|
|
37
|
+
workspaces: this.$store.dispatch('management/findAll', { type: FLEET.WORKSPACE }),
|
|
38
|
+
bundleDeployments: this.$store.dispatch('management/findAll', { type: FLEET.BUNDLE_DEPLOYMENT })
|
|
34
39
|
});
|
|
35
40
|
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
await this.$store.dispatch('management/findAll', { type: FLEET.WORKSPACE });
|
|
39
|
-
|
|
40
|
-
await this.$store.dispatch('management/findAll', { type: FLEET.BUNDLE_DEPLOYMENT });
|
|
41
|
+
this.rancherCluster = hash.rancherCluster;
|
|
42
|
+
this.allRepos = hash.repos;
|
|
41
43
|
},
|
|
42
44
|
|
|
43
45
|
data() {
|
|
@@ -40,7 +40,7 @@ export default {
|
|
|
40
40
|
},
|
|
41
41
|
computed: {
|
|
42
42
|
gitRepoHasClusters() {
|
|
43
|
-
return this.value
|
|
43
|
+
return this.value.status.desiredReadyClusters;
|
|
44
44
|
},
|
|
45
45
|
clusterSchema() {
|
|
46
46
|
return this.$store.getters['management/schemaFor'](FLEET.CLUSTER);
|
|
@@ -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,13 +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, { VMWARE_VSPHERE } from '@shell/utils/v-sphere';
|
|
67
68
|
|
|
68
69
|
const HARVESTER = 'harvester';
|
|
69
70
|
const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
|
|
70
71
|
const NETBIOS_TRUNCATION_LENGTH = 15;
|
|
71
72
|
|
|
72
|
-
const VMWARE_VSPHERE = 'vmwarevsphere';
|
|
73
|
-
|
|
74
73
|
/**
|
|
75
74
|
* Classes to be adopted by the node badges in Machine pools
|
|
76
75
|
*/
|
|
@@ -892,6 +891,8 @@ export default {
|
|
|
892
891
|
created() {
|
|
893
892
|
this.registerBeforeHook(this.saveMachinePools, 'save-machine-pools', 1);
|
|
894
893
|
this.registerBeforeHook(this.setRegistryConfig, 'set-registry-config');
|
|
894
|
+
this.registerBeforeHook(this.handleVsphereCpiSecret, 'sync-vsphere-cpi');
|
|
895
|
+
this.registerBeforeHook(this.handleVsphereCsiSecret, 'sync-vsphere-csi');
|
|
895
896
|
this.registerAfterHook(this.cleanupMachinePools, 'cleanup-machine-pools');
|
|
896
897
|
this.registerAfterHook(this.saveRoleBindings, 'save-role-bindings');
|
|
897
898
|
|
|
@@ -904,6 +905,14 @@ export default {
|
|
|
904
905
|
methods: {
|
|
905
906
|
set,
|
|
906
907
|
|
|
908
|
+
async handleVsphereCpiSecret() {
|
|
909
|
+
return VsphereUtils.handleVsphereCpiSecret(this);
|
|
910
|
+
},
|
|
911
|
+
|
|
912
|
+
async handleVsphereCsiSecret() {
|
|
913
|
+
return VsphereUtils.handleVsphereCsiSecret(this);
|
|
914
|
+
},
|
|
915
|
+
|
|
907
916
|
/**
|
|
908
917
|
* Initialize all the cluster specs
|
|
909
918
|
*/
|
|
@@ -2420,8 +2429,10 @@ export default {
|
|
|
2420
2429
|
name="additionalmanifest"
|
|
2421
2430
|
label-key="cluster.tabs.addOnAdditionalManifest"
|
|
2422
2431
|
:showHeader="false"
|
|
2432
|
+
@active="refreshComponentWithYamls('additionalmanifest')"
|
|
2423
2433
|
>
|
|
2424
2434
|
<AddOnAdditionalManifest
|
|
2435
|
+
ref="additionalmanifest"
|
|
2425
2436
|
:value="value"
|
|
2426
2437
|
:mode="mode"
|
|
2427
2438
|
@additional-manifest-changed="updateAdditionalManifest"
|