Merge pull request #2474 from justinsb/subnet_tagging

Use explicit tag management in network tasks
This commit is contained in:
Justin Santa Barbara 2017-05-02 10:17:48 -04:00 committed by GitHub
commit b351696476
20 changed files with 164 additions and 76 deletions

View File

@ -29,7 +29,9 @@ import (
"k8s.io/kops/pkg/apis/kops/util"
"k8s.io/kops/pkg/featureflag"
"k8s.io/kops/pkg/model/components"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
)
var UseLegacyELBName = featureflag.New("UseLegacyELBName", featureflag.Bool(false))
@ -189,6 +191,27 @@ func (m *KopsModelContext) CloudTagsForInstanceGroup(ig *kops.InstanceGroup) (ma
return labels, nil
}
// CloudTags computes the tags to apply to a normal cloud resource with the specified name
func (m *KopsModelContext) CloudTags(name string, shared bool) map[string]string {
tags := make(map[string]string)
switch fi.CloudProviderID(m.Cluster.Spec.CloudProvider) {
case fi.CloudProviderAWS:
tags[awsup.TagClusterName] = m.Cluster.ObjectMeta.Name
if name != "" {
tags["Name"] = name
}
if shared {
tags["kubernetes.io/cluster/"+m.Cluster.ObjectMeta.Name] = "shared"
} else {
tags["kubernetes.io/cluster/"+m.Cluster.ObjectMeta.Name] = "owned"
}
}
return tags
}
func (m *KopsModelContext) UsesBastionDns() bool {
if m.Cluster.Spec.Topology.Bastion != nil && m.Cluster.Spec.Topology.Bastion.BastionPublicName != "" {
return true

View File

@ -40,13 +40,17 @@ func (b *NetworkModelBuilder) Build(c *fi.ModelBuilderContext) error {
}
sharedVPC := b.Cluster.SharedVPC()
vpcName := b.ClusterName()
// VPC that holds everything for the cluster
{
tags := b.CloudTags(vpcName, sharedVPC)
t := &awstasks.VPC{
Name: s(b.ClusterName()),
Name: s(vpcName),
Shared: fi.Bool(sharedVPC),
EnableDNSSupport: fi.Bool(true),
Tags: tags,
}
if sharedVPC && VersionGTE(kubernetesVersion, 1, 5) {
@ -133,13 +137,16 @@ func (b *NetworkModelBuilder) Build(c *fi.ModelBuilderContext) error {
for i := range b.Cluster.Spec.Subnets {
subnetSpec := &b.Cluster.Spec.Subnets[i]
sharedSubnet := subnetSpec.ProviderID != ""
subnetName := subnetSpec.Name + "." + b.ClusterName()
tags := b.CloudTags(subnetName, sharedSubnet)
subnet := &awstasks.Subnet{
Name: s(subnetSpec.Name + "." + b.ClusterName()),
Name: s(subnetName),
VPC: b.LinkToVPC(),
AvailabilityZone: s(subnetSpec.Zone),
CIDR: s(subnetSpec.CIDR),
Shared: fi.Bool(sharedSubnet),
Tags: tags,
}
if subnetSpec.ProviderID != "" {

View File

@ -342,8 +342,9 @@ resource "aws_subnet" "us-test-1a-complex-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "complex.example.com"
Name = "us-test-1a.complex.example.com"
KubernetesCluster = "complex.example.com"
Name = "us-test-1a.complex.example.com"
"kubernetes.io/cluster/complex.example.com" = "owned"
}
}
@ -353,8 +354,9 @@ resource "aws_vpc" "complex-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "complex.example.com"
Name = "complex.example.com"
KubernetesCluster = "complex.example.com"
Name = "complex.example.com"
"kubernetes.io/cluster/complex.example.com" = "owned"
}
}

View File

@ -512,8 +512,9 @@ resource "aws_subnet" "us-test-1a-ha-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "ha.example.com"
Name = "us-test-1a.ha.example.com"
KubernetesCluster = "ha.example.com"
Name = "us-test-1a.ha.example.com"
"kubernetes.io/cluster/ha.example.com" = "owned"
}
}
@ -523,8 +524,9 @@ resource "aws_subnet" "us-test-1b-ha-example-com" {
availability_zone = "us-test-1b"
tags = {
KubernetesCluster = "ha.example.com"
Name = "us-test-1b.ha.example.com"
KubernetesCluster = "ha.example.com"
Name = "us-test-1b.ha.example.com"
"kubernetes.io/cluster/ha.example.com" = "owned"
}
}
@ -534,8 +536,9 @@ resource "aws_subnet" "us-test-1c-ha-example-com" {
availability_zone = "us-test-1c"
tags = {
KubernetesCluster = "ha.example.com"
Name = "us-test-1c.ha.example.com"
KubernetesCluster = "ha.example.com"
Name = "us-test-1c.ha.example.com"
"kubernetes.io/cluster/ha.example.com" = "owned"
}
}
@ -545,8 +548,9 @@ resource "aws_vpc" "ha-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "ha.example.com"
Name = "ha.example.com"
KubernetesCluster = "ha.example.com"
Name = "ha.example.com"
"kubernetes.io/cluster/ha.example.com" = "owned"
}
}

