Skip to content

Commit ced6fd4

Browse files
author
kishan
committed
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
1 parent 6160333 commit ced6fd4

12 files changed

Lines changed: 562 additions & 1 deletion

File tree

api/src/com/cloud/event/EventTypes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ public class EventTypes {
184184
public static final String EVENT_SECURITY_GROUP_REVOKE_EGRESS = "SG.REVOKE.EGRESS";
185185
public static final String EVENT_SECURITY_GROUP_CREATE = "SG.CREATE";
186186
public static final String EVENT_SECURITY_GROUP_DELETE = "SG.DELETE";
187+
public static final String EVENT_SECURITY_GROUP_ASSIGN = "SG.ASSIGN";
188+
public static final String EVENT_SECURITY_GROUP_REMOVE = "SG.REMOVE";
187189

188190
// Host
189191
public static final String EVENT_HOST_RECONNECT = "HOST.RECONNECT";

core/src/com/cloud/event/UsageEventVO.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ public UsageEventVO(String usageType, long accountId, long zoneId, long resource
116116
this.resourceType = resourceType;
117117
}
118118

119+
//Security Group usage event
120+
public UsageEventVO(String usageType, long accountId,
121+
long zoneId, long vmId, long securityGroupId) {
122+
this.type = usageType;
123+
this.accountId = accountId;
124+
this.zoneId = zoneId;
125+
this.resourceId = vmId;
126+
this.offeringId = securityGroupId;
127+
}
128+
119129
@Override
120130
public long getId() {
121131
return id;

server/src/com/cloud/api/commands/GetUsageRecordsCmd.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ public void execute(){
318318
} else if(usageRecord.getUsageType() == UsageTypes.VPN_USERS){
319319
//VPN User ID
320320
usageRecResponse.setUsageId(usageRecord.getUsageId().toString());
321+
322+
} else if(usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP){
323+
//Security Group Id
324+
usageRecResponse.setUsageId(identityDao.getIdentityUuid("security_group", usageRecord.getUsageId().toString()));
321325
}
322326

323327
if (usageRecord.getRawUsage() != null) {

server/src/com/cloud/network/security/SecurityGroupManagerImpl.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
import com.cloud.domain.dao.DomainDao;
5858
import com.cloud.event.ActionEvent;
5959
import com.cloud.event.EventTypes;
60+
import com.cloud.event.UsageEventVO;
61+
import com.cloud.event.dao.UsageEventDao;
6062
import com.cloud.exception.AgentUnavailableException;
6163
import com.cloud.exception.InvalidParameterValueException;
6264
import com.cloud.exception.OperationTimedoutException;
@@ -152,7 +154,9 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
152154
DomainManager _domainMgr;
153155
@Inject
154156
ProjectManager _projectMgr;
155-
157+
@Inject
158+
UsageEventDao _usageEventDao;
159+
156160
ScheduledExecutorService _executorPool;
157161
ScheduledExecutorService _cleanupExecutor;
158162

@@ -449,6 +453,10 @@ protected List<Long> getAffectedVmsForVmStart(VMInstanceVO vm) {
449453
List<SecurityGroupVMMapVO> groupsForVm = _securityGroupVMMapDao.listByInstanceId(vm.getId());
450454
// For each group, find the security rules that allow the group
451455
for (SecurityGroupVMMapVO mapVO : groupsForVm) {// FIXME: use custom sql in the dao
456+
//Add usage events for security group assign
457+
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SECURITY_GROUP_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), mapVO.getSecurityGroupId());
458+
_usageEventDao.persist(usageEvent);
459+
452460
List<SecurityGroupRuleVO> allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId());
453461
// For each security rule that allows a group that the vm belongs to, find the group it belongs to
454462
affectedVms.addAll(getAffectedVmsForSecurityRules(allowingRules));
@@ -461,6 +469,10 @@ protected List<Long> getAffectedVmsForVmStop(VMInstanceVO vm) {
461469
List<SecurityGroupVMMapVO> groupsForVm = _securityGroupVMMapDao.listByInstanceId(vm.getId());
462470
// For each group, find the security rules rules that allow the group
463471
for (SecurityGroupVMMapVO mapVO : groupsForVm) {// FIXME: use custom sql in the dao
472+
//Add usage events for security group remove
473+
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SECURITY_GROUP_REMOVE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), mapVO.getSecurityGroupId());
474+
_usageEventDao.persist(usageEvent);
475+
464476
List<SecurityGroupRuleVO> allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId());
465477
// For each security rule that allows a group that the vm belongs to, find the group it belongs to
466478
affectedVms.addAll(getAffectedVmsForSecurityRules(allowingRules));
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* * Copyright (C) 2012 Citrix Systems, Inc. All rights reserved
3+
*
4+
*
5+
* This software is licensed under the GNU General Public License v3 or later.
6+
*
7+
* It is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or any later version.
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*
18+
*/
19+
20+
package com.cloud.usage;
21+
22+
import java.util.Date;
23+
24+
import javax.persistence.Column;
25+
import javax.persistence.Entity;
26+
import javax.persistence.Table;
27+
import javax.persistence.Temporal;
28+
import javax.persistence.TemporalType;
29+
30+
@Entity
31+
@Table(name="usage_security_group")
32+
public class UsageSecurityGroupVO {
33+
34+
@Column(name="zone_id")
35+
private long zoneId;
36+
37+
@Column(name="account_id")
38+
private long accountId;
39+
40+
@Column(name="domain_id")
41+
private long domainId;
42+
43+
@Column(name="vm_instance_id")
44+
private long vmInstanceId;
45+
46+
@Column(name="security_group_id")
47+
private Long securityGroupId;
48+
49+
@Column(name="created")
50+
@Temporal(value=TemporalType.TIMESTAMP)
51+
private Date created = null;
52+
53+
@Column(name="deleted")
54+
@Temporal(value=TemporalType.TIMESTAMP)
55+
private Date deleted = null;
56+
57+
public UsageSecurityGroupVO(){
58+
}
59+
60+
public UsageSecurityGroupVO(long zoneId, long accountId, long domainId, long vmInstanceId, long securityGroupId, Date created, Date deleted) {
61+
this.zoneId = zoneId;
62+
this.accountId = accountId;
63+
this.domainId = domainId;
64+
this.vmInstanceId = vmInstanceId;
65+
this.securityGroupId = securityGroupId;
66+
this.created = created;
67+
this.deleted = deleted;
68+
}
69+
70+
public long getZoneId() {
71+
return zoneId;
72+
}
73+
74+
public long getAccountId() {
75+
return accountId;
76+
}
77+
78+
public long getDomainId() {
79+
return domainId;
80+
}
81+
82+
public long getVmInstanceId() {
83+
return vmInstanceId;
84+
}
85+
86+
public Long getSecurityGroupId() {
87+
return securityGroupId;
88+
}
89+
90+
public Date getCreated() {
91+
return created;
92+
}
93+
94+
public Date getDeleted() {
95+
return deleted;
96+
}
97+
public void setDeleted(Date deleted) {
98+
this.deleted = deleted;
99+
}
100+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* * Copyright (C) 2012 Citrix Systems, Inc. All rights reserved
3+
*
4+
*
5+
* This software is licensed under the GNU General Public License v3 or later.
6+
*
7+
* It is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or any later version.
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*
18+
*/
19+
20+
package com.cloud.usage.dao;
21+
22+
import java.util.Date;
23+
import java.util.List;
24+
25+
import com.cloud.usage.UsageSecurityGroupVO;
26+
import com.cloud.utils.db.GenericDao;
27+
28+
public interface UsageSecurityGroupDao extends GenericDao<UsageSecurityGroupVO, Long> {
29+
public void update(UsageSecurityGroupVO usage);
30+
public List<UsageSecurityGroupVO> getUsageRecords(Long accountId, Long domainId, Date startDate, Date endDate, boolean limit, int page);
31+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/**
2+
* * Copyright (C) 2012 Citrix Systems, Inc. All rights reserved
3+
*
4+
*
5+
* This software is licensed under the GNU General Public License v3 or later.
6+
*
7+
* It is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or any later version.
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*
18+
*/
19+
20+
package com.cloud.usage.dao;
21+
22+
import java.sql.PreparedStatement;
23+
import java.sql.ResultSet;
24+
import java.util.ArrayList;
25+
import java.util.Date;
26+
import java.util.List;
27+
import java.util.TimeZone;
28+
29+
import javax.ejb.Local;
30+
31+
import org.apache.log4j.Logger;
32+
33+
import com.cloud.usage.UsageSecurityGroupVO;
34+
import com.cloud.utils.DateUtil;
35+
import com.cloud.utils.db.GenericDaoBase;
36+
import com.cloud.utils.db.Transaction;
37+
38+
@Local(value={UsageSecurityGroupDao.class})
39+
public class UsageSecurityGroupDaoImpl extends GenericDaoBase<UsageSecurityGroupVO, Long> implements UsageSecurityGroupDao {
40+
public static final Logger s_logger = Logger.getLogger(UsageSecurityGroupDaoImpl.class.getName());
41+
42+
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";
43+
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT zone_id, account_id, domain_id, vm_instance_id, security_group_id, created, deleted " +
44+
"FROM usage_security_group " +
45+
"WHERE account_id = ? AND ((deleted IS NULL) OR (created BETWEEN ? AND ?) OR " +
46+
" (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?)))";
47+
protected static final String GET_USAGE_RECORDS_BY_DOMAIN = "SELECT zone_id, account_id, domain_id, vm_instance_id, security_group_id, created, deleted " +
48+
"FROM usage_security_group " +
49+
"WHERE domain_id = ? AND ((deleted IS NULL) OR (created BETWEEN ? AND ?) OR " +
50+
" (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?)))";
51+
protected static final String GET_ALL_USAGE_RECORDS = "SELECT zone_id, account_id, domain_id, vm_instance_id, security_group_id, created, deleted " +
52+
"FROM usage_security_group " +
53+
"WHERE (deleted IS NULL) OR (created BETWEEN ? AND ?) OR " +
54+
" (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?))";
55+
56+
public UsageSecurityGroupDaoImpl() {}
57+
58+
public void update(UsageSecurityGroupVO usage) {
59+
Transaction txn = Transaction.open(Transaction.USAGE_DB);
60+
PreparedStatement pstmt = null;
61+
try {
62+
txn.start();
63+
if (usage.getDeleted() != null) {
64+
pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED);
65+
pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted()));
66+
pstmt.setLong(2, usage.getAccountId());
67+
pstmt.setLong(3, usage.getVmInstanceId());
68+
pstmt.setLong(4, usage.getSecurityGroupId());
69+
}
70+
pstmt.executeUpdate();
71+
txn.commit();
72+
} catch (Exception e) {
73+
txn.rollback();
74+
s_logger.warn("Error updating UsageSecurityGroupVO", e);
75+
} finally {
76+
txn.close();
77+
}
78+
}
79+
80+
@Override
81+
public List<UsageSecurityGroupVO> getUsageRecords(Long accountId, Long domainId, Date startDate, Date endDate, boolean limit, int page) {
82+
List<UsageSecurityGroupVO> usageRecords = new ArrayList<UsageSecurityGroupVO>();
83+
84+
Long param1 = null;
85+
String sql = null;
86+
if (accountId != null) {
87+
sql = GET_USAGE_RECORDS_BY_ACCOUNT;
88+
param1 = accountId;
89+
} else if (domainId != null) {
90+
sql = GET_USAGE_RECORDS_BY_DOMAIN;
91+
param1 = domainId;
92+
} else {
93+
sql = GET_ALL_USAGE_RECORDS;
94+
}
95+
96+
if (limit) {
97+
int startIndex = 0;
98+
if (page > 0) {
99+
startIndex = 500 * (page-1);
100+
}
101+
sql += " LIMIT " + startIndex + ",500";
102+
}
103+
104+
Transaction txn = Transaction.open(Transaction.USAGE_DB);
105+
PreparedStatement pstmt = null;
106+
107+
try {
108+
int i = 1;
109+
pstmt = txn.prepareAutoCloseStatement(sql);
110+
if (param1 != null) {
111+
pstmt.setLong(i++, param1);
112+
}
113+
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
114+
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
115+
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
116+
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
117+
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
118+
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
119+
120+
ResultSet rs = pstmt.executeQuery();
121+
while (rs.next()) {
122+
//zoneId, account_id, domain_id, vm_instance_id, security_group_id, created, deleted
123+
Long zoneId = Long.valueOf(rs.getLong(1));
124+
Long acctId = Long.valueOf(rs.getLong(2));
125+
Long dId = Long.valueOf(rs.getLong(3));
126+
long vmId = Long.valueOf(rs.getLong(4));
127+
long sgId = Long.valueOf(rs.getLong(5));
128+
Date createdDate = null;
129+
Date deletedDate = null;
130+
String createdTS = rs.getString(6);
131+
String deletedTS = rs.getString(7);
132+
133+
134+
if (createdTS != null) {
135+
createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS);
136+
}
137+
if (deletedTS != null) {
138+
deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS);
139+
}
140+
141+
usageRecords.add(new UsageSecurityGroupVO(zoneId, acctId, dId, vmId, sgId, createdDate, deletedDate));
142+
}
143+
} catch (Exception e) {
144+
txn.rollback();
145+
s_logger.warn("Error getting usage records", e);
146+
} finally {
147+
txn.close();
148+
}
149+
150+
return usageRecords;
151+
}
152+
}

