// 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; } }