Skip to content

Commit

Permalink
Fix subnet ordering assumption
Browse files Browse the repository at this point in the history
- pass full provider to stack manager and cluster stack builder
  • Loading branch information
errordeveloper committed Nov 9, 2018
1 parent d6b1943 commit 5a8e339
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 97 deletions.
185 changes: 120 additions & 65 deletions pkg/cfn/builder/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@ package builder_test
import (
"encoding/base64"
"encoding/json"
"fmt"
"net"
"path/filepath"
"strings"

cfn "github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/stretchr/testify/mock"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/weaveworks/eksctl/pkg/cfn/builder"
"github.com/weaveworks/eksctl/pkg/cloudconfig"
"github.com/weaveworks/eksctl/pkg/eks/api"
"github.com/weaveworks/eksctl/pkg/nodebootstrap"
"github.com/weaveworks/eksctl/pkg/testutils"
"github.com/weaveworks/eksctl/pkg/vpc"
)

Expand All @@ -24,6 +28,10 @@ const (
endpoint = "https://DE37D8AFB23F7275D2361AD6B2599143.yl4.us-west-2.eks.amazonaws.com"
caCert = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNE1EWXdOekExTlRBMU5Wb1hEVEk0TURZd05EQTFOVEExTlZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTWJoCnpvZElYR0drckNSZE1jUmVEN0YvMnB1NFZweTdvd3FEVDgrdk9zeGs2bXFMNWxQd3ZicFhmYkE3R0xzMDVHa0wKaDdqL0ZjcU91cnMwUFZSK3N5REtuQXltdDFORWxGNllGQktSV1dUQ1hNd2lwN1pweW9XMXdoYTlJYUlPUGxCTQpPTEVlckRabFVrVDFVV0dWeVdsMmxPeFgxa2JhV2gvakptWWdkeW5jMXhZZ3kxa2JybmVMSkkwLzVUVTRCajJxClB1emtrYW5Xd3lKbGdXQzhBSXlpWW82WFh2UVZmRzYrM3RISE5XM1F1b3ZoRng2MTFOYnl6RUI3QTdtZGNiNmgKR0ZpWjdOeThHZnFzdjJJSmI2Nk9FVzBSdW9oY1k3UDZPdnZmYnlKREhaU2hqTStRWFkxQXN5b3g4Ri9UelhHSgpQUWpoWUZWWEVhZU1wQmJqNmNFQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFCa2hKRVd4MHk1LzlMSklWdXJ1c1hZbjN6Z2EKRkZ6V0JsQU44WTlqUHB3S2t0Vy9JNFYyUGg3bWY2Z3ZwZ3Jhc2t1Slk1aHZPcDdBQmcxSTFhaHUxNUFpMUI0ZApuMllRaDlOaHdXM2pKMmhuRXk0VElpb0gza2JFdHRnUVB2bWhUQzNEYUJreEpkbmZJSEJCV1RFTTU1czRwRmxUClpzQVJ3aDc1Q3hYbjdScVU0akpKcWNPaTRjeU5qeFVpRDBqR1FaTmNiZWEyMkRCeTJXaEEzUWZnbGNScGtDVGUKRDVPS3NOWlF4MW9MZFAwci9TSmtPT1NPeUdnbVJURTIrODQxN21PRW02Z3RPMCszdWJkbXQ0aENsWEtFTTZYdwpuQWNlK0JxVUNYblVIN2ZNS3p2TDE5UExvMm5KbFU1TnlCbU1nL1pNVHVlUy80eFZmKy94WnpsQ0Q1WT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
arn = "arn:aws:eks:us-west-2:376248598259:cluster/" + clusterName

vpcID = "vpc-0e265ad953062b94b"
subnetsPublic = "subnet-0f98135715dfcf55f,subnet-0ade11bad78dced9e,subnet-0e2e63ff1712bf6ef"
subnetsPrivate = "subnet-0f98135715dfcf55a,subnet-0ade11bad78dced9f,subnet-0e2e63ff1712bf6ea"
)

