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 listSrxFirewallNetworks=1
#### Palo Alto firewall commands #### Palo Alto firewall commands
addExternalFirewall=1
deleteExternalFirewall=1
listExternalFirewalls=1
addPaloAltoFirewall=1 addPaloAltoFirewall=1
deletePaloAltoFirewall=1 deletePaloAltoFirewall=1
configurePaloAltoFirewall=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 org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDBUtils;
import com.cloud.api.commands.AddExternalFirewallCmd;
import com.cloud.api.commands.AddPaloAltoFirewallCmd; import com.cloud.api.commands.AddPaloAltoFirewallCmd;
import com.cloud.api.commands.ConfigurePaloAltoFirewallCmd; import com.cloud.api.commands.ConfigurePaloAltoFirewallCmd;
import com.cloud.api.commands.DeleteExternalFirewallCmd;
import com.cloud.api.commands.DeletePaloAltoFirewallCmd; import com.cloud.api.commands.DeletePaloAltoFirewallCmd;
import com.cloud.api.commands.ListExternalFirewallsCmd;
import com.cloud.api.commands.ListPaloAltoFirewallNetworksCmd; import com.cloud.api.commands.ListPaloAltoFirewallNetworksCmd;
import com.cloud.api.commands.ListPaloAltoFirewallsCmd; import com.cloud.api.commands.ListPaloAltoFirewallsCmd;
import com.cloud.api.response.PaloAltoFirewallResponse; import com.cloud.api.response.PaloAltoFirewallResponse;
@ -293,85 +290,12 @@ public class PaloAltoExternalFirewallElement extends ExternalFirewallDeviceManag
return true; 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 @Override
public List<Class<?>> getCommands() { public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<Class<?>>(); List<Class<?>> cmdList = new ArrayList<Class<?>>();
cmdList.add(AddExternalFirewallCmd.class);
cmdList.add(AddPaloAltoFirewallCmd.class); cmdList.add(AddPaloAltoFirewallCmd.class);
cmdList.add(ConfigurePaloAltoFirewallCmd.class); cmdList.add(ConfigurePaloAltoFirewallCmd.class);
cmdList.add(DeleteExternalFirewallCmd.class);
cmdList.add(DeletePaloAltoFirewallCmd.class); cmdList.add(DeletePaloAltoFirewallCmd.class);
cmdList.add(ListExternalFirewallsCmd.class);
cmdList.add(ListPaloAltoFirewallNetworksCmd.class); cmdList.add(ListPaloAltoFirewallNetworksCmd.class);
cmdList.add(ListPaloAltoFirewallsCmd.class); cmdList.add(ListPaloAltoFirewallsCmd.class);
return cmdList; return cmdList;

View File

@ -20,12 +20,9 @@ import java.util.List;
import org.apache.cloudstack.api.response.ExternalFirewallResponse; import org.apache.cloudstack.api.response.ExternalFirewallResponse;
import com.cloud.api.commands.AddExternalFirewallCmd;
import com.cloud.api.commands.AddPaloAltoFirewallCmd; import com.cloud.api.commands.AddPaloAltoFirewallCmd;
import com.cloud.api.commands.ConfigurePaloAltoFirewallCmd; import com.cloud.api.commands.ConfigurePaloAltoFirewallCmd;
import com.cloud.api.commands.DeleteExternalFirewallCmd;
import com.cloud.api.commands.DeletePaloAltoFirewallCmd; import com.cloud.api.commands.DeletePaloAltoFirewallCmd;
import com.cloud.api.commands.ListExternalFirewallsCmd;
import com.cloud.api.commands.ListPaloAltoFirewallNetworksCmd; import com.cloud.api.commands.ListPaloAltoFirewallNetworksCmd;
import com.cloud.api.commands.ListPaloAltoFirewallsCmd; import com.cloud.api.commands.ListPaloAltoFirewallsCmd;
import com.cloud.api.response.PaloAltoFirewallResponse; import com.cloud.api.response.PaloAltoFirewallResponse;
@ -72,24 +69,4 @@ public interface PaloAltoFirewallElementService extends PluggableService {
public List<? extends Network> listNetworks(ListPaloAltoFirewallNetworksCmd cmd); public List<? extends Network> listNetworks(ListPaloAltoFirewallNetworksCmd cmd);
public PaloAltoFirewallResponse createPaloAltoFirewallResponse(ExternalFirewallDeviceVO fwDeviceVO); 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.naming.ConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.OutputKeys; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
@ -55,6 +56,7 @@ import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HTTP;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
@ -462,11 +464,14 @@ public class PaloAltoResource implements ServerResource {
String guestVlanSubnet = NetUtils.getCidrSubNet(guestVlanGateway, cidrSize); String guestVlanSubnet = NetUtils.getCidrSubNet(guestVlanGateway, cidrSize);
Long publicVlanTag = null; Long publicVlanTag = null;
if (ip.getBroadcastUri() != null && !ip.getBroadcastUri().equals("untagged")) { if (ip.getBroadcastUri() != null) {
try { String parsedVlanTag = parsePublicVlanTag(ip.getBroadcastUri());
publicVlanTag = Long.parseLong(ip.getBroadcastUri()); if (!parsedVlanTag.equals("untagged")) {
} catch (Exception e) { try {
throw new ExecutionException("Could not parse public VLAN tag: " + ip.getBroadcastUri()); 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 { String privateGateway, String privateSubnet, long privateCidrSize) throws ExecutionException {
privateSubnet = privateSubnet + "/" + privateCidrSize; privateSubnet = privateSubnet + "/" + privateCidrSize;
// remove any orphaned egress rules if they exist...
removeOrphanedFirewallRules(cmdList, privateVlanTag);
if (type.equals(GuestNetworkType.SOURCE_NAT)) { if (type.equals(GuestNetworkType.SOURCE_NAT)) {
manageNetworkIsolation(cmdList, PaloAltoPrimative.DELETE, privateVlanTag, privateSubnet, privateGateway); manageNetworkIsolation(cmdList, PaloAltoPrimative.DELETE, privateVlanTag, privateSubnet, privateGateway);
manageSrcNatRule(cmdList, PaloAltoPrimative.DELETE, type, publicVlanTag, sourceNatIpAddress + "/32", privateVlanTag, privateGateway + "/" + privateCidrSize); 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 dstNatName = genDstNatRuleName(publicIp, rule.getId());
String publicInterfaceName; String publicInterfaceName;
String publicVlanTag = rule.getSrcVlanTag(); String publicVlanTag;
if (publicVlanTag == null || publicVlanTag.equals("untagged")) { if (rule.getSrcVlanTag() == null) {
publicInterfaceName = genPublicInterfaceName(new Long("9999")); publicInterfaceName = genPublicInterfaceName(new Long("9999"));
} else { } 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) { switch (prim) {
@ -1085,11 +1098,16 @@ public class PaloAltoResource implements ServerResource {
String stcNatName = genStcNatRuleName(publicIp, rule.getId()); String stcNatName = genStcNatRuleName(publicIp, rule.getId());
String publicInterfaceName; String publicInterfaceName;
String publicVlanTag = rule.getSrcVlanTag(); String publicVlanTag;
if (publicVlanTag == null || publicVlanTag.equals("untagged")) { if (rule.getSrcVlanTag() == null) {
publicInterfaceName = genPublicInterfaceName(new Long("9999")); publicInterfaceName = genPublicInterfaceName(new Long("9999"));
} else { } 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) { switch (prim) {
@ -1170,13 +1188,20 @@ public class PaloAltoResource implements ServerResource {
/* /*
* Firewall rule implementation * Firewall rule implementation
*/ */
private String genFirewallRuleName(long id) { // ingress
private String genFirewallRuleName(long id) {
return "policy_" + Long.toString(id); 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 { 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) { switch (prim) {
@ -1203,6 +1228,7 @@ public class PaloAltoResource implements ServerResource {
String serviceXML; String serviceXML;
String protocol = rule.getProtocol(); String protocol = rule.getProtocol();
String action = "allow";
// Only ICMP will use an Application, so others will be any. // Only ICMP will use an Application, so others will be any.
if (protocol.equals(Protocol.ICMP.toString())) { if (protocol.equals(Protocol.ICMP.toString())) {
@ -1232,11 +1258,23 @@ public class PaloAltoResource implements ServerResource {
serviceXML = "<member>any</member>"; 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; srcZone = _privateZone;
dstZone = _publicZone; dstZone = _publicZone;
dstAddressXML = "<member>any</member>"; 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; srcZone = _publicZone;
dstZone = _privateZone; dstZone = _privateZone;
dstAddressXML = "<member>" + rule.getSrcIp() + "</member>"; dstAddressXML = "<member>" + rule.getSrcIp() + "</member>";
@ -1265,6 +1303,7 @@ public class PaloAltoResource implements ServerResource {
} }
} }
// build new rule xml
String xml = ""; String xml = "";
xml += "<from><member>" + srcZone + "</member></from>"; xml += "<from><member>" + srcZone + "</member></from>";
xml += "<to><member>" + dstZone + "</member></to>"; xml += "<to><member>" + dstZone + "</member></to>";
@ -1272,16 +1311,52 @@ public class PaloAltoResource implements ServerResource {
xml += "<destination>" + dstAddressXML + "</destination>"; xml += "<destination>" + dstAddressXML + "</destination>";
xml += "<application>" + appXML + "</application>"; xml += "<application>" + appXML + "</application>";
xml += "<service>" + serviceXML + "</service>"; xml += "<service>" + serviceXML + "</service>";
xml += "<action>allow</action>"; xml += "<action>"+action+"</action>";
xml += "<negate-source>no</negate-source>"; xml += "<negate-source>no</negate-source>";
xml += "<negate-destination>no</negate-destination>"; 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>"; 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>"; 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>(); Map<String, String> a_params = new HashMap<String, String>();
a_params.put("type", "config"); a_params.put("type", "config");
a_params.put("action", "set"); a_params.put("action", "set");
@ -1289,6 +1364,17 @@ public class PaloAltoResource implements ServerResource {
a_params.put("element", xml); a_params.put("element", xml);
cmdList.add(new DefaultPaloAltoCommand(PaloAltoMethod.POST, a_params)); 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; return true;
case DELETE: 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 * Usage
*/ */
@ -1935,6 +2040,10 @@ public class PaloAltoResource implements ServerResource {
return ip.replace('.', '-').replace('/', '-'); return ip.replace('.', '-').replace('/', '-');
} }
private String parsePublicVlanTag(String uri) {
return uri.replace("vlan://", "");
}
private Protocol getProtocol(String protocolName) throws ExecutionException { private Protocol getProtocol(String protocolName) throws ExecutionException {
protocolName = protocolName.toLowerCase(); 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) { private String prettyFormat(String input) {
int indent = 4; int indent = 4;
try { try {
@ -1999,14 +2122,12 @@ public class PaloAltoResource implements ServerResource {
@Override @Override
public void setName(String name) { public void setName(String name) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
//@Override //@Override
@Override @Override
public void setConfigParams(Map<String, Object> params) { public void setConfigParams(Map<String, Object> params) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
//@Override //@Override
@ -2027,7 +2148,5 @@ public class PaloAltoResource implements ServerResource {
@Override @Override
public void setRunLevel(int level) { public void setRunLevel(int level) {
// TODO Auto-generated method stub // 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 // 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']")) { 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")) { 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\">" "<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>" + "<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>" + "</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>"; + "</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 // 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 (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")) { 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 // 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>"; response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
context.put("has_egress_fw_rule", "true"); context.put("has_egress_fw_rule", "true");
} }
@ -325,7 +330,7 @@ public class MockablePaloAltoResource extends PaloAltoResource {
// action = 'delete' // action = 'delete'
if (params.get("action").equals("delete")) { if (params.get("action").equals("delete")) {
// remove egress firewall rule // 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>"; response = "<response status=\"success\" code=\"20\"><msg>command succeeded</msg></response>";
context.remove("has_egress_fw_rule"); 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>(); Set<Provider> firewallProviderSet = new HashSet<Provider>();
firewallProviderSet.add(firewallProvider); firewallProviderSet.add(firewallProvider);
serviceProviderMap.put(Service.Firewall, firewallProviderSet); 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) { 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()); firewallProvider.getName());
} }
} }