Compare commits

..
1 Commits
Author SHA1 Message Date
Andy Lee 55bb650b0a feat: add rancher-k3k addon UI
Signed-off-by: Andy Lee <andy.lee@suse.com>
2026-08-31 16:19:39 +08:00
15 changed files with 1398 additions and 1767 deletions
+5 -7
View File
@@ -7,7 +7,7 @@
}, },
"dependencies": { "dependencies": {
"@babel/plugin-transform-class-static-block": "7.29.7", "@babel/plugin-transform-class-static-block": "7.29.7",
"@rancher/shell": "3.0.13", "@rancher/shell": "3.0.12-rc.7",
"@vue-flow/background": "^1.3.0", "@vue-flow/background": "^1.3.0",
"@vue-flow/controls": "^1.1.1", "@vue-flow/controls": "^1.1.1",
"@vue-flow/core": "^1.33.5", "@vue-flow/core": "^1.33.5",
@@ -39,7 +39,7 @@
"merge": "2.1.1", "merge": "2.1.1",
"node-forge": "1.4.0", "node-forge": "1.4.0",
"nth-check": "2.1.1", "nth-check": "2.1.1",
"qs": "6.16.0", "qs": "6.15.3",
"roarr": "7.21.7", "roarr": "7.21.7",
"semver": "7.8.5", "semver": "7.8.5",
"@vue/cli-service/html-webpack-plugin": "^5.0.0" "@vue/cli-service/html-webpack-plugin": "^5.0.0"
@@ -48,17 +48,15 @@
"dev": "NODE_ENV=dev ./node_modules/.bin/vue-cli-service serve", "dev": "NODE_ENV=dev ./node_modules/.bin/vue-cli-service serve",
"build": "./node_modules/.bin/vue-cli-service build", "build": "./node_modules/.bin/vue-cli-service build",
"clean": "./node_modules/@rancher/shell/scripts/clean", "clean": "./node_modules/@rancher/shell/scripts/clean",
"lint": "./node_modules/@rancher/shell/scripts/lint --max-warnings 0 --ext .js,.ts,.vue .", "lint": "./node_modules/.bin/eslint --max-warnings 0 --ext .js,.ts,.vue .",
"lint:fix": "./node_modules/@rancher/shell/scripts/lint --fix --max-warnings 0 --ext .js,.ts,.vue .", "lint:fix": "./node_modules/.bin/eslint --fix --max-warnings 0 --ext .js,.ts,.vue .",
"build-pkg": "./node_modules/@rancher/shell/scripts/build-pkg.sh", "build-pkg": "./node_modules/@rancher/shell/scripts/build-pkg.sh",
"serve-pkgs": "./node_modules/@rancher/shell/scripts/serve-pkgs", "serve-pkgs": "./node_modules/@rancher/shell/scripts/serve-pkgs",
"publish-pkgs": "./node_modules/@rancher/shell/scripts/extension/publish", "publish-pkgs": "./node_modules/@rancher/shell/scripts/extension/publish",
"parse-tag-name": "./node_modules/@rancher/shell/scripts/extension/parse-tag-name", "parse-tag-name": "./node_modules/@rancher/shell/scripts/extension/parse-tag-name",
"commitlint": "commitlint --edit", "commitlint": "commitlint --edit",
"prepare": "husky", "prepare": "husky",
"agents:generate": "./scripts/generate-agent-and-persona-mds.sh", "agents:generate": "./scripts/generate-agent-and-persona-mds.sh"
"prelint": "npm --prefix node_modules/@rancher/shell/eslint-legacy install eslint-plugin-jest@^24 --no-save --no-audit --no-fund --legacy-peer-deps --loglevel=error",
"prelint:fix": "npm --prefix node_modules/@rancher/shell/eslint-legacy install eslint-plugin-jest@^24 --no-save --no-audit --no-fund --legacy-peer-deps --loglevel=error"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/load": "^19.8.1", "@commitlint/load": "^19.8.1",
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.8 KiB

+14 -20
View File
@@ -53,7 +53,7 @@ export default {
}; };
}, },
computed: { ...mapGetters({ t: 'i18n/t', isHarvesterPrime: 'harvester-common/isHarvesterPrime' }) }, computed: { ...mapGetters({ t: 'i18n/t' }) },
watch: { watch: {
settings: { settings: {
@@ -231,21 +231,14 @@ export default {
v-if="setting.customized" v-if="setting.customized"
class="modified" class="modified"
> >
{{ t('advancedSettings.tags.modified.label') }} Modified
</span> </span>
<span <span
v-if="setting.experimental" v-if="setting.experimental"
v-clean-tooltip="t('advancedSettings.tags.experimental.description')" v-clean-tooltip="t('advancedSettings.experimental')"
class="experimental" class="experimental"
> >
{{ t('advancedSettings.tags.experimental.label') }} Experimental
</span>
<span
v-if="setting.preview"
v-clean-tooltip="t('advancedSettings.tags.preview.description')"
class="preview"
>
{{ t('advancedSettings.tags.preview.label') }}
</span> </span>
</h1> </h1>
<h2 v-clean-html="t(setting.description, getDocLinkParams(setting) || {}, true)"> <h2 v-clean-html="t(setting.description, getDocLinkParams(setting) || {}, true)">
@@ -269,8 +262,7 @@ export default {
v-if="!setting.hide" v-if="!setting.hide"
class="settings-value" class="settings-value"
> >
<pre v-if="setting.id === 'branding' && isHarvesterPrime">{{ $store.getters['harvester-common/privateLabel'] }}</pre> <pre v-if="setting.kind === 'json'">{{ setting.json }}</pre>
<pre v-else-if="setting.kind === 'json'">{{ setting.json }}</pre>
<pre v-else-if="setting.kind === 'multiline'">{{ setting.data.value || setting.data.default }}</pre> <pre v-else-if="setting.kind === 'multiline'">{{ setting.data.value || setting.data.default }}</pre>
<pre v-else-if="setting.kind === 'enum'">{{ t(setting.enum) }}</pre> <pre v-else-if="setting.kind === 'enum'">{{ t(setting.enum) }}</pre>
<pre v-else-if="setting.kind === 'custom' && setting.custom">{{ setting.custom }}</pre> <pre v-else-if="setting.kind === 'custom' && setting.custom">{{ setting.custom }}</pre>
@@ -360,19 +352,21 @@ export default {
flex: 1; flex: 1;
} }
.modified, .modified {
.experimental,
.preview {
margin-left: 10px; margin-left: 10px;
border: 1px solid; border: 1px solid var(--primary);
border-radius: 5px; border-radius: 5px;
padding: 2px 10px; padding: 2px 10px;
font-size: 12px; font-size: 12px;
} }
.modified { border-color: var(--primary); } .experimental {
.experimental { border-color: var(--error); } margin-left: 10px;
.preview { border-color: var(--warning); } border: 1px solid var(--error);
border-radius: 5px;
padding: 2px 10px;
font-size: 12px;
}
.no-search-match { .no-search-match {
text-align: center; text-align: center;
+3 -20
View File
@@ -57,7 +57,6 @@ import {
} from './table-headers'; } from './table-headers';
import { ADD_ONS } from './harvester-map'; import { ADD_ONS } from './harvester-map';
import { registerAddonSideNav } from '../utils/dynamic-nav'; import { registerAddonSideNav } from '../utils/dynamic-nav';
import { setVendor } from '@shell/config/private-label';
const TEMPLATE = HCI.VM_VERSION; const TEMPLATE = HCI.VM_VERSION;
const MONITORING_GROUP = 'Monitoring & Logging::Monitoring'; const MONITORING_GROUP = 'Monitoring & Logging::Monitoring';
@@ -110,31 +109,15 @@ export function init($plugin, store) {
} }
}; };
store.watch(
(_state, getters) => ({
isHarvesterPrime: !!getters['harvester-common/isHarvesterPrime'],
isDark: getters['prefs/theme'] === 'dark',
privateLabel: getters['harvester-common/privateLabel']
}),
({ isHarvesterPrime, isDark, privateLabel }) => {
const primeLogo = isDark ? require('../assets/images/dark/suse-virtualization.svg') : require('../assets/images/suse-virtualization.svg');
setVendor(privateLabel || '');
const primeLabelKey = privateLabel ? 'harvester.branding.primeLabel' : 'harvester.branding.primeEmptyLabel';
store.dispatch('setIsSingleProduct', { store.dispatch('setIsSingleProduct', {
productName: PRODUCT_NAME, productName: PRODUCT_NAME,
logo: isHarvesterPrime ? primeLogo : require(`@shell/assets/images/providers/harvester.svg`), logo: require(`@shell/assets/images/providers/harvester.svg`),
productNameKey: isHarvesterPrime ? primeLabelKey : 'harvester.productLabel', productNameKey: 'harvester.productLabel',
getVersionInfo: (store) => store.getters[`${ PRODUCT_NAME }/byId`]?.(HCI.SETTING, 'server-version')?.value || 'unknown', getVersionInfo: (store) => store.getters[`${ PRODUCT_NAME }/byId`]?.(HCI.SETTING, 'server-version')?.value || 'unknown',
afterLoginRoute: home, afterLoginRoute: home,
logoRoute: home, logoRoute: home,
supportCustomLogo: !isHarvesterPrime supportCustomLogo: true
}); });
},
{ immediate: true }
);
} }
product({ product({
+1 -3
View File
@@ -111,17 +111,15 @@ export const HCI_ALLOWED_SETTINGS = {
[HCI_SETTING.KUBECONFIG_DEFAULT_TOKEN_TTL_MINUTES]: { kind: 'number', featureFlag: 'kubeconfigDefaultTokenTTLMinutesSetting' }, [HCI_SETTING.KUBECONFIG_DEFAULT_TOKEN_TTL_MINUTES]: { kind: 'number', featureFlag: 'kubeconfigDefaultTokenTTLMinutesSetting' },
[HCI_SETTING.LONGHORN_V2_DATA_ENGINE_ENABLED]: { [HCI_SETTING.LONGHORN_V2_DATA_ENGINE_ENABLED]: {
kind: 'boolean', kind: 'boolean',
preview: true, experimental: true,
featureFlag: 'longhornV2LVMSupport' featureFlag: 'longhornV2LVMSupport'
}, },
[HCI_SETTING.LONGHORN_V2_DATA_ENGINE_HUGEPAGE_ENABLED]: { [HCI_SETTING.LONGHORN_V2_DATA_ENGINE_HUGEPAGE_ENABLED]: {
kind: 'boolean', kind: 'boolean',
preview: true,
featureFlag: 'longhornV2HugepageSettings' featureFlag: 'longhornV2HugepageSettings'
}, },
[HCI_SETTING.LONGHORN_V2_DATA_ENGINE_MEMORY_SIZE]: { [HCI_SETTING.LONGHORN_V2_DATA_ENGINE_MEMORY_SIZE]: {
kind: 'number', kind: 'number',
preview: true,
featureFlag: 'longhornV2HugepageSettings' featureFlag: 'longhornV2HugepageSettings'
}, },
[HCI_SETTING.ADDITIONAL_GUEST_MEMORY_OVERHEAD_RATIO]: { kind: 'string', from: 'import' }, [HCI_SETTING.ADDITIONAL_GUEST_MEMORY_OVERHEAD_RATIO]: { kind: 'string', from: 'import' },
-164
View File
@@ -1,164 +0,0 @@
<script>
import merge from 'lodash/merge';
import jsyaml from 'js-yaml';
import { mapGetters } from 'vuex';
import { Card } from '@components/Card';
import { LabeledInput } from '@components/Form/LabeledInput';
import AsyncButton from '@shell/components/AsyncButton';
import { escapeHtml } from '@shell/utils/string';
const DEFAULT_VALUE = {
rancher: {
hostname: '',
version: '',
bootstrapPassword: '',
},
};
export default {
name: 'HarvesterEnableK3k',
emits: ['close'],
components: {
AsyncButton,
Card,
LabeledInput,
},
props: {
resources: {
type: Array,
required: true
}
},
data() {
const addon = this.resources[0];
let valuesContentJson;
try {
valuesContentJson = merge({}, DEFAULT_VALUE, jsyaml.load(addon.spec.valuesContent));
} catch (e) {
valuesContentJson = merge({}, DEFAULT_VALUE);
}
return { valuesContentJson };
},
computed: {
...mapGetters({ t: 'i18n/t' }),
buttonDisabled() {
const { rancher } = this.valuesContentJson;
return !(rancher?.hostname || '').trim() || !(rancher?.version || '').trim() || !(rancher?.bootstrapPassword || '').trim();
}
},
methods: {
close() {
this.$emit('close');
},
async enable(buttonCb) {
const addon = this.resources[0];
try {
addon.spec.valuesContent = jsyaml.dump(this.valuesContentJson);
addon.spec.enabled = true;
await addon.save();
buttonCb(true);
this.close();
} catch (err) {
addon.spec.enabled = false;
this.$store.dispatch('growl/fromError', {
title: this.t('generic.notification.title.error', { name: escapeHtml(addon.metadata.name) }),
err,
}, { root: true });
buttonCb(false);
}
}
}
};
</script>
<template>
<Card :show-highlight-border="false">
<template #title>
<h4
v-clean-html="t('harvester.addons.rancherK3k.enable.title')"
class="text-default-text"
/>
</template>
<template #body>
<div class="body">
<div class="row mb-15">
<div class="col span-6">
<LabeledInput
v-model:value="valuesContentJson.rancher.hostname"
:required="true"
:label="t('harvester.addons.rancherK3k.hostname')"
placeholder="rancher.$vip.nip.io"
/>
</div>
<div class="col span-6">
<LabeledInput
v-model:value="valuesContentJson.rancher.version"
:required="true"
:label="t('harvester.addons.rancherK3k.version')"
placeholder="v1.14.0"
/>
</div>
</div>
<div class="row mb-15">
<div class="col span-12">
<LabeledInput
v-model:value="valuesContentJson.rancher.bootstrapPassword"
:required="true"
type="password"
:label="t('harvester.addons.rancherK3k.password')"
:tooltip="t('harvester.addons.rancherK3k.passwordTooltip')"
/>
</div>
</div>
</div>
</template>
<template #actions>
<div class="buttons actions">
<button
class="btn role-secondary mr-10"
@click="close"
>
{{ t('generic.cancel') }}
</button>
<AsyncButton
mode="enable"
:disabled="buttonDisabled"
@click="enable"
/>
</div>
</template>
</Card>
</template>
<style lang="scss" scoped>
.body {
display: flex;
flex-direction: column;
min-width: 400px;
}
.actions {
width: 100%;
}
.buttons {
display: flex;
justify-content: flex-end;
width: 100%;
}
</style>
@@ -4,22 +4,16 @@ import jsyaml from 'js-yaml';
import { LabeledInput } from '@components/Form/LabeledInput'; import { LabeledInput } from '@components/Form/LabeledInput';
import { RadioGroup } from '@components/Form/Radio'; import { RadioGroup } from '@components/Form/Radio';
const DEFAULT_VALUE = { const DEFAUL_VALUE = {
certManagerVersion: 'v1.20.2',
rancher: { rancher: {
hostname: '', hostname: '',
version: '', version: '',
bootstrapPassword: '', bootstrapPassword: '',
}, },
k3kCluster: {
servers: 1,
version: 'v1.35.4-k3s1',
storageClassName: 'harvester-longhorn',
},
}; };
export default { export default {
name: 'EditAddonRancherK3k', name: 'EditAddonK3k',
components: { LabeledInput, RadioGroup }, components: { LabeledInput, RadioGroup },
inheritAttrs: false, inheritAttrs: false,
@@ -44,9 +38,9 @@ export default {
let valuesContentJson = {}; let valuesContentJson = {};
try { try {
valuesContentJson = merge({}, DEFAULT_VALUE, jsyaml.load(this.value.spec.valuesContent)); valuesContentJson = merge({}, DEFAUL_VALUE, jsyaml.load(this.value.spec.valuesContent));
} catch (err) { } catch (err) {
valuesContentJson = merge({}, DEFAULT_VALUE); valuesContentJson = DEFAUL_VALUE;
this.$store.dispatch('growl/fromError', { this.$store.dispatch('growl/fromError', {
title: this.$store.getters['i18n/t']('generic.notification.title.error'), title: this.$store.getters['i18n/t']('generic.notification.title.error'),
@@ -75,10 +69,6 @@ export default {
errors.push(this.t('validation.required', { key: this.t('harvester.addons.rancherK3k.hostname') }, true)); errors.push(this.t('validation.required', { key: this.t('harvester.addons.rancherK3k.hostname') }, true));
} }
if (!this.valuesContentJson.rancher.version) {
errors.push(this.t('validation.required', { key: this.t('harvester.addons.rancherK3k.version') }, true));
}
if (!this.valuesContentJson.rancher.bootstrapPassword) { if (!this.valuesContentJson.rancher.bootstrapPassword) {
errors.push(this.t('validation.required', { key: this.t('harvester.addons.rancherK3k.password') }, true)); errors.push(this.t('validation.required', { key: this.t('harvester.addons.rancherK3k.password') }, true));
} }
@@ -135,8 +125,7 @@ export default {
v-model:value="valuesContentJson.rancher.version" v-model:value="valuesContentJson.rancher.version"
label-key="harvester.addons.rancherK3k.version" label-key="harvester.addons.rancherK3k.version"
:required="true" :required="true"
:mode="mode" :disabled="false"
placeholder="v1.14.0"
/> />
</div> </div>
</div> </div>
@@ -149,7 +138,6 @@ export default {
:mode="mode" :mode="mode"
:required="true" :required="true"
type="password" type="password"
:tooltip="t('harvester.addons.rancherK3k.passwordTooltip')"
/> />
</div> </div>
</div> </div>
+4 -17
View File
@@ -1,4 +1,4 @@
wizard: advancedSettingswizard:
create: Create create: Create
next: Proceed next: Proceed
previous: Back previous: Back
@@ -84,8 +84,6 @@ dialog:
harvester: harvester:
branding: branding:
primeLabel: '{vendor}'
primeEmptyLabel: ''
logos: logos:
tip: 'Upload a logo to replace the Harvester logo in the top-level navigation header. Image height should be 21 pixels with a max width of 200 pixels. Max file size is 20KB. Accepted formats: JPEG, PNG, SVG.' tip: 'Upload a logo to replace the Harvester logo in the top-level navigation header. Image height should be 21 pixels with a max width of 200 pixels. Max file size is 20KB. Accepted formats: JPEG, PNG, SVG.'
favicon: favicon:
@@ -1827,6 +1825,7 @@ harvester:
'harvester-system/pcidevices-controller': pcidevices-controller is an add-on to help discover PCI devices for nodes in your cluster and allow users to prepare devices for PCI Passthrough, for use with Harvester virtual machine and guest clusters. 'harvester-system/pcidevices-controller': pcidevices-controller is an add-on to help discover PCI devices for nodes in your cluster and allow users to prepare devices for PCI Passthrough, for use with Harvester virtual machine and guest clusters.
'cattle-logging-system/rancher-logging': rancher-logging is an add-on to collect versatile logs, events, and audits from the Harvester cluster and route them to many kinds of servers based on flows. 'cattle-logging-system/rancher-logging': rancher-logging is an add-on to collect versatile logs, events, and audits from the Harvester cluster and route them to many kinds of servers based on flows.
'harvester-system/rancher-vcluster': rancher-vcluster deploys a virtual cluster (vcluster) with Rancher installed. 'harvester-system/rancher-vcluster': rancher-vcluster deploys a virtual cluster (vcluster) with Rancher installed.
'k3k-system/k3k': k3k deploys a k3k virtual cluster with Rancher installed.
'cattle-monitoring-system/rancher-monitoring': rancher-monitoring is an add-on that collects Harvester cluster and virtual machine metrics and allows you to view the metrics on an embedded dashboard and send alert(s) to remote servers. 'cattle-monitoring-system/rancher-monitoring': rancher-monitoring is an add-on that collects Harvester cluster and virtual machine metrics and allows you to view the metrics on an embedded dashboard and send alert(s) to remote servers.
'vm-import-controller': vm-import-controller is an add-on to help migrate virtual machine workloads from other source clusters to an existing Harvester cluster. 'vm-import-controller': vm-import-controller is an add-on to help migrate virtual machine workloads from other source clusters to an existing Harvester cluster.
'pcidevices-controller': pcidevices-controller is an add-on to help discover PCI devices for nodes in your cluster and allow users to prepare devices for PCI Passthrough, for use with Harvester virtual machines and guest clusters. 'pcidevices-controller': pcidevices-controller is an add-on to help discover PCI devices for nodes in your cluster and allow users to prepare devices for PCI Passthrough, for use with Harvester virtual machines and guest clusters.
@@ -1834,8 +1833,7 @@ harvester:
'rancher-logging': rancher-logging is an add-on to collect versatile logs, events, and audits from the Harvester cluster and route them to many kinds of servers based on flows. 'rancher-logging': rancher-logging is an add-on to collect versatile logs, events, and audits from the Harvester cluster and route them to many kinds of servers based on flows.
'rancher-monitoring': rancher-monitoring is an add-on to collect Harvester cluster and virtual machine metrics, view them on the embedded dashboard, and send alert(s) to remote servers. 'rancher-monitoring': rancher-monitoring is an add-on to collect Harvester cluster and virtual machine metrics, view them on the embedded dashboard, and send alert(s) to remote servers.
'rancher-vcluster': rancher-vcluster deploys a virtual cluster (vcluster) with Rancher installed. 'rancher-vcluster': rancher-vcluster deploys a virtual cluster (vcluster) with Rancher installed.
'k3k': k3k is an add-on to deploy the k3k controller. 'k3k': k3k deploys a k3k virtual cluster with Rancher installed.
'rancher-k3k': rancher-k3k deploys a k3k virtual cluster with Rancher installed.
'harvester-seeder': harvester-seeder is an add-on that uses IPMI and Redfish to discover hardware information and perform out-of-band operations. 'harvester-seeder': harvester-seeder is an add-on that uses IPMI and Redfish to discover hardware information and perform out-of-band operations.
'harvester-system/harvester-seeder': harvester-seeder is an add-on that uses IPMI and Redfish to discover hardware information and perform out-of-band operations. 'harvester-system/harvester-seeder': harvester-seeder is an add-on that uses IPMI and Redfish to discover hardware information and perform out-of-band operations.
'harvester-csi-driver-lvm': harvester-csi-driver-lvm is an add-on allowing users to create PVC through the LVM with local devices. 'harvester-csi-driver-lvm': harvester-csi-driver-lvm is an add-on allowing users to create PVC through the LVM with local devices.
@@ -2145,9 +2143,6 @@ harvester:
hostname: Hostname hostname: Hostname
version: Rancher Version version: Rancher Version
password: Bootstrap Password password: Bootstrap Password
passwordTooltip: The initial password in Rancher for the first time login.
enable:
title: Enable K3k
switchFailed: "{action} {name} failed!" switchFailed: "{action} {name} failed!"
nvidiaDriverToolkit: nvidiaDriverToolkit:
titles: titles:
@@ -2429,15 +2424,7 @@ typeDescription:
harvester: "Branding allows administrators to globally re-brand the UI by customizing the Harvester product name, logos and color scheme." harvester: "Branding allows administrators to globally re-brand the UI by customizing the Harvester product name, logos and color scheme."
advancedSettings: advancedSettings:
tags: experimental: 'Experimental features allow users to test and evaluate early-access functionality prior to official supported releases'
modified:
label: Modified
experimental:
label: Experimental
description: 'Experimental: The feature is incomplete but its essential functionality is operational. The feature is not recommended for use in production environments.'
preview:
label: Technical Preview
description: 'Technical Preview: The feature is almost complete and its functionality is not expected to change significantly. Explore the feature extensively before using in production environments.'
descriptions: descriptions:
'harv-vlan': Default Network Interface name of the VLAN network. 'harv-vlan': Default Network Interface name of the VLAN network.
'harv-backup-target': Custom backup target to store virtual machine backups. 'harv-backup-target': Custom backup target to store virtual machine backups.
+1 -1
View File
@@ -72,7 +72,7 @@ export default {
/> />
<a <a
v-if="['rancher-vcluster', 'rancher-k3k'].includes(scope.row.metadata.name) && scope.row.spec.enabled" v-if="['rancher-vcluster', 'k3k'].includes(scope.row.metadata.name) && scope.row.spec.enabled"
v-tooltip="t('harvester.addons.rancherVcluster.accessRancher')" v-tooltip="t('harvester.addons.rancherVcluster.accessRancher')"
class="ml-5" class="ml-5"
rel="nofollow noopener noreferrer" rel="nofollow noopener noreferrer"
+1 -2
View File
@@ -1317,9 +1317,8 @@ export default {
case SOURCE_TYPE.IMAGE: { case SOURCE_TYPE.IMAGE: {
const image = this.images.find( (I) => R.image === I.id); const image = this.images.find( (I) => R.image === I.id);
out.spec.storageClassName = R.realName ? R.storageClassName : (R.storageClassName || image?.storageClassName);
if (image) { if (image) {
out.spec.storageClassName = image.storageClassName;
out.metadata.annotations = { [HCI_ANNOTATIONS.IMAGE_ID]: image.id }; out.metadata.annotations = { [HCI_ANNOTATIONS.IMAGE_ID]: image.id };
} else { } else {
out.metadata.annotations = { [HCI_ANNOTATIONS.IMAGE_ID]: '' }; out.metadata.annotations = { [HCI_ANNOTATIONS.IMAGE_ID]: '' };
+3 -12
View File
@@ -6,13 +6,13 @@ import { HCI } from '../types';
const HARVESTER_NVIDIA_DRIVER_TOOLKIT = 'harvester-system/nvidia-driver-toolkit'; const HARVESTER_NVIDIA_DRIVER_TOOLKIT = 'harvester-system/nvidia-driver-toolkit';
const RANCHER_VCLUSTER = 'harvester-system/rancher-vcluster'; const RANCHER_VCLUSTER = 'harvester-system/rancher-vcluster';
const RANCHER_K3K_ADDON = 'rancher-k3k/rancher-k3k'; const RANCHER_K3K = 'k3k-system/k3k';
export default class HciAddonConfig extends HarvesterResource { export default class HciAddonConfig extends HarvesterResource {
get availableActions() { get availableActions() {
const out = super._availableActions; const out = super._availableActions;
if (this.id === RANCHER_VCLUSTER || this.id === RANCHER_K3K_ADDON) { if (this.id === RANCHER_VCLUSTER || this.id === RANCHER_K3K) {
const rancherDashboard = { const rancherDashboard = {
action: 'goToRancher', action: 'goToRancher',
enabled: this.spec.enabled, enabled: this.spec.enabled,
@@ -59,15 +59,6 @@ export default class HciAddonConfig extends HarvesterResource {
return; return;
} }
if (!this.spec.enabled && this.id === RANCHER_K3K_ADDON) {
this.$dispatch('promptModal', {
resources: [this],
component: 'HarvesterEnableK3k',
});
return;
}
this.spec.enabled = !this.spec.enabled; this.spec.enabled = !this.spec.enabled;
await this.save(); await this.save();
} catch (err) { } catch (err) {
@@ -90,7 +81,7 @@ export default class HciAddonConfig extends HarvesterResource {
const valuesContent = jsyaml.load(this.spec.valuesContent) || {}; const valuesContent = jsyaml.load(this.spec.valuesContent) || {};
// rancher-k3k nests the hostname under `rancher`, rancher-vcluster keeps it at the top level // rancher-k3k nests the hostname under `rancher`, rancher-vcluster keeps it at the top level
const hostname = this.id === RANCHER_K3K_ADDON ? valuesContent.rancher?.hostname : valuesContent.hostname; const hostname = this.id === RANCHER_K3K ? valuesContent.rancher?.hostname : valuesContent.hostname;
return `https://${ hostname }`; return `https://${ hostname }`;
} }
+2 -14
View File
@@ -63,7 +63,6 @@ export default {
return { return {
vendor: getVendor(), vendor: getVendor(),
uiPLSetting: {}, uiPLSetting: {},
privateLabelDraft: null,
uiLogoDarkSetting: {}, uiLogoDarkSetting: {},
uiLogoDark: '', uiLogoDark: '',
uiLogoLightSetting: {}, uiLogoLightSetting: {},
@@ -82,17 +81,6 @@ export default {
}; };
}, },
computed: { computed: {
isHarvesterPrime() {
return !!this.$store.getters['harvester-common/isHarvesterPrime'];
},
privateLabel: {
get() {
return this.privateLabelDraft ?? (this.isHarvesterPrime ? this.$store.getters['harvester-common/privateLabel'] : this.uiPLSetting.value);
},
set(value) {
this.privateLabelDraft = value;
}
},
mode() { mode() {
const schema = this.$store.getters[`management/schemaFor`](MANAGEMENT.SETTING); const schema = this.$store.getters[`management/schemaFor`](MANAGEMENT.SETTING);
@@ -124,7 +112,7 @@ export default {
this.errors.push(e); this.errors.push(e);
}, },
async save(btnCB) { async save(btnCB) {
this.uiPLSetting.value = (this.privateLabel || '').replaceAll(/[\<>&=#()"]/gm, ''); this.uiPLSetting.value = this.uiPLSetting.value.replaceAll(/[\<>&=#()"]/gm, '');
if (this.customizeLogo) { if (this.customizeLogo) {
this.uiLogoLightSetting.value = this.uiLogoLight; this.uiLogoLightSetting.value = this.uiLogoLight;
this.uiLogoDarkSetting.value = this.uiLogoDark; this.uiLogoDarkSetting.value = this.uiLogoDark;
@@ -181,7 +169,7 @@ export default {
<div class="row mb-20"> <div class="row mb-20">
<div class="col span-6"> <div class="col span-6">
<LabeledInput <LabeledInput
v-model:value="privateLabel" v-model:value="uiPLSetting.value"
:label="t('branding.uiPL.label')" :label="t('branding.uiPL.label')"
:mode="mode" :mode="mode"
:maxlength="100" :maxlength="100"
-19
View File
@@ -1,6 +1,4 @@
import Parse from 'url-parse'; import Parse from 'url-parse';
import { MANAGEMENT } from '@shell/config/types';
import { SETTING } from '@shell/config/settings';
import { HCI } from '../types'; import { HCI } from '../types';
import { PRODUCT_NAME } from '../config/harvester'; import { PRODUCT_NAME } from '../config/harvester';
import { featureEnabled, getVersion } from '../utils/feature-flags'; import { featureEnabled, getVersion } from '../utils/feature-flags';
@@ -66,23 +64,6 @@ const mutations = {
}; };
const getters = { const getters = {
isHarvesterPrime: (_state, _getters, _rootState, rootGetters) => {
const setting = rootGetters['harvester/byId']?.(HCI.SETTING, 'server-flavor');
return (setting?.value || setting?.default) === 'prime';
},
privateLabel: (_state, getters, _rootState, rootGetters) => {
const setting = rootGetters['management/byId']?.(MANAGEMENT.SETTING, SETTING.PL);
const value = setting?.value || '';
if (getters.isHarvesterPrime && value === (setting?.default || 'Harvester')) {
return '';
}
return value;
},
getBundleId(state) { getBundleId(state) {
return state.latestBundleId; return state.latestBundleId;
}, },
+1352 -1462
View File
File diff suppressed because it is too large Load Diff