use of com.cloud.kubernetes.version.KubernetesSupportedVersion in project cloudstack by apache.
the class KubernetesClusterStartWorker method isKubernetesVersionSupportsHA.
private boolean isKubernetesVersionSupportsHA() {
boolean haSupported = false;
KubernetesSupportedVersion version = getKubernetesClusterVersion();
if (version != null) {
try {
if (KubernetesVersionManagerImpl.compareSemanticVersions(version.getSemanticVersion(), KubernetesClusterService.MIN_KUBERNETES_VERSION_HA_SUPPORT) >= 0) {
haSupported = true;
}
} catch (IllegalArgumentException e) {
LOGGER.error(String.format("Unable to compare Kubernetes version for cluster version : %s with %s", version.getName(), KubernetesClusterService.MIN_KUBERNETES_VERSION_HA_SUPPORT), e);
}
}
return haSupported;
}
use of com.cloud.kubernetes.version.KubernetesSupportedVersion in project cloudstack by apache.
the class KubernetesClusterManagerImpl method validateKubernetesClusterCreateParameters.
private void validateKubernetesClusterCreateParameters(final CreateKubernetesClusterCmd cmd) throws CloudRuntimeException {
validateEndpointUrl();
final String name = cmd.getName();
final Long zoneId = cmd.getZoneId();
final Long kubernetesVersionId = cmd.getKubernetesVersionId();
final Long serviceOfferingId = cmd.getServiceOfferingId();
final Account owner = accountService.getActiveAccountById(cmd.getEntityOwnerId());
final Long networkId = cmd.getNetworkId();
final String sshKeyPair = cmd.getSSHKeyPairName();
final Long controlNodeCount = cmd.getControlNodes();
final Long clusterSize = cmd.getClusterSize();
final long totalNodeCount = controlNodeCount + clusterSize;
final String dockerRegistryUserName = cmd.getDockerRegistryUserName();
final String dockerRegistryPassword = cmd.getDockerRegistryPassword();
final String dockerRegistryUrl = cmd.getDockerRegistryUrl();
final Long nodeRootDiskSize = cmd.getNodeRootDiskSize();
final String externalLoadBalancerIpAddress = cmd.getExternalLoadBalancerIpAddress();
if (name == null || name.isEmpty()) {
throw new InvalidParameterValueException("Invalid name for the Kubernetes cluster name:" + name);
}
if (controlNodeCount < 1) {
throw new InvalidParameterValueException("Invalid cluster control nodes count: " + controlNodeCount);
}
if (clusterSize < 1) {
throw new InvalidParameterValueException("Invalid cluster size: " + clusterSize);
}
int maxClusterSize = KubernetesMaxClusterSize.valueIn(owner.getId());
if (totalNodeCount > maxClusterSize) {
throw new InvalidParameterValueException(String.format("Maximum cluster size can not exceed %d. Please contact your administrator", maxClusterSize));
}
DataCenter zone = dataCenterDao.findById(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Unable to find zone by ID: " + zoneId);
}
if (Grouping.AllocationState.Disabled == zone.getAllocationState()) {
throw new PermissionDeniedException(String.format("Cannot perform this operation, zone ID: %s is currently disabled", zone.getUuid()));
}
if (!isKubernetesServiceConfigured(zone)) {
throw new CloudRuntimeException("Kubernetes service has not been configured properly to provision Kubernetes clusters");
}
final KubernetesSupportedVersion clusterKubernetesVersion = kubernetesSupportedVersionDao.findById(kubernetesVersionId);
if (clusterKubernetesVersion == null) {
throw new InvalidParameterValueException("Unable to find given Kubernetes version in supported versions");
}
if (!KubernetesSupportedVersion.State.Enabled.equals(clusterKubernetesVersion.getState())) {
throw new InvalidParameterValueException(String.format("Kubernetes version ID: %s is in %s state", clusterKubernetesVersion.getUuid(), clusterKubernetesVersion.getState()));
}
if (clusterKubernetesVersion.getZoneId() != null && !clusterKubernetesVersion.getZoneId().equals(zone.getId())) {
throw new InvalidParameterValueException(String.format("Kubernetes version ID: %s is not available for zone ID: %s", clusterKubernetesVersion.getUuid(), zone.getUuid()));
}
if (controlNodeCount > 1) {
try {
if (KubernetesVersionManagerImpl.compareSemanticVersions(clusterKubernetesVersion.getSemanticVersion(), MIN_KUBERNETES_VERSION_HA_SUPPORT) < 0) {
throw new InvalidParameterValueException(String.format("HA support is available only for Kubernetes version %s and above. Given version ID: %s is %s", MIN_KUBERNETES_VERSION_HA_SUPPORT, clusterKubernetesVersion.getUuid(), clusterKubernetesVersion.getSemanticVersion()));
}
} catch (IllegalArgumentException e) {
logAndThrow(Level.WARN, String.format("Unable to compare Kubernetes version for given version ID: %s with %s", clusterKubernetesVersion.getUuid(), MIN_KUBERNETES_VERSION_HA_SUPPORT), e);
}
}
if (clusterKubernetesVersion.getZoneId() != null && clusterKubernetesVersion.getZoneId() != zone.getId()) {
throw new InvalidParameterValueException(String.format("Kubernetes version ID: %s is not available for zone ID: %s", clusterKubernetesVersion.getUuid(), zone.getUuid()));
}
VMTemplateVO iso = templateDao.findById(clusterKubernetesVersion.getIsoId());
if (iso == null) {
throw new InvalidParameterValueException(String.format("Invalid ISO associated with version ID: %s", clusterKubernetesVersion.getUuid()));
}
if (CollectionUtils.isEmpty(templateJoinDao.newTemplateView(iso, zone.getId(), true))) {
throw new InvalidParameterValueException(String.format("ISO associated with version ID: %s is not in Ready state for datacenter ID: %s", clusterKubernetesVersion.getUuid(), zone.getUuid()));
}
ServiceOffering serviceOffering = serviceOfferingDao.findById(serviceOfferingId);
if (serviceOffering == null) {
throw new InvalidParameterValueException("No service offering with ID: " + serviceOfferingId);
}
if (sshKeyPair != null && !sshKeyPair.isEmpty()) {
SSHKeyPairVO sshKeyPairVO = sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), sshKeyPair);
if (sshKeyPairVO == null) {
throw new InvalidParameterValueException(String.format("Given SSH key pair with name: %s was not found for the account %s", sshKeyPair, owner.getAccountName()));
}
}
if (nodeRootDiskSize != null && nodeRootDiskSize <= 0) {
throw new InvalidParameterValueException(String.format("Invalid value for %s", ApiConstants.NODE_ROOT_DISK_SIZE));
}
if (!validateServiceOffering(serviceOffering, clusterKubernetesVersion)) {
throw new InvalidParameterValueException("Given service offering ID: %s is not suitable for Kubernetes cluster");
}
validateDockerRegistryParams(dockerRegistryUserName, dockerRegistryPassword, dockerRegistryUrl);
Network network = null;
if (networkId != null) {
network = networkService.getNetwork(networkId);
if (network == null) {
throw new InvalidParameterValueException("Unable to find network with given ID");
}
}
if (StringUtils.isNotEmpty(externalLoadBalancerIpAddress)) {
if (!NetUtils.isValidIp4(externalLoadBalancerIpAddress) && !NetUtils.isValidIp6(externalLoadBalancerIpAddress)) {
throw new InvalidParameterValueException("Invalid external load balancer IP address");
}
if (network == null) {
throw new InvalidParameterValueException(String.format("%s parameter must be specified along with %s parameter", ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, ApiConstants.NETWORK_ID));
}
if (Network.GuestType.Shared.equals(network.getGuestType())) {
throw new InvalidParameterValueException(String.format("%s parameter must be specified along with %s type of network", ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, Network.GuestType.Shared.toString()));
}
}
if (!KubernetesClusterExperimentalFeaturesEnabled.value() && !StringUtils.isAllEmpty(dockerRegistryUrl, dockerRegistryUserName, dockerRegistryPassword)) {
throw new CloudRuntimeException(String.format("Private registry for the Kubernetes cluster is an experimental feature. Use %s configuration for enabling experimental features", KubernetesClusterExperimentalFeaturesEnabled.key()));
}
}
use of com.cloud.kubernetes.version.KubernetesSupportedVersion in project cloudstack by apache.
the class KubernetesClusterActionWorker method attachIsoKubernetesVMs.
protected void attachIsoKubernetesVMs(List<UserVm> clusterVMs, final KubernetesSupportedVersion kubernetesSupportedVersion) throws CloudRuntimeException {
KubernetesSupportedVersion version = kubernetesSupportedVersion;
if (kubernetesSupportedVersion == null) {
version = kubernetesSupportedVersionDao.findById(kubernetesCluster.getKubernetesVersionId());
}
KubernetesCluster.Event failedEvent = KubernetesCluster.Event.OperationFailed;
KubernetesCluster cluster = kubernetesClusterDao.findById(kubernetesCluster.getId());
if (cluster != null && cluster.getState() == KubernetesCluster.State.Starting) {
failedEvent = KubernetesCluster.Event.CreateFailed;
}
if (version == null) {
logTransitStateAndThrow(Level.ERROR, String.format("Unable to find Kubernetes version for cluster : %s", kubernetesCluster.getName()), kubernetesCluster.getId(), failedEvent);
}
VMTemplateVO iso = templateDao.findById(version.getIsoId());
if (iso == null) {
logTransitStateAndThrow(Level.ERROR, String.format("Unable to attach ISO to Kubernetes cluster : %s. Binaries ISO not found.", kubernetesCluster.getName()), kubernetesCluster.getId(), failedEvent);
}
if (!iso.getFormat().equals(Storage.ImageFormat.ISO)) {
logTransitStateAndThrow(Level.ERROR, String.format("Unable to attach ISO to Kubernetes cluster : %s. Invalid Binaries ISO.", kubernetesCluster.getName()), kubernetesCluster.getId(), failedEvent);
}
if (!iso.getState().equals(VirtualMachineTemplate.State.Active)) {
logTransitStateAndThrow(Level.ERROR, String.format("Unable to attach ISO to Kubernetes cluster : %s. Binaries ISO not active.", kubernetesCluster.getName()), kubernetesCluster.getId(), failedEvent);
}
for (UserVm vm : clusterVMs) {
try {
templateService.attachIso(iso.getId(), vm.getId(), true);
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Attached binaries ISO for VM : %s in cluster: %s", vm.getDisplayName(), kubernetesCluster.getName()));
}
} 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);
}
}
}
use of com.cloud.kubernetes.version.KubernetesSupportedVersion 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()));
}
}
}
}
use of com.cloud.kubernetes.version.KubernetesSupportedVersion in project cloudstack by apache.
the class DeleteKubernetesSupportedVersionCmd method getEventDescription.
@Override
public String getEventDescription() {
String description = "Deleting Kubernetes supported version";
KubernetesSupportedVersion version = _entityMgr.findById(KubernetesSupportedVersion.class, getId());
if (version != null) {
description += String.format(" ID: %s", version.getUuid());
} else {
description += String.format(" ID: %d", getId());
}
return description;
}
Aggregations