Adds url kubernetes iso (#10862)

Co-authored-by: Vitor Hugo Homem Marzarotto <vitor.marzarotto@scclouds.com.br>
Co-authored-by: Henrique Sato <henriquesato2003@gmail.com>
This commit is contained in:
Vitor Hugo Homem Marzarotto 2026-01-20 04:10:42 -03:00 committed by GitHub
parent 42f1e19362
commit 2a6ce0c8a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 105 additions and 31 deletions

View File

@ -1097,6 +1097,7 @@ public class ApiConstants {
public static final String DOCKER_REGISTRY_EMAIL = "dockerregistryemail";
public static final String ISO_NAME = "isoname";
public static final String ISO_STATE = "isostate";
public static final String ISO_URL = "isourl";
public static final String SEMANTIC_VERSION = "semanticversion";
public static final String KUBERNETES_VERSION_ID = "kubernetesversionid";
public static final String KUBERNETES_VERSION_NAME = "kubernetesversionname";

View File

@ -53,6 +53,7 @@ import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.template.TemplateApiService;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentContext;
@ -85,7 +86,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
public static final String MINIMUN_AUTOSCALER_SUPPORTED_VERSION = "1.15.0";
protected void updateTemplateDetailsInKubernetesSupportedVersionResponse(
final KubernetesSupportedVersion kubernetesSupportedVersion, KubernetesSupportedVersionResponse response) {
final KubernetesSupportedVersion kubernetesSupportedVersion, KubernetesSupportedVersionResponse response, boolean isRootAdmin) {
TemplateJoinVO template = templateJoinDao.findById(kubernetesSupportedVersion.getIsoId());
if (template == null) {
return;
@ -95,11 +96,14 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
if (template.getState() != null) {
response.setIsoState(template.getState().toString());
}
if (isRootAdmin) {
response.setIsoUrl(template.getUrl());
}
response.setIsoArch(template.getArch().getType());
response.setDirectDownload(template.isDirectDownload());
}
private KubernetesSupportedVersionResponse createKubernetesSupportedVersionResponse(final KubernetesSupportedVersion kubernetesSupportedVersion) {
private KubernetesSupportedVersionResponse createKubernetesSupportedVersionResponse(final KubernetesSupportedVersion kubernetesSupportedVersion, boolean isRootAdmin) {
KubernetesSupportedVersionResponse response = new KubernetesSupportedVersionResponse();
response.setObjectName("kubernetessupportedversion");
response.setId(kubernetesSupportedVersion.getUuid());
@ -118,7 +122,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
response.setSupportsHA(compareSemanticVersions(kubernetesSupportedVersion.getSemanticVersion(),
KubernetesClusterService.MIN_KUBERNETES_VERSION_HA_SUPPORT)>=0);
response.setSupportsAutoscaling(versionSupportsAutoscaling(kubernetesSupportedVersion));
updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion, response);
updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion, response, isRootAdmin);
response.setCreated(kubernetesSupportedVersion.getCreated());
return response;
}
@ -126,8 +130,11 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
private ListResponse<KubernetesSupportedVersionResponse> createKubernetesSupportedVersionListResponse(
List<KubernetesSupportedVersionVO> versions, Integer count) {
List<KubernetesSupportedVersionResponse> responseList = new ArrayList<>();
Account caller = CallContext.current().getCallingAccount();
boolean isRootAdmin = accountManager.isRootAdmin(caller.getId());
for (KubernetesSupportedVersionVO version : versions) {
responseList.add(createKubernetesSupportedVersionResponse(version));
responseList.add(createKubernetesSupportedVersionResponse(version, isRootAdmin));
}
ListResponse<KubernetesSupportedVersionResponse> response = new ListResponse<>();
response.setResponses(responseList, count);
@ -374,7 +381,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
supportedVersionVO = kubernetesSupportedVersionDao.persist(supportedVersionVO);
CallContext.current().putContextParameter(KubernetesSupportedVersion.class, supportedVersionVO.getUuid());
return createKubernetesSupportedVersionResponse(supportedVersionVO);
return createKubernetesSupportedVersionResponse(supportedVersionVO, true);
}
@Override
@ -435,7 +442,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
}
version = kubernetesSupportedVersionDao.findById(versionId);
}
return createKubernetesSupportedVersionResponse(version);
return createKubernetesSupportedVersionResponse(version, true);
}
@Override

View File

@ -50,6 +50,10 @@ public class KubernetesSupportedVersionResponse extends BaseResponse {
@Param(description = "The name of the binaries ISO for Kubernetes supported version")
private String isoName;
@SerializedName(ApiConstants.ISO_URL)
@Param(description = "the URL of the binaries ISO for Kubernetes supported version")
private String isoUrl;
@SerializedName(ApiConstants.ISO_STATE)
@Param(description = "The state of the binaries ISO for Kubernetes supported version")
private String isoState;
@ -134,6 +138,14 @@ public class KubernetesSupportedVersionResponse extends BaseResponse {
this.isoName = isoName;
}
public String getIsoUrl() {
return isoUrl;
}
public void setIsoUrl(String isoUrl) {
this.isoUrl = isoUrl;
}
public String getIsoState() {
return isoState;
}

View File

@ -48,7 +48,7 @@ public class KubernetesVersionManagerImplTest {
Mockito.when(kubernetesSupportedVersion.getIsoId()).thenReturn(1L);
KubernetesSupportedVersionResponse response = new KubernetesSupportedVersionResponse();
kubernetesVersionManager.updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion,
response);
response, true);
Assert.assertNull(ReflectionTestUtils.getField(response, "isoId"));
}
@ -63,13 +63,13 @@ public class KubernetesVersionManagerImplTest {
Mockito.when(templateJoinVO.getUuid()).thenReturn(uuid);
Mockito.when(templateJoinDao.findById(1L)).thenReturn(templateJoinVO);
kubernetesVersionManager.updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion,
response);
response, true);
Assert.assertEquals(uuid, ReflectionTestUtils.getField(response, "isoId"));
Assert.assertNull(ReflectionTestUtils.getField(response, "isoState"));
ObjectInDataStoreStateMachine.State state = ObjectInDataStoreStateMachine.State.Ready;
Mockito.when(templateJoinVO.getState()).thenReturn(state);
kubernetesVersionManager.updateTemplateDetailsInKubernetesSupportedVersionResponse(kubernetesSupportedVersion,
response);
response, true);
Assert.assertEquals(state.toString(), ReflectionTestUtils.getField(response, "isoState"));
}
}

View File

@ -17,6 +17,9 @@
package com.cloud.kubernetes.version;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
@ -25,6 +28,11 @@ import java.util.List;
import java.util.UUID;
import com.cloud.cpu.CPU;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.UserVO;
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.UpdateKubernetesSupportedVersionCmd;
@ -63,11 +71,6 @@ import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.template.TemplateApiService;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.db.Filter;
@ -95,6 +98,8 @@ public class KubernetesVersionServiceTest {
private DataCenterDao dataCenterDao;
@Mock
private TemplateApiService templateService;
@Mock
private Account accountMock;
AutoCloseable closeable;
@ -124,6 +129,7 @@ public class KubernetesVersionServiceTest {
when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone);
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
when(templateJoinVO.getUrl()).thenReturn("https://download.cloudstack.com");
when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);
when(templateJoinVO.getArch()).thenReturn(CPU.CPUArch.getDefault());
when(templateJoinDao.findById(Mockito.anyLong())).thenReturn(templateJoinVO);
@ -140,20 +146,67 @@ public class KubernetesVersionServiceTest {
@Test
public void listKubernetesSupportedVersionsTest() {
CallContext callContextMock = Mockito.mock(CallContext.class);
try (MockedStatic<CallContext> callContextMockedStatic = Mockito.mockStatic(CallContext.class)) {
callContextMockedStatic.when(CallContext::current).thenReturn(callContextMock);
final SearchCriteria<KubernetesSupportedVersionVO> versionSearchCriteria = Mockito.mock(SearchCriteria.class);
when(callContextMock.getCallingAccount()).thenReturn(accountMock);
ListKubernetesSupportedVersionsCmd cmd = Mockito.mock(ListKubernetesSupportedVersionsCmd.class);
List<KubernetesSupportedVersionVO> versionVOs = new ArrayList<>();
KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class);
when(versionVO.getSemanticVersion()).thenReturn(KubernetesVersionService.MIN_KUBERNETES_VERSION);
versionVOs.add(versionVO);
when(kubernetesSupportedVersionDao.findById(Mockito.anyLong())).thenReturn(versionVO);
when(kubernetesSupportedVersionDao.searchAndCount(Mockito.any(SearchCriteria.class),
Mockito.any(Filter.class))).thenReturn(new Pair<>(versionVOs, versionVOs.size()));
when(kubernetesSupportedVersionDao.searchAndCount(Mockito.any(), Mockito.any(Filter.class)))
.thenReturn(new Pair<>(versionVOs, versionVOs.size()));
ListResponse<KubernetesSupportedVersionResponse> versionsResponse =
kubernetesVersionService.listKubernetesSupportedVersions(cmd);
Assert.assertEquals(versionVOs.size(), versionsResponse.getCount().intValue());
Assert.assertTrue(CollectionUtils.isNotEmpty(versionsResponse.getResponses()));
Assert.assertEquals(versionVOs.size(), versionsResponse.getResponses().size());
}
}
@Test
public void listKubernetesSupportedVersionsTestWhenAdmin() {
CallContext callContextMock = Mockito.mock(CallContext.class);
try (MockedStatic<CallContext> callContextMockedStatic = Mockito.mockStatic(CallContext.class)) {
callContextMockedStatic.when(CallContext::current).thenReturn(callContextMock);
ListKubernetesSupportedVersionsCmd cmd = Mockito.mock(ListKubernetesSupportedVersionsCmd.class);
List<KubernetesSupportedVersionVO> versionVOs = new ArrayList<>();
KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class);
when(versionVO.getSemanticVersion()).thenReturn(KubernetesVersionService.MIN_KUBERNETES_VERSION);
versionVOs.add(versionVO);
when(callContextMock.getCallingAccount()).thenReturn(accountMock);
when(kubernetesSupportedVersionDao.findById(Mockito.anyLong())).thenReturn(versionVO);
when(kubernetesSupportedVersionDao.searchAndCount(Mockito.any(), Mockito.any(Filter.class)))
.thenReturn(new Pair<>(versionVOs, versionVOs.size()));
when(accountManager.isRootAdmin(anyLong())).thenReturn(true);
ListResponse<KubernetesSupportedVersionResponse> response = kubernetesVersionService.listKubernetesSupportedVersions(cmd);
assertNotNull(response.getResponses().get(0).getIsoUrl());
}
}
@Test
public void listKubernetesSupportedVersionsTestWhenOtherUser() {
CallContext callContextMock = Mockito.mock(CallContext.class);
try (MockedStatic<CallContext> callContextMockedStatic = Mockito.mockStatic(CallContext.class)) {
callContextMockedStatic.when(CallContext::current).thenReturn(callContextMock);
ListKubernetesSupportedVersionsCmd cmd = Mockito.mock(ListKubernetesSupportedVersionsCmd.class);
List<KubernetesSupportedVersionVO> versionVOs = new ArrayList<>();
KubernetesSupportedVersionVO versionVO = Mockito.mock(KubernetesSupportedVersionVO.class);
when(versionVO.getSemanticVersion()).thenReturn(KubernetesVersionService.MIN_KUBERNETES_VERSION);
versionVOs.add(versionVO);
when(callContextMock.getCallingAccount()).thenReturn(accountMock);
when(kubernetesSupportedVersionDao.findById(Mockito.anyLong())).thenReturn(versionVO);
when(kubernetesSupportedVersionDao.searchAndCount(Mockito.any(), Mockito.any(Filter.class)))
.thenReturn(new Pair<>(versionVOs, versionVOs.size()));
when(accountManager.isRootAdmin(anyLong())).thenReturn(false);
when(accountMock.getId()).thenReturn(2L);
ListResponse<KubernetesSupportedVersionResponse> response = kubernetesVersionService.listKubernetesSupportedVersions(cmd);
assertNull(response.getResponses().get(0).getIsoUrl());
}
}
@Test(expected = InvalidParameterValueException.class)
public void addKubernetesSupportedVersionLowerUnsupportedTest() {
@ -224,7 +277,6 @@ public class KubernetesVersionServiceTest {
mockedComponentContext.when(() -> ComponentContext.inject(Mockito.any(RegisterIsoCmd.class))).thenReturn(
new RegisterIsoCmd());
mockedCallContext.when(CallContext::current).thenReturn(callContext);
when(templateService.registerIso(Mockito.any(RegisterIsoCmd.class))).thenReturn(
Mockito.mock(VirtualMachineTemplate.class));
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);

View File

@ -1254,6 +1254,7 @@
"label.isoname": "Attached ISO",
"label.isos": "ISOs",
"label.isostate": "ISO state",
"label.isourl": "ISO URL",
"label.ispersistent": "Persistent ",
"label.ispublic": "Public",
"label.isready": "Ready",

View File

@ -874,6 +874,7 @@
"label.isoname": "Imagem ISO plugada",
"label.isos": "ISOs",
"label.isostate": "Estado da ISO",
"label.isourl": "URL da ISO",
"label.ispersistent": "Persistente",
"label.ispublic": "P\u00fablico",
"label.isready": "Pronto",

View File

@ -60,9 +60,9 @@ export default {
details: () => {
var fields = ['name', 'id', 'displaytext', 'checksum', 'hypervisor', 'arch', 'format', 'ostypename', 'size', 'physicalsize', 'isready', 'passwordenabled',
'crossZones', 'templatetype', 'directdownload', 'deployasis', 'ispublic', 'isfeatured', 'isextractable', 'isdynamicallyscalable', 'crosszones', 'type',
'account', 'domain', 'created', 'userdatadetails', 'userdatapolicy']
'account', 'domain', 'created', 'userdatadetails', 'userdatapolicy', 'url']
if (['Admin'].includes(store.getters.userInfo.roletype)) {
fields.push('templatetag', 'templatetype', 'url')
fields.push('templatetag', 'templatetype')
}
return fields
},
@ -372,7 +372,7 @@ export default {
permission: ['listKubernetesSupportedVersions'],
searchFilters: ['zoneid', 'minimumsemanticversion', 'arch'],
columns: ['name', 'state', 'semanticversion', 'isostate', 'mincpunumber', 'minmemory', 'arch', 'zonename'],
details: ['name', 'semanticversion', 'supportsautoscaling', 'zoneid', 'zonename', 'isoid', 'isoname', 'isostate', 'arch', 'mincpunumber', 'minmemory', 'supportsha', 'state', 'created'],
details: ['name', 'semanticversion', 'supportsautoscaling', 'zoneid', 'zonename', 'isoid', 'isoname', 'isostate', 'arch', 'mincpunumber', 'minmemory', 'supportsha', 'state', 'created', 'isourl'],
tabs: [
{
name: 'details',