mirror of https://github.com/kubernetes/kops.git
188 lines
4.8 KiB
Go
188 lines
4.8 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"k8s.io/kops/pkg/apis/kops"
|
|
"k8s.io/kops/upup/pkg/fi"
|
|
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
|
|
"k8s.io/kubernetes/pkg/util/sets"
|
|
)
|
|
|
|
// NetworkModelBuilder configures network objects
|
|
type NetworkModelBuilder struct {
|
|
*KopsModelContext
|
|
}
|
|
|
|
var _ fi.ModelBuilder = &NetworkModelBuilder{}
|
|
|
|
func (b *NetworkModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|
sharedVPC := b.Cluster.SharedVPC()
|
|
|
|
// VPC that holds everything for the cluster
|
|
{
|
|
t := &awstasks.VPC{
|
|
Name: s(b.ClusterName()),
|
|
EnableDNSHostnames: fi.Bool(true),
|
|
EnableDNSSupport: fi.Bool(true),
|
|
Shared: fi.Bool(sharedVPC),
|
|
}
|
|
|
|
if b.Cluster.Spec.NetworkID != "" {
|
|
t.ID = s(b.Cluster.Spec.NetworkID)
|
|
}
|
|
if b.Cluster.Spec.NetworkCIDR != "" {
|
|
t.CIDR = s(b.Cluster.Spec.NetworkCIDR)
|
|
}
|
|
c.AddTask(t)
|
|
}
|
|
|
|
if !sharedVPC {
|
|
dhcp := &awstasks.DHCPOptions{
|
|
Name: s(b.ClusterName()),
|
|
DomainNameServers: s("AmazonProvidedDNS"),
|
|
}
|
|
if b.Region == "us-east-1" {
|
|
dhcp.DomainName = s("ec2.internal")
|
|
} else {
|
|
dhcp.DomainName = s(b.Region + ".compute.internal")
|
|
}
|
|
c.AddTask(dhcp)
|
|
|
|
c.AddTask(&awstasks.VPCDHCPOptionsAssociation{
|
|
Name: s(b.ClusterName()),
|
|
|
|
VPC: b.LinkToVPC(),
|
|
DHCPOptions: dhcp,
|
|
})
|
|
} else {
|
|
// TODO: would be good to create these as shared, to verify them
|
|
}
|
|
|
|
// We always have a public route table, though for private networks it is only used for NGWs and ELBs
|
|
var publicRouteTable *awstasks.RouteTable
|
|
//if b.Cluster.IsTopologyPublic()
|
|
{
|
|
// The internet gateway is the main entry point to the cluster.
|
|
igw := &awstasks.InternetGateway{
|
|
Name: s(b.ClusterName()),
|
|
VPC: b.LinkToVPC(),
|
|
Shared: fi.Bool(sharedVPC),
|
|
}
|
|
c.AddTask(igw)
|
|
|
|
publicRouteTable = &awstasks.RouteTable{
|
|
Name: s(b.ClusterName()),
|
|
VPC: b.LinkToVPC(),
|
|
}
|
|
c.AddTask(publicRouteTable)
|
|
|
|
c.AddTask(&awstasks.Route{
|
|
Name: s("0.0.0.0/0"),
|
|
CIDR: s("0.0.0.0/0"),
|
|
RouteTable: publicRouteTable,
|
|
InternetGateway: igw,
|
|
})
|
|
}
|
|
|
|
privateZones := sets.NewString()
|
|
|
|
for i := range b.Cluster.Spec.Subnets {
|
|
subnetSpec := &b.Cluster.Spec.Subnets[i]
|
|
sharedSubnet := subnetSpec.ProviderID != ""
|
|
|
|
subnet := &awstasks.Subnet{
|
|
Name: s(subnetSpec.SubnetName + "." + b.ClusterName()),
|
|
VPC: b.LinkToVPC(),
|
|
AvailabilityZone: s(subnetSpec.Zone),
|
|
CIDR: s(subnetSpec.CIDR),
|
|
Shared: fi.Bool(sharedSubnet),
|
|
}
|
|
if subnetSpec.ProviderID != "" {
|
|
subnet.ID = s(subnetSpec.ProviderID)
|
|
}
|
|
c.AddTask(subnet)
|
|
|
|
switch subnetSpec.Type {
|
|
case kops.SubnetTypePublic, kops.SubnetTypeUtility:
|
|
if !sharedSubnet {
|
|
c.AddTask(&awstasks.RouteTableAssociation{
|
|
Name: s(subnetSpec.SubnetName + "." + b.ClusterName()),
|
|
RouteTable: publicRouteTable,
|
|
Subnet: subnet,
|
|
})
|
|
}
|
|
|
|
case kops.SubnetTypePrivate:
|
|
// Private subnets get a Network Gateway, and their own route table to associate them with the network gateway
|
|
|
|
if !sharedSubnet {
|
|
// Private Subnet Route Table Associations
|
|
//
|
|
// Map the Private subnet to the Private route table
|
|
c.AddTask(&awstasks.RouteTableAssociation{
|
|
Name: s("private-" + subnetSpec.SubnetName + "." + b.ClusterName()),
|
|
RouteTable: &awstasks.RouteTable{Name: s(b.NamePrivateRouteTableInZone(subnetSpec.Zone))},
|
|
Subnet: subnet,
|
|
})
|
|
|
|
privateZones.Insert(subnetSpec.Zone)
|
|
}
|
|
|
|
default:
|
|
return fmt.Errorf("subnet %q has unknown type %q", subnetSpec.SubnetName, subnetSpec.Type)
|
|
}
|
|
}
|
|
|
|
for _, zone := range privateZones.List() {
|
|
utilitySubnet, err := b.LinkToUtilitySubnetInZone(zone)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Every NGW needs a public (Elastic) IP address, every private
|
|
// subnet needs a NGW, lets create it. We tie it to a subnet
|
|
// so we can track it in AWS
|
|
eip := &awstasks.ElasticIP{
|
|
Name: s(zone + "." + b.ClusterName()),
|
|
Subnet: utilitySubnet,
|
|
}
|
|
c.AddTask(eip)
|
|
|
|
// NAT Gateway
|
|
//
|
|
// All private subnets will need a NGW, one per zone
|
|
//
|
|
// The instances in the private subnet can access the Internet by
|
|
// using a network address translation (NAT) gateway that resides
|
|
// in the public subnet.
|
|
ngw := &awstasks.NatGateway{
|
|
Name: s(zone + "." + b.ClusterName()),
|
|
Subnet: utilitySubnet,
|
|
ElasticIp: eip,
|
|
}
|
|
c.AddTask(ngw)
|
|
|
|
// Private Route Table
|
|
//
|
|
// The private route table that will route to the NAT Gateway
|
|
rt := &awstasks.RouteTable{
|
|
Name: s(b.NamePrivateRouteTableInZone(zone)),
|
|
VPC: b.LinkToVPC(),
|
|
}
|
|
c.AddTask(rt)
|
|
|
|
// Private Routes
|
|
//
|
|
// Routes for the private route table.
|
|
// Will route to the NAT Gateway
|
|
c.AddTask(&awstasks.Route{
|
|
Name: s("private-" + zone + "-0.0.0.0/0"),
|
|
CIDR: s("0.0.0.0/0"),
|
|
RouteTable: rt,
|
|
NatGateway: ngw,
|
|
})
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|