mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.19' into 4.20
This commit is contained in:
commit
dd84c74e82
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,11 @@ All notable changes to Linstor CloudStack plugin will be documented in this file
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [2025-05-07]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Implemented storage/volume stats
|
||||||
|
|
||||||
## [2025-03-13]
|
## [2025-03-13]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@ -28,11 +28,11 @@ import com.linbit.linstor.api.model.ResourceDefinition;
|
|||||||
import com.linbit.linstor.api.model.ResourceDefinitionCloneRequest;
|
import com.linbit.linstor.api.model.ResourceDefinitionCloneRequest;
|
||||||
import com.linbit.linstor.api.model.ResourceDefinitionCloneStarted;
|
import com.linbit.linstor.api.model.ResourceDefinitionCloneStarted;
|
||||||
import com.linbit.linstor.api.model.ResourceDefinitionCreate;
|
import com.linbit.linstor.api.model.ResourceDefinitionCreate;
|
||||||
|
|
||||||
import com.linbit.linstor.api.model.ResourceDefinitionModify;
|
import com.linbit.linstor.api.model.ResourceDefinitionModify;
|
||||||
import com.linbit.linstor.api.model.ResourceGroup;
|
import com.linbit.linstor.api.model.ResourceGroup;
|
||||||
import com.linbit.linstor.api.model.ResourceGroupSpawn;
|
import com.linbit.linstor.api.model.ResourceGroupSpawn;
|
||||||
import com.linbit.linstor.api.model.ResourceMakeAvailable;
|
import com.linbit.linstor.api.model.ResourceMakeAvailable;
|
||||||
|
import com.linbit.linstor.api.model.ResourceWithVolumes;
|
||||||
import com.linbit.linstor.api.model.Snapshot;
|
import com.linbit.linstor.api.model.Snapshot;
|
||||||
import com.linbit.linstor.api.model.SnapshotRestore;
|
import com.linbit.linstor.api.model.SnapshotRestore;
|
||||||
import com.linbit.linstor.api.model.VolumeDefinition;
|
import com.linbit.linstor.api.model.VolumeDefinition;
|
||||||
@ -134,6 +134,9 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
@Inject
|
@Inject
|
||||||
private HostDao _hostDao;
|
private HostDao _hostDao;
|
||||||
|
|
||||||
|
private long volumeStatsLastUpdate = 0L;
|
||||||
|
private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>();
|
||||||
|
|
||||||
public LinstorPrimaryDataStoreDriverImpl()
|
public LinstorPrimaryDataStoreDriverImpl()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -403,9 +406,9 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRscGrp(StoragePoolVO storagePoolVO) {
|
private String getRscGrp(StoragePool storagePool) {
|
||||||
return storagePoolVO.getUserInfo() != null && !storagePoolVO.getUserInfo().isEmpty() ?
|
return storagePool.getUserInfo() != null && !storagePool.getUserInfo().isEmpty() ?
|
||||||
storagePoolVO.getUserInfo() : "DfltRscGrp";
|
storagePool.getUserInfo() : "DfltRscGrp";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -618,7 +621,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
*/
|
*/
|
||||||
private void updateRscGrpIfNecessary(DevelopersApi api, String rscName, String tgtRscGrp) throws ApiException {
|
private void updateRscGrpIfNecessary(DevelopersApi api, String rscName, String tgtRscGrp) throws ApiException {
|
||||||
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(
|
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(
|
||||||
Collections.singletonList(rscName), null, null, null);
|
Collections.singletonList(rscName), false, null, null, null);
|
||||||
if (rscDfns != null && !rscDfns.isEmpty()) {
|
if (rscDfns != null && !rscDfns.isEmpty()) {
|
||||||
ResourceDefinition rscDfn = rscDfns.get(0);
|
ResourceDefinition rscDfn = rscDfns.get(0);
|
||||||
|
|
||||||
@ -648,7 +651,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
private void deleteTemplateForProps(
|
private void deleteTemplateForProps(
|
||||||
DevelopersApi api, String rscName) throws ApiException {
|
DevelopersApi api, String rscName) throws ApiException {
|
||||||
List<ResourceDefinition> rdList = api.resourceDefinitionList(
|
List<ResourceDefinition> rdList = api.resourceDefinitionList(
|
||||||
Collections.singletonList(rscName), null, null, null);
|
Collections.singletonList(rscName), false, null, null, null);
|
||||||
|
|
||||||
if (CollectionUtils.isNotEmpty(rdList)) {
|
if (CollectionUtils.isNotEmpty(rdList)) {
|
||||||
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||||
@ -1506,22 +1509,77 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canProvideStorageStats() {
|
public boolean canProvideStorageStats() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<Long, Long> getStorageStats(StoragePool storagePool) {
|
public Pair<Long, Long> getStorageStats(StoragePool storagePool) {
|
||||||
return null;
|
logger.debug(String.format("Requesting storage stats: %s", storagePool));
|
||||||
|
return LinstorUtil.getStorageStats(storagePool.getHostAddress(), getRscGrp(storagePool));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canProvideVolumeStats() {
|
public boolean canProvideVolumeStats() {
|
||||||
return false;
|
return LinstorConfigurationManager.VolumeStatsCacheTime.value() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the cache map containing current allocated size data.
|
||||||
|
* @param api Linstor Developers api object
|
||||||
|
*/
|
||||||
|
private void fillVolumeStatsCache(DevelopersApi api) {
|
||||||
|
try {
|
||||||
|
logger.trace("Start volume stats cache update");
|
||||||
|
List<ResourceWithVolumes> resources = api.viewResources(
|
||||||
|
Collections.emptyList(),
|
||||||
|
Collections.emptyList(),
|
||||||
|
Collections.emptyList(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
|
||||||
|
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(
|
||||||
|
Collections.emptyList(), true, null, null, null);
|
||||||
|
|
||||||
|
HashMap<String, Long> resSizeMap = new HashMap<>();
|
||||||
|
for (ResourceDefinition rscDfn : rscDfns) {
|
||||||
|
if (CollectionUtils.isNotEmpty(rscDfn.getVolumeDefinitions())) {
|
||||||
|
resSizeMap.put(rscDfn.getName(), rscDfn.getVolumeDefinitions().get(0).getSizeKib() * 1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<String, Long> allocSizeMap = new HashMap<>();
|
||||||
|
for (ResourceWithVolumes rsc : resources) {
|
||||||
|
if (!LinstorUtil.isRscDiskless(rsc) && !rsc.getVolumes().isEmpty()) {
|
||||||
|
long allocatedBytes = allocSizeMap.getOrDefault(rsc.getName(), 0L);
|
||||||
|
allocSizeMap.put(rsc.getName(), Math.max(allocatedBytes, rsc.getVolumes().get(0).getAllocatedSizeKib() * 1024));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
volumeStats.clear();
|
||||||
|
for (Map.Entry<String, Long> entry : allocSizeMap.entrySet()) {
|
||||||
|
Long reserved = resSizeMap.getOrDefault(entry.getKey(), 0L);
|
||||||
|
Pair<Long, Long> volStat = new Pair<>(entry.getValue(), reserved);
|
||||||
|
volumeStats.put(entry.getKey(), volStat);
|
||||||
|
}
|
||||||
|
volumeStatsLastUpdate = System.currentTimeMillis();
|
||||||
|
logger.trace("Done volume stats cache update: {}", volumeStats.size());
|
||||||
|
} catch (ApiException e) {
|
||||||
|
logger.error("Unable to fetch Linstor resources: {}", e.getBestMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<Long, Long> getVolumeStats(StoragePool storagePool, String volumeId) {
|
public Pair<Long, Long> getVolumeStats(StoragePool storagePool, String volumeId) {
|
||||||
return null;
|
final DevelopersApi api = LinstorUtil.getLinstorAPI(storagePool.getHostAddress());
|
||||||
|
synchronized (volumeStats) {
|
||||||
|
long invalidateCacheTime = volumeStatsLastUpdate +
|
||||||
|
LinstorConfigurationManager.VolumeStatsCacheTime.value() * 1000;
|
||||||
|
if (invalidateCacheTime < System.currentTimeMillis()) {
|
||||||
|
fillVolumeStatsCache(api);
|
||||||
|
}
|
||||||
|
return volumeStats.get(LinstorUtil.RSC_PREFIX + volumeId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -24,7 +24,14 @@ public class LinstorConfigurationManager implements Configurable
|
|||||||
public static final ConfigKey<Boolean> BackupSnapshots = new ConfigKey<>(Boolean.class, "lin.backup.snapshots", "Advanced", "true",
|
public static final ConfigKey<Boolean> BackupSnapshots = new ConfigKey<>(Boolean.class, "lin.backup.snapshots", "Advanced", "true",
|
||||||
"Backup Linstor primary storage snapshots to secondary storage (deleting ps snapshot)", true, ConfigKey.Scope.Global, null);
|
"Backup Linstor primary storage snapshots to secondary storage (deleting ps snapshot)", true, ConfigKey.Scope.Global, null);
|
||||||
|
|
||||||
public static final ConfigKey<?>[] CONFIG_KEYS = new ConfigKey<?>[] { BackupSnapshots };
|
public static final ConfigKey<Integer> VolumeStatsCacheTime = new ConfigKey<>("Advanced", Integer.class,
|
||||||
|
"lin.volumes.stats.cachetime", "300",
|
||||||
|
"Cache time of volume stats for Linstor volumes. 0 to disable volume stats",
|
||||||
|
false);
|
||||||
|
|
||||||
|
public static final ConfigKey<?>[] CONFIG_KEYS = new ConfigKey<?>[] {
|
||||||
|
BackupSnapshots, VolumeStatsCacheTime
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getConfigComponentName()
|
public String getConfigComponentName()
|
||||||
|
|||||||
@ -196,6 +196,30 @@ public class LinstorUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Pair<Long, Long> getStorageStats(String linstorUrl, String rscGroupName) {
|
||||||
|
DevelopersApi linstorApi = getLinstorAPI(linstorUrl);
|
||||||
|
try {
|
||||||
|
List<StoragePool> storagePools = LinstorUtil.getRscGroupStoragePools(linstorApi, rscGroupName);
|
||||||
|
|
||||||
|
long capacity = storagePools.stream()
|
||||||
|
.filter(sp -> sp.getProviderKind() != ProviderKind.DISKLESS)
|
||||||
|
.mapToLong(sp -> sp.getTotalCapacity() != null ? sp.getTotalCapacity() : 0L)
|
||||||
|
.sum() * 1024; // linstor uses kiB
|
||||||
|
|
||||||
|
long used = storagePools.stream()
|
||||||
|
.filter(sp -> sp.getProviderKind() != ProviderKind.DISKLESS)
|
||||||
|
.mapToLong(sp -> sp.getTotalCapacity() != null && sp.getFreeCapacity() != null ?
|
||||||
|
sp.getTotalCapacity() - sp.getFreeCapacity() : 0L)
|
||||||
|
.sum() * 1024; // linstor uses Kib
|
||||||
|
LOGGER.debug(
|
||||||
|
String.format("Linstor(%s;%s): storageStats -> %d/%d", linstorUrl, rscGroupName, capacity, used));
|
||||||
|
return new Pair<>(capacity, used);
|
||||||
|
} catch (ApiException apiEx) {
|
||||||
|
LOGGER.error(apiEx.getMessage());
|
||||||
|
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if any resource of the given name is InUse on any host.
|
* Check if any resource of the given name is InUse on any host.
|
||||||
*
|
*
|
||||||
@ -304,7 +328,7 @@ public class LinstorUtil {
|
|||||||
public static List<ResourceDefinition> getRDListStartingWith(DevelopersApi api, String startWith)
|
public static List<ResourceDefinition> getRDListStartingWith(DevelopersApi api, String startWith)
|
||||||
throws ApiException
|
throws ApiException
|
||||||
{
|
{
|
||||||
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(null, null, null, null);
|
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(null, false, null, null, null);
|
||||||
|
|
||||||
return rscDfns.stream()
|
return rscDfns.stream()
|
||||||
.filter(rscDfn -> rscDfn.getName().toLowerCase().startsWith(startWith.toLowerCase()))
|
.filter(rscDfn -> rscDfn.getName().toLowerCase().startsWith(startWith.toLowerCase()))
|
||||||
@ -387,7 +411,7 @@ public class LinstorUtil {
|
|||||||
*/
|
*/
|
||||||
public static ResourceDefinition findResourceDefinition(DevelopersApi api, String rscName, String rscGrpName)
|
public static ResourceDefinition findResourceDefinition(DevelopersApi api, String rscName, String rscGrpName)
|
||||||
throws ApiException {
|
throws ApiException {
|
||||||
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(null, null, null, null);
|
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(null, false, null, null, null);
|
||||||
|
|
||||||
List<ResourceDefinition> rdsStartingWith = rscDfns.stream()
|
List<ResourceDefinition> rdsStartingWith = rscDfns.stream()
|
||||||
.filter(rscDfn -> rscDfn.getName().toLowerCase().startsWith(rscName.toLowerCase()))
|
.filter(rscDfn -> rscDfn.getName().toLowerCase().startsWith(rscName.toLowerCase()))
|
||||||
@ -403,4 +427,8 @@ public class LinstorUtil {
|
|||||||
|
|
||||||
return rd.orElseGet(() -> rdsStartingWith.get(0));
|
return rd.orElseGet(() -> rdsStartingWith.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isRscDiskless(ResourceWithVolumes rsc) {
|
||||||
|
return rsc.getFlags() != null && rsc.getFlags().contains(ApiConsts.FLAG_DISKLESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@ -175,7 +175,7 @@
|
|||||||
<cs.nitro.version>10.1</cs.nitro.version>
|
<cs.nitro.version>10.1</cs.nitro.version>
|
||||||
<cs.opensaml.version>2.6.6</cs.opensaml.version>
|
<cs.opensaml.version>2.6.6</cs.opensaml.version>
|
||||||
<cs.rados-java.version>0.6.0</cs.rados-java.version>
|
<cs.rados-java.version>0.6.0</cs.rados-java.version>
|
||||||
<cs.java-linstor.version>0.6.0</cs.java-linstor.version>
|
<cs.java-linstor.version>0.6.1</cs.java-linstor.version>
|
||||||
<cs.reflections.version>0.10.2</cs.reflections.version>
|
<cs.reflections.version>0.10.2</cs.reflections.version>
|
||||||
<cs.servicemix.version>3.4.4_1</cs.servicemix.version>
|
<cs.servicemix.version>3.4.4_1</cs.servicemix.version>
|
||||||
<cs.servlet.version>4.0.1</cs.servlet.version>
|
<cs.servlet.version>4.0.1</cs.servlet.version>
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package com.cloud.alert;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -88,41 +89,55 @@ import com.cloud.utils.Pair;
|
|||||||
import com.cloud.utils.component.ManagerBase;
|
import com.cloud.utils.component.ManagerBase;
|
||||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable {
|
public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable {
|
||||||
protected Logger logger = LogManager.getLogger(AlertManagerImpl.class.getName());
|
protected Logger logger = LogManager.getLogger(AlertManagerImpl.class.getName());
|
||||||
|
|
||||||
|
public static final List<AlertType> ALERTS = Arrays.asList(AlertType.ALERT_TYPE_HOST
|
||||||
|
, AlertType.ALERT_TYPE_USERVM
|
||||||
|
, AlertType.ALERT_TYPE_DOMAIN_ROUTER
|
||||||
|
, AlertType.ALERT_TYPE_CONSOLE_PROXY
|
||||||
|
, AlertType.ALERT_TYPE_SSVM
|
||||||
|
, AlertType.ALERT_TYPE_STORAGE_MISC
|
||||||
|
, AlertType.ALERT_TYPE_MANAGEMENT_NODE
|
||||||
|
, AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED
|
||||||
|
, AlertType.ALERT_TYPE_UPLOAD_FAILED
|
||||||
|
, AlertType.ALERT_TYPE_OOBM_AUTH_ERROR
|
||||||
|
, AlertType.ALERT_TYPE_HA_ACTION
|
||||||
|
, AlertType.ALERT_TYPE_CA_CERT);
|
||||||
|
|
||||||
private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds.
|
private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds.
|
||||||
|
|
||||||
private static final DecimalFormat DfPct = new DecimalFormat("###.##");
|
private static final DecimalFormat DfPct = new DecimalFormat("###.##");
|
||||||
private static final DecimalFormat DfWhole = new DecimalFormat("########");
|
private static final DecimalFormat DfWhole = new DecimalFormat("########");
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AlertDao _alertDao;
|
AlertDao _alertDao;
|
||||||
@Inject
|
@Inject
|
||||||
protected StorageManager _storageMgr;
|
protected StorageManager _storageMgr;
|
||||||
@Inject
|
@Inject
|
||||||
protected CapacityManager _capacityMgr;
|
protected CapacityManager _capacityMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private CapacityDao _capacityDao;
|
CapacityDao _capacityDao;
|
||||||
@Inject
|
@Inject
|
||||||
private DataCenterDao _dcDao;
|
DataCenterDao _dcDao;
|
||||||
@Inject
|
@Inject
|
||||||
private HostPodDao _podDao;
|
HostPodDao _podDao;
|
||||||
@Inject
|
@Inject
|
||||||
private ClusterDao _clusterDao;
|
ClusterDao _clusterDao;
|
||||||
@Inject
|
@Inject
|
||||||
private IPAddressDao _publicIPAddressDao;
|
IPAddressDao _publicIPAddressDao;
|
||||||
@Inject
|
@Inject
|
||||||
private DataCenterIpAddressDao _privateIPAddressDao;
|
DataCenterIpAddressDao _privateIPAddressDao;
|
||||||
@Inject
|
@Inject
|
||||||
private PrimaryDataStoreDao _storagePoolDao;
|
PrimaryDataStoreDao _storagePoolDao;
|
||||||
@Inject
|
@Inject
|
||||||
private ConfigurationDao _configDao;
|
ConfigurationDao _configDao;
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceManager _resourceMgr;
|
ResourceManager _resourceMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private ConfigurationManager _configMgr;
|
ConfigurationManager _configMgr;
|
||||||
@Inject
|
@Inject
|
||||||
protected ConfigDepot _configDepot;
|
protected ConfigDepot _configDepot;
|
||||||
@Inject
|
@Inject
|
||||||
@ -138,7 +153,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
private double _vlanCapacityThreshold = 0.75;
|
private double _vlanCapacityThreshold = 0.75;
|
||||||
private double _directNetworkPublicIpCapacityThreshold = 0.75;
|
private double _directNetworkPublicIpCapacityThreshold = 0.75;
|
||||||
private double _localStorageCapacityThreshold = 0.75;
|
private double _localStorageCapacityThreshold = 0.75;
|
||||||
Map<Short, Double> _capacityTypeThresholdMap = new HashMap<Short, Double>();
|
Map<Short, Double> _capacityTypeThresholdMap = new HashMap<>();
|
||||||
|
|
||||||
private final ExecutorService _executor;
|
private final ExecutorService _executor;
|
||||||
|
|
||||||
@ -402,18 +417,15 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
private void createOrUpdateVlanCapacity(long dcId, AllocationState capacityState) {
|
private void createOrUpdateVlanCapacity(long dcId, AllocationState capacityState) {
|
||||||
|
|
||||||
SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
|
SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
|
||||||
|
|
||||||
List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
|
|
||||||
capacitySC = _capacityDao.createSearchCriteria();
|
|
||||||
capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
|
capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
|
||||||
capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_VLAN);
|
capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_VLAN);
|
||||||
capacities = _capacityDao.search(capacitySC, null);
|
List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
|
||||||
|
|
||||||
int totalVlans = _dcDao.countZoneVlans(dcId, false);
|
int totalVlans = _dcDao.countZoneVlans(dcId, false);
|
||||||
int allocatedVlans = _dcDao.countZoneVlans(dcId, true);
|
int allocatedVlans = _dcDao.countZoneVlans(dcId, true);
|
||||||
|
|
||||||
CapacityState vlanCapacityState = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
|
CapacityState vlanCapacityState = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
|
||||||
if (capacities.size() == 0) {
|
if (capacities.isEmpty()) {
|
||||||
CapacityVO newVlanCapacity = new CapacityVO(null, dcId, null, null, allocatedVlans, totalVlans, Capacity.CAPACITY_TYPE_VLAN);
|
CapacityVO newVlanCapacity = new CapacityVO(null, dcId, null, null, allocatedVlans, totalVlans, Capacity.CAPACITY_TYPE_VLAN);
|
||||||
newVlanCapacity.setCapacityState(vlanCapacityState);
|
newVlanCapacity.setCapacityState(vlanCapacityState);
|
||||||
_capacityDao.persist(newVlanCapacity);
|
_capacityDao.persist(newVlanCapacity);
|
||||||
@ -430,16 +442,13 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
|
|
||||||
public void createOrUpdateIpCapacity(Long dcId, Long podId, short capacityType, AllocationState capacityState) {
|
public void createOrUpdateIpCapacity(Long dcId, Long podId, short capacityType, AllocationState capacityState) {
|
||||||
SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
|
SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
|
||||||
|
|
||||||
List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
|
|
||||||
capacitySC = _capacityDao.createSearchCriteria();
|
|
||||||
capacitySC.addAnd("podId", SearchCriteria.Op.EQ, podId);
|
capacitySC.addAnd("podId", SearchCriteria.Op.EQ, podId);
|
||||||
capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
|
capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
|
||||||
capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
|
capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
|
||||||
|
|
||||||
int totalIPs;
|
int totalIPs;
|
||||||
int allocatedIPs;
|
int allocatedIPs;
|
||||||
capacities = _capacityDao.search(capacitySC, null);
|
List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
|
||||||
if (capacityType == Capacity.CAPACITY_TYPE_PRIVATE_IP) {
|
if (capacityType == Capacity.CAPACITY_TYPE_PRIVATE_IP) {
|
||||||
totalIPs = _privateIPAddressDao.countIPs(podId, dcId, false);
|
totalIPs = _privateIPAddressDao.countIPs(podId, dcId, false);
|
||||||
allocatedIPs = _privateIPAddressDao.countIPs(podId, dcId, true);
|
allocatedIPs = _privateIPAddressDao.countIPs(podId, dcId, true);
|
||||||
@ -452,7 +461,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
}
|
}
|
||||||
|
|
||||||
CapacityState ipCapacityState = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
|
CapacityState ipCapacityState = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
|
||||||
if (capacities.size() == 0) {
|
if (capacities.isEmpty()) {
|
||||||
CapacityVO newPublicIPCapacity = new CapacityVO(null, dcId, podId, null, allocatedIPs, totalIPs, capacityType);
|
CapacityVO newPublicIPCapacity = new CapacityVO(null, dcId, podId, null, allocatedIPs, totalIPs, capacityType);
|
||||||
newPublicIPCapacity.setCapacityState(ipCapacityState);
|
newPublicIPCapacity.setCapacityState(ipCapacityState);
|
||||||
_capacityDao.persist(newPublicIPCapacity);
|
_capacityDao.persist(newPublicIPCapacity);
|
||||||
@ -477,7 +486,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
int total = usedTotal.second();
|
int total = usedTotal.second();
|
||||||
int allocated = usedTotal.first();
|
int allocated = usedTotal.first();
|
||||||
CapacityState state = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
|
CapacityState state = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
|
||||||
if (capacities.size() == 0) {
|
if (capacities.isEmpty()) {
|
||||||
CapacityVO capacityVO = new CapacityVO(null, dcId, null, null, allocated, total, capacityType);
|
CapacityVO capacityVO = new CapacityVO(null, dcId, null, null, allocated, total, capacityType);
|
||||||
capacityVO.setCapacityState(state);
|
capacityVO.setCapacityState(state);
|
||||||
_capacityDao.persist(capacityVO);
|
_capacityDao.persist(capacityVO);
|
||||||
@ -524,13 +533,12 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
// Generate Alerts for Zone Level capacities
|
// Generate Alerts for Zone Level capacities
|
||||||
for (DataCenterVO dc : dataCenterList) {
|
for (DataCenterVO dc : dataCenterList) {
|
||||||
for (Short capacityType : dataCenterCapacityTypes) {
|
for (Short capacityType : dataCenterCapacityTypes) {
|
||||||
List<SummedCapacity> capacity = new ArrayList<SummedCapacity>();
|
List<SummedCapacity> capacity = _capacityDao.findCapacityBy(capacityType.intValue(), dc.getId(), null, null);
|
||||||
capacity = _capacityDao.findCapacityBy(capacityType.intValue(), dc.getId(), null, null);
|
|
||||||
|
|
||||||
if (capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
|
if (capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
|
||||||
capacity.add(getUsedStats(capacityType, dc.getId(), null, null));
|
capacity.add(getUsedStats(capacityType, dc.getId(), null, null));
|
||||||
}
|
}
|
||||||
if (capacity == null || capacity.size() == 0) {
|
if (capacity == null || capacity.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double totalCapacity = capacity.get(0).getTotalCapacity();
|
double totalCapacity = capacity.get(0).getTotalCapacity();
|
||||||
@ -545,7 +553,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
for (HostPodVO pod : podList) {
|
for (HostPodVO pod : podList) {
|
||||||
for (Short capacityType : podCapacityTypes) {
|
for (Short capacityType : podCapacityTypes) {
|
||||||
List<SummedCapacity> capacity = _capacityDao.findCapacityBy(capacityType.intValue(), pod.getDataCenterId(), pod.getId(), null);
|
List<SummedCapacity> capacity = _capacityDao.findCapacityBy(capacityType.intValue(), pod.getDataCenterId(), pod.getId(), null);
|
||||||
if (capacity == null || capacity.size() == 0) {
|
if (capacity == null || capacity.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double totalCapacity = capacity.get(0).getTotalCapacity();
|
double totalCapacity = capacity.get(0).getTotalCapacity();
|
||||||
@ -559,11 +567,10 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
// Generate Alerts for Cluster Level capacities
|
// Generate Alerts for Cluster Level capacities
|
||||||
for (ClusterVO cluster : clusterList) {
|
for (ClusterVO cluster : clusterList) {
|
||||||
for (Short capacityType : clusterCapacityTypes) {
|
for (Short capacityType : clusterCapacityTypes) {
|
||||||
List<SummedCapacity> capacity = new ArrayList<SummedCapacity>();
|
List<SummedCapacity> capacity = _capacityDao.findCapacityBy(capacityType.intValue(), cluster.getDataCenterId(), null, cluster.getId());
|
||||||
capacity = _capacityDao.findCapacityBy(capacityType.intValue(), cluster.getDataCenterId(), null, cluster.getId());
|
|
||||||
|
|
||||||
// cpu and memory allocated capacity notification threshold can be defined at cluster level, so getting the value if they are defined at cluster level
|
// cpu and memory allocated capacity notification threshold can be defined at cluster level, so getting the value if they are defined at cluster level
|
||||||
double threshold = 0;
|
double threshold;
|
||||||
switch (capacityType) {
|
switch (capacityType) {
|
||||||
case Capacity.CAPACITY_TYPE_STORAGE:
|
case Capacity.CAPACITY_TYPE_STORAGE:
|
||||||
capacity.add(getUsedStats(capacityType, cluster.getDataCenterId(), cluster.getPodId(), cluster.getId()));
|
capacity.add(getUsedStats(capacityType, cluster.getDataCenterId(), cluster.getPodId(), cluster.getId()));
|
||||||
@ -581,7 +588,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
default:
|
default:
|
||||||
threshold = _capacityTypeThresholdMap.get(capacityType);
|
threshold = _capacityTypeThresholdMap.get(capacityType);
|
||||||
}
|
}
|
||||||
if (capacity == null || capacity.size() == 0) {
|
if (capacity == null || capacity.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,7 +704,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
|
|
||||||
private List<Short> getCapacityTypesAtZoneLevel() {
|
private List<Short> getCapacityTypesAtZoneLevel() {
|
||||||
|
|
||||||
List<Short> dataCenterCapacityTypes = new ArrayList<Short>();
|
List<Short> dataCenterCapacityTypes = new ArrayList<>();
|
||||||
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP);
|
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP);
|
||||||
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP);
|
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP);
|
||||||
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
|
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
|
||||||
@ -709,7 +716,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
|
|
||||||
private List<Short> getCapacityTypesAtPodLevel() {
|
private List<Short> getCapacityTypesAtPodLevel() {
|
||||||
|
|
||||||
List<Short> podCapacityTypes = new ArrayList<Short>();
|
List<Short> podCapacityTypes = new ArrayList<>();
|
||||||
podCapacityTypes.add(Capacity.CAPACITY_TYPE_PRIVATE_IP);
|
podCapacityTypes.add(Capacity.CAPACITY_TYPE_PRIVATE_IP);
|
||||||
return podCapacityTypes;
|
return podCapacityTypes;
|
||||||
|
|
||||||
@ -717,7 +724,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
|
|
||||||
private List<Short> getCapacityTypesAtClusterLevel() {
|
private List<Short> getCapacityTypesAtClusterLevel() {
|
||||||
|
|
||||||
List<Short> clusterCapacityTypes = new ArrayList<Short>();
|
List<Short> clusterCapacityTypes = new ArrayList<>();
|
||||||
clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_CPU);
|
clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_CPU);
|
||||||
clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_MEMORY);
|
clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_MEMORY);
|
||||||
clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_STORAGE);
|
clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_STORAGE);
|
||||||
@ -748,19 +755,11 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
|
|
||||||
public void sendAlert(AlertType alertType, DataCenter dataCenter, Pod pod, Cluster cluster, String subject, String content)
|
public void sendAlert(AlertType alertType, DataCenter dataCenter, Pod pod, Cluster cluster, String subject, String content)
|
||||||
throws MessagingException, UnsupportedEncodingException {
|
throws MessagingException, UnsupportedEncodingException {
|
||||||
logger.warn(String.format("alertType=[%s] dataCenter=[%s] pod=[%s] cluster=[%s] message=[%s].", alertType, dataCenter, pod, cluster, subject));
|
|
||||||
AlertVO alert = null;
|
|
||||||
Long clusterId = cluster == null ? null : cluster.getId();
|
Long clusterId = cluster == null ? null : cluster.getId();
|
||||||
Long podId = pod == null ? null : pod.getId();
|
Long podId = pod == null ? null : pod.getId();
|
||||||
long dcId = dataCenter == null ? 0L : dataCenter.getId();
|
long dcId = dataCenter == null ? 0L : dataCenter.getId();
|
||||||
if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) && (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM)
|
logger.warn(String.format("alertType=[%s] dataCenterId=[%s] podId=[%s] clusterId=[%s] message=[%s].", alertType, dcId, podId, clusterId, subject));
|
||||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) && (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY)
|
AlertVO alert = getAlertForTrivialAlertType(alertType, dcId, podId, clusterId);
|
||||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) && (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC)
|
|
||||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGEMENT_NODE) && (alertType != AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED)
|
|
||||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED) && (alertType != AlertManager.AlertType.ALERT_TYPE_OOBM_AUTH_ERROR)
|
|
||||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_HA_ACTION) && (alertType != AlertManager.AlertType.ALERT_TYPE_CA_CERT)) {
|
|
||||||
alert = _alertDao.getLastAlert(alertType.getType(), dcId, podId, clusterId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alert == null) {
|
if (alert == null) {
|
||||||
AlertVO newAlert = new AlertVO();
|
AlertVO newAlert = new AlertVO();
|
||||||
@ -802,6 +801,15 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private AlertVO getAlertForTrivialAlertType(AlertType alertType, long dataCenterId, Long podId, Long clusterId) {
|
||||||
|
AlertVO alert = null;
|
||||||
|
if (!ALERTS.contains(alertType)) {
|
||||||
|
alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId);
|
||||||
|
}
|
||||||
|
return alert;
|
||||||
|
}
|
||||||
|
|
||||||
protected void sendMessage(SMTPMailProperties mailProps) {
|
protected void sendMessage(SMTPMailProperties mailProps) {
|
||||||
_executor.execute(new Runnable() {
|
_executor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -2909,6 +2909,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
Account callerAccount = _accountMgr.getActiveAccountById(user.getAccountId());
|
Account callerAccount = _accountMgr.getActiveAccountById(user.getAccountId());
|
||||||
_accountMgr.checkAccess(callerAccount, AccessType.OperateEntry, true, network);
|
_accountMgr.checkAccess(callerAccount, AccessType.OperateEntry, true, network);
|
||||||
if (!network.isRedundant() && makeRedundant) {
|
if (!network.isRedundant() && makeRedundant) {
|
||||||
|
NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
|
||||||
|
Map<Network.Capability, String> sourceNatCapabilities = getNetworkOfferingServiceCapabilities(networkOffering, Service.SourceNat);
|
||||||
|
String isRedundantRouterSupported = sourceNatCapabilities.get(Capability.RedundantRouter);
|
||||||
|
if (!Boolean.parseBoolean(isRedundantRouterSupported)) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Redundant router is not supported by the network offering %s", networkOffering));
|
||||||
|
}
|
||||||
network.setRedundant(true);
|
network.setRedundant(true);
|
||||||
if (!_networksDao.update(network.getId(), network)) {
|
if (!_networksDao.update(network.getId(), network)) {
|
||||||
throw new CloudRuntimeException("Failed to update network into a redundant one, please try again");
|
throw new CloudRuntimeException("Failed to update network into a redundant one, please try again");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user