mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-01 03:36:04 +08:00
Lint fixes
Signed-off-by: Francesco Torchia <francesco.torchia@suse.com>
This commit is contained in:
@@ -97,7 +97,10 @@ export default {
|
||||
color="error"
|
||||
:label="t('harvester.addons.nvidiaDriverToolkit.parsingSpecError', null, { raw: true })"
|
||||
/>
|
||||
<Tabbed v-else :side-tabs="true">
|
||||
<Tabbed
|
||||
v-else
|
||||
:side-tabs="true"
|
||||
>
|
||||
<Tab
|
||||
name="basic"
|
||||
:label="t('harvester.addons.nvidiaDriverToolkit.titles.basic')"
|
||||
@@ -113,7 +116,10 @@ export default {
|
||||
@update:value="toggleEnable"
|
||||
/>
|
||||
<div v-if="value.spec.enabled">
|
||||
<div v-if="valuesContentJson.image" class="row mb-15">
|
||||
<div
|
||||
v-if="valuesContentJson.image"
|
||||
class="row mb-15"
|
||||
>
|
||||
<div class="col span-6">
|
||||
<LabeledInput
|
||||
v-model:value="valuesContentJson.image.repo"
|
||||
|
||||
@@ -102,7 +102,12 @@ export default {
|
||||
:labels="[t('generic.enabled'), t('generic.disabled')]"
|
||||
/>
|
||||
</Tab>
|
||||
<Tab v-if="value.spec.enabled" name="fluentbit" :label="t('harvester.logging.configuration.section.fluentbit')" :weight="-1">
|
||||
<Tab
|
||||
v-if="value.spec.enabled"
|
||||
name="fluentbit"
|
||||
:label="t('harvester.logging.configuration.section.fluentbit')"
|
||||
:weight="-1"
|
||||
>
|
||||
<div class="row mt-20">
|
||||
<div class="col span-6">
|
||||
<LabeledInput
|
||||
@@ -140,7 +145,12 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab v-if="value.spec.enabled" name="fluentd" :label="t('harvester.logging.configuration.section.fluentd')" :weight="-1">
|
||||
<Tab
|
||||
v-if="value.spec.enabled"
|
||||
name="fluentd"
|
||||
:label="t('harvester.logging.configuration.section.fluentd')"
|
||||
:weight="-1"
|
||||
>
|
||||
<div class="row mt-20">
|
||||
<div class="col span-6">
|
||||
<LabeledInput
|
||||
|
||||
@@ -216,7 +216,12 @@ export default {
|
||||
:labels="[t('generic.enabled'), t('generic.disabled')]"
|
||||
/>
|
||||
</Tab>
|
||||
<Tab v-if="value.spec.enabled" name="prometheus" :label="t('harvester.setting.harvesterMonitoring.section.prometheus')" :weight="-1">
|
||||
<Tab
|
||||
v-if="value.spec.enabled"
|
||||
name="prometheus"
|
||||
:label="t('harvester.setting.harvesterMonitoring.section.prometheus')"
|
||||
:weight="-1"
|
||||
>
|
||||
<a
|
||||
v-clean-tooltip="!externalLinks.prometheus.enabled ? t('monitoring.overview.linkedList.na') : undefined"
|
||||
:disabled="!externalLinks.prometheus.enabled"
|
||||
@@ -325,7 +330,12 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab v-if="value.spec.enabled" name="nodeExporter" :label="t('harvester.setting.harvesterMonitoring.section.prometheusNodeExporter')" :weight="-2">
|
||||
<Tab
|
||||
v-if="value.spec.enabled"
|
||||
name="nodeExporter"
|
||||
:label="t('harvester.setting.harvesterMonitoring.section.prometheusNodeExporter')"
|
||||
:weight="-2"
|
||||
>
|
||||
<div class="row mt-10">
|
||||
<div class="col span-6">
|
||||
<LabeledInput
|
||||
@@ -363,7 +373,12 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab v-if="value.spec.enabled && valuesContentJson.grafana.resources" name="grafana" :label="t('harvester.setting.harvesterMonitoring.section.grafana')" :weight="-3">
|
||||
<Tab
|
||||
v-if="value.spec.enabled && valuesContentJson.grafana.resources"
|
||||
name="grafana"
|
||||
:label="t('harvester.setting.harvesterMonitoring.section.grafana')"
|
||||
:weight="-3"
|
||||
>
|
||||
<a
|
||||
v-clean-tooltip="!externalLinks.grafana.enabled ? t('monitoring.overview.linkedList.na') : undefined"
|
||||
:disabled="!externalLinks.grafana.enabled"
|
||||
@@ -425,7 +440,12 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab v-if="value.spec.enabled" name="alertmanager" :label="t('harvester.setting.harvesterMonitoring.section.alertmanager')" :weight="-4">
|
||||
<Tab
|
||||
v-if="value.spec.enabled"
|
||||
name="alertmanager"
|
||||
:label="t('harvester.setting.harvesterMonitoring.section.alertmanager')"
|
||||
:weight="-4"
|
||||
>
|
||||
<RadioGroup
|
||||
v-model:value="valuesContentJson.alertmanager.enabled"
|
||||
class="mb-20"
|
||||
|
||||
@@ -86,7 +86,7 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const storages = this.$store.getters[`${ inStore }/all`](STORAGE_CLASS);
|
||||
|
||||
const out = storages.filter(s => !s.parameters?.backingImage).map((s) => {
|
||||
const out = storages.filter((s) => !s.parameters?.backingImage).map((s) => {
|
||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
|
||||
return {
|
||||
@@ -106,7 +106,7 @@ export default {
|
||||
|
||||
setDefaultClassName() {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const defaultStorage = this.$store.getters[`${ inStore }/all`](STORAGE_CLASS).find( s => s.isDefault);
|
||||
const defaultStorage = this.$store.getters[`${ inStore }/all`](STORAGE_CLASS).find( (s) => s.isDefault);
|
||||
|
||||
this.valuesContent.pvcClaim['storageClassName'] = this.valuesContent?.pvcClaim?.storageClassName || defaultStorage?.metadata?.name || 'longhorn';
|
||||
|
||||
|
||||
@@ -83,13 +83,17 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
:namespaced="true"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<Tabbed :side-tabs="true">
|
||||
<Tab name="basics" :label="t('harvester.host.tabs.basics')" :weight="1">
|
||||
<Tab
|
||||
name="basics"
|
||||
:label="t('harvester.host.tabs.basics')"
|
||||
:weight="1"
|
||||
>
|
||||
<div class="mb-20">
|
||||
<LabeledSelect
|
||||
v-model:value="type"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<script>
|
||||
import { allHash } from '@shell/utils/promise';
|
||||
import { CSI_DRIVER, LONGHORN, LONGHORN_DRIVER, LONGHORN_VERSION_V1, LONGHORN_VERSION_V2 } from '@shell/config/types';
|
||||
import {
|
||||
CSI_DRIVER, LONGHORN, LONGHORN_DRIVER, LONGHORN_VERSION_V1, LONGHORN_VERSION_V2
|
||||
} from '@shell/config/types';
|
||||
import { LabeledInput } from '@components/Form/LabeledInput';
|
||||
import LabelValue from '@shell/components/LabelValue';
|
||||
import { BadgeState } from '@components/BadgeState';
|
||||
@@ -123,7 +125,7 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const lvmVolumeGroups = this.$store.getters[`${ inStore }/all`](HCI.LVM_VOLUME_GROUP) || [];
|
||||
|
||||
const out = lvmVolumeGroups.filter(group => group.spec.nodeName === this.node.name).map(g => g.spec.vgName);
|
||||
const out = lvmVolumeGroups.filter((group) => group.spec.nodeName === this.node.name).map((g) => g.spec.vgName);
|
||||
|
||||
out.unshift({
|
||||
label: this.t('harvester.host.disk.lvmVolumeGroup.create'),
|
||||
@@ -134,7 +136,7 @@ export default {
|
||||
},
|
||||
|
||||
targetDisk() {
|
||||
return this.disks.find(disk => disk.name === this.value.name);
|
||||
return this.disks.find((disk) => disk.name === this.value.name);
|
||||
},
|
||||
|
||||
schedulableTooltipMessage() {
|
||||
@@ -329,7 +331,10 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="disk" @update:value="update">
|
||||
<div
|
||||
class="disk"
|
||||
@update:value="update"
|
||||
>
|
||||
<div class="mt-10" />
|
||||
<Banner
|
||||
v-if="mountedMessage && isProvisioned"
|
||||
@@ -395,7 +400,10 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!value.isNew" class="row mt-30">
|
||||
<div
|
||||
v-if="!value.isNew"
|
||||
class="row mt-30"
|
||||
>
|
||||
<div class="col flex span-12">
|
||||
<LabelValue
|
||||
:name="t('harvester.host.disk.storageAvailable.label')"
|
||||
@@ -422,7 +430,7 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row mt-10">
|
||||
<div :class="`col span-${ value.isNew ? '6': '12' }`">
|
||||
<LabeledSelect
|
||||
@@ -437,7 +445,10 @@ export default {
|
||||
@keydown.native.enter.prevent="()=>{}"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="(value.isNew && isLonghornV1 && !isFormatted) || isCorrupted" class="col span-6">
|
||||
<div
|
||||
v-if="(value.isNew && isLonghornV1 && !isFormatted) || isCorrupted"
|
||||
class="col span-6"
|
||||
>
|
||||
<RadioGroup
|
||||
v-model:value="value.forceFormatted"
|
||||
:mode="mode"
|
||||
@@ -459,7 +470,10 @@ export default {
|
||||
</template>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
<div v-if="value.isNew && isLvm" class="col span-6">
|
||||
<div
|
||||
v-if="value.isNew && isLvm"
|
||||
class="col span-6"
|
||||
>
|
||||
<LabeledSelect
|
||||
v-model:value="value.lvmVolumeGroup"
|
||||
:mode="mode"
|
||||
|
||||
@@ -136,10 +136,20 @@ export default {
|
||||
class="mb-20"
|
||||
/>
|
||||
|
||||
<Checkbox v-model:value="enableMergeAcrossNodes" :mode="mode" class="check mb-20" type="checkbox" :label="t('harvester.host.ksmtuned.enableMergeNodes')" />
|
||||
<Checkbox
|
||||
v-model:value="enableMergeAcrossNodes"
|
||||
:mode="mode"
|
||||
class="check mb-20"
|
||||
type="checkbox"
|
||||
:label="t('harvester.host.ksmtuned.enableMergeNodes')"
|
||||
/>
|
||||
|
||||
<h3>
|
||||
<t k="harvester.host.ksmtuned.modeLink" :raw="true" :url="ksmtunedLink" />
|
||||
<t
|
||||
k="harvester.host.ksmtuned.modeLink"
|
||||
:raw="true"
|
||||
:url="ksmtunedLink"
|
||||
/>
|
||||
</h3>
|
||||
<RadioGroup
|
||||
v-model:value="spec.mode"
|
||||
|
||||
@@ -250,7 +250,9 @@ export default {
|
||||
<div>
|
||||
<div v-if="inventory.warningMessages.length > 0">
|
||||
<Banner
|
||||
v-for="(msg, i) in inventory.warningMessages" :key="i" color="error"
|
||||
v-for="(msg, i) in inventory.warningMessages"
|
||||
:key="i"
|
||||
color="error"
|
||||
:label="msg.text"
|
||||
/>
|
||||
</div>
|
||||
@@ -343,9 +345,9 @@ export default {
|
||||
<template #content>
|
||||
<NameNsDescription
|
||||
:value="secret"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:namespaced="true"
|
||||
mode="create"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<LabeledInput
|
||||
|
||||
@@ -9,7 +9,9 @@ import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
|
||||
import ButtonDropdown from '@shell/components/ButtonDropdown';
|
||||
import CreateEditView from '@shell/mixins/create-edit-view';
|
||||
import { HCI as HCI_LABELS_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
|
||||
import { LONGHORN, SECRET, LONGHORN_DRIVER, LONGHORN_VERSION_V1, LONGHORN_VERSION_V2 } from '@shell/config/types';
|
||||
import {
|
||||
LONGHORN, SECRET, LONGHORN_DRIVER, LONGHORN_VERSION_V1, LONGHORN_VERSION_V2
|
||||
} from '@shell/config/types';
|
||||
import { allHash } from '@shell/utils/promise';
|
||||
import { formatSi } from '@shell/utils/units';
|
||||
import { findBy } from '@shell/utils/array';
|
||||
@@ -37,7 +39,7 @@ export const LONGHORN_SYSTEM = 'longhorn-system';
|
||||
export const LONGHORN_V2_DATA_ENGINE = 'longhorn-system/v2-data-engine';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEditNode',
|
||||
name: 'HarvesterEditNode',
|
||||
|
||||
emits: ['update:value'],
|
||||
|
||||
@@ -58,9 +60,9 @@ export default {
|
||||
HarvesterSeeder,
|
||||
MessageLink,
|
||||
},
|
||||
mixins: [CreateEditView],
|
||||
mixins: [CreateEditView],
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
required: true,
|
||||
@@ -114,7 +116,7 @@ export default {
|
||||
this.blockDeviceOpts = this.getBlockDeviceOpts();
|
||||
|
||||
const addons = this.$store.getters[`${ inStore }/all`](HCI.ADD_ONS);
|
||||
const seeder = addons.find(addon => addon.id === `harvester-system/${ ADD_ONS.HARVESTER_SEEDER }`);
|
||||
const seeder = addons.find((addon) => addon.id === `harvester-system/${ ADD_ONS.HARVESTER_SEEDER }`);
|
||||
|
||||
const seederEnabled = seeder ? seeder?.spec?.enabled : false;
|
||||
|
||||
@@ -122,7 +124,7 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const inventories = this.$store.getters[`${ inStore }/all`](HCI.INVENTORY) || [];
|
||||
|
||||
const inventory = inventories.find(inv => inv.id === `harvester-system/${ this.value.id }`);
|
||||
const inventory = inventories.find((inv) => inv.id === `harvester-system/${ this.value.id }`);
|
||||
|
||||
if (inventory) {
|
||||
this.inventory = await this.$store.dispatch(`${ inStore }/clone`, { resource: inventory });
|
||||
@@ -214,7 +216,7 @@ export default {
|
||||
},
|
||||
|
||||
showFormattedWarning() {
|
||||
const out = this.newDisks.filter(d => d.forceFormatted && d.isNew && d.provisionerVersion === LONGHORN_VERSION_V1) || [];
|
||||
const out = this.newDisks.filter((d) => d.forceFormatted && d.isNew && d.provisionerVersion === LONGHORN_VERSION_V1) || [];
|
||||
|
||||
return out.length > 0;
|
||||
},
|
||||
@@ -235,13 +237,13 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const longhornNodes = this.$store.getters[`${ inStore }/all`](LONGHORN.NODES);
|
||||
|
||||
return longhornNodes.find(node => node.id === `${ LONGHORN_SYSTEM }/${ this.value.id }`);
|
||||
return longhornNodes.find((node) => node.id === `${ LONGHORN_SYSTEM }/${ this.value.id }`);
|
||||
},
|
||||
|
||||
seederEnabled() {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const addons = this.$store.getters[`${ inStore }/all`](HCI.ADD_ONS);
|
||||
const seeder = addons.find(addon => addon.id === `harvester-system/${ ADD_ONS.HARVESTER_SEEDER }`);
|
||||
const seeder = addons.find((addon) => addon.id === `harvester-system/${ ADD_ONS.HARVESTER_SEEDER }`);
|
||||
|
||||
return seeder ? seeder?.spec?.enabled : false;
|
||||
},
|
||||
@@ -271,7 +273,7 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const addons = this.$store.getters[`${ inStore }/all`](HCI.ADD_ONS);
|
||||
|
||||
return addons.find(addon => addon.id === `harvester-system/${ ADD_ONS.HARVESTER_SEEDER }`);
|
||||
return addons.find((addon) => addon.id === `harvester-system/${ ADD_ONS.HARVESTER_SEEDER }`);
|
||||
},
|
||||
|
||||
hasInventorySchema() {
|
||||
@@ -350,8 +352,8 @@ export default {
|
||||
|
||||
async saveDisk() {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const addDisks = this.newDisks.filter(d => d.isNew);
|
||||
const removeDisks = this.disks.filter(d => !findBy(this.newDisks, 'name', d.name) && d.blockDevice);
|
||||
const addDisks = this.newDisks.filter((d) => d.isNew);
|
||||
const removeDisks = this.disks.filter((d) => !findBy(this.newDisks, 'name', d.name) && d.blockDevice);
|
||||
|
||||
if (addDisks.length === 0 && removeDisks.length === 0) {
|
||||
return Promise.resolve();
|
||||
@@ -459,7 +461,7 @@ export default {
|
||||
const sizeBytes = d.status?.deviceStatus?.capacity?.sizeBytes;
|
||||
const size = formatSi(sizeBytes, { increment: 1024 });
|
||||
const parentDevice = d.status?.deviceStatus?.parentDevice;
|
||||
const isChildAdded = this.newDisks.find(newDisk => newDisk.blockDevice?.status?.deviceStatus?.parentDevice === devPath);
|
||||
const isChildAdded = this.newDisks.find((newDisk) => newDisk.blockDevice?.status?.deviceStatus?.parentDevice === devPath);
|
||||
const name = d.displayName;
|
||||
|
||||
let label = `${ name } (Type: ${ deviceType }, Size: ${ size })`;
|
||||
@@ -528,7 +530,7 @@ export default {
|
||||
opt: { force: true },
|
||||
});
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, '5000'));
|
||||
await new Promise((resolve) => setTimeout(resolve, '5000'));
|
||||
await retrySave();
|
||||
} else {
|
||||
return Promise.reject(exceptionToErrorsArray(err));
|
||||
@@ -545,16 +547,27 @@ export default {
|
||||
</script>
|
||||
<template>
|
||||
<Loading v-if="$fetchState.pending" />
|
||||
<div v-else id="node">
|
||||
<div
|
||||
v-else
|
||||
id="node"
|
||||
>
|
||||
<div class="content">
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:namespaced="false"
|
||||
:mode="mode"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
<Tabbed ref="tabbed" class="mt-15" :side-tabs="true">
|
||||
<Tab name="basics" :weight="100" :label="t('harvester.host.tabs.basics')">
|
||||
<Tabbed
|
||||
ref="tabbed"
|
||||
class="mt-15"
|
||||
:side-tabs="true"
|
||||
>
|
||||
<Tab
|
||||
name="basics"
|
||||
:weight="100"
|
||||
:label="t('harvester.host.tabs.basics')"
|
||||
>
|
||||
<LabeledInput
|
||||
v-model:value="customName"
|
||||
:label="t('harvester.host.detail.customName')"
|
||||
@@ -637,8 +650,17 @@ export default {
|
||||
</template>
|
||||
</ArrayListGrouped>
|
||||
</Tab>
|
||||
<Tab v-if="hasKsmtunedSchema" name="Ksmtuned" :weight="70" :label="t('harvester.host.tabs.ksmtuned')">
|
||||
<HarvesterKsmtuned :mode="mode" :node="value" :register-before-hook="registerBeforeHook" />
|
||||
<Tab
|
||||
v-if="hasKsmtunedSchema"
|
||||
name="Ksmtuned"
|
||||
:weight="70"
|
||||
:label="t('harvester.host.tabs.ksmtuned')"
|
||||
>
|
||||
<HarvesterKsmtuned
|
||||
:mode="mode"
|
||||
:node="value"
|
||||
:register-before-hook="registerBeforeHook"
|
||||
/>
|
||||
</Tab>
|
||||
<Tab
|
||||
v-if="hasAddonSchema"
|
||||
@@ -678,7 +700,10 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab name="labels" label-key="harvester.host.tabs.labels">
|
||||
<Tab
|
||||
name="labels"
|
||||
label-key="harvester.host.tabs.labels"
|
||||
>
|
||||
<KeyValue
|
||||
key="labels"
|
||||
:value="filteredLabels"
|
||||
@@ -697,7 +722,13 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Footer class="footer" :mode="mode" :errors="errors" @save="save" @done="done" />
|
||||
<Footer
|
||||
class="footer"
|
||||
:mode="mode"
|
||||
:errors="errors"
|
||||
@save="save"
|
||||
@done="done"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -90,12 +90,21 @@ export default {
|
||||
ref="nd"
|
||||
:key="randomString"
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<Tabbed v-bind="$attrs" class="mt-15" :side-tabs="true">
|
||||
<Tab name="basic" :label="t('harvester.sshKey.tabs.basics')" :weight="1" class="bordered-table">
|
||||
<Tabbed
|
||||
v-bind="$attrs"
|
||||
class="mt-15"
|
||||
:side-tabs="true"
|
||||
>
|
||||
<Tab
|
||||
name="basic"
|
||||
:label="t('harvester.sshKey.tabs.basics')"
|
||||
:weight="1"
|
||||
class="bordered-table"
|
||||
>
|
||||
<LabeledInput
|
||||
v-model:value="publicKey"
|
||||
type="multiline"
|
||||
|
||||
@@ -13,7 +13,7 @@ export default {
|
||||
this.registerBeforeHook(this.willSave, 'willSave');
|
||||
this.registerAfterHook(() => {
|
||||
const allNamespaces = this.$store.getters['allNamespaces'];
|
||||
const defaultNamepsace = allNamespaces.find(N => N.id === 'default');
|
||||
const defaultNamepsace = allNamespaces.find((N) => N.id === 'default');
|
||||
const ns = defaultNamepsace?.id || allNamespaces?.[0]?.id || '';
|
||||
|
||||
this.value.$dispatch('prefs/set', { key: LAST_NAMESPACE, value: ns }, { root: true });
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
|
||||
this.registerAfterHook(() => {
|
||||
const allNamespaces = this.$store.getters['allNamespaces'];
|
||||
const defaultNamepsace = allNamespaces.find(N => N.id === 'default');
|
||||
const defaultNamepsace = allNamespaces.find((N) => N.id === 'default');
|
||||
const ns = defaultNamepsace?.id || allNamespaces?.[0]?.id || '';
|
||||
|
||||
this.value.$dispatch('prefs/set', { key: LAST_NAMESPACE, value: ns }, { root: true });
|
||||
|
||||
@@ -77,7 +77,7 @@ export default {
|
||||
|
||||
set(this.value, 'spec', this.value.spec || {});
|
||||
|
||||
const providers = PROVIDERS.map(provider => ({
|
||||
const providers = PROVIDERS.map((provider) => ({
|
||||
...provider,
|
||||
value: provider.name,
|
||||
label: this.t(provider.labelKey)
|
||||
@@ -117,7 +117,7 @@ export default {
|
||||
return EDITOR_MODES;
|
||||
},
|
||||
enabledProviders() {
|
||||
return this.providers.filter(p => p.enabled);
|
||||
return this.providers.filter((p) => p.enabled);
|
||||
},
|
||||
cruMode() {
|
||||
if (this.selectedProviders.length > 1 || !this.value.allProvidersSupported) {
|
||||
@@ -192,20 +192,35 @@ export default {
|
||||
<NameNsDescription
|
||||
v-if="!isView"
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
label="generic.name"
|
||||
:register-before-hook="registerBeforeHook"
|
||||
:namespaced="value.type !== LOGGING.CLUSTER_OUTPUT"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
<Banner v-if="selectedProviders.length > 1" color="info">
|
||||
<Banner
|
||||
v-if="selectedProviders.length > 1"
|
||||
color="info"
|
||||
>
|
||||
{{ t('logging.output.tips.singleProvider') }}
|
||||
</Banner>
|
||||
<Banner v-else-if="!value.allProvidersSupported" color="info">
|
||||
<Banner
|
||||
v-else-if="!value.allProvidersSupported"
|
||||
color="info"
|
||||
>
|
||||
{{ t('logging.output.tips.multipleProviders') }}
|
||||
</Banner>
|
||||
<Tabbed v-else ref="tabbed" :side-tabs="true" @changed="tabChanged($event)">
|
||||
<Tab name="Output" label="Output" :weight="2">
|
||||
<Tabbed
|
||||
v-else
|
||||
ref="tabbed"
|
||||
:side-tabs="true"
|
||||
@changed="tabChanged($event)"
|
||||
>
|
||||
<Tab
|
||||
name="Output"
|
||||
label="Output"
|
||||
:weight="2"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col span-6">
|
||||
<LabeledSelect
|
||||
@@ -220,13 +235,27 @@ export default {
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col span-6">
|
||||
<LabeledSelect v-model:value="selectedProvider" label="Output" :options="providers" :mode="mode" />
|
||||
<LabeledSelect
|
||||
v-model:value="selectedProvider"
|
||||
label="Output"
|
||||
:options="providers"
|
||||
:mode="mode"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<component :is="getComponent(selectedProvider)" :value="value.spec[selectedProvider]" :namespace="value.namespace" :mode="mode" />
|
||||
<component
|
||||
:is="getComponent(selectedProvider)"
|
||||
:value="value.spec[selectedProvider]"
|
||||
:namespace="value.namespace"
|
||||
:mode="mode"
|
||||
/>
|
||||
</Tab>
|
||||
<Tab name="buffer" :label="t('logging.output.buffer.label')" :weight="1">
|
||||
<Tab
|
||||
name="buffer"
|
||||
:label="t('logging.output.buffer.label')"
|
||||
:weight="1"
|
||||
>
|
||||
<YamlEditor
|
||||
ref="yaml"
|
||||
v-model:value="bufferYaml"
|
||||
|
||||
@@ -16,7 +16,7 @@ import { _CREATE, _EDIT, _VIEW, _CONFIG } from '@shell/config/query-params';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: {
|
||||
ActionMenu,
|
||||
CruResource,
|
||||
@@ -54,7 +54,7 @@ export default {
|
||||
const defaultReceiverValues = {};
|
||||
const receiverSchema = this.$store.getters['harvester/schemaFor'](MONITORING.SPOOFED.ALERTMANAGERCONFIG_RECEIVER_SPEC);
|
||||
const routeSchema = this.$store.getters['harvester/schemaFor'](MONITORING.SPOOFED.ALERTMANAGERCONFIG_ROUTE_SPEC);
|
||||
const receiverOptions = (this.value?.spec?.receivers || []).map(receiver => receiver.name);
|
||||
const receiverOptions = (this.value?.spec?.receivers || []).map((receiver) => receiver.name);
|
||||
|
||||
return {
|
||||
actionMenuTargetElement: null,
|
||||
@@ -195,9 +195,9 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
:namespaced="isNamespaced"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<Tabbed>
|
||||
|
||||
@@ -17,7 +17,7 @@ const MANUAL = 'manual';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: {
|
||||
Tab,
|
||||
Tabbed,
|
||||
@@ -191,11 +191,20 @@ export default {
|
||||
<NameNsDescription
|
||||
ref="nd"
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
<Tabbed v-bind="$attrs" class="mt-15" :side-tabs="true">
|
||||
<Tab name="basics" :label="t('harvester.network.tabs.basics')" :weight="99" class="bordered-table">
|
||||
<Tabbed
|
||||
v-bind="$attrs"
|
||||
class="mt-15"
|
||||
:side-tabs="true"
|
||||
>
|
||||
<Tab
|
||||
name="basics"
|
||||
:label="t('harvester.network.tabs.basics')"
|
||||
:weight="99"
|
||||
class="bordered-table"
|
||||
>
|
||||
<LabeledSelect
|
||||
v-model:value="type"
|
||||
class="mb-20"
|
||||
|
||||
@@ -73,7 +73,7 @@ export default {
|
||||
cron: '',
|
||||
retain: 8,
|
||||
maxFailure: 4,
|
||||
vmbackup: {
|
||||
vmbackup: {
|
||||
source: {
|
||||
apiGroup: 'kubevirt.io',
|
||||
kind: 'VirtualMachine',
|
||||
@@ -90,7 +90,7 @@ export default {
|
||||
|
||||
computed: {
|
||||
backupTargetResource() {
|
||||
return this.settings.find( O => O.id === 'backup-target');
|
||||
return this.settings.find( (O) => O.id === 'backup-target');
|
||||
},
|
||||
isEmptyValue() {
|
||||
return this.getBackupTargetValueIsEmpty(this.backupTargetResource);
|
||||
@@ -112,8 +112,8 @@ export default {
|
||||
return this.value.spec.vmbackup.type === BACKUP_TYPE.BACKUP && (this.errorMessage || this.isEmptyValue) && this.canUpdate;
|
||||
},
|
||||
vmOptions() {
|
||||
const nsVmList = this.$store.getters['harvester/all'](HCI.VM).filter(vm => vm.metadata.namespace === this.value.metadata.namespace);
|
||||
const vmObjectLists = nsVmList.map(obj => ({
|
||||
const nsVmList = this.$store.getters['harvester/all'](HCI.VM).filter((vm) => vm.metadata.namespace === this.value.metadata.namespace);
|
||||
const vmObjectLists = nsVmList.map((obj) => ({
|
||||
label: obj.nameDisplay,
|
||||
value: obj.name,
|
||||
}));
|
||||
@@ -196,7 +196,7 @@ export default {
|
||||
:mode="mode"
|
||||
:errors="errors"
|
||||
:apply-hooks="applyHooks"
|
||||
:validationPassed="canSave"
|
||||
:validation-passed="canSave"
|
||||
@finish="save"
|
||||
@error="e=>errors = e"
|
||||
>
|
||||
@@ -258,8 +258,17 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Tabbed v-bind="$attrs" class="mt-15" :side-tabs="true">
|
||||
<Tab name="basics" :label="t('harvester.network.tabs.basics')" :weight="99" class="bordered-table">
|
||||
<Tabbed
|
||||
v-bind="$attrs"
|
||||
class="mt-15"
|
||||
:side-tabs="true"
|
||||
>
|
||||
<Tab
|
||||
name="basics"
|
||||
:label="t('harvester.network.tabs.basics')"
|
||||
:weight="99"
|
||||
class="bordered-table"
|
||||
>
|
||||
<LabeledInput
|
||||
v-model:value="value.spec.cron"
|
||||
class="mb-30"
|
||||
|
||||
@@ -160,7 +160,7 @@ export default {
|
||||
created() {
|
||||
this.registerAfterHook(() => {
|
||||
const allNamespaces = this.$store.getters['allNamespaces'];
|
||||
const defaultNamepsace = allNamespaces.find(N => N.id === 'default');
|
||||
const defaultNamepsace = allNamespaces.find((N) => N.id === 'default');
|
||||
const ns = defaultNamepsace?.id || allNamespaces?.[0]?.id || '';
|
||||
|
||||
this.value.$dispatch('prefs/set', { key: LAST_NAMESPACE, value: ns }, { root: true });
|
||||
@@ -238,9 +238,9 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
:namespaced="!isCloud"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<div class="spacer" />
|
||||
|
||||
@@ -31,7 +31,7 @@ export default {
|
||||
let enumOptions = [];
|
||||
|
||||
if (setting.kind === 'enum') {
|
||||
enumOptions = setting.options.map(id => ({
|
||||
enumOptions = setting.options.map((id) => ({
|
||||
label: `advancedSettings.enum.harv-${ this.value.id }.${ id }`,
|
||||
value: id
|
||||
}));
|
||||
@@ -53,7 +53,7 @@ export default {
|
||||
const customSettingComponents = require
|
||||
.context('../components/settings', false, /^.*\.vue$/)
|
||||
.keys()
|
||||
.map(path => path.replace(/(\.\/)|(.vue)/g, ''));
|
||||
.map((path) => path.replace(/(\.\/)|(.vue)/g, ''));
|
||||
|
||||
return {
|
||||
setting,
|
||||
@@ -183,7 +183,11 @@ export default {
|
||||
>
|
||||
<h4 v-clean-html="description"></h4>
|
||||
|
||||
<h5 v-if="editHelp" v-clean-html="editHelp" class="edit-help" />
|
||||
<h5
|
||||
v-if="editHelp"
|
||||
v-clean-html="editHelp"
|
||||
class="edit-help"
|
||||
/>
|
||||
|
||||
<div class="edit-change mt-20">
|
||||
<h5 v-t="'advancedSettings.edit.changeSetting'" />
|
||||
@@ -229,7 +233,10 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="setting.kind === 'multiline' || setting.kind === 'json'">
|
||||
<TextAreaAutoGrow v-model:value="value.value" :min-height="254" />
|
||||
<TextAreaAutoGrow
|
||||
v-model:value="value.value"
|
||||
:min-height="254"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<LabeledInput
|
||||
|
||||
@@ -13,7 +13,9 @@ import Loading from '@shell/components/Loading';
|
||||
|
||||
import { _CREATE, _VIEW } from '@shell/config/query-params';
|
||||
import { mapFeature, UNSUPPORTED_STORAGE_DRIVERS } from '@shell/store/features';
|
||||
import { STORAGE_CLASS, LONGHORN, LONGHORN_DRIVER, SECRET, NAMESPACE } from '@shell/config/types';
|
||||
import {
|
||||
STORAGE_CLASS, LONGHORN, LONGHORN_DRIVER, SECRET, NAMESPACE
|
||||
} from '@shell/config/types';
|
||||
import { allHash } from '@shell/utils/promise';
|
||||
import { clone } from '@shell/utils/object';
|
||||
import { CSI_DRIVER } from '../../types';
|
||||
@@ -84,7 +86,7 @@ export default {
|
||||
}
|
||||
];
|
||||
|
||||
const allowedTopologies = clone(this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).filter(t => t.key !== LVM_TOPOLOGY_LABEL);
|
||||
const allowedTopologies = clone(this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).filter((t) => t.key !== LVM_TOPOLOGY_LABEL);
|
||||
|
||||
this.value['parameters'] = this.value.parameters || {};
|
||||
this.value['provisioner'] = this.value.provisioner || LONGHORN_DRIVER;
|
||||
@@ -200,7 +202,7 @@ export default {
|
||||
let parameters = {};
|
||||
|
||||
if (provisioner === LVM_DRIVER) {
|
||||
const matchLabelExpressions = (this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).filter(t => t.key !== LVM_TOPOLOGY_LABEL);
|
||||
const matchLabelExpressions = (this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).filter((t) => t.key !== LVM_TOPOLOGY_LABEL);
|
||||
|
||||
if (matchLabelExpressions.length > 0) {
|
||||
this.value['allowedTopologies'] = [{ matchLabelExpressions }];
|
||||
@@ -246,8 +248,8 @@ export default {
|
||||
},
|
||||
|
||||
formatAllowedTopoloties() {
|
||||
const neu = this.allowedTopologies.filter(t => t.key !== LVM_TOPOLOGY_LABEL);
|
||||
const lvmMatchExpression = (this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).filter(t => t.key === LVM_TOPOLOGY_LABEL);
|
||||
const neu = this.allowedTopologies.filter((t) => t.key !== LVM_TOPOLOGY_LABEL);
|
||||
const lvmMatchExpression = (this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).filter((t) => t.key === LVM_TOPOLOGY_LABEL);
|
||||
|
||||
if (!neu || neu.length === 0) {
|
||||
if (lvmMatchExpression.length > 0) {
|
||||
@@ -259,7 +261,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const matchLabelExpressions = neu.filter(R => !!R.key.trim() && (R.values.length > 0 && !R.values.find(V => !V.trim())));
|
||||
const matchLabelExpressions = neu.filter((R) => !!R.key.trim() && (R.values.length > 0 && !R.values.find((V) => !V.trim())));
|
||||
|
||||
if (matchLabelExpressions.length > 0) {
|
||||
this.value.allowedTopologies = [{ matchLabelExpressions: [...matchLabelExpressions, ...lvmMatchExpression] }];
|
||||
@@ -287,9 +289,9 @@ export default {
|
||||
<NameNsDescription
|
||||
:namespaced="false"
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
:register-before-hook="registerBeforeHook"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
<LabeledSelect
|
||||
v-model:value="provisioner"
|
||||
@@ -302,7 +304,11 @@ export default {
|
||||
class="mb-20"
|
||||
/>
|
||||
<Tabbed :side-tabs="true">
|
||||
<Tab name="parameters" :label="t('storageClass.parameters.label')" :weight="2">
|
||||
<Tab
|
||||
name="parameters"
|
||||
:label="t('storageClass.parameters.label')"
|
||||
:weight="2"
|
||||
>
|
||||
<component
|
||||
:is="getComponent(provisioner)"
|
||||
:key="provisioner"
|
||||
@@ -311,7 +317,10 @@ export default {
|
||||
:real-mode="realMode"
|
||||
/>
|
||||
</Tab>
|
||||
<Tab name="customize" :label="t('storageClass.customize.label')">
|
||||
<Tab
|
||||
name="customize"
|
||||
:label="t('storageClass.customize.label')"
|
||||
>
|
||||
<div class="row mt-20">
|
||||
<div class="col span-6">
|
||||
<RadioGroup
|
||||
|
||||
@@ -78,7 +78,7 @@ export default {
|
||||
const allSecrets = this.$store.getters[`${ inStore }/all`](SECRET);
|
||||
|
||||
// only show non-system secret to user to select
|
||||
return allSecrets.filter(secret => secret.isSystem === false);
|
||||
return allSecrets.filter((secret) => secret.isSystem === false);
|
||||
},
|
||||
|
||||
longhornNodes() {
|
||||
@@ -124,7 +124,7 @@ export default {
|
||||
},
|
||||
|
||||
secretOptions() {
|
||||
return this.secrets.map(secret => secret.id);
|
||||
return this.secrets.map((secret) => secret.id);
|
||||
},
|
||||
|
||||
volumeEncryptionOptions() {
|
||||
@@ -282,7 +282,10 @@ export default {
|
||||
:mode="mode"
|
||||
>
|
||||
<template #no-options="{ searching }">
|
||||
<span v-if="!searching" class="text-muted">
|
||||
<span
|
||||
v-if="!searching"
|
||||
class="text-muted"
|
||||
>
|
||||
{{ t('harvester.storage.parameters.nodeSelector.no-options', null, true) }}
|
||||
</span>
|
||||
</template>
|
||||
@@ -298,7 +301,10 @@ export default {
|
||||
:mode="mode"
|
||||
>
|
||||
<template #no-options="{ searching }">
|
||||
<span v-if="!searching" class="text-muted">
|
||||
<span
|
||||
v-if="!searching"
|
||||
class="text-muted"
|
||||
>
|
||||
{{ t('harvester.storage.parameters.diskSelector.no-options', null, true) }}
|
||||
</span>
|
||||
</template>
|
||||
@@ -323,7 +329,10 @@ export default {
|
||||
:options="volumeEncryptionOptions"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="value.parameters.encrypted === 'true'" class="row mt-20">
|
||||
<div
|
||||
v-if="value.parameters.encrypted === 'true'"
|
||||
class="row mt-20"
|
||||
>
|
||||
<div class="col span-6">
|
||||
<LabeledSelect
|
||||
v-model:value="secret"
|
||||
|
||||
@@ -78,7 +78,7 @@ export default {
|
||||
const allSecrets = this.$store.getters[`${ inStore }/all`](SECRET);
|
||||
|
||||
// only show non-system secret to user to select
|
||||
return allSecrets.filter(secret => secret.isSystem === false);
|
||||
return allSecrets.filter((secret) => secret.isSystem === false);
|
||||
},
|
||||
|
||||
longhornNodes() {
|
||||
@@ -124,7 +124,7 @@ export default {
|
||||
},
|
||||
|
||||
secretOptions() {
|
||||
return this.secrets.map(secret => secret.id);
|
||||
return this.secrets.map((secret) => secret.id);
|
||||
},
|
||||
|
||||
volumeEncryptionOptions() {
|
||||
@@ -282,7 +282,10 @@ export default {
|
||||
:mode="mode"
|
||||
>
|
||||
<template #no-options="{ searching }">
|
||||
<span v-if="!searching" class="text-muted">
|
||||
<span
|
||||
v-if="!searching"
|
||||
class="text-muted"
|
||||
>
|
||||
{{ t('harvester.storage.parameters.nodeSelector.no-options', null, true) }}
|
||||
</span>
|
||||
</template>
|
||||
@@ -298,7 +301,10 @@ export default {
|
||||
:mode="mode"
|
||||
>
|
||||
<template #no-options="{ searching }">
|
||||
<span v-if="!searching" class="text-muted">
|
||||
<span
|
||||
v-if="!searching"
|
||||
class="text-muted"
|
||||
>
|
||||
{{ t('harvester.storage.parameters.diskSelector.no-options', null, true) }}
|
||||
</span>
|
||||
</template>
|
||||
@@ -325,7 +331,10 @@ export default {
|
||||
:disabled="true"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="value.parameters.encrypted === 'true'" class="row mt-20">
|
||||
<div
|
||||
v-if="value.parameters.encrypted === 'true'"
|
||||
class="row mt-20"
|
||||
>
|
||||
<div class="col span-6">
|
||||
<LabeledSelect
|
||||
v-model:value="secret"
|
||||
|
||||
+12
-6
@@ -52,7 +52,7 @@ export default {
|
||||
},
|
||||
|
||||
data() {
|
||||
const node = (this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).find(t => t.key === LVM_TOPOLOGY_LABEL)?.values[0];
|
||||
const node = (this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).find((t) => t.key === LVM_TOPOLOGY_LABEL)?.values[0];
|
||||
|
||||
return {
|
||||
volumeGroupTypes: ['striped', 'dm-thin'],
|
||||
@@ -77,7 +77,7 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const nodes = this.$store.getters[`${ inStore }/all`](NODE) || [];
|
||||
|
||||
return nodes.filter(n => n.labels[LVM_TOPOLOGY_LABEL] === n.name).map(n => n.name);
|
||||
return nodes.filter((n) => n.labels[LVM_TOPOLOGY_LABEL] === n.name).map((n) => n.name);
|
||||
},
|
||||
|
||||
volumeGroups() {
|
||||
@@ -85,8 +85,8 @@ export default {
|
||||
const lvmVolumeGroups = this.$store.getters[`${ inStore }/all`](HCI.LVM_VOLUME_GROUP) || [];
|
||||
|
||||
return lvmVolumeGroups
|
||||
.filter(group => group.spec.nodeName === this.node)
|
||||
.map(g => g.spec.vgName);
|
||||
.filter((group) => group.spec.nodeName === this.node)
|
||||
.map((g) => g.spec.vgName);
|
||||
},
|
||||
|
||||
parameters: {
|
||||
@@ -119,7 +119,10 @@ export default {
|
||||
:required="true"
|
||||
>
|
||||
<template #no-options="{ searching }">
|
||||
<span v-if="!searching" class="text-muted">
|
||||
<span
|
||||
v-if="!searching"
|
||||
class="text-muted"
|
||||
>
|
||||
{{ t('harvester.storage.parameters.diskSelector.no-options', null, true) }}
|
||||
</span>
|
||||
</template>
|
||||
@@ -136,7 +139,10 @@ export default {
|
||||
:required="true"
|
||||
>
|
||||
<template #no-options="{ searching }">
|
||||
<span v-if="!searching" class="text-muted">
|
||||
<span
|
||||
v-if="!searching"
|
||||
class="text-muted"
|
||||
>
|
||||
{{ t('harvester.storage.parameters.lvmVolumeGroup.no-options', null, true) }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -98,7 +98,7 @@ export default {
|
||||
|
||||
const backupList = this.$store.getters['harvester/all'](HCI.BACKUP);
|
||||
|
||||
return backupList.find( O => O.name === name);
|
||||
return backupList.find( (O) => O.name === name);
|
||||
},
|
||||
|
||||
disableExisting() {
|
||||
@@ -108,7 +108,7 @@ export default {
|
||||
backupNamespace() {
|
||||
const backupList = this.$store.getters['harvester/all'](HCI.BACKUP);
|
||||
|
||||
return backupList.find( B => B.metadata.name === this.backupName)?.metadata?.namespace;
|
||||
return backupList.find( (B) => B.metadata.name === this.backupName)?.metadata?.namespace;
|
||||
},
|
||||
|
||||
namespaces() {
|
||||
@@ -265,7 +265,13 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Footer mode="create" class="footer" :errors="errors" @save="saveRestore" @done="cancelAction" />
|
||||
<Footer
|
||||
mode="create"
|
||||
class="footer"
|
||||
:errors="errors"
|
||||
@save="saveRestore"
|
||||
@done="cancelAction"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ export default {
|
||||
storageClasses: this.$store.dispatch(`${ inStore }/findAll`, { type: STORAGE_CLASS }),
|
||||
});
|
||||
|
||||
const defaultStorage = this.$store.getters[`${ inStore }/all`](STORAGE_CLASS).find(s => s.isDefault);
|
||||
const defaultStorage = this.$store.getters[`${ inStore }/all`](STORAGE_CLASS).find((s) => s.isDefault);
|
||||
|
||||
this['storageClassName'] = this.storageClassName || defaultStorage?.metadata?.name || 'longhorn';
|
||||
this.images = this.$store.getters[`${ inStore }/all`](HCI.IMAGE);
|
||||
@@ -73,7 +73,7 @@ export default {
|
||||
// image ns/name = image.id
|
||||
const sourceImage = `${ securityParameters.sourceImageNamespace }/${ securityParameters.sourceImageName }`;
|
||||
|
||||
this.selectedImage = this.images.find(image => image.id === sourceImage);
|
||||
this.selectedImage = this.images.find((image) => image.id === sourceImage);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -88,11 +88,11 @@ export default {
|
||||
if (image && cryptoOperation) {
|
||||
const imageObject = JSON.parse(image);
|
||||
|
||||
this.value.spec.securityParameters = {
|
||||
this.value.spec.securityParameters = {
|
||||
cryptoOperation,
|
||||
sourceImageName: imageObject.metadata.name,
|
||||
sourceImageNamespace: imageObject.metadata.namespace
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!this.value.metadata.name) {
|
||||
@@ -140,7 +140,7 @@ export default {
|
||||
const storages = this.$store.getters[`${ inStore }/all`](STORAGE_CLASS);
|
||||
|
||||
return storages
|
||||
.filter(s => !s.parameters?.backingImage && s.provisioner !== LVM_DRIVER) // Lvm storage is not supported.
|
||||
.filter((s) => !s.parameters?.backingImage && s.provisioner !== LVM_DRIVER) // Lvm storage is not supported.
|
||||
.map((s) => {
|
||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
|
||||
@@ -167,12 +167,12 @@ export default {
|
||||
return options;
|
||||
}
|
||||
if (this.value.spec.securityParameters.cryptoOperation === ENCRYPT) {
|
||||
options = this.images.filter(image => !image.isEncrypted);
|
||||
options = this.images.filter((image) => !image.isEncrypted);
|
||||
} else {
|
||||
options = this.images.filter(image => image.isEncrypted);
|
||||
options = this.images.filter((image) => image.isEncrypted);
|
||||
}
|
||||
|
||||
return options.map(image => image.displayNameWithNamespace);
|
||||
return options.map((image) => image.displayNameWithNamespace);
|
||||
},
|
||||
sourceImage: {
|
||||
get() {
|
||||
@@ -183,7 +183,7 @@ export default {
|
||||
return '';
|
||||
},
|
||||
set(neu) {
|
||||
this.selectedImage = this.images.find(i => i.displayNameWithNamespace === neu);
|
||||
this.selectedImage = this.images.find((i) => i.displayNameWithNamespace === neu);
|
||||
// sourceImageName should bring the name of the image
|
||||
this.value.spec.securityParameters.sourceImageName = this.selectedImage?.metadata.name || '';
|
||||
this.value.spec.securityParameters.sourceImageNamespace = this.selectedImage?.metadata.namespace || '';
|
||||
@@ -322,7 +322,7 @@ export default {
|
||||
internalAnnotations(option) {
|
||||
const optionKeys = [HCI_ANNOTATIONS.OS_TYPE, HCI_ANNOTATIONS.IMAGE_SUFFIX];
|
||||
|
||||
return optionKeys.find(O => O === option.key);
|
||||
return optionKeys.find((O) => O === option.key);
|
||||
},
|
||||
|
||||
calculateOptions(keyName) {
|
||||
@@ -352,7 +352,7 @@ export default {
|
||||
|
||||
return OS.find( (os) => {
|
||||
if (os.match) {
|
||||
return os.match.find(matchValue => str.toLowerCase().includes(matchValue)) ? os.value : false;
|
||||
return os.match.find((matchValue) => str.toLowerCase().includes(matchValue)) ? os.value : false;
|
||||
} else {
|
||||
return str.toLowerCase().includes(os.value.toLowerCase()) ? os.value : false;
|
||||
}
|
||||
@@ -376,13 +376,17 @@ export default {
|
||||
<NameNsDescription
|
||||
ref="nd"
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
:label="t('generic.name')"
|
||||
name-key="spec.displayName"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<Tabbed v-bind="$attrs" class="mt-15" :side-tabs="true">
|
||||
<Tabbed
|
||||
v-bind="$attrs"
|
||||
class="mt-15"
|
||||
:side-tabs="true"
|
||||
>
|
||||
<Tab
|
||||
name="basic"
|
||||
:label="t('harvester.image.tabs.basics')"
|
||||
@@ -503,7 +507,12 @@ export default {
|
||||
</div>
|
||||
</Tab>
|
||||
|
||||
<Tab name="labels" :label="t('labels.labels.title')" :weight="2" class="bordered-table">
|
||||
<Tab
|
||||
name="labels"
|
||||
:label="t('labels.labels.title')"
|
||||
:weight="2"
|
||||
class="bordered-table"
|
||||
>
|
||||
<KeyValue
|
||||
key="labels"
|
||||
ref="labels"
|
||||
|
||||
@@ -99,7 +99,7 @@ export default {
|
||||
templateId: {
|
||||
async handler(neu) {
|
||||
const templates = await this.$store.dispatch('harvester/findAll', { type: HCI.VM_TEMPLATE });
|
||||
let templateValue = templates.find( V => V.id === neu) || null;
|
||||
let templateValue = templates.find( (V) => V.id === neu) || null;
|
||||
let templateSpec = templateValue?.spec;
|
||||
|
||||
if (!templateValue) {
|
||||
@@ -131,7 +131,7 @@ export default {
|
||||
// Set the default version according to annotation:[HCI_ANNOTATIONS.TEMPLATE_VERSION_CUSTOM_NAME]
|
||||
const versions = await this.$store.dispatch('harvester/findAll', { type: HCI.VM_VERSION, opt: { force: true } });
|
||||
|
||||
const version = versions.find( V => V?.metadata?.annotations?.[HCI_ANNOTATIONS.TEMPLATE_VERSION_CUSTOM_NAME] === this.customName);
|
||||
const version = versions.find( (V) => V?.metadata?.annotations?.[HCI_ANNOTATIONS.TEMPLATE_VERSION_CUSTOM_NAME] === this.customName);
|
||||
|
||||
if (version) {
|
||||
try {
|
||||
@@ -159,7 +159,7 @@ export default {
|
||||
this.parseVM();
|
||||
|
||||
const templates = await this.$store.dispatch('harvester/findAll', { type: HCI.VM_TEMPLATE });
|
||||
const template = templates.find( O => O.metadata.name === this.templateValue.metadata.name);
|
||||
const template = templates.find( (O) => O.metadata.name === this.templateValue.metadata.name);
|
||||
|
||||
try {
|
||||
if (!this.templateId) {
|
||||
@@ -223,10 +223,10 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="realTemplateMode"
|
||||
name-label="harvester.vmTemplate.nameNsDescription.name"
|
||||
:namespaced="true"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<Checkbox
|
||||
@@ -238,9 +238,20 @@ export default {
|
||||
:mode="mode"
|
||||
/>
|
||||
|
||||
<Tabbed :side-tabs="true" @changed="onTabChanged">
|
||||
<Tab name="Basics" :label="t('harvester.vmTemplate.tabs.basics')">
|
||||
<CpuMemory :cpu="cpu" :memory="memory" :disabled="isConfig" @updateCpuMemory="updateCpuMemory" />
|
||||
<Tabbed
|
||||
:side-tabs="true"
|
||||
@changed="onTabChanged"
|
||||
>
|
||||
<Tab
|
||||
name="Basics"
|
||||
:label="t('harvester.vmTemplate.tabs.basics')"
|
||||
>
|
||||
<CpuMemory
|
||||
:cpu="cpu"
|
||||
:memory="memory"
|
||||
:disabled="isConfig"
|
||||
@updateCpuMemory="updateCpuMemory"
|
||||
/>
|
||||
|
||||
<div class="mb-20">
|
||||
<SSHKey
|
||||
@@ -254,12 +265,28 @@ export default {
|
||||
</div>
|
||||
</Tab>
|
||||
|
||||
<Tab name="Volume" :label="t('harvester.tab.volume')" :weight="-1">
|
||||
<Volume v-model:value="diskRows" :mode="mode" :namespace="value.metadata.namespace" :existing-volume-disabled="true" />
|
||||
<Tab
|
||||
name="Volume"
|
||||
:label="t('harvester.tab.volume')"
|
||||
:weight="-1"
|
||||
>
|
||||
<Volume
|
||||
v-model:value="diskRows"
|
||||
:mode="mode"
|
||||
:namespace="value.metadata.namespace"
|
||||
:existing-volume-disabled="true"
|
||||
/>
|
||||
</Tab>
|
||||
|
||||
<Tab name="Network" :label="t('harvester.tab.network')" :weight="-2">
|
||||
<Network v-model:value="networkRows" :mode="mode" />
|
||||
<Tab
|
||||
name="Network"
|
||||
:label="t('harvester.tab.network')"
|
||||
:weight="-2"
|
||||
>
|
||||
<Network
|
||||
v-model:value="networkRows"
|
||||
:mode="mode"
|
||||
/>
|
||||
</Tab>
|
||||
|
||||
<Tab
|
||||
@@ -276,7 +303,11 @@ export default {
|
||||
</template>
|
||||
</Tab>
|
||||
|
||||
<Tab :label="t('harvester.tab.vmScheduling')" name="vmScheduling" :weight="-4">
|
||||
<Tab
|
||||
:label="t('harvester.tab.vmScheduling')"
|
||||
name="vmScheduling"
|
||||
:weight="-4"
|
||||
>
|
||||
<template #default>
|
||||
<PodAffinity
|
||||
:mode="mode"
|
||||
@@ -318,7 +349,11 @@ export default {
|
||||
</Labels>
|
||||
</Tab>
|
||||
|
||||
<Tab name="advanced" :label="t('harvester.tab.advanced')" :weight="-99">
|
||||
<Tab
|
||||
name="advanced"
|
||||
:label="t('harvester.tab.advanced')"
|
||||
:weight="-99"
|
||||
>
|
||||
<div class="row mb-20">
|
||||
<div class="col span-6">
|
||||
<LabeledSelect
|
||||
@@ -371,8 +406,18 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="row mb-20">
|
||||
<a v-if="showAdvanced" v-t="'harvester.generic.showMore'" role="button" @click="toggleAdvanced" />
|
||||
<a v-else v-t="'harvester.generic.showMore'" role="button" @click="toggleAdvanced" />
|
||||
<a
|
||||
v-if="showAdvanced"
|
||||
v-t="'harvester.generic.showMore'"
|
||||
role="button"
|
||||
@click="toggleAdvanced"
|
||||
/>
|
||||
<a
|
||||
v-else
|
||||
v-t="'harvester.generic.showMore'"
|
||||
role="button"
|
||||
@click="toggleAdvanced"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="showAdvanced">
|
||||
|
||||
@@ -94,7 +94,7 @@ export default {
|
||||
|
||||
const backupList = this.$store.getters['harvester/all'](HCI.BACKUP);
|
||||
|
||||
return backupList.find( O => O.name === name);
|
||||
return backupList.find( (O) => O.name === name);
|
||||
},
|
||||
|
||||
disableExisting() {
|
||||
@@ -104,7 +104,7 @@ export default {
|
||||
snapshotNamespace() {
|
||||
const backupList = this.$store.getters['harvester/all'](HCI.BACKUP);
|
||||
|
||||
return backupList.find( B => B.metadata.name === this.snapshotName)?.metadata?.namespace;
|
||||
return backupList.find( (B) => B.metadata.name === this.snapshotName)?.metadata?.namespace;
|
||||
},
|
||||
|
||||
namespaces() {
|
||||
@@ -113,7 +113,7 @@ export default {
|
||||
const systemNamespaces = this.$store.getters['systemNamespaces'];
|
||||
|
||||
const out = sortBy(
|
||||
choices.filter(N => !systemNamespaces.includes(N.metadata.name)).map((obj) => {
|
||||
choices.filter((N) => !systemNamespaces.includes(N.metadata.name)).map((obj) => {
|
||||
return {
|
||||
label: obj.nameDisplay,
|
||||
value: obj.id,
|
||||
@@ -239,12 +239,28 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LabeledSelect v-model:value="snapshotName" class="mb-20" :label="t('harvester.vmSnapshot.snapshot')" :options="snapshotOption" />
|
||||
<LabeledSelect
|
||||
v-model:value="snapshotName"
|
||||
class="mb-20"
|
||||
:label="t('harvester.vmSnapshot.snapshot')"
|
||||
:options="snapshotOption"
|
||||
/>
|
||||
|
||||
<LabeledSelect v-if="!restoreNewVm" v-model:value="deletionPolicy" :label="t('harvester.backup.restore.deletePreviousVolumes')" :options="deletionPolicyOption" />
|
||||
<LabeledSelect
|
||||
v-if="!restoreNewVm"
|
||||
v-model:value="deletionPolicy"
|
||||
:label="t('harvester.backup.restore.deletePreviousVolumes')"
|
||||
:options="deletionPolicyOption"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Footer mode="create" class="footer" :errors="errors" @save="saveRestore" @done="cancelAction" />
|
||||
<Footer
|
||||
mode="create"
|
||||
class="footer"
|
||||
:errors="errors"
|
||||
@save="saveRestore"
|
||||
@done="cancelAction"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ export default {
|
||||
this.snapshots = hash.snapshots;
|
||||
this.images = hash.images;
|
||||
|
||||
const defaultStorage = this.$store.getters[`harvester/all`](STORAGE_CLASS).find( O => O.isDefault);
|
||||
const defaultStorage = this.$store.getters[`harvester/all`](STORAGE_CLASS).find( (O) => O.isDefault);
|
||||
|
||||
this.value.spec['storageClassName'] = this.value?.spec?.storageClassName || defaultStorage?.metadata?.name || 'longhorn';
|
||||
},
|
||||
@@ -97,7 +97,7 @@ export default {
|
||||
isBlank() {
|
||||
return this.source === 'blank';
|
||||
},
|
||||
|
||||
|
||||
isEdit() {
|
||||
return this.mode === _EDIT;
|
||||
},
|
||||
@@ -123,7 +123,7 @@ export default {
|
||||
imageOption() {
|
||||
return sortBy(
|
||||
this.images
|
||||
.filter(obj => obj.isReady)
|
||||
.filter((obj) => obj.isReady)
|
||||
.map((obj) => {
|
||||
return {
|
||||
label: `${ obj.metadata.namespace }/${ obj.spec.displayName }`,
|
||||
@@ -174,7 +174,7 @@ export default {
|
||||
},
|
||||
|
||||
storageClassOptions() {
|
||||
return this.storageClasses.filter(s => !s.parameters?.backingImage).map((s) => {
|
||||
return this.storageClasses.filter((s) => !s.parameters?.backingImage).map((s) => {
|
||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
|
||||
return {
|
||||
@@ -243,7 +243,7 @@ export default {
|
||||
let imageAnnotations = '';
|
||||
let storageClassName = this.value.spec.storageClassName;
|
||||
|
||||
const storageClass = this.storageClasses.find(sc => sc.name === storageClassName);
|
||||
const storageClass = this.storageClasses.find((sc) => sc.name === storageClassName);
|
||||
const storageClassProvisioner = storageClass?.provisioner;
|
||||
const storageClassDataEngine = storageClass?.parameters?.dataEngine;
|
||||
|
||||
@@ -254,7 +254,7 @@ export default {
|
||||
...this.value.metadata.annotations,
|
||||
[HCI_ANNOTATIONS.IMAGE_ID]: this.imageId
|
||||
};
|
||||
storageClassName = images?.find(image => this.imageId === image.id)?.storageClassName;
|
||||
storageClassName = images?.find((image) => this.imageId === image.id)?.storageClassName;
|
||||
} else {
|
||||
imageAnnotations = { ...this.value.metadata.annotations };
|
||||
}
|
||||
@@ -272,7 +272,7 @@ export default {
|
||||
},
|
||||
updateImage() {
|
||||
if (this.isVMImage && this.imageId) {
|
||||
const imageResource = this.images?.find(image => this.imageId === image.id);
|
||||
const imageResource = this.images?.find((image) => this.imageId === image.id);
|
||||
const imageSize = Math.max(imageResource?.status?.size, imageResource?.status?.virtualSize);
|
||||
|
||||
if (imageSize) {
|
||||
@@ -300,7 +300,12 @@ export default {
|
||||
:apply-hooks="applyHooks"
|
||||
@finish="save"
|
||||
>
|
||||
<NameNsDescription :value="value" @update:value="$emit('update:value', $event)" :namespaced="true" :mode="mode" />
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
:namespaced="true"
|
||||
:mode="mode"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<ResourceTabs
|
||||
v-model:value="value"
|
||||
@@ -310,7 +315,12 @@ export default {
|
||||
:side-tabs="true"
|
||||
:mode="mode"
|
||||
>
|
||||
<Tab name="basic" :label="t('harvester.volume.tabs.basics')" :weight="3" class="bordered-table">
|
||||
<Tab
|
||||
name="basic"
|
||||
:label="t('harvester.volume.tabs.basics')"
|
||||
:weight="3"
|
||||
class="bordered-table"
|
||||
>
|
||||
<LabeledSelect
|
||||
v-model:value="source"
|
||||
:label="t('harvester.volume.source')"
|
||||
@@ -358,14 +368,41 @@ export default {
|
||||
@update:value="update"
|
||||
/>
|
||||
|
||||
<Banner v-if="isLonghornV2 && isEdit" color="warning">
|
||||
<Banner
|
||||
v-if="isLonghornV2 && isEdit"
|
||||
color="warning"
|
||||
>
|
||||
<span>{{ t('harvester.volume.longhorn.disableResize') }}</span>
|
||||
</Banner>
|
||||
</Tab>
|
||||
<Tab v-if="!isCreate" name="details" :label="t('harvester.volume.tabs.details')" :weight="2.5" class="bordered-table">
|
||||
<LabeledInput v-model:value="frontendDisplay" class="mb-20" :mode="mode" :disabled="true" :label="t('harvester.volume.frontend')" />
|
||||
<LabeledInput v-model:value="attachedNode" class="mb-20" :mode="mode" :disabled="true" :label="t('harvester.volume.attachedNode')" />
|
||||
<LabeledInput v-model:value="endpoint" class="mb-20" :mode="mode" :disabled="true" :label="t('harvester.volume.endpoint')" />
|
||||
<Tab
|
||||
v-if="!isCreate"
|
||||
name="details"
|
||||
:label="t('harvester.volume.tabs.details')"
|
||||
:weight="2.5"
|
||||
class="bordered-table"
|
||||
>
|
||||
<LabeledInput
|
||||
v-model:value="frontendDisplay"
|
||||
class="mb-20"
|
||||
:mode="mode"
|
||||
:disabled="true"
|
||||
:label="t('harvester.volume.frontend')"
|
||||
/>
|
||||
<LabeledInput
|
||||
v-model:value="attachedNode"
|
||||
class="mb-20"
|
||||
:mode="mode"
|
||||
:disabled="true"
|
||||
:label="t('harvester.volume.attachedNode')"
|
||||
/>
|
||||
<LabeledInput
|
||||
v-model:value="endpoint"
|
||||
class="mb-20"
|
||||
:mode="mode"
|
||||
:disabled="true"
|
||||
:label="t('harvester.volume.endpoint')"
|
||||
/>
|
||||
<LabeledSelect
|
||||
v-model:value="diskTags"
|
||||
:multiple="true"
|
||||
@@ -384,23 +421,63 @@ export default {
|
||||
:mode="mode"
|
||||
class="mb-20"
|
||||
/>
|
||||
<LabeledInput v-model:value="lastBackup" class="mb-20" :mode="mode" :disabled="true" :label="t('harvester.volume.lastBackup')" />
|
||||
<LabeledInput v-model:value="lastBackupAt" class="mb-20" :mode="mode" :disabled="true" :label="t('harvester.volume.lastBackupAt')" />
|
||||
<LabeledInput v-model:value="replicasNumber" class="mb-20" :mode="mode" :disabled="true" :label="t('harvester.volume.replicasNumber')" />
|
||||
<LabeledInput
|
||||
v-model:value="lastBackup"
|
||||
class="mb-20"
|
||||
:mode="mode"
|
||||
:disabled="true"
|
||||
:label="t('harvester.volume.lastBackup')"
|
||||
/>
|
||||
<LabeledInput
|
||||
v-model:value="lastBackupAt"
|
||||
class="mb-20"
|
||||
:mode="mode"
|
||||
:disabled="true"
|
||||
:label="t('harvester.volume.lastBackupAt')"
|
||||
/>
|
||||
<LabeledInput
|
||||
v-model:value="replicasNumber"
|
||||
class="mb-20"
|
||||
:mode="mode"
|
||||
:disabled="true"
|
||||
:label="t('harvester.volume.replicasNumber')"
|
||||
/>
|
||||
</Tab>
|
||||
<Tab v-if="!isCreate" name="instances" :label="t('harvester.volume.tabs.snapshots')" :weight="2" class="bordered-table">
|
||||
<Tab
|
||||
v-if="!isCreate"
|
||||
name="instances"
|
||||
:label="t('harvester.volume.tabs.snapshots')"
|
||||
:weight="2"
|
||||
class="bordered-table"
|
||||
>
|
||||
<SortableTable
|
||||
v-bind="$attrs"
|
||||
:headers="snapshotHeaders"
|
||||
default-sort-by="age"
|
||||
:rows="value.relatedVolumeSnapshotCounts"
|
||||
key-field="_key"
|
||||
|
||||
/>
|
||||
</Tab>
|
||||
<Tab v-if="!isCreate && value.spec.dataSource" name="datasource" :label="t('harvester.volume.tabs.datasource')" :weight="1" class="bordered-table">
|
||||
<LabeledInput v-model:value="dataSourceKind" class="mb-20" :mode="mode" :disabled="true" :label="t('harvester.volume.kind')" />
|
||||
<LabeledInput v-model:value="value.spec.dataSource.name" :mode="mode" :disabled="true" :label="t('nameNsDescription.name.label')" />
|
||||
<Tab
|
||||
v-if="!isCreate && value.spec.dataSource"
|
||||
name="datasource"
|
||||
:label="t('harvester.volume.tabs.datasource')"
|
||||
:weight="1"
|
||||
class="bordered-table"
|
||||
>
|
||||
<LabeledInput
|
||||
v-model:value="dataSourceKind"
|
||||
class="mb-20"
|
||||
:mode="mode"
|
||||
:disabled="true"
|
||||
:label="t('harvester.volume.kind')"
|
||||
/>
|
||||
<LabeledInput
|
||||
v-model:value="value.spec.dataSource.name"
|
||||
:mode="mode"
|
||||
:disabled="true"
|
||||
:label="t('nameNsDescription.name.label')"
|
||||
/>
|
||||
</Tab>
|
||||
</ResourceTabs>
|
||||
</CruResource>
|
||||
|
||||
@@ -10,7 +10,7 @@ import { HCI as HCI_ANNOTATIONS } from '@shell/config/labels-annotations';
|
||||
import { HCI } from '../types';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterSnapshot',
|
||||
name: 'HarvesterSnapshot',
|
||||
|
||||
emits: ['update:value'],
|
||||
|
||||
@@ -65,7 +65,12 @@ export default {
|
||||
:apply-hooks="applyHooks"
|
||||
@finish="save"
|
||||
>
|
||||
<NameNsDescription :value="value" @update:value="$emit('update:value', $event)" :namespaced="true" :mode="mode" />
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
:namespaced="true"
|
||||
:mode="mode"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
<ResourceTabs
|
||||
v-model:value="value"
|
||||
class="mt-15"
|
||||
@@ -74,20 +79,42 @@ export default {
|
||||
:side-tabs="true"
|
||||
:mode="mode"
|
||||
>
|
||||
<Tab name="basics" :label="t('harvester.virtualMachine.detail.tabs.basics')" class="bordered-table">
|
||||
<Tab
|
||||
name="basics"
|
||||
:label="t('harvester.virtualMachine.detail.tabs.basics')"
|
||||
class="bordered-table"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col span-12">
|
||||
<LabeledInput v-model:value="size" :label="t('harvester.snapshot.size')" class="mt-20" :disabled="true" />
|
||||
<LabeledInput
|
||||
v-model:value="size"
|
||||
:label="t('harvester.snapshot.size')"
|
||||
class="mt-20"
|
||||
:disabled="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col span-12">
|
||||
<LabeledInput v-model:value="targetVolume" :label="t('harvester.snapshot.targetVolume')" class="mt-20" :disabled="true" />
|
||||
<LabeledInput
|
||||
v-model:value="targetVolume"
|
||||
:label="t('harvester.snapshot.targetVolume')"
|
||||
class="mt-20"
|
||||
:disabled="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isImageVolume" class="row">
|
||||
<div
|
||||
v-if="isImageVolume"
|
||||
class="row"
|
||||
>
|
||||
<div class="col span-12">
|
||||
<LabeledInput v-model:value="imageName" :label="t('harvester.snapshot.image')" class="mt-20" :disabled="true" />
|
||||
<LabeledInput
|
||||
v-model:value="imageName"
|
||||
:label="t('harvester.snapshot.image')"
|
||||
class="mt-20"
|
||||
:disabled="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
|
||||
@@ -82,16 +82,28 @@ export default {
|
||||
</div>
|
||||
<div>{{ t('harvester.devices.matrixHostName') }}</div>
|
||||
</div>
|
||||
<div v-for="(nodeName, i) in allNodeNames" :key="i" >
|
||||
<div
|
||||
v-for="(nodeName, i) in allNodeNames"
|
||||
:key="i"
|
||||
>
|
||||
<span> {{ nodeName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(deviceCRD, i) in enabledDevices" :key="i" >
|
||||
<div v-clean-tooltip="deviceTooltip(deviceCRD)" class="compat-cell device-label" :class="{'text-muted': noneAvailable(deviceCRD)}">
|
||||
<div
|
||||
v-for="(deviceCRD, i) in enabledDevices"
|
||||
:key="i"
|
||||
>
|
||||
<div
|
||||
v-clean-tooltip="deviceTooltip(deviceCRD)"
|
||||
class="compat-cell device-label"
|
||||
:class="{'text-muted': noneAvailable(deviceCRD)}"
|
||||
>
|
||||
{{ deviceCRD.metadata.name }}
|
||||
</div>
|
||||
<div
|
||||
v-for="(nodeName, k) in allNodeNames" :key="k" class="compat-cell"
|
||||
v-for="(nodeName, k) in allNodeNames"
|
||||
:key="k"
|
||||
class="compat-cell"
|
||||
:class="{'has-device': nodeHasDevice(nodeName, deviceCRD)}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ const _NEW = '_NEW';
|
||||
|
||||
export default {
|
||||
emits: ['update:user', 'update:newUser'],
|
||||
|
||||
|
||||
components: {
|
||||
LabeledInput,
|
||||
LabeledSelect,
|
||||
|
||||
+21
-6
@@ -14,7 +14,7 @@ const _NEW = '_NEW';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: {
|
||||
Banner,
|
||||
InfoBox
|
||||
@@ -152,11 +152,23 @@ export default {
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Banner class="mb-20" color="info" :label="t('harvester.virtualMachine.accessCredentials.tips')" />
|
||||
<Banner
|
||||
class="mb-20"
|
||||
color="info"
|
||||
:label="t('harvester.virtualMachine.accessCredentials.tips')"
|
||||
/>
|
||||
|
||||
<div v-for="(row, i) in rows" :key="i">
|
||||
<div
|
||||
v-for="(row, i) in rows"
|
||||
:key="i"
|
||||
>
|
||||
<InfoBox class="volume-source">
|
||||
<button v-if="isEdit" type="button" class="role-link btn btn-sm remove-vol" @click="remove(row)">
|
||||
<button
|
||||
v-if="isEdit"
|
||||
type="button"
|
||||
class="role-link btn btn-sm remove-vol"
|
||||
@click="remove(row)"
|
||||
>
|
||||
<i class="icon icon-x" />
|
||||
</button>
|
||||
<h3>
|
||||
@@ -169,7 +181,7 @@ export default {
|
||||
:is="componentFor(row.source)"
|
||||
v-model:value="rows[i]"
|
||||
:rows="rows"
|
||||
:resourceType="resourceType"
|
||||
:resource-type="resourceType"
|
||||
:user-options="userOptions"
|
||||
:mode="mode"
|
||||
:idx="i"
|
||||
@@ -180,7 +192,10 @@ export default {
|
||||
</InfoBox>
|
||||
</div>
|
||||
|
||||
<div v-if="isEdit && isQemuInstalled" class="mt-20">
|
||||
<div
|
||||
v-if="isEdit && isQemuInstalled"
|
||||
class="mt-20"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm bg-primary mr-15 mb-10"
|
||||
|
||||
+7
-4
@@ -3,10 +3,10 @@ import Password from '@shell/components/form/Password';
|
||||
import AccessCredentialsUsers from '../AccessCredentialsUsers';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEditVolume',
|
||||
name: 'HarvesterEditVolume',
|
||||
|
||||
emits: ['update', 'update:newUser'],
|
||||
|
||||
|
||||
components: { Password, AccessCredentialsUsers },
|
||||
|
||||
props: {
|
||||
@@ -64,11 +64,14 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row" @update:value="update">
|
||||
<div
|
||||
class="row"
|
||||
@update:value="update"
|
||||
>
|
||||
<div class="col span-6">
|
||||
<AccessCredentialsUsers
|
||||
v-model:value="value.username"
|
||||
:resourceType="resourceType"
|
||||
:resource-type="resourceType"
|
||||
:user-options="userOptions"
|
||||
:multiple="false"
|
||||
:mode="mode"
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ import SSHKey from '../../VirtualMachineSSHKey';
|
||||
import AccessCredentialsUsers from '../AccessCredentialsUsers';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEditVolume',
|
||||
name: 'HarvesterEditVolume',
|
||||
|
||||
emits: ['update', 'update:newUser'],
|
||||
|
||||
@@ -65,7 +65,7 @@ export default {
|
||||
<div class="col span-6">
|
||||
<AccessCredentialsUsers
|
||||
v-model:value="value.users"
|
||||
:resourceType="resourceType"
|
||||
:resource-type="resourceType"
|
||||
:user-options="userOptions"
|
||||
:mode="mode"
|
||||
:multiple="true"
|
||||
|
||||
+4
-1
@@ -114,7 +114,10 @@ export default {
|
||||
<div class="mb-20">
|
||||
<h3>{{ t(`harvester.virtualMachine.cloudConfig.${type}.title`) }}</h3>
|
||||
<p class="text-muted mb-20">
|
||||
<t :k="`harvester.virtualMachine.cloudConfig.${type}.tip`" :raw="true" />
|
||||
<t
|
||||
:k="`harvester.virtualMachine.cloudConfig.${type}.tip`"
|
||||
:raw="true"
|
||||
/>
|
||||
</p>
|
||||
|
||||
<LabeledSelect
|
||||
|
||||
@@ -14,7 +14,7 @@ const _NEW = '_NEW';
|
||||
|
||||
export default {
|
||||
emits: ['updateUserData', 'updateNetworkData', 'updateDataTemplateId'],
|
||||
|
||||
|
||||
components: {
|
||||
DataTemplate, YamlEditor, LabeledInput, ModalWithCard
|
||||
},
|
||||
|
||||
@@ -3,10 +3,10 @@ import UnitInput from '@shell/components/form/UnitInput';
|
||||
import InputOrDisplay from '@shell/components/InputOrDisplay';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEditCpuMemory',
|
||||
name: 'HarvesterEditCpuMemory',
|
||||
|
||||
emits: ['updateCpuMemory'],
|
||||
|
||||
|
||||
components: { UnitInput, InputOrDisplay },
|
||||
|
||||
props: {
|
||||
@@ -78,7 +78,11 @@ export default {
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col span-6 mb-10">
|
||||
<InputOrDisplay name="CPU" :value="cupDisplay" :mode="mode">
|
||||
<InputOrDisplay
|
||||
name="CPU"
|
||||
:value="cupDisplay"
|
||||
:mode="mode"
|
||||
>
|
||||
<UnitInput
|
||||
v-model:value="localCpu"
|
||||
label="CPU"
|
||||
@@ -94,7 +98,11 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="col span-6 mb-10">
|
||||
<InputOrDisplay :name="t('harvester.virtualMachine.input.memory')" :value="memoryDisplay" :mode="mode">
|
||||
<InputOrDisplay
|
||||
:name="t('harvester.virtualMachine.input.memory')"
|
||||
:value="memoryDisplay"
|
||||
:mode="mode"
|
||||
>
|
||||
<UnitInput
|
||||
v-model:value="localMemory"
|
||||
:label="t('harvester.virtualMachine.input.memory')"
|
||||
|
||||
@@ -28,10 +28,10 @@ const MODEL = [{
|
||||
}];
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEditNetwork',
|
||||
name: 'HarvesterEditNetwork',
|
||||
|
||||
emits: ['update'],
|
||||
|
||||
|
||||
components: {
|
||||
LabeledInput, LabeledSelect, InputOrDisplay
|
||||
},
|
||||
@@ -139,7 +139,7 @@ export default {
|
||||
watch: {
|
||||
rows: {
|
||||
handler(neu) {
|
||||
const hasManagementNetwork = !!neu.some(N => N.isPod);
|
||||
const hasManagementNetwork = !!neu.some((N) => N.isPod);
|
||||
|
||||
this['hasManagementNetwork'] = hasManagementNetwork;
|
||||
},
|
||||
@@ -233,7 +233,10 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" :class="{'mb-20': !isMasquerade}">
|
||||
<div
|
||||
class="row"
|
||||
:class="{'mb-20': !isMasquerade}"
|
||||
>
|
||||
<div
|
||||
data-testid="input-hen-networkName"
|
||||
class="col span-6"
|
||||
@@ -278,7 +281,10 @@ export default {
|
||||
|
||||
<div v-if="!isMasquerade && isSingle">
|
||||
<div class="row mb-20">
|
||||
<a role="button" @click="toggleAdvanced">
|
||||
<a
|
||||
role="button"
|
||||
@click="toggleAdvanced"
|
||||
>
|
||||
{{ showAdvanced ? t('harvester.generic.hideMore') : t('harvester.generic.showMore') }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -109,7 +109,7 @@ export default {
|
||||
|
||||
while (hasUsed) {
|
||||
name = `nic-${ this.nameIdx }`;
|
||||
hasUsed = this.rows.find( O => O.name === name);
|
||||
hasUsed = this.rows.find( (O) => O.name === name);
|
||||
this.nameIdx++;
|
||||
}
|
||||
|
||||
@@ -125,8 +125,16 @@ export default {
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<InfoBox v-for="(row, i) in rows" :key="i">
|
||||
<button v-if="!isView" type="button" class="role-link remove-vol" @click="remove(row)">
|
||||
<InfoBox
|
||||
v-for="(row, i) in rows"
|
||||
:key="i"
|
||||
>
|
||||
<button
|
||||
v-if="!isView"
|
||||
type="button"
|
||||
class="role-link remove-vol"
|
||||
@click="remove(row)"
|
||||
>
|
||||
<i class="icon icon-x" />
|
||||
</button>
|
||||
|
||||
@@ -142,7 +150,12 @@ export default {
|
||||
/>
|
||||
</InfoBox>
|
||||
|
||||
<button v-if="!isView" type="button" class="btn btn-sm bg-primary" @click="add">
|
||||
<button
|
||||
v-if="!isView"
|
||||
type="button"
|
||||
class="btn btn-sm bg-primary"
|
||||
@click="add"
|
||||
>
|
||||
{{ t('harvester.virtualMachine.network.addNetwork') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
+22
-5
@@ -131,7 +131,7 @@ export default {
|
||||
});
|
||||
},
|
||||
groupIsAllEnabled(rows = []) {
|
||||
return !rows.find(device => !device.passthroughClaim);
|
||||
return !rows.find((device) => !device.passthroughClaim);
|
||||
},
|
||||
|
||||
changeRows(filterRows, parentSriov) {
|
||||
@@ -162,11 +162,25 @@ export default {
|
||||
:rows-per-page="10"
|
||||
>
|
||||
<template #group-by="{group}">
|
||||
<div :ref="group.key" v-trim-whitespace class="group-tab">
|
||||
<button v-if="groupIsAllEnabled(group.rows)" type="button" class="btn btn-sm role-secondary mr-5" @click="e=>{disableGroup(group.rows); e.target.blur()}">
|
||||
<div
|
||||
:ref="group.key"
|
||||
v-trim-whitespace
|
||||
class="group-tab"
|
||||
>
|
||||
<button
|
||||
v-if="groupIsAllEnabled(group.rows)"
|
||||
type="button"
|
||||
class="btn btn-sm role-secondary mr-5"
|
||||
@click="e=>{disableGroup(group.rows); e.target.blur()}"
|
||||
>
|
||||
{{ t('harvester.pci.disableGroup') }}
|
||||
</button>
|
||||
<button v-else type="button" class="btn btn-sm role-secondary mr-5" @click="e=>{enableGroup(group.rows); e.target.blur()}">
|
||||
<button
|
||||
v-else
|
||||
type="button"
|
||||
class="btn btn-sm role-secondary mr-5"
|
||||
@click="e=>{enableGroup(group.rows); e.target.blur()}"
|
||||
>
|
||||
{{ t('harvester.pci.enableGroup') }}
|
||||
</button>
|
||||
<span v-clean-html="group.key" />
|
||||
@@ -174,7 +188,10 @@ export default {
|
||||
</template>
|
||||
<template #cell:claimed="{row}">
|
||||
<span v-if="row.isEnabled">{{ row.claimedBy }}</span>
|
||||
<span v-else class="text-muted">—</span>
|
||||
<span
|
||||
v-else
|
||||
class="text-muted"
|
||||
>—</span>
|
||||
</template>
|
||||
<template #more-header-middle>
|
||||
<FilterBySriov
|
||||
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
|
||||
if (checkName && name.includes(checkName) && !otherDevices.includes(name)) {
|
||||
oldFormatDevices.push(name);
|
||||
} else if (this.enabledDevices.find(device => device?.metadata?.name === name)) {
|
||||
} else if (this.enabledDevices.find((device) => device?.metadata?.name === name)) {
|
||||
selectedDevices.push(name);
|
||||
}
|
||||
});
|
||||
@@ -87,7 +87,7 @@ export default {
|
||||
watch: {
|
||||
selectedDevices(neu) {
|
||||
const formatted = neu.map((selectedDevice) => {
|
||||
const deviceCRD = this.enabledDevices.find(device => device.metadata.name === selectedDevice);
|
||||
const deviceCRD = this.enabledDevices.find((device) => device.metadata.name === selectedDevice);
|
||||
const deviceName = deviceCRD?.status?.resourceName;
|
||||
|
||||
return {
|
||||
@@ -153,7 +153,7 @@ export default {
|
||||
|
||||
this.selectedDevices.forEach((deviceUid) => {
|
||||
remove(out, (nodeName) => {
|
||||
const device = this.enabledDevices.find(deviceCRD => deviceCRD.metadata.name === deviceUid);
|
||||
const device = this.enabledDevices.find((deviceCRD) => deviceCRD.metadata.name === deviceUid);
|
||||
|
||||
return device.status.nodeName !== nodeName;
|
||||
});
|
||||
@@ -166,7 +166,7 @@ export default {
|
||||
deviceOpts() {
|
||||
const filteredOptions = this.enabledDevices.filter((deviceCRD) => {
|
||||
if (this.selectedDevices.length > 0) {
|
||||
const selectedDevice = this.enabledDevices.find(device => device.metadata.name === this.selectedDevices[0]);
|
||||
const selectedDevice = this.enabledDevices.find((device) => device.metadata.name === this.selectedDevices[0]);
|
||||
|
||||
return !this.devicesInUse[deviceCRD?.metadata.name] && deviceCRD.status.nodeName === selectedDevice.status.nodeName;
|
||||
}
|
||||
@@ -192,13 +192,13 @@ export default {
|
||||
|
||||
methods: {
|
||||
otherDevices(vmDevices) {
|
||||
return vmDevices.filter(device => !this.pciDevices.find(pci => device.name === pci.name));
|
||||
return vmDevices.filter((device) => !this.pciDevices.find((pci) => device.name === pci.name));
|
||||
},
|
||||
|
||||
nodeNameFromUid(uid) {
|
||||
for (const deviceUid in this.uniqueDevices) {
|
||||
const nodes = this.uniqueDevices[deviceUid].nodes;
|
||||
const thisNode = nodes.find(node => node.systemUUID === uid);
|
||||
const thisNode = nodes.find((node) => node.systemUUID === uid);
|
||||
|
||||
if (thisNode) {
|
||||
return thisNode.name;
|
||||
@@ -227,7 +227,10 @@ export default {
|
||||
<Banner color="info">
|
||||
<t k="harvester.pci.howToUseDevice" />
|
||||
</Banner>
|
||||
<Banner v-if="selectedDevices.length > 0" color="info">
|
||||
<Banner
|
||||
v-if="selectedDevices.length > 0"
|
||||
color="info"
|
||||
>
|
||||
<t k="harvester.pci.deviceInTheSameHost" />
|
||||
</Banner>
|
||||
</div>
|
||||
@@ -250,28 +253,52 @@ export default {
|
||||
</LabeledSelect>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="compatibleNodes.length && selectedDevices.length" class="row">
|
||||
<div
|
||||
v-if="compatibleNodes.length && selectedDevices.length"
|
||||
class="row"
|
||||
>
|
||||
<div class="col span-12 text-muted">
|
||||
Compatible hosts:
|
||||
<!-- eslint-disable-next-line vue/no-parsing-error -->
|
||||
<span v-for="(node, idx) in compatibleNodes" :key="idx">{{ node }}{{ idx < compatibleNodes.length-1 ? ', ' : '' }}</span>
|
||||
<span
|
||||
v-for="(node, idx) in compatibleNodes"
|
||||
:key="idx"
|
||||
>{{ node }}{{ idx < compatibleNodes.length-1 ? ', ' : '' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="selectedDevices.length" class="text-error">
|
||||
<div
|
||||
v-else-if="selectedDevices.length"
|
||||
class="text-error"
|
||||
>
|
||||
{{ t('harvester.pci.impossibleSelection') }}
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm role-link pl-0" @click="e=>{showMatrix = !showMatrix; e.target.blur()}">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm role-link pl-0"
|
||||
@click="e=>{showMatrix = !showMatrix; e.target.blur()}"
|
||||
>
|
||||
{{ showMatrix ? t('harvester.pci.hideCompatibility') : t('harvester.pci.showCompatibility') }}
|
||||
</button>
|
||||
<div v-if="showMatrix" class="row mt-20">
|
||||
<div
|
||||
v-if="showMatrix"
|
||||
class="row mt-20"
|
||||
>
|
||||
<div class="col span-12">
|
||||
<CompatibilityMatrix :enabled-devices="enabledDevices" :devices-by-node="devicesByNode" :devices-in-use="devicesInUse" />
|
||||
<CompatibilityMatrix
|
||||
:enabled-devices="enabledDevices"
|
||||
:devices-by-node="devicesByNode"
|
||||
:devices-in-use="devicesInUse"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="row mt-20">
|
||||
<div class="col span-12">
|
||||
<DeviceList :schema="pciDeviceSchema" :devices="pciDevices" @submit.prevent />
|
||||
<DeviceList
|
||||
:schema="pciDeviceSchema"
|
||||
:devices="pciDevices"
|
||||
@submit.prevent
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import UnitInput from '@shell/components/form/UnitInput';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterReserved',
|
||||
name: 'HarvesterReserved',
|
||||
|
||||
emits: ['updateReserved'],
|
||||
|
||||
|
||||
components: { UnitInput },
|
||||
|
||||
props: {
|
||||
|
||||
@@ -16,7 +16,7 @@ const _NEW = '_NEW';
|
||||
|
||||
export default {
|
||||
emits: ['update:sshKey'],
|
||||
|
||||
|
||||
components: {
|
||||
LabeledInput,
|
||||
ModalWithCard,
|
||||
@@ -83,7 +83,7 @@ export default {
|
||||
},
|
||||
|
||||
isCreatable() {
|
||||
if ( this.schema && !this.schema?.collectionMethods.find(x => ['blocked-post', 'post'].includes(x.toLowerCase())) ) {
|
||||
if ( this.schema && !this.schema?.collectionMethods.find((x) => ['blocked-post', 'post'].includes(x.toLowerCase())) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ export default {
|
||||
|
||||
const namespaces = await this.$store.dispatch('harvester/findAll', { type: NAMESPACE });
|
||||
|
||||
const exists = namespaces?.find(n => n.name === this.namespace);
|
||||
const exists = namespaces?.find((n) => n.name === this.namespace);
|
||||
|
||||
if (!exists) {
|
||||
const ns = await this.$store.dispatch('harvester/createNamespace', { name: this.namespace }, { root: true });
|
||||
|
||||
+22
-5
@@ -108,7 +108,7 @@ export default {
|
||||
});
|
||||
},
|
||||
groupIsAllEnabled(rows = []) {
|
||||
return !rows.find(device => !device.passthroughClaim);
|
||||
return !rows.find((device) => !device.passthroughClaim);
|
||||
},
|
||||
|
||||
changeRows(filterRows) {
|
||||
@@ -142,11 +142,25 @@ export default {
|
||||
:rows-per-page="10"
|
||||
>
|
||||
<template #group-by="{group}">
|
||||
<div :ref="group.key" v-trim-whitespace class="group-tab">
|
||||
<button v-if="groupIsAllEnabled(group.rows)" type="button" class="btn btn-sm role-secondary mr-5" @click="e=>{disableGroup(group.rows); e.target.blur()}">
|
||||
<div
|
||||
:ref="group.key"
|
||||
v-trim-whitespace
|
||||
class="group-tab"
|
||||
>
|
||||
<button
|
||||
v-if="groupIsAllEnabled(group.rows)"
|
||||
type="button"
|
||||
class="btn btn-sm role-secondary mr-5"
|
||||
@click="e=>{disableGroup(group.rows); e.target.blur()}"
|
||||
>
|
||||
{{ t('harvester.usb.disableGroup') }}
|
||||
</button>
|
||||
<button v-else type="button" class="btn btn-sm role-secondary mr-5" @click="e=>{enableGroup(group.rows); e.target.blur()}">
|
||||
<button
|
||||
v-else
|
||||
type="button"
|
||||
class="btn btn-sm role-secondary mr-5"
|
||||
@click="e=>{enableGroup(group.rows); e.target.blur()}"
|
||||
>
|
||||
{{ t('harvester.usb.enableGroup') }}
|
||||
</button>
|
||||
<span v-clean-html="group.key" />
|
||||
@@ -154,7 +168,10 @@ export default {
|
||||
</template>
|
||||
<template #cell:claimed="{row}">
|
||||
<span v-if="row.status.enabled">{{ row.claimedBy }}</span>
|
||||
<span v-else class="text-muted">—</span>
|
||||
<span
|
||||
v-else
|
||||
class="text-muted"
|
||||
>—</span>
|
||||
</template>
|
||||
</ResourceTable>
|
||||
</template>
|
||||
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
|
||||
this.selectedDevices = (this.value?.domain?.devices?.hostDevices || [])
|
||||
.map(({ name }) => name)
|
||||
.filter(name => this.enabledDevices.find(device => device?.metadata?.name === name));
|
||||
.filter((name) => this.enabledDevices.find((device) => device?.metadata?.name === name));
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -70,7 +70,7 @@ export default {
|
||||
watch: {
|
||||
selectedDevices(neu) {
|
||||
const formatted = neu.map((selectedDevice) => {
|
||||
const deviceCRD = this.enabledDevices.find(device => device.metadata.name === selectedDevice);
|
||||
const deviceCRD = this.enabledDevices.find((device) => device.metadata.name === selectedDevice);
|
||||
const deviceName = deviceCRD?.status?.resourceName;
|
||||
|
||||
return {
|
||||
@@ -92,7 +92,7 @@ export default {
|
||||
deviceOpts() {
|
||||
const filteredOptions = this.enabledDevices.filter((deviceCRD) => {
|
||||
if (this.selectedDevices.length > 0) {
|
||||
const selectedDevice = this.enabledDevices.find(device => device.metadata.name === this.selectedDevices[0]);
|
||||
const selectedDevice = this.enabledDevices.find((device) => device.metadata.name === this.selectedDevices[0]);
|
||||
|
||||
return !this.devicesInUse[deviceCRD?.metadata.name] && deviceCRD.status.nodeName === selectedDevice?.status.nodeName;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ export default {
|
||||
|
||||
this.selectedDevices.forEach((deviceUid) => {
|
||||
remove(out, (nodeName) => {
|
||||
const device = this.enabledDevices.find(deviceCRD => deviceCRD.metadata.name === deviceUid);
|
||||
const device = this.enabledDevices.find((deviceCRD) => deviceCRD.metadata.name === deviceUid);
|
||||
|
||||
return device?.status.nodeName !== nodeName;
|
||||
});
|
||||
@@ -164,7 +164,7 @@ export default {
|
||||
|
||||
methods: {
|
||||
otherDevices(vmDevices) {
|
||||
return vmDevices.filter(device => !this.devices.find(usb => device.name === usb.name));
|
||||
return vmDevices.filter((device) => !this.devices.find((usb) => device.name === usb.name));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -177,7 +177,10 @@ export default {
|
||||
<Banner color="info">
|
||||
<t k="harvester.usb.howToUseDevice" />
|
||||
</Banner>
|
||||
<Banner v-if="selectedDevices.length > 0" color="info">
|
||||
<Banner
|
||||
v-if="selectedDevices.length > 0"
|
||||
color="info"
|
||||
>
|
||||
<t k="harvester.usb.deviceInTheSameHost" />
|
||||
</Banner>
|
||||
</div>
|
||||
@@ -200,28 +203,52 @@ export default {
|
||||
</LabeledSelect>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="compatibleNodes.length && selectedDevices.length" class="row">
|
||||
<div
|
||||
v-if="compatibleNodes.length && selectedDevices.length"
|
||||
class="row"
|
||||
>
|
||||
<div class="col span-12 text-muted">
|
||||
Compatible hosts:
|
||||
<!-- eslint-disable-next-line vue/no-parsing-error -->
|
||||
<span v-for="(node, idx) in compatibleNodes" :key="node">{{ node }}{{ idx < compatibleNodes.length-1 ? ', ' : '' }}</span>
|
||||
<span
|
||||
v-for="(node, idx) in compatibleNodes"
|
||||
:key="node"
|
||||
>{{ node }}{{ idx < compatibleNodes.length-1 ? ', ' : '' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="selectedDevices.length" class="text-error">
|
||||
<div
|
||||
v-else-if="selectedDevices.length"
|
||||
class="text-error"
|
||||
>
|
||||
{{ t('harvester.usb.impossibleSelection') }}
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm role-link pl-0" @click="e=>{showMatrix = !showMatrix; e.target.blur()}">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm role-link pl-0"
|
||||
@click="e=>{showMatrix = !showMatrix; e.target.blur()}"
|
||||
>
|
||||
{{ showMatrix ? t('harvester.usb.hideCompatibility') : t('harvester.usb.showCompatibility') }}
|
||||
</button>
|
||||
<div v-if="showMatrix" class="row mt-20">
|
||||
<div
|
||||
v-if="showMatrix"
|
||||
class="row mt-20"
|
||||
>
|
||||
<div class="col span-12">
|
||||
<CompatibilityMatrix :enabled-devices="enabledDevices" :devices-by-node="devicesByNode" :devices-in-use="devicesInUse" />
|
||||
<CompatibilityMatrix
|
||||
:enabled-devices="enabledDevices"
|
||||
:devices-by-node="devicesByNode"
|
||||
:devices-in-use="devicesInUse"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="row mt-20">
|
||||
<div class="col span-12">
|
||||
<DeviceList :schema="deviceSchema" :devices="devices" @submit.prevent />
|
||||
<DeviceList
|
||||
:schema="deviceSchema"
|
||||
:devices="devices"
|
||||
@submit.prevent
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
...(this.value?.domain?.devices?.gpus || []).map(({ name }) => name),
|
||||
...Object.values(this.vm?.provisionedVGpus).reduce((acc, gpus) => [...acc, ...gpus], [])
|
||||
]).forEach((name) => {
|
||||
if (this.enabledDevices.find(device => device?.metadata?.name === name)) {
|
||||
if (this.enabledDevices.find((device) => device?.metadata?.name === name)) {
|
||||
this.selectedDevices.push(name);
|
||||
}
|
||||
});
|
||||
@@ -68,7 +68,7 @@ export default {
|
||||
watch: {
|
||||
selectedDevices(neu) {
|
||||
const formatted = neu.map((selectedDevice) => {
|
||||
const deviceCRD = this.enabledDevices.find(device => device.metadata.name === selectedDevice);
|
||||
const deviceCRD = this.enabledDevices.find((device) => device.metadata.name === selectedDevice);
|
||||
const deviceName = `nvidia.com/${ deviceCRD?.status?.configureVGPUTypeName?.replace(/\s+/g, '_') }`;
|
||||
|
||||
return {
|
||||
@@ -125,7 +125,7 @@ export default {
|
||||
|
||||
this.selectedDevices.forEach((deviceUid) => {
|
||||
remove(out, (nodeName) => {
|
||||
const device = this.enabledDevices.find(deviceCRD => deviceCRD.metadata.name === deviceUid);
|
||||
const device = this.enabledDevices.find((deviceCRD) => deviceCRD.metadata.name === deviceUid);
|
||||
|
||||
return device.spec.nodeName !== nodeName;
|
||||
});
|
||||
@@ -137,7 +137,7 @@ export default {
|
||||
deviceOpts() {
|
||||
const filteredOptions = this.enabledDevices.filter((deviceCRD) => {
|
||||
if (this.selectedDevices.length > 0) {
|
||||
const selectedDevice = this.enabledDevices.find(device => device.metadata.name === this.selectedDevices[0]);
|
||||
const selectedDevice = this.enabledDevices.find((device) => device.metadata.name === this.selectedDevices[0]);
|
||||
|
||||
return !this.devicesInUse[deviceCRD?.metadata.name] && deviceCRD.spec.nodeName === selectedDevice.spec.nodeName;
|
||||
}
|
||||
@@ -163,7 +163,10 @@ export default {
|
||||
<Banner color="info">
|
||||
<t k="harvester.vgpu.howToUseDevice" />
|
||||
</Banner>
|
||||
<Banner v-if="selectedDevices.length > 0" color="info">
|
||||
<Banner
|
||||
v-if="selectedDevices.length > 0"
|
||||
color="info"
|
||||
>
|
||||
<t k="harvester.vgpu.deviceInTheSameHost" />
|
||||
</Banner>
|
||||
</div>
|
||||
@@ -186,20 +189,33 @@ export default {
|
||||
</LabeledSelect>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="compatibleNodes.length && selectedDevices.length" class="row">
|
||||
<div
|
||||
v-if="compatibleNodes.length && selectedDevices.length"
|
||||
class="row"
|
||||
>
|
||||
<div class="col span-12 text-muted">
|
||||
Compatible hosts:
|
||||
<!-- eslint-disable-next-line vue/no-parsing-error -->
|
||||
<span v-for="(node, idx) in compatibleNodes" :key="idx">{{ node }}{{ idx < compatibleNodes.length-1 ? ', ' : '' }}</span>
|
||||
<span
|
||||
v-for="(node, idx) in compatibleNodes"
|
||||
:key="idx"
|
||||
>{{ node }}{{ idx < compatibleNodes.length-1 ? ', ' : '' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="selectedDevices.length" class="text-error">
|
||||
<div
|
||||
v-else-if="selectedDevices.length"
|
||||
class="text-error"
|
||||
>
|
||||
{{ t('harvester.vgpu.impossibleSelection') }}
|
||||
</div>
|
||||
</template>
|
||||
<div class="row mt-20">
|
||||
<div class="col span-12">
|
||||
<VGpuDeviceList :schema="deviceSchema" :devices="devices" @submit.prevent />
|
||||
<VGpuDeviceList
|
||||
:schema="deviceSchema"
|
||||
:devices="devices"
|
||||
@submit.prevent
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { Sortable } from "sortablejs-vue3";
|
||||
import { Sortable } from 'sortablejs-vue3';
|
||||
import InfoBox from '@shell/components/InfoBox';
|
||||
import { Banner } from '@components/Banner';
|
||||
import BadgeStateFormatter from '@shell/components/formatter/BadgeStateFormatter';
|
||||
@@ -20,7 +20,7 @@ import { HCI } from '../../../types';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: {
|
||||
Banner, BadgeStateFormatter, Sortable, InfoBox, LabeledInput, UnitInput, LabeledSelect, ModalWithCard
|
||||
},
|
||||
@@ -146,7 +146,7 @@ export default {
|
||||
query: { mode: _EDIT }
|
||||
};
|
||||
|
||||
V.pvc = this.pvcs.find(pvc => pvc.metadata.name === V.realName);
|
||||
V.pvc = this.pvcs.find((pvc) => pvc.metadata.name === V.realName);
|
||||
}
|
||||
|
||||
return V;
|
||||
@@ -189,7 +189,7 @@ export default {
|
||||
|
||||
while (hasName) {
|
||||
name = `disk-${ this.nameIdx }`;
|
||||
hasName = this.rows.find(O => O.name === name);
|
||||
hasName = this.rows.find((O) => O.name === name);
|
||||
this.nameIdx++;
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ export default {
|
||||
},
|
||||
|
||||
getImageDisplayName(id) {
|
||||
return this.$store.getters['harvester/all'](HCI.IMAGE).find(image => image.id === id)?.spec?.displayName;
|
||||
return this.$store.getters['harvester/all'](HCI.IMAGE).find((image) => image.id === id)?.spec?.displayName;
|
||||
},
|
||||
|
||||
isLonghornV2(volume) {
|
||||
@@ -275,8 +275,8 @@ export default {
|
||||
<Sortable
|
||||
:list="rows"
|
||||
:options="{disabled: isView}"
|
||||
@end="update"
|
||||
item-key="id"
|
||||
@end="update"
|
||||
>
|
||||
<template #item="{element: volume, index: i}">
|
||||
<div :key="volume.name">
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import { VOLUME_TYPE, InterfaceOption } from '../../../../config/harvester-map';
|
||||
import { Banner } from '@components/Banner';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEditContainer',
|
||||
name: 'HarvesterEditContainer',
|
||||
|
||||
emits: ['update'],
|
||||
|
||||
|
||||
+4
-4
@@ -13,7 +13,7 @@ import { HCI } from '../../../../types';
|
||||
import { VOLUME_TYPE, InterfaceOption } from '../../../../config/harvester-map';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEditExisting',
|
||||
name: 'HarvesterEditExisting',
|
||||
|
||||
emits: ['update'],
|
||||
|
||||
@@ -79,7 +79,7 @@ export default {
|
||||
},
|
||||
|
||||
image() {
|
||||
const imageResource = this.$store.getters['harvester/all'](HCI.IMAGE).find(I => I.id === this.pvcResource?.metadata?.annotations?.[HCI_ANNOTATIONS.IMAGE_ID]);
|
||||
const imageResource = this.$store.getters['harvester/all'](HCI.IMAGE).find((I) => I.id === this.pvcResource?.metadata?.annotations?.[HCI_ANNOTATIONS.IMAGE_ID]);
|
||||
|
||||
if (!imageResource) {
|
||||
return;
|
||||
@@ -89,7 +89,7 @@ export default {
|
||||
},
|
||||
|
||||
pvcResource() {
|
||||
return this.allPVCs.find( P => P.metadata.name === this.value.volumeName );
|
||||
return this.allPVCs.find( (P) => P.metadata.name === this.value.volumeName );
|
||||
},
|
||||
|
||||
volumeOption() {
|
||||
@@ -130,7 +130,7 @@ export default {
|
||||
|
||||
watch: {
|
||||
'value.volumeName'(neu) {
|
||||
const pvcResource = this.allPVCs.find( P => P.metadata.name === neu);
|
||||
const pvcResource = this.allPVCs.find( (P) => P.metadata.name === neu);
|
||||
|
||||
if (!pvcResource) {
|
||||
return;
|
||||
|
||||
+12
-5
@@ -88,7 +88,7 @@ export default {
|
||||
},
|
||||
|
||||
imagesOption() {
|
||||
return this.images.filter(c => c.isReady).sort((a, b) => a.creationTimestamp > b.creationTimestamp ? -1 : 1).map( (I) => {
|
||||
return this.images.filter((c) => c.isReady).sort((a, b) => a.creationTimestamp > b.creationTimestamp ? -1 : 1).map( (I) => {
|
||||
return {
|
||||
label: `${ I.metadata.namespace }/${ I.spec.displayName }`,
|
||||
value: I.id
|
||||
@@ -97,7 +97,7 @@ export default {
|
||||
},
|
||||
|
||||
imageName() {
|
||||
const image = this.imagesOption.find(I => I.value === this.value.image);
|
||||
const image = this.imagesOption.find((I) => I.value === this.value.image);
|
||||
|
||||
return image ? image.label : '-';
|
||||
},
|
||||
@@ -163,7 +163,7 @@ export default {
|
||||
},
|
||||
|
||||
onImageChange() {
|
||||
const imageResource = this.$store.getters['harvester/all'](HCI.IMAGE)?.find( I => this.value.image === I.id);
|
||||
const imageResource = this.$store.getters['harvester/all'](HCI.IMAGE)?.find( (I) => this.value.image === I.id);
|
||||
const isIsoImage = /iso$/i.test(imageResource?.imageSuffix);
|
||||
const imageSize = Math.max(imageResource?.status?.size, imageResource?.status?.virtualSize);
|
||||
|
||||
@@ -212,7 +212,11 @@ export default {
|
||||
data-testid="input-hevi-name"
|
||||
class="col span-6"
|
||||
>
|
||||
<InputOrDisplay :name="t('harvester.fields.name')" :value="value.name" :mode="mode">
|
||||
<InputOrDisplay
|
||||
:name="t('harvester.fields.name')"
|
||||
:value="value.name"
|
||||
:mode="mode"
|
||||
>
|
||||
<LabeledInput
|
||||
v-model:value="value.name"
|
||||
:label="t('harvester.fields.name')"
|
||||
@@ -321,7 +325,10 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-20">
|
||||
<div v-if="value.volumeBackups && isView" class="col span-3">
|
||||
<div
|
||||
v-if="value.volumeBackups && isView"
|
||||
class="col span-3"
|
||||
>
|
||||
<LabelValue
|
||||
:name="t('harvester.virtualMachine.volume.readyToUse')"
|
||||
:value="readyToUse"
|
||||
|
||||
@@ -14,7 +14,7 @@ import { LVM_DRIVER } from '../../../../models/harvester/storage.k8s.io.storagec
|
||||
import { DATA_ENGINE_V2 } from '../../../../edit/harvesterhci.io.storage/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'HarvesterEditVolume',
|
||||
name: 'HarvesterEditVolume',
|
||||
|
||||
emits: ['update'],
|
||||
|
||||
@@ -82,7 +82,7 @@ export default {
|
||||
pvcsResource() {
|
||||
const allPVCs = this.$store.getters['harvester/all'](PVC) || [];
|
||||
|
||||
return allPVCs.find(P => P.id === `${ this.namespace }/${ this.value.volumeName }`);
|
||||
return allPVCs.find((P) => P.id === `${ this.namespace }/${ this.value.volumeName }`);
|
||||
},
|
||||
|
||||
isDisabled() {
|
||||
@@ -94,7 +94,7 @@ export default {
|
||||
},
|
||||
|
||||
storageClassOptions() {
|
||||
return this.storageClasses.filter(s => !s.parameters?.backingImage).map((s) => {
|
||||
return this.storageClasses.filter((s) => !s.parameters?.backingImage).map((s) => {
|
||||
const label = s.isDefault ? `${ s.name } (${ this.t('generic.default') })` : s.name;
|
||||
|
||||
return {
|
||||
@@ -113,7 +113,7 @@ export default {
|
||||
'value.storageClassName': {
|
||||
immediate: true,
|
||||
handler(neu) {
|
||||
const storageClass = this.storageClasses.find(sc => sc.name === neu);
|
||||
const storageClass = this.storageClasses.find((sc) => sc.name === neu);
|
||||
const provisioner = storageClass?.provisioner;
|
||||
const engine = storageClass?.parameters?.dataEngine;
|
||||
|
||||
@@ -158,7 +158,10 @@ export default {
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Loading mode="relative" :loading="loading" />
|
||||
<Loading
|
||||
mode="relative"
|
||||
:loading="loading"
|
||||
/>
|
||||
<div class="row mb-20">
|
||||
<div
|
||||
class="col span-6"
|
||||
@@ -249,7 +252,11 @@ export default {
|
||||
data-testid="input-hev-bus"
|
||||
class="col span-6"
|
||||
>
|
||||
<InputOrDisplay :name="t('harvester.virtualMachine.volume.bus')" :value="value.bus" :mode="mode">
|
||||
<InputOrDisplay
|
||||
:name="t('harvester.virtualMachine.volume.bus')"
|
||||
:value="value.bus"
|
||||
:mode="mode"
|
||||
>
|
||||
<LabeledSelect
|
||||
v-model:value="value.bus"
|
||||
:label="t('harvester.virtualMachine.volume.bus')"
|
||||
@@ -271,7 +278,10 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-20">
|
||||
<div v-if="value.volumeBackups && isView" class="col span-3">
|
||||
<div
|
||||
v-if="value.volumeBackups && isView"
|
||||
class="col span-3"
|
||||
>
|
||||
<LabelValue
|
||||
:name="t('harvester.virtualMachine.volume.readyToUse')"
|
||||
:value="readyToUse"
|
||||
|
||||
@@ -142,7 +142,7 @@ export default {
|
||||
versionOptions() {
|
||||
const defaultVersion = this.curTemplateResource?.defaultVersion;
|
||||
|
||||
return this.versions.filter( O => O.templateId === this.templateId).map( (T) => {
|
||||
return this.versions.filter( (O) => O.templateId === this.templateId).map( (T) => {
|
||||
const version = T.version;
|
||||
|
||||
const label = defaultVersion === version ? `${ version } (${ this.t('generic.default') })` : version;
|
||||
@@ -157,7 +157,7 @@ export default {
|
||||
},
|
||||
|
||||
curTemplateResource() {
|
||||
return this.templates.find( O => O.id === this.templateId);
|
||||
return this.templates.find( (O) => O.id === this.templateId);
|
||||
},
|
||||
|
||||
nameLabel() {
|
||||
@@ -190,7 +190,7 @@ export default {
|
||||
|
||||
enableCpuPinningCheckbox() {
|
||||
if (this.mode === 'create') {
|
||||
return this.nodes.some(node => node.isCPUManagerEnabled); // any one of nodes has label cpuManager=true
|
||||
return this.nodes.some((node) => node.isCPUManagerEnabled); // any one of nodes has label cpuManager=true
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -202,7 +202,7 @@ export default {
|
||||
}
|
||||
|
||||
if (this.mode === 'create') {
|
||||
return this.nodes.every(node => !node.isCPUManagerEnabled); // no node enabled CPU manager
|
||||
return this.nodes.every((node) => !node.isCPUManagerEnabled); // no node enabled CPU manager
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -218,7 +218,7 @@ export default {
|
||||
if (id !== old && !this.templateVersionId) {
|
||||
const templates = await this.$store.dispatch('harvester/findAll', { type: HCI.VM_TEMPLATE });
|
||||
|
||||
this.templateVersionId = templates.find( O => O.id === id)?.spec?.defaultVersionId;
|
||||
this.templateVersionId = templates.find( (O) => O.id === id)?.spec?.defaultVersionId;
|
||||
}
|
||||
},
|
||||
immediate: false
|
||||
@@ -230,7 +230,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
const versions = await this.$store.dispatch('harvester/findAll', { type: HCI.VM_VERSION });
|
||||
const curVersion = versions.find( V => V.id === id);
|
||||
const curVersion = versions.find( (V) => V.id === id);
|
||||
const cloneVersionVM = clone(curVersion.spec.vm);
|
||||
|
||||
delete cloneVersionVM.spec?.template?.spec?.accessCredentials;
|
||||
@@ -458,7 +458,7 @@ export default {
|
||||
hasAvailableVersion(templateId) {
|
||||
let hasAvailableVersion = false;
|
||||
|
||||
this.versions.filter( O => O.templateId === templateId).find( (T) => {
|
||||
this.versions.filter( (O) => O.templateId === templateId).find( (T) => {
|
||||
if (T.isReady) {
|
||||
hasAvailableVersion = true;
|
||||
}
|
||||
@@ -483,7 +483,7 @@ export default {
|
||||
id="vm"
|
||||
:done-route="doneRoute"
|
||||
:resource="value"
|
||||
:cancelEvent="true"
|
||||
:cancel-event="true"
|
||||
:mode="mode"
|
||||
:can-yaml="isSingle ? true : false"
|
||||
:errors="errors"
|
||||
@@ -503,13 +503,13 @@ export default {
|
||||
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
:has-extra="!isSingle"
|
||||
:name-label="nameLabel"
|
||||
:namespaced="true"
|
||||
:name-placeholder="isSingle ? 'nameNsDescription.name.placeholder' : 'harvester.virtualMachine.instance.multiple.nameNsDescription'"
|
||||
:extra-columns="isSingle ? [] :['type']"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
>
|
||||
<template #type>
|
||||
<LabeledInput
|
||||
@@ -653,16 +653,44 @@ export default {
|
||||
/>
|
||||
</Tab>
|
||||
|
||||
<Tab v-if="enabledSriovgpu" :label="t('harvester.tab.vGpuDevices')" name="vGpuDevices" :weight="-6">
|
||||
<VGpuDevices :mode="mode" :value="spec.template.spec" :vm="value" />
|
||||
<Tab
|
||||
v-if="enabledSriovgpu"
|
||||
:label="t('harvester.tab.vGpuDevices')"
|
||||
name="vGpuDevices"
|
||||
:weight="-6"
|
||||
>
|
||||
<VGpuDevices
|
||||
:mode="mode"
|
||||
:value="spec.template.spec"
|
||||
:vm="value"
|
||||
/>
|
||||
</Tab>
|
||||
|
||||
<Tab v-if="enabledPCI" :label="t('harvester.tab.usbDevices')" name="usbDevices" :weight="-7">
|
||||
<UsbDevices :mode="mode" :value="spec.template.spec" :vm="value" />
|
||||
<Tab
|
||||
v-if="enabledPCI"
|
||||
:label="t('harvester.tab.usbDevices')"
|
||||
name="usbDevices"
|
||||
:weight="-7"
|
||||
>
|
||||
<UsbDevices
|
||||
:mode="mode"
|
||||
:value="spec.template.spec"
|
||||
:vm="value"
|
||||
/>
|
||||
</Tab>
|
||||
|
||||
<Tab v-if="isEdit" :label="t('harvester.tab.accessCredentials')" name="accessCredentials" :weight="-8">
|
||||
<AccessCredentials v-model:value="accessCredentials" :mode="mode" :resourceType="value" :is-qemu-installed="isQemuInstalled" />
|
||||
<Tab
|
||||
v-if="isEdit"
|
||||
:label="t('harvester.tab.accessCredentials')"
|
||||
name="accessCredentials"
|
||||
:weight="-8"
|
||||
>
|
||||
<AccessCredentials
|
||||
v-model:value="accessCredentials"
|
||||
:mode="mode"
|
||||
:resource-type="value"
|
||||
:is-qemu-installed="isQemuInstalled"
|
||||
/>
|
||||
</Tab>
|
||||
|
||||
<Tab
|
||||
@@ -739,11 +767,24 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="row mb-20">
|
||||
<a v-if="showAdvanced" v-t="'harvester.generic.showMore'" role="button" @click="toggleAdvanced" />
|
||||
<a v-else v-t="'harvester.generic.showMore'" role="button" @click="toggleAdvanced" />
|
||||
<a
|
||||
v-if="showAdvanced"
|
||||
v-t="'harvester.generic.showMore'"
|
||||
role="button"
|
||||
@click="toggleAdvanced"
|
||||
/>
|
||||
<a
|
||||
v-else
|
||||
v-t="'harvester.generic.showMore'"
|
||||
role="button"
|
||||
@click="toggleAdvanced"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="showAdvanced" class="mb-20">
|
||||
<div
|
||||
v-if="showAdvanced"
|
||||
class="mb-20"
|
||||
>
|
||||
<div class="row mb-20">
|
||||
<div class="col span-6">
|
||||
<LabeledInput
|
||||
|
||||
@@ -8,7 +8,7 @@ import PriorityRow from './PriorityRow';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: { PriorityRow },
|
||||
|
||||
props: {
|
||||
@@ -122,7 +122,9 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-for="(row, idx) in rows" :key="idx">
|
||||
v-for="(row, idx) in rows"
|
||||
:key="idx"
|
||||
>
|
||||
<PriorityRow
|
||||
:row="row"
|
||||
:mode="mode"
|
||||
@@ -133,8 +135,15 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showAdd" class="footer">
|
||||
<button type="button" class="btn role-tertiary add" @click="add()">
|
||||
<div
|
||||
v-if="showAdd"
|
||||
class="footer"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn role-tertiary add"
|
||||
@click="add()"
|
||||
>
|
||||
<t k="harvester.ipPool.scope.addLabel" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { HCI } from '@pkg/harvester/types';
|
||||
|
||||
export default {
|
||||
emits: ['update:value', 'remove'],
|
||||
|
||||
|
||||
components: { Select },
|
||||
|
||||
props: {
|
||||
@@ -82,13 +82,13 @@ export default {
|
||||
guestClusterOptions() {
|
||||
const clusters = this.$store.getters['management/all'](CAPI.RANCHER_CLUSTER);
|
||||
const configs = this.$store.getters['management/all'](HCI.HARVESTER_CONFIG);
|
||||
const selectedClusters = this.rows.map(row => row?.guestCluster);
|
||||
const filteredNamespaces = this.filteredNamespaces.map(n => n.id);
|
||||
const selectedClusters = this.rows.map((row) => row?.guestCluster);
|
||||
const filteredNamespaces = this.filteredNamespaces.map((n) => n.id);
|
||||
|
||||
const out = clusters.filter((c) => {
|
||||
const machinePools = c.spec?.rkeConfig?.machinePools || [];
|
||||
const machineConfigName = machinePools[0]?.machineConfigRef?.name;
|
||||
const config = configs.find(c => c.id === `fleet-default/${ machineConfigName }`);
|
||||
const config = configs.find((c) => c.id === `fleet-default/${ machineConfigName }`);
|
||||
|
||||
if (config) {
|
||||
const vmNamespace = config?.vmNamespace;
|
||||
@@ -120,7 +120,7 @@ export default {
|
||||
projectOptions() {
|
||||
const projects = this.$store.getters['management/all'](MANAGEMENT.PROJECT);
|
||||
|
||||
const out = projects.filter(p => p.metadata.namespace === this.currentCluster.id).map((project) => {
|
||||
const out = projects.filter((p) => p.metadata.namespace === this.currentCluster.id).map((project) => {
|
||||
return {
|
||||
label: project.nameDisplay,
|
||||
value: project.id,
|
||||
@@ -219,8 +219,15 @@ export default {
|
||||
@update:value="update"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="showRemove" class="remove">
|
||||
<button type="button" class="btn role-link" @click="remove(idx)">
|
||||
<div
|
||||
v-if="showRemove"
|
||||
class="remove"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn role-link"
|
||||
@click="remove(idx)"
|
||||
>
|
||||
<t k="generic.remove" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { removeAt } from '@shell/utils/array';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
@@ -103,7 +103,9 @@ export default {
|
||||
<div>
|
||||
<div v-if="rows.length">
|
||||
<div
|
||||
v-for="(row, idx) in rows" :key="idx">
|
||||
v-for="(row, idx) in rows"
|
||||
:key="idx"
|
||||
>
|
||||
<div
|
||||
class="pool-headers"
|
||||
:class="{
|
||||
@@ -196,19 +198,37 @@ export default {
|
||||
@input="queueUpdate"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="showRemove" class="remove">
|
||||
<button type="button" class="btn role-link" @click="remove(idx)">
|
||||
<div
|
||||
v-if="showRemove"
|
||||
class="remove"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn role-link"
|
||||
@click="remove(idx)"
|
||||
>
|
||||
<t k="generic.remove" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showAdd" class="footer">
|
||||
<button type="button" class="btn role-tertiary add" @click="addCIDR()">
|
||||
<div
|
||||
v-if="showAdd"
|
||||
class="footer"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn role-tertiary add"
|
||||
@click="addCIDR()"
|
||||
>
|
||||
<t k="harvester.ipPool.cidr.addLabel" />
|
||||
</button>
|
||||
<button type="button" class="btn role-tertiary add" @click="addRange()">
|
||||
<button
|
||||
type="button"
|
||||
class="btn role-tertiary add"
|
||||
@click="addRange()"
|
||||
>
|
||||
<t k="harvester.ipPool.range.addLabel" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ import Priority from './Priority';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: {
|
||||
LabeledSelect,
|
||||
LabeledInput,
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
return [{
|
||||
label: this.t('generic.none'),
|
||||
value: '',
|
||||
}, ...networks.map(n => ({
|
||||
}, ...networks.map((n) => ({
|
||||
label: n.id,
|
||||
value: n.id,
|
||||
}))];
|
||||
|
||||
@@ -84,9 +84,9 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:namespaced="false"
|
||||
:mode="mode"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<ResourceTabs
|
||||
|
||||
@@ -5,7 +5,7 @@ import RadioGroup from '@components/Form/Radio/RadioGroup';
|
||||
|
||||
export default {
|
||||
emits: ['enabled'],
|
||||
|
||||
|
||||
components: {
|
||||
LabeledInput,
|
||||
LabeledSelect,
|
||||
@@ -42,7 +42,7 @@ export default {
|
||||
portOptions() {
|
||||
const ports = this.model?.spec?.listeners || [];
|
||||
|
||||
return ports.filter(p => p.port && p.protocol === 'TCP').map(p => p.backendPort) || [];
|
||||
return ports.filter((p) => p.port && p.protocol === 'TCP').map((p) => p.backendPort) || [];
|
||||
},
|
||||
},
|
||||
|
||||
@@ -71,7 +71,10 @@ export default {
|
||||
</div>
|
||||
<div v-if="healthCheckEnabled">
|
||||
<div class="row mt-10">
|
||||
<div v-if="healthCheckEnabled" class="col span-6">
|
||||
<div
|
||||
v-if="healthCheckEnabled"
|
||||
class="col span-6"
|
||||
>
|
||||
<LabeledSelect
|
||||
v-model:value="value.port"
|
||||
:mode="mode"
|
||||
|
||||
@@ -7,7 +7,7 @@ import Select from '@shell/components/form/Select';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: { Select },
|
||||
props: {
|
||||
value: {
|
||||
@@ -129,7 +129,9 @@ export default {
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-for="(row, idx) in rows" :key="idx" class="listener-row"
|
||||
v-for="(row, idx) in rows"
|
||||
:key="idx"
|
||||
class="listener-row"
|
||||
>
|
||||
<div class="port-name">
|
||||
<span v-if="isView">
|
||||
@@ -182,15 +184,29 @@ export default {
|
||||
@input="queueUpdate"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="showRemove" class="remove">
|
||||
<button type="button" class="btn role-link" @click="remove(idx)">
|
||||
<div
|
||||
v-if="showRemove"
|
||||
class="remove"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn role-link"
|
||||
@click="remove(idx)"
|
||||
>
|
||||
<t k="generic.remove" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showAdd" class="footer">
|
||||
<button type="button" class="btn role-tertiary add" @click="add()">
|
||||
<div
|
||||
v-if="showAdd"
|
||||
class="footer"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn role-tertiary add"
|
||||
@click="add()"
|
||||
>
|
||||
<t k="generic.add" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -105,7 +105,7 @@ export default {
|
||||
ipPoolOptions() {
|
||||
const ipPools = this.$store.getters['harvester/all'](HCI.IP_POOL);
|
||||
|
||||
const out = ipPools.map(ipPool => ipPool.id);
|
||||
const out = ipPools.map((ipPool) => ipPool.id);
|
||||
|
||||
return [{
|
||||
label: this.t('harvester.loadBalancer.ipPool.options.none'),
|
||||
@@ -116,13 +116,13 @@ export default {
|
||||
projectOptions() {
|
||||
const projects = this.$store.getters['harvester/all'](MANAGEMENT.PROJECT);
|
||||
|
||||
return projects.map(project => project.id);
|
||||
return projects.map((project) => project.id);
|
||||
},
|
||||
|
||||
namespaceOptions() {
|
||||
const namespaces = this.$store.getters['harvester/all'](NAMESPACE);
|
||||
|
||||
return namespaces.map(n => n.id);
|
||||
return namespaces.map((n) => n.id);
|
||||
},
|
||||
|
||||
backendServerSelector: {
|
||||
@@ -166,7 +166,7 @@ export default {
|
||||
|
||||
healthCheckPortInUseWarning() {
|
||||
const healthCheckPort = this.value?.spec?.healthCheck?.port;
|
||||
const portInUse = this.value?.spec?.listeners?.find(l => l.backendPort === healthCheckPort);
|
||||
const portInUse = this.value?.spec?.listeners?.find((l) => l.backendPort === healthCheckPort);
|
||||
|
||||
if (healthCheckPort && portInUse) {
|
||||
return this.t('harvester.loadBalancer.healthCheck.warning.portInUse', { port: portInUse.backendPort }, true);
|
||||
@@ -191,7 +191,7 @@ export default {
|
||||
|
||||
updateMatchingVMs: throttle(function() {
|
||||
const backendServerSelector = this.value.spec.backendServerSelector;
|
||||
const allVMs = this.$store.getters['harvester/all'](HCI.VM).filter(vm => vm.metadata.namespace === this.value.metadata.namespace);
|
||||
const allVMs = this.$store.getters['harvester/all'](HCI.VM).filter((vm) => vm.metadata.namespace === this.value.metadata.namespace);
|
||||
|
||||
if (isEmpty(backendServerSelector)) {
|
||||
this.matchingVMs = {
|
||||
@@ -238,9 +238,9 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:namespaced="true"
|
||||
:mode="mode"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<ResourceTabs
|
||||
|
||||
@@ -21,7 +21,7 @@ import { Banner } from '@components/Banner';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: {
|
||||
ContainerResourceLimit, CruResource, Labels, LabeledSelect, NameNsDescription, ProjectMembershipEditor, ResourceQuota, Tabbed, Tab, Banner
|
||||
},
|
||||
@@ -114,7 +114,7 @@ export default {
|
||||
|
||||
const cur = this.value.status?.podSecurityPolicyTemplateId;
|
||||
|
||||
if ( cur && !out.find(x => x.value === cur) ) {
|
||||
if ( cur && !out.find((x) => x.value === cur) ) {
|
||||
out.unshift({ label: this.t('project.psp.current', { value: cur }), value: cur });
|
||||
}
|
||||
|
||||
@@ -219,7 +219,6 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:name-editable="true"
|
||||
:mode="mode"
|
||||
:namespaced="false"
|
||||
@@ -228,6 +227,7 @@ export default {
|
||||
name-key="spec.displayName"
|
||||
:normalize-name="false"
|
||||
:rules="{ name: fvGetAndReportPathRules('spec.displayName'), namespace: [], description: [] }"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
<div class="row mb-20">
|
||||
<div class="col span-3">
|
||||
|
||||
@@ -70,9 +70,9 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
:namespaced="false"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
<ResourceTabs
|
||||
v-model:value="value"
|
||||
|
||||
@@ -11,7 +11,7 @@ import { HCI } from '../../types';
|
||||
|
||||
export default {
|
||||
emits: ['updateMatchingNICs', 'updateMatchingNodes'],
|
||||
|
||||
|
||||
components: {
|
||||
RadioGroup,
|
||||
LabeledSelect,
|
||||
|
||||
@@ -26,7 +26,7 @@ import NodeSelector from './NodeSelector';
|
||||
|
||||
export default {
|
||||
emits: ['update:value'],
|
||||
|
||||
|
||||
components: {
|
||||
CruResource,
|
||||
NameNsDescription,
|
||||
@@ -96,7 +96,7 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const nodes = this.$store.getters[`${ inStore }/all`](NODE);
|
||||
|
||||
return nodes.filter(n => n.isEtcd !== 'true').map((node) => {
|
||||
return nodes.filter((n) => n.isEtcd !== 'true').map((node) => {
|
||||
return {
|
||||
label: node.nameDisplay,
|
||||
value: node.id
|
||||
@@ -154,7 +154,7 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const linkMonitor = this.$store.getters[`${ inStore }/byId`](HCI.LINK_MONITOR, 'nic') || {};
|
||||
const linkStatus = linkMonitor?.status?.linkStatus || {};
|
||||
const nodes = this.nodes.map(n => n.id);
|
||||
const nodes = this.nodes.map((n) => n.id);
|
||||
|
||||
const out = [];
|
||||
|
||||
@@ -194,7 +194,7 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
return out.filter(o => !map[o.name].masterIndex).map((o) => {
|
||||
return out.filter((o) => !map[o.name].masterIndex).map((o) => {
|
||||
let label = '';
|
||||
|
||||
if (map[o.name].down === 0) {
|
||||
@@ -217,7 +217,7 @@ export default {
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const nodes = this.$store.getters[`${ inStore }/all`](NODE);
|
||||
|
||||
return nodes.filter(n => n.isEtcd !== 'true');
|
||||
return nodes.filter((n) => n.isEtcd !== 'true');
|
||||
},
|
||||
},
|
||||
|
||||
@@ -236,7 +236,7 @@ export default {
|
||||
errors.push(nicRequired);
|
||||
}
|
||||
|
||||
const option = this.nicOptions.find(option => option.value === n);
|
||||
const option = this.nicOptions.find((option) => option.value === n);
|
||||
|
||||
if (option && option?.disabled) {
|
||||
errors.push(this.t('harvester.vlanConfig.uplink.nics.validate.available', { nic: n }, true));
|
||||
@@ -280,15 +280,15 @@ export default {
|
||||
|
||||
if (isEmpty(nodeSelector)) {
|
||||
matchNICs = clone(allNICs);
|
||||
commonNodes = (this.nodes || []).map(n => n.id);
|
||||
commonNodes = (this.nodes || []).map((n) => n.id);
|
||||
} else if (nodeSelector[HOSTNAME] && Object.keys(nodeSelector).length === 1) {
|
||||
matchNICs = allNICs.filter(n => n.nodeName === nodeSelector[HOSTNAME]);
|
||||
matchNICs = allNICs.filter((n) => n.nodeName === nodeSelector[HOSTNAME]);
|
||||
commonNodes = [nodeSelector[HOSTNAME]];
|
||||
} else {
|
||||
const matchNodes = matching(this.nodes || [], nodeSelector).map(n => n.id);
|
||||
const matchNodes = matching(this.nodes || [], nodeSelector).map((n) => n.id);
|
||||
|
||||
matchNICs = allNICs.filter(n => matchNodes.includes(n.nodeName));
|
||||
commonNodes = matchNodes.map(n => n.id);
|
||||
matchNICs = allNICs.filter((n) => matchNodes.includes(n.nodeName));
|
||||
commonNodes = matchNodes.map((n) => n.id);
|
||||
}
|
||||
|
||||
this.matchNICs = this.intersection(matchNICs, commonNodes) || [];
|
||||
@@ -301,7 +301,7 @@ export default {
|
||||
map[n.name] = (map[n.name] || 0) + 1;
|
||||
});
|
||||
|
||||
return nics.filter(n => map[n.name] === commonNodes.length);
|
||||
return nics.filter((n) => map[n.name] === commonNodes.length);
|
||||
},
|
||||
|
||||
updateMatchingNodes: throttle(function() {
|
||||
@@ -316,7 +316,7 @@ export default {
|
||||
sample: allNodes[0] ? allNodes[0].nameDisplay : null,
|
||||
};
|
||||
} else if (selector[HOSTNAME] && Object.keys(selector).length === 1) {
|
||||
const matchNode = allNodes.find(n => n.id === selector[HOSTNAME]);
|
||||
const matchNode = allNodes.find((n) => n.id === selector[HOSTNAME]);
|
||||
|
||||
if (matchNode) {
|
||||
this.matchingNodes = {
|
||||
@@ -352,7 +352,7 @@ export default {
|
||||
const nicErrors = [];
|
||||
|
||||
nics.map((n) => {
|
||||
const option = options.find(option => option.value === n);
|
||||
const option = options.find((option) => option.value === n);
|
||||
|
||||
if ((option && option?.disabled) || !option) {
|
||||
nicErrors.push(this.t('harvester.vlanConfig.uplink.nics.validate.available', { nic: n }, true));
|
||||
@@ -376,9 +376,9 @@ export default {
|
||||
>
|
||||
<NameNsDescription
|
||||
:value="value"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
:mode="mode"
|
||||
:namespaced="false"
|
||||
@update:value="$emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<Tabbed
|
||||
@@ -433,14 +433,16 @@ export default {
|
||||
<div class="row mt-20">
|
||||
<div class="col span-12">
|
||||
<Banner
|
||||
v-for="(err, i) in nicErrors" :key="i" color="warning"
|
||||
v-for="(err, i) in nicErrors"
|
||||
:key="i"
|
||||
color="warning"
|
||||
:label="err"
|
||||
/>
|
||||
<ArrayListSelect
|
||||
v-model:value="value.spec.uplink.nics"
|
||||
:mode="mode"
|
||||
:options="nicOptions"
|
||||
:enableDefaultAddValue="false"
|
||||
:enable-default-add-value="false"
|
||||
:array-list-props="{
|
||||
addLabel: t('harvester.vlanConfig.uplink.nics.addLabel'),
|
||||
initialEmptyRow: true,
|
||||
|
||||
Reference in New Issue
Block a user