package org.batfish.representation.aws_vpcs;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.batfish.common.BatfishException;
import org.batfish.common.BatfishLogger;
import org.batfish.datamodel.Configuration;
import org.batfish.datamodel.Interface;
import org.batfish.datamodel.Ip;
import org.batfish.datamodel.IpAccessList;
import org.batfish.datamodel.IpAccessListLine;
import org.batfish.datamodel.Prefix;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
public class Instance implements AwsVpcEntity, Serializable {
private static final long serialVersionUID = 1L;
private transient IpAccessList _inAcl;
private final String _instanceId;
private final List<String> _networkInterfaces;
private transient IpAccessList _outAcl;
private final List<String> _securityGroups;
private final String _subnetId;
private final String _vpcId;
public Instance(JSONObject jObj, BatfishLogger logger) throws JSONException {
_securityGroups = new LinkedList<>();
_networkInterfaces = new LinkedList<>();
_instanceId = jObj.getString(JSON_KEY_INSTANCE_ID);
boolean hasVpcId = jObj.has(JSON_KEY_VPC_ID);
_vpcId = hasVpcId ? jObj.getString(JSON_KEY_VPC_ID) : null;
_subnetId = hasVpcId ? jObj.getString(JSON_KEY_SUBNET_ID) : null;
JSONArray securityGroups = jObj.getJSONArray(JSON_KEY_SECURITY_GROUPS);
initSecurityGroups(securityGroups, logger);
JSONArray networkInterfaces = jObj
.getJSONArray(JSON_KEY_NETWORK_INTERFACES);
initNetworkInterfaces(networkInterfaces, logger);
// check if the public and private ip addresses are associated with an
// interface
}
@Override
public String getId() {
return _instanceId;
}
public IpAccessList getInAcl() {
return _inAcl;
}
public String getInstanceId() {
return _instanceId;
}
public List<String> getNetworkInterfaces() {
return _networkInterfaces;
}
public IpAccessList getOutAcl() {
return _outAcl;
}
public List<String> getSecurityGroups() {
return _securityGroups;
}
public String getSubnetId() {
return _subnetId;
}
public String getVpcId() {
return _vpcId;
}
private void initNetworkInterfaces(JSONArray routes, BatfishLogger logger)
throws JSONException {
for (int index = 0; index < routes.length(); index++) {
JSONObject childObject = routes.getJSONObject(index);
_networkInterfaces
.add(childObject.getString(JSON_KEY_NETWORK_INTERFACE_ID));
}
}
private void initSecurityGroups(JSONArray associations, BatfishLogger logger)
throws JSONException {
for (int index = 0; index < associations.length(); index++) {
JSONObject childObject = associations.getJSONObject(index);
_securityGroups.add(childObject.getString(JSON_KEY_GROUP_ID));
}
}
public Configuration toConfigurationNode(AwsVpcConfiguration awsVpcConfig) {
String sgIngressAclName = "~SECURITY_GROUP_INGRESS_ACL~";
String sgEgressAclName = "~SECURITY_GROUP_EGRESS_ACL~";
Configuration cfgNode = new Configuration(_instanceId);
List<IpAccessListLine> inboundRules = new LinkedList<>();
List<IpAccessListLine> outboundRules = new LinkedList<>();
// create ACLs from inboundRules and outboundRules
IpAccessList inAcl = new IpAccessList(sgIngressAclName, inboundRules);
IpAccessList outAcl = new IpAccessList(sgEgressAclName, outboundRules);
cfgNode.getIpAccessLists().put(sgIngressAclName, inAcl);
cfgNode.getIpAccessLists().put(sgEgressAclName, outAcl);
_inAcl = inAcl;
_outAcl = outAcl;
for (String sGroupId : _securityGroups) {
SecurityGroup sGroup = awsVpcConfig.getSecurityGroups().get(sGroupId);
if (sGroup == null) {
throw new BatfishException("Security group " + sGroupId
+ " for instance " + _instanceId + " not found");
}
sGroup.addInOutAccessLines(inboundRules, outboundRules);
}
for (String interfaceId : _networkInterfaces) {
NetworkInterface netInterface = awsVpcConfig.getNetworkInterfaces()
.get(interfaceId);
if (netInterface == null) {
throw new BatfishException("Network interface " + interfaceId
+ " for instance " + _instanceId + " not found");
}
Interface iface = new Interface(interfaceId, cfgNode);
Set<Ip> privateIpAddresses = new TreeSet<>();
privateIpAddresses
.addAll(netInterface.getIpAddressAssociations().keySet());
Subnet subnet = awsVpcConfig.getSubnets()
.get(netInterface.getSubnetId());
Prefix ifaceSubnet = subnet.getCidrBlock();
for (Ip ip : privateIpAddresses) {
if (!ifaceSubnet.contains(ip)) {
throw new BatfishException(
"Instance subnet: " + ifaceSubnet.toString()
+ " does not contain private ip: " + ip.toString());
}
if (ip.equals(ifaceSubnet.getEndAddress())) {
throw new BatfishException("Expected end address: "
+ ip.toString() + " to be used by generated subnet node");
}
Prefix prefix = new Prefix(ip, ifaceSubnet.getPrefixLength());
iface.getAllPrefixes().add(prefix);
}
Ip lowestIp = privateIpAddresses.toArray(new Ip[] {})[0];
iface.setPrefix(new Prefix(lowestIp, ifaceSubnet.getPrefixLength()));
// apply ACLs to interface
iface.setIncomingFilter(inAcl);
iface.setOutgoingFilter(outAcl);
cfgNode.getInterfaces().put(interfaceId, iface);
cfgNode.getDefaultVrf().getInterfaces().put(interfaceId, iface);
}
return cfgNode;
}
}