From a54a1c2436096f0c2b94c3010008f0bb108827e6 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 18 Sep 2025 17:02:47 +0200 Subject: [PATCH 1/2] api,server: support templatetype when upload template from local --- .../GetUploadParamsForTemplateCmd.java | 9 ++++++ .../upload/params/TemplateUploadParams.java | 5 ++-- .../storage/upload/params/UploadParams.java | 2 ++ .../upload/params/UploadParamsBase.java | 28 ++++++++++++++----- .../cloud/template/TemplateAdapterBase.java | 18 ++++++++++-- 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java index 330224a60552..2472a03b890b 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java @@ -104,6 +104,11 @@ public class GetUploadParamsForTemplateCmd extends AbstractGetUploadParamsCmd { description = "if true, the templates would be available for deploying CKS clusters", since = "4.21.0") protected Boolean forCks; + @Parameter(name = ApiConstants.TEMPLATE_TYPE, type = CommandType.STRING, + description = "the type of the template. Valid options are: USER/VNF (for all users) and SYSTEM/ROUTING/BUILTIN (for admins only).", + since = "4.22.0") + private String templateType; + public String getDisplayText() { return StringUtils.isBlank(displayText) ? getName() : displayText; } @@ -181,6 +186,10 @@ public CPU.CPUArch getArch() { return CPU.CPUArch.fromType(arch); } + public String getTemplateType() { + return templateType; + } + @Override public void execute() throws ServerApiException { validateRequest(); diff --git a/server/src/main/java/com/cloud/storage/upload/params/TemplateUploadParams.java b/server/src/main/java/com/cloud/storage/upload/params/TemplateUploadParams.java index 769aa3dc1f2a..aae7c0be812a 100644 --- a/server/src/main/java/com/cloud/storage/upload/params/TemplateUploadParams.java +++ b/server/src/main/java/com/cloud/storage/upload/params/TemplateUploadParams.java @@ -30,10 +30,11 @@ public TemplateUploadParams(long userId, String name, String displayText, CPU.CP Long zoneId, Hypervisor.HypervisorType hypervisorType, String chksum, String templateTag, long templateOwnerId, Map details, Boolean sshkeyEnabled, - Boolean isDynamicallyScalable, Boolean isRoutingType, boolean deployAsIs, boolean forCks) { + Boolean isDynamicallyScalable, Boolean isRoutingType, boolean deployAsIs, + boolean forCks, String templateType) { super(userId, name, displayText, arch, bits, passwordEnabled, requiresHVM, isPublic, featured, isExtractable, format, guestOSId, zoneId, hypervisorType, chksum, templateTag, templateOwnerId, details, - sshkeyEnabled, isDynamicallyScalable, isRoutingType, deployAsIs, forCks); + sshkeyEnabled, isDynamicallyScalable, isRoutingType, deployAsIs, forCks, templateType); setBootable(true); } } diff --git a/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java b/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java index 7be526d780d8..5738cfaad884 100644 --- a/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java +++ b/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java @@ -49,4 +49,6 @@ public interface UploadParams { boolean isDirectDownload(); boolean isDeployAsIs(); CPU.CPUArch getArch(); + boolean isForCks(); + String getTemplateType(); } diff --git a/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java b/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java index c3499d75c3bc..945551a9318c 100644 --- a/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java +++ b/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java @@ -48,15 +48,17 @@ public abstract class UploadParamsBase implements UploadParams { private boolean deployAsIs; private boolean forCks; private CPU.CPUArch arch; + private String templateType; UploadParamsBase(long userId, String name, String displayText, CPU.CPUArch arch, - Integer bits, boolean passwordEnabled, boolean requiresHVM, - boolean isPublic, boolean featured, - boolean isExtractable, String format, Long guestOSId, - Long zoneId, Hypervisor.HypervisorType hypervisorType, String checksum, - String templateTag, long templateOwnerId, - Map details, boolean sshkeyEnabled, - boolean isDynamicallyScalable, boolean isRoutingType, boolean deployAsIs, boolean forCks) { + Integer bits, boolean passwordEnabled, boolean requiresHVM, + boolean isPublic, boolean featured, + boolean isExtractable, String format, Long guestOSId, + Long zoneId, Hypervisor.HypervisorType hypervisorType, String checksum, + String templateTag, long templateOwnerId, + Map details, boolean sshkeyEnabled, + boolean isDynamicallyScalable, boolean isRoutingType, boolean deployAsIs, + boolean forCks, String templateType) { this.userId = userId; this.name = name; this.displayText = displayText; @@ -79,6 +81,8 @@ public abstract class UploadParamsBase implements UploadParams { this.isDynamicallyScalable = isDynamicallyScalable; this.isRoutingType = isRoutingType; this.deployAsIs = deployAsIs; + this.forCks = forCks; + this.templateType = templateType; } UploadParamsBase(long userId, String name, String displayText, boolean isPublic, boolean isFeatured, @@ -261,4 +265,14 @@ public CPU.CPUArch getArch() { public void setArch(CPU.CPUArch arch) { this.arch = arch; } + + @Override + public boolean isForCks() { + return forCks; + } + + @Override + public String getTemplateType() { + return templateType; + } } diff --git a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java index 75c63aebe0d8..cae18c79f525 100644 --- a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java @@ -490,12 +490,25 @@ private TemplateProfile prepareUploadParamsInternal(UploadParams params) throws StringUtils.join(Arrays.stream(HypervisorType.values()).filter(h -> h != HypervisorType.None).map(HypervisorType::name).toArray(), ", "))); } + TemplateType templateType; + if (params.getTemplateType() != null) { + try { + templateType = TemplateType.valueOf(params.getTemplateType().toUpperCase()); + } catch (IllegalArgumentException ex) { + throw new InvalidParameterValueException(String.format("Please specify a valid templatetype: %s", + org.apache.commons.lang3.StringUtils.join(",", TemplateType.values()))); + } + } else { + templateType = params.isRoutingType() ? TemplateType.ROUTING : TemplateType.USER; + } + return prepare(params.isIso(), params.getUserId(), params.getName(), params.getDisplayText(), params.getArch(), params.getBits(), params.isPasswordEnabled(), params.requiresHVM(), params.getUrl(), params.isPublic(), params.isFeatured(), params.isExtractable(), params.getFormat(), params.getGuestOSId(), zoneList, params.getHypervisorType(), params.getChecksum(), params.isBootable(), params.getTemplateTag(), owner, params.getDetails(), params.isSshKeyEnabled(), params.getImageStoreUuid(), - params.isDynamicallyScalable(), params.isRoutingType() ? TemplateType.ROUTING : TemplateType.USER, params.isDirectDownload(), params.isDeployAsIs(), false, null); + params.isDynamicallyScalable(), templateType, params.isDirectDownload(), params.isDeployAsIs(), + params.isForCks(), null); } private Long getDefaultDeployAsIsGuestOsId() { @@ -516,7 +529,8 @@ public TemplateProfile prepare(GetUploadParamsForTemplateCmd cmd) throws Resourc BooleanUtils.toBoolean(cmd.isFeatured()), BooleanUtils.toBoolean(cmd.isExtractable()), cmd.getFormat(), osTypeId, cmd.getZoneId(), HypervisorType.getType(cmd.getHypervisor()), cmd.getChecksum(), cmd.getTemplateTag(), cmd.getEntityOwnerId(), cmd.getDetails(), BooleanUtils.toBoolean(cmd.isSshKeyEnabled()), - BooleanUtils.toBoolean(cmd.isDynamicallyScalable()), BooleanUtils.toBoolean(cmd.isRoutingType()), cmd.isDeployAsIs(), cmd.isForCks()); + BooleanUtils.toBoolean(cmd.isDynamicallyScalable()), BooleanUtils.toBoolean(cmd.isRoutingType()), cmd.isDeployAsIs(), + cmd.isForCks(), cmd.getTemplateType()); return prepareUploadParamsInternal(params); } From 13c7e0cfdc9eb84216ef466d5032690933cdaf4d Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 18 Sep 2025 19:46:02 +0200 Subject: [PATCH 2/2] Update 11682: check templatetype --- .../cloud/template/TemplateAdapterBase.java | 20 ++++++------------- .../cloud/template/TemplateManagerImpl.java | 5 ++++- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java index cae18c79f525..a9adfa932366 100644 --- a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java @@ -29,6 +29,7 @@ import javax.inject.Inject; import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseCmd; 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; @@ -469,7 +470,7 @@ public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocatio /** * Prepare upload parameters internal method for templates and ISOs local upload */ - private TemplateProfile prepareUploadParamsInternal(UploadParams params) throws ResourceAllocationException { + private TemplateProfile prepareUploadParamsInternal(BaseCmd cmd, UploadParams params) throws ResourceAllocationException { //check if the caller can operate with the template owner Account caller = CallContext.current().getCallingAccount(); Account owner = _accountMgr.getAccount(params.getTemplateOwnerId()); @@ -490,17 +491,8 @@ private TemplateProfile prepareUploadParamsInternal(UploadParams params) throws StringUtils.join(Arrays.stream(HypervisorType.values()).filter(h -> h != HypervisorType.None).map(HypervisorType::name).toArray(), ", "))); } - TemplateType templateType; - if (params.getTemplateType() != null) { - try { - templateType = TemplateType.valueOf(params.getTemplateType().toUpperCase()); - } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException(String.format("Please specify a valid templatetype: %s", - org.apache.commons.lang3.StringUtils.join(",", TemplateType.values()))); - } - } else { - templateType = params.isRoutingType() ? TemplateType.ROUTING : TemplateType.USER; - } + TemplateType templateType = templateMgr.validateTemplateType(cmd, _accountMgr.isAdmin(caller.getAccountId()), + false, params.getHypervisorType()); return prepare(params.isIso(), params.getUserId(), params.getName(), params.getDisplayText(), params.getArch(), params.getBits(), params.isPasswordEnabled(), params.requiresHVM(), params.getUrl(), params.isPublic(), params.isFeatured(), @@ -531,7 +523,7 @@ public TemplateProfile prepare(GetUploadParamsForTemplateCmd cmd) throws Resourc cmd.getTemplateTag(), cmd.getEntityOwnerId(), cmd.getDetails(), BooleanUtils.toBoolean(cmd.isSshKeyEnabled()), BooleanUtils.toBoolean(cmd.isDynamicallyScalable()), BooleanUtils.toBoolean(cmd.isRoutingType()), cmd.isDeployAsIs(), cmd.isForCks(), cmd.getTemplateType()); - return prepareUploadParamsInternal(params); + return prepareUploadParamsInternal(cmd, params); } @Override @@ -540,7 +532,7 @@ public TemplateProfile prepare(GetUploadParamsForIsoCmd cmd) throws ResourceAllo cmd.getDisplayText(), BooleanUtils.toBoolean(cmd.isPublic()), BooleanUtils.toBoolean(cmd.isFeatured()), BooleanUtils.toBoolean(cmd.isExtractable()), cmd.getOsTypeId(), cmd.getZoneId(), BooleanUtils.toBoolean(cmd.isBootable()), cmd.getEntityOwnerId()); - return prepareUploadParamsInternal(params); + return prepareUploadParamsInternal(cmd, params); } @Override diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 5518a29955be..7bb66958cb44 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -2339,7 +2339,7 @@ else if (details != null && !details.isEmpty()) { @Override public TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean isCrossZones, HypervisorType hypervisorType) { - if (!(cmd instanceof UpdateTemplateCmd) && !(cmd instanceof RegisterTemplateCmd)) { + if (!(cmd instanceof UpdateTemplateCmd) && !(cmd instanceof RegisterTemplateCmd) && !(cmd instanceof GetUploadParamsForTemplateCmd)) { return null; } TemplateType templateType = null; @@ -2351,6 +2351,9 @@ public TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean i } else if (cmd instanceof RegisterTemplateCmd) { newType = ((RegisterTemplateCmd)cmd).getTemplateType(); isRoutingType = ((RegisterTemplateCmd)cmd).isRoutingType(); + } else if (cmd instanceof GetUploadParamsForTemplateCmd) { + newType = ((GetUploadParamsForTemplateCmd)cmd).getTemplateType(); + isRoutingType = ((GetUploadParamsForTemplateCmd)cmd).isRoutingType(); } if (newType != null) { try {