View File

@ -342,8 +342,9 @@ resource "aws_subnet" "us-test-1a-minimal-141-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "minimal-141.example.com"
Name = "us-test-1a.minimal-141.example.com"
KubernetesCluster = "minimal-141.example.com"
Name = "us-test-1a.minimal-141.example.com"
"kubernetes.io/cluster/minimal-141.example.com" = "owned"
}
}
@ -353,8 +354,9 @@ resource "aws_vpc" "minimal-141-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "minimal-141.example.com"
Name = "minimal-141.example.com"
KubernetesCluster = "minimal-141.example.com"
Name = "minimal-141.example.com"
"kubernetes.io/cluster/minimal-141.example.com" = "owned"
}
}

View File

@ -397,6 +397,10 @@
{
"Key": "Name",
"Value": "us-test-1a.minimal.example.com"
},
{
"Key": "kubernetes.io/cluster/minimal.example.com",
"Value": "owned"
}
]
}
@ -437,6 +441,10 @@
{
"Key": "Name",
"Value": "minimal.example.com"
},
{
"Key": "kubernetes.io/cluster/minimal.example.com",
"Value": "owned"
}
]
}

View File

@ -342,8 +342,9 @@ resource "aws_subnet" "us-test-1a-minimal-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "minimal.example.com"
Name = "us-test-1a.minimal.example.com"
KubernetesCluster = "minimal.example.com"
Name = "us-test-1a.minimal.example.com"
"kubernetes.io/cluster/minimal.example.com" = "owned"
}
}
@ -353,8 +354,9 @@ resource "aws_vpc" "minimal-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "minimal.example.com"
Name = "minimal.example.com"
KubernetesCluster = "minimal.example.com"
Name = "minimal.example.com"
"kubernetes.io/cluster/minimal.example.com" = "owned"
}
}

View File

@ -614,8 +614,9 @@ resource "aws_subnet" "us-test-1a-privatecalico-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatecalico.example.com"
Name = "us-test-1a.privatecalico.example.com"
KubernetesCluster = "privatecalico.example.com"
Name = "us-test-1a.privatecalico.example.com"
"kubernetes.io/cluster/privatecalico.example.com" = "owned"
}
}
@ -625,8 +626,9 @@ resource "aws_subnet" "utility-us-test-1a-privatecalico-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatecalico.example.com"
Name = "utility-us-test-1a.privatecalico.example.com"
KubernetesCluster = "privatecalico.example.com"
Name = "utility-us-test-1a.privatecalico.example.com"
"kubernetes.io/cluster/privatecalico.example.com" = "owned"
}
}
@ -636,8 +638,9 @@ resource "aws_vpc" "privatecalico-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "privatecalico.example.com"
Name = "privatecalico.example.com"
KubernetesCluster = "privatecalico.example.com"
Name = "privatecalico.example.com"
"kubernetes.io/cluster/privatecalico.example.com" = "owned"
}
}

View File

