Search in sources :

Example 1 with ScaleKubernetesClusterCmd

use of org.apache.cloudstack.api.command.user.kubernetes.cluster.ScaleKubernetesClusterCmd in project cloudstack by apache.

the class KubernetesClusterManagerImpl method validateKubernetesClusterScaleParameters.

private void validateKubernetesClusterScaleParameters(ScaleKubernetesClusterCmd cmd) {
    final Long kubernetesClusterId = cmd.getId();
    final Long serviceOfferingId = cmd.getServiceOfferingId();
    final Long clusterSize = cmd.getClusterSize();
    final List<Long> nodeIds = cmd.getNodeIds();
    final Boolean isAutoscalingEnabled = cmd.isAutoscalingEnabled();
    final Long minSize = cmd.getMinSize();
    final Long maxSize = cmd.getMaxSize();
    if (kubernetesClusterId == null || kubernetesClusterId < 1L) {
        throw new InvalidParameterValueException("Invalid Kubernetes cluster ID");
    }
    KubernetesClusterVO kubernetesCluster = kubernetesClusterDao.findById(kubernetesClusterId);
    if (kubernetesCluster == null || kubernetesCluster.getRemoved() != null) {
        throw new InvalidParameterValueException("Invalid Kubernetes cluster ID");
    }
    final DataCenter zone = dataCenterDao.findById(kubernetesCluster.getZoneId());
    if (zone == null) {
        logAndThrow(Level.WARN, String.format("Unable to find zone for Kubernetes cluster : %s", kubernetesCluster.getName()));
    }
    if (serviceOfferingId == null && clusterSize == null && nodeIds == null && isAutoscalingEnabled == null) {
        throw new InvalidParameterValueException(String.format("Kubernetes cluster %s cannot be scaled, either service offering or cluster size or nodeids to be removed or autoscaling must be passed", kubernetesCluster.getName()));
    }
    Account caller = CallContext.current().getCallingAccount();
    accountManager.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, false, kubernetesCluster);
    final KubernetesSupportedVersion clusterVersion = kubernetesSupportedVersionDao.findById(kubernetesCluster.getKubernetesVersionId());
    if (clusterVersion == null) {
        throw new CloudRuntimeException(String.format("Invalid Kubernetes version associated with Kubernetes cluster : %s", kubernetesCluster.getName()));
    }
    List<KubernetesCluster.State> validClusterStates = Arrays.asList(KubernetesCluster.State.Created, KubernetesCluster.State.Running, KubernetesCluster.State.Stopped);
    if (!(validClusterStates.contains(kubernetesCluster.getState()))) {
        throw new PermissionDeniedException(String.format("Kubernetes cluster %s is in %s state and can not be scaled", kubernetesCluster.getName(), kubernetesCluster.getState().toString()));
    }
    int maxClusterSize = KubernetesMaxClusterSize.valueIn(kubernetesCluster.getAccountId());
    if (isAutoscalingEnabled != null && isAutoscalingEnabled) {
        if (clusterSize != null || serviceOfferingId != null || nodeIds != null) {
            throw new InvalidParameterValueException("Autoscaling can not be passed along with nodeids or clustersize or service offering");
        }
        if (!KubernetesVersionManagerImpl.versionSupportsAutoscaling(clusterVersion)) {
            throw new InvalidParameterValueException(String.format("Autoscaling requires Kubernetes Version %s or above", KubernetesVersionManagerImpl.MINIMUN_AUTOSCALER_SUPPORTED_VERSION));
        }
        validateEndpointUrl();
        if (minSize == null || maxSize == null) {
            throw new InvalidParameterValueException("Autoscaling requires minsize and maxsize to be passed");
        }
        if (minSize < 1) {
            throw new InvalidParameterValueException("Minsize must be at least than 1");
        }
        if (maxSize <= minSize) {
            throw new InvalidParameterValueException("Maxsize must be greater than minsize");
        }
        if (maxSize + kubernetesCluster.getControlNodeCount() > maxClusterSize) {
            throw new InvalidParameterValueException(String.format("Maximum cluster size can not exceed %d. Please contact your administrator", maxClusterSize));
        }
    }
    if (nodeIds != null) {
        if (clusterSize != null || serviceOfferingId != null) {
            throw new InvalidParameterValueException("nodeids can not be passed along with clustersize or service offering");
        }
        List<KubernetesClusterVmMapVO> nodes = kubernetesClusterVmMapDao.listByClusterIdAndVmIdsIn(kubernetesCluster.getId(), nodeIds);
        // Do all the nodes exist ?
        if (nodes == null || nodes.size() != nodeIds.size()) {
            throw new InvalidParameterValueException("Invalid node ids");
        }
        // Ensure there's always a control node
        long controleNodesToRemove = nodes.stream().filter(x -> x.isControlNode()).count();
        if (controleNodesToRemove >= kubernetesCluster.getControlNodeCount()) {
            throw new InvalidParameterValueException("Can not remove all control nodes from a cluster");
        }
        // Ensure there's always a node
        long nodesToRemove = nodes.stream().filter(x -> !x.isControlNode()).count();
        if (nodesToRemove >= kubernetesCluster.getNodeCount()) {
            throw new InvalidParameterValueException("Can not remove all nodes from a cluster");
        }
    }
    ServiceOffering serviceOffering = null;
    if (serviceOfferingId != null) {
        serviceOffering = serviceOfferingDao.findById(serviceOfferingId);
        if (serviceOffering == null) {
            throw new InvalidParameterValueException("Failed to find service offering ID: " + serviceOfferingId);
        } else {
            if (serviceOffering.isDynamic()) {
                throw new InvalidParameterValueException(String.format("Custom service offerings are not supported for Kubernetes clusters. Kubernetes cluster : %s, service offering : %s", kubernetesCluster.getName(), serviceOffering.getName()));
            }
            if (serviceOffering.getCpu() < MIN_KUBERNETES_CLUSTER_NODE_CPU || serviceOffering.getRamSize() < MIN_KUBERNETES_CLUSTER_NODE_RAM_SIZE) {
                throw new InvalidParameterValueException(String.format("Kubernetes cluster : %s cannot be scaled with service offering : %s, Kubernetes cluster template(CoreOS) needs minimum %d vCPUs and %d MB RAM", kubernetesCluster.getName(), serviceOffering.getName(), MIN_KUBERNETES_CLUSTER_NODE_CPU, MIN_KUBERNETES_CLUSTER_NODE_RAM_SIZE));
            }
            if (serviceOffering.getCpu() < clusterVersion.getMinimumCpu()) {
                throw new InvalidParameterValueException(String.format("Kubernetes cluster : %s cannot be scaled with service offering : %s, associated Kubernetes version : %s needs minimum %d vCPUs", kubernetesCluster.getName(), serviceOffering.getName(), clusterVersion.getName(), clusterVersion.getMinimumCpu()));
            }
            if (serviceOffering.getRamSize() < clusterVersion.getMinimumRamSize()) {
                throw new InvalidParameterValueException(String.format("Kubernetes cluster : %s cannot be scaled with service offering : %s, associated Kubernetes version : %s needs minimum %d MB RAM", kubernetesCluster.getName(), serviceOffering.getName(), clusterVersion.getName(), clusterVersion.getMinimumRamSize()));
            }
        }
        final ServiceOffering existingServiceOffering = serviceOfferingDao.findById(kubernetesCluster.getServiceOfferingId());
        if (serviceOffering.getRamSize() < existingServiceOffering.getRamSize() || serviceOffering.getCpu() * serviceOffering.getSpeed() < existingServiceOffering.getCpu() * existingServiceOffering.getSpeed()) {
            logAndThrow(Level.WARN, String.format("Kubernetes cluster cannot be scaled down for service offering. Service offering : %s offers lesser resources as compared to service offering : %s of Kubernetes cluster : %s", serviceOffering.getName(), existingServiceOffering.getName(), kubernetesCluster.getName()));
        }
    }
    if (clusterSize != null) {
        if (kubernetesCluster.getState().equals(KubernetesCluster.State.Stopped)) {
            // Cannot scale stopped cluster currently for cluster size
            throw new PermissionDeniedException(String.format("Kubernetes cluster : %s is in %s state", kubernetesCluster.getName(), kubernetesCluster.getState().toString()));
        }
        if (clusterSize < 1) {
            throw new InvalidParameterValueException(String.format("Kubernetes cluster : %s cannot be scaled for size, %d", kubernetesCluster.getName(), clusterSize));
        }
        if (clusterSize + kubernetesCluster.getControlNodeCount() > maxClusterSize) {
            throw new InvalidParameterValueException(String.format("Maximum cluster size can not exceed %d. Please contact your administrator", maxClusterSize));
        }
        if (clusterSize > kubernetesCluster.getNodeCount()) {
            // Upscale
            VMTemplateVO template = templateDao.findById(kubernetesCluster.getTemplateId());
            if (template == null) {
                throw new InvalidParameterValueException(String.format("Invalid template associated with Kubernetes cluster : %s", kubernetesCluster.getName()));
            }
            if (CollectionUtils.isEmpty(templateJoinDao.newTemplateView(template, zone.getId(), true))) {
                throw new InvalidParameterValueException(String.format("Template : %s associated with Kubernetes cluster : %s is not in Ready state for datacenter : %s", template.getName(), kubernetesCluster.getName(), zone.getName()));
            }
        }
    }
}
Also used : KubernetesSupportedVersion(com.cloud.kubernetes.version.KubernetesSupportedVersion) AccountService(com.cloud.user.AccountService) NetworkModel(com.cloud.network.NetworkModel) Arrays(java.util.Arrays) HostDao(com.cloud.host.dao.HostDao) UserVmJoinDao(com.cloud.api.query.dao.UserVmJoinDao) ComponentContext(com.cloud.utils.component.ComponentContext) Transaction(com.cloud.utils.db.Transaction) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) StringUtils(org.apache.commons.lang3.StringUtils) Base64(org.apache.commons.codec.binary.Base64) SecureRandom(java.security.SecureRandom) ServiceOfferingDao(com.cloud.service.dao.ServiceOfferingDao) Level(org.apache.log4j.Level) Map(java.util.Map) BigInteger(java.math.BigInteger) NetworkOrchestrationService(org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService) CapacityManager(com.cloud.capacity.CapacityManager) Service(com.cloud.network.Network.Service) PhysicalNetworkDao(com.cloud.network.dao.PhysicalNetworkDao) EnumSet(java.util.EnumSet) CallContext(org.apache.cloudstack.context.CallContext) ResourceManager(com.cloud.resource.ResourceManager) Network(com.cloud.network.Network) TransactionStatus(com.cloud.utils.db.TransactionStatus) KubernetesClusterActionWorker(com.cloud.kubernetes.cluster.actionworkers.KubernetesClusterActionWorker) ApiDBUtils(com.cloud.api.ApiDBUtils) NetworkOfferingVO(com.cloud.offerings.NetworkOfferingVO) Executors(java.util.concurrent.Executors) ScaleKubernetesClusterCmd(org.apache.cloudstack.api.command.user.kubernetes.cluster.ScaleKubernetesClusterCmd) Project(com.cloud.projects.Project) ServiceOfferingVO(com.cloud.service.ServiceOfferingVO) KubernetesClusterDao(com.cloud.kubernetes.cluster.dao.KubernetesClusterDao) KubernetesClusterConfigResponse(org.apache.cloudstack.api.response.KubernetesClusterConfigResponse) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) ServiceOffering(com.cloud.offering.ServiceOffering) InsufficientServerCapacityException(com.cloud.exception.InsufficientServerCapacityException) KubernetesClusterStartWorker(com.cloud.kubernetes.cluster.actionworkers.KubernetesClusterStartWorker) ListResponse(org.apache.cloudstack.api.response.ListResponse) NetworkOfferingJoinDao(com.cloud.api.query.dao.NetworkOfferingJoinDao) ManagerBase(com.cloud.utils.component.ManagerBase) FirewallRule(com.cloud.network.rules.FirewallRule) VMTemplateDao(com.cloud.storage.dao.VMTemplateDao) DataCenterVO(com.cloud.dc.DataCenterVO) NetworkOfferingServiceMapDao(com.cloud.offerings.dao.NetworkOfferingServiceMapDao) ArrayList(java.util.ArrayList) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ClusterDao(com.cloud.dc.dao.ClusterDao) UserDao(com.cloud.user.dao.UserDao) SearchCriteria(com.cloud.utils.db.SearchCriteria) VMDetails(org.apache.cloudstack.api.ApiConstants.VMDetails) User(com.cloud.user.User) NetworkService(com.cloud.network.NetworkService) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ClusterVO(com.cloud.dc.ClusterVO) VMInstanceDao(com.cloud.vm.dao.VMInstanceDao) KubernetesClusterDetailsDao(com.cloud.kubernetes.cluster.dao.KubernetesClusterDetailsDao) UserAccount(com.cloud.user.UserAccount) KubernetesSupportedVersion(com.cloud.kubernetes.version.KubernetesSupportedVersion) UpgradeKubernetesClusterCmd(org.apache.cloudstack.api.command.user.kubernetes.cluster.UpgradeKubernetesClusterCmd) StopKubernetesClusterCmd(org.apache.cloudstack.api.command.user.kubernetes.cluster.StopKubernetesClusterCmd) PhysicalNetwork(com.cloud.network.PhysicalNetwork) KubernetesClusterResponse(org.apache.cloudstack.api.response.KubernetesClusterResponse) ControlledEntity(org.apache.cloudstack.acl.ControlledEntity) AccountManager(com.cloud.user.AccountManager) ClusterDetailsVO(com.cloud.dc.ClusterDetailsVO) ClusterDetailsDao(com.cloud.dc.ClusterDetailsDao) GlobalLock(com.cloud.utils.db.GlobalLock) KubernetesClusterScaleWorker(com.cloud.kubernetes.cluster.actionworkers.KubernetesClusterScaleWorker) AnnotationDao(org.apache.cloudstack.annotation.dao.AnnotationDao) URL(java.net.URL) Date(java.util.Date) KubernetesClusterDestroyWorker(com.cloud.kubernetes.cluster.actionworkers.KubernetesClusterDestroyWorker) Networks(com.cloud.network.Networks) Grouping(com.cloud.org.Grouping) SecurityChecker(org.apache.cloudstack.acl.SecurityChecker) Filter(com.cloud.utils.db.Filter) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) UserVmJoinVO(com.cloud.api.query.vo.UserVmJoinVO) Cluster(com.cloud.org.Cluster) Logger(org.apache.log4j.Logger) KubernetesClusterVmMapDao(com.cloud.kubernetes.cluster.dao.KubernetesClusterVmMapDao) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ApiServiceConfiguration(org.apache.cloudstack.config.ApiServiceConfiguration) DeleteKubernetesClusterCmd(org.apache.cloudstack.api.command.user.kubernetes.cluster.DeleteKubernetesClusterCmd) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) ManagedContextRunnable(org.apache.cloudstack.managed.context.ManagedContextRunnable) UserVO(com.cloud.user.UserVO) VMInstanceVO(com.cloud.vm.VMInstanceVO) KubernetesSupportedVersionVO(com.cloud.kubernetes.version.KubernetesSupportedVersionVO) TransactionCallback(com.cloud.utils.db.TransactionCallback) StateMachine2(com.cloud.utils.fsm.StateMachine2) DeployDestination(com.cloud.deploy.DeployDestination) IpAddress(com.cloud.network.IpAddress) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Account(com.cloud.user.Account) Pair(com.cloud.utils.Pair) UUID(java.util.UUID) CreateKubernetesClusterCmd(org.apache.cloudstack.api.command.user.kubernetes.cluster.CreateKubernetesClusterCmd) List(java.util.List) DataCenterDao(com.cloud.dc.dao.DataCenterDao) NetworkOfferingServiceMapVO(com.cloud.offerings.NetworkOfferingServiceMapVO) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) ResponseView(org.apache.cloudstack.api.ResponseObject.ResponseView) KubernetesVersionManagerImpl(com.cloud.kubernetes.version.KubernetesVersionManagerImpl) NetUtils(com.cloud.utils.net.NetUtils) VirtualMachine(com.cloud.vm.VirtualMachine) SearchBuilder(com.cloud.utils.db.SearchBuilder) HashMap(java.util.HashMap) Domain(com.cloud.domain.Domain) NetworkDao(com.cloud.network.dao.NetworkDao) ConfigurationException(javax.naming.ConfigurationException) ConfigKey(org.apache.cloudstack.framework.config.ConfigKey) Inject(javax.inject.Inject) IPAddressVO(com.cloud.network.dao.IPAddressVO) GetKubernetesClusterConfigCmd(org.apache.cloudstack.api.command.user.kubernetes.cluster.GetKubernetesClusterConfigCmd) CollectionUtils(org.apache.commons.collections.CollectionUtils) NetworkVO(com.cloud.network.dao.NetworkVO) IPAddressDao(com.cloud.network.dao.IPAddressDao) NetworkOfferingJoinVO(com.cloud.api.query.vo.NetworkOfferingJoinVO) FirewallRulesDao(com.cloud.network.dao.FirewallRulesDao) NamedThreadFactory(com.cloud.utils.concurrency.NamedThreadFactory) DataCenter(com.cloud.dc.DataCenter) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) HostVO(com.cloud.host.HostVO) ListKubernetesClustersCmd(org.apache.cloudstack.api.command.user.kubernetes.cluster.ListKubernetesClustersCmd) UserVmResponse(org.apache.cloudstack.api.response.UserVmResponse) KubernetesClusterStopWorker(com.cloud.kubernetes.cluster.actionworkers.KubernetesClusterStopWorker) VMTemplateVO(com.cloud.storage.VMTemplateVO) SSHKeyPairVO(com.cloud.user.SSHKeyPairVO) AnnotationService(org.apache.cloudstack.annotation.AnnotationService) Type(com.cloud.host.Host.Type) MalformedURLException(java.net.MalformedURLException) Hypervisor(com.cloud.hypervisor.Hypervisor) SSHKeyPairDao(com.cloud.user.dao.SSHKeyPairDao) ApiConstants(org.apache.cloudstack.api.ApiConstants) StartKubernetesClusterCmd(org.apache.cloudstack.api.command.user.kubernetes.cluster.StartKubernetesClusterCmd) NumbersUtil.toHumanReadableSize(com.cloud.utils.NumbersUtil.toHumanReadableSize) TemplateJoinDao(com.cloud.api.query.dao.TemplateJoinDao) NetworkOffering(com.cloud.offering.NetworkOffering) TimeUnit(java.util.concurrent.TimeUnit) KubernetesClusterUpgradeWorker(com.cloud.kubernetes.cluster.actionworkers.KubernetesClusterUpgradeWorker) KubernetesSupportedVersionDao(com.cloud.kubernetes.version.dao.KubernetesSupportedVersionDao) Ternary(com.cloud.utils.Ternary) NetworkOfferingDao(com.cloud.offerings.dao.NetworkOfferingDao) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO) UserAccount(com.cloud.user.UserAccount) Account(com.cloud.user.Account) ServiceOffering(com.cloud.offering.ServiceOffering) VMTemplateVO(com.cloud.storage.VMTemplateVO) DataCenter(com.cloud.dc.DataCenter) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException)

