@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
|
@@ -1,63 +1,214 @@
|
|
|
1
1
|
|
|
2
2
|
<script>
|
|
3
3
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
4
|
-
import { _CREATE } from '@shell/config/query-params';
|
|
4
|
+
import { _CREATE, _EDIT } from '@shell/config/query-params';
|
|
5
|
+
import RadioGroup from '@components/Form/Radio/RadioGroup.vue';
|
|
6
|
+
import { Banner } from '@components/Banner';
|
|
7
|
+
|
|
8
|
+
export const DATA_DIR_RADIO_OPTIONS = {
|
|
9
|
+
DEFAULT: 'defaultDataDir',
|
|
10
|
+
COMMON: 'commonBaseDataDir',
|
|
11
|
+
CUSTOM: 'customDataDir',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const DEFAULT_COMMON_BASE_PATH = '/var/lib/rancher';
|
|
15
|
+
|
|
16
|
+
export const DEFAULT_SUBDIRS = {
|
|
17
|
+
AGENT: 'agent',
|
|
18
|
+
PROVISIONING: 'provisioning',
|
|
19
|
+
K8S_DISTRO_RKE2: 'rke2',
|
|
20
|
+
K8S_DISTRO_K3S: 'k3s',
|
|
21
|
+
};
|
|
5
22
|
|
|
6
23
|
export default {
|
|
7
24
|
name: 'DirectoryConfig',
|
|
8
|
-
components: {
|
|
9
|
-
|
|
25
|
+
components: {
|
|
26
|
+
LabeledInput,
|
|
27
|
+
RadioGroup,
|
|
28
|
+
Banner
|
|
29
|
+
},
|
|
30
|
+
props: {
|
|
10
31
|
mode: {
|
|
11
32
|
type: String,
|
|
12
33
|
required: true,
|
|
13
34
|
},
|
|
14
35
|
|
|
36
|
+
k8sVersion: {
|
|
37
|
+
type: String,
|
|
38
|
+
required: true,
|
|
39
|
+
},
|
|
40
|
+
|
|
15
41
|
value: {
|
|
16
42
|
type: Object,
|
|
17
43
|
required: true,
|
|
18
44
|
},
|
|
19
45
|
},
|
|
46
|
+
data() {
|
|
47
|
+
let dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.DEFAULT;
|
|
48
|
+
let k8sDistroSubDir = DEFAULT_SUBDIRS.K8S_DISTRO_RKE2;
|
|
49
|
+
|
|
50
|
+
if (this.k8sVersion && this.k8sVersion.includes('k3s')) {
|
|
51
|
+
k8sDistroSubDir = DEFAULT_SUBDIRS.K8S_DISTRO_K3S;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (this.mode !== _CREATE) {
|
|
55
|
+
dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.CUSTOM;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
DATA_DIR_RADIO_OPTIONS,
|
|
60
|
+
dataConfigRadioValue,
|
|
61
|
+
k8sDistroSubDir,
|
|
62
|
+
commonConfig: '',
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
watch: {
|
|
66
|
+
commonConfig(neu) {
|
|
67
|
+
if (neu && neu.length && this.dataConfigRadioValue === DATA_DIR_RADIO_OPTIONS.COMMON) {
|
|
68
|
+
this.value.systemAgent = `${ neu }/${ DEFAULT_SUBDIRS.AGENT }`;
|
|
69
|
+
this.value.provisioning = `${ neu }/${ DEFAULT_SUBDIRS.PROVISIONING }`;
|
|
70
|
+
this.value.k8sDistro = `${ neu }/${ this.k8sDistroSubDir }`;
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
k8sVersion: {
|
|
74
|
+
handler(neu) {
|
|
75
|
+
if (neu && neu.includes('k3s')) {
|
|
76
|
+
this.k8sDistroSubDir = DEFAULT_SUBDIRS.K8S_DISTRO_K3S;
|
|
77
|
+
} else {
|
|
78
|
+
this.k8sDistroSubDir = DEFAULT_SUBDIRS.K8S_DISTRO_RKE2;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (this.value.k8sDistro) {
|
|
82
|
+
this.value.k8sDistro = `${ neu }/${ this.k8sDistroSubDir }`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
20
87
|
computed: {
|
|
21
|
-
|
|
22
|
-
return this.mode
|
|
88
|
+
isDisabled() {
|
|
89
|
+
return this.mode === _EDIT;
|
|
90
|
+
},
|
|
91
|
+
dataConfigRadioOptions() {
|
|
92
|
+
const defaultDataDirOption = {
|
|
93
|
+
value: DATA_DIR_RADIO_OPTIONS.DEFAULT,
|
|
94
|
+
label: this.t('cluster.directoryConfig.radioInput.defaultLabel')
|
|
95
|
+
};
|
|
96
|
+
const customDataDirOption = {
|
|
97
|
+
value: DATA_DIR_RADIO_OPTIONS.CUSTOM,
|
|
98
|
+
label: this.t('cluster.directoryConfig.radioInput.customLabel')
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
if (this.mode === _CREATE) {
|
|
102
|
+
return [
|
|
103
|
+
defaultDataDirOption,
|
|
104
|
+
{ value: DATA_DIR_RADIO_OPTIONS.COMMON, label: this.t('cluster.directoryConfig.radioInput.commonLabel') },
|
|
105
|
+
customDataDirOption
|
|
106
|
+
];
|
|
107
|
+
} else {
|
|
108
|
+
return [
|
|
109
|
+
defaultDataDirOption,
|
|
110
|
+
customDataDirOption
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
methods: {
|
|
116
|
+
handleRadioInput(val) {
|
|
117
|
+
switch (val) {
|
|
118
|
+
case DATA_DIR_RADIO_OPTIONS.DEFAULT:
|
|
119
|
+
if (this.mode === _CREATE) {
|
|
120
|
+
this.commonConfig = '';
|
|
121
|
+
}
|
|
122
|
+
this.value.systemAgent = '';
|
|
123
|
+
this.value.provisioning = '';
|
|
124
|
+
this.value.k8sDistro = '';
|
|
125
|
+
|
|
126
|
+
this.dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.DEFAULT;
|
|
127
|
+
break;
|
|
128
|
+
case DATA_DIR_RADIO_OPTIONS.COMMON:
|
|
129
|
+
this.commonConfig = DEFAULT_COMMON_BASE_PATH;
|
|
130
|
+
|
|
131
|
+
this.dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.COMMON;
|
|
132
|
+
break;
|
|
133
|
+
// default is custom config
|
|
134
|
+
default:
|
|
135
|
+
if (this.mode === _CREATE) {
|
|
136
|
+
this.commonConfig = '';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.value.systemAgent = '';
|
|
140
|
+
this.value.provisioning = '';
|
|
141
|
+
this.value.k8sDistro = '';
|
|
142
|
+
|
|
143
|
+
this.dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.CUSTOM;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
23
146
|
}
|
|
24
|
-
}
|
|
147
|
+
},
|
|
25
148
|
};
|
|
26
149
|
</script>
|
|
27
150
|
|
|
28
151
|
<template>
|
|
29
152
|
<div class="row">
|
|
30
153
|
<div class="col span-8">
|
|
31
|
-
<h3
|
|
154
|
+
<h3>
|
|
32
155
|
{{ t('cluster.directoryConfig.title') }}
|
|
33
156
|
</h3>
|
|
34
|
-
<
|
|
35
|
-
v-model="value.systemAgent"
|
|
157
|
+
<Banner
|
|
36
158
|
class="mb-20"
|
|
37
|
-
:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
:disabled="disableEditInput"
|
|
41
|
-
data-testid="rke2-directory-config-systemAgent-data-dir"
|
|
159
|
+
:closable="false"
|
|
160
|
+
color="info"
|
|
161
|
+
label-key="cluster.directoryConfig.banner"
|
|
42
162
|
/>
|
|
43
|
-
<
|
|
44
|
-
v-
|
|
45
|
-
|
|
163
|
+
<RadioGroup
|
|
164
|
+
v-show="!isDisabled"
|
|
165
|
+
:value="dataConfigRadioValue"
|
|
166
|
+
class="mb-10"
|
|
46
167
|
:mode="mode"
|
|
47
|
-
:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
168
|
+
:options="dataConfigRadioOptions"
|
|
169
|
+
name="directory-config-radio"
|
|
170
|
+
data-testid="rke2-directory-config-radio-input"
|
|
171
|
+
@input="handleRadioInput"
|
|
51
172
|
/>
|
|
52
173
|
<LabeledInput
|
|
53
|
-
v-
|
|
174
|
+
v-if="dataConfigRadioValue === DATA_DIR_RADIO_OPTIONS.COMMON"
|
|
175
|
+
v-model="commonConfig"
|
|
54
176
|
class="mb-20"
|
|
55
177
|
:mode="mode"
|
|
56
|
-
:label="t('cluster.directoryConfig.
|
|
57
|
-
:tooltip="t('cluster.directoryConfig.
|
|
58
|
-
:disabled="
|
|
59
|
-
data-testid="rke2-directory-config-
|
|
178
|
+
:label="t('cluster.directoryConfig.common.label')"
|
|
179
|
+
:tooltip="t('cluster.directoryConfig.common.tooltip')"
|
|
180
|
+
:disabled="isDisabled"
|
|
181
|
+
data-testid="rke2-directory-config-common-data-dir"
|
|
60
182
|
/>
|
|
183
|
+
<div v-if="dataConfigRadioValue === DATA_DIR_RADIO_OPTIONS.CUSTOM">
|
|
184
|
+
<LabeledInput
|
|
185
|
+
v-model="value.systemAgent"
|
|
186
|
+
class="mb-20"
|
|
187
|
+
:mode="mode"
|
|
188
|
+
:label="t('cluster.directoryConfig.systemAgent.label')"
|
|
189
|
+
:tooltip="t('cluster.directoryConfig.systemAgent.tooltip')"
|
|
190
|
+
:disabled="isDisabled"
|
|
191
|
+
data-testid="rke2-directory-config-systemAgent-data-dir"
|
|
192
|
+
/>
|
|
193
|
+
<LabeledInput
|
|
194
|
+
v-model="value.provisioning"
|
|
195
|
+
class="mb-20"
|
|
196
|
+
:mode="mode"
|
|
197
|
+
:label="t('cluster.directoryConfig.provisioning.label')"
|
|
198
|
+
:tooltip="t('cluster.directoryConfig.provisioning.tooltip')"
|
|
199
|
+
:disabled="isDisabled"
|
|
200
|
+
data-testid="rke2-directory-config-provisioning-data-dir"
|
|
201
|
+
/>
|
|
202
|
+
<LabeledInput
|
|
203
|
+
v-model="value.k8sDistro"
|
|
204
|
+
class="mb-20"
|
|
205
|
+
:mode="mode"
|
|
206
|
+
:label="t('cluster.directoryConfig.k8sDistro.label')"
|
|
207
|
+
:tooltip="t('cluster.directoryConfig.k8sDistro.tooltip')"
|
|
208
|
+
:disabled="isDisabled"
|
|
209
|
+
data-testid="rke2-directory-config-k8sDistro-data-dir"
|
|
210
|
+
/>
|
|
211
|
+
</div>
|
|
61
212
|
<div class="mb-40" />
|
|
62
213
|
</div>
|
|
63
214
|
</div>
|
|
@@ -7,9 +7,9 @@ jest.mock('@shell/utils/clipboard', () => {
|
|
|
7
7
|
describe('class MgmtCluster', () => {
|
|
8
8
|
describe('provisioner', () => {
|
|
9
9
|
const testCases = [
|
|
10
|
-
[{ provider: 'rke', driver: 'imported' }, '
|
|
11
|
-
[{ provider: 'k3s', driver: 'K3S' }, '
|
|
12
|
-
[{ provider: 'aks', driver: 'AKS' }, '
|
|
10
|
+
[{ provider: 'rke', driver: 'imported' }, 'imported'],
|
|
11
|
+
[{ provider: 'k3s', driver: 'K3S' }, 'K3S'],
|
|
12
|
+
[{ provider: 'aks', driver: 'AKS' }, 'AKS'],
|
|
13
13
|
[{}, 'imported'],
|
|
14
14
|
];
|
|
15
15
|
|
|
@@ -1,31 +1,6 @@
|
|
|
1
1
|
import ProvCluster from '@shell/models/provisioning.cattle.io.cluster';
|
|
2
2
|
|
|
3
3
|
describe('class ProvCluster', () => {
|
|
4
|
-
const importedClusterInfo = {
|
|
5
|
-
clusterName: 'test', provisioner: 'imported', mgmt: { spec: { gkeConfig: {} } }, spec: {}
|
|
6
|
-
};
|
|
7
|
-
const importedGkeClusterInfo = {
|
|
8
|
-
clusterName: 'test', provisioner: 'rke2', mgmt: { spec: { gkeConfig: { imported: true } } }
|
|
9
|
-
};
|
|
10
|
-
const importedAksClusterInfo = {
|
|
11
|
-
clusterName: 'test', provisioner: 'rke2', mgmt: { spec: { aksConfig: { imported: true } } }
|
|
12
|
-
};
|
|
13
|
-
const importedEksClusterInfo = {
|
|
14
|
-
clusterName: 'test', provisioner: 'rke2', mgmt: { spec: { eksConfig: { imported: true } } }
|
|
15
|
-
};
|
|
16
|
-
const notImportedGkeClusterInfo = {
|
|
17
|
-
clusterName: 'test', provisioner: 'rke2', mgmt: { spec: { gkeConfig: { imported: false } }, rkeConfig: {} }
|
|
18
|
-
};
|
|
19
|
-
const importedClusterInfoWithProviderForEmberParam = {
|
|
20
|
-
clusterName: 'test', provisioner: 'rke2', mgmt: { providerForEmberParam: 'import' }
|
|
21
|
-
};
|
|
22
|
-
const localClusterInfo = {
|
|
23
|
-
clusterName: 'test', provisioner: 'imported', mgmt: { isLocal: true, spec: { gkeConfig: {} } }, spec: {}
|
|
24
|
-
};
|
|
25
|
-
const doRke2Info = {
|
|
26
|
-
clusterName: 'test', provisioner: 'rke2', mgmt: { isLocal: false, providerForEmberParam: 'import' }, spec: { rkeConfig: {} }
|
|
27
|
-
};
|
|
28
|
-
|
|
29
4
|
const gkeClusterWithPrivateEndpoint = {
|
|
30
5
|
clusterName: 'test',
|
|
31
6
|
provisioner: 'GKE',
|
|
@@ -76,67 +51,6 @@ describe('class ProvCluster', () => {
|
|
|
76
51
|
});
|
|
77
52
|
});
|
|
78
53
|
|
|
79
|
-
describe('isImported', () => {
|
|
80
|
-
const testCases = [
|
|
81
|
-
[importedClusterInfo, true],
|
|
82
|
-
[importedGkeClusterInfo, true],
|
|
83
|
-
[importedAksClusterInfo, true],
|
|
84
|
-
[importedEksClusterInfo, true],
|
|
85
|
-
[notImportedGkeClusterInfo, false],
|
|
86
|
-
[importedClusterInfoWithProviderForEmberParam, true],
|
|
87
|
-
[localClusterInfo, false],
|
|
88
|
-
[doRke2Info, false],
|
|
89
|
-
[{}, false],
|
|
90
|
-
];
|
|
91
|
-
const resetMocks = () => {
|
|
92
|
-
// Clear all mock function calls:
|
|
93
|
-
jest.clearAllMocks();
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
it.each(testCases)('should return the isImported value properly based on the props data', (clusterData: Object, expected: Boolean) => {
|
|
97
|
-
const cluster = new ProvCluster({ spec: clusterData.spec });
|
|
98
|
-
|
|
99
|
-
jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(
|
|
100
|
-
clusterData.mgmt
|
|
101
|
-
);
|
|
102
|
-
jest.spyOn(cluster, 'provisioner', 'get').mockReturnValue(
|
|
103
|
-
clusterData.provisioner
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
expect(cluster.isImported).toBe(expected);
|
|
107
|
-
resetMocks();
|
|
108
|
-
}
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('mgmt', () => {
|
|
113
|
-
const testCases = [
|
|
114
|
-
[importedClusterInfo, importedClusterInfo.mgmt],
|
|
115
|
-
[importedGkeClusterInfo, importedGkeClusterInfo.mgmt],
|
|
116
|
-
[importedAksClusterInfo, importedAksClusterInfo.mgmt],
|
|
117
|
-
[importedEksClusterInfo, importedEksClusterInfo.mgmt],
|
|
118
|
-
[notImportedGkeClusterInfo, notImportedGkeClusterInfo.mgmt],
|
|
119
|
-
[importedClusterInfoWithProviderForEmberParam, importedClusterInfoWithProviderForEmberParam.mgmt],
|
|
120
|
-
[localClusterInfo, localClusterInfo.mgmt],
|
|
121
|
-
[doRke2Info, doRke2Info.mgmt],
|
|
122
|
-
[{}, null],
|
|
123
|
-
];
|
|
124
|
-
|
|
125
|
-
const resetMocks = () => {
|
|
126
|
-
// Clear all mock function calls:
|
|
127
|
-
jest.clearAllMocks();
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
it.each(testCases)('should return the isImported value properly based on the props data', (clusterData: Object, expected: Object) => {
|
|
131
|
-
const clusterMock = jest.fn(() => clusterData.mgmt);
|
|
132
|
-
const ctx = { rootGetters: { 'management/byId': clusterMock } };
|
|
133
|
-
const cluster = new ProvCluster({ status: { clusterName: clusterData.clusterName } }, ctx);
|
|
134
|
-
|
|
135
|
-
expect(cluster.mgmt).toBe(expected);
|
|
136
|
-
resetMocks();
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
54
|
describe('hasError', () => {
|
|
141
55
|
const conditionsWithoutError = [
|
|
142
56
|
{
|
|
@@ -30,7 +30,9 @@ export default class FleetBundle extends SteveModel {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
get repoName() {
|
|
33
|
-
|
|
33
|
+
const labels = this.metadata?.labels || {};
|
|
34
|
+
|
|
35
|
+
return labels['fleet.cattle.io/repo-name'];
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
get targetClusters() {
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import Vue from 'vue';
|
|
2
2
|
import { convert, matching, convertSelectorObj } from '@shell/utils/selector';
|
|
3
3
|
import jsyaml from 'js-yaml';
|
|
4
|
-
import { escapeHtml
|
|
4
|
+
import { escapeHtml } from '@shell/utils/string';
|
|
5
5
|
import { FLEET } from '@shell/config/types';
|
|
6
6
|
import { FLEET as FLEET_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
7
7
|
import { addObject, addObjects, findBy, insertAt } from '@shell/utils/array';
|
|
8
8
|
import { set } from '@shell/utils/object';
|
|
9
9
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
10
10
|
import {
|
|
11
|
-
|
|
11
|
+
colorForState, mapStateToEnum, primaryDisplayStatusFromCount, stateDisplay, stateSort
|
|
12
12
|
} from '@shell/plugins/dashboard-store/resource-class';
|
|
13
13
|
import { NAME } from '@shell/config/product/explorer';
|
|
14
|
+
import FleetUtils from '@shell/utils/fleet';
|
|
14
15
|
|
|
15
16
|
function quacksLikeAHash(str) {
|
|
16
17
|
if (str.match(/^[a-f0-9]{40,}$/i)) {
|
|
@@ -322,35 +323,29 @@ export default class GitRepo extends SteveModel {
|
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
get resourcesStatuses() {
|
|
325
|
-
const
|
|
326
|
-
const
|
|
327
|
-
|
|
326
|
+
const bundleDeployments = this.bundleDeployments || [];
|
|
327
|
+
const clusters = (this.targetClusters || []).reduce((res, c) => {
|
|
328
|
+
res[c.id] = c;
|
|
329
|
+
|
|
330
|
+
return res;
|
|
331
|
+
}, {});
|
|
328
332
|
|
|
329
333
|
const out = [];
|
|
330
334
|
|
|
331
|
-
for (const
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
?.status?.resources || [];
|
|
335
|
+
for (const bd of bundleDeployments) {
|
|
336
|
+
const clusterId = FleetUtils.clusterIdFromBundleDeploymentLabels(bd.metadata?.labels);
|
|
337
|
+
const c = clusters[clusterId];
|
|
335
338
|
|
|
336
|
-
|
|
337
|
-
|
|
339
|
+
if (!c) {
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
338
342
|
|
|
339
|
-
|
|
340
|
-
namespacedName = `${ r.namespace }:${ r.name }`;
|
|
341
|
-
}
|
|
343
|
+
const resources = FleetUtils.resourcesFromBundleDeploymentStatus(bd.status);
|
|
342
344
|
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
if (perEntry) {
|
|
348
|
-
state = perEntry.state;
|
|
349
|
-
} else if (tooMany) {
|
|
350
|
-
state = STATES_ENUM.UNKNOWN;
|
|
351
|
-
} else {
|
|
352
|
-
state = STATES_ENUM.READY;
|
|
353
|
-
}
|
|
345
|
+
resources.forEach((r) => {
|
|
346
|
+
const id = FleetUtils.resourceId(r);
|
|
347
|
+
const type = FleetUtils.resourceType(r);
|
|
348
|
+
const state = r.state;
|
|
354
349
|
|
|
355
350
|
const color = colorForState(state).replace('text-', 'bg-');
|
|
356
351
|
const display = stateDisplay(state);
|
|
@@ -360,33 +355,38 @@ export default class GitRepo extends SteveModel {
|
|
|
360
355
|
params: {
|
|
361
356
|
product: NAME,
|
|
362
357
|
cluster: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME],
|
|
363
|
-
resource:
|
|
358
|
+
resource: type,
|
|
364
359
|
namespace: r.namespace,
|
|
365
360
|
id: r.name,
|
|
366
361
|
}
|
|
367
362
|
};
|
|
368
363
|
|
|
364
|
+
const key = `${ c.id }-${ type }-${ r.namespace }-${ r.name }`;
|
|
365
|
+
|
|
369
366
|
out.push({
|
|
370
|
-
key
|
|
371
|
-
tableKey:
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
clusterName:
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
367
|
+
key,
|
|
368
|
+
tableKey: key,
|
|
369
|
+
|
|
370
|
+
// Needed?
|
|
371
|
+
id,
|
|
372
|
+
type,
|
|
373
|
+
clusterId: c.id,
|
|
374
|
+
|
|
375
|
+
// columns, see FleetResources.vue
|
|
376
|
+
state: mapStateToEnum(state),
|
|
377
|
+
clusterName: c.nameDisplay,
|
|
378
|
+
apiVersion: r.apiVersion,
|
|
379
|
+
kind: r.kind,
|
|
380
|
+
name: r.name,
|
|
381
|
+
namespace: r.namespace,
|
|
382
|
+
creationTimestamp: r.createdAt,
|
|
383
|
+
|
|
384
|
+
// other properties
|
|
385
|
+
clusterLabel: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME],
|
|
386
|
+
stateBackground: color,
|
|
387
|
+
stateDisplay: display,
|
|
388
|
+
stateSort: stateSort(color, display),
|
|
386
389
|
detailLocation,
|
|
387
|
-
conditions: conditions[i],
|
|
388
|
-
bundleDeploymentStatus: clusterBundleDeploymentResources?.[i],
|
|
389
|
-
creationTimestamp: clusterBundleDeploymentResources?.[i]?.createdAt
|
|
390
390
|
});
|
|
391
391
|
});
|
|
392
392
|
}
|
|
@@ -407,9 +407,7 @@ export default class GitRepo extends SteveModel {
|
|
|
407
407
|
|
|
408
408
|
get clusterResourceStatus() {
|
|
409
409
|
const clusterStatuses = this.resourcesStatuses.reduce((prev, curr) => {
|
|
410
|
-
const { clusterId, clusterLabel } = curr;
|
|
411
|
-
|
|
412
|
-
const state = curr.state;
|
|
410
|
+
const { clusterId, clusterLabel, state } = curr;
|
|
413
411
|
|
|
414
412
|
if (!prev[clusterId]) {
|
|
415
413
|
prev[clusterId] = {
|
|
@@ -90,10 +90,6 @@ export default class MgmtCluster extends SteveModel {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
get provisioner() {
|
|
93
|
-
if (this.status?.provider ) {
|
|
94
|
-
return this.status.provider;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
93
|
// For imported K3s clusters, this.status.driver is 'k3s.'
|
|
98
94
|
return this.status?.driver ? this.status.driver : 'imported';
|
|
99
95
|
}
|
|
@@ -117,7 +113,8 @@ export default class MgmtCluster extends SteveModel {
|
|
|
117
113
|
get providerForEmberParam() {
|
|
118
114
|
// Ember wants one word called provider to tell what component to show, but has much indirect mapping to figure out what it is.
|
|
119
115
|
let provider;
|
|
120
|
-
|
|
116
|
+
|
|
117
|
+
// provisioner is status.driver
|
|
121
118
|
const provisioner = KONTAINER_TO_DRIVER[(this.provisioner || '').toLowerCase()] || this.provisioner;
|
|
122
119
|
|
|
123
120
|
if ( provisioner === 'rancherKubernetesEngine' ) {
|
|
@@ -282,19 +282,29 @@ export default class ProvCluster extends SteveModel {
|
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
get isImported() {
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
if (this.isLocal) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// imported rke2 and k3s have status.driver === rke2 and k3s respectively
|
|
290
|
+
// Provisioned rke2 and k3s have status.driver === imported
|
|
291
|
+
if (this.mgmt?.status?.provider === 'k3s' || this.mgmt?.status?.provider === 'rke2') {
|
|
292
|
+
return this.mgmt?.status?.driver === this.mgmt?.status?.provider;
|
|
293
|
+
}
|
|
287
294
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
295
|
+
// imported KEv2
|
|
296
|
+
// we can't rely on this.provisioner to determine imported-ness for these clusters, as it will return 'aks' 'eks' 'gke' for both provisioned and imported clusters
|
|
297
|
+
const kontainerConfigs = ['aksConfig', 'eksConfig', 'gkeConfig'];
|
|
298
|
+
|
|
299
|
+
const isImportedKontainer = kontainerConfigs.filter((key) => {
|
|
300
|
+
return this.mgmt?.spec?.[key]?.imported === true;
|
|
301
|
+
}).length;
|
|
302
|
+
|
|
303
|
+
if (isImportedKontainer) {
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
296
306
|
|
|
297
|
-
return
|
|
307
|
+
return this.provisioner === 'imported';
|
|
298
308
|
}
|
|
299
309
|
|
|
300
310
|
get isCustom() {
|
|
@@ -330,7 +340,8 @@ export default class ProvCluster extends SteveModel {
|
|
|
330
340
|
}
|
|
331
341
|
|
|
332
342
|
get isRke1() {
|
|
333
|
-
|
|
343
|
+
// rancherKubernetesEngineConfig is not defined on imported RKE1 clusters
|
|
344
|
+
return !!this.mgmt?.spec?.rancherKubernetesEngineConfig || this.mgmt?.labels['provider.cattle.io'] === 'rke';
|
|
334
345
|
}
|
|
335
346
|
|
|
336
347
|
get isHarvester() {
|
|
@@ -407,6 +418,8 @@ export default class ProvCluster extends SteveModel {
|
|
|
407
418
|
provisioner = 'k3s';
|
|
408
419
|
} else if ( this.isImportedRke2 ) {
|
|
409
420
|
provisioner = 'rke2';
|
|
421
|
+
} else if ((this.isImported || this.isLocal) && this.isRke1) {
|
|
422
|
+
provisioner = 'rke';
|
|
410
423
|
}
|
|
411
424
|
|
|
412
425
|
return this.$rootGetters['i18n/withFallback'](`cluster.provider."${ provisioner }"`, null, ucFirst(provisioner));
|
package/package.json
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
annotations:
|
|
2
2
|
catalog.cattle.io/certified: rancher # Any application we are adding as a helm chart
|
|
3
|
-
catalog.cattle.io/kube-version: '>= 1.16.0-0'
|
|
4
3
|
catalog.cattle.io/namespace: cattle-ui-plugin-system # Must prefix with cattle- and suffix with -system=
|
|
5
4
|
catalog.cattle.io/os: linux
|
|
6
5
|
catalog.cattle.io/permits-os: linux, windows
|
|
7
|
-
catalog.cattle.io/rancher-version: '>= 2.7.0-0 < 2.9.0-0'
|
|
8
6
|
catalog.cattle.io/scope: management
|
|
9
7
|
catalog.cattle.io/ui-component: plugins
|
|
10
8
|
apiVersion: v2
|
|
@@ -4,27 +4,36 @@ GITHUB_RELEASE_TAG=$1
|
|
|
4
4
|
GITHUB_RUN_ID=$2
|
|
5
5
|
GITHUB_WORKFLOW_TYPE=$3
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
echo "Parse tag name - evaluating release tag $GITHUB_RELEASE_TAG"
|
|
8
|
+
|
|
9
|
+
# Ensure "catalog" workflow release tag name matches the root <pkg-name>
|
|
8
10
|
if [[ "${GITHUB_WORKFLOW_TYPE}" == "catalog" ]]; then
|
|
11
|
+
BASE_EXT=$(jq -r .name package.json)
|
|
12
|
+
EXT_VERSION=$(jq -r .version package.json)
|
|
13
|
+
|
|
14
|
+
if [[ "${GITHUB_RELEASE_TAG}" != "${BASE_EXT}-${EXT_VERSION}" ]]; then
|
|
15
|
+
echo -e "release tag doesn't match catalog tag: release tag -> ${GITHUB_RELEASE_TAG} ::: curr catalog tag -> ${BASE_EXT}-${EXT_VERSION}"
|
|
16
|
+
gh run cancel ${GITHUB_RUN_ID}
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
# Ensure "chart" workflow release tag name matches some pkg/<pkg-name>
|
|
20
|
+
else
|
|
21
|
+
NO_MATCHES="true"
|
|
22
|
+
|
|
9
23
|
for d in pkg/*/ ; do
|
|
10
24
|
pkg=$(basename $d)
|
|
11
25
|
|
|
12
26
|
PKG_VERSION=$(jq -r .version pkg/${pkg}/package.json)
|
|
13
|
-
|
|
27
|
+
CURR_PKG_TAG="${pkg}-${PKG_VERSION}"
|
|
14
28
|
|
|
15
|
-
if [[ "${GITHUB_RELEASE_TAG}" == "${
|
|
16
|
-
|
|
17
|
-
else
|
|
18
|
-
continue
|
|
29
|
+
if [[ "${GITHUB_RELEASE_TAG}" == "${CURR_PKG_TAG}" ]]; then
|
|
30
|
+
NO_MATCHES="false"
|
|
19
31
|
fi
|
|
20
32
|
done
|
|
21
|
-
else
|
|
22
|
-
# Ensure "charts" workflow release tag name does not match the root <pkg-name>
|
|
23
|
-
BASE_EXT=$(jq -r .name package.json)
|
|
24
|
-
EXT_VERSION=$(jq -r .version package.json)
|
|
25
33
|
|
|
26
|
-
if [[ "${
|
|
27
|
-
echo -e "tag: ${GITHUB_RELEASE_TAG}"
|
|
34
|
+
if [[ "${NO_MATCHES}" == "true" ]]; then
|
|
35
|
+
echo -e "release tag doesn't match any chart tag: ${GITHUB_RELEASE_TAG}. Check your pkg/<!-YOUR-EXT-> folders and corresponding versions to complete the match"
|
|
28
36
|
gh run cancel ${GITHUB_RUN_ID}
|
|
37
|
+
exit 1
|
|
29
38
|
fi
|
|
30
39
|
fi
|