type Template struct {
Expand Down Expand Up @@ -83,6 +91,72 @@ users:
`
}

func testVPC() *api.ClusterVPC {
return &api.ClusterVPC{
Network: api.Network{
ID: vpcID,
CIDR: &net.IPNet{
IP: []byte{192, 168, 0, 0},
Mask: []byte{255, 255, 0, 0},
},
},
SecurityGroup: "sg-0b44c48bcba5b7362",
Subnets: map[api.SubnetTopology]map[string]api.Network{
"Public": map[string]api.Network{
"us-west-2b": {
ID: "subnet-0f98135715dfcf55f",
CIDR: &net.IPNet{
IP: []byte{192, 168, 0, 0},
Mask: []byte{255, 255, 224, 0},
},
},
"us-west-2a": {
ID: "subnet-0ade11bad78dced9e",
CIDR: &net.IPNet{
IP: []byte{192, 168, 32, 0},
Mask: []byte{255, 255, 224, 0},
},
},
"us-west-2c": {
ID: "subnet-0e2e63ff1712bf6ef",
CIDR: &net.IPNet{
IP: []byte{192, 168, 64, 0},
Mask: []byte{255, 255, 224, 0},
},
},
},
"Private": map[string]api.Network{
"us-west-2b": {
ID: "subnet-0f98135715dfcf55a",
CIDR: &net.IPNet{
IP: []byte{192, 168, 96, 0},
Mask: []byte{255, 255, 224, 0},
},
},
"us-west-2a": {
ID: "subnet-0ade11bad78dced9f",
CIDR: &net.IPNet{
IP: []byte{192, 168, 128, 0},
Mask: []byte{255, 255, 224, 0},
},
},
"us-west-2c": {
ID: "subnet-0e2e63ff1712bf6ea",
CIDR: &net.IPNet{
IP: []byte{192, 168, 160, 0},
Mask: []byte{255, 255, 224, 0},
},
},
},
},
}
}

var subnetLists = map[api.SubnetTopology]string{
"Public": subnetsPublic,
"Private": subnetsPrivate,
}

func newStackWithOutputs(outputs map[string]string) cfn.Stack {
s := cfn.Stack{}
for k, v := range outputs {
Expand Down Expand Up @@ -116,6 +190,46 @@ var _ = Describe("CloudFormation template builder API", func() {
return cfg
}

p := testutils.NewMockProvider()

{
joinCompare := func(input *ec2.DescribeSubnetsInput, compare string) bool {
ids := make([]string, len(input.SubnetIds))
for x, id := range input.SubnetIds {
ids[x] = *id
}
return strings.Join(ids, ",") == compare
}
testVPC := testVPC()
for t := range subnetLists {
func(list string, subnetsByAz map[string]api.Network) {
subnets := strings.Split(list, ",")

output := &ec2.DescribeSubnetsOutput{
Subnets: make([]*ec2.Subnet, len(subnets)),
}

for i := range subnets {
subnet := &ec2.Subnet{}
subnet.SetSubnetId(subnets[i])
subnet.SetVpcId(vpcID)
for az := range subnetsByAz {
if subnetsByAz[az].ID == subnets[i] {
subnet.SetAvailabilityZone(az)
subnet.SetCidrBlock(subnetsByAz[az].CIDR.String())
}
}
output.Subnets[i] = subnet

}
p.MockEC2().On("DescribeSubnets", mock.MatchedBy(func(input *ec2.DescribeSubnetsInput) bool {
fmt.Fprintf(GinkgoWriter, "%s subnets = %#v\n", t, output)
return joinCompare(input, list)
})).Return(output, nil)
}(subnetLists[t], testVPC.Subnets[t])
}
}

Describe("GetAllOutputsFromClusterStack", func() {
caCertData, err := base64.StdEncoding.DecodeString(caCert)
It("should not error", func() { Expect(err).ShouldNot(HaveOccurred()) })
Expand All @@ -129,65 +243,7 @@ var _ = Describe("CloudFormation template builder API", func() {
CertificateAuthorityData: caCertData,
ARN: arn,
AvailabilityZones: testAZs,

VPC: &api.ClusterVPC{
Network: api.Network{
ID: "vpc-0e265ad953062b94b",
CIDR: &net.IPNet{
IP: []byte{192, 168, 0, 0},
Mask: []byte{255, 255, 0, 0},
},
},
SecurityGroup: "sg-0b44c48bcba5b7362",
Subnets: map[api.SubnetTopology]map[string]api.Network{
"Public": map[string]api.Network{
"us-west-2b": {
ID: "subnet-0f98135715dfcf55f",
CIDR: &net.IPNet{
IP: []byte{192, 168, 0, 0},
Mask: []byte{255, 255, 224, 0},
},
},
"us-west-2a": {
ID: "subnet-0ade11bad78dced9e",
CIDR: &net.IPNet{
IP: []byte{192, 168, 32, 0},
Mask: []byte{255, 255, 224, 0},
},
},
"us-west-2c": {
ID: "subnet-0e2e63ff1712bf6ef",
CIDR: &net.IPNet{
IP: []byte{192, 168, 64, 0},
Mask: []byte{255, 255, 224, 0},
},
},
},
"Private": map[string]api.Network{
"us-west-2b": {
ID: "subnet-0f98135715dfcf55a",
CIDR: &net.IPNet{
IP: []byte{192, 168, 96, 0},
Mask: []byte{255, 255, 224, 0},
},
},
"us-west-2a": {
ID: "subnet-0ade11bad78dced9f",
CIDR: &net.IPNet{
IP: []byte{192, 168, 128, 0},
Mask: []byte{255, 255, 224, 0},
},
},
"us-west-2c": {
ID: "subnet-0e2e63ff1712bf6ea",
CIDR: &net.IPNet{
IP: []byte{192, 168, 160, 0},
Mask: []byte{255, 255, 224, 0},
},
},
},
},
},
VPC: testVPC(),
NodeGroups: []*api.NodeGroup{
{
AMI: "",
Expand All @@ -199,7 +255,6 @@ var _ = Describe("CloudFormation template builder API", func() {
}

cfg := newClusterConfig()
//ctl := eks.New(testutils.ProviderConfig, cfg)

It("should not error when calling SetSubnets", func() {
err := vpc.SetSubnets(cfg)
Expand All @@ -214,17 +269,17 @@ var _ = Describe("CloudFormation template builder API", func() {
}
})

rs := NewClusterResourceSet(cfg)
rs := NewClusterResourceSet(p, cfg)
It("should add all resources without error", func() {
err := rs.AddAllResources()
Expect(err).ShouldNot(HaveOccurred())
})

sampleOutputs := map[string]string{
"SecurityGroup": "sg-0b44c48bcba5b7362",
"SubnetsPublic": "subnet-0f98135715dfcf55f,subnet-0ade11bad78dced9e,subnet-0e2e63ff1712bf6ef",
"SubnetsPrivate": "subnet-0f98135715dfcf55a,subnet-0ade11bad78dced9f,subnet-0e2e63ff1712bf6ea",
"VPC": "vpc-0e265ad953062b94b",
"SubnetsPublic": subnetsPublic,
"SubnetsPrivate": subnetsPrivate,
"VPC": vpcID,
"Endpoint": endpoint,
"CertificateAuthorityData": caCert,
"ARN": arn,
Expand Down Expand Up @@ -470,7 +525,7 @@ var _ = Describe("CloudFormation template builder API", func() {
cfg.AvailabilityZones = testAZs
cfg.VPC = &api.ClusterVPC{
Network: api.Network{
ID: "vpc-0e265ad953062b94b",
ID: vpcID,
},
SecurityGroup: "sg-0b44c48bcba5b7362",
Subnets: map[api.SubnetTopology]map[string]api.Network{
Expand Down
20 changes: 11 additions & 9 deletions pkg/cfn/builder/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,27 @@ import (
gfn "github.com/awslabs/goformation/cloudformation"

"github.com/weaveworks/eksctl/pkg/eks/api"
"github.com/weaveworks/eksctl/pkg/vpc"
)

// ClusterResourceSet stores the resource information of the cluster
type ClusterResourceSet struct {
rs *resourceSet
spec *api.ClusterConfig
provider api.ClusterProvider
vpc *gfn.Value
subnets map[api.SubnetTopology][]*gfn.Value
securityGroups []*gfn.Value
outputs *ClusterStackOutputs
}

// NewClusterResourceSet returns a resource set for the new cluster
func NewClusterResourceSet(spec *api.ClusterConfig) *ClusterResourceSet {
func NewClusterResourceSet(provider api.ClusterProvider, spec *api.ClusterConfig) *ClusterResourceSet {
return &ClusterResourceSet{
rs: newResourceSet(),
spec: spec,
outputs: &ClusterStackOutputs{},
rs: newResourceSet(),
spec: spec,
provider: provider,
outputs: &ClusterStackOutputs{},
}
}

Expand Down Expand Up @@ -99,13 +102,12 @@ func (c *ClusterResourceSet) GetAllOutputs(stack cfn.Stack) error {
c.spec.VPC.ID = c.outputs.VPC
c.spec.VPC.SecurityGroup = c.outputs.SecurityGroup

// TODO: shouldn't assume the order - https://github.com/weaveworks/eksctl/issues/293
for i, subnet := range c.outputs.SubnetsPrivate {
c.spec.ImportSubnet(api.SubnetTopologyPrivate, c.spec.AvailabilityZones[i], subnet, "")
if err := vpc.UseSubnets(c.provider, c.spec, api.SubnetTopologyPrivate, c.outputs.SubnetsPrivate); err != nil {
return err
}

for i, subnet := range c.outputs.SubnetsPublic {
c.spec.ImportSubnet(api.SubnetTopologyPublic, c.spec.AvailabilityZones[i], subnet, "")
if err := vpc.UseSubnets(c.provider, c.spec, api.SubnetTopologyPublic, c.outputs.SubnetsPublic); err != nil {
return err
}

c.spec.ClusterStackName = c.outputs.ClusterStackName
Expand Down
Loading

0 comments on commit 5a8e339

Please sign in to comment.