mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Bug 12954: Added usage for security groups. Usage will be generated for each security group that is assigned to a Vm.
Status 12954: resolved fixed Reviewed-By: Nitin
This commit is contained in:
parent
61603335b2
commit
ced6fd46b8
@ -184,6 +184,8 @@ public class EventTypes {
|
||||
public static final String EVENT_SECURITY_GROUP_REVOKE_EGRESS = "SG.REVOKE.EGRESS";
|
||||
public static final String EVENT_SECURITY_GROUP_CREATE = "SG.CREATE";
|
||||
public static final String EVENT_SECURITY_GROUP_DELETE = "SG.DELETE";
|
||||
public static final String EVENT_SECURITY_GROUP_ASSIGN = "SG.ASSIGN";
|
||||
public static final String EVENT_SECURITY_GROUP_REMOVE = "SG.REMOVE";
|
||||
|
||||
// Host
|
||||
public static final String EVENT_HOST_RECONNECT = "HOST.RECONNECT";
|
||||
|
||||
@ -116,6 +116,16 @@ public class UsageEventVO implements UsageEvent {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
//Security Group usage event
|
||||
public UsageEventVO(String usageType, long accountId,
|
||||
long zoneId, long vmId, long securityGroupId) {
|
||||
this.type = usageType;
|
||||
this.accountId = accountId;
|
||||
this.zoneId = zoneId;
|
||||
this.resourceId = vmId;
|
||||
this.offeringId = securityGroupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
|
||||
@ -318,6 +318,10 @@ public class GetUsageRecordsCmd extends BaseListCmd {
|
||||
} else if(usageRecord.getUsageType() == UsageTypes.VPN_USERS){
|
||||
//VPN User ID
|
||||
usageRecResponse.setUsageId(usageRecord.getUsageId().toString());
|
||||
|
||||
} else if(usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP){
|
||||
//Security Group Id
|
||||
usageRecResponse.setUsageId(identityDao.getIdentityUuid("security_group", usageRecord.getUsageId().toString()));
|
||||
}
|
||||
|
||||
if (usageRecord.getRawUsage() != null) {
|
||||
|
||||
@ -57,6 +57,8 @@ import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.UsageEventVO;
|
||||
import com.cloud.event.dao.UsageEventDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
@ -152,7 +154,9 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
DomainManager _domainMgr;
|
||||
@Inject
|
||||
ProjectManager _projectMgr;
|
||||
|
||||
@Inject
|
||||
UsageEventDao _usageEventDao;
|
||||
|
||||
ScheduledExecutorService _executorPool;
|
||||
ScheduledExecutorService _cleanupExecutor;
|
||||
|
||||
@ -449,6 +453,10 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
List<SecurityGroupVMMapVO> groupsForVm = _securityGroupVMMapDao.listByInstanceId(vm.getId());
|
||||
// For each group, find the security rules that allow the group
|
||||
for (SecurityGroupVMMapVO mapVO : groupsForVm) {// FIXME: use custom sql in the dao
|
||||
//Add usage events for security group assign
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SECURITY_GROUP_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), mapVO.getSecurityGroupId());
|
||||
_usageEventDao.persist(usageEvent);
|
||||
|
||||
List<SecurityGroupRuleVO> allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId());
|
||||
// For each security rule that allows a group that the vm belongs to, find the group it belongs to
|
||||
affectedVms.addAll(getAffectedVmsForSecurityRules(allowingRules));
|
||||
@ -461,6 +469,10 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
List<SecurityGroupVMMapVO> groupsForVm = _securityGroupVMMapDao.listByInstanceId(vm.getId());
|
||||
// For each group, find the security rules rules that allow the group
|
||||
for (SecurityGroupVMMapVO mapVO : groupsForVm) {// FIXME: use custom sql in the dao
|
||||
//Add usage events for security group remove
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SECURITY_GROUP_REMOVE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), mapVO.getSecurityGroupId());
|
||||
_usageEventDao.persist(usageEvent);
|
||||
|
||||
List<SecurityGroupRuleVO> allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId());
|
||||
// For each security rule that allows a group that the vm belongs to, find the group it belongs to
|
||||
affectedVms.addAll(getAffectedVmsForSecurityRules(allowingRules));
|
||||
|
||||
100
server/src/com/cloud/usage/UsageSecurityGroupVO.java
Normal file
100
server/src/com/cloud/usage/UsageSecurityGroupVO.java
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* * Copyright (C) 2012 Citrix Systems, Inc. All rights reserved
|
||||
*
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.usage;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
@Entity
|
||||
@Table(name="usage_security_group")
|
||||
public class UsageSecurityGroupVO {
|
||||
|
||||
@Column(name="zone_id")
|
||||
private long zoneId;
|
||||
|
||||
@Column(name="account_id")
|
||||
private long accountId;
|
||||
|
||||
@Column(name="domain_id")
|
||||
private long domainId;
|
||||
|
||||
@Column(name="vm_instance_id")
|
||||
private long vmInstanceId;
|
||||
|
||||
@Column(name="security_group_id")
|
||||
private Long securityGroupId;
|
||||
|
||||
@Column(name="created")
|
||||
@Temporal(value=TemporalType.TIMESTAMP)
|
||||
private Date created = null;
|
||||
|
||||
@Column(name="deleted")
|
||||
@Temporal(value=TemporalType.TIMESTAMP)
|
||||
private Date deleted = null;
|
||||
|
||||
public UsageSecurityGroupVO(){
|
||||
}
|
||||
|
||||
public UsageSecurityGroupVO(long zoneId, long accountId, long domainId, long vmInstanceId, long securityGroupId, Date created, Date deleted) {
|
||||
this.zoneId = zoneId;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.vmInstanceId = vmInstanceId;
|
||||
this.securityGroupId = securityGroupId;
|
||||
this.created = created;
|
||||
this.deleted = deleted;
|
||||
}
|
||||
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public long getVmInstanceId() {
|
||||
return vmInstanceId;
|
||||
}
|
||||
|
||||
public Long getSecurityGroupId() {
|
||||
return securityGroupId;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public Date getDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
public void setDeleted(Date deleted) {
|
||||
this.deleted = deleted;
|
||||
}
|
||||
}
|
||||
31
server/src/com/cloud/usage/dao/UsageSecurityGroupDao.java
Normal file
31
server/src/com/cloud/usage/dao/UsageSecurityGroupDao.java
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* * Copyright (C) 2012 Citrix Systems, Inc. All rights reserved
|
||||
*
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.usage.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.usage.UsageSecurityGroupVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface UsageSecurityGroupDao extends GenericDao<UsageSecurityGroupVO, Long> {
|
||||
public void update(UsageSecurityGroupVO usage);
|
||||
public List<UsageSecurityGroupVO> getUsageRecords(Long accountId, Long domainId, Date startDate, Date endDate, boolean limit, int page);
|
||||
}
|
||||
152
server/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java
Normal file
152
server/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java
Normal file
@ -0,0 +1,152 @@
|
||||
/**
|
||||
* * Copyright (C) 2012 Citrix Systems, Inc. All rights reserved
|
||||
*
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.usage.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.usage.UsageSecurityGroupVO;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
|
||||
@Local(value={UsageSecurityGroupDao.class})
|
||||
public class UsageSecurityGroupDaoImpl extends GenericDaoBase<UsageSecurityGroupVO, Long> implements UsageSecurityGroupDao {
|
||||
public static final Logger s_logger = Logger.getLogger(UsageSecurityGroupDaoImpl.class.getName());
|
||||
|
||||
protected static final String UPDATE_DELETED = "UPDATE usage_security_group SET deleted = ? WHERE account_id = ? AND vm_instance_id = ? AND security_group_id = ? and deleted IS NULL";
|
||||
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT zone_id, account_id, domain_id, vm_instance_id, security_group_id, created, deleted " +
|
||||
"FROM usage_security_group " +
|
||||
"WHERE account_id = ? AND ((deleted IS NULL) OR (created BETWEEN ? AND ?) OR " +
|
||||
" (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?)))";
|
||||
protected static final String GET_USAGE_RECORDS_BY_DOMAIN = "SELECT zone_id, account_id, domain_id, vm_instance_id, security_group_id, created, deleted " +
|
||||
"FROM usage_security_group " +
|
||||
"WHERE domain_id = ? AND ((deleted IS NULL) OR (created BETWEEN ? AND ?) OR " +
|
||||
" (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?)))";
|
||||
protected static final String GET_ALL_USAGE_RECORDS = "SELECT zone_id, account_id, domain_id, vm_instance_id, security_group_id, created, deleted " +
|
||||
"FROM usage_security_group " +
|
||||
"WHERE (deleted IS NULL) OR (created BETWEEN ? AND ?) OR " +
|
||||
" (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?))";
|
||||
|
||||
public UsageSecurityGroupDaoImpl() {}
|
||||
|
||||
public void update(UsageSecurityGroupVO usage) {
|
||||
Transaction txn = Transaction.open(Transaction.USAGE_DB);
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
txn.start();
|
||||
if (usage.getDeleted() != null) {
|
||||
pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED);
|
||||
pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted()));
|
||||
pstmt.setLong(2, usage.getAccountId());
|
||||
pstmt.setLong(3, usage.getVmInstanceId());
|
||||
pstmt.setLong(4, usage.getSecurityGroupId());
|
||||
}
|
||||
pstmt.executeUpdate();
|
||||
txn.commit();
|
||||
} catch (Exception e) {
|
||||
txn.rollback();
|
||||
s_logger.warn("Error updating UsageSecurityGroupVO", e);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UsageSecurityGroupVO> getUsageRecords(Long accountId, Long domainId, Date startDate, Date endDate, boolean limit, int page) {
|
||||
List<UsageSecurityGroupVO> usageRecords = new ArrayList<UsageSecurityGroupVO>();
|
||||
|
||||
Long param1 = null;
|
||||
String sql = null;
|
||||
if (accountId != null) {
|
||||
sql = GET_USAGE_RECORDS_BY_ACCOUNT;
|
||||
param1 = accountId;
|
||||
} else if (domainId != null) {
|
||||
sql = GET_USAGE_RECORDS_BY_DOMAIN;
|
||||
param1 = domainId;
|
||||
} else {
|
||||
sql = GET_ALL_USAGE_RECORDS;
|
||||
}
|
||||
|
||||
if (limit) {
|
||||
int startIndex = 0;
|
||||
if (page > 0) {
|
||||
startIndex = 500 * (page-1);
|
||||
}
|
||||
sql += " LIMIT " + startIndex + ",500";
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.open(Transaction.USAGE_DB);
|
||||
PreparedStatement pstmt = null;
|
||||
|
||||
try {
|
||||
int i = 1;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
if (param1 != null) {
|
||||
pstmt.setLong(i++, param1);
|
||||
}
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
//zoneId, account_id, domain_id, vm_instance_id, security_group_id, created, deleted
|
||||
Long zoneId = Long.valueOf(rs.getLong(1));
|
||||
Long acctId = Long.valueOf(rs.getLong(2));
|
||||
Long dId = Long.valueOf(rs.getLong(3));
|
||||
long vmId = Long.valueOf(rs.getLong(4));
|
||||
long sgId = Long.valueOf(rs.getLong(5));
|
||||
Date createdDate = null;
|
||||
Date deletedDate = null;
|
||||
String createdTS = rs.getString(6);
|
||||
String deletedTS = rs.getString(7);
|
||||
|
||||
|
||||
if (createdTS != null) {
|
||||
createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS);
|
||||
}
|
||||
if (deletedTS != null) {
|
||||
deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS);
|
||||
}
|
||||
|
||||
usageRecords.add(new UsageSecurityGroupVO(zoneId, acctId, dId, vmId, sgId, createdDate, deletedDate));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
txn.rollback();
|
||||
s_logger.warn("Error getting usage records", e);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
|
||||
return usageRecords;
|
||||
}
|
||||
}
|
||||
@ -28,6 +28,7 @@ DROP TABLE IF EXISTS `cloud_usage`.`usage_port_forwarding`;
|
||||
DROP TABLE IF EXISTS `cloud_usage`.`usage_network_offering`;
|
||||
DROP TABLE IF EXISTS `cloud_usage`.`usage_event`;
|
||||
DROP TABLE IF EXISTS `cloud_usage`.`usage_vpn_user`;
|
||||
DROP TABLE IF EXISTS `cloud_usage`.`usage_security_group`;
|
||||
|
||||
CREATE TABLE `cloud_usage`.`cloud_usage` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
@ -263,6 +264,19 @@ ALTER TABLE `cloud_usage`.`usage_vpn_user` ADD INDEX `i_usage_vpn_user__account_
|
||||
ALTER TABLE `cloud_usage`.`usage_vpn_user` ADD INDEX `i_usage_vpn_user__created`(`created`);
|
||||
ALTER TABLE `cloud_usage`.`usage_vpn_user` ADD INDEX `i_usage_vpn_user__deleted`(`deleted`);
|
||||
|
||||
CREATE TABLE `cloud_usage`.`usage_security_group` (
|
||||
`zone_id` bigint unsigned NOT NULL,
|
||||
`account_id` bigint unsigned NOT NULL,
|
||||
`domain_id` bigint unsigned NOT NULL,
|
||||
`vm_instance_id` bigint unsigned NOT NULL,
|
||||
`security_group_id` bigint unsigned NOT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
`deleted` DATETIME NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__account_id`(`account_id`);
|
||||
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__created`(`created`);
|
||||
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__deleted`(`deleted`);
|
||||
|
||||
CREATE TABLE `cloud`.`netapp_volume` (
|
||||
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
|
||||
|
||||
@ -647,3 +647,17 @@ UPDATE `cloud`.`configuration` SET category = 'Hidden' WHERE name = 'kvm.private
|
||||
UPDATE `cloud`.`configuration` SET category = 'Hidden' WHERE name = 'kvm.guest.network.device';
|
||||
|
||||
ALTER TABLE `cloud`.`physical_network_traffic_types` ADD COLUMN `ovm_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a Ovm host';
|
||||
|
||||
CREATE TABLE `cloud_usage`.`usage_security_group` (
|
||||
`zone_id` bigint unsigned NOT NULL,
|
||||
`account_id` bigint unsigned NOT NULL,
|
||||
`domain_id` bigint unsigned NOT NULL,
|
||||
`vm_instance_id` bigint unsigned NOT NULL,
|
||||
`security_group_id` bigint unsigned NOT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
`deleted` DATETIME NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__account_id`(`account_id`);
|
||||
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__created`(`created`);
|
||||
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__deleted`(`deleted`);
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
<dao name="Usage Port Forwarding Rule" class="com.cloud.usage.dao.UsagePortForwardingRuleDaoImpl"/>
|
||||
<dao name="Usage Network Offering" class="com.cloud.usage.dao.UsageNetworkOfferingDaoImpl"/>
|
||||
<dao name="Usage VPN User" class="com.cloud.usage.dao.UsageVPNUserDaoImpl"/>
|
||||
<dao name="Usage Security Group" class="com.cloud.usage.dao.UsageSecurityGroupDaoImpl"/>
|
||||
<dao name="Usage Job" class="com.cloud.usage.dao.UsageJobDaoImpl"/>
|
||||
<dao name="Configuration" class="com.cloud.configuration.dao.ConfigurationDaoImpl"/>
|
||||
<dao name="Alert" class="com.cloud.alert.dao.AlertDaoImpl"/>
|
||||
|
||||
@ -50,6 +50,7 @@ import com.cloud.usage.dao.UsageLoadBalancerPolicyDao;
|
||||
import com.cloud.usage.dao.UsageNetworkDao;
|
||||
import com.cloud.usage.dao.UsageNetworkOfferingDao;
|
||||
import com.cloud.usage.dao.UsagePortForwardingRuleDao;
|
||||
import com.cloud.usage.dao.UsageSecurityGroupDao;
|
||||
import com.cloud.usage.dao.UsageStorageDao;
|
||||
import com.cloud.usage.dao.UsageVMInstanceDao;
|
||||
import com.cloud.usage.dao.UsageVPNUserDao;
|
||||
@ -59,6 +60,7 @@ import com.cloud.usage.parser.LoadBalancerUsageParser;
|
||||
import com.cloud.usage.parser.NetworkOfferingUsageParser;
|
||||
import com.cloud.usage.parser.NetworkUsageParser;
|
||||
import com.cloud.usage.parser.PortForwardingUsageParser;
|
||||
import com.cloud.usage.parser.SecurityGroupUsageParser;
|
||||
import com.cloud.usage.parser.StorageUsageParser;
|
||||
import com.cloud.usage.parser.VMInstanceUsageParser;
|
||||
import com.cloud.usage.parser.VPNUserUsageParser;
|
||||
@ -104,6 +106,7 @@ public class UsageManagerImpl implements UsageManager, Runnable {
|
||||
private final UsagePortForwardingRuleDao m_usagePortForwardingRuleDao = _locator.getDao(UsagePortForwardingRuleDao.class);
|
||||
private final UsageNetworkOfferingDao m_usageNetworkOfferingDao = _locator.getDao(UsageNetworkOfferingDao.class);
|
||||
private final UsageVPNUserDao m_usageVPNUserDao = _locator.getDao(UsageVPNUserDao.class);
|
||||
private final UsageSecurityGroupDao m_usageSecurityGroupDao = _locator.getDao(UsageSecurityGroupDao.class);
|
||||
private final UsageJobDao m_usageJobDao = _locator.getDao(UsageJobDao.class);
|
||||
@Inject protected AlertManager _alertMgr;
|
||||
@Inject protected UsageEventDao _usageEventDao;
|
||||
@ -721,6 +724,13 @@ public class UsageManagerImpl implements UsageManager, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
parsed = SecurityGroupUsageParser.parse(account, currentStartDate, currentEndDate);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
if (!parsed) {
|
||||
s_logger.debug("Security Group usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
parsed = LoadBalancerUsageParser.parse(account, currentStartDate, currentEndDate);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
if (!parsed) {
|
||||
@ -779,6 +789,8 @@ public class UsageManagerImpl implements UsageManager, Runnable {
|
||||
createNetworkOfferingEvent(event);
|
||||
} else if (isVPNUserEvent(eventType)) {
|
||||
createVPNUserEvent(event);
|
||||
} else if (isSecurityGroupEvent(eventType)) {
|
||||
createSecurityGroupEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -840,6 +852,12 @@ public class UsageManagerImpl implements UsageManager, Runnable {
|
||||
if (eventType == null) return false;
|
||||
return eventType.startsWith("VPN.USER");
|
||||
}
|
||||
|
||||
private boolean isSecurityGroupEvent(String eventType) {
|
||||
if (eventType == null) return false;
|
||||
return (eventType.equals(EventTypes.EVENT_SECURITY_GROUP_ASSIGN) ||
|
||||
eventType.equals(EventTypes.EVENT_SECURITY_GROUP_REMOVE));
|
||||
}
|
||||
|
||||
private void createVMHelperEvent(UsageEventVO event) {
|
||||
|
||||
@ -1354,6 +1372,41 @@ public class UsageManagerImpl implements UsageManager, Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createSecurityGroupEvent(UsageEventVO event) {
|
||||
|
||||
long zoneId = -1L;
|
||||
|
||||
long vmId = event.getResourceId();
|
||||
long sgId = event.getOfferingId();
|
||||
|
||||
if (EventTypes.EVENT_SECURITY_GROUP_ASSIGN.equals(event.getType())) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Assigning : security group"+ sgId +" to Vm: " + vmId + " for account: " + event.getAccountId());
|
||||
}
|
||||
zoneId = event.getZoneId();
|
||||
Account acct = m_accountDao.findByIdIncludingRemoved(event.getAccountId());
|
||||
UsageSecurityGroupVO securityGroup = new UsageSecurityGroupVO(zoneId, event.getAccountId(), acct.getDomainId(), vmId, sgId,event.getCreateDate(), null);
|
||||
m_usageSecurityGroupDao.persist(securityGroup);
|
||||
} else if (EventTypes.EVENT_SECURITY_GROUP_REMOVE.equals(event.getType())) {
|
||||
SearchCriteria<UsageSecurityGroupVO> sc = m_usageSecurityGroupDao.createSearchCriteria();
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId());
|
||||
sc.addAnd("vmInstanceId", SearchCriteria.Op.EQ, vmId);
|
||||
sc.addAnd("securityGroupId", SearchCriteria.Op.EQ, sgId);
|
||||
sc.addAnd("deleted", SearchCriteria.Op.NULL);
|
||||
List<UsageSecurityGroupVO> sgVOs = m_usageSecurityGroupDao.search(sc, null);
|
||||
if (sgVOs.size() > 1) {
|
||||
s_logger.warn("More that one usage entry for security group: "+ sgId +" for Vm: " + vmId+" assigned to account: " + event.getAccountId() + "; marking them all as deleted...");
|
||||
}
|
||||
for (UsageSecurityGroupVO sgVO : sgVOs) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("deleting security group: " + sgVO.getSecurityGroupId() + " from Vm: " + sgVO.getVmInstanceId());
|
||||
}
|
||||
sgVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one
|
||||
m_usageSecurityGroupDao.update(sgVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Heartbeat implements Runnable {
|
||||
public void run() {
|
||||
|
||||
168
usage/src/com/cloud/usage/parser/SecurityGroupUsageParser.java
Normal file
168
usage/src/com/cloud/usage/parser/SecurityGroupUsageParser.java
Normal file
@ -0,0 +1,168 @@
|
||||
|
||||
/**
|
||||
* * Copyright (C) 2012 Citrix Systems, Inc. All rights reserved
|
||||
*
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.usage.parser;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.usage.UsageSecurityGroupVO;
|
||||
import com.cloud.usage.UsageServer;
|
||||
import com.cloud.usage.UsageTypes;
|
||||
import com.cloud.usage.UsageVO;
|
||||
import com.cloud.usage.dao.UsageDao;
|
||||
import com.cloud.usage.dao.UsageSecurityGroupDao;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
|
||||
public class SecurityGroupUsageParser {
|
||||
public static final Logger s_logger = Logger.getLogger(SecurityGroupUsageParser.class.getName());
|
||||
|
||||
private static ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage");
|
||||
private static UsageDao m_usageDao = _locator.getDao(UsageDao.class);
|
||||
private static UsageSecurityGroupDao m_usageSecurityGroupDao = _locator.getDao(UsageSecurityGroupDao.class);
|
||||
|
||||
public static boolean parse(AccountVO account, Date startDate, Date endDate) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Parsing all SecurityGroup usage events for account: " + account.getId());
|
||||
}
|
||||
if ((endDate == null) || endDate.after(new Date())) {
|
||||
endDate = new Date();
|
||||
}
|
||||
|
||||
// - query usage_volume table with the following criteria:
|
||||
// - look for an entry for accountId with start date in the given range
|
||||
// - look for an entry for accountId with end date in the given range
|
||||
// - look for an entry for accountId with end date null (currently running vm or owned IP)
|
||||
// - look for an entry for accountId with start date before given range *and* end date after given range
|
||||
List<UsageSecurityGroupVO> usageSGs = m_usageSecurityGroupDao.getUsageRecords(account.getId(), account.getDomainId(), startDate, endDate, false, 0);
|
||||
|
||||
if(usageSGs.isEmpty()){
|
||||
s_logger.debug("No SecurityGroup usage events for this period");
|
||||
return true;
|
||||
}
|
||||
|
||||
// This map has both the running time *and* the usage amount.
|
||||
Map<String, Pair<Long, Long>> usageMap = new HashMap<String, Pair<Long, Long>>();
|
||||
Map<String, SGInfo> sgMap = new HashMap<String, SGInfo>();
|
||||
|
||||
// loop through all the security groups, create a usage record for each
|
||||
for (UsageSecurityGroupVO usageSG : usageSGs) {
|
||||
long vmId = usageSG.getVmInstanceId();
|
||||
long sgId = usageSG.getSecurityGroupId();
|
||||
String key = ""+vmId+"SG"+sgId;
|
||||
|
||||
sgMap.put(key, new SGInfo(vmId, usageSG.getZoneId(), sgId));
|
||||
|
||||
Date sgCreateDate = usageSG.getCreated();
|
||||
Date sgDeleteDate = usageSG.getDeleted();
|
||||
|
||||
if ((sgDeleteDate == null) || sgDeleteDate.after(endDate)) {
|
||||
sgDeleteDate = endDate;
|
||||
}
|
||||
|
||||
// clip the start date to the beginning of our aggregation range if the vm has been running for a while
|
||||
if (sgCreateDate.before(startDate)) {
|
||||
sgCreateDate = startDate;
|
||||
}
|
||||
|
||||
long currentDuration = (sgDeleteDate.getTime() - sgCreateDate.getTime()) + 1; // make sure this is an inclusive check for milliseconds (i.e. use n - m + 1 to find total number of millis to charge)
|
||||
|
||||
|
||||
updateSGUsageData(usageMap, key, usageSG.getVmInstanceId(), currentDuration);
|
||||
}
|
||||
|
||||
for (String sgIdKey : usageMap.keySet()) {
|
||||
Pair<Long, Long> sgtimeInfo = usageMap.get(sgIdKey);
|
||||
long useTime = sgtimeInfo.second().longValue();
|
||||
|
||||
// Only create a usage record if we have a runningTime of bigger than zero.
|
||||
if (useTime > 0L) {
|
||||
SGInfo info = sgMap.get(sgIdKey);
|
||||
createUsageRecord(UsageTypes.SECURITY_GROUP, useTime, startDate, endDate, account, info.getVmId(), info.getSGId(), info.getZoneId());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void updateSGUsageData(Map<String, Pair<Long, Long>> usageDataMap, String key, long vmId, long duration) {
|
||||
Pair<Long, Long> sgUsageInfo = usageDataMap.get(key);
|
||||
if (sgUsageInfo == null) {
|
||||
sgUsageInfo = new Pair<Long, Long>(new Long(vmId), new Long(duration));
|
||||
} else {
|
||||
Long runningTime = sgUsageInfo.second();
|
||||
runningTime = new Long(runningTime.longValue() + duration);
|
||||
sgUsageInfo = new Pair<Long, Long>(sgUsageInfo.first(), runningTime);
|
||||
}
|
||||
usageDataMap.put(key, sgUsageInfo);
|
||||
}
|
||||
|
||||
private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, long sgId, long zoneId) {
|
||||
// Our smallest increment is hourly for now
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Total running time " + runningTime + "ms");
|
||||
}
|
||||
|
||||
float usage = runningTime / 1000f / 60f / 60f;
|
||||
|
||||
DecimalFormat dFormat = new DecimalFormat("#.######");
|
||||
String usageDisplay = dFormat.format(usage);
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Creating security group:" + sgId + " usage record for Vm : " + vmId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId());
|
||||
}
|
||||
|
||||
// Create the usage record
|
||||
String usageDesc = "Security Group: " + sgId + " for Vm : " + vmId + " usage time";
|
||||
|
||||
UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type,
|
||||
new Double(usage), vmId, null, null, null, sgId, null, startDate, endDate);
|
||||
m_usageDao.persist(usageRecord);
|
||||
}
|
||||
|
||||
private static class SGInfo {
|
||||
private long vmId;
|
||||
private long zoneId;
|
||||
private long sgId;
|
||||
|
||||
public SGInfo(long vmId, long zoneId, long sgId) {
|
||||
this.vmId = vmId;
|
||||
this.zoneId = zoneId;
|
||||
this.sgId = sgId;
|
||||
}
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
public long getSGId() {
|
||||
return sgId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user