Skip to content

Commit

Permalink
Merge pull request #1047 from convox/20160812
Browse files Browse the repository at this point in the history
[RELEASE] 20160812
  • Loading branch information
ddollar authored Aug 13, 2016
2 parents a1b7738 + 95b9c54 commit 8ef2ae7
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 81 deletions.
3 changes: 3 additions & 0 deletions REGIONS
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
ap-northeast-1
ap-southeast-1
ap-southeast-2
eu-central-1
eu-west-1
us-east-1
us-west-2
2 changes: 1 addition & 1 deletion api/cmd/formation/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ formation.zip: lambda.js formation

release: formation.zip
for region in $(shell cat ../../../REGIONS); do \
aws s3 cp formation.zip s3://convox-$$region/release/$(VERSION)/formation.zip --acl public-read; \
aws s3 cp formation.zip s3://convox-$$region/release/$(VERSION)/formation.zip --acl public-read --region $$region; \
done
94 changes: 62 additions & 32 deletions api/dist/kernel.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
"Autoscale": { "Fn::Equals": [ { "Ref": "Autoscale" }, "Yes" ] },
"BlankAmi": { "Fn::Equals": [ { "Ref": "Ami" }, "" ] },
"BlankExistingVpc": { "Fn::Equals": [ { "Ref": "ExistingVpc" }, "" ] },
"BlankExistingVpcAndThirdAvailabilityZone": {
"Fn::And": [ { "Condition": "BlankExistingVpc" }, { "Condition": "ThirdAvailabilityZone" } ]
},
"BlankInstanceBootCommand": { "Fn::Equals": [ { "Ref": "InstanceBootCommand" }, "" ] },
"BlankInstanceRunCommand": { "Fn::Equals": [ { "Ref": "InstanceRunCommand" }, "" ] },
"BlankKey": { "Fn::Equals": [ { "Ref": "Key" }, "" ] },
"Development": { "Fn::Equals": [ { "Ref": "Development" }, "Yes" ] },
"ExistingVpc": { "Fn::Not": [ { "Fn::Equals": [ { "Ref": "ExistingVpc" }, "" ] } ] },
"Private": { "Fn::Equals": [ { "Ref": "Private" }, "Yes" ] },
"PrivateAndThirdAvailabilityZone": {
"Fn::And": [ { "Condition": "Private" }, { "Condition": "ThirdAvailabilityZone" } ]
},
"PrivateApi": { "Fn::Equals": [ { "Ref": "PrivateApi" }, "Yes" ] },
"RegionHasECR": {
"Fn::Or": [
Expand All @@ -24,18 +30,25 @@
{ "Fn::Equals": [ { "Ref": "AWS::Region" }, "us-west-2" ]},
{ "Fn::Equals": [ { "Ref": "AWS::Region" }, "eu-west-1" ]}
]
}
},
"RegionHasEFSAndThirdAvailabilityZone": {
"Fn::And": [ { "Condition": "RegionHasEFS" }, { "Condition": "ThirdAvailabilityZone" } ]
},
"ThirdAvailabilityZone": { "Fn::Equals": [
{ "Fn::FindInMap": [ "RegionConfig", { "Ref": "AWS::Region" }, "ThirdAvailabilityZone" ] },
"Yes"
] }
},
"Mappings": {
"RegionConfig": {
"us-east-1": { "Ami": "ami-c17ce0d6" },
"us-west-1": { "Ami": "ami-b74b08d7" },
"us-west-2": { "Ami": "ami-f3468e93" },
"eu-west-1": { "Ami": "ami-12ea8261" },
"eu-central-1": { "Ami": "ami-3bf10754" },
"ap-northeast-1": { "Ami": "ami-ed26e78c" },
"ap-southeast-1": { "Ami": "ami-032af460" },
"ap-southeast-2": { "Ami": "ami-a1281cc2" }
"us-east-1": { "Ami": "ami-8f7687e2", "ThirdAvailabilityZone": "Yes" },
"us-west-1": { "Ami": "ami-bb473cdb", "ThirdAvailabilityZone": "Yes" },
"us-west-2": { "Ami": "ami-84b44de4", "ThirdAvailabilityZone": "Yes" },
"eu-west-1": { "Ami": "ami-4e6ffe3d", "ThirdAvailabilityZone": "Yes" },
"eu-central-1": { "Ami": "ami-b0cc23df", "ThirdAvailabilityZone": "No" },
"ap-northeast-1": { "Ami": "ami-095dbf68", "ThirdAvailabilityZone": "No" },
"ap-southeast-1": { "Ami": "ami-cf03d2ac", "ThirdAvailabilityZone": "No" },
"ap-southeast-2": { "Ami": "ami-697a540a", "ThirdAvailabilityZone": "Yes" }
}
},
"Outputs": {
Expand Down Expand Up @@ -129,7 +142,7 @@
[
{ "Ref": "Subnet0" },
{ "Ref": "Subnet1" },
{ "Ref": "Subnet2" }
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "Subnet2" }, { "Ref": "AWS::NoValue" } ] }
]
]
}
Expand Down Expand Up @@ -575,7 +588,7 @@
}
},
"Nat2": {
"Condition": "Private",
"Condition": "PrivateAndThirdAvailabilityZone",
"Type": "AWS::EC2::NatGateway",
"Properties": {
"AllocationId": { "Fn::GetAtt": [ "NatAddress2", "AllocationId" ] },
Expand Down Expand Up @@ -634,6 +647,7 @@
}
},
"Subnet2": {
"Condition": "ThirdAvailabilityZone",
"DependsOn": [ "AvailabilityZones" ],
"Type": "AWS::EC2::Subnet",
"Properties": {
Expand Down Expand Up @@ -681,7 +695,7 @@
}
},
"SubnetPrivate2": {
"Condition": "Private",
"Condition": "PrivateAndThirdAvailabilityZone",
"DependsOn": [ "AvailabilityZones" ],
"Type": "AWS::EC2::Subnet",
"Properties": {
Expand Down Expand Up @@ -737,7 +751,7 @@
}
},
"RouteTablePrivate2": {
"Condition": "Private",
"Condition": "PrivateAndThirdAvailabilityZone",
"DependsOn": [ "Nat2" ],
"Type": "AWS::EC2::RouteTable",
"Properties": {
Expand Down Expand Up @@ -768,7 +782,7 @@
}
},
"RouteDefaultPrivate2": {
"Condition": "Private",
"Condition": "PrivateAndThirdAvailabilityZone",
"DependsOn": [ "Nat2", "RouteTablePrivate2" ],
"Type": "AWS::EC2::Route",
"Properties": {
Expand All @@ -778,27 +792,27 @@
}
},
"Subnet0Routes": {
"Condition": "BlankExistingVpc",
"DependsOn": [ "Subnet0", "Routes" ],
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Condition": "BlankExistingVpc",
"Properties": {
"SubnetId": { "Ref": "Subnet0" },
"RouteTableId": { "Ref": "Routes" }
}
},
"Subnet1Routes": {
"Condition": "BlankExistingVpc",
"DependsOn": [ "Subnet1", "Routes" ],
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Condition": "BlankExistingVpc",
"Properties": {
"SubnetId": { "Ref": "Subnet1" },
"RouteTableId": { "Ref": "Routes" }
}
},
"Subnet2Routes": {
"Condition": "BlankExistingVpcAndThirdAvailabilityZone",
"DependsOn": [ "Subnet2", "Routes" ],
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Condition": "BlankExistingVpc",
"Properties": {
"SubnetId": { "Ref": "Subnet2" },
"RouteTableId": { "Ref": "Routes" }
Expand All @@ -823,7 +837,7 @@
}
},
"SubnetPrivate2Routes": {
"Condition": "Private",
"Condition": "PrivateAndThirdAvailabilityZone",
"DependsOn": [ "SubnetPrivate2", "RouteTablePrivate2" ],
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
Expand Down Expand Up @@ -995,32 +1009,32 @@
}
},
"Instances": {
"DependsOn": [ "AvailabilityZones", "Subnet0", "Subnet1", "Subnet2" ],
"DependsOn": [ "AvailabilityZones", "Subnet0", "Subnet1" ],
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties" : {
"LaunchConfigurationName" : { "Ref": "LaunchConfiguration" },
"AvailabilityZones": [
{ "Fn::GetAtt": [ "AvailabilityZones", "AvailabilityZone0" ] },
{ "Fn::GetAtt": [ "AvailabilityZones", "AvailabilityZone1" ] },
{ "Fn::GetAtt": [ "AvailabilityZones", "AvailabilityZone2" ] }
{ "Fn::If": [ "ThirdAvailabilityZone", { "Fn::GetAtt": [ "AvailabilityZones", "AvailabilityZone2" ] }, { "Ref": "AWS::NoValue" } ] }
],
"VPCZoneIdentifier": {
"Fn::If": [ "Private", [
{ "Ref": "SubnetPrivate0" },
{ "Ref": "SubnetPrivate1" },
{ "Ref": "SubnetPrivate2" }
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "SubnetPrivate2" }, { "Ref": "AWS::NoValue" } ] }
], [
{ "Ref": "Subnet0" },
{ "Ref": "Subnet1" },
{ "Ref": "Subnet2" }
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "Subnet2" }, { "Ref": "AWS::NoValue" } ] }
] ]
},
"Cooldown": 5,
"DesiredCapacity": { "Ref": "InstanceCount" },
"HealthCheckType": "EC2",
"HealthCheckGracePeriod": "120",
"MinSize" : "1",
"MaxSize" : "100",
"MaxSize" : "1000",
"MetricsCollection": [ { "Granularity": "1Minute" } ],
"Tags": [
{
Expand Down Expand Up @@ -1296,11 +1310,11 @@
"Fn::If": [ "PrivateApi", [
{ "Ref": "SubnetPrivate0" },
{ "Ref": "SubnetPrivate1" },
{ "Ref": "SubnetPrivate2" }
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "SubnetPrivate2" }, { "Ref": "AWS::NoValue" } ] }
], [
{ "Ref": "Subnet0" },
{ "Ref": "Subnet1" },
{ "Ref": "Subnet2" }
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "Subnet2" }, { "Ref": "AWS::NoValue" } ] }
] ]
},
"Tags": [
Expand Down Expand Up @@ -1545,7 +1559,7 @@
},
"VolumeTarget2": {
"Type": "AWS::EFS::MountTarget",
"Condition": "RegionHasEFS",
"Condition": "RegionHasEFSAndThirdAvailabilityZone",
"DependsOn": "Subnet2",
"Properties": {
"FileSystemId": { "Ref": "VolumeFilesystem" },
Expand Down Expand Up @@ -1579,7 +1593,7 @@
"Type": "AWS::S3::Bucket"
},
"ApiWebTasks": {
"DependsOn": [ "Balancer", "Cluster", "CustomTopic", "DynamoBuilds", "DynamoReleases", "KernelAccess", "LogGroup", "RegistryAccess", "RegistryBucket", "Subnet0", "Subnet1", "Subnet2" ],
"DependsOn": [ "Balancer", "Cluster", "CustomTopic", "DynamoBuilds", "DynamoReleases", "KernelAccess", "LogGroup", "RegistryAccess", "RegistryBucket", "Subnet0", "Subnet1" ],
"Properties": {
"Name": { "Fn::Join": [ "-", [ { "Ref": "AWS::StackName" }, "web" ] ] },
"ServiceToken": { "Fn::GetAtt": [ "CustomTopic", "Arn" ] },
Expand Down Expand Up @@ -1614,10 +1628,18 @@
"SETTINGS_BUCKET": { "Ref": "Settings" },
"STACK_ID": { "Ref": "AWS::StackId" },
"SUBNETS": {
"Fn::Join": [ ",", [ { "Ref": "Subnet0" }, { "Ref": "Subnet1" }, { "Ref": "Subnet2" } ] ]
"Fn::Join": [ ",", [
{ "Ref": "Subnet0" },
{ "Ref": "Subnet1" },
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "Subnet2" }, { "Ref": "AWS::NoValue" } ] }
] ]
},
"SUBNETS_PRIVATE": { "Fn::If": [ "Private",
{ "Fn::Join": [ ",", [ { "Ref": "SubnetPrivate0" }, { "Ref": "SubnetPrivate1" }, { "Ref": "SubnetPrivate2" } ] ] },
{ "Fn::Join": [ ",", [
{ "Ref": "SubnetPrivate0" },
{ "Ref": "SubnetPrivate1" },
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "SubnetPrivate2" }, { "Ref": "AWS::NoValue" } ] }
] ] },
""
] },
"VPC": { "Fn::If": [ "BlankExistingVpc",
Expand Down Expand Up @@ -1670,7 +1692,7 @@
"Version": "1.0"
},
"ApiMonitorTasks": {
"DependsOn": [ "Balancer", "Cluster", "CustomTopic", "DynamoBuilds", "DynamoReleases", "KernelAccess", "LogGroup", "Subnet0", "Subnet1", "Subnet2" ],
"DependsOn": [ "Balancer", "Cluster", "CustomTopic", "DynamoBuilds", "DynamoReleases", "KernelAccess", "LogGroup", "Subnet0", "Subnet1" ],
"Properties": {
"Name": { "Fn::Join": [ "-", [ { "Ref": "AWS::StackName" }, "monitor" ] ] },
"ServiceToken": { "Fn::GetAtt": [ "CustomTopic", "Arn" ] },
Expand Down Expand Up @@ -1704,10 +1726,18 @@
"SEGMENT_WRITE_KEY": "KLvwCXo6qcTmQHLpF69DEwGf9zh7lt9i",
"STACK_ID": { "Ref": "AWS::StackId" },
"SUBNETS": {
"Fn::Join": [ ",", [ { "Ref": "Subnet0" }, { "Ref": "Subnet1" }, { "Ref": "Subnet2" } ] ]
"Fn::Join": [ ",", [
{ "Ref": "Subnet0" },
{ "Ref": "Subnet1" },
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "Subnet2" }, { "Ref": "AWS::NoValue" } ] }
] ]
},
"SUBNETS_PRIVATE": { "Fn::If": [ "Private",
{ "Fn::Join": [ ",", [ { "Ref": "SubnetPrivate0" }, { "Ref": "SubnetPrivate1" }, { "Ref": "SubnetPrivate2" } ] ] },
{ "Fn::Join": [ ",", [
{ "Ref": "SubnetPrivate0" },
{ "Ref": "SubnetPrivate1" },
{ "Fn::If": [ "ThirdAvailabilityZone", { "Ref": "SubnetPrivate2" }, { "Ref": "AWS::NoValue" } ] }
] ] },
""
] },
"VPC": { "Fn::If": [ "BlankExistingVpc",
Expand Down
2 changes: 1 addition & 1 deletion cmd/convox/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ release:
equinox release --config=.equinox.yaml --version=$(shell convox/convox --version | cut -d' ' -f3) .

templates:
go-bindata -nometadata -pkg=templates -prefix=templates/ -o=templates/templates.go templates/...
go-bindata -pkg=templates -prefix=templates/ -o=templates/templates.go -ignore=templates.go templates/...

test:
go get -t ./...
Expand Down
2 changes: 1 addition & 1 deletion cmd/convox/apps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestApps(t *testing.T) {
test.ExecRun{
Command: "convox apps",
Exit: 0,
Stdout: "APP STATUS \nsinatra running\n",
Stdout: "APP STATUS\nsinatra running\n",
},
)
}
Expand Down
22 changes: 16 additions & 6 deletions cmd/convox/stdcli/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,36 @@ package stdcli

import (
"fmt"
"io"
"os"
"strings"
"unicode"
)

type Table struct {
Headers []string
Rows [][]string

Output io.Writer
}

func NewTable(headers ...string) *Table {
return &Table{Headers: headers}
return &Table{Headers: headers, Output: os.Stdout}
}

func (t *Table) AddRow(values ...string) {
t.Rows = append(t.Rows, values)
}

func (t *Table) Print() {
fs := t.FormatString()

fmt.Printf(fs, interfaceSlice(t.Headers)...)
t.printValues(t.Headers)

for _, row := range t.Rows {
fmt.Printf(fs, interfaceSlice(row)...)
t.printValues(row)
}
}

func (t *Table) FormatString() string {
func (t *Table) formatString() string {
longest := make([]int, len(t.Headers))

for i, header := range t.Headers {
Expand All @@ -52,6 +55,13 @@ func (t *Table) FormatString() string {
return strings.Join(parts, " ") + "\n"
}

func (t *Table) printValues(values []string) {
line := fmt.Sprintf(t.formatString(), interfaceSlice(values)...)
line = strings.TrimRightFunc(line, unicode.IsSpace) + "\n"

fmt.Fprintf(t.Output, line)
}

func interfaceSlice(ss []string) []interface{} {
is := make([]interface{}, len(ss))

Expand Down
29 changes: 29 additions & 0 deletions cmd/convox/stdcli/table_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package stdcli_test

import (
"bytes"
"strings"
"testing"

"github.com/convox/rack/cmd/convox/stdcli"
"github.com/stretchr/testify/assert"
)

func TestTableOutput(t *testing.T) {
buf := &bytes.Buffer{}

tb := stdcli.NewTable("FOO", "BAR")
tb.Output = buf

tb.AddRow("foo bar", "foo bar baz qux")
tb.AddRow("bar foo baz", "foo")
tb.Print()

lines := strings.Split(buf.String(), "\n")

assert.Equal(t, 4, len(lines))
assert.Equal(t, "FOO BAR", lines[0])
assert.Equal(t, "foo bar foo bar baz qux", lines[1])
assert.Equal(t, "bar foo baz foo", lines[2])
assert.Equal(t, "", lines[3])
}
Loading

0 comments on commit 8ef2ae7

Please sign in to comment.