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>
This commit is contained in:
Koushik Das 2016-04-11 21:49:56 +05:30
commit d1def0a730
11 changed files with 450 additions and 363 deletions

2
.gitignore vendored
View File

@ -96,3 +96,5 @@ tools/appliance/box/
.pydevproject
systemvm/.pydevproject
test/.pydevprojec
plugins/hypervisors/kvm/.pydevproject
scripts/.pydevproject

View File

@ -21,6 +21,7 @@ package com.cloud.agent.api;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.DeflaterOutputStream;
@ -32,32 +33,48 @@ import com.cloud.agent.api.LogLevel.Log4jLevel;
import com.cloud.utils.net.NetUtils;
public class SecurityGroupRulesCmd extends Command {
private static Logger s_logger = Logger.getLogger(SecurityGroupRulesCmd.class);
private static final String CIDR_LENGTH_SEPARATOR = "/";
private static final char RULE_TARGET_SEPARATOR = ',';
private static final char RULE_COMMAND_SEPARATOR = ':';
protected static final String EGRESS_RULE = "E:";
protected static final String INGRESS_RULE = "I:";
private static final Logger LOGGER = Logger.getLogger(SecurityGroupRulesCmd.class);
private final String guestIp;
private final String vmName;
private final String guestMac;
private final String signature;
private final Long seqNum;
private final Long vmId;
private Long msId;
private List<IpPortAndProto> ingressRuleSet;
private List<IpPortAndProto> egressRuleSet;
private final List<String> secIps;
public static class IpPortAndProto {
private String proto;
private int startPort;
private int endPort;
private final String proto;
private final int startPort;
private final int endPort;
@LogLevel(Log4jLevel.Trace)
private String[] allowedCidrs;
private List<String> allowedCidrs;
public IpPortAndProto() {
}
public IpPortAndProto(String proto, int startPort, int endPort, String[] allowedCidrs) {
public IpPortAndProto(final String proto, final int startPort, final int endPort, final String... allowedCidrs) {
super();
this.proto = proto;
this.startPort = startPort;
this.endPort = endPort;
this.allowedCidrs = allowedCidrs;
setAllowedCidrs(allowedCidrs);
}
public String[] getAllowedCidrs() {
public List<String> getAllowedCidrs() {
return allowedCidrs;
}
public void setAllowedCidrs(String[] allowedCidrs) {
this.allowedCidrs = allowedCidrs;
public void setAllowedCidrs(final String... allowedCidrs) {
this.allowedCidrs = new ArrayList<String>();
for (final String allowedCidr : allowedCidrs) {
this.allowedCidrs.add(allowedCidr);
}
}
public String getProto() {
@ -74,52 +91,28 @@ public class SecurityGroupRulesCmd extends Command {
}
String guestIp;
String vmName;
String guestMac;
String signature;
Long seqNum;
Long vmId;
Long msId;
IpPortAndProto[] ingressRuleSet;
IpPortAndProto[] egressRuleSet;
private List<String> secIps;
public SecurityGroupRulesCmd() {
super();
}
public SecurityGroupRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ingressRuleSet,
IpPortAndProto[] egressRuleSet) {
super();
public SecurityGroupRulesCmd(
final String guestIp,
final String guestMac,
final String vmName,
final Long vmId,
final String signature,
final Long seqNum,
final IpPortAndProto[] ingressRuleSet,
final IpPortAndProto[] egressRuleSet,
final List<String> secIps) {
this.guestIp = guestIp;
this.vmName = vmName;
this.ingressRuleSet = ingressRuleSet;
this.egressRuleSet = egressRuleSet;
setIngressRuleSet(ingressRuleSet);
this.setEgressRuleSet(egressRuleSet);
this.guestMac = guestMac;
this.signature = signature;
this.seqNum = seqNum;
this.vmId = vmId;
if (signature == null) {
String stringified = stringifyRules();
this.signature = DigestUtils.md5Hex(stringified);
}
}
public SecurityGroupRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ingressRuleSet,
IpPortAndProto[] egressRuleSet, List<String> secIps) {
super();
this.guestIp = guestIp;
this.vmName = vmName;
this.ingressRuleSet = ingressRuleSet;
this.egressRuleSet = egressRuleSet;
this.guestMac = guestMac;
this.signature = signature;
this.seqNum = seqNum;
this.vmId = vmId;
if (signature == null) {
String stringified = stringifyRules();
final String stringified = stringifyRules();
this.signature = DigestUtils.md5Hex(stringified);
} else {
this.signature = signature;
}
this.secIps = secIps;
}
@ -129,20 +122,26 @@ public class SecurityGroupRulesCmd extends Command {
return true;
}
public IpPortAndProto[] getIngressRuleSet() {
public List<IpPortAndProto> getIngressRuleSet() {
return ingressRuleSet;
}
public void setIngressRuleSet(IpPortAndProto[] ingressRuleSet) {
this.ingressRuleSet = ingressRuleSet;
public void setIngressRuleSet(final IpPortAndProto... ingressRuleSet) {
this.ingressRuleSet = new ArrayList<IpPortAndProto>();
for(final IpPortAndProto rule: ingressRuleSet) {
this.ingressRuleSet.add(rule);
}
}
public IpPortAndProto[] getEgressRuleSet() {
public List<IpPortAndProto> getEgressRuleSet() {
return egressRuleSet;
}
public void setEgressRuleSet(IpPortAndProto[] egressRuleSet) {
this.egressRuleSet = egressRuleSet;
public void setEgressRuleSet(final IpPortAndProto... egressRuleSet) {
this.egressRuleSet = new ArrayList<IpPortAndProto>();
for(final IpPortAndProto rule: egressRuleSet) {
this.egressRuleSet.add(rule);
}
}
public String getGuestIp() {
@ -157,105 +156,77 @@ public class SecurityGroupRulesCmd extends Command {
return vmName;
}
public String stringifyRules() {
StringBuilder ruleBuilder = new StringBuilder();
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) {
ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
for (String cidr : ipPandP.getAllowedCidrs()) {
ruleBuilder.append(cidr).append(",");
}
ruleBuilder.append("NEXT");
ruleBuilder.append(" ");
}
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getEgressRuleSet()) {
ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
for (String cidr : ipPandP.getAllowedCidrs()) {
ruleBuilder.append(cidr).append(",");
}
ruleBuilder.append("NEXT");
ruleBuilder.append(" ");
}
return ruleBuilder.toString();
}
//convert cidrs in the form "a.b.c.d/e" to "hexvalue of 32bit ip/e"
private String compressCidr(String cidr) {
String[] toks = cidr.split("/");
long ipnum = NetUtils.ip2Long(toks[0]);
return Long.toHexString(ipnum) + "/" + toks[1];
private String compressCidrToHexRepresentation(final String cidr) {
final String[] toks = cidr.split(CIDR_LENGTH_SEPARATOR);
final long ipnum = NetUtils.ip2Long(toks[0]);
return Long.toHexString(ipnum) + CIDR_LENGTH_SEPARATOR + toks[1];
}
public String getSecIpsString() {
StringBuilder sb = new StringBuilder();
List<String> ips = getSecIps();
final StringBuilder sb = new StringBuilder();
final List<String> ips = getSecIps();
if (ips == null) {
return "0:";
sb.append("0:");
} else {
for (String ip : ips) {
sb.append(ip).append(":");
for (final String ip : ips) {
sb.append(ip).append(RULE_COMMAND_SEPARATOR);
}
}
return sb.toString();
}
public String stringifyCompressedRules() {
StringBuilder ruleBuilder = new StringBuilder();
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) {
ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
for (String cidr : ipPandP.getAllowedCidrs()) {
//convert cidrs in the form "a.b.c.d/e" to "hexvalue of 32bit ip/e"
ruleBuilder.append(compressCidr(cidr)).append(",");
}
ruleBuilder.append("NEXT");
ruleBuilder.append(" ");
}
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getEgressRuleSet()) {
ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
for (String cidr : ipPandP.getAllowedCidrs()) {
//convert cidrs in the form "a.b.c.d/e" to "hexvalue of 32bit ip/e"
ruleBuilder.append(compressCidr(cidr)).append(",");
}
ruleBuilder.append("NEXT");
ruleBuilder.append(" ");
}
public String stringifyRules() {
final StringBuilder ruleBuilder = new StringBuilder();
stringifyRulesFor(getIngressRuleSet(), INGRESS_RULE, false, ruleBuilder);
stringifyRulesFor(getEgressRuleSet(), EGRESS_RULE, false, ruleBuilder);
return ruleBuilder.toString();
}
/*
public String stringifyCompressedRules() {
final StringBuilder ruleBuilder = new StringBuilder();
stringifyRulesFor(getIngressRuleSet(), INGRESS_RULE, true, ruleBuilder);
stringifyRulesFor(getEgressRuleSet(), EGRESS_RULE, true, ruleBuilder);
return ruleBuilder.toString();
}
private void stringifyRulesFor(final List<IpPortAndProto> ipPortAndProtocols, final String inOrEgress, final boolean compressed, final StringBuilder ruleBuilder) {
for (final IpPortAndProto ipPandP : ipPortAndProtocols) {
ruleBuilder.append(inOrEgress).append(ipPandP.getProto()).append(RULE_COMMAND_SEPARATOR).append(ipPandP.getStartPort()).append(RULE_COMMAND_SEPARATOR)
.append(ipPandP.getEndPort()).append(RULE_COMMAND_SEPARATOR);
for (final String cidr : ipPandP.getAllowedCidrs()) {
ruleBuilder.append(represent(cidr, compressed)).append(RULE_TARGET_SEPARATOR);
}
ruleBuilder.append("NEXT ");
}
}
private String represent(final String cidr, final boolean compressed) {
if (compressed) {
return compressCidrToHexRepresentation(cidr);
} else {
return cidr;
}
}
/**
* Compress the security group rules using zlib compression to allow the call to the hypervisor
* to scale beyond 8k cidrs.
* Note : not using {@see GZipOutputStream} since that is for files, using {@see DeflaterOutputStream} instead.
* {@see GZipOutputStream} gives a different header, although the compression is the same
*/
public String compressStringifiedRules() {
StringBuilder ruleBuilder = new StringBuilder();
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) {
ruleBuilder.append("I:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
for (String cidr : ipPandP.getAllowedCidrs()) {
ruleBuilder.append(cidr).append(",");
}
ruleBuilder.append("NEXT");
ruleBuilder.append(" ");
}
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getEgressRuleSet()) {
ruleBuilder.append("E:").append(ipPandP.getProto()).append(":").append(ipPandP.getStartPort()).append(":").append(ipPandP.getEndPort()).append(":");
for (String cidr : ipPandP.getAllowedCidrs()) {
ruleBuilder.append(cidr).append(",");
}
ruleBuilder.append("NEXT");
ruleBuilder.append(" ");
}
String stringified = ruleBuilder.toString();
ByteArrayOutputStream out = new ByteArrayOutputStream();
final String stringified = stringifyRules();
final ByteArrayOutputStream out = new ByteArrayOutputStream();
String encodedResult = null;
try {
//Note : not using GZipOutputStream since that is for files
//GZipOutputStream gives a different header, although the compression is the same
DeflaterOutputStream dzip = new DeflaterOutputStream(out);
final DeflaterOutputStream dzip = new DeflaterOutputStream(out);
dzip.write(stringified.getBytes());
dzip.close();
} catch (IOException e) {
s_logger.warn("Exception while compressing security group rules");
return null;
encodedResult = Base64.encodeBase64String(out.toByteArray());
} catch (final IOException e) {
LOGGER.warn("Exception while compressing security group rules");
}
return Base64.encodeBase64String(out.toByteArray());
return encodedResult;
}
public String getSignature() {
@ -274,19 +245,22 @@ public class SecurityGroupRulesCmd extends Command {
return vmId;
}
/**
* used for logging
* @return the number of Cidrs in the in and egress rule sets for this security group rules command.
*/
public int getTotalNumCidrs() {
//useful for logging
int count = 0;
for (IpPortAndProto i : ingressRuleSet) {
count += i.allowedCidrs.length;
for (final IpPortAndProto i : ingressRuleSet) {
count += i.allowedCidrs.size();
}
for (IpPortAndProto i : egressRuleSet) {
count += i.allowedCidrs.length;
for (final IpPortAndProto i : egressRuleSet) {
count += i.allowedCidrs.size();
}
return count;
}
public void setMsId(long msId) {
public void setMsId(final long msId) {
this.msId = msId;
}

View File

@ -0,0 +1,93 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.api;
import static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.Vector;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto;
/**
* @author daan
*
*/
@RunWith(MockitoJUnitRunner.class)
public class SecurityGroupRulesCmdTest {
private SecurityGroupRulesCmd securityGroupRulesCmd;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
final String guestIp = "10.10.10.10";
final String guestMac = "aa:aa:aa:aa:aa:aa";
final String vmName = "vm";
final Long vmId = 1L;
final String signature = "sig";
final Long seqNum = 0L;
final String proto = "abc";
final int startPort = 1;
final int endPort = 2;
final String[] allowedCidrs = new String[] {"1.2.3.4/5","6.7.8.9/0"};
final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{new IpPortAndProto(proto, startPort, endPort, allowedCidrs)};
final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{new IpPortAndProto(proto, startPort, endPort, allowedCidrs)};
final List<String> secIps = new Vector<String>();
securityGroupRulesCmd = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
}
/**
* Test method for {@link com.cloud.agent.api.SecurityGroupRulesCmd#stringifyRules()}.
*/
@Test
public void testStringifyRules() throws Exception {
final String a = securityGroupRulesCmd.stringifyRules();
// do verification on a
assertTrue(a.contains(SecurityGroupRulesCmd.EGRESS_RULE));
}
/**
* Test method for {@link com.cloud.agent.api.SecurityGroupRulesCmd#stringifyCompressedRules()}.
*/
@Test
public void testStringifyCompressedRules() throws Exception {
final String a = securityGroupRulesCmd.stringifyCompressedRules();
// do verification on a
assertTrue(a.contains(SecurityGroupRulesCmd.EGRESS_RULE));
}
/**
* Test method for {@link com.cloud.agent.api.SecurityGroupRulesCmd#compressStringifiedRules()}.
*/
@Test
public void testCompressStringifiedRules() throws Exception {
final String compressed = "eJzztEpMSrYytDKyMtQz0jPWM9E31THTM9ez0LPUN9Dxc40IUXAlrAQAPdoP3Q==";
final String a = securityGroupRulesCmd.compressStringifiedRules();
assertTrue(compressed.equals(a));
}
}

View File

@ -1,205 +1,205 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// Automatically generated by addcopyright.py at 01/29/2013
// Apache License, Version 2.0 (the "License"); you may not use this
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.networkservice;
import com.cloud.agent.api.SecurityGroupRuleAnswer;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto;
import com.cloud.baremetal.networkservice.schema.SecurityGroupRule;
import com.cloud.baremetal.networkservice.schema.SecurityGroupVmRuleSet;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.log4j.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class SecurityGroupHttpClient {
private static final Logger logger = Logger.getLogger(SecurityGroupHttpClient.class);
private static final String ARG_NAME = "args";
private static final String COMMAND = "command";
private JAXBContext context;
private int port;
private static HttpClient httpClient;
static {
MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager();
httpClient = new HttpClient(connman);
httpClient.setConnectionTimeout(5000);
}
private enum OpConstant {
setRules, echo,
}
public SecurityGroupHttpClient() {
try {
context = JAXBContext.newInstance(SecurityGroupRule.class, SecurityGroupVmRuleSet.class);
port = 9988;
} catch (Exception e) {
throw new CloudRuntimeException(
"Unable to create JAXBContext for security group", e);
}
}
private List<SecurityGroupRule> generateRules(IpPortAndProto[] ipps) {
List<SecurityGroupRule> rules = new ArrayList<SecurityGroupRule>(
ipps.length);
for (SecurityGroupRulesCmd.IpPortAndProto ipp : ipps) {
SecurityGroupRule r = new SecurityGroupRule();
r.setProtocol(ipp.getProto());
r.setStartPort(ipp.getStartPort());
r.setEndPort(ipp.getEndPort());
for (String cidr : ipp.getAllowedCidrs()) {
r.getIp().add(cidr);
}
rules.add(r);
}
return rules;
}
public HashMap<String, Pair<Long, Long>> sync(String vmName, Long vmId, String agentIp) {
HashMap<String, Pair<Long, Long>> states = new HashMap<String, Pair<Long, Long>>();
PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort()));
try {
post.addRequestHeader("command", "sync");
if (httpClient.executeMethod(post) != 200) {
logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString()));
} else {
String res = post.getResponseBodyAsString();
// res = ';'.join([vmName, vmId, seqno])
String[] rulelogs = res.split(",");
if (rulelogs.length != 6) {
logger.debug(String.format("host[%s] returns invalid security group sync document[%s], reset rules", agentIp, res));
states.put(vmName, new Pair<Long, Long>(vmId, -1L));
return states;
}
Pair<Long, Long> p = new Pair<Long, Long>(Long.valueOf(rulelogs[1]), Long.valueOf(rulelogs[5]));
states.put(rulelogs[0], p);
return states;
}
} catch (SocketTimeoutException se) {
logger.warn(String.format("unable to sync security group rules on host[%s], %s", agentIp, se.getMessage()));
} catch (Exception e) {
logger.warn(String.format("unable to sync security group rules on host[%s]", agentIp), e);
} finally {
if (post != null) {
post.releaseConnection();
}
}
return states;
}
public boolean echo(String agentIp, long l, long m) {
boolean ret = false;
int count = 1;
while (true) {
try {
Thread.sleep(m);
count++;
} catch (InterruptedException e1) {
logger.warn("", e1);
break;
}
PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort()));
try {
post.addRequestHeader("command", "echo");
if (httpClient.executeMethod(post) != 200) {
logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString()));
} else {
ret = true;
}
break;
} catch (Exception e) {
if (count*m >= l) {
logger.debug(String.format("ping security group agent on vm[%s] timeout after %s minutes, starting vm failed, count=%s", agentIp, TimeUnit.MILLISECONDS.toSeconds(l), count));
break;
} else {
logger.debug(String.format("Having pinged security group agent on vm[%s] %s times, continue to wait...", agentIp, count));
}
} finally {
if (post != null) {
post.releaseConnection();
}
}
}
return ret;
}
public SecurityGroupRuleAnswer call(String agentIp, SecurityGroupRulesCmd cmd) {
PostMethod post = new PostMethod(String.format(
"http://%s:%s", agentIp, getPort()));
try {
SecurityGroupVmRuleSet rset = new SecurityGroupVmRuleSet();
rset.getEgressRules().addAll(generateRules(cmd.getEgressRuleSet()));
rset.getIngressRules().addAll(
generateRules(cmd.getIngressRuleSet()));
rset.setVmName(cmd.getVmName());
rset.setVmIp(cmd.getGuestIp());
rset.setVmMac(cmd.getGuestMac());
rset.setVmId(cmd.getVmId());
rset.setSignature(cmd.getSignature());
rset.setSequenceNumber(cmd.getSeqNum());
Marshaller marshaller = context.createMarshaller();
StringWriter writer = new StringWriter();
marshaller.marshal(rset, writer);
String xmlContents = writer.toString();
logger.debug(xmlContents);
post.addRequestHeader("command", "set_rules");
StringRequestEntity entity = new StringRequestEntity(xmlContents);
post.setRequestEntity(entity);
if (httpClient.executeMethod(post) != 200) {
return new SecurityGroupRuleAnswer(cmd, false,
post.getResponseBodyAsString());
} else {
return new SecurityGroupRuleAnswer(cmd);
}
} catch (Exception e) {
return new SecurityGroupRuleAnswer(cmd, false, e.getMessage());
} finally {
if (post != null) {
post.releaseConnection();
}
}
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// Automatically generated by addcopyright.py at 01/29/2013
// Apache License, Version 2.0 (the "License"); you may not use this
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.networkservice;
import com.cloud.agent.api.SecurityGroupRuleAnswer;
import com.cloud.agent.api.SecurityGroupRulesCmd;
import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto;
import com.cloud.baremetal.networkservice.schema.SecurityGroupRule;
import com.cloud.baremetal.networkservice.schema.SecurityGroupVmRuleSet;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.log4j.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class SecurityGroupHttpClient {
private static final Logger logger = Logger.getLogger(SecurityGroupHttpClient.class);
private static final String ARG_NAME = "args";
private static final String COMMAND = "command";
private JAXBContext context;
private int port;
private static HttpClient httpClient;
static {
MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager();
httpClient = new HttpClient(connman);
httpClient.setConnectionTimeout(5000);
}
private enum OpConstant {
setRules, echo,
}
public SecurityGroupHttpClient() {
try {
context = JAXBContext.newInstance(SecurityGroupRule.class, SecurityGroupVmRuleSet.class);
port = 9988;
} catch (Exception e) {
throw new CloudRuntimeException(
"Unable to create JAXBContext for security group", e);
}
}
private List<SecurityGroupRule> generateRules(final List<IpPortAndProto> ipps) {
List<SecurityGroupRule> rules = new ArrayList<SecurityGroupRule>(
ipps.size());
for (SecurityGroupRulesCmd.IpPortAndProto ipp : ipps) {
SecurityGroupRule r = new SecurityGroupRule();
r.setProtocol(ipp.getProto());
r.setStartPort(ipp.getStartPort());
r.setEndPort(ipp.getEndPort());
for (String cidr : ipp.getAllowedCidrs()) {
r.getIp().add(cidr);
}
rules.add(r);
}
return rules;
}
public HashMap<String, Pair<Long, Long>> sync(String vmName, Long vmId, String agentIp) {
HashMap<String, Pair<Long, Long>> states = new HashMap<String, Pair<Long, Long>>();
PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort()));
try {
post.addRequestHeader("command", "sync");
if (httpClient.executeMethod(post) != 200) {
logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString()));
} else {
String res = post.getResponseBodyAsString();
// res = ';'.join([vmName, vmId, seqno])
String[] rulelogs = res.split(",");
if (rulelogs.length != 6) {
logger.debug(String.format("host[%s] returns invalid security group sync document[%s], reset rules", agentIp, res));
states.put(vmName, new Pair<Long, Long>(vmId, -1L));
return states;
}
Pair<Long, Long> p = new Pair<Long, Long>(Long.valueOf(rulelogs[1]), Long.valueOf(rulelogs[5]));
states.put(rulelogs[0], p);
return states;
}
} catch (SocketTimeoutException se) {
logger.warn(String.format("unable to sync security group rules on host[%s], %s", agentIp, se.getMessage()));
} catch (Exception e) {
logger.warn(String.format("unable to sync security group rules on host[%s]", agentIp), e);
} finally {
if (post != null) {
post.releaseConnection();
}
}
return states;
}
public boolean echo(String agentIp, long l, long m) {
boolean ret = false;
int count = 1;
while (true) {
try {
Thread.sleep(m);
count++;
} catch (InterruptedException e1) {
logger.warn("", e1);
break;
}
PostMethod post = new PostMethod(String.format("http://%s:%s/", agentIp, getPort()));
try {
post.addRequestHeader("command", "echo");
if (httpClient.executeMethod(post) != 200) {
logger.debug(String.format("echoing baremetal security group agent on %s got error: %s", agentIp, post.getResponseBodyAsString()));
} else {
ret = true;
}
break;
} catch (Exception e) {
if (count*m >= l) {
logger.debug(String.format("ping security group agent on vm[%s] timeout after %s minutes, starting vm failed, count=%s", agentIp, TimeUnit.MILLISECONDS.toSeconds(l), count));
break;
} else {
logger.debug(String.format("Having pinged security group agent on vm[%s] %s times, continue to wait...", agentIp, count));
}
} finally {
if (post != null) {
post.releaseConnection();
}
}
}
return ret;
}
public SecurityGroupRuleAnswer call(String agentIp, SecurityGroupRulesCmd cmd) {
PostMethod post = new PostMethod(String.format(
"http://%s:%s", agentIp, getPort()));
try {
SecurityGroupVmRuleSet rset = new SecurityGroupVmRuleSet();
rset.getEgressRules().addAll(generateRules(cmd.getEgressRuleSet()));
rset.getIngressRules().addAll(
generateRules(cmd.getIngressRuleSet()));
rset.setVmName(cmd.getVmName());
rset.setVmIp(cmd.getGuestIp());
rset.setVmMac(cmd.getGuestMac());
rset.setVmId(cmd.getVmId());
rset.setSignature(cmd.getSignature());
rset.setSequenceNumber(cmd.getSeqNum());
Marshaller marshaller = context.createMarshaller();
StringWriter writer = new StringWriter();
marshaller.marshal(rset, writer);
String xmlContents = writer.toString();
logger.debug(xmlContents);
post.addRequestHeader("command", "set_rules");
StringRequestEntity entity = new StringRequestEntity(xmlContents);
post.setRequestEntity(entity);
if (httpClient.executeMethod(post) != 200) {
return new SecurityGroupRuleAnswer(cmd, false,
post.getResponseBodyAsString());
} else {
return new SecurityGroupRuleAnswer(cmd);
}
} catch (Exception e) {
return new SecurityGroupRuleAnswer(cmd, false, e.getMessage());
} finally {
if (post != null) {
post.releaseConnection();
}
}
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}

View File

@ -62,7 +62,7 @@ public final class LibvirtSecurityGroupRulesCommandWrapper extends CommandWrappe
return new SecurityGroupRuleAnswer(command, false, "programming network rules failed");
} else {
s_logger.debug("Programmed network rules for vm " + command.getVmName() + " guestIp=" + command.getGuestIp() + ",ingress numrules="
+ command.getIngressRuleSet().length + ",egress numrules=" + command.getEgressRuleSet().length);
+ command.getIngressRuleSet().size() + ",egress numrules=" + command.getEgressRuleSet().size());
return new SecurityGroupRuleAnswer(command);
}
}

