Skip to content

Commit be1539f

Browse files
committed
Allow uploading of ISO for creating kubernetes supported versions
1 parent b215abc commit be1539f

File tree

9 files changed

+404
-46
lines changed

9 files changed

+404
-46
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: 78 additions & 15 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

@@ -26,10 +27,13 @@
2627
import org.apache.cloudstack.api.ApiConstants;
2728
import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd;
2829
import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd;
30+
import org.apache.cloudstack.api.command.admin.kubernetes.version.GetUploadParamsForKubernetesSupportedVersionCmd;
2931
import org.apache.cloudstack.api.command.admin.kubernetes.version.UpdateKubernetesSupportedVersionCmd;
3032
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
33+
import org.apache.cloudstack.api.command.user.iso.GetUploadParamsForIsoCmd;
3134
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
3235
import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesSupportedVersionsCmd;
36+
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
3337
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
3438
import org.apache.cloudstack.api.response.ListResponse;
3539
import org.apache.cloudstack.context.CallContext;
@@ -159,6 +163,33 @@ private List <KubernetesSupportedVersionVO> filterKubernetesSupportedVersions(Li
159163
return versions;
160164
}
161165

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

304-
@Override
305-
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
306-
eventDescription = "Adding Kubernetes supported version")
307-
public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final AddKubernetesSupportedVersionCmd cmd) {
308-
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
309-
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
310-
}
311-
String name = cmd.getName();
312-
final String semanticVersion = cmd.getSemanticVersion();
313-
final Long zoneId = cmd.getZoneId();
314-
final String isoUrl = cmd.getUrl();
315-
final String isoChecksum = cmd.getChecksum();
316-
final Integer minimumCpu = cmd.getMinimumCpu();
317-
final Integer minimumRamSize = cmd.getMinimumRamSize();
318-
final boolean isDirectDownload = cmd.isDirectDownload();
335+
private void validateKubernetesSupportedVersion(Long zoneId, String semanticVersion, Integer minimumCpu,
336+
Integer minimumRamSize, boolean isDirectDownload) {
319337
if (minimumCpu == null || minimumCpu < KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_CPU) {
320338
throw new InvalidParameterValueException(String.format("Invalid value for %s parameter. Minimum %d vCPUs required.", ApiConstants.MIN_CPU_NUMBER, KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_CPU));
321339
}
@@ -334,6 +352,26 @@ public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final Ad
334352
throw new InvalidParameterValueException(String.format("Zone: %s supports only direct download Kubernetes versions", zone.getName()));
335353
}
336354
}
355+
}
356+
357+
@Override
358+
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
359+
eventDescription = "Adding Kubernetes supported version")
360+
public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final AddKubernetesSupportedVersionCmd cmd) {
361+
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
362+
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
363+
}
364+
String name = cmd.getName();
365+
final String semanticVersion = cmd.getSemanticVersion();
366+
final Long zoneId = cmd.getZoneId();
367+
final String isoUrl = cmd.getUrl();
368+
final String isoChecksum = cmd.getChecksum();
369+
final Integer minimumCpu = cmd.getMinimumCpu();
370+
final Integer minimumRamSize = cmd.getMinimumRamSize();
371+
final boolean isDirectDownload = cmd.isDirectDownload();
372+
373+
validateKubernetesSupportedVersion(zoneId, semanticVersion, minimumCpu, minimumRamSize, isDirectDownload);
374+
337375
if (StringUtils.isEmpty(isoUrl)) {
338376
throw new InvalidParameterValueException(String.format("Invalid URL for ISO specified, %s", isoUrl));
339377
}
@@ -360,6 +398,30 @@ public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final Ad
360398
return createKubernetesSupportedVersionResponse(supportedVersionVO);
361399
}
362400

