fixed egress rules for palo alto plugin and cleaned up extra api calls on master

Signed-off-by: Sheng Yang <sheng.yang@citrix.com>
This commit is contained in:
Will Stevens 2013-12-09 18:30:22 -05:00 committed by Sheng Yang
parent 4de09ee654
commit c60a256ebd
9 changed files with 155 additions and 427 deletions

View File

@ -549,10 +549,6 @@ listSrxFirewalls=1
listSrxFirewallNetworks=1
#### Palo Alto firewall commands
addExternalFirewall=1
deleteExternalFirewall=1
listExternalFirewalls=1
addPaloAltoFirewall=1
deletePaloAltoFirewall=1
configurePaloAltoFirewall=1

View File

@ -1,115 +0,0 @@
// 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.api.commands;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ExternalFirewallResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.host.Host;
import com.cloud.network.element.PaloAltoFirewallElementService;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
@APICommand(name = "addExternalFirewall", description = "Adds an external firewall appliance", responseObject = ExternalFirewallResponse.class)
public class AddExternalFirewallCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(AddExternalFirewallCmd.class.getName());
private static final String s_name = "addexternalfirewallresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
required = true,
description = "Zone in which to add the external firewall appliance.")
private Long zoneId;
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "URL of the external firewall appliance.")
private String url;
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Username of the external firewall appliance.")
private String username;
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "Password of the external firewall appliance.")
private String password;
///////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getZoneId() {
return zoneId;
}
public String getUrl() {
return url;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Inject
PaloAltoFirewallElementService _paElementService;
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@SuppressWarnings("deprecation")
@Override
public void execute() {
try {
Host externalFirewall = _paElementService.addExternalFirewall(this);
ExternalFirewallResponse response = _paElementService.createExternalFirewallResponse(externalFirewall);
response.setObjectName("externalfirewall");
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (InvalidParameterValueException ipve) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ipve.getMessage());
} catch (CloudRuntimeException cre) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, cre.getMessage());
}
}
}

View File

@ -1,89 +0,0 @@
// 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.api.commands;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.element.PaloAltoFirewallElementService;
import com.cloud.user.Account;
@APICommand(name = "deleteExternalFirewall", description = "Deletes an external firewall appliance.", responseObject = SuccessResponse.class)
public class DeleteExternalFirewallCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeleteExternalFirewallCmd.class.getName());
private static final String s_name = "deleteexternalfirewallresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "Id of the external firewall appliance.")
private Long id;
///////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Inject
PaloAltoFirewallElementService _paElementService;
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@SuppressWarnings("deprecation")
@Override
public void execute() {
try {
boolean result = _paElementService.deleteExternalFirewall(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete external firewall.");
}
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Failed to delete external firewall.");
}
}
}

View File

@ -1,89 +0,0 @@
// 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.api.commands;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
import org.apache.cloudstack.api.response.ExternalFirewallResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import com.cloud.host.Host;
import com.cloud.network.element.PaloAltoFirewallElementService;
@APICommand(name = "listExternalFirewalls", description = "List external firewall appliances.", responseObject = ExternalFirewallResponse.class)
public class ListExternalFirewallsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListServiceOfferingsCmd.class.getName());
private static final String s_name = "listexternalfirewallsresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "zone Id")
private long zoneId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public long getZoneId() {
return zoneId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Inject
PaloAltoFirewallElementService _paElementService;
@Override
public String getCommandName() {
return s_name;
}
@SuppressWarnings("deprecation")
@Override
public void execute() {
List<? extends Host> externalFirewalls = _paElementService.listExternalFirewalls(this);
ListResponse<ExternalFirewallResponse> listResponse = new ListResponse<ExternalFirewallResponse>();
List<ExternalFirewallResponse> responses = new ArrayList<ExternalFirewallResponse>();
for (Host externalFirewall : externalFirewalls) {
ExternalFirewallResponse response = _paElementService.createExternalFirewallResponse(externalFirewall);
response.setObjectName("externalfirewall");
response.setResponseName(getCommandName());
responses.add(response);
}
listResponse.setResponses(responses);
listResponse.setResponseName(getCommandName());
this.setResponseObject(listResponse);
}
}

