Skip to content

Commit 85ae62f

Browse files
committed
Allow uploading of ISO for creating kubernetes supported versions
1 parent 42a77c7 commit 85ae62f

File tree

9 files changed

+404
-48
lines changed

9 files changed

+404
-48
lines changed

api/src/main/java/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,34 @@ public Long getProjectId() {
8181
return projectId;
8282
}
8383

84+
public void setName(String name) {
85+
this.name = name;
86+
}
87+
88+
public void setFormat(String format) {
89+
this.format = format;
90+
}
91+
92+
public void setZoneId(Long zoneId) {
93+
this.zoneId = zoneId;
94+
}
95+
96+
public void setChecksum(String checksum) {
97+
this.checksum = checksum;
98+
}
99+
100+
public void setAccountName(String accountName) {
101+
this.accountName = accountName;
102+
}
103+
104+
public void setDomainId(Long domainId) {
105+
this.domainId = domainId;
106+
}
107+
108+
public void setProjectId(Long projectId) {
109+
this.projectId = projectId;
110+
}
111+
84112
public GetUploadParamsResponse createGetUploadParamsResponse(UUID id, URL postURL, String metadata, String timeout, String signature) {
85113
return new GetUploadParamsResponse(id, postURL, metadata, timeout, signature);
86114
}

api/src/main/java/org/apache/cloudstack/api/command/user/iso/GetUploadParamsForIsoCmd.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,29 @@ public Long getOsTypeId() {
104104
return osTypeId;
105105
}
106106

107+
public void setBootable(Boolean bootable) {
108+
this.bootable = bootable;
109+
}
110+
111+
public void setDisplayText(String displayText) {
112+
this.displayText = displayText;
113+
}
114+
115+
public void setFeatured(Boolean featured) {
116+
this.featured = featured;
117+
}
118+
119+
public void setPublicIso(Boolean publicIso) {
120+
this.publicIso = publicIso;
121+
}
122+
123+
public void setExtractable(Boolean extractable) {
124+
this.extractable = extractable;
125+
}
126+
127+
public void setOsTypeId(Long osTypeId) {
128+
this.osTypeId = osTypeId;
129+
}
107130

108131
/////////////////////////////////////////////////////
109132
/////////////// API Implementation///////////////////

api/src/main/java/org/apache/cloudstack/api/response/GetUploadParamsResponse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public GetUploadParamsResponse() {
6262
setObjectName("getuploadparams");
6363
}
6464

65+
public UUID getId() {
66+
return id;
67+
}
68+
6569
public void setId(UUID id) {
6670
this.id = id;
6771
}

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package com.cloud.kubernetes.version;
1919

20+
import java.net.MalformedURLException;
2021
import java.util.ArrayList;
2122
import java.util.List;
2223

@@ -27,10 +28,13 @@
2728
import org.apache.cloudstack.api.ApiConstants;
2829
import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd;
2930
import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd;
31+
import org.apache.cloudstack.api.command.admin.kubernetes.version.GetUploadParamsForKubernetesSupportedVersionCmd;
3032
import org.apache.cloudstack.api.command.admin.kubernetes.version.UpdateKubernetesSupportedVersionCmd;
3133
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
34+
import org.apache.cloudstack.api.command.user.iso.GetUploadParamsForIsoCmd;
3235
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
3336
import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesSupportedVersionsCmd;
37+
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
3438
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
3539
import org.apache.cloudstack.api.response.ListResponse;
3640
import org.apache.cloudstack.context.CallContext;
@@ -160,6 +164,33 @@ private List <KubernetesSupportedVersionVO> filterKubernetesSupportedVersions(Li
160164
return versions;
161165
}
162166

167+
private GetUploadParamsResponse registerKubernetesVersionIsoForUpload(final Long zoneId, final String versionName, final String isoChecksum) {
168+
CallContext.register(CallContext.current(), ApiCommandResourceType.Iso);
169+
String isoName = String.format("%s-Kubernetes-Binaries-ISO", versionName);
170+
GetUploadParamsForIsoCmd uploadIso = new GetUploadParamsForIsoCmd();
171+
uploadIso = ComponentContext.inject(uploadIso);
172+
uploadIso.setName(isoName);
173+
uploadIso.setPublicIso(true);
174+
if (zoneId != null) {
175+
uploadIso.setZoneId(zoneId);
176+
}
177+
uploadIso.setDisplayText(isoName);
178+
uploadIso.setBootable(false);
179+
if (StringUtils.isNotEmpty(isoChecksum)) {
180+
uploadIso.setChecksum(isoChecksum);
181+
}
182+
uploadIso.setAccountName(accountManager.getSystemAccount().getAccountName());
183+
uploadIso.setDomainId(accountManager.getSystemAccount().getDomainId());
184+
try {
185+
return templateService.registerIsoForPostUpload(uploadIso);
186+
} catch (MalformedURLException | ResourceAllocationException e) {
187+
logger.error(String.format("Unable to register binaries ISO for supported kubernetes version, %s", versionName), e);
188+
throw new CloudRuntimeException(String.format("Unable to register binaries ISO for supported kubernetes version, %s", versionName), e);
189+
} finally {
190+
CallContext.unregister();
191+
}
192+
}
193+
163194
private VirtualMachineTemplate registerKubernetesVersionIso(final Long zoneId, final String versionName, final String isoUrl, final String isoChecksum, final boolean directDownload, CPU.CPUArch arch) throws IllegalAccessException, NoSuchFieldException,
164195
IllegalArgumentException, ResourceAllocationException {
165196
CallContext.register(CallContext.current(), ApiCommandResourceType.Iso);
@@ -303,23 +334,8 @@ public ListResponse<KubernetesSupportedVersionResponse> listKubernetesSupportedV
303334
return createKubernetesSupportedVersionListResponse(versions, versionsAndCount.second());
304335
}
305336

306-
@Override
307-
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
308-
eventDescription = "Adding Kubernetes supported version")
309-
public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final AddKubernetesSupportedVersionCmd cmd) {
310-
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
311-
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
312-
}
313-
String name = cmd.getName();
314-
final String semanticVersion = cmd.getSemanticVersion();
315-
final Long zoneId = cmd.getZoneId();
316-
final String isoUrl = cmd.getUrl();
317-
final String isoChecksum = cmd.getChecksum();
318-
final Integer minimumCpu = cmd.getMinimumCpu();
319-
final Integer minimumRamSize = cmd.getMinimumRamSize();
320-
final boolean isDirectDownload = cmd.isDirectDownload();
321-
CPU.CPUArch arch = cmd.getArch();
322-
337+
private void validateKubernetesSupportedVersion(Long zoneId, String semanticVersion, Integer minimumCpu,
338+
Integer minimumRamSize, boolean isDirectDownload) {
323339
if (minimumCpu == null || minimumCpu < KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_CPU) {
324340
throw new InvalidParameterValueException(String.format("Invalid value for %s parameter. Minimum %d vCPUs required.", ApiConstants.MIN_CPU_NUMBER, KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_CPU));
325341
}
@@ -338,6 +354,27 @@ public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final Ad
338354
throw new InvalidParameterValueException(String.format("Zone: %s supports only direct download Kubernetes versions", zone.getName()));
339355
}
340356
}
357+
}
358+
359+
@Override
360+
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
361+
eventDescription = "Adding Kubernetes supported version")
362+
public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final AddKubernetesSupportedVersionCmd cmd) {
363+
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
364+
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
365+
}
366+
String name = cmd.getName();
367+
final String semanticVersion = cmd.getSemanticVersion();
368+
final Long zoneId = cmd.getZoneId();
369+
final String isoUrl = cmd.getUrl();
370+
final String isoChecksum = cmd.getChecksum();
371+
final Integer minimumCpu = cmd.getMinimumCpu();
372+
final Integer minimumRamSize = cmd.getMinimumRamSize();
373+
final boolean isDirectDownload = cmd.isDirectDownload();
374+
CPU.CPUArch arch = cmd.getArch();
375+
376+
validateKubernetesSupportedVersion(zoneId, semanticVersion, minimumCpu, minimumRamSize, isDirectDownload);
377+
341378
if (StringUtils.isEmpty(isoUrl)) {
342379
throw new InvalidParameterValueException(String.format("Invalid URL for ISO specified, %s", isoUrl));
343380
}
@@ -364,6 +401,30 @@ public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final Ad
364401
return createKubernetesSupportedVersionResponse(supportedVersionVO);
365402
}
366403

