You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ya...@apache.org on 2013/11/06 19:08:41 UTC
[2/5] Squashed commit of the Palo Alto Networks firewall integration
plugin.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f8ad3f3/plugins/network-elements/palo-alto/src/com/cloud/network/utils/HttpClientWrapper.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/network/utils/HttpClientWrapper.java b/plugins/network-elements/palo-alto/src/com/cloud/network/utils/HttpClientWrapper.java
new file mode 100644
index 0000000..7e40570
--- /dev/null
+++ b/plugins/network-elements/palo-alto/src/com/cloud/network/utils/HttpClientWrapper.java
@@ -0,0 +1,69 @@
+package com.cloud.network.utils;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import java.io.*;
+
+public class HttpClientWrapper {
+
+ public static HttpClient wrapClient(HttpClient base) {
+ try {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ X509TrustManager tm = new X509TrustManager() {
+
+ public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
+ }
+
+ public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ };
+ X509HostnameVerifier verifier = new X509HostnameVerifier() {
+
+ @Override
+ public void verify(String string, SSLSocket ssls) throws IOException {
+ }
+
+ @Override
+ public void verify(String string, X509Certificate xc) throws SSLException {
+ }
+
+ @Override
+ public void verify(String string, String[] strings, String[] strings1) throws SSLException {
+ }
+
+ @Override
+ public boolean verify(String string, SSLSession ssls) {
+ return true;
+ }
+ };
+ ctx.init(null, new TrustManager[]{tm}, null);
+ SSLSocketFactory ssf = new SSLSocketFactory(ctx);
+ ssf.setHostnameVerifier(verifier);
+ ClientConnectionManager ccm = base.getConnectionManager();
+ SchemeRegistry sr = ccm.getSchemeRegistry();
+ sr.register(new Scheme("https", ssf, 443));
+ return new DefaultHttpClient(ccm, base.getParams());
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f8ad3f3/plugins/network-elements/palo-alto/test/com/cloud/network/resource/MockablePaloAltoResource.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/palo-alto/test/com/cloud/network/resource/MockablePaloAltoResource.java b/plugins/network-elements/palo-alto/test/com/cloud/network/resource/MockablePaloAltoResource.java
new file mode 100755
index 0000000..9a9eb6e
--- /dev/null
+++ b/plugins/network-elements/palo-alto/test/com/cloud/network/resource/MockablePaloAltoResource.java
@@ -0,0 +1,460 @@
+// 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.network.resource;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import javax.naming.ConfigurationException;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
+import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalFirewallCommand;
+import com.cloud.agent.api.routing.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.to.FirewallRuleTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.host.Host;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.TrafficType;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.Script;
+
+// http client handling
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.BasicResponseHandler;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.protocol.HTTP;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.net.URLDecoder;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import com.cloud.network.utils.HttpClientWrapper;
+
+// for prettyFormat()
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import java.io.StringWriter;
+
+
+public class MockablePaloAltoResource extends PaloAltoResource {
+ private HashMap<String, String> context;
+ public void setMockContext(HashMap<String, String> context) {
+ this.context = context;
+ }
+
+ /* Fake the calls to the Palo Alto API */
+ protected String request(PaloAltoMethod method, Map<String, String> params) throws ExecutionException {
+ if (method != PaloAltoMethod.GET && method != PaloAltoMethod.POST) {
+ throw new ExecutionException("Invalid http method used to access the Palo Alto API.");
+ }
+
+ String response = "";
+
+ // 'keygen' request
+ if (params.containsKey("type") && params.get("type").equals("keygen")) {
+ response = "<response status = 'success'><result><key>LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09</key></result></response>";
+ }
+
+ // 'config' requests
+ if (params.containsKey("type") && params.get("type").equals("config") && params.containsKey("action")) {
+ // action = 'get'
+ if (params.get("action").equals("get")) {
+ // get interface for type
+ // | public_using_ethernet
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/1']")) {
+ if (context.containsKey("public_using_ethernet") && context.get("public_using_ethernet").equals("true")) {
+ context.put("public_interface_type", "ethernet");
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"ethernet1/1\" admin=\"admin\" time=\"2013/06/18 13:33:56\"><layer3 admin=\"admin\" time=\"2013/06/18 13:33:56\"><ipv6><neighbor-discovery><router-advertisement><enable>no</enable><min-interval>200</min-interval><max-interval>600</max-interval><hop-limit>64</hop-limit><reachable-time>unspecified</reachable-time><retransmission-timer>unspecified</retransmission-timer><lifetime>1800</lifetime><managed-flag>no</managed-flag><other-flag>no</other-flag><enable-consistency-check>no</enable-consistency-check><link-mtu>unspecified</link-mtu></router-advertisement><enable-dad>no</enable-dad><reachable-time>30</reachable-time><ns-interval>1</ns-interval><dad-attempts>1</dad-attempts></neighbor-discovery><enabled>no</enabled><interface-id>EUI-64</interface-id></ipv6><untagged-sub-interface>no</untagged-sub-interface><units admin=\"admin\" time=\"2013/06/18 13:33:56\">
<entry name=\"ethernet1/1.9999\" admin=\"admin\" time=\"2013/06/18 13:33:56\"><ipv6><neighbor-discovery><router-advertisement><enable>no</enable><min-interval>200</min-interval><max-interval>600</max-interval><hop-limit>64</hop-limit><reachable-time>unspecified</reachable-time><retransmission-timer>unspecified</retransmission-timer><lifetime>1800</lifetime><managed-flag>no</managed-flag><other-flag>no</other-flag><enable-consistency-check>no</enable-consistency-check><link-mtu>unspecified</link-mtu></router-advertisement><enable-dad>no</enable-dad><reachable-time>30</reachable-time><ns-interval>1</ns-interval><dad-attempts>1</dad-attempts></neighbor-discovery><enabled>no</enabled><interface-id>EUI-64</interface-id></ipv6><ip admin=\"admin\" time=\"2013/06/18 13:33:56\"><entry name=\"192.168.80.254/24\"/></ip><adjust-tcp-mss>no</adjust-tcp-mss><tag>3033</tag></entry></units></layer3><link-speed>auto</link-speed><link-duplex>auto</link-duplex><link-state>auto</link-state></entry></res
ult></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ } // | private_using_ethernet
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/2']")) {
+ if (context.containsKey("private_using_ethernet") && context.get("private_using_ethernet").equals("true")) {
+ context.put("private_interface_type", "ethernet");
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"ethernet1/2\" admin=\"admin\" time=\"2013/06/18 13:33:57\"><layer3 admin=\"admin\" time=\"2013/06/18 13:33:57\"><ipv6><neighbor-discovery><router-advertisement><enable>no</enable><min-interval>200</min-interval><max-interval>600</max-interval><hop-limit>64</hop-limit><reachable-time>unspecified</reachable-time><retransmission-timer>unspecified</retransmission-timer><lifetime>1800</lifetime><managed-flag>no</managed-flag><other-flag>no</other-flag><enable-consistency-check>no</enable-consistency-check><link-mtu>unspecified</link-mtu></router-advertisement><enable-dad>no</enable-dad><reachable-time>30</reachable-time><ns-interval>1</ns-interval><dad-attempts>1</dad-attempts></neighbor-discovery><enabled>no</enabled><interface-id>EUI-64</interface-id></ipv6><untagged-sub-interface>no</untagged-sub-interface><units admin=\"admin\" time=\"2013/06/18 13:33:57\"/
></layer3><link-speed>auto</link-speed><link-duplex>auto</link-duplex><link-state>auto</link-state></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get management profile | has_management_profile
+ if (params.get("xpath").equals("/config/devices/entry/network/profiles/interface-management-profile/entry[@name='Ping']")) {
+ if (context.containsKey("has_management_profile") && context.get("has_management_profile").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"Ping\"><ping>yes</ping></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get public interface IP | has_public_interface
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/1']/layer3/units/entry[@name='ethernet1/1.9999']/ip/entry[@name='192.168.80.102/32']")) {
+ if (context.containsKey("has_public_interface") && context.get("has_public_interface").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"192.168.80.102/32\" admin=\"admin\" time=\"2013/07/05 13:02:37\"/></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get private interface | has_private_interface
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/2']/layer3/units/entry[@name='ethernet1/2.3954']")) {
+ if (context.containsKey("has_private_interface") && context.get("has_private_interface").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"ethernet1/2.3954\" admin=\"admin\" time=\"2013/07/05 13:02:36\"><tag admin=\"admin\" time=\"2013/07/05 13:02:36\">3954</tag><ip><entry name=\"10.5.80.1/20\"/></ip><interface-management-profile>Ping</interface-management-profile></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get private interface ip
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/2']/layer3/units/entry[@name='ethernet1/2.3954']/ip/entry")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"10.3.96.1/20\"/></result></response>";
+ }
+
+ // get source nat | has_src_nat_rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='src_nat.3954']")) {
+ if (context.containsKey("has_src_nat_rule") && context.get("has_src_nat_rule").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"src_nat.3954\" admin=\"admin\" time=\"2013/07/05 13:02:38\"><to admin=\"admin\" time=\"2013/07/05 13:02:38\"><member admin=\"admin\" time=\"2013/07/05 13:02:38\">untrust</member></to><from><member>trust</member></from><source><member>10.5.80.1/20</member></source><destination><member>any</member></destination><service>any</service><nat-type>ipv4</nat-type><to-interface>ethernet1/1.9999</to-interface><source-translation><dynamic-ip-and-port><interface-address><ip>192.168.80.102/32</ip><interface>ethernet1/1.9999</interface></interface-address></dynamic-ip-and-port></source-translation></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get isolation firewall rule | has_isolation_fw_rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='isolate_3954']")) {
+ if (context.containsKey("has_isolation_fw_rule") && context.get("has_isolation_fw_rule").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"isolate_3954\" admin=\"admin\" time=\"2013/07/05 13:02:38\"><from admin=\"admin\" time=\"2013/07/05 13:02:38\"><member admin=\"admin\" time=\"2013/07/05 13:02:38\">trust</member></from><to><member>trust</member></to><source><member>10.5.80.0/20</member></source><destination><member>10.5.80.1</member></destination><application><member>any</member></application><service><member>any</member></service><action>deny</action><negate-source>no</negate-source><negate-destination>yes</negate-destination></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get service | has_service
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/service/entry[@name='cs_tcp_80']")) {
+ if (context.containsKey("has_service_tcp_80") && context.get("has_service_tcp_80").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"cs_tcp_80\"><protocol><tcp><port>80</port></tcp></protocol></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get egress firewall rule | has_egress_fw_rule | policy_0
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0']")) {
+ if (context.containsKey("has_egress_fw_rule") && context.get("has_egress_fw_rule").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"policy_0\" admin=\"admin\" time=\"2013/07/03 12:43:30\"><from admin=\"admin\" time=\"2013/07/03 12:43:30\"><member admin=\"admin\" time=\"2013/07/03 12:43:30\">trust</member></from><to><member>untrust</member></to><source><member>10.3.96.1/20</member></source><destination><member>any</member></destination><application><member>any</member></application><service><member>cs_tcp_80</member></service><action>allow</action><negate-source>no</negate-source><negate-destination>no</negate-destination></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get ingress firewall rule | has_ingress_fw_rule | policy_8
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_8']")) {
+ if (context.containsKey("has_ingress_fw_rule") && context.get("has_ingress_fw_rule").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"policy_8\" admin=\"admin\" time=\"2013/07/03 13:26:27\"><from admin=\"admin\" time=\"2013/07/03 13:26:27\"><member admin=\"admin\" time=\"2013/07/03 13:26:27\">untrust</member></from><to><member>trust</member></to><source><member>any</member></source><destination><member>192.168.80.103</member></destination><application><member>any</member></application><service><member>cs_tcp_80</member></service><action>allow</action><negate-source>no</negate-source><negate-destination>no</negate-destination></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get destination nat rule (port forwarding) | has_dst_nat_rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='dst_nat.192-168-80-103_9']")) {
+ if (context.containsKey("has_dst_nat_rule") && context.get("has_dst_nat_rule").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"dst_nat.192-168-80-103_9\" admin=\"admin\" time=\"2013/07/03 13:40:50\"><to admin=\"admin\" time=\"2013/07/03 13:40:50\"><member admin=\"admin\" time=\"2013/07/03 13:40:50\">untrust</member></to><from><member>untrust</member></from><source><member>any</member></source><destination><member>192.168.80.103</member></destination><service>cs_tcp_80</service><nat-type>ipv4</nat-type><to-interface>ethernet1/1.9999</to-interface><destination-translation><translated-address>10.3.97.158</translated-address><translated-port>8080</translated-port></destination-translation></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get destination nat rules (returns all dst nat rules per ip)
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[destination/member[text()='192.168.80.103']]")) {
+ if (context.containsKey("has_dst_nat_rule") && context.get("has_dst_nat_rule").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"dst_nat.192-168-80-103_9\" admin=\"admin\" time=\"2013/07/03 13:40:50\"><to admin=\"admin\" time=\"2013/07/03 13:40:50\"><member admin=\"admin\" time=\"2013/07/03 13:40:50\">untrust</member></to><from><member>untrust</member></from><source><member>any</member></source><destination><member>192.168.80.103</member></destination><service>cs_tcp_80</service><nat-type>ipv4</nat-type><to-interface>ethernet1/1.9999</to-interface><destination-translation><translated-address>10.3.97.158</translated-address><translated-port>8080</translated-port></destination-translation></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ // get static nat rule | has_stc_nat_rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='stc_nat.192-168-80-103_0']")) {
+ if (context.containsKey("has_stc_nat_rule") && context.get("has_stc_nat_rule").equals("true")) {
+ response = "<response status=\"success\" code=\"19\"><result total-count=\"1\" count=\"1\"><entry name=\"stc_nat.192-168-80-103_0\" admin=\"admin\" time=\"2013/07/03 14:02:23\"><to admin=\"admin\" time=\"2013/07/03 14:02:23\"><member admin=\"admin\" time=\"2013/07/03 14:02:23\">untrust</member></to><from><member>untrust</member></from><source><member>any</member></source><destination><member>192.168.80.103</member></destination><service>any</service><nat-type>ipv4</nat-type><to-interface>ethernet1/1.9999</to-interface><destination-translation><translated-address>10.3.97.158</translated-address></destination-translation></entry></result></response>";
+ } else {
+ response = "<response status=\"success\" code=\"19\"><result/></response>";
+ }
+ }
+
+ }
+
+ // action = 'set'
+ if (params.get("action").equals("set")) {
+ // set management profile
+ if (params.get("xpath").equals("/config/devices/entry/network/profiles/interface-management-profile/entry[@name='Ping']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_management_profile", "true");
+ }
+
+ // add private interface
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/2']/layer3/units/entry[@name='ethernet1/2.3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_private_interface", "true");
+ }
+
+ // add public ip to public interface
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/1']/layer3/units/entry[@name='ethernet1/1.9999']/ip")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_public_interface", "true");
+ }
+
+ // add private interface to zone
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/zone/entry[@name='trust']/network/layer3")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ }
+
+ // add public interface to zone
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/zone/entry[@name='untrust']/network/layer3")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ }
+
+ // set virtual router (public | private)
+ if (params.get("xpath").equals("/config/devices/entry/network/virtual-router/entry[@name='default']/interface")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ }
+
+ // add interface to network (public | private)
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/import/network/interface")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ }
+
+ // add src nat rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='src_nat.3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_src_nat_rule", "true");
+ }
+
+ // add isolation firewall rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='isolate_3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_isolation_fw_rule", "true");
+ }
+
+ // add egress firewall rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_egress_fw_rule", "true");
+ }
+
+ // add ingress firewall rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_8']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_ingress_fw_rule", "true");
+ }
+
+ // add destination nat rule (port forwarding)
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='dst_nat.192-168-80-103_9']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_dst_nat_rule", "true");
+ }
+
+ // add static nat rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='stc_nat.192-168-80-103_0']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_stc_nat_rule", "true");
+ }
+
+ // add tcp 80 service
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/service/entry[@name='cs_tcp_80']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.put("has_service_tcp_80", "true");
+ }
+ }
+
+ // action = 'delete'
+ if (params.get("action").equals("delete")) {
+ // remove egress firewall rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.remove("has_egress_fw_rule");
+ }
+
+ // remove ingress firewall rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_8']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.remove("has_ingress_fw_rule");
+ }
+
+ // remove destination nat rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='dst_nat.192-168-80-103_9']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.remove("has_dst_nat_rule");
+ }
+
+ // remove static nat rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='stc_nat.192-168-80-103_0']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.remove("has_dst_nat_rule");
+ }
+
+ // remove public ip from interface (dst_nat | stc_nat)
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/1']/layer3/units/entry[@name='ethernet1/1.9999']/ip/entry[@name='192.168.80.103/32']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ }
+
+ // remove isolation firewall rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='isolate_3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.remove("has_isolation_fw_rule");
+ }
+
+ // remove source nat rule
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/nat/rules/entry[@name='src_nat.3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.remove("has_src_nat_rule");
+ }
+
+ // remove public source nat ip
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/1']/layer3/units/entry[@name='ethernet1/1.9999']/ip/entry[@name='192.168.80.102/32']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.remove("has_public_interface");
+ }
+
+ // remove private interface from the zone
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/zone/entry[@name='trust']/network/layer3/member[text()='ethernet1/2.3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ }
+
+ // remove private interface from the virtual router
+ if (params.get("xpath").equals("/config/devices/entry/network/virtual-router/entry[@name='default']/interface/member[text()='ethernet1/2.3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ }
+
+ // remove private interface from network
+ if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/import/network/interface/member[text()='ethernet1/2.3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ }
+
+ // remove private interface
+ if (params.get("xpath").equals("/config/devices/entry/network/interface/ethernet/entry[@name='ethernet1/2']/layer3/units/entry[@name='ethernet1/2.3954']")) {
+ response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
+ context.remove("has_private_interface");
+ }
+
+ }
+ } // end 'config'
+
+ // 'op' requests
+ if (params.containsKey("type") && params.get("type").equals("op")) {
+ // check if there are pending changes
+ if (params.get("cmd").equals("<check><pending-changes></pending-changes></check>")) {
+ if (context.containsKey("firewall_has_pending_changes") && context.get("firewall_has_pending_changes").equals("true")) {
+ response = "<response status=\"success\"><result>yes</result></response>";
+ } else {
+ response = "<response status=\"success\"><result>no</result></response>";
+ }
+ }
+
+ // add a config lock
+ if (params.get("cmd").equals("<request><config-lock><add></add></config-lock></request>")) {
+ response = "<response status=\"success\"><result>Successfully acquired lock. Other administrators will not be able to modify configuration for scope shared until lock is released</result></response>";
+ }
+
+ // check job status
+ if (params.get("cmd").equals("<show><jobs><id>1</id></jobs></show>")) {
+ if (context.containsKey("simulate_commit_failure") && context.get("simulate_commit_failure").equals("true")) {
+ response = "<response status=\"success\"><result><job><tenq>2013/07/10 11:11:49</tenq><id>1</id><user>admin</user><type>Commit</type><status>FIN</status><stoppable>no</stoppable><result>FAIL</result><tfin>11:11:54</tfin><progress>11:11:54</progress><details><line>Bad config</line><line>Commit failed</line></details><warnings></warnings></job></result></response>";
+ } else {
+ response = "<response status=\"success\"><result><job><tenq>2013/07/02 14:49:49</tenq><id>1</id><user>admin</user><type>Commit</type><status>FIN</status><stoppable>no</stoppable><result>OK</result><tfin>14:50:02</tfin><progress>14:50:02</progress><details><line>Configuration committed successfully</line></details><warnings></warnings></job></result></response>";
+ }
+ }
+
+ // load from running config
+ if (params.get("cmd").equals("<load><config><from>running-config.xml</from></config></load>")) {
+ response = "<response status=\"success\"><result><msg><line>Config loaded from running-config.xml</line></msg></result></response>";
+ }
+
+ // remove config lock
+ if (params.get("cmd").equals("<request><config-lock><remove></remove></config-lock></request>")) {
+ response = "<response status=\"success\"><result>Config lock released for scope shared</result></response>";
+ }
+ } // end 'op'
+
+ // 'commit' requests
+ if (params.containsKey("type") && params.get("type").equals("commit")) {
+ // cmd = '<commit></commit>'
+ if (params.get("cmd").equals("<commit></commit>")) {
+ response = "<response status=\"success\" code=\"19\"><result><msg><line>Commit job enqueued with jobid 1</line></msg><job>1</job></result></response>";
+ }
+ } // end 'commit'
+
+
+ // print out the details into the console
+ if (context.containsKey("enable_console_output") && context.get("enable_console_output") == "true") {
+ if (params.containsKey("xpath")) {
+ System.out.println("XPATH("+params.get("action")+"): "+params.get("xpath"));
+ }
+ if (params.containsKey("type") && params.get("type").equals("op")) {
+ System.out.println("OP CMD: "+params.get("cmd"));
+ }
+ System.out.println(response+"\n");
+ }
+
+ return response;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f8ad3f3/plugins/network-elements/palo-alto/test/com/cloud/network/resource/PaloAltoResourceTest.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/palo-alto/test/com/cloud/network/resource/PaloAltoResourceTest.java b/plugins/network-elements/palo-alto/test/com/cloud/network/resource/PaloAltoResourceTest.java
new file mode 100755
index 0000000..c270473
--- /dev/null
+++ b/plugins/network-elements/palo-alto/test/com/cloud/network/resource/PaloAltoResourceTest.java
@@ -0,0 +1,507 @@
+// 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.network.resource;
+
+// test imports
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+
+// basic imports
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import javax.naming.ConfigurationException;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
+import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalFirewallCommand;
+import com.cloud.agent.api.routing.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.to.FirewallRuleTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.host.Host;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.TrafficType;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRule.State;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.Script;
+
+// http client handling
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.BasicResponseHandler;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.protocol.HTTP;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.net.URLDecoder;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import com.cloud.network.utils.HttpClientWrapper;
+
+// for prettyFormat()
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import java.io.StringWriter;
+
+public class PaloAltoResourceTest {
+ // configuration data
+ private String _test_name = "PaloAltoTestDevice";
+ private String _test_zoneId = "TestZone";
+ private String _test_ip = "192.168.80.2";
+ private String _test_username = "admin";
+ private String _test_password = "admin";
+ private String _test_publicInterface = "ethernet1/1";
+ private String _test_privateInterface = "ethernet1/2";
+ private String _test_publicZone = "untrust";
+ private String _test_privateZone = "trust";
+ private String _test_virtualRouter = "default";
+
+ MockablePaloAltoResource _resource;
+ Map<String, Object> _resource_params;
+ HashMap<String, String> _context;
+
+ @Before
+ public void setUp() {
+ _resource = new MockablePaloAltoResource();
+ _resource_params = new HashMap<String, Object>(); // params to be passed to configure()
+ _resource_params.put("name", _test_name);
+ _resource_params.put("zoneId", _test_zoneId);
+ _resource_params.put("ip", _test_ip);
+ _resource_params.put("username", _test_username);
+ _resource_params.put("password", _test_password);
+ _resource_params.put("publicinterface", _test_publicInterface);
+ _resource_params.put("privateinterface", _test_privateInterface);
+ _resource_params.put("publicnetwork", _test_publicZone);
+ _resource_params.put("privatenetwork", _test_privateZone);
+ _resource_params.put("pavr", _test_virtualRouter);
+ _resource_params.put("guid", "aaaaa-bbbbb-ccccc");
+
+ _context = new HashMap<String, String>(); // global context
+ _context.put("name", _test_name);
+ _context.put("zone_id", _test_zoneId);
+ _context.put("ip", _test_ip);
+ _context.put("username", _test_username);
+ _context.put("password", _test_password);
+ _context.put("public_interface", _test_publicInterface);
+ _context.put("private_interface", _test_privateInterface);
+ _context.put("public_zone", _test_publicZone);
+ _context.put("private_zone", _test_privateZone);
+ _context.put("pa_vr", _test_virtualRouter);
+ // --
+ _context.put("public_using_ethernet", "true");
+ _context.put("private_using_ethernet", "true");
+ _context.put("has_management_profile", "true");
+ _context.put("enable_console_output", "false"); // CHANGE TO "true" TO ENABLE CONSOLE LOGGING OF TESTS
+ _resource.setMockContext(_context);
+ }
+
+ @Test (expected=ConfigurationException.class)
+ public void resourceConfigureFailure() throws ConfigurationException {
+ _resource.configure("PaloAltoResource", new HashMap<String, Object>());
+ }
+
+ @Test
+ public void resourceConfigureWithoutManagementProfile() throws ConfigurationException {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: resourceConfigureWithoutManagementProfile");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.remove("has_management_profile");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+ }
+
+ @Test
+ public void resourceConfigureWithManagementProfile() throws ConfigurationException {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: resourceConfigureWithManagementProfile");
+ System.out.println("---------------------------------------------------");
+ }
+ _resource.configure("PaloAltoResource", _resource_params);
+ }
+
+ @Test (expected=ConfigurationException.class)
+ public void simulateFirewallNotConfigurable() throws ConfigurationException {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: simulateFirewallNotConfigurable");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("firewall_has_pending_changes", "true");
+ _context.remove("has_management_profile");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+ }
+
+ @Test (expected=ConfigurationException.class)
+ public void simulateFirewallCommitFailure() throws ConfigurationException {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: simulateFirewallCommitFailure");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("simulate_commit_failure", "true");
+ _context.remove("has_management_profile");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+ }
+
+ @Test
+ public void testInitialize() throws ConfigurationException {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: testInitialization");
+ System.out.println("---------------------------------------------------");
+ }
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ StartupCommand[] sc = _resource.initialize();
+ assertTrue(sc.length == 1);
+ assertTrue("aaaaa-bbbbb-ccccc".equals(sc[0].getGuid()));
+ assertTrue("PaloAltoTestDevice".equals(sc[0].getName()));
+ assertTrue("TestZone".equals(sc[0].getDataCenter()));
+ }
+
+ @Test // implement public & private interfaces, source nat, guest network
+ public void implementGuestNetwork() throws ConfigurationException, ExecutionException {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: implementGuestNetwork");
+ System.out.println("---------------------------------------------------");
+ }
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ IpAddressTO ip = new IpAddressTO(Long.valueOf("1"), "192.168.80.102", true, false, true, "untagged", null, null, null, 100, false);
+ IpAddressTO[] ips = new IpAddressTO[1];
+ ips[0] = ip;
+ IpAssocCommand cmd = new IpAssocCommand(ips);
+ cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, "10.3.96.1");
+ cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+ cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, "3954");
+
+ IpAssocAnswer answer = (IpAssocAnswer) _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test // remove public & private interface details, source nat, guest network
+ public void shutdownGuestNetwork() throws ConfigurationException, ExecutionException {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: shutdownGuestNetwork");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ IpAddressTO ip = new IpAddressTO(Long.valueOf("1"), "192.168.80.102", false, false, true, "untagged", null, null, null, 100, false);
+ IpAddressTO[] ips = new IpAddressTO[1];
+ ips[0] = ip;
+ IpAssocCommand cmd = new IpAssocCommand(ips);
+ cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, "10.3.96.1");
+ cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+ cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, "3954");
+
+ IpAssocAnswer answer = (IpAssocAnswer) _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test
+ public void addIngressFirewallRule() throws ConfigurationException, Exception {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: addIngressFirewallRule");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _context.put("has_service_tcp_80", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ long vlanId = 3954;
+ List<FirewallRuleTO> rules = new ArrayList<FirewallRuleTO>();
+ List<String> cidrList = new ArrayList<String>();
+ cidrList.add("0.0.0.0/0");
+ FirewallRuleTO active = new FirewallRuleTO(8,
+ null, "192.168.80.103", "tcp", 80, 80, false, false,
+ FirewallRule.Purpose.Firewall, cidrList, null, null);
+ rules.add(active);
+
+ SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rules);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+
+ Answer answer = _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test
+ public void removeIngressFirewallRule() throws ConfigurationException, Exception {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: removeIngressFirewallRule");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _context.put("has_service_tcp_80", "true");
+ _context.put("has_ingress_fw_rule", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ long vlanId = 3954;
+ List<FirewallRuleTO> rules = new ArrayList<FirewallRuleTO>();
+ FirewallRuleTO revoked = new FirewallRuleTO(8,
+ null, "192.168.80.103", "tcp", 80, 80, true, false,
+ FirewallRule.Purpose.Firewall, null, null, null);
+ rules.add(revoked);
+
+ SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rules);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+
+ Answer answer = _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test
+ public void addEgressFirewallRule() throws ConfigurationException, Exception {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: addEgressFirewallRule");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _context.put("has_service_tcp_80", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ long vlanId = 3954;
+ List<FirewallRuleTO> rules = new ArrayList<FirewallRuleTO>();
+ List<String> cidrList = new ArrayList<String>();
+ cidrList.add("0.0.0.0/0");
+ FirewallRuleVO activeVO = new FirewallRuleVO(null, null, 80, 80, "tcp",
+ 1, 1, 1, Purpose.Firewall, cidrList, null,
+ null, null, FirewallRule.TrafficType.Egress);
+ FirewallRuleTO active = new FirewallRuleTO(activeVO, Long.toString(vlanId), null, Purpose.Firewall, FirewallRule.TrafficType.Egress);
+ rules.add(active);
+
+ SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rules);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+
+ Answer answer = _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test
+ public void removeEgressFirewallRule() throws ConfigurationException, Exception {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: removeEgressFirewallRule");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _context.put("has_service_tcp_80", "true");
+ _context.put("has_egress_fw_rule", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ long vlanId = 3954;
+ List<FirewallRuleTO> rules = new ArrayList<FirewallRuleTO>();
+ FirewallRuleVO revokedVO = new FirewallRuleVO(null, null, 80, 80, "tcp",
+ 1, 1, 1, Purpose.Firewall, null, null, null, null, FirewallRule.TrafficType.Egress);
+ revokedVO.setState(State.Revoke);
+ FirewallRuleTO revoked = new FirewallRuleTO(revokedVO, Long.toString(vlanId), null, Purpose.Firewall, FirewallRule.TrafficType.Egress);
+ rules.add(revoked);
+
+ SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rules);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+
+ Answer answer = _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test
+ public void addStaticNatRule() throws ConfigurationException, Exception {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: addStaticNatRule");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _context.put("has_service_tcp_80", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ long vlanId = 3954;
+ List<StaticNatRuleTO> rules = new ArrayList<StaticNatRuleTO>();
+ StaticNatRuleTO active = new StaticNatRuleTO(0, "192.168.80.103", null,
+ null, "10.3.97.158", null, null, null, false, false);
+ rules.add(active);
+
+ SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rules, null);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+
+ Answer answer = _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test
+ public void removeStaticNatRule() throws ConfigurationException, Exception {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: removeStaticNatRule");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _context.put("has_service_tcp_80", "true");
+ _context.put("has_stc_nat_rule", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ long vlanId = 3954;
+ List<StaticNatRuleTO> rules = new ArrayList<StaticNatRuleTO>();
+ StaticNatRuleTO revoked = new StaticNatRuleTO(0, "192.168.80.103", null,
+ null, "10.3.97.158", null, null, null, true, false);
+ rules.add(revoked);
+
+ SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rules, null);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+
+ Answer answer = _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test
+ public void addPortForwardingRule() throws ConfigurationException, Exception {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: addPortForwardingRule");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _context.put("has_service_tcp_80", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ long vlanId = 3954;
+ List<PortForwardingRuleTO> rules = new ArrayList<PortForwardingRuleTO>();
+ PortForwardingRuleTO active = new PortForwardingRuleTO(9, "192.168.80.103", 80,
+ 80, "10.3.97.158", 8080, 8080, "tcp", false, false);
+ rules.add(active);
+
+ SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(rules);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+
+ Answer answer = _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+
+ @Test
+ public void removePortForwardingRule() throws ConfigurationException, Exception {
+ if (_context.containsKey("enable_console_output") && _context.get("enable_console_output").equals("true")) {
+ System.out.println("\nTEST: removePortForwardingRule");
+ System.out.println("---------------------------------------------------");
+ }
+ _context.put("has_public_interface", "true");
+ _context.put("has_private_interface", "true");
+ _context.put("has_src_nat_rule", "true");
+ _context.put("has_isolation_fw_rule", "true");
+ _context.put("has_service_tcp_80", "true");
+ _context.put("has_dst_nat_rule", "true");
+ _resource.setMockContext(_context);
+ _resource.configure("PaloAltoResource", _resource_params);
+
+ long vlanId = 3954;
+ List<PortForwardingRuleTO> rules = new ArrayList<PortForwardingRuleTO>();
+ PortForwardingRuleTO revoked = new PortForwardingRuleTO(9, "192.168.80.103", 80,
+ 80, "10.3.97.158", 8080, 8080, "tcp", true, false);
+ rules.add(revoked);
+
+ SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(rules);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, "10.3.96.1/20");
+
+ Answer answer = _resource.executeRequest(cmd);
+ assertTrue(answer.getResult());
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f8ad3f3/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 4f193bc..d0817a2 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -44,6 +44,7 @@
<module>network-elements/elastic-loadbalancer</module>
<module>network-elements/ovs</module>
<module>network-elements/juniper-contrail</module>
+ <module>network-elements/palo-alto</module>
<module>network-elements/nicira-nvp</module>
<module>network-elements/bigswitch-vns</module>
<module>network-elements/midonet</module>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f8ad3f3/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 769d345..36ef4bd 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2631,7 +2631,7 @@ public class ApiResponseHelper implements ResponseGenerator {
List<ProviderResponse> serviceProvidersResponses = new ArrayList<ProviderResponse>();
for (Network.Provider serviceProvider : serviceProviders) {
// return only Virtual Router/JuniperSRX/CiscoVnmc as a provider for the firewall
- if (service == Service.Firewall && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc)) {
+ if (service == Service.Firewall && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto)) {
continue;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f8ad3f3/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index e3aa4fa..2e9b388 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -3792,6 +3792,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
firewallProvider = provider;
}
+ if (provider == Provider.PaloAlto) {
+ firewallProvider = Provider.PaloAlto;
+ }
+
if ((service == Service.PortForwarding || service == Service.StaticNat)
&& provider == Provider.VirtualRouter) {
firewallProvider = Provider.VirtualRouter;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f8ad3f3/ui/dictionary.jsp
----------------------------------------------------------------------
diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp
index 85f24c6..8bd547b 100644
--- a/ui/dictionary.jsp
+++ b/ui/dictionary.jsp
@@ -322,6 +322,7 @@ dictionary = {
'label.add.new.gateway': '<fmt:message key="label.add.new.gateway" />',
'label.add.new.NetScaler': '<fmt:message key="label.add.new.NetScaler" />',
'label.add.new.SRX': '<fmt:message key="label.add.new.SRX" />',
+'label.add.new.PA': '<fmt:message key="label.add.new.PA" />',
'label.add.new.tier': '<fmt:message key="label.add.new.tier" />',
'label.add.NiciraNvp.device': '<fmt:message key="label.add.NiciraNvp.device" />',
'label.add.pod': '<fmt:message key="label.add.pod" />',
@@ -334,6 +335,7 @@ dictionary = {
'label.add.security.group': '<fmt:message key="label.add.security.group" />',
'label.add.service.offering': '<fmt:message key="label.add.service.offering" />',
'label.add.SRX.device': '<fmt:message key="label.add.SRX.device" />',
+'label.add.PA.device': '<fmt:message key="label.add.PA.device" />',
'label.add.static.nat.rule': '<fmt:message key="label.add.static.nat.rule" />',
'label.add.static.route': '<fmt:message key="label.add.static.route" />',
'label.add.system.service.offering': '<fmt:message key="label.add.system.service.offering" />',
@@ -480,6 +482,7 @@ dictionary = {
'label.delete.NiciraNvp': '<fmt:message key="label.delete.NiciraNvp" />',
'label.delete.project': '<fmt:message key="label.delete.project" />',
'label.delete.SRX': '<fmt:message key="label.delete.SRX" />',
+'label.delete.PA': '<fmt:message key="label.delete.PA" />',
'label.delete.VPN.connection': '<fmt:message key="label.delete.VPN.connection" />',
'label.delete.VPN.customer.gateway': '<fmt:message key="label.delete.VPN.customer.gateway" />',
'label.delete.VPN.gateway': '<fmt:message key="label.delete.VPN.gateway" />',
@@ -859,6 +862,8 @@ dictionary = {
'label.owned.public.ips': '<fmt:message key="label.owned.public.ips" />',
'label.owner.account': '<fmt:message key="label.owner.account" />',
'label.owner.domain': '<fmt:message key="label.owner.domain" />',
+'label.PA.log.profile': '<fmt:message key="label.PA.log.profile" />',
+'label.PA.threat.profile': '<fmt:message key="label.PA.threat.profile" />',
'label.parent.domain': '<fmt:message key="label.parent.domain" />',
'label.password.enabled': '<fmt:message key="label.password.enabled" />',
'label.password': '<fmt:message key="label.password" />',
@@ -1031,6 +1036,7 @@ dictionary = {
'label.specify.vxlan': '<fmt:message key="label.specify.vxlan" />',
'label.SR.name ': '<fmt:message key="label.SR.name " />',
'label.srx': '<fmt:message key="label.srx" />',
+'label.PA': '<fmt:message key="label.PA" />',
'label.start.IP': '<fmt:message key="label.start.IP" />',
'label.start.port': '<fmt:message key="label.start.port" />',
'label.start.reserved.system.IP': '<fmt:message key="label.start.reserved.system.IP" />',
@@ -1332,6 +1338,7 @@ dictionary = {
'message.confirm.delete.F5': '<fmt:message key="message.confirm.delete.F5" />',
'message.confirm.delete.NetScaler': '<fmt:message key="message.confirm.delete.NetScaler" />',
'message.confirm.delete.SRX': '<fmt:message key="message.confirm.delete.SRX" />',
+'message.confirm.delete.PA': '<fmt:message key="message.confirm.delete.PA" />',
'message.confirm.destroy.router': '<fmt:message key="message.confirm.destroy.router" />',
'message.confirm.disable.provider': '<fmt:message key="message.confirm.disable.provider" />',
'message.confirm.enable.provider': '<fmt:message key="message.confirm.enable.provider" />',
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8f8ad3f3/ui/scripts/docs.js
----------------------------------------------------------------------
diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js
index 3a4f8ca..7b7edf4 100755
--- a/ui/scripts/docs.js
+++ b/ui/scripts/docs.js
@@ -770,6 +770,75 @@ cloudStack.docs = {
desc: 'Number of guest networks/accounts that will share this device',
externalLink: ''
},
+ // Add Palo Alto
+ helpPaloAltoIPAddress: {
+ desc: 'The IP address of the device',
+ externalLink: ''
+ },
+ helpPaloAltoUsername: {
+ desc: 'A user ID with valid authentication credentials that provide to access the device',
+ externalLink: ''
+ },
+ helpPaloAltoPassword: {
+ desc: 'The password for the user ID provided in Username',
+ externalLink: ''
+ },
+ helpPaloAltoType: {
+ desc: 'The type of device that is being added',
+ externalLink: ''
+ },
+ helpPaloAltoPublicInterface: {
+ desc: 'Interface of device that is configured to be part of the public network. For example, ge-0/0/2',
+ externalLink: ''
+ },
+ helpPaloAltoPrivateInterface: {
+ desc: 'Interface of device that is configured to be part of the private network. For example, ge-0/0/1',
+ externalLink: ''
+ },
+ helpPaloAltoUsageInterface: {
+ desc: 'Interface used to meter traffic. If you don\'t want to use the public interface, specify a different interface name here.',
+ externalLink: ''
+ },
+ helpPaloAltoRetries: {
+ desc: 'Number of times to attempt a command on the device before considering the operation failed. Default is 2.',
+ externalLink: ''
+ },
+ helpPaloAltoTimeout: {
+ desc: 'The time to wait for a command on the Palo Alto before considering it failed. Default is 300 seconds.',
+ externalLink: ''
+ },
+ helpPaloAltoMode: {
+ desc: 'Side by side mode is supported for the Palo Alto.',
+ externalLink: ''
+ },
+ helpPaloAltoPublicNetwork: {
+ desc: 'The name of the public network on the Palo Alto. For example, trust.',
+ externalLink: ''
+ },
+ helpPaloAltoPrivateNetwork: {
+ desc: 'The name of the private network on the Palo Alto. For example, untrust.',
+ externalLink: ''
+ },
+ helpPaloAltoVirtualRouter: {
+ desc: 'The name of the virtual router on the Palo Alto.',
+ externalLink: ''
+ },
+ helpPaloAltoThreatProfile: {
+ desc: 'The threat profile name/group to associate with allow firewall policies.',
+ externalLink: ''
+ },
+ helpPaloAltoLogProfile: {
+ desc: 'The log profile name/group to associate with allow firewall policies.',
+ externalLink: ''
+ },
+ helpPaloAltoDedicated: {
+ desc: 'Check this box to dedicate the device to a single account. The value in the Capacity field will be ignored.',
+ externalLink: ''
+ },
+ helpPaloAltoCapacity: {
+ desc: 'Number of guest networks/accounts that will share this device',
+ externalLink: ''
+ },
// Add system service offering
helpSystemOfferingName: {
desc: 'Any desired name for the offering',