@rancher/shell 0.1.4 → 0.1.21
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/suse/favicon.png +0 -0
- package/assets/images/generic-plugin.svg +1 -7
- package/assets/translations/en-us.yaml +81 -47
- package/components/CommunityLinks.vue +40 -49
- package/components/ExplorerProjectsNamespaces.vue +20 -3
- package/components/LazyImage.vue +21 -8
- package/components/PromptRemove.vue +2 -2
- package/components/ResourceList/Masthead.vue +21 -1
- package/components/ResourceList/ResourceLoadingIndicator.vue +0 -8
- package/components/ResourceList/index.vue +9 -23
- package/components/SortableTable/index.vue +13 -10
- package/components/Tabbed/index.vue +25 -7
- package/components/TypeDescription.vue +10 -1
- package/components/fleet/FleetClusters.vue +6 -0
- package/components/fleet/FleetRepos.vue +7 -1
- package/components/form/Command.vue +5 -0
- package/components/form/EnvVars.vue +5 -0
- package/components/form/NameNsDescription.vue +3 -1
- package/components/form/NodeScheduling.vue +6 -1
- package/components/form/PodAffinity.vue +5 -0
- package/components/form/ServiceNameSelect.vue +5 -0
- package/components/form/ValueFromResource.vue +7 -1
- package/components/nav/TopLevelMenu.vue +2 -1
- package/config/home-links.js +155 -0
- package/config/private-label.js +1 -1
- package/config/product/manager.js +0 -2
- package/config/product/uiplugins.js +1 -1
- package/config/settings.js +3 -1
- package/config/uiplugins.js +63 -6
- package/config/version.js +17 -0
- package/core/plugin.ts +12 -0
- package/core/plugins.js +29 -5
- package/core/types.ts +6 -0
- package/creators/app/{.eslintignore → files/.eslintignore} +0 -0
- package/creators/app/{.eslintrc.js → files/.eslintrc.js} +0 -0
- package/creators/app/{.vscode → files/.vscode}/settings.json +0 -0
- package/creators/app/{babel.config.js → files/babel.config.js} +0 -0
- package/creators/app/{nuxt.config.js → files/nuxt.config.js} +0 -0
- package/creators/app/{tsconfig.json → files/tsconfig.json} +2 -1
- package/creators/app/init +16 -17
- package/creators/app/package.json +6 -0
- package/creators/pkg/{babel.config.js → files/babel.config.js} +0 -0
- package/creators/pkg/{index.ts → files/index.ts} +0 -0
- package/creators/pkg/{tsconfig.json → files/tsconfig.json} +13 -12
- package/creators/pkg/{vue.config.js → files/vue.config.js} +0 -0
- package/creators/pkg/init +1 -1
- package/creators/update/init +54 -0
- package/creators/update/package.json +20 -0
- package/creators/update/upgrade +56 -0
- package/creators/update/yarn-error.log +54 -0
- package/detail/workload/index.vue +1 -0
- package/edit/persistentvolume/index.vue +48 -13
- package/edit/persistentvolumeclaim.vue +31 -13
- package/edit/provisioning.cattle.io.cluster/rke2.vue +27 -19
- package/edit/workload/index.vue +19 -9
- package/edit/workload/mixins/workload.js +109 -114
- package/edit/workload/storage/index.vue +11 -17
- package/edit/workload/storage/persistentVolumeClaim/index.vue +5 -0
- package/edit/workload/storage/secret.vue +6 -1
- package/list/catalog.cattle.io.app.vue +10 -9
- package/list/catalog.cattle.io.clusterrepo.vue +6 -61
- package/list/cis.cattle.io.clusterscan.vue +12 -12
- package/list/fleet.cattle.io.bundle.vue +33 -28
- package/list/fleet.cattle.io.cluster.vue +26 -22
- package/list/fleet.cattle.io.clustergroup.vue +6 -0
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +28 -24
- package/list/fleet.cattle.io.gitrepo.vue +25 -14
- package/list/helm.cattle.io.projecthelmchart.vue +52 -33
- package/list/logging.banzaicloud.io.clusterflow.vue +7 -12
- package/list/logging.banzaicloud.io.flow.vue +7 -14
- package/list/management.cattle.io.cluster.vue +26 -15
- package/list/management.cattle.io.feature.vue +13 -8
- package/list/management.cattle.io.user.vue +38 -19
- package/list/monitoring.coreos.com.alertmanagerconfig.vue +8 -15
- package/list/namespace.vue +14 -1
- package/list/node.vue +13 -16
- package/list/persistentvolume.vue +16 -9
- package/list/persistentvolumeclaim.vue +5 -8
- package/list/provisioning.cattle.io.cluster.vue +34 -8
- package/list/service.vue +24 -12
- package/list/ui.cattle.io.navlink.vue +6 -0
- package/list/workload.vue +2 -2
- package/middleware/authenticated.js +6 -0
- package/mixins/resource-fetch.js +12 -18
- package/mixins/resource-manager.js +126 -0
- package/models/catalog.cattle.io.uiplugin.js +4 -0
- package/models/pod.js +15 -5
- package/models/provisioning.cattle.io.cluster.js +4 -0
- package/models/workload.service.js +10 -0
- package/nuxt.config.js +2 -1
- package/package.json +1 -1
- package/pages/auth/login.vue +10 -0
- package/pages/auth/verify.vue +9 -0
- package/pages/c/_cluster/settings/DefaultLinksEditor.vue +108 -0
- package/pages/c/_cluster/settings/links.vue +53 -101
- package/pages/c/_cluster/settings/performance.vue +90 -7
- package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +3 -3
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +71 -20
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +21 -5
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +2 -7
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +23 -15
- package/pages/c/_cluster/uiplugins/UninstallDialog.vue +11 -4
- package/pages/c/_cluster/uiplugins/index.vue +179 -65
- package/pages/support/index.vue +31 -142
- package/plugins/dashboard-store/actions.js +19 -0
- package/plugins/dashboard-store/getters.js +20 -3
- package/plugins/dashboard-store/mutations.js +13 -7
- package/plugins/plugin.js +18 -15
- package/plugins/steve/getters.js +12 -0
- package/plugins/version.js +21 -0
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -7
- package/rancher-components/components/BadgeState/BadgeState.spec.ts +12 -0
- package/rancher-components/components/BadgeState/BadgeState.vue +107 -0
- package/rancher-components/components/BadgeState/index.ts +1 -0
- package/rancher-components/components/Banner/Banner.test.ts +13 -0
- package/rancher-components/components/Banner/Banner.vue +163 -0
- package/rancher-components/components/Banner/index.ts +1 -0
- package/rancher-components/components/Card/Card.vue +150 -0
- package/rancher-components/components/Card/index.ts +1 -0
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +77 -0
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +395 -0
- package/rancher-components/components/Form/Checkbox/index.ts +1 -0
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +29 -0
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +343 -0
- package/rancher-components/components/Form/LabeledInput/index.ts +1 -0
- package/rancher-components/components/Form/Radio/RadioButton.vue +270 -0
- package/rancher-components/components/Form/Radio/RadioGroup.vue +235 -0
- package/rancher-components/components/Form/Radio/index.ts +2 -0
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +168 -0
- package/rancher-components/components/Form/TextArea/index.ts +1 -0
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +107 -0
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +137 -0
- package/rancher-components/components/Form/ToggleSwitch/index.ts +1 -0
- package/rancher-components/components/Form/index.ts +5 -0
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +137 -0
- package/rancher-components/components/LabeledTooltip/index.ts +1 -0
- package/scripts/publish-shell.sh +39 -6
- package/scripts/record-deps.js +37 -0
- package/scripts/test-plugins-build.sh +8 -5
- package/scripts/typegen.sh +84 -0
- package/store/auth.js +3 -0
- package/store/index.js +12 -3
- package/types/shell/index.d.ts +3046 -0
- package/utils/favicon.js +8 -2
- package/utils/gc/gc-interval.ts +40 -0
- package/utils/gc/gc-root-store.js +76 -0
- package/utils/gc/gc-route-changed.ts +44 -0
- package/utils/gc/gc-types.ts +21 -0
- package/utils/gc/gc.ts +282 -0
- package/config/footer.js +0 -18
- package/creators/pkg/nuxt.config.js +0 -6
- package/yarn-error.log +0 -195
|
@@ -1222,32 +1222,40 @@ export default {
|
|
|
1222
1222
|
return;
|
|
1223
1223
|
}
|
|
1224
1224
|
|
|
1225
|
-
|
|
1225
|
+
try {
|
|
1226
|
+
const clusterId = get(this.credential, 'decodedData.clusterId') || '';
|
|
1226
1227
|
|
|
1227
|
-
|
|
1228
|
+
this.applyChartValues(this.value.spec.rkeConfig);
|
|
1228
1229
|
|
|
1229
|
-
|
|
1230
|
+
const isUpgrade = this.isEdit && this.liveValue?.spec?.kubernetesVersion !== this.value?.spec?.kubernetesVersion;
|
|
1230
1231
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1232
|
+
if (this.agentConfig['cloud-provider-name'] === HARVESTER && clusterId && (this.isCreate || isUpgrade)) {
|
|
1233
|
+
const namespace = this.machinePools?.[0]?.config?.vmNamespace;
|
|
1233
1234
|
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1235
|
+
const res = await this.$store.dispatch('management/request', {
|
|
1236
|
+
url: `/k8s/clusters/${ clusterId }/v1/harvester/kubeconfig`,
|
|
1237
|
+
method: 'POST',
|
|
1238
|
+
data: {
|
|
1239
|
+
clusterRoleName: 'harvesterhci.io:cloudprovider',
|
|
1240
|
+
namespace,
|
|
1241
|
+
serviceAccountName: this.value.metadata.name,
|
|
1242
|
+
},
|
|
1243
|
+
});
|
|
1244
|
+
|
|
1245
|
+
const kubeconfig = res.data;
|
|
1243
1246
|
|
|
1244
|
-
|
|
1247
|
+
const harvesterKubeconfigSecret = await this.createKubeconfigSecret(kubeconfig);
|
|
1245
1248
|
|
|
1246
|
-
|
|
1249
|
+
set(this.agentConfig, 'cloud-provider-config', `secret://fleet-default:${ harvesterKubeconfigSecret?.metadata?.name }`);
|
|
1250
|
+
set(this.chartValues, `${ HARVESTER_CLOUD_PROVIDER }.clusterName`, this.value.metadata.name);
|
|
1251
|
+
set(this.chartValues, `${ HARVESTER_CLOUD_PROVIDER }.cloudConfigPath`, '/var/lib/rancher/rke2/etc/config-files/cloud-provider-config');
|
|
1252
|
+
}
|
|
1253
|
+
} catch (err) {
|
|
1254
|
+
this.errors.push(err);
|
|
1255
|
+
|
|
1256
|
+
btnCb(false);
|
|
1247
1257
|
|
|
1248
|
-
|
|
1249
|
-
set(this.chartValues, `${ HARVESTER_CLOUD_PROVIDER }.clusterName`, this.value.metadata.name);
|
|
1250
|
-
set(this.chartValues, `${ HARVESTER_CLOUD_PROVIDER }.cloudConfigPath`, '/var/lib/rancher/rke2/etc/config-files/cloud-provider-config');
|
|
1258
|
+
return;
|
|
1251
1259
|
}
|
|
1252
1260
|
|
|
1253
1261
|
await this.save(btnCb);
|
package/edit/workload/index.vue
CHANGED
|
@@ -4,7 +4,7 @@ import FormValidation from '@shell/mixins/form-validation';
|
|
|
4
4
|
import WorkLoadMixin from '@shell/edit/workload/mixins/workload';
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
|
-
name: '
|
|
7
|
+
name: 'Workload',
|
|
8
8
|
mixins: [CreateEditView, FormValidation, WorkLoadMixin], // The order here is important since WorkLoadMixin contains some FormValidation configuration
|
|
9
9
|
props: {
|
|
10
10
|
value: {
|
|
@@ -56,6 +56,7 @@ export default {
|
|
|
56
56
|
:mode="mode"
|
|
57
57
|
:rules="{name: fvGetAndReportPathRules('metadata.name'), namespace: fvGetAndReportPathRules('metadata.namespace'), description: []}"
|
|
58
58
|
@change="name=value.metadata.name"
|
|
59
|
+
@isNamespaceNew="isNamespaceNew = $event"
|
|
59
60
|
/>
|
|
60
61
|
<div v-if="isCronJob || isReplicable || isStatefulSet || containerOptions.length > 1" class="row mb-20">
|
|
61
62
|
<div v-if="isCronJob" class="col span-3">
|
|
@@ -91,10 +92,10 @@ export default {
|
|
|
91
92
|
/>
|
|
92
93
|
</div>
|
|
93
94
|
</div>
|
|
94
|
-
<Tabbed class="deployment-tabs" :show-tabs-add-remove="true" :default-tab="defaultTab" @changed="changed">
|
|
95
|
+
<Tabbed class="deployment-tabs" :show-tabs-add-remove="true" :default-tab="defaultTab" :flat="true" @changed="changed">
|
|
95
96
|
<Tab
|
|
96
97
|
v-for="(tab, i) in allContainers"
|
|
97
|
-
:key="i
|
|
98
|
+
:key="i"
|
|
98
99
|
:label="tab.name"
|
|
99
100
|
:name="tab.name"
|
|
100
101
|
:weight="tab.weight"
|
|
@@ -110,7 +111,7 @@ export default {
|
|
|
110
111
|
<div>
|
|
111
112
|
<div :style="{'align-items':'center'}" class="row mb-20">
|
|
112
113
|
<div class="col span-6">
|
|
113
|
-
<LabeledInput v-model="
|
|
114
|
+
<LabeledInput v-model="allContainers[i].name" :mode="mode" :label="t('workload.container.containerName')" />
|
|
114
115
|
</div>
|
|
115
116
|
<div class="col span-6">
|
|
116
117
|
<RadioGroup
|
|
@@ -127,7 +128,7 @@ export default {
|
|
|
127
128
|
<div class="row mb-20">
|
|
128
129
|
<div class="col span-6">
|
|
129
130
|
<LabeledInput
|
|
130
|
-
v-model.trim="
|
|
131
|
+
v-model.trim="allContainers[i].image"
|
|
131
132
|
:mode="mode"
|
|
132
133
|
:label="t('workload.container.image')"
|
|
133
134
|
:placeholder="t('generic.placeholder', {text: 'nginx:latest'}, true)"
|
|
@@ -136,7 +137,7 @@ export default {
|
|
|
136
137
|
</div>
|
|
137
138
|
<div class="col span-6">
|
|
138
139
|
<LabeledSelect
|
|
139
|
-
v-model="
|
|
140
|
+
v-model="allContainers[i].imagePullPolicy"
|
|
140
141
|
:label="t('workload.container.imagePullPolicy')"
|
|
141
142
|
:options="pullPolicyOptions"
|
|
142
143
|
:mode="mode"
|
|
@@ -169,7 +170,13 @@ export default {
|
|
|
169
170
|
<div class="spacer" />
|
|
170
171
|
<div>
|
|
171
172
|
<h3>{{ t('workload.container.titles.command') }}</h3>
|
|
172
|
-
<Command
|
|
173
|
+
<Command
|
|
174
|
+
v-model="allContainers[i]"
|
|
175
|
+
:secrets="namespacedSecrets"
|
|
176
|
+
:config-maps="namespacedConfigMaps"
|
|
177
|
+
:mode="mode"
|
|
178
|
+
:loading="isLoadingSecondaryResources"
|
|
179
|
+
/>
|
|
173
180
|
</div>
|
|
174
181
|
<ServiceNameSelect
|
|
175
182
|
:value="podTemplateSpec.serviceAccountName"
|
|
@@ -178,6 +185,7 @@ export default {
|
|
|
178
185
|
:select-placeholder="t('workload.serviceAccountName.label')"
|
|
179
186
|
:options="namespacedServiceNames"
|
|
180
187
|
option-label="metadata.name"
|
|
188
|
+
:loading="isLoadingSecondaryResources"
|
|
181
189
|
@input="updateServiceAccount"
|
|
182
190
|
/>
|
|
183
191
|
<div class="spacer" />
|
|
@@ -234,6 +242,8 @@ export default {
|
|
|
234
242
|
:secrets="namespacedSecrets"
|
|
235
243
|
:config-maps="namespacedConfigMaps"
|
|
236
244
|
:save-pvc-hook-name="savePvcHookName"
|
|
245
|
+
:loading="isLoadingSecondaryResources"
|
|
246
|
+
:namespaced-pvcs="pvcs"
|
|
237
247
|
@removePvcForm="clearPvcFormState"
|
|
238
248
|
/>
|
|
239
249
|
</Tab>
|
|
@@ -265,10 +275,10 @@ export default {
|
|
|
265
275
|
</template>
|
|
266
276
|
</Tab>
|
|
267
277
|
<Tab :label="t('workload.container.titles.podScheduling')" name="podScheduling" :weight="tabWeightMap['podScheduling']">
|
|
268
|
-
<PodAffinity :mode="mode" :value="podTemplateSpec" :nodes="allNodeObjects" />
|
|
278
|
+
<PodAffinity :mode="mode" :value="podTemplateSpec" :nodes="allNodeObjects" :loading="isLoadingSecondaryResources" />
|
|
269
279
|
</Tab>
|
|
270
280
|
<Tab :label="t('workload.container.titles.nodeScheduling')" name="nodeScheduling" :weight="tabWeightMap['nodeScheduling']">
|
|
271
|
-
<NodeScheduling :mode="mode" :value="podTemplateSpec" :nodes="allNodes" />
|
|
281
|
+
<NodeScheduling :mode="mode" :value="podTemplateSpec" :nodes="allNodes" :loading="isLoadingSecondaryResources" />
|
|
272
282
|
</Tab>
|
|
273
283
|
<Tab :label="t('workload.container.titles.upgrading')" name="upgrading" :weight="tabWeightMap['upgrading']">
|
|
274
284
|
<Job v-if="isJob || isCronJob" v-model="spec" :mode="mode" :type="type" />
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mapGetters } from 'vuex';
|
|
1
2
|
import omitBy from 'lodash/omitBy';
|
|
2
3
|
import { cleanUp } from '@shell/utils/object';
|
|
3
4
|
import {
|
|
@@ -13,7 +14,7 @@ import {
|
|
|
13
14
|
} from '@shell/config/types';
|
|
14
15
|
import Tab from '@shell/components/Tabbed/Tab';
|
|
15
16
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
16
|
-
import
|
|
17
|
+
import ResourceManager from '@shell/mixins/resource-manager';
|
|
17
18
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
18
19
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
19
20
|
import ServiceNameSelect from '@shell/components/form/ServiceNameSelect';
|
|
@@ -29,7 +30,7 @@ import WorkloadPorts from '@shell/components/form/WorkloadPorts';
|
|
|
29
30
|
import ContainerResourceLimit from '@shell/components/ContainerResourceLimit';
|
|
30
31
|
import KeyValue from '@shell/components/form/KeyValue';
|
|
31
32
|
import Tabbed from '@shell/components/Tabbed';
|
|
32
|
-
|
|
33
|
+
|
|
33
34
|
import NodeScheduling from '@shell/components/form/NodeScheduling';
|
|
34
35
|
import PodAffinity from '@shell/components/form/PodAffinity';
|
|
35
36
|
import Tolerations from '@shell/components/form/Tolerations';
|
|
@@ -94,7 +95,7 @@ export default {
|
|
|
94
95
|
ContainerMountPaths
|
|
95
96
|
},
|
|
96
97
|
|
|
97
|
-
mixins: [CreateEditView],
|
|
98
|
+
mixins: [CreateEditView, ResourceManager],
|
|
98
99
|
|
|
99
100
|
props: {
|
|
100
101
|
value: {
|
|
@@ -118,36 +119,11 @@ export default {
|
|
|
118
119
|
},
|
|
119
120
|
|
|
120
121
|
async fetch() {
|
|
121
|
-
|
|
122
|
-
const needed = {
|
|
123
|
-
configMaps: CONFIG_MAP,
|
|
124
|
-
nodes: NODE,
|
|
125
|
-
services: SERVICE,
|
|
126
|
-
pvcs: PVC,
|
|
127
|
-
sas: SERVICE_ACCOUNT,
|
|
128
|
-
secrets: SECRET,
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// Only fetch types if the user can see them
|
|
132
|
-
Object.keys(needed).forEach((key) => {
|
|
133
|
-
const type = needed[key];
|
|
134
|
-
|
|
135
|
-
if (this.$store.getters['cluster/schemaFor'](type)) {
|
|
136
|
-
requests[key] = this.$store.dispatch('cluster/findAll', { type });
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const hash = await allHash(requests);
|
|
122
|
+
await this.$store.dispatch('management/findAll', { type: CAPI.RANCHER_CLUSTER });
|
|
141
123
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
-
this.allConfigMaps = hash.configMaps || [];
|
|
146
|
-
this.allNodeObjects = hash.nodes || [];
|
|
147
|
-
this.allNodes = this.allNodeObjects.map(node => node.id);
|
|
148
|
-
this.allServices = hash.services || [];
|
|
149
|
-
this.pvcs = hash.pvcs || [];
|
|
150
|
-
this.sas = hash.sas || [];
|
|
124
|
+
// don't block UI for these resources
|
|
125
|
+
this.resourceManagerFetchSecondaryResources(this.secondaryResourceData);
|
|
126
|
+
this.servicesOwned = await this.value.getServicesOwned();
|
|
151
127
|
},
|
|
152
128
|
|
|
153
129
|
data() {
|
|
@@ -167,16 +143,21 @@ export default {
|
|
|
167
143
|
name: `container-0`,
|
|
168
144
|
}];
|
|
169
145
|
|
|
170
|
-
const
|
|
146
|
+
const metadata = { ...this.value.metadata };
|
|
147
|
+
|
|
148
|
+
const podSpec = { template: { spec: { containers: podContainers, initContainers: [] }, metadata } };
|
|
171
149
|
|
|
172
150
|
this.$set(this.value, 'spec', podSpec);
|
|
173
151
|
}
|
|
174
152
|
}
|
|
175
153
|
|
|
154
|
+
// EDIT view for POD
|
|
155
|
+
// Transform it from POD world to workload
|
|
176
156
|
if ((this.mode === _EDIT || this.mode === _VIEW ) && this.value.type === 'pod' ) {
|
|
177
157
|
const podSpec = { ...this.value.spec };
|
|
158
|
+
const metadata = { ...this.value.metadata };
|
|
178
159
|
|
|
179
|
-
this.$set(this.value.spec, 'template', { spec: podSpec });
|
|
160
|
+
this.$set(this.value.spec, 'template', { spec: podSpec, metadata });
|
|
180
161
|
}
|
|
181
162
|
|
|
182
163
|
const spec = this.value.spec;
|
|
@@ -228,37 +209,81 @@ export default {
|
|
|
228
209
|
this.selectContainer(container);
|
|
229
210
|
|
|
230
211
|
return {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
212
|
+
secondaryResourceData: {
|
|
213
|
+
namespace: this.value?.metadata?.namespace || null,
|
|
214
|
+
data: {
|
|
215
|
+
[CONFIG_MAP]: { applyTo: [{ var: 'namespacedConfigMaps' }] },
|
|
216
|
+
[PVC]: { applyTo: [{ var: 'pvcs' }] },
|
|
217
|
+
[SERVICE_ACCOUNT]: { applyTo: [{ var: 'namespacedServiceNames' }] },
|
|
218
|
+
[SECRET]: {
|
|
219
|
+
applyTo: [
|
|
220
|
+
{ var: 'namespacedSecrets' },
|
|
221
|
+
{
|
|
222
|
+
var: 'imagePullNamespacedSecrets',
|
|
223
|
+
parsingFunc: (data) => {
|
|
224
|
+
return data.filter(secret => (secret._type === SECRET_TYPES.DOCKER || secret._type === SECRET_TYPES.DOCKER_JSON));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
},
|
|
229
|
+
[NODE]: {
|
|
230
|
+
applyTo: [
|
|
231
|
+
{ var: 'allNodeObjects' },
|
|
232
|
+
{
|
|
233
|
+
var: 'allNodes',
|
|
234
|
+
parsingFunc: (data) => {
|
|
235
|
+
return data.map(node => node.id);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
]
|
|
239
|
+
},
|
|
240
|
+
[SERVICE]: {
|
|
241
|
+
applyTo: [
|
|
242
|
+
{ var: 'allServices' },
|
|
243
|
+
{
|
|
244
|
+
var: 'headlessServices',
|
|
245
|
+
parsingFunc: (data) => {
|
|
246
|
+
return data.filter(service => service.spec.clusterIP === 'None');
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
namespacedConfigMaps: [],
|
|
254
|
+
allNodes: null,
|
|
255
|
+
allNodeObjects: [],
|
|
256
|
+
namespacedSecrets: [],
|
|
257
|
+
imagePullNamespacedSecrets: [],
|
|
258
|
+
allServices: [],
|
|
259
|
+
headlessServices: [],
|
|
260
|
+
name: this.value?.metadata?.name || null,
|
|
261
|
+
pvcs: [],
|
|
262
|
+
namespacedServiceNames: [],
|
|
263
|
+
showTabs: false,
|
|
264
|
+
pullPolicyOptions: ['Always', 'IfNotPresent', 'Never'],
|
|
241
265
|
spec,
|
|
242
266
|
type,
|
|
243
|
-
servicesOwned:
|
|
244
|
-
servicesToRemove:
|
|
245
|
-
portsForServices:
|
|
267
|
+
servicesOwned: [],
|
|
268
|
+
servicesToRemove: [],
|
|
269
|
+
portsForServices: [],
|
|
246
270
|
isInitContainer,
|
|
247
271
|
container,
|
|
248
|
-
containerChange:
|
|
249
|
-
tabChange:
|
|
250
|
-
podFsGroup:
|
|
251
|
-
savePvcHookName:
|
|
252
|
-
tabWeightMap:
|
|
253
|
-
fvFormRuleSets:
|
|
272
|
+
containerChange: 0,
|
|
273
|
+
tabChange: 0,
|
|
274
|
+
podFsGroup: podTemplateSpec.securityContext?.fsGroup,
|
|
275
|
+
savePvcHookName: 'savePvcHook',
|
|
276
|
+
tabWeightMap: TAB_WEIGHT_MAP,
|
|
277
|
+
fvFormRuleSets: [{
|
|
254
278
|
path: 'image', rootObject: this.container, rules: ['required'], translationKey: 'workload.container.image'
|
|
255
279
|
}],
|
|
256
280
|
fvReportedValidationPaths: ['spec'],
|
|
257
|
-
|
|
281
|
+
isNamespaceNew: false,
|
|
258
282
|
};
|
|
259
283
|
},
|
|
260
284
|
|
|
261
285
|
computed: {
|
|
286
|
+
...mapGetters(['currentCluster']),
|
|
262
287
|
tabErrors() {
|
|
263
288
|
return { general: this.fvGetPathErrors(['image'])?.length > 0 };
|
|
264
289
|
},
|
|
@@ -326,13 +351,13 @@ export default {
|
|
|
326
351
|
}
|
|
327
352
|
|
|
328
353
|
return this.spec.jobTemplate.metadata.labels;
|
|
329
|
-
}
|
|
330
|
-
if (!this.spec.template.metadata) {
|
|
331
|
-
this.$set(this.spec.template, 'metadata', { labels: {} });
|
|
332
|
-
}
|
|
354
|
+
}
|
|
333
355
|
|
|
334
|
-
|
|
356
|
+
if (!this.spec.template.metadata) {
|
|
357
|
+
this.$set(this.spec.template, 'metadata', { labels: {} });
|
|
335
358
|
}
|
|
359
|
+
|
|
360
|
+
return this.spec.template.metadata.labels;
|
|
336
361
|
},
|
|
337
362
|
set(neu) {
|
|
338
363
|
if (this.isCronJob) {
|
|
@@ -351,13 +376,12 @@ export default {
|
|
|
351
376
|
}
|
|
352
377
|
|
|
353
378
|
return this.spec.jobTemplate.metadata.annotations;
|
|
354
|
-
} else {
|
|
355
|
-
if (!this.spec.template.metadata) {
|
|
356
|
-
this.$set(this.spec.template, 'metadata', { annotations: {} });
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
return this.spec.template.metadata.annotations;
|
|
360
379
|
}
|
|
380
|
+
if (!this.spec.template.metadata) {
|
|
381
|
+
this.$set(this.spec.template, 'metadata', { annotations: {} });
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return this.spec.template.metadata.annotations;
|
|
361
385
|
},
|
|
362
386
|
set(neu) {
|
|
363
387
|
if (this.isCronJob) {
|
|
@@ -467,55 +491,6 @@ export default {
|
|
|
467
491
|
return this.$store.getters['cluster/schemaFor'](this.type);
|
|
468
492
|
},
|
|
469
493
|
|
|
470
|
-
namespacedSecrets() {
|
|
471
|
-
const namespace = this.value?.metadata?.namespace;
|
|
472
|
-
|
|
473
|
-
if (namespace) {
|
|
474
|
-
return this.allSecrets.filter(
|
|
475
|
-
secret => secret.metadata.namespace === namespace
|
|
476
|
-
);
|
|
477
|
-
} else {
|
|
478
|
-
return this.allSecrets;
|
|
479
|
-
}
|
|
480
|
-
},
|
|
481
|
-
|
|
482
|
-
imagePullNamespacedSecrets() {
|
|
483
|
-
const namespace = this.value?.metadata?.namespace;
|
|
484
|
-
|
|
485
|
-
return this.allSecrets.filter(secret => secret.metadata.namespace === namespace && (secret._type === SECRET_TYPES.DOCKER || secret._type === SECRET_TYPES.DOCKER_JSON));
|
|
486
|
-
},
|
|
487
|
-
|
|
488
|
-
namespacedConfigMaps() {
|
|
489
|
-
const namespace = this.value?.metadata?.namespace;
|
|
490
|
-
|
|
491
|
-
if (namespace) {
|
|
492
|
-
return this.allConfigMaps.filter(
|
|
493
|
-
configMap => configMap.metadata.namespace === namespace
|
|
494
|
-
);
|
|
495
|
-
} else {
|
|
496
|
-
return this.allConfigMaps;
|
|
497
|
-
}
|
|
498
|
-
},
|
|
499
|
-
|
|
500
|
-
namespacedServiceNames() {
|
|
501
|
-
const { namespace } = this.value?.metadata;
|
|
502
|
-
|
|
503
|
-
if (namespace) {
|
|
504
|
-
return this.sas.filter(
|
|
505
|
-
serviceName => serviceName.metadata.namespace === namespace
|
|
506
|
-
);
|
|
507
|
-
} else {
|
|
508
|
-
return this.sas;
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
|
|
512
|
-
headlessServices() {
|
|
513
|
-
return this.allServices.filter(
|
|
514
|
-
service => service.spec.clusterIP === 'None' &&
|
|
515
|
-
service.metadata.namespace === this.value.metadata.namespace
|
|
516
|
-
);
|
|
517
|
-
},
|
|
518
|
-
|
|
519
494
|
workloadTypes() {
|
|
520
495
|
return omitBy(WORKLOAD_TYPES, (type) => {
|
|
521
496
|
return (
|
|
@@ -558,6 +533,25 @@ export default {
|
|
|
558
533
|
},
|
|
559
534
|
|
|
560
535
|
watch: {
|
|
536
|
+
async 'value.metadata.namespace'(neu) {
|
|
537
|
+
if (this.isNamespaceNew) {
|
|
538
|
+
// we don't need to re-fetch namespace specific (or non-namespace specific) resources when the namespace hasn't been created yet
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
this.secondaryResourceData.namespace = neu;
|
|
542
|
+
// Fetch resources that are namespace specific, we don't need to re-fetch non-namespaced resources on namespace change
|
|
543
|
+
this.resourceManagerFetchSecondaryResources(this.secondaryResourceData, true);
|
|
544
|
+
|
|
545
|
+
this.servicesOwned = await this.value.getServicesOwned();
|
|
546
|
+
},
|
|
547
|
+
|
|
548
|
+
isNamespaceNew(neu, old) {
|
|
549
|
+
if (!old && neu) {
|
|
550
|
+
// As the namespace is new any resource that's been fetched with a namespace is now invalid
|
|
551
|
+
this.resourceManagerClearSecondaryResources(this.secondaryResourceData, true);
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
|
|
561
555
|
type(neu, old) {
|
|
562
556
|
const template =
|
|
563
557
|
old === WORKLOAD_TYPES.CRON_JOB ? this.spec?.jobTemplate?.spec?.template : this.spec?.template;
|
|
@@ -689,6 +683,7 @@ export default {
|
|
|
689
683
|
template = this.spec.template;
|
|
690
684
|
}
|
|
691
685
|
|
|
686
|
+
// WORKLOADS
|
|
692
687
|
if (
|
|
693
688
|
this.type !== WORKLOAD_TYPES.JOB &&
|
|
694
689
|
this.type !== WORKLOAD_TYPES.CRON_JOB &&
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { PVC } from '@shell/config/types';
|
|
3
2
|
import ButtonDropdown from '@shell/components/ButtonDropdown';
|
|
4
3
|
import Mount from '@shell/edit/workload/storage/Mount';
|
|
5
4
|
import { _VIEW } from '@shell/config/query-params';
|
|
@@ -47,25 +46,25 @@ export default {
|
|
|
47
46
|
type: Array,
|
|
48
47
|
default: () => [],
|
|
49
48
|
},
|
|
49
|
+
namespacedPvcs: {
|
|
50
|
+
type: Array,
|
|
51
|
+
default: () => [],
|
|
52
|
+
},
|
|
50
53
|
|
|
51
54
|
registerBeforeHook: {
|
|
52
55
|
type: Function,
|
|
53
56
|
default: null,
|
|
54
57
|
},
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this.pvcs = await this.$store.dispatch('cluster/findAll', { type: PVC });
|
|
60
|
-
} else {
|
|
61
|
-
this.pvcs = [];
|
|
62
|
-
}
|
|
58
|
+
loading: {
|
|
59
|
+
default: false,
|
|
60
|
+
type: Boolean
|
|
61
|
+
},
|
|
63
62
|
},
|
|
64
63
|
|
|
65
64
|
data() {
|
|
66
65
|
this.initializeStorage();
|
|
67
66
|
|
|
68
|
-
return {
|
|
67
|
+
return {};
|
|
69
68
|
},
|
|
70
69
|
|
|
71
70
|
computed: {
|
|
@@ -73,12 +72,6 @@ export default {
|
|
|
73
72
|
return this.mode === _VIEW;
|
|
74
73
|
},
|
|
75
74
|
|
|
76
|
-
namespacedPVCs() {
|
|
77
|
-
const namespace = this.namespace || this.$store.getters['defaultNamespace'];
|
|
78
|
-
|
|
79
|
-
return this.pvcs.filter(pvc => pvc.metadata.namespace === namespace);
|
|
80
|
-
},
|
|
81
|
-
|
|
82
75
|
/**
|
|
83
76
|
* Generated list of volumes
|
|
84
77
|
*/
|
|
@@ -110,7 +103,7 @@ export default {
|
|
|
110
103
|
},
|
|
111
104
|
|
|
112
105
|
pvcNames() {
|
|
113
|
-
return this.
|
|
106
|
+
return this.namespacedPvcs.map(pvc => pvc.metadata.name);
|
|
114
107
|
},
|
|
115
108
|
},
|
|
116
109
|
|
|
@@ -270,6 +263,7 @@ export default {
|
|
|
270
263
|
:pvcs="pvcNames"
|
|
271
264
|
:register-before-hook="registerBeforeHook"
|
|
272
265
|
:save-pvc-hook-name="savePvcHookName"
|
|
266
|
+
:loading="loading"
|
|
273
267
|
@removePvcForm="removePvcForm"
|
|
274
268
|
/>
|
|
275
269
|
<div v-else-if="isView">
|
|
@@ -53,6 +53,10 @@ export default {
|
|
|
53
53
|
type: String,
|
|
54
54
|
required: true
|
|
55
55
|
},
|
|
56
|
+
loading: {
|
|
57
|
+
default: false,
|
|
58
|
+
type: Boolean
|
|
59
|
+
},
|
|
56
60
|
},
|
|
57
61
|
|
|
58
62
|
async fetch() {
|
|
@@ -129,6 +133,7 @@ export default {
|
|
|
129
133
|
:mode="mode"
|
|
130
134
|
:label="t('workload.storage.subtypes.persistentVolumeClaim')"
|
|
131
135
|
:options="pvcs"
|
|
136
|
+
:loading="loading"
|
|
132
137
|
/>
|
|
133
138
|
</div>
|
|
134
139
|
</div>
|
|
@@ -43,7 +43,10 @@ export default {
|
|
|
43
43
|
return {};
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
|
-
|
|
46
|
+
loading: {
|
|
47
|
+
default: false,
|
|
48
|
+
type: Boolean
|
|
49
|
+
},
|
|
47
50
|
},
|
|
48
51
|
|
|
49
52
|
computed: {
|
|
@@ -154,6 +157,7 @@ export default {
|
|
|
154
157
|
:mode="mode"
|
|
155
158
|
:required="true"
|
|
156
159
|
:label="t('workload.storage.subtypes.secret')"
|
|
160
|
+
:loading="loading"
|
|
157
161
|
/>
|
|
158
162
|
<LabeledSelect
|
|
159
163
|
v-else-if="type==='configMap'"
|
|
@@ -162,6 +166,7 @@ export default {
|
|
|
162
166
|
:required="true"
|
|
163
167
|
:mode="mode"
|
|
164
168
|
:label="t('workload.storage.subtypes.configMap')"
|
|
169
|
+
:loading="loading"
|
|
165
170
|
/>
|
|
166
171
|
</div>
|
|
167
172
|
<div class="col span-6">
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import ResourceTable from '@shell/components/ResourceTable';
|
|
3
|
-
import
|
|
3
|
+
import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
name: 'ListApps',
|
|
7
|
-
components: {
|
|
7
|
+
components: { ResourceTable },
|
|
8
|
+
mixins: [ResourceFetch],
|
|
8
9
|
|
|
9
10
|
props: {
|
|
10
11
|
resource: {
|
|
@@ -21,18 +22,18 @@ export default {
|
|
|
21
22
|
async fetch() {
|
|
22
23
|
await this.$store.dispatch('catalog/load');
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
data() {
|
|
28
|
-
return { rows: null };
|
|
25
|
+
await this.$fetchType(this.resource);
|
|
29
26
|
},
|
|
30
27
|
};
|
|
31
28
|
</script>
|
|
32
29
|
|
|
33
30
|
<template>
|
|
34
|
-
<
|
|
35
|
-
|
|
31
|
+
<ResourceTable
|
|
32
|
+
class="apps"
|
|
33
|
+
:schema="schema"
|
|
34
|
+
:rows="rows"
|
|
35
|
+
:loading="loading"
|
|
36
|
+
>
|
|
36
37
|
<template #cell:upgrade="{row}">
|
|
37
38
|
<span v-if="row.upgradeAvailable" class="badge-state bg-warning hand" @click="row.goToUpgrade(row.upgradeAvailable)">
|
|
38
39
|
{{ row.upgradeAvailable }}
|