Lint fixes

Signed-off-by: Francesco Torchia <francesco.torchia@suse.com>
This commit is contained in:
Francesco Torchia
2024-11-12 11:50:20 +01:00
parent 19b11aac2c
commit 4626d56acd
214 changed files with 3162 additions and 1298 deletions
@@ -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>
+12 -3
View File
@@ -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" />
+11 -4
View File
@@ -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"
@@ -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>
+99 -22
View File
@@ -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>
@@ -11,7 +11,7 @@ const _NEW = '_NEW';
export default {
emits: ['update:user', 'update:newUser'],
components: {
LabeledInput,
LabeledSelect,
@@ -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"
@@ -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"
@@ -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"
@@ -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>
@@ -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">&mdash;</span>
<span
v-else
class="text-muted"
>&mdash;</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 });
@@ -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">&mdash;</span>
<span
v-else
class="text-muted"
>&mdash;</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">
@@ -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'],
@@ -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;
@@ -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,