401+
@Override
402+
public GetUploadParamsResponse registerKubernetesSupportedVersionForPostUpload(GetUploadParamsForKubernetesSupportedVersionCmd cmd) {
403+
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
404+
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
405+
}
406+
String name = cmd.getName();
407+
final String semanticVersion = cmd.getSemanticVersion();
408+
final Long zoneId = cmd.getZoneId();
409+
final String isoChecksum = cmd.getChecksum();
410+
final Integer minimumCpu = cmd.getMinimumCpu();
411+
final Integer minimumRamSize = cmd.getMinimumRamSize();
412+
413+
validateKubernetesSupportedVersion(zoneId, semanticVersion, minimumCpu, minimumRamSize, false);
414+
415+
GetUploadParamsResponse response = registerKubernetesVersionIsoForUpload(zoneId, name, isoChecksum);
416+
417+
VMTemplateVO template = templateDao.findByUuid(response.getId().toString());
418+
KubernetesSupportedVersionVO supportedVersionVO = new KubernetesSupportedVersionVO(name, semanticVersion, template.getId(), zoneId, minimumCpu, minimumRamSize);
419+
supportedVersionVO = kubernetesSupportedVersionDao.persist(supportedVersionVO);
420+
CallContext.current().putContextParameter(KubernetesSupportedVersion.class, supportedVersionVO.getUuid());
421+
422+
return response;
423+
}
424+
363425
@Override
364426
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_DELETE,
365427
eventDescription = "deleting Kubernetes supported version", async = true)
@@ -428,6 +490,7 @@ public List<Class<?>> getCommands() {
428490
return cmdList;
429491
}
430492
cmdList.add(AddKubernetesSupportedVersionCmd.class);
493+
cmdList.add(GetUploadParamsForKubernetesSupportedVersionCmd.class);
431494
cmdList.add(ListKubernetesSupportedVersionsCmd.class);
432495
cmdList.add(DeleteKubernetesSupportedVersionCmd.class);
433496
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,128 @@
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.api.response.ZoneResponse;
38+
import org.apache.cloudstack.context.CallContext;
39+
import org.apache.commons.lang3.StringUtils;
40+
41+
import javax.inject.Inject;
42+
43+
@APICommand(name = "getUploadParamsForKubernetesSupportedVersion",
44+
description = "Add a supported Kubernetes version",
45+
responseObject = KubernetesSupportedVersionResponse.class,
46+
responseView = ResponseObject.ResponseView.Full,
47+
entityType = {KubernetesSupportedVersion.class},
48+
authorized = {RoleType.Admin})
49+
public class GetUploadParamsForKubernetesSupportedVersionCmd extends AbstractGetUploadParamsCmd implements AdminCmd {
50+
51+
@Inject
52+
private KubernetesVersionService kubernetesVersionService;
53+
54+
/////////////////////////////////////////////////////
55+
//////////////// API parameters /////////////////////
56+
/////////////////////////////////////////////////////
57+
@Parameter(name = ApiConstants.SEMANTIC_VERSION, type = CommandType.STRING, required = true,
58+
description = "the semantic version of the Kubernetes version. It needs to be specified in MAJOR.MINOR.PATCH format")
59+
private String semanticVersion;
60+
61+
@Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING,
62+
description = "the checksum value of the binaries ISO. " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
63+
private String checksum;
64+
65+
@Parameter(name = ApiConstants.MIN_CPU_NUMBER, type = CommandType.INTEGER, required = true,
66+
description = "the minimum number of CPUs to be set with the Kubernetes version")
67+
private Integer minimumCpu;
68+
69+
@Parameter(name = ApiConstants.MIN_MEMORY, type = CommandType.INTEGER, required = true,
70+
description = "the minimum RAM size in MB to be set with the Kubernetes version")
71+
private Integer minimumRamSize;
72+
73+
/////////////////////////////////////////////////////
74+
/////////////////// Accessors ///////////////////////
75+
/////////////////////////////////////////////////////
76+
77+
public String getSemanticVersion() {
78+
if(StringUtils.isEmpty(semanticVersion)) {
79+
throw new InvalidParameterValueException("Version can not be null");
80+
}
81+
if(!semanticVersion.matches("[0-9]+(\\.[0-9]+)*")) {
82+
throw new IllegalArgumentException("Invalid version format. Semantic version needed");
83+
}
84+
return semanticVersion;
85+
}
86+
87+
public String getChecksum() {
88+
return checksum;
89+
}
90+
91+
public Integer getMinimumCpu() {
92+
return minimumCpu;
93+
}
94+
95+
public Integer getMinimumRamSize() {
96+
return minimumRamSize;
97+
}
98+
99+
@Override
100+
public long getEntityOwnerId() {
101+
return CallContext.current().getCallingAccountId();
102+
}
103+
104+
@Override
105+
public ApiCommandResourceType getApiResourceType() {
106+
return ApiCommandResourceType.KubernetesSupportedVersion;
107+
}
108+
109+
/////////////////////////////////////////////////////
110+
/////////////// API Implementation///////////////////
111+
/////////////////////////////////////////////////////
112+
@Override
113+
public void execute() throws ServerApiException, ConcurrentOperationException {
114+
if (getZoneId() <= 0) {
115+
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid zoneid");
116+
}
117+
try {
118+
GetUploadParamsResponse response = kubernetesVersionService.registerKubernetesSupportedVersionForPostUpload(this);
119+
if (response == null) {
120+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Kubernetes supported version");
121+
}
122+
response.setResponseName(getCommandName());
123+
setResponseObject(response);
124+
} catch (CloudRuntimeException ex) {
125+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
126+
}
127+
}
128+
}

ui/src/config/section/image.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,14 @@ export default {
391391
popup: true,
392392
component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue')))
393393
},
394+
{
395+
api: 'addKubernetesSupportedVersion',
396+
icon: 'cloud-upload-outlined',
397+
label: 'label.kubernetes.version.add.from.local',
398+
listView: true,
399+
popup: true,
400+
component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue')))
401+
},
394402
{
395403
api: 'updateKubernetesSupportedVersion',
396404
icon: 'edit-outlined',

ui/src/views/AutogenView.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,9 @@ export default {
12811281
if (possibleApi === 'listTemplates') {
12821282
params.templatefilter = 'executable'
12831283
} else if (possibleApi === 'listIsos') {
1284+
if (this.$route.path.startsWith('/kubernetesiso')) {
1285+
params.bootable = false
1286+
}
12841287
params.isofilter = 'executable'
12851288
} else if (possibleApi === 'listHosts') {
12861289
params.type = 'routing'

0 commit comments

Comments
 (0)