This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch 4.20
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.20 by this push:
     new 2a6ce0c8a81 Adds url kubernetes iso (#10862)
2a6ce0c8a81 is described below

commit 2a6ce0c8a810e908139f06d6e12d365801af4422
Author: Vitor Hugo Homem Marzarotto 
<[email protected]>
AuthorDate: Tue Jan 20 04:10:42 2026 -0300

    Adds url kubernetes iso (#10862)
    
    Co-authored-by: Vitor Hugo Homem Marzarotto 
<[email protected]>
    Co-authored-by: Henrique Sato <[email protected]>
---
 .../org/apache/cloudstack/api/ApiConstants.java    |  1 +
 .../version/KubernetesVersionManagerImpl.java      | 19 +++--
 .../KubernetesSupportedVersionResponse.java        | 12 +++
 .../version/KubernetesVersionManagerImplTest.java  |  6 +-
 .../version/KubernetesVersionServiceTest.java      | 90 +++++++++++++++++-----
 ui/public/locales/en.json                          |  1 +
 ui/public/locales/pt_BR.json                       |  1 +
 ui/src/config/section/image.js                     |  6 +-
 8 files changed, 105 insertions(+), 31 deletions(-)

diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java 
b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index 4abc0d13d74..daf1bdc705d 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -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";
diff --git 
a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java
 
b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java
index 99c9a4de051..7b126b2fba0 100644
--- 
a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java
+++ 
b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java
@@ -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
diff --git 
a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesSupportedVersionResponse.java
 
b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesSupportedVersionResponse.java
index cfa3212e409..f6e1ee85944 100644
--- 
a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesSupportedVersionResponse.java
+++ 
b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesSupportedVersionResponse.java
@@ -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;
     }
diff --git 
a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java
 
b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java
index f827610c3cb..bbec555e8e5 100644
--- 
a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java
+++ 
b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java
@@ -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"));
     }
 }
diff --git 
a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java
 
b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java
index 455df6b57d4..b874a9a0ffa 100644
--- 
a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java
+++ 
b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java
@@ -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,19 +146,66 @@ public class KubernetesVersionServiceTest {
 
     @Test
     public void listKubernetesSupportedVersionsTest() {
-        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()));
-        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());
+        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(), 
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)
@@ -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);
diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index 791091e8e2a..aaf499d2f95 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -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",
diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json
index 4d95b341ab4..1b51bc438e5 100644
--- a/ui/public/locales/pt_BR.json
+++ b/ui/public/locales/pt_BR.json
@@ -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",
diff --git a/ui/src/config/section/image.js b/ui/src/config/section/image.js
index 46dec2e1b24..3f8286c5fb1 100644
--- a/ui/src/config/section/image.js
+++ b/ui/src/config/section/image.js
@@ -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',

Reply via email to