Skip to content

Commit d1def0a

Browse files
committed
Merge pull request #1287 from DaanHoogland/securityrules-cleanup
SecurityGroupRulesCmd code cleanupWrote a test and cleaned some duplicate code with the objective to evaluate the jenkins pull request process at builds.a.o worthwhile to keep, IMHO. * pr/1287: SecurityGroupRulesCmd code cleanup review comments handled deal with PMD warnings code cleanup security rules test remove autogenerated pydev files Signed-off-by: Koushik Das <koushik@apache.org>
2 parents 67b4e66 + b9b5967 commit d1def0a

11 files changed

Lines changed: 447 additions & 360 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,5 @@ tools/appliance/box/
9696
.pydevproject
9797
systemvm/.pydevproject
9898
test/.pydevprojec
99+
plugins/hypervisors/kvm/.pydevproject
100+
scripts/.pydevproject

core/src/com/cloud/agent/api/SecurityGroupRulesCmd.java

Lines changed: 113 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.io.ByteArrayOutputStream;
2323
import java.io.IOException;
24+
import java.util.ArrayList;
2425
import java.util.List;
2526
import java.util.zip.DeflaterOutputStream;
2627

@@ -32,32 +33,48 @@
3233
import com.cloud.utils.net.NetUtils;
3334

