blob: b0053500464019ce403650f3354ea7f75f8d4020 [file] [log] [blame]
// 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.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
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 {
protected Logger logger = LogManager.getLogger(getClass());
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;
}
}