Aggregations

ApiDBUtils (com.cloud.api.ApiDBUtils)1 NetworkOfferingJoinDao (com.cloud.api.query.dao.NetworkOfferingJoinDao)1 TemplateJoinDao (com.cloud.api.query.dao.TemplateJoinDao)1 UserVmJoinDao (com.cloud.api.query.dao.UserVmJoinDao)1 NetworkOfferingJoinVO (com.cloud.api.query.vo.NetworkOfferingJoinVO)1 UserVmJoinVO (com.cloud.api.query.vo.UserVmJoinVO)1 CapacityManager (com.cloud.capacity.CapacityManager)1 ClusterDetailsDao (com.cloud.dc.ClusterDetailsDao)1 ClusterDetailsVO (com.cloud.dc.ClusterDetailsVO)1 ClusterVO (com.cloud.dc.ClusterVO)1 DataCenter (com.cloud.dc.DataCenter)1 DataCenterVO (com.cloud.dc.DataCenterVO)1 ClusterDao (com.cloud.dc.dao.ClusterDao)1 DataCenterDao (com.cloud.dc.dao.DataCenterDao)1 DeployDestination (com.cloud.deploy.DeployDestination)1 Domain (com.cloud.domain.Domain)1 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)1 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)1 InsufficientServerCapacityException (com.cloud.exception.InsufficientServerCapacityException)1 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)1