Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MM-49396] Add Name tag in ELB resources #826

Merged
merged 8 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ go 1.19
require (
github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557
github.com/Masterminds/squirrel v1.5.3
github.com/aws/aws-sdk-go v1.42.16
github.com/aws/aws-sdk-go-v2 v1.17.3
github.com/aws/aws-sdk-go-v2/config v1.18.7
github.com/aws/aws-sdk-go-v2/service/acm v1.15.2
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.17.9
github.com/aws/aws-sdk-go-v2/service/ec2 v1.72.0
github.com/aws/aws-sdk-go-v2/service/eks v1.26.0
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.15.0
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.18.28
github.com/aws/aws-sdk-go-v2/service/iam v1.18.25
github.com/aws/aws-sdk-go-v2/service/kms v1.19.4
github.com/aws/aws-sdk-go-v2/service/rds v1.36.0
Expand Down Expand Up @@ -53,13 +56,13 @@ require (
k8s.io/apimachinery v0.23.0
k8s.io/client-go v0.23.0
k8s.io/kube-aggregator v0.18.8
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b
)

require (
emperror.dev/errors v0.8.0 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/aws/aws-sdk-go v1.42.16 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.7 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21 // indirect
Expand Down Expand Up @@ -140,7 +143,6 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.30.0 // indirect
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b // indirect
sigs.k8s.io/controller-runtime v0.11.0 // indirect
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 // indirect
Expand Down
12 changes: 4 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ github.com/aws/aws-sdk-go-v2/service/ec2 v1.72.0 h1:bCFJL8mahOZJa3+t8+uWHL1JzuCI
github.com/aws/aws-sdk-go-v2/service/ec2 v1.72.0/go.mod h1:zul71QqzR4D1a90/5FloZiAnZ1CtuIjVH7R9MP997+A=
github.com/aws/aws-sdk-go-v2/service/eks v1.26.0 h1:YgH4p2ZmNkpsEWOB1xcd4ncvD+JACPhYy7o5EydX0m4=
github.com/aws/aws-sdk-go-v2/service/eks v1.26.0/go.mod h1:H/748RFDDxPmaxe03lhX0ufIQHIO2ctqjTfxuX4N7Vg=
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.15.0 h1:FFfQypN9iItIrGhbl8em90uXMFBLrCkNC1yJ65+m9Sk=
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.15.0/go.mod h1:3OUv9SlYvymsCF3I5NftITc1+B09cF5lg4IsZgQQy1U=
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.18.28 h1:Ae7aH1PEbrVSg1fSQy33E/mILWd1Csncz95FMfxYWms=
github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.18.28/go.mod h1:ix71C17la8K2MUJrqJzu+i7+aPoQYTAy14hKQbGDB9w=
github.com/aws/aws-sdk-go-v2/service/iam v1.18.25 h1:Np+wTW2nuSBGyEu0WFsiu0LO05rxLFMh3hYVAjOzyVw=
github.com/aws/aws-sdk-go-v2/service/iam v1.18.25/go.mod h1:OyAuvpFeSVNppcSsp1hFOVQcaTRc1LE24YIR7pMbbAA=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.1/go.mod h1:v33JQ57i2nekYTA70Mb+O18KeH4KqhdqxTJZNK1zdRE=
Expand All @@ -245,12 +249,6 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19/go.mod h1:02
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 h1:5C6XgTViSb0bunmU57b3CT+MhxULqHH2721FVA+/kDM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21/go.mod h1:lRToEJsn+DRA9lW4O9L9+/3hjTkUzlzyzHqn8MTds5k=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.5.1/go.mod h1:6EQZIwNNvHpq/2/QSJnp4+ECvqIy55w95Ofs0ze+nGQ=
github.com/aws/aws-sdk-go-v2/service/kms v1.19.4 h1:bX+nEwdukfDdfGPUjNNqs7NwZyqyMjIy5YpZda9Gcu4=
github.com/aws/aws-sdk-go-v2/service/kms v1.19.4/go.mod h1:13sjgMH7Xu4e46+0BEDhSnNh+cImHSYS5PpBjV3oXcU=
github.com/aws/aws-sdk-go-v2/service/rds v1.36.0 h1:vZpqgQhYoay+Qb+OfTxFLxoqBnDOFI3C8yx8c4T1pak=
github.com/aws/aws-sdk-go-v2/service/rds v1.36.0/go.mod h1:Ume9NHqT871hUdxIRojWtWsPFyCswQmSjHHhyGot7v0=
github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.13.26 h1:/PUrNPA60N/tE60pf3AZPIe5th/E5GXgVq+PdLgae5c=
github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.13.26/go.mod h1:NjPeUP8L8V1lN1ik1Znb0cEnIgGA3Upt/UFSzwBLC6o=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21 h1:vY5siRXvW5TrOKm2qKEf9tliBfdLxdfy0i02LOcmqUo=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21/go.mod h1:WZvNXT1XuH8dnJM0HvOlvk+RNn7NbAPvA/ACO0QarSc=
github.com/aws/aws-sdk-go-v2/service/kms v1.19.4 h1:bX+nEwdukfDdfGPUjNNqs7NwZyqyMjIy5YpZda9Gcu4=
Expand All @@ -262,8 +260,6 @@ github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.13.26/go.mod h1
github.com/aws/aws-sdk-go-v2/service/route53 v1.25.2 h1:MNL6bLDcwOGL9j+ANiejLYn/cBSku1m+pLWXri/FFF4=
github.com/aws/aws-sdk-go-v2/service/route53 v1.25.2/go.mod h1:4SAHuLdh4v7pA2F6HdhUUgiLUDA6J89KWr7xAYCDiyc=
github.com/aws/aws-sdk-go-v2/service/s3 v1.11.1/go.mod h1:XLAGFrEjbvMCLvAtWLLP32yTv8GpBquCApZEycDLunI=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.10 h1:6obimjQAiRlEUZT7a2Q1ikH7ck4cPO3phGz4wqI5f2w=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.10/go.mod h1:jAeo/PdIJZuDSwsvxJS94G4d6h8tStj7WXVuKwLHWU8=
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.6 h1:W8pLcSn6Uy0eXgDBUUl8M8Kxv7JCoP68ZKTD04OXLEA=
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.6/go.mod h1:L2l2/q76teehcW7YEsgsDjqdsDTERJeX3nOMIFlgGUE=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.10 h1:6obimjQAiRlEUZT7a2Q1ikH7ck4cPO3phGz4wqI5f2w=
Expand Down
14 changes: 14 additions & 0 deletions internal/mocks/aws-tools/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions internal/provisioner/kops_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,32 @@ func getPrivateLoadBalancerEndpoint(ctx context.Context, namespace string, logge
}
}

// getElasticLoadBalancerInfo returns the private load balancer endpoint and type of the NGINX service.
func getElasticLoadBalancerInfo(namespace string, logger log.FieldLogger, configPath string) (string, string, error) {
k8sClient, err := k8s.NewFromFile(configPath, logger)
if err != nil {
return "", "", err
}

services, err := k8sClient.Clientset.CoreV1().Services(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return "", "", err
}

for _, service := range services.Items {
if service.Spec.Type == "LoadBalancer" {
if service.Status.LoadBalancer.Ingress != nil {
endpoint := service.Status.LoadBalancer.Ingress[0].Hostname
if endpoint != "" {
return endpoint, service.Annotations["service.beta.kubernetes.io/aws-load-balancer-type"], nil
}
}
}
}

return "", "", nil
}

// GetPublicLoadBalancerEndpoint returns the public load balancer endpoint of the NGINX service.
func (provisioner *KopsProvisioner) GetPublicLoadBalancerEndpoint(cluster *model.Cluster, namespace string) (string, error) {
logger := provisioner.logger.WithFields(log.Fields{
Expand Down
31 changes: 28 additions & 3 deletions internal/provisioner/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
log "github.com/sirupsen/logrus"
)

const (
namespaceNginx = "nginx"
)

type nginx struct {
awsClient aws.AWS
kubeconfigPath string
Expand Down Expand Up @@ -69,8 +73,29 @@ func (n *nginx) CreateOrUpgrade() error {
return err
}

err = n.updateVersion(h)
return err
if err = n.updateVersion(h); err != nil {
return err
}

if err = n.addLoadBalancerNameTag(); err != nil {
n.logger.Errorln(err)
}

return nil
}

func (n *nginx) addLoadBalancerNameTag() error {

endpoint, elbType, err := getElasticLoadBalancerInfo(namespaceNginx, n.logger, n.kubeconfigPath)
if err != nil {
return errors.Wrap(err, "couldn't get the loadbalancer endpoint (nginx)")
}

if err := addLoadBalancerNameTag(n.awsClient.GetLoadBalancerAPI(elbType), endpoint); err != nil {
return errors.Wrap(err, "failed to add loadbalancer name tag (nginx)")
}

return nil
}

func (n *nginx) DesiredVersion() *model.HelmUtilityVersion {
Expand Down Expand Up @@ -121,7 +146,7 @@ func (n *nginx) NewHelmDeployment() (*helmDeployment, error) {
return newHelmDeployment(
"ingress-nginx/ingress-nginx",
"nginx",
"nginx",
namespaceNginx,
n.kubeconfigPath,
n.desiredVersion,
fmt.Sprintf("controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-ssl-cert=%s,controller.config.proxy-real-ip-cidr=%s", *certificate.ARN, clusterResources.VpcCIDR),
Expand Down
49 changes: 47 additions & 2 deletions internal/provisioner/nginx_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,30 @@ func (n *nginxInternal) CreateOrUpgrade() error {
return err
}

err = n.updateVersion(h)
return err
if err = n.updateVersion(h); err != nil {
return err

}

if err = n.addLoadBalancerNameTag(); err != nil {
n.logger.Errorln(err)
}

return nil
}

func (n *nginxInternal) addLoadBalancerNameTag() error {

endpoint, elbType, err := getElasticLoadBalancerInfo(namespaceNginxInternal, n.logger, n.kubeconfigPath)
if err != nil {
return errors.Wrap(err, "couldn't get the loadbalancer endpoint (nginx-internal)")
}

if err := addLoadBalancerNameTag(n.awsClient.GetLoadBalancerAPI(elbType), endpoint); err != nil {
return errors.Wrap(err, "failed to add loadbalancer name tag (nginx-internal)")
}

return nil
}

func (n *nginxInternal) DesiredVersion() *model.HelmUtilityVersion {
Expand Down Expand Up @@ -142,3 +164,26 @@ func (n *nginxInternal) NewHelmDeployment(withArguments bool) (*helmDeployment,
func (n *nginxInternal) Name() string {
return model.NginxInternalCanonicalName
}

func addLoadBalancerNameTag(elbClient aws.ELB, hostname string) error {
if hostname == "" {
return errors.New("cannot add loadbalancer name tag if hostname is empty")
}

parts := strings.Split(hostname, "-")
loadbalancerName := parts[0]

resource, err := elbClient.GetLoadBalancerResource(loadbalancerName)
if err != nil {
return errors.Wrap(err, "failed to get loadbalancer ARN")
}

err = elbClient.TagLoadBalancer(resource, map[string]string{
"Name": loadbalancerName,
})
if err != nil {
return errors.Wrap(err, "failed to tag loadbalancer")
}

return nil
}
5 changes: 5 additions & 0 deletions internal/supervisor/installation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,11 @@ func (p *mockInstallationProvisioner) PrepareClusterUtilities(cluster *model.Clu
// can be tested.
type mockAWS struct{}

func (a *mockAWS) GetLoadBalancerAPI(s string) aws.ELB {
//TODO implement me
panic("implement me")
}

func (a *mockAWS) InstallEKSEBSAddon(cluster *model.Cluster) error {
return nil
}
Expand Down
4 changes: 4 additions & 0 deletions internal/tools/aws/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ type AWS interface {

GetRegion() string
GetAccountID() (string, error)

GetLoadBalancerAPI(string) ELB
}

// Client is a client for interacting with AWS resources in a single AWS account.
Expand Down Expand Up @@ -141,6 +143,7 @@ type Service struct {
dynamodb DynamoDBAPI
sts STSAPI
eks EKSAPI
elb elasticLoadbalancer
}

// NewService creates a new instance of Service.
Expand All @@ -158,6 +161,7 @@ func NewService(cfg aws.Config) *Service {
dynamodb: dynamodb.NewFromConfig(cfg), // v2
sts: sts.NewFromConfig(cfg), // v2
eks: eks.NewFromConfig(cfg), // v2
elb: newElasticLoadbalancerFromConfig(cfg),
}
}

Expand Down
99 changes: 99 additions & 0 deletions internal/tools/aws/elb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package aws

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
elbv1 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
elbv1Type "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing/types"
elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
elbv2Type "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
"k8s.io/utils/pointer"
)

type elasticLoadbalancer struct {
elasticLoadbalancerV1
elasticLoadbalancerV2
}

func newElasticLoadbalancerFromConfig(cfg aws.Config) elasticLoadbalancer {
return elasticLoadbalancer{
elasticLoadbalancerV1: elasticLoadbalancerV1{
elbv1.NewFromConfig(cfg),
},
elasticLoadbalancerV2: elasticLoadbalancerV2{
elbv2.NewFromConfig(cfg),
},
}
}

// GetLoadBalancerAPI returns the correct ELB API based on elb type
func (c *Client) GetLoadBalancerAPI(elbType string) ELB {
mirshahriar marked this conversation as resolved.
Show resolved Hide resolved
if elbType == "nlb" {
return c.service.elb.elasticLoadbalancerV2
}
return c.service.elb.elasticLoadbalancerV1
}

type elasticLoadbalancerV1 struct {
ELBV1
}

// GetLoadBalancerResource does nothing
func (e elasticLoadbalancerV1) GetLoadBalancerResource(name string) (string, error) {
return name, nil
}

// TagLoadBalancer adds tags to the ELB
func (e elasticLoadbalancerV1) TagLoadBalancer(name string, tags map[string]string) error {
var elbTags []elbv1Type.Tag
for key, value := range tags {
elbTags = append(elbTags, elbv1Type.Tag{
Key: pointer.String(key),
Value: pointer.String(value),
mirshahriar marked this conversation as resolved.
Show resolved Hide resolved
})
}

_, err := e.AddTags(context.Background(), &elbv1.AddTagsInput{
LoadBalancerNames: []string{name},
Tags: elbTags,
})
return err
}

type elasticLoadbalancerV2 struct {
ELBV2
}

// GetLoadBalancerResource returns the ARN of the ELB
func (e elasticLoadbalancerV2) GetLoadBalancerResource(name string) (string, error) {
loadBalancer, err := e.DescribeLoadBalancers(context.Background(), &elbv2.DescribeLoadBalancersInput{
Names: []string{name},
})
if err != nil {
return "", err
}

if len(loadBalancer.LoadBalancers) == 0 || loadBalancer.LoadBalancers[0].LoadBalancerArn == nil {
return "", nil
}

return *loadBalancer.LoadBalancers[0].LoadBalancerArn, nil
}

// TagLoadBalancer adds tags to the ELB
func (e elasticLoadbalancerV2) TagLoadBalancer(arn string, tags map[string]string) error {
var elbTags []elbv2Type.Tag
for key, value := range tags {
elbTags = append(elbTags, elbv2Type.Tag{
Key: pointer.String(key),
Value: pointer.String(value),
})
}

_, err := e.AddTags(context.Background(), &elbv2.AddTagsInput{
ResourceArns: []string{arn},
Tags: elbTags,
})
return err
}
Loading