@ -605,8 +605,9 @@ resource "aws_subnet" "us-test-1a-privatecanal-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatecanal.example.com"
Name = "us-test-1a.privatecanal.example.com"
KubernetesCluster = "privatecanal.example.com"
Name = "us-test-1a.privatecanal.example.com"
"kubernetes.io/cluster/privatecanal.example.com" = "owned"
}
}
@ -616,8 +617,9 @@ resource "aws_subnet" "utility-us-test-1a-privatecanal-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatecanal.example.com"
Name = "utility-us-test-1a.privatecanal.example.com"
KubernetesCluster = "privatecanal.example.com"
Name = "utility-us-test-1a.privatecanal.example.com"
"kubernetes.io/cluster/privatecanal.example.com" = "owned"
}
}
@ -627,8 +629,9 @@ resource "aws_vpc" "privatecanal-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "privatecanal.example.com"
Name = "privatecanal.example.com"
KubernetesCluster = "privatecanal.example.com"
Name = "privatecanal.example.com"
"kubernetes.io/cluster/privatecanal.example.com" = "owned"
}
}

View File

@ -610,8 +610,9 @@ resource "aws_subnet" "us-test-1a-privatedns1-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatedns1.example.com"
Name = "us-test-1a.privatedns1.example.com"
KubernetesCluster = "privatedns1.example.com"
Name = "us-test-1a.privatedns1.example.com"
"kubernetes.io/cluster/privatedns1.example.com" = "owned"
}
}
@ -621,8 +622,9 @@ resource "aws_subnet" "utility-us-test-1a-privatedns1-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatedns1.example.com"
Name = "utility-us-test-1a.privatedns1.example.com"
KubernetesCluster = "privatedns1.example.com"
Name = "utility-us-test-1a.privatedns1.example.com"
"kubernetes.io/cluster/privatedns1.example.com" = "owned"
}
}
@ -632,8 +634,9 @@ resource "aws_vpc" "privatedns1-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "privatedns1.example.com"
Name = "privatedns1.example.com"
KubernetesCluster = "privatedns1.example.com"
Name = "privatedns1.example.com"
"kubernetes.io/cluster/privatedns1.example.com" = "owned"
}
}

View File

@ -596,8 +596,9 @@ resource "aws_subnet" "us-test-1a-privatedns2-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatedns2.example.com"
Name = "us-test-1a.privatedns2.example.com"
KubernetesCluster = "privatedns2.example.com"
Name = "us-test-1a.privatedns2.example.com"
"kubernetes.io/cluster/privatedns2.example.com" = "owned"
}
}
@ -607,7 +608,8 @@ resource "aws_subnet" "utility-us-test-1a-privatedns2-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatedns2.example.com"
Name = "utility-us-test-1a.privatedns2.example.com"
KubernetesCluster = "privatedns2.example.com"
Name = "utility-us-test-1a.privatedns2.example.com"
"kubernetes.io/cluster/privatedns2.example.com" = "owned"
}
}

View File

@ -605,8 +605,9 @@ resource "aws_subnet" "us-test-1a-privateflannel-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privateflannel.example.com"
Name = "us-test-1a.privateflannel.example.com"
KubernetesCluster = "privateflannel.example.com"
Name = "us-test-1a.privateflannel.example.com"
"kubernetes.io/cluster/privateflannel.example.com" = "owned"
}
}
@ -616,8 +617,9 @@ resource "aws_subnet" "utility-us-test-1a-privateflannel-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privateflannel.example.com"
Name = "utility-us-test-1a.privateflannel.example.com"
KubernetesCluster = "privateflannel.example.com"
Name = "utility-us-test-1a.privateflannel.example.com"
"kubernetes.io/cluster/privateflannel.example.com" = "owned"
}
}
@ -627,8 +629,9 @@ resource "aws_vpc" "privateflannel-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "privateflannel.example.com"
Name = "privateflannel.example.com"
KubernetesCluster = "privateflannel.example.com"
Name = "privateflannel.example.com"
"kubernetes.io/cluster/privateflannel.example.com" = "owned"
}
}

View File

