Skip to content

Commit 284eba2

Browse files
author
Daman Arora
committed
Add image store validation for Kubernetes version registration
1 parent 6a324da commit 284eba2

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
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;
3638
import org.apache.commons.lang3.StringUtils;
3739

3840
import com.cloud.api.query.dao.TemplateJoinDao;
@@ -80,6 +82,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
8082
@Inject
8183
private DataCenterDao dataCenterDao;
8284
@Inject
85+
private ImageStoreDao imageStoreDao;
86+
@Inject
8387
private TemplateApiService templateService;
8488

8589
public static final String MINIMUN_AUTOSCALER_SUPPORTED_VERSION = "1.15.0";
@@ -316,6 +320,32 @@ public ListResponse<KubernetesSupportedVersionResponse> listKubernetesSupportedV
316320
return createKubernetesSupportedVersionListResponse(versions, versionsAndCount.second());
317321
}
318322

323+
private void validateImageStoreForZone(Long zoneId, boolean directDownload) {
324+
if (directDownload) {
325+
return;
326+
}
327+
if (zoneId != null) {
328+
List<ImageStoreVO> imageStores = imageStoreDao.listStoresByZoneId(zoneId);
329+
if (imageStores == null || imageStores.isEmpty()) {
330+
DataCenterVO zone = dataCenterDao.findById(zoneId);
331+
String zoneName = zone != null ? zone.getName() : String.valueOf(zoneId);
332+
throw new InvalidParameterValueException(String.format("Unable to register Kubernetes version ISO. No image store available in zone: %s", zoneName));
333+
}
334+
} else {
335+
List<DataCenterVO> zones = dataCenterDao.listAllZones();
336+
List<String> zonesWithoutStorage = new ArrayList<>();
337+
for (DataCenterVO zone : zones) {
338+
List<ImageStoreVO> imageStores = imageStoreDao.listStoresByZoneId(zone.getId());
339+
if (imageStores == null || imageStores.isEmpty()) {
340+
zonesWithoutStorage.add(zone.getName());
341+
}
342+
}
343+
if (!zonesWithoutStorage.isEmpty()) {
344+
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)));
345+
}
346+
}
347+
}
348+
319349
@Override
320350
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
321351
eventDescription = "Adding Kubernetes supported version")
@@ -361,6 +391,8 @@ public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final Ad
361391
}
362392
}
363393

394+
validateImageStoreForZone(zoneId, isDirectDownload);
395+
364396
VMTemplateVO template = null;
365397
try {
366398
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);
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
}

0 commit comments

Comments
 (0)