404+
@Override
405+
public GetUploadParamsResponse registerKubernetesSupportedVersionForPostUpload(GetUploadParamsForKubernetesSupportedVersionCmd cmd) {
406+
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
407+
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
408+
}
409+
String name = cmd.getName();
410+
final String semanticVersion = cmd.getSemanticVersion();
411+
final Long zoneId = cmd.getZoneId();
412+
final String isoChecksum = cmd.getChecksum();
413+
final Integer minimumCpu = cmd.getMinimumCpu();
414+
final Integer minimumRamSize = cmd.getMinimumRamSize();
415+
416+
validateKubernetesSupportedVersion(zoneId, semanticVersion, minimumCpu, minimumRamSize, false);
417+
418+
GetUploadParamsResponse response = registerKubernetesVersionIsoForUpload(zoneId, name, isoChecksum);
419+
420+
VMTemplateVO template = templateDao.findByUuid(response.getId().toString());
421+
KubernetesSupportedVersionVO supportedVersionVO = new KubernetesSupportedVersionVO(name, semanticVersion, template.getId(), zoneId, minimumCpu, minimumRamSize);
422+
supportedVersionVO = kubernetesSupportedVersionDao.persist(supportedVersionVO);
423+
CallContext.current().putContextParameter(KubernetesSupportedVersion.class, supportedVersionVO.getUuid());
424+
425+
return response;
426+
}
427+
367428
@Override
368429
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_DELETE,
369430
eventDescription = "deleting Kubernetes supported version", async = true)
@@ -432,6 +493,7 @@ public List<Class<?>> getCommands() {
432493
return cmdList;
433494
}
434495
cmdList.add(AddKubernetesSupportedVersionCmd.class);
496+
cmdList.add(GetUploadParamsForKubernetesSupportedVersionCmd.class);
435497
cmdList.add(ListKubernetesSupportedVersionsCmd.class);
436498
cmdList.add(DeleteKubernetesSupportedVersionCmd.class);
437499
cmdList.add(UpdateKubernetesSupportedVersionCmd.class);

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd;
2121
import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd;
22+
import org.apache.cloudstack.api.command.admin.kubernetes.version.GetUploadParamsForKubernetesSupportedVersionCmd;
2223
import org.apache.cloudstack.api.command.admin.kubernetes.version.UpdateKubernetesSupportedVersionCmd;
2324
import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesSupportedVersionsCmd;
25+
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
2426
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
2527
import org.apache.cloudstack.api.response.ListResponse;
2628