View File

@ -32,12 +32,9 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.commands.AddExternalFirewallCmd;
import com.cloud.api.commands.AddPaloAltoFirewallCmd;
import com.cloud.api.commands.ConfigurePaloAltoFirewallCmd;
import com.cloud.api.commands.DeleteExternalFirewallCmd;
import com.cloud.api.commands.DeletePaloAltoFirewallCmd;
import com.cloud.api.commands.ListExternalFirewallsCmd;
import com.cloud.api.commands.ListPaloAltoFirewallNetworksCmd;
import com.cloud.api.commands.ListPaloAltoFirewallsCmd;
import com.cloud.api.response.PaloAltoFirewallResponse;
@ -293,85 +290,12 @@ public class PaloAltoExternalFirewallElement extends ExternalFirewallDeviceManag
return true;
}
@Override
@Deprecated
// should use more generic addNetworkDevice command to add firewall
public
Host addExternalFirewall(AddExternalFirewallCmd cmd) {
Long zoneId = cmd.getZoneId();
DataCenterVO zone = null;
PhysicalNetworkVO pNetwork = null;
HostVO fwHost = null;
zone = _dcDao.findById(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Could not find zone with ID: " + zoneId);
}
List<PhysicalNetworkVO> physicalNetworks = _physicalNetworkDao.listByZone(zoneId);
if ((physicalNetworks == null) || (physicalNetworks.size() > 1)) {
throw new InvalidParameterValueException("There are no physical networks or multiple physical networks configured in zone with ID: " + zoneId +
" to add this device.");
}
pNetwork = physicalNetworks.get(0);
String deviceType = NetworkDevice.PaloAltoFirewall.getName();
ExternalFirewallDeviceVO fwDeviceVO =
addExternalFirewall(pNetwork.getId(), cmd.getUrl(), cmd.getUsername(), cmd.getPassword(), deviceType, new PaloAltoResource());
if (fwDeviceVO != null) {
fwHost = _hostDao.findById(fwDeviceVO.getHostId());
}
return fwHost;
}
@Override
public boolean deleteExternalFirewall(DeleteExternalFirewallCmd cmd) {
return deleteExternalFirewall(cmd.getId());
}
@Override
@Deprecated
// should use more generic listNetworkDevice command
public
List<Host> listExternalFirewalls(ListExternalFirewallsCmd cmd) {
List<Host> firewallHosts = new ArrayList<Host>();
Long zoneId = cmd.getZoneId();
DataCenterVO zone = null;
PhysicalNetworkVO pNetwork = null;
if (zoneId != null) {
zone = _dcDao.findById(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Could not find zone with ID: " + zoneId);
}
List<PhysicalNetworkVO> physicalNetworks = _physicalNetworkDao.listByZone(zoneId);
if ((physicalNetworks == null) || (physicalNetworks.size() > 1)) {
throw new InvalidParameterValueException("There are no physical networks or multiple physical networks configured in zone with ID: " + zoneId +
" to add this device.");
}
pNetwork = physicalNetworks.get(0);
}
firewallHosts.addAll(listExternalFirewalls(pNetwork.getId(), NetworkDevice.PaloAltoFirewall.getName()));
return firewallHosts;
}
@Override
public ExternalFirewallResponse createExternalFirewallResponse(Host externalFirewall) {
return super.createExternalFirewallResponse(externalFirewall);
}
@Override
public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<Class<?>>();
cmdList.add(AddExternalFirewallCmd.class);
cmdList.add(AddPaloAltoFirewallCmd.class);
cmdList.add(ConfigurePaloAltoFirewallCmd.class);
cmdList.add(DeleteExternalFirewallCmd.class);
cmdList.add(DeletePaloAltoFirewallCmd.class);
cmdList.add(ListExternalFirewallsCmd.class);
cmdList.add(ListPaloAltoFirewallNetworksCmd.class);
cmdList.add(ListPaloAltoFirewallsCmd.class);
return cmdList;