View File

@ -39,6 +39,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.Vector;
import javax.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
@ -2893,8 +2894,11 @@ public class LibvirtComputingResourceTest {
final Long seqNum = 1l;
final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
final List<String> secIps = new Vector<String>();
final List<String> cidrs = new Vector<String>();
cidrs.add("0.0.0.0/0");
final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet);
final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
final Connect conn = Mockito.mock(Connect.class);
@ -2914,12 +2918,12 @@ public class LibvirtComputingResourceTest {
when(ingressRuleSet[0].getProto()).thenReturn("tcp");
when(ingressRuleSet[0].getStartPort()).thenReturn(22);
when(ingressRuleSet[0].getEndPort()).thenReturn(22);
when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(new String[]{"0.0.0.0/0"});
when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
when(egressRuleSet[0].getProto()).thenReturn("tcp");
when(egressRuleSet[0].getStartPort()).thenReturn(22);
when(egressRuleSet[0].getEndPort()).thenReturn(22);
when(egressRuleSet[0].getAllowedCidrs()).thenReturn(new String[]{"0.0.0.0/0"});
when(egressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
assertNotNull(wrapper);
@ -2945,8 +2949,11 @@ public class LibvirtComputingResourceTest {
final Long seqNum = 1l;
final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
final List<String> secIps = new Vector<String>();
final List<String> cidrs = new Vector<String>();
cidrs.add("0.0.0.0/0");
final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet);
final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
final Connect conn = Mockito.mock(Connect.class);
@ -2972,12 +2979,12 @@ public class LibvirtComputingResourceTest {
when(ingressRuleSet[0].getProto()).thenReturn("tcp");
when(ingressRuleSet[0].getStartPort()).thenReturn(22);
when(ingressRuleSet[0].getEndPort()).thenReturn(22);
when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(new String[]{"0.0.0.0/0"});
when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
when(egressRuleSet[0].getProto()).thenReturn("tcp");
when(egressRuleSet[0].getStartPort()).thenReturn(22);
when(egressRuleSet[0].getEndPort()).thenReturn(22);
when(egressRuleSet[0].getAllowedCidrs()).thenReturn(new String[]{"0.0.0.0/0"});
when(egressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
when(libvirtComputingResource.addNetworkRules(command.getVmName(), Long.toString(command.getVmId()), command.getGuestIp(), command.getSignature(),
Long.toString(command.getSeqNum()), command.getGuestMac(), command.stringifyRules(), vif, brname, command.getSecIpsString())).thenReturn(true);
@ -3007,8 +3014,9 @@ public class LibvirtComputingResourceTest {
final Long seqNum = 1l;
final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
final List<String> secIps = new Vector<String>();
final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet);
final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
final Connect conn = Mockito.mock(Connect.class);

View File

@ -940,8 +940,8 @@ public class OvmResourceBase implements ServerResource, HypervisorResource {
s_logger.warn("Failed to program network rules for vm " + cmd.getVmName());
return new SecurityGroupRuleAnswer(cmd, false, "programming network rules failed");
} else {
s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ":ingress num rules=" + cmd.getIngressRuleSet().length +
":egress num rules=" + cmd.getEgressRuleSet().length);
s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ":ingress num rules=" + cmd.getIngressRuleSet().size() +
":egress num rules=" + cmd.getEgressRuleSet().size());
return new SecurityGroupRuleAnswer(cmd);
}
}

View File

@ -626,7 +626,7 @@ public class MockVmManagerImpl extends ManagerBase implements MockVmManager {
reason = ", seqno_new";
}
s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " seqno=" + cmd.getSeqNum() + " signature=" + cmd.getSignature() + " guestIp=" +
cmd.getGuestIp() + ", numIngressRules=" + cmd.getIngressRuleSet().length + ", numEgressRules=" + cmd.getEgressRuleSet().length + " total cidrs=" +
cmd.getGuestIp() + ", numIngressRules=" + cmd.getIngressRuleSet().size() + ", numEgressRules=" + cmd.getEgressRuleSet().size() + " total cidrs=" +
cmd.getTotalNumCidrs() + action + reason);
return updateSeqnoAndSig;
}