@ -596,8 +596,9 @@ resource "aws_subnet" "us-test-1a-privatekopeio-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatekopeio.example.com"
Name = "us-test-1a.privatekopeio.example.com"
KubernetesCluster = "privatekopeio.example.com"
Name = "us-test-1a.privatekopeio.example.com"
"kubernetes.io/cluster/privatekopeio.example.com" = "owned"
}
}
@ -607,8 +608,9 @@ resource "aws_subnet" "utility-us-test-1a-privatekopeio-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privatekopeio.example.com"
Name = "utility-us-test-1a.privatekopeio.example.com"
KubernetesCluster = "privatekopeio.example.com"
Name = "utility-us-test-1a.privatekopeio.example.com"
"kubernetes.io/cluster/privatekopeio.example.com" = "owned"
}
}
@ -618,8 +620,9 @@ resource "aws_vpc" "privatekopeio-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "privatekopeio.example.com"
Name = "privatekopeio.example.com"
KubernetesCluster = "privatekopeio.example.com"
Name = "privatekopeio.example.com"
"kubernetes.io/cluster/privatekopeio.example.com" = "owned"
}
}

View File

@ -605,8 +605,9 @@ resource "aws_subnet" "us-test-1a-privateweave-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privateweave.example.com"
Name = "us-test-1a.privateweave.example.com"
KubernetesCluster = "privateweave.example.com"
Name = "us-test-1a.privateweave.example.com"
"kubernetes.io/cluster/privateweave.example.com" = "owned"
}
}
@ -616,8 +617,9 @@ resource "aws_subnet" "utility-us-test-1a-privateweave-example-com" {
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "privateweave.example.com"
Name = "utility-us-test-1a.privateweave.example.com"
KubernetesCluster = "privateweave.example.com"
Name = "utility-us-test-1a.privateweave.example.com"
"kubernetes.io/cluster/privateweave.example.com" = "owned"
}
}
@ -627,8 +629,9 @@ resource "aws_vpc" "privateweave-example-com" {
enable_dns_support = true
tags = {
KubernetesCluster = "privateweave.example.com"
Name = "privateweave.example.com"
KubernetesCluster = "privateweave.example.com"
Name = "privateweave.example.com"
"kubernetes.io/cluster/privateweave.example.com" = "owned"
}
}

View File

