mirror of https://github.com/apache/cloudstack.git
Add node type to service offering mapping parameter on createKubernetesCluster API
This commit is contained in:
parent
35357dc8f9
commit
2397c22f4a
|
|
@ -21,6 +21,11 @@ import org.apache.cloudstack.acl.ControlledEntity;
|
|||
|
||||
public interface KubernetesClusterHelper extends Adapter {
|
||||
|
||||
enum KubernetesClusterNodeType {
|
||||
WORKER, MASTER, ETCD
|
||||
}
|
||||
|
||||
ControlledEntity findByUuid(String uuid);
|
||||
ControlledEntity findByVmId(long vmId);
|
||||
boolean isValidNodeType(String nodeType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ public interface VmDetailConstants {
|
|||
String DEPLOY_AS_IS_CONFIGURATION = "configurationId";
|
||||
String KEY_PAIR_NAMES = "keypairnames";
|
||||
String CKS_CONTROL_NODE_LOGIN_USER = "controlNodeLoginUser";
|
||||
String CKS_NODE_TYPE = "node";
|
||||
String OFFERING = "offering";
|
||||
|
||||
// VMware to KVM VM migrations specific
|
||||
String VMWARE_TO_KVM_PREFIX = "vmware-to-kvm";
|
||||
|
|
|
|||
|
|
@ -1036,6 +1036,7 @@ public class ApiConstants {
|
|||
public static final String AUTOSCALING_ENABLED = "autoscalingenabled";
|
||||
public static final String MIN_SIZE = "minsize";
|
||||
public static final String MAX_SIZE = "maxsize";
|
||||
public static final String NODE_TYPE_OFFERING_MAP = "nodetypeofferingmap";
|
||||
|
||||
public static final String BOOT_TYPE = "boottype";
|
||||
public static final String BOOT_MODE = "bootmode";
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.cloud.utils.component.AdapterBase;
|
|||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -49,6 +50,19 @@ public class KubernetesClusterHelperImpl extends AdapterBase implements Kubernet
|
|||
return kubernetesClusterDao.findById(clusterVmMapVO.getClusterId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidNodeType(String nodeType) {
|
||||
if (StringUtils.isBlank(nodeType)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
KubernetesClusterNodeType.valueOf(nodeType.toUpperCase());
|
||||
return true;
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return KubernetesClusterHelper.class.getSimpleName();
|
||||
|
|
|
|||
|
|
@ -17,10 +17,15 @@
|
|||
package org.apache.cloudstack.api.command.user.kubernetes.cluster;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.kubernetes.cluster.KubernetesClusterHelper;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
|
|
@ -40,6 +45,7 @@ import org.apache.cloudstack.api.response.ProjectResponse;
|
|||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -62,6 +68,8 @@ public class CreateKubernetesClusterCmd extends BaseAsyncCreateCmd {
|
|||
|
||||
@Inject
|
||||
public KubernetesClusterService kubernetesClusterService;
|
||||
@Inject
|
||||
protected KubernetesClusterHelper kubernetesClusterHelper;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
|
|
@ -87,6 +95,11 @@ public class CreateKubernetesClusterCmd extends BaseAsyncCreateCmd {
|
|||
description = "the ID of the service offering for the virtual machines in the cluster.")
|
||||
private Long serviceOfferingId;
|
||||
|
||||
@ACL(accessType = AccessType.UseEntry)
|
||||
@Parameter(name = ApiConstants.NODE_TYPE_OFFERING_MAP, type = CommandType.MAP,
|
||||
description = "(Optional) Node Type to Service Offering ID mapping. If provided, it overrides the serviceofferingid parameter")
|
||||
protected Map<String, Map<String, String>> nodeTypeOfferingMap;
|
||||
|
||||
@ACL(accessType = AccessType.UseEntry)
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the" +
|
||||
" virtual machine. Must be used with domainId.")
|
||||
|
|
@ -244,6 +257,28 @@ public class CreateKubernetesClusterCmd extends BaseAsyncCreateCmd {
|
|||
return clusterType;
|
||||
}
|
||||
|
||||
public Map<String, Long> getNodeTypeOfferingMap() {
|
||||
Map<String, Long> mapping = new HashMap<>();
|
||||
if (MapUtils.isNotEmpty(nodeTypeOfferingMap)) {
|
||||
for (Map<String, String> entry : nodeTypeOfferingMap.values()) {
|
||||
String nodeTypeStr = entry.get(VmDetailConstants.CKS_NODE_TYPE);
|
||||
String serviceOfferingUuid = entry.get(VmDetailConstants.OFFERING);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(String.format("Node Type: '%s' should use Service Offering ID: '%s'", nodeTypeStr, serviceOfferingUuid));
|
||||
}
|
||||
ServiceOffering serviceOffering = _entityMgr.findByUuid(ServiceOffering.class, serviceOfferingUuid);
|
||||
if (StringUtils.isAnyEmpty(nodeTypeStr, serviceOfferingUuid) ||
|
||||
!kubernetesClusterHelper.isValidNodeType(nodeTypeStr) ||
|
||||
serviceOffering == null) {
|
||||
throw new InvalidParameterValueException(String.format("Service Offering ID: %s for Node Type: %s is invalid", serviceOfferingUuid, nodeTypeStr));
|
||||
}
|
||||
KubernetesClusterHelper.KubernetesClusterNodeType nodeType = KubernetesClusterHelper.KubernetesClusterNodeType.valueOf(nodeTypeStr.toUpperCase());
|
||||
mapping.put(nodeType.name(), serviceOffering.getId());
|
||||
}
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.kubernetes.cluster;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class KubernetesClusterHelperImplTest {
|
||||
|
||||
private final KubernetesClusterHelperImpl helper = new KubernetesClusterHelperImpl();
|
||||
|
||||
@Test
|
||||
public void testIsValidNodeTypeEmptyNodeType() {
|
||||
Assert.assertFalse(helper.isValidNodeType(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidNodeTypeInvalidNodeType() {
|
||||
String nodeType = "invalidNodeType";
|
||||
Assert.assertFalse(helper.isValidNodeType(nodeType));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidNodeTypeValidNodeTypeLowercase() {
|
||||
String nodeType = KubernetesClusterHelper.KubernetesClusterNodeType.WORKER.name().toLowerCase();
|
||||
Assert.assertTrue(helper.isValidNodeType(nodeType));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.kubernetes.cluster;
|
||||
|
||||
import com.cloud.kubernetes.cluster.KubernetesClusterHelper;
|
||||
import com.cloud.kubernetes.cluster.KubernetesClusterHelperImpl;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.cloud.kubernetes.cluster.KubernetesClusterHelper.KubernetesClusterNodeType.MASTER;
|
||||
import static com.cloud.kubernetes.cluster.KubernetesClusterHelper.KubernetesClusterNodeType.WORKER;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CreateKubernetesClusterCmdTest {
|
||||
|
||||
@Mock
|
||||
EntityManager entityManager;
|
||||
KubernetesClusterHelper helper = new KubernetesClusterHelperImpl();
|
||||
|
||||
@Mock
|
||||
ServiceOffering workerServiceOffering;
|
||||
@Mock
|
||||
ServiceOffering masterServiceOffering;
|
||||
|
||||
private final CreateKubernetesClusterCmd cmd = new CreateKubernetesClusterCmd();
|
||||
|
||||
private static final String workerNodesOfferingId = UUID.randomUUID().toString();
|
||||
private static final String masterNodesOfferingId = UUID.randomUUID().toString();
|
||||
private static final Long workerOfferingId = 1L;
|
||||
private static final Long masterOfferingId = 2L;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
cmd._entityMgr = entityManager;
|
||||
cmd.kubernetesClusterHelper = helper;
|
||||
Mockito.when(entityManager.findByUuid(ServiceOffering.class, workerNodesOfferingId)).thenReturn(workerServiceOffering);
|
||||
Mockito.when(entityManager.findByUuid(ServiceOffering.class, masterNodesOfferingId)).thenReturn(masterServiceOffering);
|
||||
Mockito.when(workerServiceOffering.getId()).thenReturn(workerOfferingId);
|
||||
Mockito.when(masterServiceOffering.getId()).thenReturn(masterOfferingId);
|
||||
}
|
||||
|
||||
private Map<String, String> createMapEntry(KubernetesClusterHelper.KubernetesClusterNodeType nodeType,
|
||||
String nodeTypeOfferingUuid) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put(VmDetailConstants.CKS_NODE_TYPE, nodeType.name().toLowerCase());
|
||||
map.put(VmDetailConstants.OFFERING, nodeTypeOfferingUuid);
|
||||
return map;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodeOfferingMap() {
|
||||
cmd.nodeTypeOfferingMap = new HashMap<>();
|
||||
Map<String, String> firstMap = createMapEntry(WORKER, workerNodesOfferingId);
|
||||
Map<String, String> secondMap = createMapEntry(MASTER, masterNodesOfferingId);
|
||||
cmd.nodeTypeOfferingMap.put("map1", firstMap);
|
||||
cmd.nodeTypeOfferingMap.put("map2", secondMap);
|
||||
Map<String, Long> map = cmd.getNodeTypeOfferingMap();
|
||||
Assert.assertNotNull(map);
|
||||
Assert.assertEquals(2, map.size());
|
||||
Assert.assertTrue(map.containsKey(WORKER.name()) && map.containsKey(MASTER.name()));
|
||||
Assert.assertEquals(workerOfferingId, map.get(WORKER.name()));
|
||||
Assert.assertEquals(masterOfferingId, map.get(MASTER.name()));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue