Skip to content

Commit da518e9

Browse files
Damans227Daman Arora
andauthored
CKS: Add image store validation for Kubernetes version registration (#12418)
Co-authored-by: Daman Arora <[email protected]>
1 parent 03d24ff commit da518e9

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
3434
import org.apache.cloudstack.api.response.ListResponse;
3535
import org.apache.cloudstack.context.CallContext;
36+
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
37+
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
38+
import org.apache.commons.collections.CollectionUtils;
3639
import org.apache.commons.lang3.StringUtils;
3740

3841
import com.cloud.api.query.dao.TemplateJoinDao;
@@ -81,6 +84,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
8184
@Inject
8285
private DataCenterDao dataCenterDao;
8386
@Inject
87+
private ImageStoreDao imageStoreDao;
88+
@Inject
8489
private TemplateApiService templateService;
8590

8691
public static final String MINIMUN_AUTOSCALER_SUPPORTED_VERSION = "1.15.0";
@@ -323,6 +328,32 @@ public ListResponse<KubernetesSupportedVersionResponse> listKubernetesSupportedV
323328
return createKubernetesSupportedVersionListResponse(versions, versionsAndCount.second());
324329
}
325330

331+
private void validateImageStoreForZone(Long zoneId, boolean directDownload) {
332+
if (directDownload) {
333+
return;
334+
}
335+
if (zoneId != null) {
336+
List<ImageStoreVO> imageStores = imageStoreDao.listStoresByZoneId(zoneId);
337+
if (CollectionUtils.isEmpty(imageStores)) {
338+
DataCenterVO zone = dataCenterDao.findById(zoneId);
339+
String zoneName = zone != null ? zone.getName() : String.valueOf(zoneId);
340+
throw new InvalidParameterValueException(String.format("Unable to register Kubernetes version ISO. No image store available in zone: %s", zoneName));
341+
}
342+
} else {
343+
List<DataCenterVO> zones = dataCenterDao.listAllZones();
344+
List<String> zonesWithoutStorage = new ArrayList<>();
345+
for (DataCenterVO zone : zones) {
346+
List<ImageStoreVO> imageStores = imageStoreDao.listStoresByZoneId(zone.getId());
347+
if (CollectionUtils.isEmpty(imageStores)) {
348+
zonesWithoutStorage.add(zone.getName());
349+
}
350+
}
351+
if (!zonesWithoutStorage.isEmpty()) {
352+
throw new InvalidParameterValueException(String.format("Unable to register Kubernetes version ISO for all zones. The following zones have no image store: %s", String.join(", ", zonesWithoutStorage)));
353+
}
354+
}
355+
}
356+
326357
@Override
327358
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
328359
eventDescription = "Adding Kubernetes supported version")
@@ -368,6 +399,8 @@ public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final Ad
368399
}
369400
}
370401

