Allow uploading of ISO for creating kubernetes supported versions (#9561)

This commit is contained in:
Vishesh 2025-10-13 16:21:30 +05:30 committed by GitHub
parent 8464e46b53
commit 0ca267f516
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 414 additions and 49 deletions

View File

@ -81,6 +81,34 @@ public abstract class AbstractGetUploadParamsCmd extends BaseCmd {
return projectId; return projectId;
} }
public void setName(String name) {
this.name = name;
}
public void setFormat(String format) {
this.format = format;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
public void setChecksum(String checksum) {
this.checksum = checksum;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
public void setProjectId(Long projectId) {
this.projectId = projectId;
}
public GetUploadParamsResponse createGetUploadParamsResponse(UUID id, URL postURL, String metadata, String timeout, String signature) { public GetUploadParamsResponse createGetUploadParamsResponse(UUID id, URL postURL, String metadata, String timeout, String signature) {
return new GetUploadParamsResponse(id, postURL, metadata, timeout, signature); return new GetUploadParamsResponse(id, postURL, metadata, timeout, signature);
} }

View File

@ -104,6 +104,29 @@ public class GetUploadParamsForIsoCmd extends AbstractGetUploadParamsCmd {
return osTypeId; return osTypeId;
} }
public void setBootable(Boolean bootable) {
this.bootable = bootable;
}
public void setDisplayText(String displayText) {
this.displayText = displayText;
}
public void setFeatured(Boolean featured) {
this.featured = featured;
}
public void setPublicIso(Boolean publicIso) {
this.publicIso = publicIso;
}
public void setExtractable(Boolean extractable) {
this.extractable = extractable;
}
public void setOsTypeId(Long osTypeId) {
this.osTypeId = osTypeId;
}
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
/////////////// API Implementation/////////////////// /////////////// API Implementation///////////////////

View File

@ -62,6 +62,10 @@ public class GetUploadParamsResponse extends BaseResponse {
setObjectName("getuploadparams"); setObjectName("getuploadparams");
} }
public UUID getId() {
return id;
}
public void setId(UUID id) { public void setId(UUID id) {
this.id = id; this.id = id;
} }

View File

