This is an automated email from the ASF dual-hosted git repository. rohit pushed a commit to branch 4.19 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.19 by this push: new ce9b2c52f32 cks: fix events (#9070) ce9b2c52f32 is described below commit ce9b2c52f32091552247ed79a9630b60bbe3535d Author: Abhishek Kumar <abhishek.mr...@gmail.com> AuthorDate: Fri Jun 14 12:22:39 2024 +0530 cks: fix events (#9070) Fixes #8043 Signed-off-by: Abhishek Kumar <abhishek.mr...@gmail.com> --- api/src/main/java/com/cloud/event/EventTypes.java | 6 +- ...terHelper.java => KubernetesServiceHelper.java} | 2 +- .../java/com/cloud/network/NetworkService.java | 5 + api/src/main/java/com/cloud/vm/UserVmService.java | 3 + .../cloudstack/api/ApiCommandResourceType.java | 15 ++- .../core/spring-core-registry-core-context.xml | 2 +- ...re-lifecycle-kubernetes-context-inheritable.xml | 4 +- .../cluster/KubernetesClusterManagerImpl.java | 102 ++++++++++++++++----- .../cluster/KubernetesClusterService.java | 5 +- ...rImpl.java => KubernetesServiceHelperImpl.java} | 42 ++++++++- .../KubernetesClusterActionWorker.java | 14 ++- .../KubernetesClusterDestroyWorker.java | 6 ++ ...ernetesClusterResourceModifierActionWorker.java | 68 +++++++++----- .../KubernetesClusterScaleWorker.java | 11 ++- .../actionworkers/KubernetesClusterStopWorker.java | 6 ++ .../version/KubernetesVersionManagerImpl.java | 27 +++++- .../version/AddKubernetesSupportedVersionCmd.java | 6 ++ .../DeleteKubernetesSupportedVersionCmd.java | 6 ++ .../UpdateKubernetesSupportedVersionCmd.java | 14 ++- .../cluster/CreateKubernetesClusterCmd.java | 11 +-- .../cluster/DeleteKubernetesClusterCmd.java | 11 +++ ...oveVirtualMachinesFromKubernetesClusterCmd.java | 6 ++ .../cluster/ScaleKubernetesClusterCmd.java | 6 ++ .../cluster/StartKubernetesClusterCmd.java | 28 ++---- .../cluster/StopKubernetesClusterCmd.java | 6 ++ .../cluster/UpgradeKubernetesClusterCmd.java | 6 ++ .../spring-kubernetes-service-context.xml | 4 +- ...t.java => KubernetesServiceHelperImplTest.java} | 10 +- .../version/KubernetesVersionServiceTest.java | 5 +- .../com/cloud/event/ActionEventInterceptor.java | 13 ++- .../java/com/cloud/network/NetworkServiceImpl.java | 20 +++- .../main/java/com/cloud/vm/UserVmManagerImpl.java | 16 +++- .../annotation/AnnotationManagerImpl.java | 14 +-- .../core/spring-server-core-managers-context.xml | 2 +- .../java/com/cloud/vpc/MockNetworkManagerImpl.java | 7 ++ ui/src/components/widgets/ResourceLabel.vue | 17 +++- ui/src/config/section/compute.js | 10 +- ui/src/config/section/image.js | 12 +++ ui/src/utils/plugins.js | 4 + ui/src/views/compute/KubernetesServiceTab.vue | 7 +- 40 files changed, 430 insertions(+), 129 deletions(-) diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java index 01ad12a71e0..689676290b3 100644 --- a/api/src/main/java/com/cloud/event/EventTypes.java +++ b/api/src/main/java/com/cloud/event/EventTypes.java @@ -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); + } } diff --git a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelper.java b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java similarity index 94% rename from api/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelper.java rename to api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java index e67e5277cee..a39c26680fd 100644 --- a/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelper.java +++ b/api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java @@ -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); diff --git a/api/src/main/java/com/cloud/network/NetworkService.java b/api/src/main/java/com/cloud/network/NetworkService.java index 82d229da459..c562a54a048 100644 --- a/api/src/main/java/com/cloud/network/NetworkService.java +++ b/api/src/main/java/com/cloud/network/NetworkService.java @@ -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); diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index 787ed7bde37..7355d05053f 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -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; diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java index aafc039b36b..93893676516 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java @@ -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); + } } diff --git a/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml index a36d1243155..dbca5deb739 100644 --- a/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml +++ b/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml @@ -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> diff --git a/core/src/main/resources/META-INF/cloudstack/kubernetes/spring-core-lifecycle-kubernetes-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/kubernetes/spring-core-lifecycle-kubernetes-context-inheritable.xml index df1a4b5c229..96a9a634bae 100644 --- a/core/src/main/resources/META-INF/cloudstack/kubernetes/spring-core-lifecycle-kubernetes-context-inheritable.xml +++ b/core/src/main/resources/META-INF/cloudstack/kubernetes/spring-core-lifecycle-kubernetes-context-inheritable.xml @@ -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> diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java index 04c8a5d7554..5283a1273c4 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java @@ -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"); diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterService.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterService.java index 39b926537f5..6acc876493e 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterService.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterService.java @@ -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; diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelperImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImpl.java similarity index 61% rename from plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelperImpl.java rename to plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImpl.java index 74f97426d85..1b149a97de2 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterHelperImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImpl.java @@ -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(); + } } diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java index a84320e4d7f..199f6da90d2 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java @@ -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()) { diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterDestroyWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterDestroyWorker.java index 29da3ffb59d..d42f31ec2d3 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterDestroyWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterDestroyWorker.java @@ -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(); } } } diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java index 0ae22bf8c8d..d721db4b6b4 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java @@ -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(); } } diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterScaleWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterScaleWorker.java index df94642a881..5b496509eeb 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterScaleWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterScaleWorker.java @@ -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(); diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStopWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStopWorker.java index 682175047bf..74bbfa7f6f0 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStopWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStopWorker.java @@ -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) { diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java index f31dc36768f..efdbebc1ab9 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/version/KubernetesVersionManagerImpl.java @@ -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"); diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/AddKubernetesSupportedVersionCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/AddKubernetesSupportedVersionCmd.java index 380c93cca20..1cff833d9cf 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/AddKubernetesSupportedVersionCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/AddKubernetesSupportedVersionCmd.java @@ -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/////////////////// ///////////////////////////////////////////////////// diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/DeleteKubernetesSupportedVersionCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/DeleteKubernetesSupportedVersionCmd.java index 42ac28dd16a..b709637bf8b 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/DeleteKubernetesSupportedVersionCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/DeleteKubernetesSupportedVersionCmd.java @@ -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/////////////////// ///////////////////////////////////////////////////// diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/UpdateKubernetesSupportedVersionCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/UpdateKubernetesSupportedVersionCmd.java index f932e5a9ba1..9950a06dc84 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/UpdateKubernetesSupportedVersionCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/admin/kubernetes/version/UpdateKubernetesSupportedVersionCmd.java @@ -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(); } ///////////////////////////////////////////////////// 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 12a50c9e88f..52908825430 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 @@ -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); diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/DeleteKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/DeleteKubernetesClusterCmd.java index 2b4a1283ce2..9ea48b0e9d7 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/DeleteKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/DeleteKubernetesClusterCmd.java @@ -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"; diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/RemoveVirtualMachinesFromKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/RemoveVirtualMachinesFromKubernetesClusterCmd.java index 704d0b2f1f0..61096be24c8 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/RemoveVirtualMachinesFromKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/RemoveVirtualMachinesFromKubernetesClusterCmd.java @@ -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 { diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/ScaleKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/ScaleKubernetesClusterCmd.java index e5a5c902f4d..49017e937ca 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/ScaleKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/ScaleKubernetesClusterCmd.java @@ -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/////////////////// ///////////////////////////////////////////////////// diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/StartKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/StartKubernetesClusterCmd.java index 7a7c1e82232..a15c7646967 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/StartKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/StartKubernetesClusterCmd.java @@ -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) { diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/StopKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/StopKubernetesClusterCmd.java index 866a7a8fd7f..7cefef0b947 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/StopKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/StopKubernetesClusterCmd.java @@ -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/////////////////// ///////////////////////////////////////////////////// diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/UpgradeKubernetesClusterCmd.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/UpgradeKubernetesClusterCmd.java index 2cbedf5608a..faba8a930ca 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/UpgradeKubernetesClusterCmd.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/command/user/kubernetes/cluster/UpgradeKubernetesClusterCmd.java @@ -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/////////////////// ///////////////////////////////////////////////////// diff --git a/plugins/integrations/kubernetes-service/src/main/resources/META-INF/cloudstack/kubernetes-service/spring-kubernetes-service-context.xml b/plugins/integrations/kubernetes-service/src/main/resources/META-INF/cloudstack/kubernetes-service/spring-kubernetes-service-context.xml index cf9faeeead5..9d236eed26c 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/META-INF/cloudstack/kubernetes-service/spring-kubernetes-service-context.xml +++ b/plugins/integrations/kubernetes-service/src/main/resources/META-INF/cloudstack/kubernetes-service/spring-kubernetes-service-context.xml @@ -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> diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterHelperImplTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImplTest.java similarity index 89% rename from plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterHelperImplTest.java rename to plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImplTest.java index 167ade67cfb..8749fe2b7dc 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterHelperImplTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesServiceHelperImplTest.java @@ -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); } } diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java index d3412bbf750..f7e816596c2 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/version/KubernetesVersionServiceTest.java @@ -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)); diff --git a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java index 30ff61b3e7f..ee025c825f5 100644 --- a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java +++ b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java @@ -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) { diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 068a06427db..91e19c00e90 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -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) { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index a8810dea54e..0c8ab1cd793 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -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"); } } diff --git a/server/src/main/java/org/apache/cloudstack/annotation/AnnotationManagerImpl.java b/server/src/main/java/org/apache/cloudstack/annotation/AnnotationManagerImpl.java index 6a9d40cad18..0239891c8c0 100644 --- a/server/src/main/java/org/apache/cloudstack/annotation/AnnotationManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/annotation/AnnotationManagerImpl.java @@ -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: diff --git a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index 735a9075f9e..cbe4911d7b0 100644 --- a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -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" /> diff --git a/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java index 288211c4330..c6762b2a2a1 100644 --- a/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java @@ -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) */ diff --git a/ui/src/components/widgets/ResourceLabel.vue b/ui/src/components/widgets/ResourceLabel.vue index 6e44ce54a5d..0a10843ff86 100644 --- a/ui/src/components/widgets/ResourceLabel.vue +++ b/ui/src/components/widgets/ResourceLabel.vue @@ -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> diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index 57177d0da93..270d16831d6 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -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: [ { diff --git a/ui/src/config/section/image.js b/ui/src/config/section/image.js index 6f0bd5e9322..0706f2e9870 100644 --- a/ui/src/config/section/image.js +++ b/ui/src/config/section/image.js @@ -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', diff --git a/ui/src/utils/plugins.js b/ui/src/utils/plugins.js index be6276dbd0c..acaebf45892 100644 --- a/ui/src/utils/plugins.js +++ b/ui/src/utils/plugins.js @@ -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': diff --git a/ui/src/views/compute/KubernetesServiceTab.vue b/ui/src/views/compute/KubernetesServiceTab.vue index 9632846ef37..bdaa2eefde6 100644 --- a/ui/src/views/compute/KubernetesServiceTab.vue +++ b/ui/src/views/compute/KubernetesServiceTab.vue @@ -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'],