402+
validateImageStoreForZone(zoneId, isDirectDownload);
403+
371404
VMTemplateVO template = null;
372405
try {
373406
VirtualMachineTemplate vmTemplate = registerKubernetesVersionIso(zoneId, name, isoUrl, isoChecksum, isDirectDownload, arch);

plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionManagerImplTest.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616
// under the License.
1717
package com.cloud.kubernetes.version;
1818

19+
import java.util.Arrays;
20+
import java.util.Collections;
21+
import java.util.List;
1922
import java.util.UUID;
2023

2124
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
2225
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
26+
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
27+
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
2328
import org.junit.Assert;
2429
import org.junit.Test;
2530
import org.junit.runner.RunWith;
@@ -32,13 +37,22 @@
3237
import com.cloud.api.query.dao.TemplateJoinDao;
3338
import com.cloud.api.query.vo.TemplateJoinVO;
3439
import com.cloud.cpu.CPU;
40+
import com.cloud.dc.DataCenterVO;
41+
import com.cloud.dc.dao.DataCenterDao;
42+
import com.cloud.exception.InvalidParameterValueException;
3543

3644
@RunWith(MockitoJUnitRunner.class)
3745
public class KubernetesVersionManagerImplTest {
3846

3947
@Mock
4048
TemplateJoinDao templateJoinDao;
4149

50+
@Mock
51+
ImageStoreDao imageStoreDao;
52+
53+
@Mock
54+
DataCenterDao dataCenterDao;
55+
4256
@InjectMocks
4357
KubernetesVersionManagerImpl kubernetesVersionManager = new KubernetesVersionManagerImpl();
4458

@@ -72,4 +86,62 @@ public void testUpdateTemplateDetailsInKubernetesSupportedVersionResponseValidTe
7286
response, true);
7387
Assert.assertEquals(state.toString(), ReflectionTestUtils.getField(response, "isoState"));
7488
}
89+
90+
@Test
91+
public void testValidateImageStoreForZoneWithDirectDownload() {
92+
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", 1L, true);
93+
}
94+
95+
@Test
96+
public void testValidateImageStoreForZoneWithValidZone() {
97+
Long zoneId = 1L;
98+
List<ImageStoreVO> imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class));
99+
Mockito.when(imageStoreDao.listStoresByZoneId(zoneId)).thenReturn(imageStores);
100+
101+
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", zoneId, false);
102+
}
103+
104+
@Test(expected = InvalidParameterValueException.class)
105+
public void testValidateImageStoreForZoneWithNoImageStore() {
106+
Long zoneId = 1L;
107+
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
108+
Mockito.when(zone.getName()).thenReturn("test-zone");
109+
Mockito.when(dataCenterDao.findById(zoneId)).thenReturn(zone);
110+
Mockito.when(imageStoreDao.listStoresByZoneId(zoneId)).thenReturn(Collections.emptyList());
111+
112+
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", zoneId, false);
113+
}
114+
115+
@Test
116+
public void testValidateImageStoreForAllZonesWithAllValid() {
117+
DataCenterVO zone1 = Mockito.mock(DataCenterVO.class);
118+
Mockito.when(zone1.getId()).thenReturn(1L);
119+
DataCenterVO zone2 = Mockito.mock(DataCenterVO.class);
120+
Mockito.when(zone2.getId()).thenReturn(2L);
121+
List<DataCenterVO> zones = Arrays.asList(zone1, zone2);
122+
Mockito.when(dataCenterDao.listAllZones()).thenReturn(zones);
123+
124+
List<ImageStoreVO> imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class));
125+
Mockito.when(imageStoreDao.listStoresByZoneId(1L)).thenReturn(imageStores);
126+
Mockito.when(imageStoreDao.listStoresByZoneId(2L)).thenReturn(imageStores);
127+
128+
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", (Long) null, false);
129+
}
130+
131+
@Test(expected = InvalidParameterValueException.class)
132+
public void testValidateImageStoreForAllZonesWithSomeMissingStorage() {
133+
DataCenterVO zone1 = Mockito.mock(DataCenterVO.class);
134+
Mockito.when(zone1.getId()).thenReturn(1L);
135+
DataCenterVO zone2 = Mockito.mock(DataCenterVO.class);
136+
Mockito.when(zone2.getId()).thenReturn(2L);
137+
Mockito.when(zone2.getName()).thenReturn("zone-without-storage");
138+
List<DataCenterVO> zones = Arrays.asList(zone1, zone2);
139+
Mockito.when(dataCenterDao.listAllZones()).thenReturn(zones);
140+
141+
List<ImageStoreVO> imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class));
142+
Mockito.when(imageStoreDao.listStoresByZoneId(1L)).thenReturn(imageStores);
143+
Mockito.when(imageStoreDao.listStoresByZoneId(2L)).thenReturn(Collections.emptyList());
144+
145+
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", (Long) null, false);
146+
}
75147
}

plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
import com.cloud.utils.db.SearchCriteria;
7979
import com.cloud.utils.exception.CloudRuntimeException;
8080

81+
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
82+
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
83+
8184
@RunWith(MockitoJUnitRunner.class)
8285
public class KubernetesVersionServiceTest {
8386

@@ -97,6 +100,8 @@ public class KubernetesVersionServiceTest {
97100
@Mock
98101
private DataCenterDao dataCenterDao;
99102
@Mock
103+
private ImageStoreDao imageStoreDao;
104+
@Mock
100105
private TemplateApiService templateService;
101106
@Mock
102107
private Account accountMock;
@@ -128,6 +133,10 @@ public void setUp() throws Exception {
128133
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
129134
when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone);
130135

136+
List<ImageStoreVO> imageStores = new ArrayList<>();
137+
imageStores.add(Mockito.mock(ImageStoreVO.class));
138+
when(imageStoreDao.listStoresByZoneId(Mockito.anyLong())).thenReturn(imageStores);
139+
131140
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
132141
when(templateJoinVO.getUrl()).thenReturn("https://download.cloudstack.com");
133142
when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);

0 commit comments

Comments
 (0)