3435
public class SecurityGroupRulesCmd extends Command {
35-
private static Logger s_logger = Logger.getLogger(SecurityGroupRulesCmd.class);
36+
private static final String CIDR_LENGTH_SEPARATOR = "/";
37+
private static final char RULE_TARGET_SEPARATOR = ',';
38+
private static final char RULE_COMMAND_SEPARATOR = ':';
39+
protected static final String EGRESS_RULE = "E:";
40+
protected static final String INGRESS_RULE = "I:";
41+
private static final Logger LOGGER = Logger.getLogger(SecurityGroupRulesCmd.class);
42+
43+
private final String guestIp;
44+
private final String vmName;
45+
private final String guestMac;
46+
private final String signature;
47+
private final Long seqNum;
48+
private final Long vmId;
49+
private Long msId;
50+
private List<IpPortAndProto> ingressRuleSet;
51+
private List<IpPortAndProto> egressRuleSet;
52+
private final List<String> secIps;
3653

3754
public static class IpPortAndProto {
38-
private String proto;
39-
private int startPort;
40-
private int endPort;
55+
private final String proto;
56+
private final int startPort;
57+
private final int endPort;
4158
@LogLevel(Log4jLevel.Trace)
42-
private String[] allowedCidrs;
59+
private List<String> allowedCidrs;
4360

44-
public IpPortAndProto() {
45-
}
46-
47-
public IpPortAndProto(String proto, int startPort, int endPort, String[] allowedCidrs) {
61+
public IpPortAndProto(final String proto, final int startPort, final int endPort, final String... allowedCidrs) {
4862
super();
4963
this.proto = proto;
5064
this.startPort = startPort;
5165
this.endPort = endPort;
52-
this.allowedCidrs = allowedCidrs;
66+
setAllowedCidrs(allowedCidrs);
5367
}
5468

55-
public String[] getAllowedCidrs() {
69+
public List<String> getAllowedCidrs() {
5670
return allowedCidrs;
5771
}
5872

59-
public void setAllowedCidrs(String[] allowedCidrs) {
60-
this.allowedCidrs = allowedCidrs;
73+
public void setAllowedCidrs(final String... allowedCidrs) {
74+
this.allowedCidrs = new ArrayList<String>();
75+
for (final String allowedCidr : allowedCidrs) {
76+
this.allowedCidrs.add(allowedCidr);
77+
}
6178
}
6279

6380
public String getProto() {
@@ -74,52 +91,28 @@ public int getEndPort() {
7491

7592
}
7693

77-
String guestIp;
78-
String vmName;
79-
String guestMac;
80-
String signature;
81-
Long seqNum;
82-
Long vmId;
83-
Long msId;
84-
IpPortAndProto[] ingressRuleSet;
85-
IpPortAndProto[] egressRuleSet;
86-
private List<String> secIps;
87-
88-
public SecurityGroupRulesCmd() {
89-
super();
90-
}
91-
92-
public SecurityGroupRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ingressRuleSet,
93-
IpPortAndProto[] egressRuleSet) {
94-
super();
95-
this.guestIp = guestIp;
96-
this.vmName = vmName;
97-
this.ingressRuleSet = ingressRuleSet;
98-
this.egressRuleSet = egressRuleSet;
99-
this.guestMac = guestMac;
100-
this.signature = signature;
101-
this.seqNum = seqNum;
102-
this.vmId = vmId;
103-
if (signature == null) {
104-
String stringified = stringifyRules();
105-
this.signature = DigestUtils.md5Hex(stringified);
106-
}
107-
}
108-
109-
public SecurityGroupRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ingressRuleSet,
110-
IpPortAndProto[] egressRuleSet, List<String> secIps) {
111-
super();
94+
public SecurityGroupRulesCmd(
95+
final String guestIp,
96+
final String guestMac,
97+
final String vmName,
98+
final Long vmId,
99+
final String signature,
100+
final Long seqNum,
101+
final IpPortAndProto[] ingressRuleSet,
102+
final IpPortAndProto[] egressRuleSet,
103+
final List<String> secIps) {
112104
this.guestIp = guestIp;
113105
this.vmName = vmName;
114-
this.ingressRuleSet = ingressRuleSet;
115-
this.egressRuleSet = egressRuleSet;
106+
setIngressRuleSet(ingressRuleSet);
107+
this.setEgressRuleSet(egressRuleSet);
116108
this.guestMac = guestMac;
117-
this.signature = signature;
118109
this.seqNum = seqNum;
119110
this.vmId = vmId;
120111
if (signature == null) {
121-
String stringified = stringifyRules();
112+
final String stringified = stringifyRules();
122113
this.signature = DigestUtils.md5Hex(stringified);
114+
} else {
115+
this.signature = signature;
123116
}
124117
this.secIps = secIps;
125118
}
@@ -129,20 +122,26 @@ public boolean executeInSequence() {
129122
return true;
130123
}
131124

132-
public IpPortAndProto[] getIngressRuleSet() {
125+
public List<IpPortAndProto> getIngressRuleSet() {
133126
return ingressRuleSet;
134127
}
135128

136-
public void setIngressRuleSet(IpPortAndProto[] ingressRuleSet) {
137-
this.ingressRuleSet = ingressRuleSet;
129+
public void setIngressRuleSet(final IpPortAndProto... ingressRuleSet) {
130+
this.ingressRuleSet = new ArrayList<IpPortAndProto>();
131+
for(final IpPortAndProto rule: ingressRuleSet) {
132+
this.ingressRuleSet.add(rule);
133+
}
138134
}
139135

140-
public IpPortAndProto[] getEgressRuleSet() {
136+
public List<IpPortAndProto> getEgressRuleSet() {
141137
return egressRuleSet;
142138
}
143139

144-
public void setEgressRuleSet(IpPortAndProto[] egressRuleSet) {
145-
this.egressRuleSet = egressRuleSet;
140+
public void setEgressRuleSet(final IpPortAndProto... egressRuleSet) {
141+
this.egressRuleSet = new ArrayList<IpPortAndProto>();
142+
for(final IpPortAndProto rule: egressRuleSet) {
143+
this.egressRuleSet.add(rule);
144+
}
146145
}
147146

148147
public String getGuestIp() {
@@ -157,105 +156,77 @@ public String getVmName() {
157156
return vmName;
158157
}
159158

160-
public String stringifyRules() {
161-
StringBuilder ruleBuilder = new StringBuilder();
162-
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) {
163-
ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
164-
for (String cidr : ipPandP.getAllowedCidrs()) {
165-
ruleBuilder.append(cidr).append(",");
166-
}
167-
ruleBuilder.append("NEXT");
168-
ruleBuilder.append(" ");
169-
}
170-
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getEgressRuleSet()) {
171-
ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
172-
for (String cidr : ipPandP.getAllowedCidrs()) {
173-
ruleBuilder.append(cidr).append(",");
174-
}
175-
ruleBuilder.append("NEXT");
176-
ruleBuilder.append(" ");
177-
}
178-
return ruleBuilder.toString();
179-
}
180-
181-
//convert cidrs in the form "a.b.c.d/e" to "hexvalue of 32bit ip/e"
182-
private String compressCidr(String cidr) {
183-
String[] toks = cidr.split("/");
184-
long ipnum = NetUtils.ip2Long(toks[0]);
185-
return Long.toHexString(ipnum) + "/" + toks[1];
159+
private String compressCidrToHexRepresentation(final String cidr) {
160+
final String[] toks = cidr.split(CIDR_LENGTH_SEPARATOR);
161+
final long ipnum = NetUtils.ip2Long(toks[0]);
162+
return Long.toHexString(ipnum) + CIDR_LENGTH_SEPARATOR + toks[1];
186163
}
187164

188165
public String getSecIpsString() {
189-
StringBuilder sb = new StringBuilder();
190-
List<String> ips = getSecIps();
166+
final StringBuilder sb = new StringBuilder();
167+
final List<String> ips = getSecIps();
191168
if (ips == null) {
192-
return "0:";
169+
sb.append("0:");
193170
} else {
194-
for (String ip : ips) {
195-
sb.append(ip).append(":");
171+
for (final String ip : ips) {
172+
sb.append(ip).append(RULE_COMMAND_SEPARATOR);
196173
}
197174
}
198175
return sb.toString();
199176
}
200177

178+
public String stringifyRules() {
179+
final StringBuilder ruleBuilder = new StringBuilder();
180+
stringifyRulesFor(getIngressRuleSet(), INGRESS_RULE, false, ruleBuilder);
181+
stringifyRulesFor(getEgressRuleSet(), EGRESS_RULE, false, ruleBuilder);
182+
return ruleBuilder.toString();
183+
}
184+
201185
public String stringifyCompressedRules() {
202-
StringBuilder ruleBuilder = new StringBuilder();
203-
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) {
204-
ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
205-
for (String cidr : ipPandP.getAllowedCidrs()) {
206-
//convert cidrs in the form "a.b.c.d/e" to "hexvalue of 32bit ip/e"
207-
ruleBuilder.append(compressCidr(cidr)).append(",");
186+
final StringBuilder ruleBuilder = new StringBuilder();
187+
stringifyRulesFor(getIngressRuleSet(), INGRESS_RULE, true, ruleBuilder);
188+
stringifyRulesFor(getEgressRuleSet(), EGRESS_RULE, true, ruleBuilder);
189+
return ruleBuilder.toString();
190+
}
191+
192+
private void stringifyRulesFor(final List<IpPortAndProto> ipPortAndProtocols, final String inOrEgress, final boolean compressed, final StringBuilder ruleBuilder) {
193+
for (final IpPortAndProto ipPandP : ipPortAndProtocols) {
194+
ruleBuilder.append(inOrEgress).append(ipPandP.getProto()).append(RULE_COMMAND_SEPARATOR).append(ipPandP.getStartPort()).append(RULE_COMMAND_SEPARATOR)
195+
.append(ipPandP.getEndPort()).append(RULE_COMMAND_SEPARATOR);
196+
for (final String cidr : ipPandP.getAllowedCidrs()) {
197+
ruleBuilder.append(represent(cidr, compressed)).append(RULE_TARGET_SEPARATOR);
208198
}
209-
ruleBuilder.append("NEXT");
210-
ruleBuilder.append(" ");
199+
ruleBuilder.append("NEXT ");
211200
}
212-
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getEgressRuleSet()) {
213-
ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
214-
for (String cidr : ipPandP.getAllowedCidrs()) {
215-
//convert cidrs in the form "a.b.c.d/e" to "hexvalue of 32bit ip/e"
216-
ruleBuilder.append(compressCidr(cidr)).append(",");
217-
}
218-
ruleBuilder.append("NEXT");
219-
ruleBuilder.append(" ");
201+
}
202+
203+
private String represent(final String cidr, final boolean compressed) {
204+
if (compressed) {
205+
return compressCidrToHexRepresentation(cidr);
206+
} else {
207+
return cidr;
220208
}
221-
return ruleBuilder.toString();
222209
}
223210

224-
/*
211+
/**
225212
* Compress the security group rules using zlib compression to allow the call to the hypervisor
226213
* to scale beyond 8k cidrs.
214+
* Note : not using {@see GZipOutputStream} since that is for files, using {@see DeflaterOutputStream} instead.
215+
* {@see GZipOutputStream} gives a different header, although the compression is the same
227216
*/
228217
public String compressStringifiedRules() {
229-
StringBuilder ruleBuilder = new StringBuilder();
230-
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) {
231-
ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
232-
for (String cidr : ipPandP.getAllowedCidrs()) {
233-
ruleBuilder.append(cidr).append(",");
234-
}
235-
ruleBuilder.append("NEXT");
236-
ruleBuilder.append(" ");
237-
}
238-
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getEgressRuleSet()) {
239-
ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
240-
for (String cidr : ipPandP.getAllowedCidrs()) {
241-
ruleBuilder.append(cidr).append(",");
242-
}
243-
ruleBuilder.append("NEXT");
244-
ruleBuilder.append(" ");
245-
}
246-
String stringified = ruleBuilder.toString();
247-
ByteArrayOutputStream out = new ByteArrayOutputStream();
218+
final String stringified = stringifyRules();
219+
final ByteArrayOutputStream out = new ByteArrayOutputStream();
220+
String encodedResult = null;
248221
try {
249-
//Note : not using GZipOutputStream since that is for files
250-
//GZipOutputStream gives a different header, although the compression is the same
251-
DeflaterOutputStream dzip = new DeflaterOutputStream(out);
222+
final DeflaterOutputStream dzip = new DeflaterOutputStream(out);
252223
dzip.write(stringified.getBytes());
253224
dzip.close();
254-
} catch (IOException e) {
255-
s_logger.warn("Exception while compressing security group rules");
256-
return null;
225+
encodedResult = Base64.encodeBase64String(out.toByteArray());
226+
} catch (final IOException e) {
227+
LOGGER.warn("Exception while compressing security group rules");
257228
}
258-
return Base64.encodeBase64String(out.toByteArray());
229+
return encodedResult;
259230
}
260231

261232
public String getSignature() {
@@ -274,19 +245,22 @@ public Long getVmId() {
274245
return vmId;
275246
}
276247

248+
/**
249+
* used for logging
250+
* @return the number of Cidrs in the in and egress rule sets for this security group rules command.
251+
*/
277252
public int getTotalNumCidrs() {
278-
//useful for logging
279253
int count = 0;
280-
for (IpPortAndProto i : ingressRuleSet) {
281-
count += i.allowedCidrs.length;
254+
for (final IpPortAndProto i : ingressRuleSet) {
255+
count += i.allowedCidrs.size();
282256
}
283-
for (IpPortAndProto i : egressRuleSet) {
284-
count += i.allowedCidrs.length;
257+
for (final IpPortAndProto i : egressRuleSet) {
258+
count += i.allowedCidrs.size();
285259
}
286260
return count;
287261
}
288262

289-
public void setMsId(long msId) {
263+
public void setMsId(final long msId) {
290264
this.msId = msId;
291265
}
292266

0 commit comments

Comments
 (0)