func GetRegionVpcs(region string, vpcList *Vpcs, search string) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ec2.New(sess)
	result, err := svc.DescribeVpcs(&ec2.DescribeVpcsInput{})
	if err != nil {
		return err
	}
	vpcs := make(Vpcs, len(result.Vpcs))
	for i, vpc := range result.Vpcs {
		vpcs[i].Marshal(vpc, region)
	}
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, v := range vpcs {
			rVpc := reflect.ValueOf(v)
			for k := 0; k < rVpc.NumField(); k++ {
				sVal := rVpc.Field(k).String()
				if term.MatchString(sVal) {
					*vpcList = append(*vpcList, vpcs[i])
					continue Loop
				}
			}
		}
	} else {
		*vpcList = append(*vpcList, vpcs[:]...)
	}
	return nil
}
GetRegionVpcs returns a list of a regions VPCs that match the provided search term
package aws
import (
	"errors"
	"fmt"
	"os"
	"reflect"
	"regexp"
	"sync"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/murdinc/awsm/aws/regions"
	"github.com/murdinc/awsm/config"
	"github.com/murdinc/awsm/models"
	"github.com/murdinc/terminal"
	"github.com/olekukonko/tablewriter"
)
type Vpcs []Vpc
type Vpc models.Vpc
type InternetGateways []InternetGateway
type InternetGateway models.InternetGateway
type RouteTables []RouteTable
type RouteTable models.RouteTable
type RouteTableAssociations []RouteTableAssociation
type RouteTableAssociation models.RouteTableAssociation
func GetRegionVpcByTag(region, key, value string) (Vpc, error) {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ec2.New(sess)
	params := &ec2.DescribeVpcsInput{
		Filters: []*ec2.Filter{
			{
				Name: aws.String("tag:" + key),
				Values: []*string{
					aws.String(value),
				},
			},
		},
	}
	result, err := svc.DescribeVpcs(params)
	if err != nil {
		return Vpc{}, err
	}
	count := len(result.Vpcs)
	switch count {
	case 0:
		return Vpc{}, errors.New("No VPC found with [" + key + "] of [" + value + "] in [" + region + "], Aborting!")
	case 1:
		vpc := new(Vpc)
		vpc.Marshal(result.Vpcs[0], region)
		return *vpc, nil
	}
	return Vpc{}, errors.New("Found more than one VPC with [" + key + "] of [" + value + "] in [" + region + "], Aborting!")
}
func GetVpcByTag(region, key, value string) (Vpc, error) {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ec2.New(sess)
	params := &ec2.DescribeVpcsInput{
		Filters: []*ec2.Filter{
			{
				Name: aws.String("tag:" + key),
				Values: []*string{
					aws.String(value),
				},
			},
		},
	}
	result, err := svc.DescribeVpcs(params)
	if err != nil {
		return Vpc{}, err
	}
	count := len(result.Vpcs)
	switch count {
	case 0:
		return Vpc{}, errors.New("No VPC found with [" + key + "] of [" + value + "] in [" + region + "], Aborting!")
	case 1:
		vpc := new(Vpc)
		vpc.Marshal(result.Vpcs[0], region)
		return *vpc, nil
	}
	return Vpc{}, errors.New("Found more than one VPC with [" + key + "] of [" + value + "] in [" + region + "], Aborting!")
}
func (v *Vpc) GetVpcSecurityGroupByTag(key, value string) (SecurityGroup, error) {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(v.Region)}))
	svc := ec2.New(sess)
	params := &ec2.DescribeSecurityGroupsInput{
		Filters: []*ec2.Filter{
			{
				Name: aws.String("vpc-id"),
				Values: []*string{
					aws.String(v.VpcID),
				},
			},
			{
				Name: aws.String("tag:" + key),
				Values: []*string{
					aws.String(value),
				},
			},
		},
	}
	result, err := svc.DescribeSecurityGroups(params)
	if err != nil {
		return SecurityGroup{}, err
	}
	count := len(result.SecurityGroups)
	switch count {
	case 0:
		return SecurityGroup{}, errors.New("No VPC Security Group found with [" + key + "] of [" + value + "] in [" + v.Region + "], Aborting!")
	case 1:
		sec := new(SecurityGroup)
		sec.Marshal(result.SecurityGroups[0], v.Region, &Vpcs{*v})
		return *sec, nil
	}
	return SecurityGroup{}, errors.New("Found more than one VPC Security Group with [" + key + "] of [" + value + "] in [" + v.Region + "], Aborting!")
}
func (v *Vpc) GetVpcSecurityGroupByTagMulti(key string, value []string) (SecurityGroups, error) {
	var secList SecurityGroups
	for _, val := range value {
		secgroup, err := v.GetVpcSecurityGroupByTag(key, val)
		if err != nil {
			return SecurityGroups{}, err
		}
		secList = append(secList, secgroup)
	}
	return secList, nil
}
func (v *Vpc) GetVpcSubnetByTag(key, value string) (Subnet, error) {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(v.Region)}))
	svc := ec2.New(sess)
	params := &ec2.DescribeSubnetsInput{
		Filters: []*ec2.Filter{
			{
				Name: aws.String("tag:" + key),
				Values: []*string{
					aws.String(value),
				},
			},
			{
				Name: aws.String("vpc-id"),
				Values: []*string{
					aws.String(v.VpcID),
				},
			},
		},
	}
	result, err := svc.DescribeSubnets(params)
	if err != nil {
		return Subnet{}, err
	}
	count := len(result.Subnets)
	switch count {
	case 0:
		return Subnet{}, errors.New("No Subnet found with [" + key + "] of [" + value + "] in [" + v.Region + "] VPC [" + v.Name + "], Aborting!")
	case 1:
		subnet := new(Subnet)
		subnet.Marshal(result.Subnets[0], v.Region, &Vpcs{*v})
		return *subnet, nil
	}
	return Subnet{}, errors.New("Please limit your request to return only one Subnet")
}
func GetVpcs(search string) (*Vpcs, []error) {
	var wg sync.WaitGroup
	var errs []error
	vpcList := new(Vpcs)
	regions := GetRegionListWithoutIgnored()
	for _, region := range regions {
		wg.Add(1)
		go func(region *ec2.Region) {
			defer wg.Done()
			err := GetRegionVpcs(*region.RegionName, vpcList, search)
			if err != nil {
				terminal.ShowErrorMessage(fmt.Sprintf("Error gathering vpc list for region [%s]", *region.RegionName), err.Error())
				errs = append(errs, err)
			}
		}(region)
	}
	wg.Wait()
	return vpcList, errs
}
func AttachInternetGateway(gatewaySearch, vpcSearch string, dryRun bool) error {
	if dryRun {
		terminal.Information("--dry-run flag is set, not making any actual changes!")
	}
	gatewayList, errs := GetInternetGateways(gatewaySearch, true)
	if errs != nil {
		return errors.New("Error while trying to find the internet gateway!")
	}
	gatewayCount := len(*gatewayList)
	if gatewayCount < 1 {
		return errors.New("No available Internet Gateways found matching [" + gatewaySearch + "]")
	} else if gatewayCount > 1 {
		gatewayList.PrintTable()
		return errors.New("Please limit your search term to just one Internet Gateway")
	}
	gateway := (*gatewayList)[0]
	terminal.Information("Found Internet Gateway [" + gateway.InternetGatewayID + "] named [" + gateway.Name + "] in [" + gateway.Region + "]!")
	vpcList := new(Vpcs)
	GetRegionVpcs(gateway.Region, vpcList, vpcSearch)
	vpcCount := len(*vpcList)
	if vpcCount == 0 {
		return errors.New("No VPCs found for your search terms.")
	}
	if vpcCount > 1 {
		vpcList.PrintTable()
		return errors.New("Please limit your search to return only one VPC.")
	}
	vpc := (*vpcList)[0]
	terminal.Information("Found VPC [" + vpc.VpcID + "] named [" + vpc.Name + "] with a class of [" + vpc.Class + "] in [" + vpc.Region + "]!")
	if !terminal.PromptBool("Are you sure you want to attach this Internet Gateway to this VPC?") {
		terminal.ErrorLine("Aborting!")
		return nil
	}
	err := attachInternetGateway(vpc.VpcID, gateway.InternetGatewayID, vpc.Region, dryRun)
	if err != nil {
		return err
	}
	terminal.Information("Done!")
	return nil
}
func attachInternetGateway(vpcId, internetGatewayId, region string, dryRun bool) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ec2.New(sess)
	params := &ec2.AttachInternetGatewayInput{
		InternetGatewayId: aws.String(internetGatewayId),
		VpcId:             aws.String(vpcId),
		DryRun:            aws.Bool(dryRun),
	}
	_, err := svc.AttachInternetGateway(params)
	if err != nil {
		return err
	}
	terminal.Delta("Attached Internet Gateway [" + internetGatewayId + "] to VPC [" + vpcId + "]!")
	return nil
}
func AssociateRouteTable(routeTableSearch, subnetSearch string, dryRun bool) error {
	if dryRun {
		terminal.Information("--dry-run flag is set, not making any actual changes!")
	}
	subnetList, _ := GetSubnets(subnetSearch)
	subCount := len(*subnetList)
	if subCount == 0 {
		return errors.New("No Subnets found for your search terms.")
	}
	if subCount > 1 {
		subnetList.PrintTable()
		return errors.New("Please limit your search to return only one Subnet.")
	}
	subnet := (*subnetList)[0]
	terminal.Information("Found Subnet [" + subnet.SubnetID + "] named [" + subnet.Name + "] with a class of [" + subnet.Class + "] in [" + subnet.Region + "]!")
	rtList, err := GetVpcRouteTables(routeTableSearch, subnet.VpcID, subnet.Region)
	if err != nil {
		return errors.New("Error while trying to find the route table!")
	}
	rtCount := len(*rtList)
	if rtCount < 1 {
		return errors.New("No Route Tables found matching [" + routeTableSearch + "]")
	} else if rtCount > 1 {
		rtList.PrintTable()
		return errors.New("Please limit your search term to just one Route Table")
	}
	rt := (*rtList)[0]
	terminal.Information("Found Route Table [" + rt.RouteTableID + "] named[" + rt.Name + "] in [" + rt.Region + "]!")
	if !terminal.PromptBool("Are you sure you want to associate this Route Table to this Subnet?") {
		terminal.ErrorLine("Aborting!")
		return nil
	}
	associateRouteTable(rt.RouteTableID, subnet.SubnetID, subnet.Region, dryRun)
	terminal.Information("Done!")
	return nil
}
func associateRouteTable(rtId, subnetId, region string, dryRun bool) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ec2.New(sess)
	params := &ec2.AssociateRouteTableInput{
		RouteTableId: aws.String(rtId),
		SubnetId:     aws.String(subnetId),
		DryRun:       aws.Bool(dryRun),
	}
	_, err := svc.AssociateRouteTable(params)
	if err != nil {
		return err
	}
	terminal.Delta("Associated Route Table [" + rtId + "] to Subnet [" + subnetId + "] !")
	return nil
}
func DetachInternetGateway(gatewaySearch string, dryRun bool) error {
	if dryRun {
		terminal.Information("--dry-run flag is set, not making any actual changes!")
	}
	gatewayList, err := GetInternetGateways(gatewaySearch, false)
	if err != nil {
		return errors.New("Error while trying to find the internet gateway!")
	}
	gatewayCount := len(*gatewayList)
	if gatewayCount < 1 {
		return errors.New("No Internet Gateways found matching [" + gatewaySearch + "]")
	} else if gatewayCount > 1 {
		gatewayList.PrintTable()
		return errors.New("Please limit your search term to just one Internet Gateway")
	}
	gateway := (*gatewayList)[0]
	terminal.Information("Found Internet Gateway [" + gateway.InternetGatewayID + "] named [" + gateway.Name + "] attached to [" + gateway.Attachment + "] in [" + gateway.Region + "]!")
	if gateway.Attachment == "" {
		terminal.ErrorLine("This Internet Gateway does not appear to be attached to a VPC! Aborting.")
		return nil
	}
	if !terminal.PromptBool("Are you sure you want to detach this Internet Gateway from this VPC?") {
		terminal.ErrorLine("Aborting!")
		return nil
	}
	detachInternetGateway(gateway, dryRun)
	terminal.Information("Done!")
	return nil
}
func detachInternetGateway(internetGateway InternetGateway, dryRun bool) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(internetGateway.Region)}))
	svc := ec2.New(sess)
	params := &ec2.DetachInternetGatewayInput{
		InternetGatewayId: aws.String(internetGateway.InternetGatewayID),
		VpcId:             aws.String(internetGateway.Attachment),
		DryRun:            aws.Bool(dryRun),
	}
	_, err := svc.DetachInternetGateway(params)
	if err != nil {
		return err
	}
	terminal.Delta("Detached Internet Gateway [" + internetGateway.InternetGatewayID + "] named [" + internetGateway.Name + "] from VPC [" + internetGateway.Attachment + "]!")
	return nil
}
func DisassociateRouteTable(routeTableSearch, subnetSearch string, dryRun bool) error {
	if dryRun {
		terminal.Information("--dry-run flag is set, not making any actual changes!")
	}
	subnetList, _ := GetSubnets(subnetSearch)
	subCount := len(*subnetList)
	if subCount == 0 {
		return errors.New("No Subnets found for your search terms.")
	}
	if subCount > 1 {
		subnetList.PrintTable()
		return errors.New("Please limit your search to return only one Subnet.")
	}
	subnet := (*subnetList)[0]
	terminal.Information("Found Subnet [" + subnet.SubnetID + "] named [" + subnet.Name + "] with a class of [" + subnet.Class + "] in [" + subnet.Region + "]!")
	rtList, err := GetVpcRouteTables(routeTableSearch, subnet.VpcID, subnet.Region)
	if err != nil {
		return errors.New("Error while trying to find the route table!")
	}
	rtCount := len(*rtList)
	if rtCount < 1 {
		return errors.New("No Route Tables found matching [" + routeTableSearch + "]")
	} else if rtCount > 1 {
		rtList.PrintTable()
		return errors.New("Please limit your search term to just one Route Table")
	}
	rt := (*rtList)[0]
	terminal.Information("Found Route Table [" + rt.RouteTableID + "] named [" + rt.Name + "] in [" + rt.Region + "]!")
	associationId := ""
Loop:
	for _, association := range rt.Associations {
		if association.SubnetID == subnet.SubnetID {
			associationId = association.AssociationID
			break Loop
		}
	}
	if associationId == "" {
		return errors.New("Unable to locate the association id between this route table and subnet!")
	}
	if !terminal.PromptBool("Are you sure you want to disassociate this Route Table from this Subnet?") {
		terminal.ErrorLine("Aborting!")
		return nil
	}
	disassociateRouteTable(associationId, rt, subnet, dryRun)
	terminal.Information("Done!")
	return nil
}
func disassociateRouteTable(associationId string, rt RouteTable, subnet Subnet, dryRun bool) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(subnet.Region)}))
	svc := ec2.New(sess)
	params := &ec2.DisassociateRouteTableInput{
		AssociationId: aws.String(associationId),
		DryRun:        aws.Bool(dryRun),
	}
	_, err := svc.DisassociateRouteTable(params)
	if err != nil {
		return err
	}
	terminal.Delta("Disassociated Route Table [" + rt.RouteTableID + "] named [" + rt.Name + "] from Subnet [" + subnet.SubnetID + "] named [" + subnet.Name + "]!")
	return nil
}
func DeleteInternetGateway(gatewaySearch string, dryRun bool) error {
	if dryRun {
		terminal.Information("--dry-run flag is set, not making any actual changes!")
	}
	gatewayList, err := GetInternetGateways(gatewaySearch, false)
	if err != nil {
		return errors.New("Error while trying to find the internet gateway!")
	}
	gatewayCount := len(*gatewayList)
	if gatewayCount < 1 {
		return errors.New("No Internet Gateways found matching [" + gatewaySearch + "]")
	} else if gatewayCount > 1 {
		gatewayList.PrintTable()
		return errors.New("Please limit your search term to just one Internet Gateway")
	}
	gateway := (*gatewayList)[0]
	terminal.Information("Found Internet Gateway [" + gateway.InternetGatewayID + "] named [" + gateway.Name + "] in [" + gateway.Region + "]!")
	if !terminal.PromptBool("Are you sure you want to delete this Internet Gateway?") {
		terminal.ErrorLine("Aborting!")
		return nil
	}
	deleteInternetGateway(gateway, dryRun)
	terminal.Information("Done!")
	return nil
}
func deleteInternetGateway(internetGateway InternetGateway, dryRun bool) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(internetGateway.Region)}))
	svc := ec2.New(sess)
	params := &ec2.DeleteInternetGatewayInput{
		InternetGatewayId: aws.String(internetGateway.InternetGatewayID),
		DryRun:            aws.Bool(dryRun),
	}
	_, err := svc.DeleteInternetGateway(params)
	if err != nil {
		return err
	}
	terminal.Delta("Deleted Internet Gateway [" + internetGateway.InternetGatewayID + "] named [" + internetGateway.Name + "]!")
	return nil
}
func DeleteRouteTable(routeTableSearch string, dryRun bool) error {
	if dryRun {
		terminal.Information("--dry-run flag is set, not making any actual changes!")
	}
	rtList, err := GetRouteTables(routeTableSearch)
	if err != nil {
		return errors.New("Error while trying to find the route table!")
	}
	rtCount := len(*rtList)
	if rtCount < 1 {
		return errors.New("No Route Tables found matching [" + routeTableSearch + "]")
	} else if rtCount > 1 {
		rtList.PrintTable()
		return errors.New("Please limit your search term to just one Route Table")
	}
	rt := (*rtList)[0]
	terminal.Information("Found Route Table [" + rt.RouteTableID + "] named [" + rt.Name + "] in [" + rt.Region + "]!")
	if !terminal.PromptBool("Are you sure you want to delete this Route Table?") {
		terminal.ErrorLine("Aborting!")
		return nil
	}
	deleteRouteTable(rt, dryRun)
	terminal.Information("Done!")
	return nil
}
func deleteRouteTable(rt RouteTable, dryRun bool) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(rt.Region)}))
	svc := ec2.New(sess)
	params := &ec2.DeleteRouteTableInput{
		RouteTableId: aws.String(rt.RouteTableID),
		DryRun:       aws.Bool(dryRun),
	}
	_, err := svc.DeleteRouteTable(params)
	if err != nil {
		return err
	}
	terminal.Delta("Deleted Route Table [" + rt.RouteTableID + "] named [" + rt.Name + "]!")
	return nil
}
func GetInternetGateways(search string, available bool) (*InternetGateways, []error) {
	var wg sync.WaitGroup
	var errs []error
	igList := new(InternetGateways)
	regions := GetRegionListWithoutIgnored()
	for _, region := range regions {
		wg.Add(1)
		go func(region *ec2.Region) {
			defer wg.Done()
			err := GetRegionInternetGateways(*region.RegionName, igList, search, available)
			if err != nil {
				terminal.ShowErrorMessage(fmt.Sprintf("Error gathering internet gateway list for region [%s]", *region.RegionName), err.Error())
				errs = append(errs, err)
			}
		}(region)
	}
	wg.Wait()
	return igList, errs
}
func GetRegionInternetGateways(region string, igList *InternetGateways, search string, available bool) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ec2.New(sess)
	result, err := svc.DescribeInternetGateways(&ec2.DescribeInternetGatewaysInput{})
	if err != nil {
		return err
	}
	igs := make(InternetGateways, len(result.InternetGateways))
	for i, ig := range result.InternetGateways {
		igs[i].Marshal(ig, region)
	}
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, v := range igs {
			rIg := reflect.ValueOf(v)
			for k := 0; k < rIg.NumField(); k++ {
				sVal := rIg.Field(k).String()
				if term.MatchString(sVal) && ((available && igs[i].State == "detached") || !available) {
					*igList = append(*igList, igs[i])
					continue Loop
				}
			}
		}
	} else {
		if available {
			for i, _ := range igs {
				if igs[i].State == "detached" {
					*igList = append(*igList, igs[i])
				}
			}
		} else {
			*igList = append(*igList, igs[:]...)
		}
	}
	return nil
}
func (i *InternetGateway) Marshal(ig *ec2.InternetGateway, region string) {
	i.Name = GetTagValue("Name", ig.Tags)
	i.InternetGatewayID = aws.StringValue(ig.InternetGatewayId)
	i.State = "detached"
	i.Region = region
	if len(ig.Attachments) > 0 {
		i.State = "attached"
		i.Attachment = aws.StringValue(ig.Attachments[0].VpcId)
	}
}
func GetVpcMainRouteTable(vpcId, region string) (RouteTable, error) {
	rtList, err := GetVpcRouteTables("", vpcId, region)
	if err != nil {
		return RouteTable{}, errors.New("Error while trying to find the route table!")
	}
	rtCount := len(*rtList)
	if rtCount < 1 {
		return RouteTable{}, errors.New("No Route Tables found!")
	}
	for _, rt := range *rtList {
		if rt.VpcID == vpcId {
			for _, assoc := range rt.Associations {
				if assoc.Main {
					return rt, nil
				}
			}
		}
	}
	return RouteTable{}, errors.New("Unable to locate the Main Route Table!")
}
func GetVpcRouteTables(search, vpcId, region string) (*RouteTables, error) {
	rtList := new(RouteTables)
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ec2.New(sess)
	result, err := svc.DescribeRouteTables(&ec2.DescribeRouteTablesInput{
		Filters: []*ec2.Filter{
			{
				Name: aws.String("vpc-id"),
				Values: []*string{
					aws.String(vpcId),
				},
			},
		},
	})
	if err != nil {
		return rtList, err
	}
	rts := make(RouteTables, len(result.RouteTables))
	for i, rt := range result.RouteTables {
		rts[i].Marshal(rt, region)
	}
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, v := range rts {
			rIg := reflect.ValueOf(v)
			for k := 0; k < rIg.NumField(); k++ {
				sVal := rIg.Field(k).String()
				if term.MatchString(sVal) {
					*rtList = append(*rtList, rts[i])
					continue Loop
				}
			}
		}
	} else {
		*rtList = append(*rtList, rts[:]...)
	}
	return rtList, nil
}
func GetRouteTables(search string) (*RouteTables, []error) {
	var wg sync.WaitGroup
	var errs []error
	rtList := new(RouteTables)
	regions := GetRegionListWithoutIgnored()
	for _, region := range regions {
		wg.Add(1)
		go func(region *ec2.Region) {
			defer wg.Done()
			err := GetRegionRouteTables(*region.RegionName, rtList, search)
			if err != nil {
				terminal.ShowErrorMessage(fmt.Sprintf("Error gathering route tables list for region [%s]", *region.RegionName), err.Error())
				errs = append(errs, err)
			}
		}(region)
	}
	wg.Wait()
	return rtList, errs
}
func GetRegionRouteTables(region string, rtList *RouteTables, search string) error {
	sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(region)}))
	svc := ec2.New(sess)
	result, err := svc.DescribeRouteTables(&ec2.DescribeRouteTablesInput{})
	if err != nil {
		return err
	}
	rts := make(RouteTables, len(result.RouteTables))
	for i, rt := range result.RouteTables {
		rts[i].Marshal(rt, region)
	}
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, v := range rts {
			rIg := reflect.ValueOf(v)
			for k := 0; k < rIg.NumField(); k++ {
				sVal := rIg.Field(k).String()
				if term.MatchString(sVal) {
					*rtList = append(*rtList, rts[i])
					continue Loop
				}
			}
		}
	} else {
		*rtList = append(*rtList, rts[:]...)
	}
	return nil
}
func (r *RouteTable) Marshal(rt *ec2.RouteTable, region string) {
	r.Name = GetTagValue("Name", rt.Tags)
	r.RouteTableID = aws.StringValue(rt.RouteTableId)
	r.VpcID = aws.StringValue(rt.VpcId)
	r.Region = region
	for _, association := range rt.Associations {
		r.Associations = append(r.Associations, models.RouteTableAssociation{
			Main:          aws.BoolValue(association.Main),
			AssociationID: aws.StringValue(association.RouteTableAssociationId),
			SubnetID:      aws.StringValue(association.SubnetId),
		})
	}
}
func (v *Vpc) Marshal(vpc *ec2.Vpc, region string) {
	v.Name = GetTagValue("Name", vpc.Tags)
	v.Class = GetTagValue("Class", vpc.Tags)
	v.VpcID = aws.StringValue(vpc.VpcId)
	v.State = aws.StringValue(vpc.State)
	v.Default = aws.BoolValue(vpc.IsDefault)
	v.CIDRBlock = aws.StringValue(vpc.CidrBlock)
	v.DHCPOptID = aws.StringValue(vpc.DhcpOptionsId)
	v.Tenancy = aws.StringValue(vpc.InstanceTenancy)
	v.Region = region
}