View File

@ -20,12 +20,9 @@ import java.util.List;
import org.apache.cloudstack.api.response.ExternalFirewallResponse;
import com.cloud.api.commands.AddExternalFirewallCmd;
import com.cloud.api.commands.AddPaloAltoFirewallCmd;
import com.cloud.api.commands.ConfigurePaloAltoFirewallCmd;
import com.cloud.api.commands.DeleteExternalFirewallCmd;
import com.cloud.api.commands.DeletePaloAltoFirewallCmd;
import com.cloud.api.commands.ListExternalFirewallsCmd;
import com.cloud.api.commands.ListPaloAltoFirewallNetworksCmd;
import com.cloud.api.commands.ListPaloAltoFirewallsCmd;
import com.cloud.api.response.PaloAltoFirewallResponse;
@ -72,24 +69,4 @@ public interface PaloAltoFirewallElementService extends PluggableService {
public List<? extends Network> listNetworks(ListPaloAltoFirewallNetworksCmd cmd);
public PaloAltoFirewallResponse createPaloAltoFirewallResponse(ExternalFirewallDeviceVO fwDeviceVO);
@Deprecated
// API helper function supported for backward compatibility
public
Host addExternalFirewall(AddExternalFirewallCmd cmd);
@Deprecated
// API helper function supported for backward compatibility
public
boolean deleteExternalFirewall(DeleteExternalFirewallCmd cmd);
@Deprecated
// API helper function supported for backward compatibility
public
List<Host> listExternalFirewalls(ListExternalFirewallsCmd cmd);
@Deprecated
// API helper function supported for backward compatibility
public
ExternalFirewallResponse createExternalFirewallResponse(Host externalFirewall);
}

View File

