cks: fix events (#9070)

Fixes #8043

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Abhishek Kumar 2024-06-14 12:22:39 +05:30 committed by GitHub
parent df5c546559
commit ce9b2c52f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 430 additions and 129 deletions

View File

@ -29,9 +29,9 @@ import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.ha.HAConfig;
import org.apache.cloudstack.quota.QuotaTariff;
import org.apache.cloudstack.storage.object.Bucket;
import org.apache.cloudstack.storage.object.ObjectStore;
import org.apache.cloudstack.quota.QuotaTariff;
import org.apache.cloudstack.usage.Usage;
import org.apache.cloudstack.vm.schedule.VMSchedule;
@ -1229,4 +1229,8 @@ public class EventTypes {
public static boolean isVpcEvent(String eventType) {
return EventTypes.EVENT_VPC_CREATE.equals(eventType) || EventTypes.EVENT_VPC_DELETE.equals(eventType);
}
public static void addEntityEventDetail(String event, Class<?> clazz) {
entityEventDetails.put(event, clazz);
}
}

View File

@ -21,7 +21,7 @@ import org.apache.cloudstack.acl.ControlledEntity;
import com.cloud.uservm.UserVm;
import com.cloud.utils.component.Adapter;
public interface KubernetesClusterHelper extends Adapter {
public interface KubernetesServiceHelper extends Adapter {
ControlledEntity findByUuid(String uuid);
void checkVmCanBeDestroyed(UserVm userVm);

View File

@ -19,6 +19,7 @@ package com.cloud.network;
import java.util.List;
import java.util.Map;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
@ -98,6 +99,10 @@ public interface NetworkService {
Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
Network createGuestNetwork(long networkOfferingId, String name, String displayText, Account owner,
PhysicalNetwork physicalNetwork, long zoneId, ControlledEntity.ACLType aclType) throws
InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
Pair<List<? extends Network>, Integer> searchForNetworks(ListNetworksCmd cmd);
boolean deleteNetwork(long networkId, boolean forced);

View File

@ -45,6 +45,7 @@ import com.cloud.dc.DataCenter;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ManagementServerException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
@ -110,6 +111,8 @@ public interface UserVmService {
UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, ExecutionException, ConcurrentOperationException, ResourceUnavailableException,
InsufficientCapacityException, ResourceAllocationException;
void startVirtualMachine(UserVm vm) throws OperationTimedoutException, ResourceUnavailableException, InsufficientCapacityException;
UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException;
UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;

View File

@ -17,7 +17,9 @@
package org.apache.cloudstack.api;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.cloudstack.region.PortableIp;
import org.apache.commons.collections.CollectionUtils;
@ -81,15 +83,22 @@ public enum ApiCommandResourceType {
ManagementServer(org.apache.cloudstack.management.ManagementServerHost.class),
ObjectStore(org.apache.cloudstack.storage.object.ObjectStore.class),
Bucket(org.apache.cloudstack.storage.object.Bucket.class),
QuotaTariff(org.apache.cloudstack.quota.QuotaTariff.class);
QuotaTariff(org.apache.cloudstack.quota.QuotaTariff.class),
KubernetesCluster(null),
KubernetesSupportedVersion(null);
private final Class<?> clazz;
static final Map<ApiCommandResourceType, Class<?>> additionalClassMappings = new HashMap<>();
private ApiCommandResourceType(Class<?> clazz) {
this.clazz = clazz;
}
public Class<?> getAssociatedClass() {
if (this.clazz == null && additionalClassMappings.containsKey(this)) {
return additionalClassMappings.get(this);
}
return this.clazz;
}
@ -119,4 +128,8 @@ public enum ApiCommandResourceType {
}
return null;
}
public static void setClassMapping(ApiCommandResourceType type, Class<?> clazz) {
additionalClassMappings.put(type, clazz);
}
}

View File

@ -339,7 +339,7 @@
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
</bean>
<bean id="kubernetesClusterHelperRegistry"
<bean id="kubernetesServiceHelperRegistry"
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
</bean>

View File

@ -25,8 +25,8 @@
>
<bean class="org.apache.cloudstack.spring.lifecycle.registry.RegistryLifecycle">
<property name="registry" ref="kubernetesClusterHelperRegistry" />
<property name="typeClass" value="com.cloud.kubernetes.cluster.KubernetesClusterHelper" />
<property name="registry" ref="kubernetesServiceHelperRegistry" />
<property name="typeClass" value="com.cloud.kubernetes.cluster.KubernetesServiceHelper" />
</bean>
</beans>

View File

@ -40,12 +40,11 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.uservm.UserVm;
import com.cloud.vm.UserVmService;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.api.BaseCmd;
@ -92,6 +91,7 @@ import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.Domain;
import com.cloud.event.ActionEvent;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
@ -159,6 +159,7 @@ import com.cloud.user.UserAccount;
import com.cloud.user.UserVO;
import com.cloud.user.dao.SSHKeyPairDao;
import com.cloud.user.dao.UserDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.ComponentContext;
@ -176,6 +177,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.utils.fsm.StateMachine2;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.UserVmService;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VMInstanceDao;
@ -863,13 +865,15 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
LOGGER.info(String.format("Creating network for account ID: %s from the network offering ID: %s as part of Kubernetes cluster: %s deployment process", owner.getUuid(), networkOffering.getUuid(), clusterName));
}
CallContext networkContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Network);
try {
network = networkMgr.createGuestNetwork(networkOffering.getId(), clusterName + "-network", owner.getAccountName() + "-network",
null, null, null, false, null, owner, null, physicalNetwork, zone.getId(),
ControlledEntity.ACLType.Account, null, null, null, null, true, null,
null, null, null, null, null, null, null, null, null);
network = networkService.createGuestNetwork(networkOffering.getId(), clusterName + "-network",
owner.getAccountName() + "-network", owner, physicalNetwork, zone.getId(),
ControlledEntity.ACLType.Account);
} catch (ConcurrentOperationException | InsufficientCapacityException | ResourceAllocationException e) {
logAndThrow(Level.ERROR, String.format("Unable to create network for the Kubernetes cluster: %s", clusterName));
} finally {
CallContext.unregister();
}
}
return network;
@ -1138,6 +1142,8 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
}
@Override
@ActionEvent(eventType = KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_CREATE,
eventDescription = "creating Kubernetes cluster", create = true)
public KubernetesCluster createUnmanagedKubernetesCluster(CreateKubernetesClusterCmd cmd) throws CloudRuntimeException {
if (!KubernetesServiceEnabled.value()) {
logAndThrow(Level.ERROR, "Kubernetes Service plugin is disabled");
@ -1184,10 +1190,13 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Kubernetes cluster with name: %s and ID: %s has been created", cluster.getName(), cluster.getUuid()));
}
CallContext.current().putContextParameter(KubernetesCluster.class, cluster.getUuid());
return cluster;
}
@Override
@ActionEvent(eventType = KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_CREATE,
eventDescription = "creating Kubernetes cluster", create = true)
public KubernetesCluster createManagedKubernetesCluster(CreateKubernetesClusterCmd cmd) throws CloudRuntimeException {
if (!KubernetesServiceEnabled.value()) {
logAndThrow(Level.ERROR, "Kubernetes Service plugin is disabled");
@ -1244,6 +1253,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Kubernetes cluster name: %s and ID: %s has been created", cluster.getName(), cluster.getUuid()));
}
CallContext.current().putContextParameter(KubernetesCluster.class, cluster.getUuid());
return cluster;
}
@ -1270,29 +1280,64 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
return securityGroup;
}
@Override
@ActionEvent(eventType = KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_CREATE,
eventDescription = "creating Kubernetes cluster", async = true)
public void startKubernetesCluster(CreateKubernetesClusterCmd cmd) throws CloudRuntimeException {
final Long id = cmd.getEntityId();
if (KubernetesCluster.ClusterType.valueOf(cmd.getClusterType()) != KubernetesCluster.ClusterType.CloudManaged) {
return;
}
final KubernetesClusterVO kubernetesCluster = kubernetesClusterDao.findById(id);
if (kubernetesCluster == null) {
throw new InvalidParameterValueException("Failed to find Kubernetes cluster with given ID");
}
if (!startKubernetesCluster(kubernetesCluster, true)) {
throw new CloudRuntimeException(String.format("Failed to start created Kubernetes cluster: %s",
kubernetesCluster.getName()));
}
}
@Override
@ActionEvent(eventType = KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_START,
eventDescription = "starting Kubernetes cluster", async = true)
public void startKubernetesCluster(StartKubernetesClusterCmd cmd) throws CloudRuntimeException {
final Long id = cmd.getId();
if (id == null || id < 1L) {
throw new InvalidParameterValueException("Invalid Kubernetes cluster ID provided");
}
final KubernetesClusterVO kubernetesCluster = kubernetesClusterDao.findById(id);
if (kubernetesCluster == null) {
throw new InvalidParameterValueException("Given Kubernetes cluster was not found");
}
if (!isCommandSupported(kubernetesCluster, cmd.getActualCommandName())) {
throw new InvalidParameterValueException(String.format("Start kubernetes cluster is not supported for " +
"an externally managed cluster (%s)", kubernetesCluster.getName()));
}
if (!startKubernetesCluster(kubernetesCluster, false)) {
throw new CloudRuntimeException(String.format("Failed to start Kubernetes cluster: %s",
kubernetesCluster.getName()));
}
}
/**
* Start operation can be performed at two different life stages of Kubernetes cluster. First when a freshly created cluster
* in which case there are no resources provisioned for the Kubernetes cluster. So during start all the resources
* are provisioned from scratch. Second kind of start, happens on Stopped Kubernetes cluster, in which all resources
* are provisioned (like volumes, nics, networks etc). It just that VM's are not in running state. So just
* start the VM's (which can possibly implicitly start the network also).
* @param kubernetesClusterId
* @param kubernetesCluster
* @param onCreate
* @return
* @throws CloudRuntimeException
*/
@Override
public boolean startKubernetesCluster(long kubernetesClusterId, boolean onCreate) throws CloudRuntimeException {
public boolean startKubernetesCluster(KubernetesClusterVO kubernetesCluster, boolean onCreate) throws CloudRuntimeException {
if (!KubernetesServiceEnabled.value()) {
logAndThrow(Level.ERROR, "Kubernetes Service plugin is disabled");
}
final KubernetesClusterVO kubernetesCluster = kubernetesClusterDao.findById(kubernetesClusterId);
if (kubernetesCluster == null) {
throw new InvalidParameterValueException("Failed to find Kubernetes cluster with given ID");
}
if (kubernetesCluster.getRemoved() != null) {
throw new InvalidParameterValueException(String.format("Kubernetes cluster : %s is already deleted", kubernetesCluster.getName()));
throw new InvalidParameterValueException(String.format("Kubernetes cluster : %s is already deleted",
kubernetesCluster.getName()));
}
accountManager.checkAccess(CallContext.current().getCallingAccount(), SecurityChecker.AccessType.OperateEntry, false, kubernetesCluster);
if (kubernetesCluster.getState().equals(KubernetesCluster.State.Running)) {
@ -1350,6 +1395,8 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
}
@Override
@ActionEvent(eventType = KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_STOP,
eventDescription = "stopping Kubernetes cluster", async = true)
public boolean stopKubernetesCluster(StopKubernetesClusterCmd cmd) throws CloudRuntimeException {
long kubernetesClusterId = cmd.getId();
if (!KubernetesServiceEnabled.value()) {
@ -1384,6 +1431,8 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
}
@Override
@ActionEvent(eventType = KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_DELETE,
eventDescription = "deleting Kubernetes cluster", async = true)
public boolean deleteKubernetesCluster(DeleteKubernetesClusterCmd cmd) throws CloudRuntimeException {
if (!KubernetesServiceEnabled.value()) {
logAndThrow(Level.ERROR, "Kubernetes Service plugin is disabled");
@ -1526,6 +1575,8 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
}
@Override
@ActionEvent(eventType = KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_SCALE,
eventDescription = "scaling Kubernetes cluster", async = true)
public boolean scaleKubernetesCluster(ScaleKubernetesClusterCmd cmd) throws CloudRuntimeException {
if (!KubernetesServiceEnabled.value()) {
logAndThrow(Level.ERROR, "Kubernetes Service plugin is disabled");
@ -1533,22 +1584,29 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
validateKubernetesClusterScaleParameters(cmd);
KubernetesClusterVO kubernetesCluster = kubernetesClusterDao.findById(cmd.getId());
final Long clusterSize = cmd.getClusterSize();
if (clusterSize != null) {
CallContext.current().setEventDetails(String.format("Kubernetes cluster ID: %s scaling from size: %d to %d",
kubernetesCluster.getUuid(), kubernetesCluster.getNodeCount(), clusterSize));
}
String[] keys = getServiceUserKeys(kubernetesCluster);
KubernetesClusterScaleWorker scaleWorker =
new KubernetesClusterScaleWorker(kubernetesClusterDao.findById(cmd.getId()),
serviceOfferingDao.findById(cmd.getServiceOfferingId()),
cmd.getClusterSize(),
cmd.getNodeIds(),
cmd.isAutoscalingEnabled(),
cmd.getMinSize(),
cmd.getMaxSize(),
this);
serviceOfferingDao.findById(cmd.getServiceOfferingId()),
clusterSize,
cmd.getNodeIds(),
cmd.isAutoscalingEnabled(),
cmd.getMinSize(),
cmd.getMaxSize(),
this);
scaleWorker.setKeys(keys);
scaleWorker = ComponentContext.inject(scaleWorker);
return scaleWorker.scaleCluster();
}
@Override
@ActionEvent(eventType = KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_UPGRADE,
eventDescription = "upgrading Kubernetes cluster", async = true)
public boolean upgradeKubernetesCluster(UpgradeKubernetesClusterCmd cmd) throws CloudRuntimeException {
if (!KubernetesServiceEnabled.value()) {
logAndThrow(Level.ERROR, "Kubernetes Service plugin is disabled");

View File

@ -23,6 +23,7 @@ import org.apache.cloudstack.api.command.user.kubernetes.cluster.GetKubernetesCl
import org.apache.cloudstack.api.command.user.kubernetes.cluster.ListKubernetesClustersCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.RemoveVirtualMachinesFromKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.ScaleKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.StartKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.StopKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.UpgradeKubernetesClusterCmd;
import org.apache.cloudstack.api.response.KubernetesClusterConfigResponse;
@ -98,7 +99,9 @@ public interface KubernetesClusterService extends PluggableService, Configurable
KubernetesCluster createManagedKubernetesCluster(CreateKubernetesClusterCmd cmd) throws CloudRuntimeException;
boolean startKubernetesCluster(long kubernetesClusterId, boolean onCreate) throws CloudRuntimeException;
void startKubernetesCluster(CreateKubernetesClusterCmd cmd) throws CloudRuntimeException;
void startKubernetesCluster(StartKubernetesClusterCmd cmd) throws CloudRuntimeException;
boolean stopKubernetesCluster(StopKubernetesClusterCmd cmd) throws CloudRuntimeException;

View File

@ -16,30 +16,56 @@
// under the License.
package com.cloud.kubernetes.cluster;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import javax.inject.Inject;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.event.EventTypes;
import com.cloud.kubernetes.cluster.dao.KubernetesClusterDao;
import com.cloud.kubernetes.cluster.dao.KubernetesClusterVmMapDao;
import com.cloud.kubernetes.version.KubernetesSupportedVersion;
import com.cloud.kubernetes.version.KubernetesVersionEventTypes;
import com.cloud.uservm.UserVm;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmManager;
@Component
public class KubernetesClusterHelperImpl extends AdapterBase implements KubernetesClusterHelper, Configurable {
private static final Logger logger = Logger.getLogger(KubernetesClusterHelperImpl.class);
public class KubernetesServiceHelperImpl extends AdapterBase implements KubernetesServiceHelper, Configurable {
private static final Logger logger = Logger.getLogger(KubernetesServiceHelperImpl.class);
@Inject
private KubernetesClusterDao kubernetesClusterDao;
@Inject
private KubernetesClusterVmMapDao kubernetesClusterVmMapDao;
protected void setEventTypeEntityDetails(Class<?> eventTypeDefinedClass, Class<?> entityClass) {
Field[] declaredFields = eventTypeDefinedClass.getDeclaredFields();
for (Field field : declaredFields) {
int modifiers = field.getModifiers();
if (!Modifier.isPublic(modifiers) || !Modifier.isStatic(modifiers)) {
continue;
}
try {
Object value = field.get(null);
if (ObjectUtils.allNotNull(value, value.toString())) {
EventTypes.addEntityEventDetail(value.toString(), entityClass);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
@Override
public ControlledEntity findByUuid(String uuid) {
return kubernetesClusterDao.findByUuid(uuid);
@ -67,11 +93,21 @@ public class KubernetesClusterHelperImpl extends AdapterBase implements Kubernet
@Override
public String getConfigComponentName() {
return KubernetesClusterHelper.class.getSimpleName();
return KubernetesServiceHelper.class.getSimpleName();
}
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[]{};
}
@Override
public boolean start() {
setEventTypeEntityDetails(KubernetesClusterEventTypes.class, KubernetesCluster.class);
setEventTypeEntityDetails(KubernetesVersionEventTypes.class, KubernetesSupportedVersion.class);
ApiCommandResourceType.setClassMapping(ApiCommandResourceType.KubernetesCluster, KubernetesCluster.class);
ApiCommandResourceType.setClassMapping(ApiCommandResourceType.KubernetesSupportedVersion,
KubernetesSupportedVersion.class);
return super.start();
}
}

View File

@ -31,9 +31,11 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.ca.CAManager;
import org.apache.cloudstack.config.ApiServiceConfiguration;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.commons.collections.CollectionUtils;
@ -91,7 +93,7 @@ import com.cloud.utils.ssh.SshHelper;
import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.UserVmService;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
@ -149,8 +151,6 @@ public class KubernetesClusterActionWorker {
@Inject
protected VlanDao vlanDao;
@Inject
protected VirtualMachineManager itMgr;
@Inject
protected LaunchPermissionDao launchPermissionDao;
@Inject
public ProjectService projectService;
@ -474,6 +474,8 @@ public class KubernetesClusterActionWorker {
}
for (UserVm vm : clusterVMs) {
CallContext vmContext = CallContext.register(CallContext.current(), ApiCommandResourceType.VirtualMachine);
vmContext.putContextParameter(VirtualMachine.class, vm.getUuid());
try {
templateService.attachIso(iso.getId(), vm.getId(), true);
if (LOGGER.isInfoEnabled()) {
@ -481,6 +483,8 @@ public class KubernetesClusterActionWorker {
}
} catch (CloudRuntimeException ex) {
logTransitStateAndThrow(Level.ERROR, String.format("Failed to attach binaries ISO for VM : %s in the Kubernetes cluster name: %s", vm.getDisplayName(), kubernetesCluster.getName()), kubernetesCluster.getId(), failedEvent, ex);
} finally {
CallContext.unregister();
}
}
}
@ -492,10 +496,14 @@ public class KubernetesClusterActionWorker {
protected void detachIsoKubernetesVMs(List<UserVm> clusterVMs) {
for (UserVm vm : clusterVMs) {
boolean result = false;
CallContext vmContext = CallContext.register(CallContext.current(), ApiCommandResourceType.VirtualMachine);
vmContext.putContextParameter(VirtualMachine.class, vm.getUuid());
try {
result = templateService.detachIso(vm.getId(), true);
} catch (CloudRuntimeException ex) {
LOGGER.warn(String.format("Failed to detach binaries ISO from VM : %s in the Kubernetes cluster : %s ", vm.getDisplayName(), kubernetesCluster.getName()), ex);
} finally {
CallContext.unregister();
}
if (result) {
if (LOGGER.isInfoEnabled()) {

View File

@ -25,6 +25,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.collections.CollectionUtils;
@ -93,6 +94,9 @@ public class KubernetesClusterDestroyWorker extends KubernetesClusterResourceMod
if (userVM == null || userVM.isRemoved()) {
continue;
}
CallContext vmContext = CallContext.register(CallContext.current(),
ApiCommandResourceType.VirtualMachine);
vmContext.setEventResourceId(vmID);
try {
UserVm vm = userVmService.destroyVm(vmID, true);
if (!userVmManager.expunge(userVM)) {
@ -106,6 +110,8 @@ public class KubernetesClusterDestroyWorker extends KubernetesClusterResourceMod
} catch (ResourceUnavailableException | ConcurrentOperationException e) {
LOGGER.warn(String.format("Failed to destroy VM : %s part of the Kubernetes cluster : %s cleanup. Moving on with destroying remaining resources provisioned for the Kubernetes cluster", userVM.getDisplayName(), kubernetesCluster.getName()), e);
return false;
} finally {
CallContext.unregister();
}
}
}

View File

@ -31,12 +31,13 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.command.user.firewall.CreateFirewallRuleCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@ -321,18 +322,19 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
}
protected void startKubernetesVM(final UserVm vm) throws ManagementServerException {
CallContext vmContext = null;
if (!ApiCommandResourceType.VirtualMachine.equals(CallContext.current().getEventResourceType())); {
vmContext = CallContext.register(CallContext.current(), ApiCommandResourceType.VirtualMachine);
vmContext.setEventResourceId(vm.getId());
}
try {
StartVMCmd startVm = new StartVMCmd();
startVm = ComponentContext.inject(startVm);
Field f = startVm.getClass().getDeclaredField("id");
f.setAccessible(true);
f.set(startVm, vm.getId());
itMgr.advanceStart(vm.getUuid(), null, null);
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Started VM : %s in the Kubernetes cluster : %s", vm.getDisplayName(), kubernetesCluster.getName()));
}
} catch (IllegalAccessException | NoSuchFieldException | OperationTimedoutException | ResourceUnavailableException | InsufficientCapacityException ex) {
userVmManager.startVirtualMachine(vm);
} catch (OperationTimedoutException | ResourceUnavailableException | InsufficientCapacityException ex) {
throw new ManagementServerException(String.format("Failed to start VM in the Kubernetes cluster : %s", kubernetesCluster.getName()), ex);
} finally {
if (vmContext != null) {
CallContext.unregister();
}
}
UserVm startVm = userVmDao.findById(vm.getId());
@ -345,19 +347,25 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
ResourceUnavailableException, InsufficientCapacityException {
List<UserVm> nodes = new ArrayList<>();
for (int i = offset + 1; i <= nodeCount; i++) {
UserVm vm = createKubernetesNode(publicIpAddress);
addKubernetesClusterVm(kubernetesCluster.getId(), vm.getId(), false);
if (kubernetesCluster.getNodeRootDiskSize() > 0) {
resizeNodeVolume(vm);
}
startKubernetesVM(vm);
vm = userVmDao.findById(vm.getId());
if (vm == null) {
throw new ManagementServerException(String.format("Failed to provision worker VM for Kubernetes cluster : %s" , kubernetesCluster.getName()));
}
nodes.add(vm);
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Provisioned node VM : %s in to the Kubernetes cluster : %s", vm.getDisplayName(), kubernetesCluster.getName()));
CallContext vmContext = CallContext.register(CallContext.current(), ApiCommandResourceType.VirtualMachine);
try {
UserVm vm = createKubernetesNode(publicIpAddress);
vmContext.setEventResourceId(vm.getId());
addKubernetesClusterVm(kubernetesCluster.getId(), vm.getId(), false);
if (kubernetesCluster.getNodeRootDiskSize() > 0) {
resizeNodeVolume(vm);
}
startKubernetesVM(vm);
vm = userVmDao.findById(vm.getId());
if (vm == null) {
throw new ManagementServerException(String.format("Failed to provision worker VM for Kubernetes cluster : %s", kubernetesCluster.getName()));
}
nodes.add(vm);
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Provisioned node VM : %s in to the Kubernetes cluster : %s", vm.getDisplayName(), kubernetesCluster.getName()));
}
} finally {
CallContext.unregister();
}
}
return nodes;
@ -628,6 +636,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
protected void createFirewallRules(IpAddress publicIp, List<Long> clusterVMIds, boolean apiRule) throws ManagementServerException {
// Firewall rule for SSH access on each node VM
CallContext.register(CallContext.current(), null);
try {
int endPort = CLUSTER_NODES_DEFAULT_START_SSH_PORT + clusterVMIds.size() - 1;
provisionFirewallRules(publicIp, owner, CLUSTER_NODES_DEFAULT_START_SSH_PORT, endPort);
@ -636,11 +645,14 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
}
} catch (NoSuchFieldException | IllegalAccessException | ResourceUnavailableException | NetworkRuleConflictException e) {
throw new ManagementServerException(String.format("Failed to provision firewall rules for SSH access for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
} finally {
CallContext.unregister();
}
if (!apiRule) {
return;
}
// Firewall rule for API access for control node VMs
CallContext.register(CallContext.current(), null);
try {
provisionFirewallRules(publicIp, owner, CLUSTER_API_PORT, CLUSTER_API_PORT);
if (LOGGER.isInfoEnabled()) {
@ -649,6 +661,8 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
}
} catch (NoSuchFieldException | IllegalAccessException | ResourceUnavailableException | NetworkRuleConflictException e) {
throw new ManagementServerException(String.format("Failed to provision firewall rules for API access for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
} finally {
CallContext.unregister();
}
}
@ -689,6 +703,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
return;
}
// ACL rule for API access for control node VMs
CallContext.register(CallContext.current(), null);
try {
provisionVpcTierAllowPortACLRule(network, CLUSTER_API_PORT, CLUSTER_API_PORT);
if (LOGGER.isInfoEnabled()) {
@ -697,7 +712,10 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
}
} catch (NoSuchFieldException | IllegalAccessException | ResourceUnavailableException | InvalidParameterValueException | PermissionDeniedException e) {
throw new ManagementServerException(String.format("Failed to provision firewall rules for API access for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
} finally {
CallContext.unregister();
}
CallContext.register(CallContext.current(), null);
try {
provisionVpcTierAllowPortACLRule(network, DEFAULT_SSH_PORT, DEFAULT_SSH_PORT);
if (LOGGER.isInfoEnabled()) {
@ -706,6 +724,8 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
}
} catch (NoSuchFieldException | IllegalAccessException | ResourceUnavailableException | InvalidParameterValueException | PermissionDeniedException e) {
throw new ManagementServerException(String.format("Failed to provision firewall rules for API access for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
} finally {
CallContext.unregister();
}
}

View File

@ -26,7 +26,9 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Level;
@ -318,6 +320,9 @@ public class KubernetesClusterScaleWorker extends KubernetesClusterResourceModif
if (!removeKubernetesClusterNode(publicIpAddress, sshPort, userVM, 3, 30000)) {
logTransitStateAndThrow(Level.ERROR, String.format("Scaling failed for Kubernetes cluster : %s, failed to remove Kubernetes node: %s running on VM : %s", kubernetesCluster.getName(), userVM.getHostName(), userVM.getDisplayName()), kubernetesCluster.getId(), KubernetesCluster.Event.OperationFailed);
}
CallContext vmContext = CallContext.register(CallContext.current(),
ApiCommandResourceType.VirtualMachine);
vmContext.setEventResourceId(userVM.getId());
try {
UserVm vm = userVmService.destroyVm(userVM.getId(), true);
if (!userVmManager.expunge(userVM)) {
@ -327,6 +332,8 @@ public class KubernetesClusterScaleWorker extends KubernetesClusterResourceModif
} catch (ResourceUnavailableException e) {
logTransitStateAndThrow(Level.ERROR, String.format("Scaling Kubernetes cluster %s failed, unable to remove VM ID: %s",
kubernetesCluster.getName() , userVM.getDisplayName()), kubernetesCluster.getId(), KubernetesCluster.Event.OperationFailed, e);
} finally {
CallContext.unregister();
}
kubernetesClusterVmMapDao.expunge(vmMapVO.getId());
if (System.currentTimeMillis() > scaleTimeoutTime) {
@ -438,10 +445,10 @@ public class KubernetesClusterScaleWorker extends KubernetesClusterResourceModif
if (existingServiceOffering == null) {
logAndThrow(Level.ERROR, String.format("Scaling Kubernetes cluster : %s failed, service offering for the Kubernetes cluster not found!", kubernetesCluster.getName()));
}
final boolean autscalingChanged = isAutoscalingChanged();
final boolean autoscalingChanged = isAutoscalingChanged();
final boolean serviceOfferingScalingNeeded = serviceOffering != null && serviceOffering.getId() != existingServiceOffering.getId();
if (autscalingChanged) {
if (autoscalingChanged) {
boolean autoScaled = autoscaleCluster(this.isAutoscalingEnabled, minSize, maxSize);
if (autoScaled && serviceOfferingScalingNeeded) {
scaleKubernetesClusterOffering();

View File

@ -19,6 +19,8 @@ package com.cloud.kubernetes.cluster.actionworkers;
import java.util.List;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Level;
import com.cloud.exception.ConcurrentOperationException;
@ -44,11 +46,15 @@ public class KubernetesClusterStopWorker extends KubernetesClusterActionWorker {
if (vm == null) {
logTransitStateAndThrow(Level.ERROR, String.format("Failed to find all VMs in Kubernetes cluster : %s", kubernetesCluster.getName()), kubernetesCluster.getId(), KubernetesCluster.Event.OperationFailed);
}
CallContext vmContext = CallContext.register(CallContext.current(), ApiCommandResourceType.VirtualMachine);
vmContext.setEventResourceId(vm.getId());
try {
userVmService.stopVirtualMachine(vm.getId(), false);
} catch (ConcurrentOperationException ex) {
LOGGER.warn(String.format("Failed to stop VM : %s in Kubernetes cluster : %s",
vm.getDisplayName(), kubernetesCluster.getName()), ex);
} finally {
CallContext.unregister();
}
}
for (final UserVm userVm : clusterVMs) {

View File

@ -22,6 +22,7 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.admin.kubernetes.version.AddKubernetesSupportedVersionCmd;
import org.apache.cloudstack.api.command.admin.kubernetes.version.DeleteKubernetesSupportedVersionCmd;
@ -31,6 +32,7 @@ import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.kubernetes.version.ListKubernetesSupportedVersionsCmd;
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@ -161,6 +163,7 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
private VirtualMachineTemplate registerKubernetesVersionIso(final Long zoneId, final String versionName, final String isoUrl, final String isoChecksum, final boolean directDownload) throws IllegalAccessException, NoSuchFieldException,
IllegalArgumentException, ResourceAllocationException {
CallContext.register(CallContext.current(), ApiCommandResourceType.Iso);
String isoName = String.format("%s-Kubernetes-Binaries-ISO", versionName);
RegisterIsoCmd registerIsoCmd = new RegisterIsoCmd();
registerIsoCmd = ComponentContext.inject(registerIsoCmd);
@ -178,15 +181,25 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
registerIsoCmd.setDirectDownload(directDownload);
registerIsoCmd.setAccountName(accountManager.getSystemAccount().getAccountName());
registerIsoCmd.setDomainId(accountManager.getSystemAccount().getDomainId());
return templateService.registerIso(registerIsoCmd);
try {
return templateService.registerIso(registerIsoCmd);
} finally {
CallContext.unregister();
}
}
private void deleteKubernetesVersionIso(long templateId) throws IllegalAccessException, NoSuchFieldException,
IllegalArgumentException {
CallContext isoContext = CallContext.register(CallContext.current(), ApiCommandResourceType.Iso);
isoContext.setEventResourceId(templateId);
DeleteIsoCmd deleteIsoCmd = new DeleteIsoCmd();
deleteIsoCmd = ComponentContext.inject(deleteIsoCmd);
deleteIsoCmd.setId(templateId);
templateService.deleteIso(deleteIsoCmd);
try {
templateService.deleteIso(deleteIsoCmd);
} finally {
CallContext.unregister();
}
}
public static int compareSemanticVersions(String v1, String v2) throws IllegalArgumentException {
@ -291,7 +304,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
}
@Override
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD, eventDescription = "Adding Kubernetes supported version")
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_ADD,
eventDescription = "Adding Kubernetes supported version")
public KubernetesSupportedVersionResponse addKubernetesSupportedVersion(final AddKubernetesSupportedVersionCmd cmd) {
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
@ -343,12 +357,14 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
KubernetesSupportedVersionVO supportedVersionVO = new KubernetesSupportedVersionVO(name, semanticVersion, template.getId(), zoneId, minimumCpu, minimumRamSize);
supportedVersionVO = kubernetesSupportedVersionDao.persist(supportedVersionVO);
CallContext.current().putContextParameter(KubernetesSupportedVersion.class, supportedVersionVO.getUuid());
return createKubernetesSupportedVersionResponse(supportedVersionVO);
}
@Override
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_DELETE, eventDescription = "Deleting Kubernetes supported version", async = true)
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_DELETE,
eventDescription = "deleting Kubernetes supported version", async = true)
public boolean deleteKubernetesSupportedVersion(final DeleteKubernetesSupportedVersionCmd cmd) {
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");
@ -379,7 +395,8 @@ public class KubernetesVersionManagerImpl extends ManagerBase implements Kuberne
}
@Override
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_UPDATE, eventDescription = "Updating Kubernetes supported version")
@ActionEvent(eventType = KubernetesVersionEventTypes.EVENT_KUBERNETES_VERSION_UPDATE,
eventDescription = "Updating Kubernetes supported version")
public KubernetesSupportedVersionResponse updateKubernetesSupportedVersion(final UpdateKubernetesSupportedVersionCmd cmd) {
if (!KubernetesClusterService.KubernetesServiceEnabled.value()) {
throw new CloudRuntimeException("Kubernetes Service plugin is disabled");

View File

@ -21,6 +21,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
@ -136,6 +137,11 @@ public class AddKubernetesSupportedVersionCmd extends BaseCmd implements AdminCm
return CallContext.current().getCallingAccountId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesSupportedVersion;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -21,6 +21,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -87,6 +88,11 @@ public class DeleteKubernetesSupportedVersionCmd extends BaseAsyncCmd implements
return description;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesSupportedVersion;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -21,6 +21,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
@ -29,6 +30,7 @@ import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.admin.AdminCmd;
import org.apache.cloudstack.api.response.KubernetesSupportedVersionResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import com.cloud.exception.ConcurrentOperationException;
@ -75,7 +77,17 @@ public class UpdateKubernetesSupportedVersionCmd extends BaseCmd implements Admi
@Override
public long getEntityOwnerId() {
return 0;
return CallContext.current().getCallingAccountId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesSupportedVersion;
}
@Override
public Long getApiResourceId() {
return getId();
}
/////////////////////////////////////////////////////

View File

@ -274,26 +274,23 @@ public class CreateKubernetesClusterCmd extends BaseAsyncCreateCmd {
@Override
public String getCreateEventDescription() {
return "creating Kubernetes cluster";
return "Creating Kubernetes cluster";
}
@Override
public String getEventDescription() {
return "Creating Kubernetes cluster. Cluster Id: " + getEntityId();
return "Creating Kubernetes cluster Id: " + getEntityId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.VirtualMachine;
return ApiCommandResourceType.KubernetesCluster;
}
@Override
public void execute() {
try {
if (KubernetesCluster.ClusterType.valueOf(getClusterType()) == KubernetesCluster.ClusterType.CloudManaged
&& !kubernetesClusterService.startKubernetesCluster(getEntityId(), true)) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start Kubernetes cluster");
}
kubernetesClusterService.startKubernetesCluster(this);
KubernetesClusterResponse response = kubernetesClusterService.createKubernetesClusterResponse(getEntityId());
response.setResponseName(getCommandName());
setResponseObject(response);

View File

@ -20,6 +20,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -114,6 +115,16 @@ public class DeleteKubernetesClusterCmd extends BaseAsyncCmd {
return KubernetesClusterEventTypes.EVENT_KUBERNETES_CLUSTER_DELETE;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesCluster;
}
@Override
public Long getApiResourceId() {
return getId();
}
@Override
public String getEventDescription() {
String description = "Deleting Kubernetes cluster";

View File

@ -20,6 +20,7 @@ import com.cloud.kubernetes.cluster.KubernetesClusterService;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
@ -85,6 +86,11 @@ public class RemoveVirtualMachinesFromKubernetesClusterCmd extends BaseListCmd {
return CallContext.current().getCallingAccount().getId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesCluster;
}
@Override
public void execute() throws ServerApiException {
try {

View File

@ -24,6 +24,7 @@ import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -146,6 +147,11 @@ public class ScaleKubernetesClusterCmd extends BaseAsyncCmd {
return CallContext.current().getCallingAccount().getId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesCluster;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -20,6 +20,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -87,33 +88,20 @@ public class StartKubernetesClusterCmd extends BaseAsyncCmd {
return CallContext.current().getCallingAccount().getId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesCluster;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
public KubernetesCluster validateRequest() {
if (getId() == null || getId() < 1L) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid Kubernetes cluster ID provided");
}
final KubernetesCluster kubernetesCluster = kubernetesClusterService.findById(getId());
if (kubernetesCluster == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Given Kubernetes cluster was not found");
}
if (!kubernetesClusterService.isCommandSupported(kubernetesCluster, getActualCommandName())) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
String.format("Start kubernetes cluster is not supported for an externally managed cluster (%s)", kubernetesCluster.getName()));
}
return kubernetesCluster;
}
@Override
public void execute() throws ServerApiException, ConcurrentOperationException {
final KubernetesCluster kubernetesCluster = validateRequest();
try {
if (!kubernetesClusterService.startKubernetesCluster(kubernetesCluster.getId(), false)) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to start Kubernetes cluster ID: %d", getId()));
}
final KubernetesClusterResponse response = kubernetesClusterService.createKubernetesClusterResponse(kubernetesCluster.getId());
kubernetesClusterService.startKubernetesCluster(this);
final KubernetesClusterResponse response = kubernetesClusterService.createKubernetesClusterResponse(getId());
response.setResponseName(getCommandName());
setResponseObject(response);
} catch (CloudRuntimeException ex) {

View File

@ -20,6 +20,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -88,6 +89,11 @@ public class StopKubernetesClusterCmd extends BaseAsyncCmd {
return CallContext.current().getCallingAccount().getId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesCluster;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -21,6 +21,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
@ -98,6 +99,11 @@ public class UpgradeKubernetesClusterCmd extends BaseAsyncCmd {
return CallContext.current().getCallingAccount().getId();
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.KubernetesCluster;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -34,8 +34,8 @@
<bean id="kubernetesClusterVmMapDaoImpl" class="com.cloud.kubernetes.cluster.dao.KubernetesClusterVmMapDaoImpl" />
<bean id="kubernetesClusterManagerImpl" class="com.cloud.kubernetes.cluster.KubernetesClusterManagerImpl" />
<bean id="kubernetesClusterHelper" class="com.cloud.kubernetes.cluster.KubernetesClusterHelperImpl" >
<property name="name" value="KubernetesClusterHelper" />
<bean id="kubernetesServiceHelper" class="com.cloud.kubernetes.cluster.KubernetesServiceHelperImpl" >
<property name="name" value="KubernetesServiceHelper" />
</bean>
</beans>

View File

@ -31,20 +31,20 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmManager;
@RunWith(MockitoJUnitRunner.class)
public class KubernetesClusterHelperImplTest {
public class KubernetesServiceHelperImplTest {
@Mock
KubernetesClusterVmMapDao kubernetesClusterVmMapDao;
@Mock
KubernetesClusterDao kubernetesClusterDao;
@InjectMocks
KubernetesClusterHelperImpl kubernetesClusterHelper = new KubernetesClusterHelperImpl();
KubernetesServiceHelperImpl kubernetesServiceHelper = new KubernetesServiceHelperImpl();
@Test
public void testCheckVmCanBeDestroyedNotCKSNode() {
UserVm vm = Mockito.mock(UserVm.class);
Mockito.when(vm.getUserVmType()).thenReturn("");
kubernetesClusterHelper.checkVmCanBeDestroyed(vm);
kubernetesServiceHelper.checkVmCanBeDestroyed(vm);
Mockito.verify(kubernetesClusterVmMapDao, Mockito.never()).findByVmId(Mockito.anyLong());
}
@ -54,7 +54,7 @@ public class KubernetesClusterHelperImplTest {
Mockito.when(vm.getId()).thenReturn(1L);
Mockito.when(vm.getUserVmType()).thenReturn(UserVmManager.CKS_NODE);
Mockito.when(kubernetesClusterVmMapDao.findByVmId(1L)).thenReturn(null);
kubernetesClusterHelper.checkVmCanBeDestroyed(vm);
kubernetesServiceHelper.checkVmCanBeDestroyed(vm);
}
@Test(expected = CloudRuntimeException.class)
@ -66,6 +66,6 @@ public class KubernetesClusterHelperImplTest {
Mockito.when(map.getClusterId()).thenReturn(1L);
Mockito.when(kubernetesClusterVmMapDao.findByVmId(1L)).thenReturn(map);
Mockito.when(kubernetesClusterDao.findById(1L)).thenReturn(Mockito.mock(KubernetesClusterVO.class));
kubernetesClusterHelper.checkVmCanBeDestroyed(vm);
kubernetesServiceHelper.checkVmCanBeDestroyed(vm);
}
}

View File

@ -215,9 +215,12 @@ public class KubernetesVersionServiceTest {
when(cmd.getMinimumRamSize()).thenReturn(KubernetesClusterService.MIN_KUBERNETES_CLUSTER_NODE_RAM_SIZE);
Account systemAccount = new AccountVO("system", 1L, "", Account.Type.ADMIN, "uuid");
when(accountManager.getSystemAccount()).thenReturn(systemAccount);
try (MockedStatic<ComponentContext> mockedComponentContext = Mockito.mockStatic(ComponentContext.class)) {
CallContext callContext = Mockito.mock(CallContext.class);
try (MockedStatic<ComponentContext> mockedComponentContext = Mockito.mockStatic(ComponentContext.class);
MockedStatic<CallContext> mockedCallContext = Mockito.mockStatic(CallContext.class)) {
mockedComponentContext.when(() -> ComponentContext.inject(Mockito.any(RegisterIsoCmd.class))).thenReturn(
new RegisterIsoCmd());
mockedCallContext.when(CallContext::current).thenReturn(callContext);
when(templateService.registerIso(Mockito.any(RegisterIsoCmd.class))).thenReturn(
Mockito.mock(VirtualMachineTemplate.class));

View File

@ -70,7 +70,7 @@ public class ActionEventInterceptor implements ComponentMethodInterceptor, Metho
if (async) {
CallContext ctx = CallContext.current();
String eventDescription = getEventDescription(actionEvent, ctx);
String eventDescription = getEventDescription(actionEvent, ctx, true);
Long eventResourceId = getEventResourceId(actionEvent, ctx);
String eventResourceType = getEventResourceType(actionEvent, ctx);
String eventType = getEventType(actionEvent, ctx);
@ -183,19 +183,24 @@ public class ActionEventInterceptor implements ComponentMethodInterceptor, Metho
return type == null ? actionEvent.eventType() : type;
}
protected String getEventDescription(ActionEvent actionEvent, CallContext ctx) {
protected String getEventDescription(ActionEvent actionEvent, CallContext ctx, boolean capitalizeFirstLetter) {
String eventDescription = ctx.getEventDescription();
if (eventDescription == null) {
eventDescription = actionEvent.eventDescription();
}
if (ctx.getEventDetails() != null) {
eventDescription += ". " + ctx.getEventDetails();
}
if (capitalizeFirstLetter && StringUtils.isNotBlank(eventDescription)) {
eventDescription = eventDescription.substring(0, 1).toUpperCase() + eventDescription.substring(1);
}
return eventDescription;
}
protected String getEventDescription(ActionEvent actionEvent, CallContext ctx) {
return getEventDescription(actionEvent, ctx, false);
}
protected Long getEventResourceId(ActionEvent actionEvent, CallContext ctx) {
Long resourceId = ctx.getEventResourceId();
if (resourceId != null) {

View File

@ -41,9 +41,6 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.network.dao.PublicIpQuarantineDao;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.dao.ServiceOfferingDao;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.alert.AlertService;
@ -164,6 +161,7 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.dao.PublicIpQuarantineDao;
import com.cloud.network.element.NetworkElement;
import com.cloud.network.element.OvsProviderVO;
import com.cloud.network.element.VirtualRouterElement;
@ -190,6 +188,7 @@ import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcGatewayDao;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
@ -198,6 +197,8 @@ import com.cloud.projects.Project;
import com.cloud.projects.ProjectManager;
import com.cloud.server.ResourceTag;
import com.cloud.server.ResourceTag.ResourceObjectType;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.tags.ResourceTagVO;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.user.Account;
@ -253,7 +254,6 @@ import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.googlecode.ipv6.IPv6Address;
import com.cloud.service.ServiceOfferingVO;
/**
* NetworkServiceImpl implements NetworkService.
@ -1672,6 +1672,18 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
return network;
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network")
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, Account owner,
PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType) throws
InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
return _networkMgr.createGuestNetwork(networkOfferingId, name, displayText,
null, null, null, false, null, owner, null, physicalNetwork, zoneId,
aclType, null, null, null, null, true, null,
null, null, null, null, null, null, null, null, null);
}
void checkAndSetRouterSourceNatIp(Account owner, CreateNetworkCmd cmd, Network network) throws InsufficientAddressCapacityException, ResourceAllocationException {
String sourceNatIp = cmd.getSourceNatIP();
if (sourceNatIp == null) {

View File

@ -242,7 +242,7 @@ import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
import com.cloud.hypervisor.kvm.dpdk.DpdkHelper;
import com.cloud.kubernetes.cluster.KubernetesClusterHelper;
import com.cloud.kubernetes.cluster.KubernetesServiceHelper;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
@ -3230,6 +3230,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
return startVirtualMachine(cmd.getId(), cmd.getPodId(), cmd.getClusterId(), cmd.getHostId(), additonalParams, cmd.getDeploymentPlanner()).first();
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_START, eventDescription = "starting Vm", async = true)
public void startVirtualMachine(UserVm vm) throws OperationTimedoutException, ResourceUnavailableException, InsufficientCapacityException {
_itMgr.advanceStart(vm.getUuid(), null, null);
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_REBOOT, eventDescription = "rebooting Vm", async = true)
public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {
@ -3286,11 +3292,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
protected void checkPluginsIfVmCanBeDestroyed(UserVm vm) {
try {
KubernetesClusterHelper kubernetesClusterHelper =
ComponentContext.getDelegateComponentOfType(KubernetesClusterHelper.class);
kubernetesClusterHelper.checkVmCanBeDestroyed(vm);
KubernetesServiceHelper kubernetesServiceHelper =
ComponentContext.getDelegateComponentOfType(KubernetesServiceHelper.class);
kubernetesServiceHelper.checkVmCanBeDestroyed(vm);
} catch (NoSuchBeanDefinitionException ignored) {
s_logger.debug("No KubernetesClusterHelper bean found");
s_logger.debug("No KubernetesServiceHelper bean found");
}
}

View File

@ -65,7 +65,7 @@ import com.cloud.event.EventTypes;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.kubernetes.cluster.KubernetesClusterHelper;
import com.cloud.kubernetes.cluster.KubernetesServiceHelper;
import com.cloud.network.as.dao.AutoScaleVmGroupDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.NetworkDao;
@ -165,7 +165,7 @@ public final class AnnotationManagerImpl extends ManagerBase implements Annotati
EntityManager entityManager;
private static final List<RoleType> adminRoles = Collections.singletonList(RoleType.Admin);
private List<KubernetesClusterHelper> kubernetesClusterHelpers;
private List<KubernetesServiceHelper> kubernetesServiceHelpers;
public static final Map<EntityType, ApiCommandResourceType> s_typeMap = new HashMap<>();
static {
@ -200,12 +200,12 @@ public final class AnnotationManagerImpl extends ManagerBase implements Annotati
s_typeMap.put(EntityType.OBJECT_STORAGE, ApiCommandResourceType.ObjectStore);
}
public List<KubernetesClusterHelper> getKubernetesClusterHelpers() {
return kubernetesClusterHelpers;
public List<KubernetesServiceHelper> getKubernetesServiceHelpers() {
return kubernetesServiceHelpers;
}
public void setKubernetesClusterHelpers(final List<KubernetesClusterHelper> kubernetesClusterHelpers) {
this.kubernetesClusterHelpers = kubernetesClusterHelpers;
public void setKubernetesServiceHelpers(final List<KubernetesServiceHelper> kubernetesServiceHelpers) {
this.kubernetesServiceHelpers = kubernetesServiceHelpers;
}
@Override
@ -535,7 +535,7 @@ public final class AnnotationManagerImpl extends ManagerBase implements Annotati
case ISO:
return templateDao.findByUuid(entityUuid);
case KUBERNETES_CLUSTER:
return kubernetesClusterHelpers.get(0).findByUuid(entityUuid);
return kubernetesServiceHelpers.get(0).findByUuid(entityUuid);
case AUTOSCALE_VM_GROUP:
return autoScaleVmGroupDao.findByUuid(entityUuid);
case MANAGEMENT_SERVER:

View File

@ -316,7 +316,7 @@
</bean>
<bean id="annotationService" class="org.apache.cloudstack.annotation.AnnotationManagerImpl">
<property name="kubernetesClusterHelpers" value="#{kubernetesClusterHelperRegistry.registered}" />
<property name="kubernetesServiceHelpers" value="#{kubernetesServiceHelperRegistry.registered}" />
</bean>
<bean id="indirectAgentLBService" class="org.apache.cloudstack.agent.lb.IndirectAgentLBServiceImpl" />

View File

@ -217,6 +217,13 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
return null;
}
@Override
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, Account owner,
PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceAllocationException {
return null;
}
/* (non-Javadoc)
* @see com.cloud.network.NetworkService#searchForNetworks(com.cloud.api.commands.ListNetworksCmd)
*/

View File

@ -18,7 +18,13 @@
<template>
<div v-if="resourceType && resourceId" >
<a-tooltip v-if="resourceIcon" placement="top" :title="resourceIconTooltip">
<render-icon style="font-size: 16px; margin-right: 5px" :icon="resourceIcon" />
<font-awesome-icon
v-if="resourceIcon && Array.isArray(resourceIcon)"
:icon="resourceIcon"
size="1x"
class="anticon"
:style="[$store.getters.darkMode ? { color: 'rgba(255, 255, 255, 0.65)' } : { color: '#888' }]" />
<render-icon v-else style="font-size: 16px; margin-right: 5px" :icon="resourceIcon" />
</a-tooltip>
<a-tag v-else>{{ resourceType }}</a-tag>
<router-link v-if="resourceRoute && $router.resolve(resourceRoute)" :to="{ path: resourceRoute }">{{ resourceName || resourceId }}</router-link>
@ -67,3 +73,12 @@ export default {
}
}
</script>
<style lang="scss" scoped>
.anticon {
margin-right: 5px;
vertical-align: center;
}
</style>

View File

@ -542,10 +542,12 @@ export default {
return filters
},
details: ['name', 'description', 'zonename', 'kubernetesversionname', 'autoscalingenabled', 'minsize', 'maxsize', 'size', 'controlnodes', 'cpunumber', 'memory', 'keypair', 'associatednetworkname', 'account', 'domain', 'zonename', 'clustertype', 'created'],
tabs: [{
name: 'k8s',
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/KubernetesServiceTab.vue')))
}],
tabs: [
{
name: 'k8s',
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/KubernetesServiceTab.vue')))
}
],
resourceType: 'KubernetesCluster',
actions: [
{

View File

@ -370,6 +370,18 @@ export default {
searchFilters: ['zoneid', 'minimumsemanticversion'],
columns: ['name', 'state', 'semanticversion', 'isostate', 'mincpunumber', 'minmemory', 'zonename'],
details: ['name', 'semanticversion', 'supportsautoscaling', 'zoneid', 'zonename', 'isoid', 'isoname', 'isostate', 'mincpunumber', 'minmemory', 'supportsha', 'state', 'created'],
tabs: [
{
name: 'details',
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
},
{
name: 'events',
resourceType: 'KubernetesSupportedVersion',
component: shallowRef(defineAsyncComponent(() => import('@/components/view/EventsTab.vue'))),
show: () => { return 'listEvents' in store.getters.apis }
}
],
actions: [
{
api: 'addKubernetesSupportedVersion',

View File

@ -390,6 +390,10 @@ export const resourceTypePlugin = {
return 'publicip'
case 'NetworkAcl':
return 'acllist'
case 'KubernetesCluster':
return 'kubernetes'
case 'KubernetesSupportedVersion':
return 'kubernetesiso'
case 'SystemVm':
case 'PhysicalNetwork':
case 'Backup':

View File

@ -149,6 +149,9 @@
<a-tab-pane :tab="$t('label.loadbalancing')" key="loadbalancing" v-if="publicIpAddress">
<LoadBalancing :resource="publicIpAddress" :loading="networkLoading" />
</a-tab-pane>
<a-tab-pane :tab="$t('label.events')" key="events" v-if="'listEvents' in $store.getters.apis">
<events-tab :resource="resource" resourceType="KubernetesCluster" :loading="loading" />
</a-tab-pane>
<a-tab-pane :tab="$t('label.annotations')" key="comments" v-if="'listAnnotations' in $store.getters.apis">
<AnnotationsTab
:resource="resource"
@ -169,6 +172,7 @@ import PortForwarding from '@/views/network/PortForwarding'
import LoadBalancing from '@/views/network/LoadBalancing'
import Status from '@/components/widgets/Status'
import AnnotationsTab from '@/components/view/AnnotationsTab'
import EventsTab from '@/components/view/EventsTab'
export default {
name: 'KubernetesServiceTab',
@ -178,7 +182,8 @@ export default {
PortForwarding,
LoadBalancing,
Status,
AnnotationsTab
AnnotationsTab,
EventsTab
},
mixins: [mixinDevice],
inject: ['parentFetchData'],