@ -17,6 +17,7 @@
package com.cloud.kubernetes.version; package com.cloud.kubernetes.version;
import java.net.MalformedURLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -26,10 +27,13 @@ import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd; import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd; import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.admin.kubernetes.version.GetUploadParamsForKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.admin.kubernetes.version.UpdateKubernetesSupportedVersionCmd; import org.apache.cloudstack.api.command.admin.kubernetes.version.UpdateKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.GetUploadParamsForIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesSupportedVersionsCmd; import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesSupportedVersionsCmd;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse; import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
@ -162,6 +166,33 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
return versions; return versions;
} }
private GetUploadParamsResponse registerKubernetesVersionIsoForUpload(final Long zoneId, final String versionName, final String isoChecksum) {
CallContext.register(CallContext.current(), ApiCommandResourceType.Iso);
String isoName = String.format("%s-Kubernetes-Binaries-ISO", versionName);
GetUploadParamsForIsoCmd uploadIso = new GetUploadParamsForIsoCmd();
uploadIso = ComponentContext.inject(uploadIso);
uploadIso.setName(isoName);
uploadIso.setPublicIso(true);
if (zoneId != null) {
uploadIso.setZoneId(zoneId);
}
uploadIso.setDisplayText(isoName);
uploadIso.setBootable(false);
if (StringUtils.isNotEmpty(isoChecksum)) {
uploadIso.setChecksum(isoChecksum);
}
uploadIso.setAccountName(accountManager.getSystemAccount().getAccountName());
uploadIso.setDomainId(accountManager.getSystemAccount().getDomainId());
try {
return templateService.registerIsoForPostUpload(uploadIso);
} catch (MalformedURLException | ResourceAllocationException e) {
logger.error(String.format("Unable to register binaries ISO for supported kubernetes version, %s", versionName), e);
throw new CloudRuntimeException(String.format("Unable to register binaries ISO for supported kubernetes version, %s", versionName), e);
} finally {
CallContext.unregister();
}
}
private VirtualMachineTemplate registerKubernetesVersionIso(final Long zoneId, final String versionName, final String isoUrl, final String isoChecksum, final boolean directDownload, CPU.CPUArch arch) throws IllegalAccessException, NoSuchFieldException, private VirtualMachineTemplate registerKubernetesVersionIso(final Long zoneId, final String versionName, final String isoUrl, final String isoChecksum, final boolean directDownload, CPU.CPUArch arch) throws IllegalAccessException, NoSuchFieldException,
IllegalArgumentException, ResourceAllocationException { IllegalArgumentException, ResourceAllocationException {
CallContext.register(CallContext.current(), ApiCommandResourceType.Iso); CallContext.register(CallContext.current(), ApiCommandResourceType.Iso);
@ -316,23 +347,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
return createKubernetesSupportedVersionListResponse(versions, versionsAndCount.second()); return createKubernetesSupportedVersionListResponse(versions, versionsAndCount.second());
} }
@Override private void validateKubernetesSupportedVersion(Long zoneId, String semanticVersion, Integer minimumCpu,
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD, Integer minimumRamSize, boolean isDirectDownload) {
eventDescription = "Adding Kubernetes supported version")
public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final AddKubernetesSupportedVersionCmd cmd) {
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
}
String name = cmd.getName();
final String semanticVersion = cmd.getSemanticVersion();
final Long zoneId = cmd.getZoneId();
final String isoUrl = cmd.getUrl();
final String isoChecksum = cmd.getChecksum();
final Integer minimumCpu = cmd.getMinimumCpu();
final Integer minimumRamSize = cmd.getMinimumRamSize();
final boolean isDirectDownload = cmd.isDirectDownload();
CPU.CPUArch arch = cmd.getArch();
if (minimumCpu == null || minimumCpu < KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_CPU) { if (minimumCpu == null || minimumCpu < KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_CPU) {
throw new InvalidParameterValueException(String.format("Invalid value for %s parameter. Minimum %d vCPUs required.", ApiConstants.MIN_CPU_NUMBER, KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_CPU)); throw new InvalidParameterValueException(String.format("Invalid value for %s parameter. Minimum %d vCPUs required.", ApiConstants.MIN_CPU_NUMBER, KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_CPU));
} }
@ -351,6 +367,27 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
throw new InvalidParameterValueException(String.format("Zone: %s supports only direct download Kubernetes versions", zone.getName())); throw new InvalidParameterValueException(String.format("Zone: %s supports only direct download Kubernetes versions", zone.getName()));
} }
} }
}
@Override
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
eventDescription = "Adding Kubernetes supported version")
public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final AddKubernetesSupportedVersionCmd cmd) {
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
}
String name = cmd.getName();
final String semanticVersion = cmd.getSemanticVersion();
final Long zoneId = cmd.getZoneId();
final String isoUrl = cmd.getUrl();
final String isoChecksum = cmd.getChecksum();
final Integer minimumCpu = cmd.getMinimumCpu();
final Integer minimumRamSize = cmd.getMinimumRamSize();
final boolean isDirectDownload = cmd.isDirectDownload();
CPU.CPUArch arch = cmd.getArch();
validateKubernetesSupportedVersion(zoneId, semanticVersion, minimumCpu, minimumRamSize, isDirectDownload);
if (StringUtils.isEmpty(isoUrl)) { if (StringUtils.isEmpty(isoUrl)) {
throw new InvalidParameterValueException(String.format("Invalid URL for ISO specified, %s", isoUrl)); throw new InvalidParameterValueException(String.format("Invalid URL for ISO specified, %s", isoUrl));
} }
@ -377,6 +414,30 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
return createKubernetesSupportedVersionResponse(supportedVersionVO); return createKubernetesSupportedVersionResponse(supportedVersionVO);
} }
@Override
public GetUploadParamsResponse registerKubernetesSupportedVersionForPostUpload(GetUploadParamsForKubernetesSupportedVersionCmd cmd) {
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
}
String name = cmd.getName();
final String semanticVersion = cmd.getSemanticVersion();
final Long zoneId = cmd.getZoneId();
final String isoChecksum = cmd.getChecksum();
final Integer minimumCpu = cmd.getMinimumCpu();
final Integer minimumRamSize = cmd.getMinimumRamSize();
validateKubernetesSupportedVersion(zoneId, semanticVersion, minimumCpu, minimumRamSize, false);
GetUploadParamsResponse response = registerKubernetesVersionIsoForUpload(zoneId, name, isoChecksum);
VMTemplateVO template = templateDao.findByUuid(response.getId().toString());
KubernetesSupportedVersionVO supportedVersionVO = new KubernetesSupportedVersionVO(name, semanticVersion, template.getId(), zoneId, minimumCpu, minimumRamSize);
supportedVersionVO = kubernetesSupportedVersionDao.persist(supportedVersionVO);
CallContext.current().putContextParameter(KubernetesSupportedVersion.class, supportedVersionVO.getUuid());
return response;
}
@Override @Override
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_DELETE, @ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_DELETE,
eventDescription = "deleting Kubernetes supported version", async = true) eventDescription = "deleting Kubernetes supported version", async = true)
@ -445,6 +506,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
return cmdList; return cmdList;
} }
cmdList.add(AddKubernetesSupportedVersionCmd.class); cmdList.add(AddKubernetesSupportedVersionCmd.class);
cmdList.add(GetUploadParamsForKubernetesSupportedVersionCmd.class);
cmdList.add(ListKubernetesSupportedVersionsCmd.class); cmdList.add(ListKubernetesSupportedVersionsCmd.class);
cmdList.add(DeleteKubernetesSupportedVersionCmd.class); cmdList.add(DeleteKubernetesSupportedVersionCmd.class);
cmdList.add(UpdateKubernetesSupportedVersionCmd.class); cmdList.add(UpdateKubernetesSupportedVersionCmd.class);

View File

@ -19,8 +19,10 @@ package com.cloud.kubernetes.version;
import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd; import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd; import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.admin.kubernetes.version.GetUploadParamsForKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.admin.kubernetes.version.UpdateKubernetesSupportedVersionCmd; import org.apache.cloudstack.api.command.admin.kubernetes.version.UpdateKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesSupportedVersionsCmd; import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesSupportedVersionsCmd;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse; import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ListResponse;
@ -31,6 +33,7 @@ public interface KubernetesVersionService extends PluggableService {
static final String MIN_KUBERNETES_VERSION = "1.11.0"; static final String MIN_KUBERNETES_VERSION = "1.11.0";
ListResponse<KubernetesSupportedVersionResponse> listKubernetesSupportedVersions(ListKubernetesSupportedVersionsCmd cmd); ListResponse<KubernetesSupportedVersionResponse> listKubernetesSupportedVersions(ListKubernetesSupportedVersionsCmd cmd);
KubernetesSupportedVersionResponse addKubernetesSupportedVersion(AddKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException; KubernetesSupportedVersionResponse addKubernetesSupportedVersion(AddKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException;
GetUploadParamsResponse registerKubernetesSupportedVersionForPostUpload(GetUploadParamsForKubernetesSupportedVersionCmd cmd);
boolean deleteKubernetesSupportedVersion(DeleteKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException; boolean deleteKubernetesSupportedVersion(DeleteKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException;
KubernetesSupportedVersionResponse updateKubernetesSupportedVersion(UpdateKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException; KubernetesSupportedVersionResponse updateKubernetesSupportedVersion(UpdateKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException;
} }

View File

@ -0,0 +1,127 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.kubernetes.version;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.kubernetes.version.KubernetesSupportedVersion;
import com.cloud.kubernetes.version.KubernetesVersionService;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.AbstractGetUploadParamsCmd;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.admin.AdminCmd;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang3.StringUtils;
import javax.inject.Inject;
@APICommand(name = "getUploadParamsForKubernetesSupportedVersion",
description = "Upload a supported Kubernetes version",
responseObject = KubernetesSupportedVersionResponse.class,
responseView = ResponseObject.ResponseView.Full,
entityType = {KubernetesSupportedVersion.class},
authorized = {RoleType.Admin})
public class GetUploadParamsForKubernetesSupportedVersionCmd extends AbstractGetUploadParamsCmd implements AdminCmd {
@Inject
private KubernetesVersionService kubernetesVersionService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.SEMANTIC_VERSION, type = CommandType.STRING, required = true,
description = "the semantic version of the Kubernetes version. It needs to be specified in MAJOR.MINOR.PATCH format")
private String semanticVersion;
@Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING,
description = "the checksum value of the binaries ISO. " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
private String checksum;
@Parameter(name = ApiConstants.MIN_CPU_NUMBER, type = CommandType.INTEGER, required = true,
description = "the minimum number of CPUs to be set with the Kubernetes version")
private Integer minimumCpu;
@Parameter(name = ApiConstants.MIN_MEMORY, type = CommandType.INTEGER, required = true,
description = "the minimum RAM size in MB to be set with the Kubernetes version")
private Integer minimumRamSize;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getSemanticVersion() {
if(StringUtils.isEmpty(semanticVersion)) {
throw new InvalidParameterValueException("Version can not be null");
}
if(!semanticVersion.matches("[0-9]+(\\.[0-9]+)*")) {
throw new IllegalArgumentException("Invalid version format. Semantic version needed");
}
return semanticVersion;
}
public String getChecksum() {
return checksum;
}
public Integer getMinimumCpu() {
return minimumCpu;
}
public Integer getMinimumRamSize() {
return minimumRamSize;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccountId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesSupportedVersion;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() throws ServerApiException, ConcurrentOperationException {
if (getZoneId() <= 0) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid zoneid");
}
try {
GetUploadParamsResponse response = kubernetesVersionService.registerKubernetesSupportedVersionForPostUpload(this);
if (response == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Kubernetes supported version");
}
response.setResponseName(getCommandName());
setResponseObject(response);
} catch (CloudRuntimeException ex) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
}
}

View File

@ -1407,6 +1407,7 @@
"label.kubernetes.version.add": "Add Kubernetes version", "label.kubernetes.version.add": "Add Kubernetes version",
"label.kubernetes.version.delete": "Delete Kubernetes version", "label.kubernetes.version.delete": "Delete Kubernetes version",
"label.kubernetes.version.update": "Manage Kubernetes version", "label.kubernetes.version.update": "Manage Kubernetes version",
"label.kubernetes.version.from.local": "Add Kubernetes version from local",
"label.kubernetesversionid": "Kubernetes version", "label.kubernetesversionid": "Kubernetes version",
"label.kubernetesversionname": "Kubernetes version", "label.kubernetesversionname": "Kubernetes version",
"label.kvm": "KVM", "label.kvm": "KVM",

View File

@ -395,6 +395,15 @@ export default {
show: isZoneCreated, show: isZoneCreated,
component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue'))) component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue')))
}, },
{
api: 'getUploadParamsForKubernetesSupportedVersion',
icon: 'cloud-upload-outlined',
label: 'label.kubernetes.version.from.local',
listView: true,
popup: true,
show: isZoneCreated,
component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue')))
},
{ {
api: 'updateKubernetesSupportedVersion', api: 'updateKubernetesSupportedVersion',
icon: 'edit-outlined', icon: 'edit-outlined',

View File

@ -1434,6 +1434,9 @@ export default {
if (possibleApi === 'listTemplates') { if (possibleApi === 'listTemplates') {
params.templatefilter = 'executable' params.templatefilter = 'executable'
} else if (possibleApi === 'listIsos') { } else if (possibleApi === 'listIsos') {
if (this.$route.path.startsWith('/kubernetesiso')) {
params.bootable = false
}
params.isofilter = 'executable' params.isofilter = 'executable'
} else if (possibleApi === 'listHosts') { } else if (possibleApi === 'listHosts') {
params.type = 'routing' params.type = 'routing'

View File

@ -17,7 +17,12 @@
<template> <template>
<div class="form-layout" v-ctrl-enter="handleSubmit"> <div class="form-layout" v-ctrl-enter="handleSubmit">
<a-spin :spinning="loading"> <span v-if="uploadPercentage > 0">
<loading-outlined />
{{ $t('message.upload.file.processing') }}
<a-progress :percent="uploadPercentage" />
</span>
<a-spin :spinning="loading" v-else>
<a-form <a-form
:ref="formRef" :ref="formRef"
:model="form" :model="form"
@ -56,7 +61,7 @@
:loading="zoneLoading" :loading="zoneLoading"
:placeholder="apiParams.zoneid.description" :placeholder="apiParams.zoneid.description"
@change="handleZoneChange"> @change="handleZoneChange">
<a-select-option v-for="(opt, optIndex) in this.zones" :key="optIndex" :label="opt.name || opt.description"> <a-select-option v-for="opt in this.zones" :key="opt.id" :label="opt.name || opt.description">
<span> <span>
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/> <resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
<global-outlined v-else style="margin-right: 5px"/> <global-outlined v-else style="margin-right: 5px"/>
@ -65,7 +70,7 @@
</a-select-option> </a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item ref="url" name="url"> <a-form-item ref="url" name="url" v-if="currentForm === 'Create'">
<template #label> <template #label>
<tooltip-label :title="$t('label.url')" :tooltip="apiParams.url.description"/> <tooltip-label :title="$t('label.url')" :tooltip="apiParams.url.description"/>
</template> </template>
@ -73,6 +78,21 @@
v-model:value="form.url" v-model:value="form.url"
:placeholder="apiParams.url.description" /> :placeholder="apiParams.url.description" />
</a-form-item> </a-form-item>
<a-form-item ref="file" name="file" :label="$t('label.templatefileupload')" v-else>
<a-upload-dragger
:multiple="false"
:fileList="fileList"
@remove="handleRemove"
:beforeUpload="beforeUpload"
v-model:value="form.file">
<p class="ant-upload-drag-icon">
<cloud-upload-outlined />
</p>
<p class="ant-upload-text" v-if="fileList.length === 0">
{{ $t('label.volume.volumefileupload.description') }}
</p>
</a-upload-dragger>
</a-form-item>
<a-form-item ref="checksum" name="checksum"> <a-form-item ref="checksum" name="checksum">
<template #label> <template #label>
<tooltip-label :title="$t('label.checksum')" :tooltip="apiParams.checksum.description"/> <tooltip-label :title="$t('label.checksum')" :tooltip="apiParams.checksum.description"/>
@ -97,7 +117,7 @@
v-model:value="form.minmemory" v-model:value="form.minmemory"
:placeholder="apiParams.minmemory.description"/> :placeholder="apiParams.minmemory.description"/>
</a-form-item> </a-form-item>
<a-form-item ref="directdownload" name="directdownload"> <a-form-item ref="directdownload" name="directdownload" v-if="currentForm !== 'Upload'">
<template #label> <template #label>
<tooltip-label :title="$t('label.directdownload')" :tooltip="apiParams.directdownload.description"/> <tooltip-label :title="$t('label.directdownload')" :tooltip="apiParams.directdownload.description"/>
</template> </template>
@ -138,6 +158,7 @@
<script> <script>
import { ref, reactive, toRaw } from 'vue' import { ref, reactive, toRaw } from 'vue'
import { getAPI, postAPI } from '@/api' import { getAPI, postAPI } from '@/api'
import { axios } from '../../utils/request'
import ResourceIcon from '@/components/view/ResourceIcon' import ResourceIcon from '@/components/view/ResourceIcon'
import TooltipLabel from '@/components/widgets/TooltipLabel' import TooltipLabel from '@/components/widgets/TooltipLabel'
@ -147,27 +168,39 @@ export default {
ResourceIcon, ResourceIcon,
TooltipLabel TooltipLabel
}, },
props: {
action: {
type: Object,
required: true
}
},
data () { data () {
return { return {
fileList: [],
zones: [], zones: [],
zoneLoading: false, zoneLoading: false,
loading: false, loading: false,
selectedZone: {}, selectedZone: {},
uploadParams: null,
directDownloadDisabled: false, directDownloadDisabled: false,
lastNonEdgeDirectDownloadUserSelection: false, lastNonEdgeDirectDownloadUserSelection: false,
architectureTypes: {} architectureTypes: {},
uploadPercentage: 0,
currentForm: ['plus-outlined', 'PlusOutlined'].includes(this.action.currentAction.icon) ? 'Create' : 'Upload'
} }
}, },
beforeCreate () { beforeCreate () {
this.apiParams = this.$getApiParams('addKubernetesSupportedVersion') this.apiParams = this.$getApiParams('addKubernetesSupportedVersion')
}, },
created () { created () {
this.zones = [ if (this.$store.getters.userInfo.roletype === 'Admin' && this.currentForm === 'Create') {
{ this.zones = [
id: null, {
name: this.$t('label.all.zone') id: null,
} name: this.$t('label.all.zone')
] }
]
}
this.initForm() this.initForm()
this.fetchData() this.fetchData()
}, },
@ -181,14 +214,10 @@ export default {
}) })
this.rules = reactive({ this.rules = reactive({
semanticversion: [{ required: true, message: this.$t('message.error.kuberversion') }], semanticversion: [{ required: true, message: this.$t('message.error.kuberversion') }],
name: [{ required: true, message: this.$t('message.error.name') }],
zoneid: [{ zoneid: [{
type: 'number', required: this.currentForm === 'Upload',
validator: async (rule, value) => { message: this.$t('message.error.select')
if (value && value.length > 1 && value.indexOf(0) !== -1) {
return Promise.reject(this.$t('message.error.zone.combined'))
}
return Promise.resolve()
}
}], }],
url: [{ required: true, message: this.$t('message.error.binaries.iso.url') }], url: [{ required: true, message: this.$t('message.error.binaries.iso.url') }],
mincpunumber: [ mincpunumber: [
@ -237,7 +266,8 @@ export default {
}).finally(() => { }).finally(() => {
this.zoneLoading = false this.zoneLoading = false
if (this.arrayHasItems(this.zones)) { if (this.arrayHasItems(this.zones)) {
this.form.zoneid = 0 this.form.zoneid = (this.zones[0].id ? this.zones[0].id : '')
this.selectedZone = this.zones[0]
} }
}) })
}, },
@ -266,36 +296,111 @@ export default {
const values = toRaw(this.form) const values = toRaw(this.form)
this.loading = true this.loading = true
const params = {} const params = {}
const customCheckParams = ['mincpunumber', 'minmemory', 'zoneid'] const customCheckParams = ['mincpunumber', 'minmemory']
for (const key in values) { for (const key in values) {
if (!customCheckParams.includes(key) && values[key]) { if (!customCheckParams.includes(key) && values[key]) {
params[key] = values[key] params[key] = values[key]
} }
} }
if (this.isValidValueForKey(values, 'zoneid') && values.zoneid > 0) {
params.zoneid = this.zones[values.zoneid].id
}
if (this.isValidValueForKey(values, 'mincpunumber') && values.mincpunumber > 0) { if (this.isValidValueForKey(values, 'mincpunumber') && values.mincpunumber > 0) {
params.mincpunumber = values.mincpunumber params.mincpunumber = values.mincpunumber
} }
if (this.isValidValueForKey(values, 'minmemory') && values.minmemory > 0) { if (this.isValidValueForKey(values, 'minmemory') && values.minmemory > 0) {
params.minmemory = values.minmemory params.minmemory = values.minmemory
} }
postAPI('addKubernetesSupportedVersion', params).then(json => {
this.$message.success(`${this.$t('message.success.add.kuberversion')}: ${values.semanticversion}`) if (this.currentForm === 'Create') {
this.$emit('refresh-data') postAPI('addKubernetesSupportedVersion', params).then(json => {
this.closeAction() this.$message.success(`${this.$t('message.success.add.kuberversion')}: ${values.semanticversion}`)
}).catch(error => { this.$emit('refresh-data')
this.$notifyError(error) this.closeAction()
}).finally(() => { }).catch(error => {
this.loading = false this.$notifyError(error)
}) }).finally(() => {
this.loading = false
})
} else {
if (this.fileList.length !== 1) {
return
}
params.format = 'ISO'
this.loading = true
postAPI('getUploadParamsForKubernetesSupportedVersion', params).then(json => {
this.uploadParams = (json.getuploadparamsforkubernetessupportedversionresponse && json.getuploadparamsforkubernetessupportedversionresponse.getuploadparams) ? json.getuploadparamsforkubernetessupportedversionresponse.getuploadparams : ''
const response = this.handleUpload()
if (response === 'upload successful') {
this.$notification.success({
message: this.$t('message.success.upload'),
description: this.$t('message.success.add.kuberversion.from.local')
})
}
}).catch(error => {
this.$notifyError(error)
}).finally(() => {
this.loading = false
this.$emit('refresh-data')
})
}
}).catch(error => { }).catch(error => {
this.formRef.value.scrollToField(error.errorFields[0].name) this.formRef.value.scrollToField(error.errorFields[0].name)
}) })
}, },
closeAction () { closeAction () {
this.$emit('close-action') this.$emit('close-action')
},
handleRemove (file) {
const index = this.fileList.indexOf(file)
const newFileList = this.fileList.slice()
newFileList.splice(index, 1)
this.fileList = newFileList
this.form.file = undefined
},
beforeUpload (file) {
this.fileList = [file]
this.form.file = file
return false
},
handleUpload () {
const { fileList } = this
if (this.fileList.length > 1) {
this.$notification.error({
message: this.$t('message.upload.iso.failed'),
description: this.$t('message.error.upload.iso.description'),
duration: 0
})
}
const formData = new FormData()
fileList.forEach(file => {
formData.append('files[]', file)
})
this.uploadPercentage = 0
axios.post(this.uploadParams.postURL,
formData,
{
headers: {
'content-type': 'multipart/form-data',
'x-signature': this.uploadParams.signature,
'x-expires': this.uploadParams.expires,
'x-metadata': this.uploadParams.metadata
},
onUploadProgress: (progressEvent) => {
this.uploadPercentage = Number(parseFloat(100 * progressEvent.loaded / progressEvent.total).toFixed(1))
},
timeout: 86400000
}).then((json) => {
this.$notification.success({
message: this.$t('message.success.upload'),
description: this.$t('message.success.upload.description')
})
this.closeAction()
this.$emit('refresh-data')
}).catch(e => {
this.$notification.error({
message: this.$t('message.upload.failed'),
description: `${this.$t('message.upload.iso.failed.description')} - ${e}`,
duration: 0
})
})
} }
} }
} }