View File

@ -56,7 +56,7 @@ public final class CitrixSecurityGroupRulesCommandWrapper extends CommandWrapper
return new SecurityGroupRuleAnswer(command, false, "programming network rules failed");
} else {
s_logger.info("Programmed network rules for vm " + command.getVmName() + " guestIp=" + command.getGuestIp() + ", ingress numrules="
+ command.getIngressRuleSet().length + ", egress numrules=" + command.getEgressRuleSet().length);
+ command.getIngressRuleSet().size() + ", egress numrules=" + command.getEgressRuleSet().size());
return new SecurityGroupRuleAnswer(command);
}
}

View File

@ -33,6 +33,7 @@ import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.apache.cloudstack.storage.command.AttachAnswer;
import org.apache.cloudstack.storage.command.AttachCommand;
@ -101,6 +102,7 @@ import com.cloud.agent.api.UnPlugNicCommand;
import com.cloud.agent.api.UpdateHostPasswordCommand;
import com.cloud.agent.api.UpgradeSnapshotCommand;
import com.cloud.agent.api.VMSnapshotTO;
import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
@ -740,7 +742,17 @@ public class CitrixRequestWrapperTest {
final Connection conn = Mockito.mock(Connection.class);
final XsHost xsHost = Mockito.mock(XsHost.class);
final SecurityGroupRulesCmd sshCommand = new SecurityGroupRulesCmd();
final String guestIp = "127.0.0.1";
final String guestMac = "00:00:00:00";
final String vmName = "Test";
final Long vmId = 1l;
final String signature = "signature";
final Long seqNum = 1l;
final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
final List<String> secIps = new Vector<String>();
final SecurityGroupRulesCmd sshCommand = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
assertNotNull(wrapper);

View File

@ -182,8 +182,6 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl {
List<String> nicSecIps = null;
if (nic != null) {
if (nic.getSecondaryIp()) {
//get secondary ips of the vm
long networkId = nic.getNetworkId();
nicSecIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nic.getId());
}
}
@ -193,7 +191,7 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl {
cmd.setMsId(_serverId);
if (s_logger.isDebugEnabled()) {
s_logger.debug("SecurityGroupManager v2: sending ruleset update for vm " + vm.getInstanceName() + ":ingress num rules=" +
cmd.getIngressRuleSet().length + ":egress num rules=" + cmd.getEgressRuleSet().length + " num cidrs=" + cmd.getTotalNumCidrs() + " sig=" +
cmd.getIngressRuleSet().size() + ":egress num rules=" + cmd.getEgressRuleSet().size() + " num cidrs=" + cmd.getTotalNumCidrs() + " sig=" +
cmd.getSignature());
}
Commands cmds = new Commands(cmd);