@ -40,11 +40,13 @@ func TestElasticIPCreate(t *testing.T) {
vpc1 := &VPC{
Name: s("vpc1"),
CIDR: s("172.20.0.0/16"),
Tags: map[string]string{"Name": "vpc1"},
}
subnet1 := &Subnet{
Name: s("subnet1"),
VPC: vpc1,
CIDR: s("172.20.1.0/24"),
Tags: map[string]string{"Name": "subnet1"},
}
eip1 := &ElasticIP{
Name: s("eip1"),

View File

@ -102,6 +102,7 @@ func TestSecurityGroupCreate(t *testing.T) {
vpc1 := &VPC{
Name: s("vpc1"),
CIDR: s("172.20.0.0/16"),
Tags: map[string]string{"Name": "vpc1"},
}
sg1 := &SecurityGroup{
Name: s("sg1"),

View File

@ -37,6 +37,8 @@ type Subnet struct {
AvailabilityZone *string
CIDR *string
Shared *bool
Tags map[string]string
}
var _ fi.CompareWithID = &Subnet{}
@ -71,6 +73,7 @@ func (e *Subnet) Find(c *fi.Context) (*Subnet, error) {
CIDR: subnet.CidrBlock,
Name: findNameTag(subnet.Tags),
Shared: e.Shared,
Tags: intersectTags(subnet.Tags, e.Tags),
}
glog.V(2).Infof("found matching subnet %q", *actual.ID)
@ -172,7 +175,7 @@ func (_ *Subnet) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Subnet) error {
e.ID = response.Subnet.SubnetId
}
return t.AddAWSTags(*e.ID, t.Cloud.BuildTags(e.Name))
return t.AddAWSTags(*e.ID, e.Tags)
}
func subnetSlicesEqualIgnoreOrder(l, r []*Subnet) bool {
@ -199,8 +202,6 @@ type terraformSubnet struct {
}
func (_ *Subnet) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *Subnet) error {
cloud := t.Cloud.(awsup.AWSCloud)
shared := fi.BoolValue(e.Shared)
if shared {
// Not terraform owned / managed
@ -211,7 +212,7 @@ func (_ *Subnet) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *Su
VPCID: e.VPC.TerraformLink(),
CIDR: e.CIDR,
AvailabilityZone: e.AvailabilityZone,
Tags: cloud.BuildTags(e.Name),
Tags: e.Tags,
}
return t.RenderResource("aws_subnet", *e.Name, tf)
@ -239,8 +240,6 @@ type cloudformationSubnet struct {
}
func (_ *Subnet) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e, changes *Subnet) error {
cloud := t.Cloud.(awsup.AWSCloud)
shared := fi.BoolValue(e.Shared)
if shared {
// Not cloudformation owned / managed
@ -251,7 +250,7 @@ func (_ *Subnet) RenderCloudformation(t *cloudformation.CloudformationTarget, a,
VPCID: e.VPC.CloudformationLink(),
CIDR: e.CIDR,
AvailabilityZone: e.AvailabilityZone,
Tags: buildCloudformationTags(cloud.BuildTags(e.Name)),
Tags: buildCloudformationTags(e.Tags),
}
return t.RenderResource("AWS::EC2::Subnet", *e.Name, cf)

View File

@ -40,3 +40,21 @@ func findNameTag(tags []*ec2.Tag) *string {
}
return nil
}
// intersectTags returns the tags of interest from a specified list of AWS tags;
// because we only add tags, this set of tags of interest is the tags that occur in the desired seet.
func intersectTags(tags []*ec2.Tag, desired map[string]string) map[string]string {
if tags == nil {
return nil
}
actual := make(map[string]string)
for _, t := range tags {
k := aws.StringValue(t.Key)
v := aws.StringValue(t.Value)
if _, found := desired[k]; found {
actual[k] = v
}
}
return actual
}

View File

@ -39,6 +39,8 @@ type VPC struct {
// Shared is set if this is a shared VPC
Shared *bool
Tags map[string]string
}
var _ fi.CompareWithID = &VPC{}
@ -74,6 +76,7 @@ func (e *VPC) Find(c *fi.Context) (*VPC, error) {
ID: vpc.VpcId,
CIDR: vpc.CidrBlock,
Name: findNameTag(vpc.Tags),
Tags: intersectTags(vpc.Tags, e.Tags),
}
glog.V(4).Infof("found matching VPC %v", actual)
@ -183,7 +186,7 @@ func (_ *VPC) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *VPC) error {
}
}
tags := t.Cloud.BuildTags(e.Name)
tags := e.Tags
if shared {
// Don't tag shared resources
tags = nil
@ -199,8 +202,6 @@ type terraformVPC struct {
}
func (_ *VPC) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *VPC) error {
cloud := t.Cloud.(awsup.AWSCloud)
if err := t.AddOutputVariable("vpc_id", e.TerraformLink()); err != nil {
return err
}
@ -213,7 +214,7 @@ func (_ *VPC) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *VPC)
tf := &terraformVPC{
CIDR: e.CIDR,
Tags: cloud.BuildTags(e.Name),
Tags: e.Tags,
EnableDNSHostnames: e.EnableDNSHostnames,
EnableDNSSupport: e.EnableDNSSupport,
}
@ -243,8 +244,6 @@ type cloudformationVPC struct {
}
func (_ *VPC) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e, changes *VPC) error {
cloud := t.Cloud.(awsup.AWSCloud)
shared := fi.BoolValue(e.Shared)
if shared {
// Not cloudformation owned / managed
@ -255,7 +254,7 @@ func (_ *VPC) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e,
CidrBlock: e.CIDR,
EnableDnsHostnames: e.EnableDNSHostnames,
EnableDnsSupport: e.EnableDNSSupport,
Tags: buildCloudformationTags(cloud.BuildTags(e.Name)),
Tags: buildCloudformationTags(e.Tags),
}
return t.RenderResource("AWS::EC2::VPC", *e.Name, tf)

View File

@ -36,6 +36,7 @@ func TestVPCCreate(t *testing.T) {
vpc1 := &VPC{
Name: s("vpc1"),
CIDR: s("172.21.0.0/16"),
Tags: map[string]string{"Name": "vpc1"},
}
return map[string]fi.Task{
"vpc1": vpc1,