@ -29,6 +29,7 @@ import java.util.Map;
import javax.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@ -55,6 +56,7 @@ import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
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;
@ -462,11 +464,14 @@ public class PaloAltoResource implements ServerResource {
String guestVlanSubnet = NetUtils.getCidrSubNet(guestVlanGateway, cidrSize);
Long publicVlanTag = null;
if (ip.getBroadcastUri() != null && !ip.getBroadcastUri().equals("untagged")) {
try {
publicVlanTag = Long.parseLong(ip.getBroadcastUri());
} catch (Exception e) {
throw new ExecutionException("Could not parse public VLAN tag: " + ip.getBroadcastUri());
if (ip.getBroadcastUri() != null) {
String parsedVlanTag = parsePublicVlanTag(ip.getBroadcastUri());
if (!parsedVlanTag.equals("untagged")) {
try {
publicVlanTag = Long.parseLong(parsedVlanTag);
} catch (Exception e) {
throw new ExecutionException("Could not parse public VLAN tag: " + parsedVlanTag);
}
}
}
@ -520,6 +525,9 @@ public class PaloAltoResource implements ServerResource {
String privateGateway, String privateSubnet, long privateCidrSize) throws ExecutionException {
privateSubnet = privateSubnet + "/" + privateCidrSize;
// remove any orphaned egress rules if they exist...
removeOrphanedFirewallRules(cmdList, privateVlanTag);
if (type.equals(GuestNetworkType.SOURCE_NAT)) {
manageNetworkIsolation(cmdList, PaloAltoPrimative.DELETE, privateVlanTag, privateSubnet, privateGateway);
manageSrcNatRule(cmdList, PaloAltoPrimative.DELETE, type, publicVlanTag, sourceNatIpAddress + "/32", privateVlanTag, privateGateway + "/" + privateCidrSize);
@ -943,11 +951,16 @@ public class PaloAltoResource implements ServerResource {
String dstNatName = genDstNatRuleName(publicIp, rule.getId());
String publicInterfaceName;
String publicVlanTag = rule.getSrcVlanTag();
if (publicVlanTag == null || publicVlanTag.equals("untagged")) {
String publicVlanTag;
if (rule.getSrcVlanTag() == null) {
publicInterfaceName = genPublicInterfaceName(new Long("9999"));
} else {
publicInterfaceName = genPublicInterfaceName(new Long(publicVlanTag));
publicVlanTag = parsePublicVlanTag(rule.getSrcVlanTag());
if (publicVlanTag.equals("untagged")) {
publicInterfaceName = genPublicInterfaceName(new Long("9999"));
} else {
publicInterfaceName = genPublicInterfaceName(new Long(publicVlanTag));
}
}
switch (prim) {
@ -1085,11 +1098,16 @@ public class PaloAltoResource implements ServerResource {
String stcNatName = genStcNatRuleName(publicIp, rule.getId());
String publicInterfaceName;
String publicVlanTag = rule.getSrcVlanTag();
if (publicVlanTag == null || publicVlanTag.equals("untagged")) {
String publicVlanTag;
if (rule.getSrcVlanTag() == null) {
publicInterfaceName = genPublicInterfaceName(new Long("9999"));
} else {
publicInterfaceName = genPublicInterfaceName(new Long(publicVlanTag));
publicVlanTag = parsePublicVlanTag(rule.getSrcVlanTag());
if (publicVlanTag.equals("untagged")) {
publicInterfaceName = genPublicInterfaceName(new Long("9999"));
} else {
publicInterfaceName = genPublicInterfaceName(new Long(publicVlanTag));
}
}
switch (prim) {
@ -1170,13 +1188,20 @@ public class PaloAltoResource implements ServerResource {
/*
* Firewall rule implementation
*/
private String genFirewallRuleName(long id) {
private String genFirewallRuleName(long id) { // ingress
return "policy_" + Long.toString(id);
}
private String genFirewallRuleName(long id, String vlan) { // egress
return "policy_"+Long.toString(id)+"_"+vlan;
}
public boolean manageFirewallRule(ArrayList<IPaloAltoCommand> cmdList, PaloAltoPrimative prim, FirewallRuleTO rule) throws ExecutionException {
String ruleName = genFirewallRuleName(rule.getId());
String ruleName;
if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
ruleName = genFirewallRuleName(rule.getId(), rule.getSrcVlanTag());
} else {
ruleName = genFirewallRuleName(rule.getId());
}
switch (prim) {
@ -1203,6 +1228,7 @@ public class PaloAltoResource implements ServerResource {
String serviceXML;
String protocol = rule.getProtocol();
String action = "allow";
// Only ICMP will use an Application, so others will be any.
if (protocol.equals(Protocol.ICMP.toString())) {
@ -1232,11 +1258,23 @@ public class PaloAltoResource implements ServerResource {
serviceXML = "<member>any</member>";
}
if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) { // Network egress rule
// handle different types of fire wall rules (egress | ingress)
if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) { // Egress Rule
srcZone = _privateZone;
dstZone = _publicZone;
dstAddressXML = "<member>any</member>";
} else {
// defaults to 'allow', the deny rules are as follows
if (rule.getType() == FirewallRule.FirewallRuleType.System) {
if (!rule.isDefaultEgressPolicy()) { // default of deny && system rule, so deny
action = "deny";
}
} else {
if (rule.isDefaultEgressPolicy()) { // default is allow && user rule, so deny
action = "deny";
}
}
} else { // Ingress Rule
srcZone = _publicZone;
dstZone = _privateZone;
dstAddressXML = "<member>" + rule.getSrcIp() + "</member>";
@ -1265,6 +1303,7 @@ public class PaloAltoResource implements ServerResource {
}
}
// build new rule xml
String xml = "";
xml += "<from><member>" + srcZone + "</member></from>";
xml += "<to><member>" + dstZone + "</member></to>";
@ -1272,16 +1311,52 @@ public class PaloAltoResource implements ServerResource {
xml += "<destination>" + dstAddressXML + "</destination>";
xml += "<application>" + appXML + "</application>";
xml += "<service>" + serviceXML + "</service>";
xml += "<action>allow</action>";
xml += "<action>"+action+"</action>";
xml += "<negate-source>no</negate-source>";
xml += "<negate-destination>no</negate-destination>";
if (_threatProfile != null) { // add the threat profile if it exists
if (_threatProfile != null && action.equals("allow")) { // add the threat profile if it exists
xml += "<profile-setting><group><member>" + _threatProfile + "</member></group></profile-setting>";
}
if (_logProfile != null) { // add the log profile if it exists
if (_logProfile != null && action.equals("allow")) { // add the log profile if it exists
xml += "<log-setting>" + _logProfile + "</log-setting>";
}
boolean has_default = false;
String defaultEgressRule = "";
if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
// check if a default egress rule exists because it always has to be after the other rules.
Map<String, String> e_params = new HashMap<String, String>();
e_params.put("type", "config");
e_params.put("action", "get");
e_params.put("xpath", "/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0_"+rule.getSrcVlanTag()+"']");
String e_response = request(PaloAltoMethod.GET, e_params);
has_default = (validResponse(e_response) && responseNotEmpty(e_response));
// there is an existing default rule, so we need to remove it and add it back after the new rule is added.
if (has_default) {
s_logger.debug("Moving the default egress rule after the new rule: "+ruleName);
NodeList response_body;
Document doc = getDocument(e_response);
XPath xpath = XPathFactory.newInstance().newXPath();
try {
XPathExpression expr = xpath.compile("/response[@status='success']/result/entry/node()");
response_body = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
} catch (XPathExpressionException e) {
throw new ExecutionException(e.getCause().getMessage());
}
for (int i=0; i<response_body.getLength(); i++) {
Node n = response_body.item(i);
defaultEgressRule += nodeToString(n);
}
Map<String, String> dd_params = new HashMap<String, String>();
dd_params.put("type", "config");
dd_params.put("action", "delete");
dd_params.put("xpath", "/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0_"+rule.getSrcVlanTag()+"']");
cmdList.add(new DefaultPaloAltoCommand(PaloAltoMethod.POST, dd_params));
}
}
// add the new rule...
Map<String, String> a_params = new HashMap<String, String>();
a_params.put("type", "config");
a_params.put("action", "set");
@ -1289,6 +1364,17 @@ public class PaloAltoResource implements ServerResource {
a_params.put("element", xml);
cmdList.add(new DefaultPaloAltoCommand(PaloAltoMethod.POST, a_params));
// add back the default rule
if (rule.getTrafficType() == FirewallRule.TrafficType.Egress && has_default) {
Map<String, String> da_params = new HashMap<String, String>();
da_params.put("type", "config");
da_params.put("action", "set");
da_params.put("xpath", "/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0_"+rule.getSrcVlanTag()+"']");
da_params.put("element", defaultEgressRule);
cmdList.add(new DefaultPaloAltoCommand(PaloAltoMethod.POST, da_params));
s_logger.debug("Completed move of the default egress rule after rule: "+ruleName);
}
return true;
case DELETE:
@ -1310,6 +1396,25 @@ public class PaloAltoResource implements ServerResource {
}
}
// remove orphaned rules if they exist...
public void removeOrphanedFirewallRules(ArrayList<IPaloAltoCommand> cmdList, long vlan) throws ExecutionException {
Map<String, String> params = new HashMap<String, String>();
params.put("type", "config");
params.put("action", "get");
params.put("xpath", "/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[contains(@name, 'policy') and contains(@name, '"+Long.toString(vlan)+"')]");
String response = request(PaloAltoMethod.GET, params);
boolean has_orphans = (validResponse(response) && responseNotEmpty(response));
if (has_orphans) {
Map<String, String> d_params = new HashMap<String, String>();
d_params.put("type", "config");
d_params.put("action", "delete");
d_params.put("xpath", "/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[contains(@name, 'policy') and contains(@name, '"+Long.toString(vlan)+"')]");
cmdList.add(new DefaultPaloAltoCommand(PaloAltoMethod.POST, d_params));
}
}
/*
* Usage
*/
@ -1935,6 +2040,10 @@ public class PaloAltoResource implements ServerResource {
return ip.replace('.', '-').replace('/', '-');
}
private String parsePublicVlanTag(String uri) {
return uri.replace("vlan://", "");
}
private Protocol getProtocol(String protocolName) throws ExecutionException {
protocolName = protocolName.toLowerCase();
@ -1964,6 +2073,20 @@ public class PaloAltoResource implements ServerResource {
}
}
// return an xml node as a string
private String nodeToString(Node node) throws ExecutionException {
StringWriter sw = new StringWriter();
try {
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.transform(new DOMSource(node), new StreamResult(sw));
} catch (Throwable t) {
throw new ExecutionException("XML convert error when modifying PA config: "+t.getMessage());
}
return sw.toString();
}
// pretty printing of xml strings
private String prettyFormat(String input) {
int indent = 4;
try {
@ -1999,14 +2122,12 @@ public class PaloAltoResource implements ServerResource {
@Override
public void setName(String name) {
// TODO Auto-generated method stub
}
//@Override
@Override
public void setConfigParams(Map<String, Object> params) {
// TODO Auto-generated method stub
}
//@Override
@ -2027,7 +2148,5 @@ public class PaloAltoResource implements ServerResource {
@Override
public void setRunLevel(int level) {
// TODO Auto-generated method stub
}
}

View File

@ -161,12 +161,12 @@ public class MockablePaloAltoResource extends PaloAltoResource {
}
}
// 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']")) {
// get egress firewall rule | has_egress_fw_rule | policy_0_3954
if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0_3954']")) {
if (context.containsKey("has_egress_fw_rule") && context.get("has_egress_fw_rule").equals("true")) {
response =
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\">"
+ "<entry name=\"policy_0_3954\" 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>";
@ -190,6 +190,11 @@ public class MockablePaloAltoResource extends PaloAltoResource {
}
}
// get default egress rule | policy_0_3954
if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[contains(@name, 'policy') and contains(@name, '3954')]")) {
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")) {
@ -292,7 +297,7 @@ public class MockablePaloAltoResource extends PaloAltoResource {
}
// add egress firewall rule
if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0']")) {
if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0_3954']")) {
response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
context.put("has_egress_fw_rule", "true");
}
@ -325,7 +330,7 @@ public class MockablePaloAltoResource extends PaloAltoResource {
// 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']")) {
if (params.get("xpath").equals("/config/devices/entry/vsys/entry[@name='vsys1']/rulebase/security/rules/entry[@name='policy_0_3954']")) {
response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
context.remove("has_egress_fw_rule");
}

View File

@ -3718,9 +3718,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
Set<Provider> firewallProviderSet = new HashSet<Provider>();
firewallProviderSet.add(firewallProvider);
serviceProviderMap.put(Service.Firewall, firewallProviderSet);
if (!(firewallProvider.getName().equals(Provider.JuniperSRX.getName()) || firewallProvider.getName().equals(Provider.VirtualRouter.getName())) &&
if (!(firewallProvider.getName().equals(Provider.JuniperSRX.getName()) || firewallProvider.getName().equals(Provider.PaloAlto.getName()) || firewallProvider.getName().equals(Provider.VirtualRouter.getName())) &&
egressDefaultPolicy == false) {
throw new InvalidParameterValueException("Firewall egress with default policy " + egressDefaultPolicy + "is not supported by the provider " +
throw new InvalidParameterValueException("Firewall egress with default policy " + egressDefaultPolicy + " is not supported by the provider " +
firewallProvider.getName());
}
}