Merge pull request #45932 from lpabon/elbtag_pr
Automatic merge from submit-queue (batch tested with PRs 45518, 46127, 46146, 45932, 45003) aws: Support for ELB tagging by users This PR provides support for tagging AWS ELBs using information in an annotation and provided as a list of comma separated key-value pairs. Closes https://github.com/kubernetes/community/pull/404
This commit is contained in:
commit
29b3bb44ba
@ -131,6 +131,12 @@ const ServiceAnnotationLoadBalancerSSLPorts = "service.beta.kubernetes.io/aws-lo
|
||||
// a HTTP listener is used.
|
||||
const ServiceAnnotationLoadBalancerBEProtocol = "service.beta.kubernetes.io/aws-load-balancer-backend-protocol"
|
||||
|
||||
// ServiceAnnotationLoadBalancerAdditionalTags is the annotation used on the service
|
||||
// to specify a comma-separated list of key-value pairs which will be recorded as
|
||||
// additional tags in the ELB.
|
||||
// For example: "Key1=Val1,Key2=Val2,KeyNoVal1=,KeyNoVal2"
|
||||
const ServiceAnnotationLoadBalancerAdditionalTags = "service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags"
|
||||
|
||||
const (
|
||||
// volumeAttachmentConsecutiveErrorLimit is the number of consecutive errors we will ignore when waiting for a volume to attach/detach
|
||||
volumeAttachmentStatusConsecutiveErrorLimit = 10
|
||||
@ -2792,6 +2798,7 @@ func (c *Cloud) EnsureLoadBalancer(clusterName string, apiService *v1.Service, n
|
||||
internalELB,
|
||||
proxyProtocol,
|
||||
loadBalancerAttributes,
|
||||
annotations,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
@ -31,7 +32,36 @@ import (
|
||||
|
||||
const ProxyProtocolPolicyName = "k8s-proxyprotocol-enabled"
|
||||
|
||||
func (c *Cloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadBalancerName string, listeners []*elb.Listener, subnetIDs []string, securityGroupIDs []string, internalELB, proxyProtocol bool, loadBalancerAttributes *elb.LoadBalancerAttributes) (*elb.LoadBalancerDescription, error) {
|
||||
// getLoadBalancerAdditionalTags converts the comma separated list of key-value
|
||||
// pairs in the ServiceAnnotationLoadBalancerAdditionalTags annotation and returns
|
||||
// it as a map.
|
||||
func getLoadBalancerAdditionalTags(annotations map[string]string) map[string]string {
|
||||
additionalTags := make(map[string]string)
|
||||
if additionalTagsList, ok := annotations[ServiceAnnotationLoadBalancerAdditionalTags]; ok {
|
||||
additionalTagsList = strings.TrimSpace(additionalTagsList)
|
||||
|
||||
// Break up list of "Key1=Val,Key2=Val2"
|
||||
tagList := strings.Split(additionalTagsList, ",")
|
||||
|
||||
// Break up "Key=Val"
|
||||
for _, tagSet := range tagList {
|
||||
tag := strings.Split(strings.TrimSpace(tagSet), "=")
|
||||
|
||||
// Accept "Key=val" or "Key=" or just "Key"
|
||||
if len(tag) >= 2 && len(tag[0]) != 0 {
|
||||
// There is a key and a value, so save it
|
||||
additionalTags[tag[0]] = tag[1]
|
||||
} else if len(tag) == 1 && len(tag[0]) != 0 {
|
||||
// Just "Key"
|
||||
additionalTags[tag[0]] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return additionalTags
|
||||
}
|
||||
|
||||
func (c *Cloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadBalancerName string, listeners []*elb.Listener, subnetIDs []string, securityGroupIDs []string, internalELB, proxyProtocol bool, loadBalancerAttributes *elb.LoadBalancerAttributes, annotations map[string]string) (*elb.LoadBalancerDescription, error) {
|
||||
loadBalancer, err := c.describeLoadBalancer(loadBalancerName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -55,9 +85,12 @@ func (c *Cloud) ensureLoadBalancer(namespacedName types.NamespacedName, loadBala
|
||||
|
||||
createRequest.SecurityGroups = stringPointerArray(securityGroupIDs)
|
||||
|
||||
tags := c.tagging.buildTags(ResourceLifecycleOwned, map[string]string{
|
||||
TagNameKubernetesService: namespacedName.String(),
|
||||
})
|
||||
// Get additional tags set by the user
|
||||
tags := getLoadBalancerAdditionalTags(annotations)
|
||||
|
||||
// Add default tags
|
||||
tags[TagNameKubernetesService] = namespacedName.String()
|
||||
tags = c.tagging.buildTags(ResourceLifecycleOwned, tags)
|
||||
|
||||
for k, v := range tags {
|
||||
createRequest.Tags = append(createRequest.Tags, &elb.Tag{
|
||||
|
@ -1284,3 +1284,68 @@ func TestProxyProtocolEnabled(t *testing.T) {
|
||||
result = proxyProtocolEnabled(fakeBackend)
|
||||
assert.False(t, result, "did not expect to find %s in %s", ProxyProtocolPolicyName, policies)
|
||||
}
|
||||
|
||||
func TestGetLoadBalancerAdditionalTags(t *testing.T) {
|
||||
tagTests := []struct {
|
||||
Annotations map[string]string
|
||||
Tags map[string]string
|
||||
}{
|
||||
{
|
||||
Annotations: map[string]string{
|
||||
ServiceAnnotationLoadBalancerAdditionalTags: "Key=Val",
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"Key": "Val",
|
||||
},
|
||||
},
|
||||
{
|
||||
Annotations: map[string]string{
|
||||
ServiceAnnotationLoadBalancerAdditionalTags: "Key1=Val1, Key2=Val2",
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"Key1": "Val1",
|
||||
"Key2": "Val2",
|
||||
},
|
||||
},
|
||||
{
|
||||
Annotations: map[string]string{
|
||||
ServiceAnnotationLoadBalancerAdditionalTags: "Key1=, Key2=Val2",
|
||||
"anotherKey": "anotherValue",
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"Key1": "",
|
||||
"Key2": "Val2",
|
||||
},
|
||||
},
|
||||
{
|
||||
Annotations: map[string]string{
|
||||
"Nothing": "Key1=, Key2=Val2, Key3",
|
||||
},
|
||||
Tags: map[string]string{},
|
||||
},
|
||||
{
|
||||
Annotations: map[string]string{
|
||||
ServiceAnnotationLoadBalancerAdditionalTags: "K=V K1=V2,Key1========, =====, ======Val, =Val, , 234,",
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"K": "V K1",
|
||||
"Key1": "",
|
||||
"234": "",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tagTest := range tagTests {
|
||||
result := getLoadBalancerAdditionalTags(tagTest.Annotations)
|
||||
for k, v := range result {
|
||||
if len(result) != len(tagTest.Tags) {
|
||||
t.Errorf("incorrect expected length: %v != %v", result, tagTest.Tags)
|
||||
continue
|
||||
}
|
||||
if tagTest.Tags[k] != v {
|
||||
t.Errorf("%s != %s", tagTest.Tags[k], v)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user