mirror of https://github.com/apache/cloudstack.git
CKS: Add image store validation for Kubernetes version registration (#12418)
Co-authored-by: Daman Arora <daman.arora@shapeblue.com>
This commit is contained in:
parent
03d24ff851
commit
da518e9036
|
|
@ -33,6 +33,9 @@ import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesS
|
||||||
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
|
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.cloud.api.query.dao.TemplateJoinDao;
|
import com.cloud.api.query.dao.TemplateJoinDao;
|
||||||
|
|
@ -81,6 +84,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
||||||
@Inject
|
@Inject
|
||||||
private DataCenterDao dataCenterDao;
|
private DataCenterDao dataCenterDao;
|
||||||
@Inject
|
@Inject
|
||||||
|
private ImageStoreDao imageStoreDao;
|
||||||
|
@Inject
|
||||||
private TemplateApiService templateService;
|
private TemplateApiService templateService;
|
||||||
|
|
||||||
public static final String MINIMUN_AUTOSCALER_SUPPORTED_VERSION = "1.15.0";
|
public static final String MINIMUN_AUTOSCALER_SUPPORTED_VERSION = "1.15.0";
|
||||||
|
|
@ -323,6 +328,32 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
||||||
return createKubernetesSupportedVersionListResponse(versions, versionsAndCount.second());
|
return createKubernetesSupportedVersionListResponse(versions, versionsAndCount.second());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateImageStoreForZone(Long zoneId, boolean directDownload) {
|
||||||
|
if (directDownload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (zoneId != null) {
|
||||||
|
List<ImageStoreVO> imageStores = imageStoreDao.listStoresByZoneId(zoneId);
|
||||||
|
if (CollectionUtils.isEmpty(imageStores)) {
|
||||||
|
DataCenterVO zone = dataCenterDao.findById(zoneId);
|
||||||
|
String zoneName = zone != null ? zone.getName() : String.valueOf(zoneId);
|
||||||
|
throw new InvalidParameterValueException(String.format("Unable to register Kubernetes version ISO. No image store available in zone: %s", zoneName));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<DataCenterVO> zones = dataCenterDao.listAllZones();
|
||||||
|
List<String> zonesWithoutStorage = new ArrayList<>();
|
||||||
|
for (DataCenterVO zone : zones) {
|
||||||
|
List<ImageStoreVO> imageStores = imageStoreDao.listStoresByZoneId(zone.getId());
|
||||||
|
if (CollectionUtils.isEmpty(imageStores)) {
|
||||||
|
zonesWithoutStorage.add(zone.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!zonesWithoutStorage.isEmpty()) {
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
|
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
|
||||||
eventDescription = "Adding Kubernetes supported version")
|
eventDescription = "Adding Kubernetes supported version")
|
||||||
|
|
@ -368,6 +399,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateImageStoreForZone(zoneId, isDirectDownload);
|
||||||
|
|
||||||
VMTemplateVO template = null;
|
VMTemplateVO template = null;
|
||||||
try {
|
try {
|
||||||
VirtualMachineTemplate vmTemplate = registerKubernetesVersionIso(zoneId, name, isoUrl, isoChecksum, isDirectDownload, arch);
|
VirtualMachineTemplate vmTemplate = registerKubernetesVersionIso(zoneId, name, isoUrl, isoChecksum, isDirectDownload, arch);
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,15 @@
|
||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.kubernetes.version;
|
package com.cloud.kubernetes.version;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
|
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
@ -32,6 +37,9 @@ import org.springframework.test.util.ReflectionTestUtils;
|
||||||
import com.cloud.api.query.dao.TemplateJoinDao;
|
import com.cloud.api.query.dao.TemplateJoinDao;
|
||||||
import com.cloud.api.query.vo.TemplateJoinVO;
|
import com.cloud.api.query.vo.TemplateJoinVO;
|
||||||
import com.cloud.cpu.CPU;
|
import com.cloud.cpu.CPU;
|
||||||
|
import com.cloud.dc.DataCenterVO;
|
||||||
|
import com.cloud.dc.dao.DataCenterDao;
|
||||||
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class KubernetesVersionManagerImplTest {
|
public class KubernetesVersionManagerImplTest {
|
||||||
|
|
@ -39,6 +47,12 @@ public class KubernetesVersionManagerImplTest {
|
||||||
@Mock
|
@Mock
|
||||||
TemplateJoinDao templateJoinDao;
|
TemplateJoinDao templateJoinDao;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ImageStoreDao imageStoreDao;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
DataCenterDao dataCenterDao;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
KubernetesVersionManagerImpl kubernetesVersionManager = new KubernetesVersionManagerImpl();
|
KubernetesVersionManagerImpl kubernetesVersionManager = new KubernetesVersionManagerImpl();
|
||||||
|
|
||||||
|
|
@ -72,4 +86,62 @@ public class KubernetesVersionManagerImplTest {
|
||||||
response, true);
|
response, true);
|
||||||
Assert.assertEquals(state.toString(), ReflectionTestUtils.getField(response, "isoState"));
|
Assert.assertEquals(state.toString(), ReflectionTestUtils.getField(response, "isoState"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateImageStoreForZoneWithDirectDownload() {
|
||||||
|
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", 1L, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateImageStoreForZoneWithValidZone() {
|
||||||
|
Long zoneId = 1L;
|
||||||
|
List<ImageStoreVO> imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class));
|
||||||
|
Mockito.when(imageStoreDao.listStoresByZoneId(zoneId)).thenReturn(imageStores);
|
||||||
|
|
||||||
|
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", zoneId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testValidateImageStoreForZoneWithNoImageStore() {
|
||||||
|
Long zoneId = 1L;
|
||||||
|
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
|
||||||
|
Mockito.when(zone.getName()).thenReturn("test-zone");
|
||||||
|
Mockito.when(dataCenterDao.findById(zoneId)).thenReturn(zone);
|
||||||
|
Mockito.when(imageStoreDao.listStoresByZoneId(zoneId)).thenReturn(Collections.emptyList());
|
||||||
|
|
||||||
|
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", zoneId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateImageStoreForAllZonesWithAllValid() {
|
||||||
|
DataCenterVO zone1 = Mockito.mock(DataCenterVO.class);
|
||||||
|
Mockito.when(zone1.getId()).thenReturn(1L);
|
||||||
|
DataCenterVO zone2 = Mockito.mock(DataCenterVO.class);
|
||||||
|
Mockito.when(zone2.getId()).thenReturn(2L);
|
||||||
|
List<DataCenterVO> zones = Arrays.asList(zone1, zone2);
|
||||||
|
Mockito.when(dataCenterDao.listAllZones()).thenReturn(zones);
|
||||||
|
|
||||||
|
List<ImageStoreVO> imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class));
|
||||||
|
Mockito.when(imageStoreDao.listStoresByZoneId(1L)).thenReturn(imageStores);
|
||||||
|
Mockito.when(imageStoreDao.listStoresByZoneId(2L)).thenReturn(imageStores);
|
||||||
|
|
||||||
|
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", (Long) null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void testValidateImageStoreForAllZonesWithSomeMissingStorage() {
|
||||||
|
DataCenterVO zone1 = Mockito.mock(DataCenterVO.class);
|
||||||
|
Mockito.when(zone1.getId()).thenReturn(1L);
|
||||||
|
DataCenterVO zone2 = Mockito.mock(DataCenterVO.class);
|
||||||
|
Mockito.when(zone2.getId()).thenReturn(2L);
|
||||||
|
Mockito.when(zone2.getName()).thenReturn("zone-without-storage");
|
||||||
|
List<DataCenterVO> zones = Arrays.asList(zone1, zone2);
|
||||||
|
Mockito.when(dataCenterDao.listAllZones()).thenReturn(zones);
|
||||||
|
|
||||||
|
List<ImageStoreVO> imageStores = Collections.singletonList(Mockito.mock(ImageStoreVO.class));
|
||||||
|
Mockito.when(imageStoreDao.listStoresByZoneId(1L)).thenReturn(imageStores);
|
||||||
|
Mockito.when(imageStoreDao.listStoresByZoneId(2L)).thenReturn(Collections.emptyList());
|
||||||
|
|
||||||
|
ReflectionTestUtils.invokeMethod(kubernetesVersionManager, "validateImageStoreForZone", (Long) null, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,9 @@ import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class KubernetesVersionServiceTest {
|
public class KubernetesVersionServiceTest {
|
||||||
|
|
||||||
|
|
@ -97,6 +100,8 @@ public class KubernetesVersionServiceTest {
|
||||||
@Mock
|
@Mock
|
||||||
private DataCenterDao dataCenterDao;
|
private DataCenterDao dataCenterDao;
|
||||||
@Mock
|
@Mock
|
||||||
|
private ImageStoreDao imageStoreDao;
|
||||||
|
@Mock
|
||||||
private TemplateApiService templateService;
|
private TemplateApiService templateService;
|
||||||
@Mock
|
@Mock
|
||||||
private Account accountMock;
|
private Account accountMock;
|
||||||
|
|
@ -128,6 +133,10 @@ public class KubernetesVersionServiceTest {
|
||||||
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
|
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
|
||||||
when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone);
|
when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone);
|
||||||
|
|
||||||
|
List<ImageStoreVO> imageStores = new ArrayList<>();
|
||||||
|
imageStores.add(Mockito.mock(ImageStoreVO.class));
|
||||||
|
when(imageStoreDao.listStoresByZoneId(Mockito.anyLong())).thenReturn(imageStores);
|
||||||
|
|
||||||
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
|
TemplateJoinVO templateJoinVO = Mockito.mock(TemplateJoinVO.class);
|
||||||
when(templateJoinVO.getUrl()).thenReturn("https://download.cloudstack.com");
|
when(templateJoinVO.getUrl()).thenReturn("https://download.cloudstack.com");
|
||||||
when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);
|
when(templateJoinVO.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue