mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-07 22:56:07 +08:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2aaa0a55a2 | ||
|
|
5c2a23924d | ||
|
|
7af8a82838 | ||
|
|
3b343bcaca | ||
|
|
6ddd35d661 | ||
|
|
bd28ba6f71 | ||
|
|
4bb67153ce |
@@ -50,6 +50,7 @@ jobs:
|
|||||||
|
|
||||||
echo "FROM=$FROM"
|
echo "FROM=$FROM"
|
||||||
echo "TO=$TO"
|
echo "TO=$TO"
|
||||||
|
|
||||||
npx commitlint --from "$FROM" --to "$TO" --verbose
|
npx commitlint --from "$FROM" --to "$TO" --verbose
|
||||||
env:
|
env:
|
||||||
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ export const DOC = {
|
|||||||
STORAGE_NETWORK_EXAMPLE: `/advanced/storagenetwork#configuration-example`,
|
STORAGE_NETWORK_EXAMPLE: `/advanced/storagenetwork#configuration-example`,
|
||||||
SUPPORT_BUNDLE_NAMESPACES: `/advanced/index/#support-bundle-namespaces`,
|
SUPPORT_BUNDLE_NAMESPACES: `/advanced/index/#support-bundle-namespaces`,
|
||||||
VPC_CONFIGURATION_EXAMPLES: `/networking/kubeovn-vpc#vpc-peering-configuration-examples`,
|
VPC_CONFIGURATION_EXAMPLES: `/networking/kubeovn-vpc#vpc-peering-configuration-examples`,
|
||||||
|
NETWORK_POLICY: `/networking/kubeovn-vm-isolation/#network-policies`,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ const FEATURE_FLAGS = {
|
|||||||
],
|
],
|
||||||
'v1.5.1': [],
|
'v1.5.1': [],
|
||||||
'v1.6.0': [
|
'v1.6.0': [
|
||||||
'vmMachineTypes',
|
|
||||||
'customSupportBundle',
|
'customSupportBundle',
|
||||||
'csiOnlineExpandValidation',
|
'csiOnlineExpandValidation',
|
||||||
'vmNetworkMigration',
|
'vmNetworkMigration',
|
||||||
@@ -50,7 +49,9 @@ const FEATURE_FLAGS = {
|
|||||||
'vmCloneRunStrategy',
|
'vmCloneRunStrategy',
|
||||||
],
|
],
|
||||||
'v1.6.1': [],
|
'v1.6.1': [],
|
||||||
'v1.7.0': []
|
'v1.7.0': [
|
||||||
|
'vmMachineTypeAuto'
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateFeatureFlags = () => {
|
const generateFeatureFlags = () => {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
LOGGING,
|
LOGGING,
|
||||||
STORAGE_CLASS,
|
STORAGE_CLASS,
|
||||||
SECRET,
|
SECRET,
|
||||||
|
NETWORK_POLICY
|
||||||
} from '@shell/config/types';
|
} from '@shell/config/types';
|
||||||
import { HCI, VOLUME_SNAPSHOT } from '../types';
|
import { HCI, VOLUME_SNAPSHOT } from '../types';
|
||||||
import {
|
import {
|
||||||
@@ -425,6 +426,7 @@ export function init($plugin, store) {
|
|||||||
HCI.CLUSTER_NETWORK,
|
HCI.CLUSTER_NETWORK,
|
||||||
HCI.NETWORK_ATTACHMENT,
|
HCI.NETWORK_ATTACHMENT,
|
||||||
HCI.VPC,
|
HCI.VPC,
|
||||||
|
NETWORK_POLICY,
|
||||||
HCI.LB,
|
HCI.LB,
|
||||||
HCI.IP_POOL,
|
HCI.IP_POOL,
|
||||||
],
|
],
|
||||||
@@ -566,6 +568,21 @@ export function init($plugin, store) {
|
|||||||
ifHaveType: HCI.VPC,
|
ifHaveType: HCI.VPC,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
configureType(NETWORK_POLICY, { hiddenNamespaceGroupButton: true, canYaml: false });
|
||||||
|
|
||||||
|
virtualType({
|
||||||
|
labelKey: 'harvester.networkPolicy.label',
|
||||||
|
name: NETWORK_POLICY,
|
||||||
|
namespaced: true,
|
||||||
|
weight: 186,
|
||||||
|
route: {
|
||||||
|
name: `${ PRODUCT_NAME }-c-cluster-resource`,
|
||||||
|
params: { resource: NETWORK_POLICY }
|
||||||
|
},
|
||||||
|
exact: false,
|
||||||
|
ifHaveType: NETWORK_POLICY,
|
||||||
|
});
|
||||||
|
|
||||||
configureType(HCI.SNAPSHOT, {
|
configureType(HCI.SNAPSHOT, {
|
||||||
isCreatable: false,
|
isCreatable: false,
|
||||||
location: {
|
location: {
|
||||||
|
|||||||
@@ -338,6 +338,15 @@ export default {
|
|||||||
saveVM(buttonCb) {
|
saveVM(buttonCb) {
|
||||||
clear(this.errors);
|
clear(this.errors);
|
||||||
|
|
||||||
|
this.validateCPUMemory();
|
||||||
|
|
||||||
|
// block create VM flow if has validation errors
|
||||||
|
if (this.errors.length) {
|
||||||
|
buttonCb(false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.isSingle) {
|
if (this.isSingle) {
|
||||||
this.saveSingle(buttonCb);
|
this.saveSingle(buttonCb);
|
||||||
} else {
|
} else {
|
||||||
@@ -345,6 +354,18 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
validateCPUMemory() {
|
||||||
|
const { cpu, memory } = this;
|
||||||
|
|
||||||
|
if ((!cpu)) {
|
||||||
|
this.errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.input.cpu') }, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!memory)) {
|
||||||
|
this.errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.input.memory') }, true));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async saveSingle(buttonCb) {
|
async saveSingle(buttonCb) {
|
||||||
this.parseVM();
|
this.parseVM();
|
||||||
this.value.spec.template.spec.hostname = this.hostname ? this.hostname : this.value.metadata.name;
|
this.value.spec.template.spec.hostname = this.hostname ? this.hostname : this.value.metadata.name;
|
||||||
@@ -466,9 +487,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cpuMemoryErrors = this.getCPUMemoryValidation();
|
const errors = this.getAccessCredentialsValidation();
|
||||||
const accessCredentialsErrors = this.getAccessCredentialsValidation();
|
|
||||||
const errors = [...cpuMemoryErrors, ...accessCredentialsErrors];
|
|
||||||
|
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
return Promise.reject(errors);
|
return Promise.reject(errors);
|
||||||
@@ -873,7 +892,10 @@ export default {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col span-6">
|
<div
|
||||||
|
v-if="!value.vmMachineTypeAutoFeatureEnabled"
|
||||||
|
class="col span-6"
|
||||||
|
>
|
||||||
<LabeledSelect
|
<LabeledSelect
|
||||||
v-model:value="machineType"
|
v-model:value="machineType"
|
||||||
label-key="harvester.virtualMachine.input.MachineType"
|
label-key="harvester.virtualMachine.input.MachineType"
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<script>
|
||||||
|
import NetworkPolicy from '@shell/edit/networking.k8s.io.networkpolicy';
|
||||||
|
import { Banner } from '@components/Banner';
|
||||||
|
import { DOC } from '../config/doc-links';
|
||||||
|
import { docLink } from '../utils/feature-flags';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
NetworkPolicy,
|
||||||
|
Banner
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
networkPolicyDocLink() {
|
||||||
|
const version = this.$store.getters['harvester-common/getServerVersion']();
|
||||||
|
|
||||||
|
return docLink(DOC.NETWORK_POLICY, version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="network-policy-edit">
|
||||||
|
<Banner color="info">
|
||||||
|
<t
|
||||||
|
k="harvester.networkPolicy.banner"
|
||||||
|
:url="networkPolicyDocLink"
|
||||||
|
:raw="true"
|
||||||
|
/>
|
||||||
|
</Banner>
|
||||||
|
<NetworkPolicy v-bind="$attrs" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.network-policy-edit {
|
||||||
|
flex: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1106,6 +1106,9 @@ harvester:
|
|||||||
remoteVpc:
|
remoteVpc:
|
||||||
label: Remote VPC
|
label: Remote VPC
|
||||||
infoBanner: The static route destination CIDR must cover all subnets CIDR from remote VPC Peer. Read <a href="{url}" target="_blank">VPC Peering Configuration Examples</a> for more information.
|
infoBanner: The static route destination CIDR must cover all subnets CIDR from remote VPC Peer. Read <a href="{url}" target="_blank">VPC Peering Configuration Examples</a> for more information.
|
||||||
|
networkPolicy:
|
||||||
|
label: Network Policies
|
||||||
|
banner: The network policies must be used for VMs attached to overlay networks. Please read the <a href="{url}" target="_blank">harvester document</a> how the network policy works.
|
||||||
network:
|
network:
|
||||||
label: Virtual Machine Networks
|
label: Virtual Machine Networks
|
||||||
tabs:
|
tabs:
|
||||||
@@ -1832,6 +1835,11 @@ typeLabel:
|
|||||||
one { Virtual Private Cloud }
|
one { Virtual Private Cloud }
|
||||||
other { Virtual Private Clouds }
|
other { Virtual Private Clouds }
|
||||||
}
|
}
|
||||||
|
networking.k8s.io.networkpolicy: |-
|
||||||
|
{count, plural,
|
||||||
|
one { Network Policy }
|
||||||
|
other { Network Policies }
|
||||||
|
}
|
||||||
harvesterhci.io.cloudtemplate: |-
|
harvesterhci.io.cloudtemplate: |-
|
||||||
{count, plural,
|
{count, plural,
|
||||||
one { Cloud Configuration Template }
|
one { Cloud Configuration Template }
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ export default {
|
|||||||
|
|
||||||
needNewSecret() {
|
needNewSecret() {
|
||||||
// When creating a template it is always necessary to create a new secret.
|
// When creating a template it is always necessary to create a new secret.
|
||||||
return this.showYaml ? false : this.resourceType === HCI.VM_VERSION || this.isCreate;
|
return this.isCreate ? true : this.showYaml ? false : this.resourceType === HCI.VM_VERSION;
|
||||||
},
|
},
|
||||||
|
|
||||||
defaultTerminationSetting() {
|
defaultTerminationSetting() {
|
||||||
@@ -299,9 +299,11 @@ export default {
|
|||||||
async created() {
|
async created() {
|
||||||
await this.$store.dispatch(`${ this.inStore }/findAll`, { type: SECRET });
|
await this.$store.dispatch(`${ this.inStore }/findAll`, { type: SECRET });
|
||||||
|
|
||||||
if (this.value.vmMachineTypesFeatureEnabled) {
|
if (!this.value.vmMachineTypeAutoFeatureEnabled) {
|
||||||
try {
|
try {
|
||||||
const url = this.$store.getters['harvester-common/getHarvesterClusterUrl']('v1/harvester/clusters/local?link=machineTypes');
|
const url = this.$store.getters['harvester-common/getHarvesterClusterUrl'](
|
||||||
|
'v1/harvester/clusters/local?link=machineTypes'
|
||||||
|
);
|
||||||
const machineTypes = await this.$store.dispatch('harvester/request', { url });
|
const machineTypes = await this.$store.dispatch('harvester/request', { url });
|
||||||
|
|
||||||
this.machineTypes = machineTypes;
|
this.machineTypes = machineTypes;
|
||||||
@@ -687,14 +689,12 @@ export default {
|
|||||||
set(this.spec.template.spec, 'domain.memory.maxGuest', this.maxMemory);
|
set(this.spec.template.spec, 'domain.memory.maxGuest', this.maxMemory);
|
||||||
set(this.spec.template.spec, 'domain.resources.limits.memory', this.maxMemory);
|
set(this.spec.template.spec, 'domain.resources.limits.memory', this.maxMemory);
|
||||||
} else {
|
} else {
|
||||||
|
this.spec.template.spec.domain.cpu.maxSockets = 1;
|
||||||
this.spec.template.spec.domain.cpu.sockets = 1;
|
this.spec.template.spec.domain.cpu.sockets = 1;
|
||||||
this.spec.template.spec.domain.cpu.cores = this.cpu;
|
this.spec.template.spec.domain.cpu.cores = this.cpu;
|
||||||
this.spec.template.spec.domain.resources.limits.cpu = this.cpu?.toString();
|
this.spec.template.spec.domain.resources.limits.cpu = this.cpu?.toString();
|
||||||
this.spec.template.spec.domain.resources.limits.memory = this.memory;
|
this.spec.template.spec.domain.resources.limits.memory = this.memory;
|
||||||
// clean below fields as we don't need them if not enable CPU and memory hotplug
|
// clean below fields as we don't need them if not enable CPU and memory hotplug
|
||||||
if (this.spec?.template?.spec?.domain?.cpu?.maxSockets) {
|
|
||||||
delete this.spec.template.spec.domain.cpu.maxSockets;
|
|
||||||
}
|
|
||||||
if (this.spec?.template?.spec?.domain?.memory?.maxGuest) {
|
if (this.spec?.template?.spec?.domain?.memory?.maxGuest) {
|
||||||
delete this.spec.template.spec.domain.memory.maxGuest;
|
delete this.spec.template.spec.domain.memory.maxGuest;
|
||||||
}
|
}
|
||||||
@@ -1369,21 +1369,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getCPUMemoryValidation() {
|
|
||||||
const errors = [];
|
|
||||||
const { cpu, memory } = this;
|
|
||||||
|
|
||||||
if ((!cpu)) {
|
|
||||||
errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.input.cpu') }, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!memory)) {
|
|
||||||
errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.input.memory') }, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
},
|
|
||||||
|
|
||||||
getAccessCredentialsValidation() {
|
getAccessCredentialsValidation() {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
||||||
|
|||||||
@@ -1236,8 +1236,8 @@ export default class VirtVm extends HarvesterResource {
|
|||||||
return this.$rootGetters['harvester-common/getFeatureEnabled']('thirdPartyStorage');
|
return this.$rootGetters['harvester-common/getFeatureEnabled']('thirdPartyStorage');
|
||||||
}
|
}
|
||||||
|
|
||||||
get vmMachineTypesFeatureEnabled() {
|
get vmMachineTypeAutoFeatureEnabled() {
|
||||||
return this.$rootGetters['harvester-common/getFeatureEnabled']('vmMachineTypes');
|
return this.$rootGetters['harvester-common/getFeatureEnabled']('vmMachineTypeAuto');
|
||||||
}
|
}
|
||||||
|
|
||||||
get isBackupTargetUnavailable() {
|
get isBackupTargetUnavailable() {
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ export default class HciVlanConfig extends HarvesterResource {
|
|||||||
uplink: {
|
uplink: {
|
||||||
nics: [],
|
nics: [],
|
||||||
linkAttributes: {},
|
linkAttributes: {},
|
||||||
bondOptions: { mode: 'active-backup' },
|
bondOptions: {
|
||||||
|
mode: 'active-backup',
|
||||||
|
miimon: -1
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,17 +3,19 @@ import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations
|
|||||||
export function getVmCPUMemoryValues(vm) {
|
export function getVmCPUMemoryValues(vm) {
|
||||||
if (!vm) {
|
if (!vm) {
|
||||||
return {
|
return {
|
||||||
cpu: 0,
|
cpu: null,
|
||||||
memory: null,
|
memory: null,
|
||||||
isHotplugEnabled: false
|
isHotplugEnabled: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const isHotplugEnabled = isCPUMemoryHotPlugEnabled(vm);
|
const isHotplugEnabled = isCPUMemoryHotPlugEnabled(vm);
|
||||||
|
const { sockets = 1, threads = 1, cores = null } = vm.spec.template.spec.domain.cpu || {};
|
||||||
|
const cpu = cores === null ? null : sockets * threads * cores;
|
||||||
|
|
||||||
if (isHotplugEnabled) {
|
if (isHotplugEnabled) {
|
||||||
return {
|
return {
|
||||||
cpu: vm.spec.template.spec.domain.cpu.sockets,
|
cpu,
|
||||||
memory: vm.spec.template.spec.domain?.memory?.guest || null,
|
memory: vm.spec.template.spec.domain?.memory?.guest || null,
|
||||||
maxCpu: vm.spec.template.spec.domain.cpu?.maxSockets || 0,
|
maxCpu: vm.spec.template.spec.domain.cpu?.maxSockets || 0,
|
||||||
maxMemory: vm.spec.template.spec.domain?.memory?.maxGuest || null,
|
maxMemory: vm.spec.template.spec.domain?.memory?.maxGuest || null,
|
||||||
@@ -21,7 +23,7 @@ export function getVmCPUMemoryValues(vm) {
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
cpu: vm.spec.template.spec.domain.cpu.cores,
|
cpu,
|
||||||
memory: vm.spec.template.spec.domain.resources?.limits?.memory || null,
|
memory: vm.spec.template.spec.domain.resources?.limits?.memory || null,
|
||||||
isHotplugEnabled
|
isHotplugEnabled
|
||||||
};
|
};
|
||||||
@@ -29,8 +31,5 @@ export function getVmCPUMemoryValues(vm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isCPUMemoryHotPlugEnabled(vm) {
|
export function isCPUMemoryHotPlugEnabled(vm) {
|
||||||
return vm?.metadata?.annotations[HCI_ANNOTATIONS.VM_CPU_MEMORY_HOTPLUG] === 'true' ||
|
return vm?.metadata?.annotations[HCI_ANNOTATIONS.VM_CPU_MEMORY_HOTPLUG] === 'true' || !!vm?.spec?.template?.spec?.domain?.memory?.maxGuest || false;
|
||||||
!!vm?.spec?.template?.spec?.domain.cpu?.maxSockets ||
|
|
||||||
!!vm?.spec?.template?.spec?.domain?.memory?.maxGuest ||
|
|
||||||
false;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3114,9 +3114,9 @@
|
|||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/node@*", "@types/node@20.10.8", "@types/node@^14.14.31", "@types/node@~20.19.0":
|
"@types/node@*", "@types/node@20.10.8", "@types/node@^14.14.31", "@types/node@~20.19.0":
|
||||||
version "20.19.17"
|
version "20.19.19"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.17.tgz#41b52697373aef8a43b3b92f33b43f329b2d674b"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.19.tgz#18c8982becd5728f92e5f1939f2f3dc85604abcd"
|
||||||
integrity sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==
|
integrity sha512-pb1Uqj5WJP7wrcbLU7Ru4QtA0+3kAXrkutGiD26wUKzSMgNNaPARTUDQmElUXp64kh3cWdou3Q0C7qwwxqSFmg==
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types "~6.21.0"
|
undici-types "~6.21.0"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user