setup/db/create-schema-premium.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ DROP TABLE IF EXISTS `cloud_usage`.`usage_port_forwarding`;
2828
DROP TABLE IF EXISTS `cloud_usage`.`usage_network_offering`;
2929
DROP TABLE IF EXISTS `cloud_usage`.`usage_event`;
3030
DROP TABLE IF EXISTS `cloud_usage`.`usage_vpn_user`;
31+
DROP TABLE IF EXISTS `cloud_usage`.`usage_security_group`;
3132

3233
CREATE TABLE `cloud_usage`.`cloud_usage` (
3334
`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_
263264
ALTER TABLE `cloud_usage`.`usage_vpn_user` ADD INDEX `i_usage_vpn_user__created`(`created`);
264265
ALTER TABLE `cloud_usage`.`usage_vpn_user` ADD INDEX `i_usage_vpn_user__deleted`(`deleted`);
265266

267+
CREATE TABLE `cloud_usage`.`usage_security_group` (
268+
`zone_id` bigint unsigned NOT NULL,
269+
`account_id` bigint unsigned NOT NULL,
270+
`domain_id` bigint unsigned NOT NULL,
271+
`vm_instance_id` bigint unsigned NOT NULL,
272+
`security_group_id` bigint unsigned NOT NULL,
273+
`created` DATETIME NOT NULL,
274+
`deleted` DATETIME NULL
275+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
276+
277+
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__account_id`(`account_id`);
278+
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__created`(`created`);
279+
ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_group__deleted`(`deleted`);
266280

267281
CREATE TABLE `cloud`.`netapp_volume` (
268282
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',

0 commit comments

Comments
 (0)