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