diff --git a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java index 1bda7019d1d..61bcd5368d8 100644 --- a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java +++ b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java @@ -18,6 +18,7 @@ package com.cloud.kubernetes.cluster; import org.apache.cloudstack.acl.ControlledEntity; +import java.util.List; import java.util.Map; import com.cloud.user.Account; @@ -36,6 +37,6 @@ public interface KubernetesServiceHelper extends Adapter { boolean isValidNodeType(String nodeType); Map getServiceOfferingNodeTypeMap(Map> serviceOfferingNodeTypeMap); Map getTemplateNodeTypeMap(Map> templateNodeTypeMap); - Map getAffinityGroupNodeTypeMap(Map> affinityGroupNodeTypeMap); + Map> getAffinityGroupNodeTypeMap(Map> affinityGroupNodeTypeMap); void cleanupForAccount(Account account); } diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImpl.java index 85a4191ed20..62712514b2d 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImpl.java @@ -18,7 +18,9 @@ package com.cloud.kubernetes.cluster; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -248,8 +250,8 @@ public class KubernetesServiceHelperImpl extends AdapterBase implements Kubernet return mapping; } - protected void checkNodeTypeAffinityGroupEntryCompleteness(String nodeTypeStr, String affinityGroupUuids) { - if (StringUtils.isAnyBlank(nodeTypeStr, affinityGroupUuids)) { + protected void checkNodeTypeAffinityGroupEntryCompleteness(String nodeType, String affinityGroupUuids) { + if (StringUtils.isAnyBlank(nodeType, affinityGroupUuids)) { String error = String.format("Any Node Type to Affinity Group entry should have a valid '%s' and '%s' values", VmDetailConstants.CKS_NODE_TYPE, VmDetailConstants.AFFINITY_GROUP); logger.error(error); @@ -257,15 +259,15 @@ public class KubernetesServiceHelperImpl extends AdapterBase implements Kubernet } } - protected void checkNodeTypeAffinityGroupEntryNodeType(String nodeTypeStr) { - if (!isValidNodeType(nodeTypeStr)) { - String error = String.format("The provided value '%s' for Node Type is invalid", nodeTypeStr); + protected void checkNodeTypeAffinityGroupEntryNodeType(String nodeType) { + if (!isValidNodeType(nodeType)) { + String error = String.format("The provided value '%s' for Node Type is invalid", nodeType); logger.error(error); throw new InvalidParameterValueException(error); } } - protected void validateAffinityGroupUuid(String affinityGroupUuid) { + protected Long validateAffinityGroupUuidAndGetId(String affinityGroupUuid) { if (StringUtils.isBlank(affinityGroupUuid)) { String error = "Empty affinity group UUID provided"; logger.error(error); @@ -277,55 +279,52 @@ public class KubernetesServiceHelperImpl extends AdapterBase implements Kubernet logger.error(error); throw new InvalidParameterValueException(error); } + return affinityGroup.getId(); } - protected String validateAndNormalizeAffinityGroupUuids(String affinityGroupUuids) { + protected List validateAndGetAffinityGroupIds(String affinityGroupUuids) { String[] uuids = affinityGroupUuids.split(","); - StringBuilder normalizedUuids = new StringBuilder(); - for (int i = 0; i < uuids.length; i++) { - String uuid = uuids[i].trim(); - validateAffinityGroupUuid(uuid); - if (i > 0) { - normalizedUuids.append(","); - } - normalizedUuids.append(uuid); + List affinityGroupIds = new ArrayList<>(); + for (String uuid : uuids) { + String trimmedUuid = uuid.trim(); + Long affinityGroupId = validateAffinityGroupUuidAndGetId(trimmedUuid); + affinityGroupIds.add(affinityGroupId); } - return normalizedUuids.toString(); + return affinityGroupIds; } - protected void addNodeTypeAffinityGroupEntry(String nodeTypeStr, String validatedAffinityGroupUuids, Map mapping) { + protected void addNodeTypeAffinityGroupEntry(String nodeType, List affinityGroupIds, Map> nodeTypeToAffinityGroupIds) { if (logger.isDebugEnabled()) { - logger.debug(String.format("Node Type: '%s' should use affinity group IDs: '%s'", nodeTypeStr, validatedAffinityGroupUuids)); + logger.debug(String.format("Node Type: '%s' should use affinity group IDs: '%s'", nodeType, affinityGroupIds)); } - KubernetesClusterNodeType nodeType = KubernetesClusterNodeType.valueOf(nodeTypeStr.toUpperCase()); - mapping.put(nodeType.name(), validatedAffinityGroupUuids); + KubernetesClusterNodeType clusterNodeType = KubernetesClusterNodeType.valueOf(nodeType.toUpperCase()); + nodeTypeToAffinityGroupIds.put(clusterNodeType.name(), affinityGroupIds); } - protected void processNodeTypeAffinityGroupEntryAndAddToMappingIfValid(Map entry, Map mapping) { - if (MapUtils.isEmpty(entry)) { + protected void processNodeTypeAffinityGroupEntryAndAddToMappingIfValid(Map nodeTypeAffinityConfig, Map> nodeTypeToAffinityGroupIds) { + if (MapUtils.isEmpty(nodeTypeAffinityConfig)) { return; } - String nodeTypeStr = entry.get(VmDetailConstants.CKS_NODE_TYPE); - String affinityGroupUuids = entry.get(VmDetailConstants.AFFINITY_GROUP); - checkNodeTypeAffinityGroupEntryCompleteness(nodeTypeStr, affinityGroupUuids); - checkNodeTypeAffinityGroupEntryNodeType(nodeTypeStr); + String nodeType = nodeTypeAffinityConfig.get(VmDetailConstants.CKS_NODE_TYPE); + String affinityGroupUuids = nodeTypeAffinityConfig.get(VmDetailConstants.AFFINITY_GROUP); + checkNodeTypeAffinityGroupEntryCompleteness(nodeType, affinityGroupUuids); + checkNodeTypeAffinityGroupEntryNodeType(nodeType); - String validatedUuids = validateAndNormalizeAffinityGroupUuids(affinityGroupUuids); - addNodeTypeAffinityGroupEntry(nodeTypeStr, validatedUuids, mapping); + List affinityGroupIds = validateAndGetAffinityGroupIds(affinityGroupUuids); + addNodeTypeAffinityGroupEntry(nodeType, affinityGroupIds, nodeTypeToAffinityGroupIds); } @Override - public Map getAffinityGroupNodeTypeMap(Map> affinityGroupNodeTypeMap) { - Map mapping = new HashMap<>(); + public Map> getAffinityGroupNodeTypeMap(Map> affinityGroupNodeTypeMap) { + Map> nodeTypeToAffinityGroupIds = new HashMap<>(); if (MapUtils.isNotEmpty(affinityGroupNodeTypeMap)) { - for (Map entry : affinityGroupNodeTypeMap.values()) { - processNodeTypeAffinityGroupEntryAndAddToMappingIfValid(entry, mapping); + for (Map nodeTypeAffinityConfig : affinityGroupNodeTypeMap.values()) { + processNodeTypeAffinityGroupEntryAndAddToMappingIfValid(nodeTypeAffinityConfig, nodeTypeToAffinityGroupIds); } } - return mapping; + return nodeTypeToAffinityGroupIds; } - public void cleanupForAccount(Account account) { kubernetesClusterService.cleanupForAccount(account); } diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/CreateKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/CreateKubernetesClusterCmd.java index 1ab88cb1372..bac3cd96486 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/CreateKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/CreateKubernetesClusterCmd.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.command.user.kubernetes.cluster; import java.security.InvalidParameterException; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -327,7 +328,7 @@ public class CreateKubernetesClusterCmd extends BaseAsyncCreateCmd { return kubernetesServiceHelper.getTemplateNodeTypeMap(templateNodeTypeMap); } - public Map getAffinityGroupNodeTypeMap() { + public Map> getAffinityGroupNodeTypeMap() { return kubernetesServiceHelper.getAffinityGroupNodeTypeMap(affinityGroupNodeTypeMap); } diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImplTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImplTest.java index 30596979d73..3994cadc307 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImplTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImplTest.java @@ -17,7 +17,9 @@ package com.cloud.kubernetes.cluster; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -218,76 +220,87 @@ public class KubernetesServiceHelperImplTest { } @Test(expected = InvalidParameterValueException.class) - public void testValidateAffinityGroupUuidBlank() { - kubernetesServiceHelper.validateAffinityGroupUuid(""); + public void testValidateAffinityGroupUuidAndGetIdBlank() { + kubernetesServiceHelper.validateAffinityGroupUuidAndGetId(""); } @Test(expected = InvalidParameterValueException.class) - public void testValidateAffinityGroupUuidNotFound() { + public void testValidateAffinityGroupUuidAndGetIdNotFound() { Mockito.when(affinityGroupDao.findByUuid("non-existent-uuid")).thenReturn(null); - kubernetesServiceHelper.validateAffinityGroupUuid("non-existent-uuid"); + kubernetesServiceHelper.validateAffinityGroupUuidAndGetId("non-existent-uuid"); } @Test - public void testValidateAffinityGroupUuidValid() { + public void testValidateAffinityGroupUuidAndGetIdValid() { AffinityGroupVO affinityGroup = Mockito.mock(AffinityGroupVO.class); + Mockito.when(affinityGroup.getId()).thenReturn(100L); Mockito.when(affinityGroupDao.findByUuid("valid-uuid")).thenReturn(affinityGroup); - kubernetesServiceHelper.validateAffinityGroupUuid("valid-uuid"); + Long result = kubernetesServiceHelper.validateAffinityGroupUuidAndGetId("valid-uuid"); + Assert.assertEquals(Long.valueOf(100L), result); } @Test - public void testValidateAndNormalizeAffinityGroupUuidsSingleUuid() { + public void testValidateAndGetAffinityGroupIdsSingleUuid() { AffinityGroupVO affinityGroup = Mockito.mock(AffinityGroupVO.class); + Mockito.when(affinityGroup.getId()).thenReturn(1L); Mockito.when(affinityGroupDao.findByUuid("uuid1")).thenReturn(affinityGroup); - String result = kubernetesServiceHelper.validateAndNormalizeAffinityGroupUuids("uuid1"); - Assert.assertEquals("uuid1", result); + List result = kubernetesServiceHelper.validateAndGetAffinityGroupIds("uuid1"); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(Long.valueOf(1L), result.get(0)); } @Test - public void testValidateAndNormalizeAffinityGroupUuidsMultipleUuids() { + public void testValidateAndGetAffinityGroupIdsMultipleUuids() { AffinityGroupVO affinityGroup1 = Mockito.mock(AffinityGroupVO.class); AffinityGroupVO affinityGroup2 = Mockito.mock(AffinityGroupVO.class); AffinityGroupVO affinityGroup3 = Mockito.mock(AffinityGroupVO.class); + Mockito.when(affinityGroup1.getId()).thenReturn(1L); + Mockito.when(affinityGroup2.getId()).thenReturn(2L); + Mockito.when(affinityGroup3.getId()).thenReturn(3L); Mockito.when(affinityGroupDao.findByUuid("uuid1")).thenReturn(affinityGroup1); Mockito.when(affinityGroupDao.findByUuid("uuid2")).thenReturn(affinityGroup2); Mockito.when(affinityGroupDao.findByUuid("uuid3")).thenReturn(affinityGroup3); - String result = kubernetesServiceHelper.validateAndNormalizeAffinityGroupUuids("uuid1,uuid2,uuid3"); - Assert.assertEquals("uuid1,uuid2,uuid3", result); + List result = kubernetesServiceHelper.validateAndGetAffinityGroupIds("uuid1,uuid2,uuid3"); + Assert.assertEquals(3, result.size()); + Assert.assertEquals(Arrays.asList(1L, 2L, 3L), result); } @Test - public void testValidateAndNormalizeAffinityGroupUuidsWithSpaces() { + public void testValidateAndGetAffinityGroupIdsWithSpaces() { AffinityGroupVO affinityGroup1 = Mockito.mock(AffinityGroupVO.class); AffinityGroupVO affinityGroup2 = Mockito.mock(AffinityGroupVO.class); + Mockito.when(affinityGroup1.getId()).thenReturn(1L); + Mockito.when(affinityGroup2.getId()).thenReturn(2L); Mockito.when(affinityGroupDao.findByUuid("uuid1")).thenReturn(affinityGroup1); Mockito.when(affinityGroupDao.findByUuid("uuid2")).thenReturn(affinityGroup2); - String result = kubernetesServiceHelper.validateAndNormalizeAffinityGroupUuids(" uuid1 , uuid2 "); - Assert.assertEquals("uuid1,uuid2", result); + List result = kubernetesServiceHelper.validateAndGetAffinityGroupIds(" uuid1 , uuid2 "); + Assert.assertEquals(2, result.size()); + Assert.assertEquals(Arrays.asList(1L, 2L), result); } @Test(expected = InvalidParameterValueException.class) - public void testValidateAndNormalizeAffinityGroupUuidsOneInvalid() { + public void testValidateAndGetAffinityGroupIdsOneInvalid() { AffinityGroupVO affinityGroup1 = Mockito.mock(AffinityGroupVO.class); Mockito.when(affinityGroupDao.findByUuid("uuid1")).thenReturn(affinityGroup1); Mockito.when(affinityGroupDao.findByUuid("invalid-uuid")).thenReturn(null); - kubernetesServiceHelper.validateAndNormalizeAffinityGroupUuids("uuid1,invalid-uuid"); + kubernetesServiceHelper.validateAndGetAffinityGroupIds("uuid1,invalid-uuid"); } @Test public void testAddNodeTypeAffinityGroupEntry() { - Map mapping = new HashMap<>(); - kubernetesServiceHelper.addNodeTypeAffinityGroupEntry("control", "uuid1,uuid2", mapping); + Map> mapping = new HashMap<>(); + kubernetesServiceHelper.addNodeTypeAffinityGroupEntry("control", Arrays.asList(1L, 2L), mapping); Assert.assertEquals(1, mapping.size()); - Assert.assertEquals("uuid1,uuid2", mapping.get("CONTROL")); + Assert.assertEquals(Arrays.asList(1L, 2L), mapping.get("CONTROL")); } @Test public void testProcessNodeTypeAffinityGroupEntryAndAddToMappingIfValidEmptyEntry() { - Map mapping = new HashMap<>(); + Map> mapping = new HashMap<>(); kubernetesServiceHelper.processNodeTypeAffinityGroupEntryAndAddToMappingIfValid(new HashMap<>(), mapping); Assert.assertTrue(mapping.isEmpty()); } @@ -295,22 +308,25 @@ public class KubernetesServiceHelperImplTest { @Test public void testProcessNodeTypeAffinityGroupEntryAndAddToMappingIfValidValidEntry() { AffinityGroupVO affinityGroup = Mockito.mock(AffinityGroupVO.class); + Mockito.when(affinityGroup.getId()).thenReturn(100L); Mockito.when(affinityGroupDao.findByUuid("affinity-group-uuid")).thenReturn(affinityGroup); Map entry = new HashMap<>(); entry.put(VmDetailConstants.CKS_NODE_TYPE, "control"); entry.put(VmDetailConstants.AFFINITY_GROUP, "affinity-group-uuid"); - Map mapping = new HashMap<>(); + Map> mapping = new HashMap<>(); kubernetesServiceHelper.processNodeTypeAffinityGroupEntryAndAddToMappingIfValid(entry, mapping); Assert.assertEquals(1, mapping.size()); - Assert.assertEquals("affinity-group-uuid", mapping.get("CONTROL")); + Assert.assertEquals(Arrays.asList(100L), mapping.get("CONTROL")); } @Test public void testProcessNodeTypeAffinityGroupEntryAndAddToMappingIfValidMultipleUuids() { AffinityGroupVO affinityGroup1 = Mockito.mock(AffinityGroupVO.class); AffinityGroupVO affinityGroup2 = Mockito.mock(AffinityGroupVO.class); + Mockito.when(affinityGroup1.getId()).thenReturn(1L); + Mockito.when(affinityGroup2.getId()).thenReturn(2L); Mockito.when(affinityGroupDao.findByUuid("uuid1")).thenReturn(affinityGroup1); Mockito.when(affinityGroupDao.findByUuid("uuid2")).thenReturn(affinityGroup2); @@ -318,15 +334,15 @@ public class KubernetesServiceHelperImplTest { entry.put(VmDetailConstants.CKS_NODE_TYPE, "worker"); entry.put(VmDetailConstants.AFFINITY_GROUP, "uuid1,uuid2"); - Map mapping = new HashMap<>(); + Map> mapping = new HashMap<>(); kubernetesServiceHelper.processNodeTypeAffinityGroupEntryAndAddToMappingIfValid(entry, mapping); Assert.assertEquals(1, mapping.size()); - Assert.assertEquals("uuid1,uuid2", mapping.get("WORKER")); + Assert.assertEquals(Arrays.asList(1L, 2L), mapping.get("WORKER")); } @Test public void testGetAffinityGroupNodeTypeMapEmptyMap() { - Map result = kubernetesServiceHelper.getAffinityGroupNodeTypeMap(null); + Map> result = kubernetesServiceHelper.getAffinityGroupNodeTypeMap(null); Assert.assertTrue(result.isEmpty()); result = kubernetesServiceHelper.getAffinityGroupNodeTypeMap(new HashMap<>()); @@ -336,9 +352,11 @@ public class KubernetesServiceHelperImplTest { @Test public void testGetAffinityGroupNodeTypeMapValidEntries() { AffinityGroupVO controlAffinityGroup = Mockito.mock(AffinityGroupVO.class); + Mockito.when(controlAffinityGroup.getId()).thenReturn(100L); Mockito.when(affinityGroupDao.findByUuid("control-affinity-uuid")).thenReturn(controlAffinityGroup); AffinityGroupVO workerAffinityGroup = Mockito.mock(AffinityGroupVO.class); + Mockito.when(workerAffinityGroup.getId()).thenReturn(200L); Mockito.when(affinityGroupDao.findByUuid("worker-affinity-uuid")).thenReturn(workerAffinityGroup); Map> affinityGroupNodeTypeMap = new HashMap<>(); @@ -353,17 +371,20 @@ public class KubernetesServiceHelperImplTest { workerEntry.put(VmDetailConstants.AFFINITY_GROUP, "worker-affinity-uuid"); affinityGroupNodeTypeMap.put("1", workerEntry); - Map result = kubernetesServiceHelper.getAffinityGroupNodeTypeMap(affinityGroupNodeTypeMap); + Map> result = kubernetesServiceHelper.getAffinityGroupNodeTypeMap(affinityGroupNodeTypeMap); Assert.assertEquals(2, result.size()); - Assert.assertEquals("control-affinity-uuid", result.get("CONTROL")); - Assert.assertEquals("worker-affinity-uuid", result.get("WORKER")); + Assert.assertEquals(Arrays.asList(100L), result.get("CONTROL")); + Assert.assertEquals(Arrays.asList(200L), result.get("WORKER")); } @Test - public void testGetAffinityGroupNodeTypeMapMultipleUuidsPerNodeType() { + public void testGetAffinityGroupNodeTypeMapMultipleIdsPerNodeType() { AffinityGroupVO ag1 = Mockito.mock(AffinityGroupVO.class); AffinityGroupVO ag2 = Mockito.mock(AffinityGroupVO.class); AffinityGroupVO ag3 = Mockito.mock(AffinityGroupVO.class); + Mockito.when(ag1.getId()).thenReturn(1L); + Mockito.when(ag2.getId()).thenReturn(2L); + Mockito.when(ag3.getId()).thenReturn(3L); Mockito.when(affinityGroupDao.findByUuid("ag1")).thenReturn(ag1); Mockito.when(affinityGroupDao.findByUuid("ag2")).thenReturn(ag2); Mockito.when(affinityGroupDao.findByUuid("ag3")).thenReturn(ag3); @@ -375,8 +396,8 @@ public class KubernetesServiceHelperImplTest { controlEntry.put(VmDetailConstants.AFFINITY_GROUP, "ag1,ag2,ag3"); affinityGroupNodeTypeMap.put("0", controlEntry); - Map result = kubernetesServiceHelper.getAffinityGroupNodeTypeMap(affinityGroupNodeTypeMap); + Map> result = kubernetesServiceHelper.getAffinityGroupNodeTypeMap(affinityGroupNodeTypeMap); Assert.assertEquals(1, result.size()); - Assert.assertEquals("ag1,ag2,ag3", result.get("CONTROL")); + Assert.assertEquals(Arrays.asList(1L, 2L, 3L), result.get("CONTROL")); } }