/*******************************************************************************
* Copyright 2012 Urbancode, Inc
*
* Licensed 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.urbancode.terraform.tasks.aws;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.log4j.Logger;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.model.RouteTable;
import com.amazonaws.services.ec2.model.RouteTableAssociation;
import com.urbancode.terraform.tasks.aws.helpers.AWSHelper;
import com.urbancode.terraform.tasks.common.exceptions.EnvironmentCreationException;
import com.urbancode.terraform.tasks.common.exceptions.EnvironmentDestructionException;
import com.urbancode.x2o.tasks.SubTask;
public class RouteTableTask extends SubTask {
//**********************************************************************************************
// CLASS
//**********************************************************************************************
final static private Logger log = Logger.getLogger(RouteTableTask.class);
//**********************************************************************************************
// INSTANCE
//**********************************************************************************************
private AmazonEC2 ec2Client;
private AWSHelper helper;
private ContextAWS context;
private String routeTableId;
private String target;
private String vpcId;
private String subnetName;
private String assId;
private List<RouteTask> routes = new ArrayList<RouteTask>();
private boolean isMainTable = false;
//----------------------------------------------------------------------------------------------
public RouteTableTask(ContextAWS context) {
this.context = context;
helper = new AWSHelper();
}
//----------------------------------------------------------------------------------------------
public String getAssocId() {
return assId;
}
//----------------------------------------------------------------------------------------------
public String getSubnetName() {
return subnetName;
}
//----------------------------------------------------------------------------------------------
public String getId() {
return routeTableId;
}
//----------------------------------------------------------------------------------------------
public List<RouteTask> getRoutes() {
return Collections.unmodifiableList(routes);
}
//----------------------------------------------------------------------------------------------
public boolean getDefault() {
return isMainTable;
}
//----------------------------------------------------------------------------------------------
public void setDefault(boolean isMainTable) {
this.isMainTable = isMainTable;
}
//----------------------------------------------------------------------------------------------
public void setAssocId(String assocId) {
this.assId = assocId;
}
//----------------------------------------------------------------------------------------------
public void setSubnetName(String subnetName) {
this.subnetName = subnetName;
}
//----------------------------------------------------------------------------------------------
public void setVpcId(String vpcId) {
this.vpcId = vpcId;
}
//----------------------------------------------------------------------------------------------
public void setRouteTarget(String target) {
this.target = target;
}
//----------------------------------------------------------------------------------------------
public void setId(String id) {
this.routeTableId = id;
}
//----------------------------------------------------------------------------------------------
public RouteTask createRoute() {
RouteTask route = new RouteTask(context);
routes.add(route);
return route;
}
//----------------------------------------------------------------------------------------------
public boolean existsInAws() {
if (ec2Client == null) {
ec2Client = context.fetchEC2Client();
}
boolean result = false;
List<String> id = new ArrayList<String>();
id.add(getId());
List<RouteTable> tables = helper.getRouteTables(id, ec2Client);
if (tables != null && !tables.isEmpty()) {
result = true;
}
return result;
}
/**
*
*
* @param defaultRoute
* @return
*/
private String setupMainTable(boolean defaultRoute) {
String result = null;
// grab id of first (only) route table in vpc
List<RouteTable> tables = helper.getRouteTables(null, ec2Client);
log.debug("tables found: " + tables.size());
for (RouteTable table : tables) {
log.debug("Table: " + table.getRouteTableId());
log.debug("VPC: " + table.getVpcId());
if (table.getVpcId().equals(vpcId)) {
routeTableId = table.getRouteTableId();
log.info("Found main route table " + routeTableId);
break;
}
}
if (defaultRoute) {
// set default route
RouteTask dRoute = new RouteTask(context);
dRoute.setRouteTableId(routeTableId);
dRoute.setTarget(target);
dRoute.setDest("0.0.0.0/0");
dRoute.create();
}
return result;
}
//----------------------------------------------------------------------------------------------
@Override
public void create()
throws EnvironmentCreationException {
log.debug("Main: " + isMainTable);
if (ec2Client == null) {
ec2Client = context.fetchEC2Client();
}
try {
log.info("Creating RouteTable...");
if (isMainTable) {
log.info("Setting up main table");
setupMainTable(true);
}
else {
log.info("Setting route table VpcId to: " + vpcId);
setId(helper.createRouteTable(vpcId, ec2Client));
}
log.info("RouteTableId created with routeTableId: " + routeTableId);
helper.tagInstance(routeTableId, "terraform.environment", context.getEnvironment().getName(), ec2Client);
// create any other routes
if (routes != null) {
for (RouteTask route : getRoutes()) {
route.setRouteTableId(routeTableId);
route.create();
}
}
String subnetId = ((EnvironmentTaskAWS)context.getEnvironment()).getVpc().findSubnetForName(subnetName).getId();
assId = helper.associateRouteTableWithSubnet(routeTableId, subnetId, ec2Client);
} catch (Exception e) {
log.error("RouteTable not created",e );
throw new EnvironmentCreationException("Could not create RouteTable completely", e);
}
finally {
ec2Client = null;
}
}
//----------------------------------------------------------------------------------------------
@Override
public void destroy()
throws EnvironmentDestructionException {
if (ec2Client == null) {
ec2Client = context.fetchEC2Client();
}
log.info("Destroying RouteTable...");
try {
// We need to check to see if the route table is associated with anything before disassociating
String subnetId = ((EnvironmentTaskAWS)context.getEnvironment()).getVpc().findSubnetForName(subnetName).getId();
List<String> id = new ArrayList<String>();
id.add(routeTableId);
List<RouteTable> table = helper.getRouteTables(id, ec2Client);
List<RouteTableAssociation> asses = table.get(0).getAssociations();
if (asses != null && !asses.isEmpty()) {
for (RouteTableAssociation ass : asses) {
if (subnetId.equals(ass.getSubnetId())) {
if (ass.getRouteTableAssociationId() != null && !ass.getRouteTableAssociationId().equals("")) {
helper.disassociateRouteTableFromSubnet(assId, ec2Client);
}
}
}
}
if (!isMainTable) {
helper.deleteRouteTable(routeTableId, ec2Client);
}
setAssocId(null);
setId(null);
}
catch (Exception e) {
log.error("Unable to destroy RouteTable completely", e);
throw new EnvironmentDestructionException("Could not destroy RouteTable", e);
}
finally {
ec2Client = null;
}
}
}