package tw.com.pictures; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.amazonaws.services.ec2.model.Address; import com.amazonaws.services.ec2.model.GroupIdentifier; import com.amazonaws.services.ec2.model.Instance; import com.amazonaws.services.ec2.model.IpPermission; import com.amazonaws.services.ec2.model.NetworkAcl; import com.amazonaws.services.ec2.model.NetworkAclAssociation; import com.amazonaws.services.ec2.model.NetworkAclEntry; import com.amazonaws.services.ec2.model.Route; import com.amazonaws.services.ec2.model.RouteTable; import com.amazonaws.services.ec2.model.RouteTableAssociation; import com.amazonaws.services.ec2.model.SecurityGroup; import com.amazonaws.services.ec2.model.Subnet; import com.amazonaws.services.ec2.model.Vpc; import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription; import com.amazonaws.services.rds.model.DBInstance; import com.amazonaws.services.rds.model.DBSecurityGroupMembership; import com.amazonaws.services.rds.model.DBSubnetGroup; import com.amazonaws.services.rds.model.VpcSecurityGroupMembership; import tw.com.exceptions.CfnAssistException; public class VPCVisitor { private static final Logger logger = LoggerFactory.getLogger(VPCVisitor.class); private DiagramBuilder diagramBuilder; private AmazonVPCFacade facade; private DiagramFactory factory; public VPCVisitor(DiagramBuilder diagramBuilder, AmazonVPCFacade facade, DiagramFactory factory) { this.diagramBuilder = diagramBuilder; this.facade = facade; this.factory = factory; } public void visit(Vpc vpc) throws CfnAssistException { VPCDiagramBuilder vpcDiagram = factory.createVPCDiagramBuilder(vpc); String vpcId = vpc.getVpcId(); /// for (Subnet subnet : facade.getSubnetFors(vpcId)) { visitSubnet(vpcDiagram, subnet); } /// for(RouteTable table : facade.getRouteTablesFor(vpcId)) { visitRouteTable(vpcDiagram, table); } // for(Address eip : facade.getEIPFor(vpcId)) { visitEIP(vpcDiagram, eip); } // for(LoadBalancerDescription elb : facade.getLBsFor(vpcId)) { visitELB(vpcDiagram, elb); } // for(DBInstance rds : facade.getRDSFor(vpcId)) { visitRDS(vpcDiagram, rds); } // for(NetworkAcl acl : facade.getACLs(vpcId)) { visitNetworkAcl(vpcDiagram, acl); } // for (Subnet subnet : facade.getSubnetFors(vpcId)) { visitSubnetForInstancesAndSecGroups(vpcDiagram, subnet); } diagramBuilder.add(vpcDiagram); } private void visitRDS(VPCDiagramBuilder vpcDiagram, DBInstance rds) throws CfnAssistException { logger.debug("visit rds " + rds.getDBInstanceIdentifier()); vpcDiagram.addDBInstance(rds); DBSubnetGroup dbSubnetGroup = rds.getDBSubnetGroup(); if (dbSubnetGroup!=null) { for(com.amazonaws.services.rds.model.Subnet subnet : dbSubnetGroup.getSubnets()) { String subnetId = subnet.getSubnetIdentifier(); logger.debug("visit rds subnet " + subnetId); vpcDiagram.associateDBWithSubnet(rds, subnetId); } } addDBSecurityGroupsToDiagram(vpcDiagram, rds); } private void addDBSecurityGroupsToDiagram(VPCDiagramBuilder vpcDiagram, DBInstance rds) throws CfnAssistException { String dbInstanceIdentifier = rds.getDBInstanceIdentifier(); for(DBSecurityGroupMembership secGroupMember : rds.getDBSecurityGroups()) { String groupName = secGroupMember.getDBSecurityGroupName(); SecurityGroup dbSecGroup = facade.getSecurityGroupDetailsByName(groupName); logger.debug("visit rds secgroup " + dbSecGroup.getGroupId()); addSecGroupToDiagram(vpcDiagram, dbInstanceIdentifier, dbSecGroup); } // for(VpcSecurityGroupMembership secGroupMember : rds.getVpcSecurityGroups()) { String groupId = secGroupMember.getVpcSecurityGroupId(); SecurityGroup dbSecGroup = facade.getSecurityGroupDetailsById(groupId); logger.debug("visit rds vpc secgroup " + dbSecGroup.getGroupId()); addSecGroupToDiagram(vpcDiagram, dbInstanceIdentifier, dbSecGroup); } } private void addSecGroupToDiagram(VPCDiagramBuilder vpcDiagram, String instanceId, SecurityGroup dbSecGroup) throws CfnAssistException { vpcDiagram.addSecurityGroup(dbSecGroup); vpcDiagram.associateInstanceWithSecGroup(instanceId, dbSecGroup); String groupId = dbSecGroup.getGroupId(); for(IpPermission perm : dbSecGroup.getIpPermissions()) { vpcDiagram.addSecGroupInboundPerms(groupId, perm); } for(IpPermission perm : dbSecGroup.getIpPermissionsEgress()) { vpcDiagram.addSecGroupOutboundPerms(groupId, perm); } } private void visitELB(VPCDiagramBuilder vpcDiagramBuilder, LoadBalancerDescription elb) throws CfnAssistException { logger.debug("visit elb " + elb.getLoadBalancerName()); vpcDiagramBuilder.addELB(elb); for(com.amazonaws.services.elasticloadbalancing.model.Instance instance : elb.getInstances()) { vpcDiagramBuilder.associateELBToInstance(elb, instance.getInstanceId()); } for(String subnetId : elb.getSubnets()) { vpcDiagramBuilder.associateELBToSubnet(elb, subnetId); } for(String groupId : elb.getSecurityGroups()) { SecurityGroup group = facade.getSecurityGroupDetailsById(groupId); addSecGroupToDiagram(vpcDiagramBuilder, elb.getDNSName(), group); } } private void visitSubnetForInstancesAndSecGroups(VPCDiagramBuilder vpcDiagramBuilder, Subnet subnet) throws CfnAssistException { String subnetId = subnet.getSubnetId(); logger.debug("visit subnet (for sec groups) " + subnetId); for(Instance instance : facade.getInstancesFor(subnetId)) { for(GroupIdentifier groupId : instance.getSecurityGroups()) { logger.debug("visit securitygroup " + groupId.getGroupId() + " for instance " + instance.getInstanceId()); SecurityGroup group = facade.getSecurityGroupDetailsById(groupId.getGroupId()); vpcDiagramBuilder.addSecurityGroup(group, subnetId); vpcDiagramBuilder.associateInstanceWithSecGroup(instance.getInstanceId(), group); visitInboundSecGroupPerms(vpcDiagramBuilder, group, subnetId); visitOutboundSecGroupPerms(vpcDiagramBuilder, group, subnetId); } } } private void visitOutboundSecGroupPerms(VPCDiagramBuilder vpcDiagramBuilder, SecurityGroup group, String subnetId) throws CfnAssistException { for(IpPermission perm : group.getIpPermissionsEgress()) { vpcDiagramBuilder.addSecGroupOutboundPerms(group.getGroupId(), perm, subnetId); } } private void visitInboundSecGroupPerms(VPCDiagramBuilder vpcDiagramBuilder, SecurityGroup group, String subnetId) throws CfnAssistException { for(IpPermission perm : group.getIpPermissions()) { vpcDiagramBuilder.addSecGroupInboundPerms(group.getGroupId(), perm, subnetId); } } private void visitNetworkAcl(VPCDiagramBuilder vpcDiagramBuilder, NetworkAcl acl) throws CfnAssistException { vpcDiagramBuilder.addAcl(acl); String networkAclId = acl.getNetworkAclId(); logger.debug("visit acl " + networkAclId); for(NetworkAclAssociation assoc : acl.getAssociations()) { String subnetId = assoc.getSubnetId(); vpcDiagramBuilder.associateAclWithSubnet(acl, subnetId); for(NetworkAclEntry entry : acl.getEntries()) { if (entry.getEgress()) { vpcDiagramBuilder.addACLOutbound(networkAclId, entry, subnetId); } else { vpcDiagramBuilder.addACLInbound(networkAclId, entry, subnetId); } } } } private void visitEIP(VPCDiagramBuilder vpcDiagram, Address eip) throws CfnAssistException { logger.debug("visit eip " + eip.getAllocationId()); vpcDiagram.addEIP(eip); String instanceId = eip.getInstanceId(); if (instanceId!=null) { vpcDiagram.linkEIPToInstance(eip.getPublicIp(), instanceId); } } private void visitSubnet(VPCDiagramBuilder parent, Subnet subnet) throws CfnAssistException { SubnetDiagramBuilder subnetDiagram = factory.createSubnetDiagramBuilder(parent, subnet); String subnetId = subnet.getSubnetId(); logger.debug("visit subnet " + subnetId); List<Instance> instances = facade.getInstancesFor(subnetId); for(Instance instance : instances) { visit(subnetDiagram, instance); } parent.add(subnetId, subnetDiagram); } private void visitRouteTable(VPCDiagramBuilder vpcDiagram, RouteTable routeTable) throws CfnAssistException { logger.debug("visit routetable " + routeTable.getRouteTableId()); List<Route> routes = routeTable.getRoutes(); List<RouteTableAssociation> usersOfTable = routeTable.getAssociations(); for (RouteTableAssociation usedBy : usersOfTable) { String subnetId = usedBy.getSubnetId(); // can subnet ever be null in an association? if (subnetId!=null) { vpcDiagram.addAsssociatedRouteTable(routeTable, subnetId); // possible duplication if route table reused? for (Route route : routes) { vpcDiagram.addRoute(routeTable.getRouteTableId(), subnetId, route); } } } } private void visit(SubnetDiagramBuilder subnetDiagram, Instance instance) throws CfnAssistException { logger.debug("visit instance " + instance.getInstanceId()); subnetDiagram.add(instance); } }