@@ -31,6 +33,7 @@ public interface KubernetesVersionService extends PluggableService {
3133
static final String MIN_KUBERNETES_VERSION = "1.11.0";
3234
ListResponse<KubernetesSupportedVersionResponse> listKubernetesSupportedVersions(ListKubernetesSupportedVersionsCmd cmd);
3335
KubernetesSupportedVersionResponse addKubernetesSupportedVersion(AddKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException;
36+
GetUploadParamsResponse registerKubernetesSupportedVersionForPostUpload(GetUploadParamsForKubernetesSupportedVersionCmd cmd);
3437
boolean deleteKubernetesSupportedVersion(DeleteKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException;
3538
KubernetesSupportedVersionResponse updateKubernetesSupportedVersion(UpdateKubernetesSupportedVersionCmd cmd) throws CloudRuntimeException;
3639
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.api.command.admin.kubernetes.version;
19+
20+
import com.cloud.exception.ConcurrentOperationException;
21+
import com.cloud.exception.InvalidParameterValueException;
22+
import com.cloud.kubernetes.version.KubernetesSupportedVersion;
23+
import com.cloud.kubernetes.version.KubernetesVersionService;
24+
import com.cloud.utils.exception.CloudRuntimeException;
25+
import org.apache.cloudstack.acl.RoleType;
26+
import org.apache.cloudstack.api.APICommand;
27+
import org.apache.cloudstack.api.AbstractGetUploadParamsCmd;
28+
import org.apache.cloudstack.api.ApiCommandResourceType;
29+
import org.apache.cloudstack.api.ApiConstants;
30+
import org.apache.cloudstack.api.ApiErrorCode;
31+
import org.apache.cloudstack.api.Parameter;
32+
import org.apache.cloudstack.api.ResponseObject;
33+
import org.apache.cloudstack.api.ServerApiException;
34+
import org.apache.cloudstack.api.command.admin.AdminCmd;
35+
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
36+
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
37+
import org.apache.cloudstack.context.CallContext;
38+
import org.apache.commons.lang3.StringUtils;
39+
40+
import javax.inject.Inject;
41+
42+
@APICommand(name = "getUploadParamsForKubernetesSupportedVersion",
43+
description = "Add a supported Kubernetes version",
44+
responseObject = KubernetesSupportedVersionResponse.class,
45+
responseView = ResponseObject.ResponseView.Full,
46+
entityType = {KubernetesSupportedVersion.class},
47+
authorized = {RoleType.Admin})
48+
public class GetUploadParamsForKubernetesSupportedVersionCmd extends AbstractGetUploadParamsCmd implements AdminCmd {
49+
50+
@Inject
51+
private KubernetesVersionService kubernetesVersionService;
52+
53+
/////////////////////////////////////////////////////
54+
//////////////// API parameters /////////////////////
55+
/////////////////////////////////////////////////////
56+
@Parameter(name = ApiConstants.SEMANTIC_VERSION, type = CommandType.STRING, required = true,
57+
description = "the semantic version of the Kubernetes version. It needs to be specified in MAJOR.MINOR.PATCH format")
58+
private String semanticVersion;
59+
60+
@Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING,
61+
description = "the checksum value of the binaries ISO. " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
62+
private String checksum;
63+
64+
@Parameter(name = ApiConstants.MIN_CPU_NUMBER, type = CommandType.INTEGER, required = true,
65+
description = "the minimum number of CPUs to be set with the Kubernetes version")
66+
private Integer minimumCpu;
67+
68+
@Parameter(name = ApiConstants.MIN_MEMORY, type = CommandType.INTEGER, required = true,
69+
description = "the minimum RAM size in MB to be set with the Kubernetes version")
70+
private Integer minimumRamSize;
71+
72+
/////////////////////////////////////////////////////
73+
/////////////////// Accessors ///////////////////////
74+
/////////////////////////////////////////////////////
75+
76+
public String getSemanticVersion() {
77+
if(StringUtils.isEmpty(semanticVersion)) {
78+
throw new InvalidParameterValueException("Version can not be null");
79+
}
80+
if(!semanticVersion.matches("[0-9]+(\\.[0-9]+)*")) {
81+
throw new IllegalArgumentException("Invalid version format. Semantic version needed");
82+
}
83+
return semanticVersion;
84+
}
85+
86+
public String getChecksum() {
87+
return checksum;
88+
}
89+
90+
public Integer getMinimumCpu() {
91+
return minimumCpu;
92+
}
93+
94+
public Integer getMinimumRamSize() {
95+
return minimumRamSize;
96+
}
97+
98+
@Override
99+
public long getEntityOwnerId() {
100+
return CallContext.current().getCallingAccountId();
101+
}
102+
103+
@Override
104+
public ApiCommandResourceType getApiResourceType() {
105+
return ApiCommandResourceType.KubernetesSupportedVersion;
106+
}
107+
108+
/////////////////////////////////////////////////////
109+
/////////////// API Implementation///////////////////
110+
/////////////////////////////////////////////////////
111+
@Override
112+
public void execute() throws ServerApiException, ConcurrentOperationException {
113+
if (getZoneId() <= 0) {
114+
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid zoneid");
115+
}
116+
try {
117+
GetUploadParamsResponse response = kubernetesVersionService.registerKubernetesSupportedVersionForPostUpload(this);
118+
if (response == null) {
119+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Kubernetes supported version");
120+
}
121+
response.setResponseName(getCommandName());
122+
setResponseObject(response);
123+
} catch (CloudRuntimeException ex) {
124+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
125+
}
126+
}
127+
}

ui/src/config/section/image.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,14 @@ export default {
395395
show: isZoneCreated,
396396
component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue')))
397397
},
398+
{
399+
api: 'addKubernetesSupportedVersion',
400+
icon: 'cloud-upload-outlined',
401+
label: 'label.kubernetes.version.add.from.local',
402+
listView: true,
403+
popup: true,
404+
component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue')))
405+
},
398406
{
399407
api: 'updateKubernetesSupportedVersion',
400408
icon: 'edit-outlined',

ui/src/views/AutogenView.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,9 @@ export default {
12921292
if (possibleApi === 'listTemplates') {
12931293
params.templatefilter = 'executable'
12941294
} else if (possibleApi === 'listIsos') {
1295+
if (this.$route.path.startsWith('/kubernetesiso')) {
1296+
params.bootable = false
1297+
}
12951298
params.isofilter = 'executable'
12961299
} else if (possibleApi === 'listHosts') {
12971300
params.type = 'routing'

0 commit comments

Comments
 (0)