Skip to content

Commit

Permalink
Merge branch 'kubernetes-sigs:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
shraddhabang authored Apr 18, 2024
2 parents f1ad24a + 33838dd commit fa60f1e
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.21.8
1.21.9
2 changes: 1 addition & 1 deletion controllers/service/service_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewServiceReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorde
modelBuilder := service.NewDefaultModelBuilder(annotationParser, subnetsResolver, vpcInfoProvider, cloud.VpcID(), trackingProvider,
elbv2TaggingManager, cloud.EC2(), controllerConfig.FeatureGates, controllerConfig.ClusterName, controllerConfig.DefaultTags, controllerConfig.ExternalManagedTags,
controllerConfig.DefaultSSLPolicy, controllerConfig.DefaultTargetType, controllerConfig.FeatureGates.Enabled(config.EnableIPTargetType), serviceUtils,
backendSGProvider, sgResolver, controllerConfig.EnableBackendSecurityGroup, controllerConfig.DisableRestrictedSGRules)
backendSGProvider, sgResolver, controllerConfig.EnableBackendSecurityGroup, controllerConfig.DisableRestrictedSGRules, logger)
stackMarshaller := deploy.NewDefaultStackMarshaller()
stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler, elbv2TaggingManager, controllerConfig, serviceTagPrefix, logger)
return &serviceReconciler{
Expand Down
9 changes: 9 additions & 0 deletions docs/guide/service/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
| [service.beta.kubernetes.io/aws-load-balancer-attributes](#load-balancer-attributes) | stringMap | | |
| [service.beta.kubernetes.io/aws-load-balancer-security-groups](#security-groups) | stringList | | |
| [service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rules](#manage-backend-sg-rules) | boolean | true | |
| [service.beta.kubernetes.io/aws-load-balancer-inbound-sg-rules-on-private-link-traffic](#update-security-settings) | string | |

## Traffic Routing
Traffic Routing can be controlled with following annotations:
Expand Down Expand Up @@ -488,6 +489,14 @@ Load balancer access can be controlled via following annotations:
service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rules: "false"
```

- <a name="update-security-settings">`service.beta.kubernetes.io/aws-load-balancer-inbound-sg-rules-on-private-link-traffic`</a> specifies whether to apply security group rules to traffic sent to the load balancer through AWS PrivateLink.

!!!example
```
service.beta.kubernetes.io/aws-load-balancer-inbound-sg-rules-on-private-link-traffic: "off"
```


## Legacy Cloud Provider
The AWS Load Balancer Controller manages Kubernetes Services in a compatible way with the AWS cloud provider's legacy service controller.

Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func main() {
corewebhook.NewServiceMutator(controllerCFG.ServiceConfig.LoadBalancerClass, ctrl.Log).SetupWithManager(mgr)
elbv2webhook.NewIngressClassParamsValidator().SetupWithManager(mgr)
elbv2webhook.NewTargetGroupBindingMutator(cloud.ELBV2(), ctrl.Log).SetupWithManager(mgr)
elbv2webhook.NewTargetGroupBindingValidator(mgr.GetClient(), cloud.ELBV2(), ctrl.Log).SetupWithManager(mgr)
elbv2webhook.NewTargetGroupBindingValidator(mgr.GetClient(), cloud.ELBV2(), cloud.VpcID(), ctrl.Log).SetupWithManager(mgr)
networkingwebhook.NewIngressValidator(mgr.GetClient(), controllerCFG.IngressConfig, ctrl.Log).SetupWithManager(mgr)
//+kubebuilder:scaffold:builder

Expand Down
71 changes: 36 additions & 35 deletions pkg/annotations/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,39 +50,40 @@ const (

// NLB annotation suffixes
// prefixes service.beta.kubernetes.io, service.kubernetes.io
SvcLBSuffixSourceRanges = "load-balancer-source-ranges"
SvcLBSuffixLoadBalancerType = "aws-load-balancer-type"
SvcLBSuffixTargetType = "aws-load-balancer-nlb-target-type"
SvcLBSuffixLoadBalancerName = "aws-load-balancer-name"
SvcLBSuffixScheme = "aws-load-balancer-scheme"
SvcLBSuffixInternal = "aws-load-balancer-internal"
SvcLBSuffixProxyProtocol = "aws-load-balancer-proxy-protocol"
SvcLBSuffixIPAddressType = "aws-load-balancer-ip-address-type"
SvcLBSuffixAccessLogEnabled = "aws-load-balancer-access-log-enabled"
SvcLBSuffixAccessLogS3BucketName = "aws-load-balancer-access-log-s3-bucket-name"
SvcLBSuffixAccessLogS3BucketPrefix = "aws-load-balancer-access-log-s3-bucket-prefix"
SvcLBSuffixCrossZoneLoadBalancingEnabled = "aws-load-balancer-cross-zone-load-balancing-enabled"
SvcLBSuffixSSLCertificate = "aws-load-balancer-ssl-cert"
SvcLBSuffixSSLPorts = "aws-load-balancer-ssl-ports"
SvcLBSuffixSSLNegotiationPolicy = "aws-load-balancer-ssl-negotiation-policy"
SvcLBSuffixBEProtocol = "aws-load-balancer-backend-protocol"
SvcLBSuffixAdditionalTags = "aws-load-balancer-additional-resource-tags"
SvcLBSuffixHCHealthyThreshold = "aws-load-balancer-healthcheck-healthy-threshold"
SvcLBSuffixHCUnhealthyThreshold = "aws-load-balancer-healthcheck-unhealthy-threshold"
SvcLBSuffixHCTimeout = "aws-load-balancer-healthcheck-timeout"
SvcLBSuffixHCInterval = "aws-load-balancer-healthcheck-interval"
SvcLBSuffixHCProtocol = "aws-load-balancer-healthcheck-protocol"
SvcLBSuffixHCPort = "aws-load-balancer-healthcheck-port"
SvcLBSuffixHCPath = "aws-load-balancer-healthcheck-path"
SvcLBSuffixHCSuccessCodes = "aws-load-balancer-healthcheck-success-codes"
SvcLBSuffixTargetGroupAttributes = "aws-load-balancer-target-group-attributes"
SvcLBSuffixSubnets = "aws-load-balancer-subnets"
SvcLBSuffixEIPAllocations = "aws-load-balancer-eip-allocations"
SvcLBSuffixPrivateIpv4Addresses = "aws-load-balancer-private-ipv4-addresses"
SvcLBSuffixIpv6Addresses = "aws-load-balancer-ipv6-addresses"
SvcLBSuffixALPNPolicy = "aws-load-balancer-alpn-policy"
SvcLBSuffixTargetNodeLabels = "aws-load-balancer-target-node-labels"
SvcLBSuffixLoadBalancerAttributes = "aws-load-balancer-attributes"
SvcLBSuffixLoadBalancerSecurityGroups = "aws-load-balancer-security-groups"
SvcLBSuffixManageSGRules = "aws-load-balancer-manage-backend-security-group-rules"
SvcLBSuffixSourceRanges = "load-balancer-source-ranges"
SvcLBSuffixLoadBalancerType = "aws-load-balancer-type"
SvcLBSuffixTargetType = "aws-load-balancer-nlb-target-type"
SvcLBSuffixLoadBalancerName = "aws-load-balancer-name"
SvcLBSuffixScheme = "aws-load-balancer-scheme"
SvcLBSuffixInternal = "aws-load-balancer-internal"
SvcLBSuffixProxyProtocol = "aws-load-balancer-proxy-protocol"
SvcLBSuffixIPAddressType = "aws-load-balancer-ip-address-type"
SvcLBSuffixAccessLogEnabled = "aws-load-balancer-access-log-enabled"
SvcLBSuffixAccessLogS3BucketName = "aws-load-balancer-access-log-s3-bucket-name"
SvcLBSuffixAccessLogS3BucketPrefix = "aws-load-balancer-access-log-s3-bucket-prefix"
SvcLBSuffixCrossZoneLoadBalancingEnabled = "aws-load-balancer-cross-zone-load-balancing-enabled"
SvcLBSuffixSSLCertificate = "aws-load-balancer-ssl-cert"
SvcLBSuffixSSLPorts = "aws-load-balancer-ssl-ports"
SvcLBSuffixSSLNegotiationPolicy = "aws-load-balancer-ssl-negotiation-policy"
SvcLBSuffixBEProtocol = "aws-load-balancer-backend-protocol"
SvcLBSuffixAdditionalTags = "aws-load-balancer-additional-resource-tags"
SvcLBSuffixHCHealthyThreshold = "aws-load-balancer-healthcheck-healthy-threshold"
SvcLBSuffixHCUnhealthyThreshold = "aws-load-balancer-healthcheck-unhealthy-threshold"
SvcLBSuffixHCTimeout = "aws-load-balancer-healthcheck-timeout"
SvcLBSuffixHCInterval = "aws-load-balancer-healthcheck-interval"
SvcLBSuffixHCProtocol = "aws-load-balancer-healthcheck-protocol"
SvcLBSuffixHCPort = "aws-load-balancer-healthcheck-port"
SvcLBSuffixHCPath = "aws-load-balancer-healthcheck-path"
SvcLBSuffixHCSuccessCodes = "aws-load-balancer-healthcheck-success-codes"
SvcLBSuffixTargetGroupAttributes = "aws-load-balancer-target-group-attributes"
SvcLBSuffixSubnets = "aws-load-balancer-subnets"
SvcLBSuffixEIPAllocations = "aws-load-balancer-eip-allocations"
SvcLBSuffixPrivateIpv4Addresses = "aws-load-balancer-private-ipv4-addresses"
SvcLBSuffixIpv6Addresses = "aws-load-balancer-ipv6-addresses"
SvcLBSuffixALPNPolicy = "aws-load-balancer-alpn-policy"
SvcLBSuffixTargetNodeLabels = "aws-load-balancer-target-node-labels"
SvcLBSuffixLoadBalancerAttributes = "aws-load-balancer-attributes"
SvcLBSuffixLoadBalancerSecurityGroups = "aws-load-balancer-security-groups"
SvcLBSuffixManageSGRules = "aws-load-balancer-manage-backend-security-group-rules"
SvcLBSuffixEnforceSGInboundRulesOnPrivateLinkTraffic = "aws-load-balancer-inbound-sg-rules-on-private-link-traffic"
)
57 changes: 49 additions & 8 deletions pkg/deploy/elbv2/load_balancer_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package elbv2
import (
"context"
"fmt"

awssdk "github.com/aws/aws-sdk-go/aws"
elbv2sdk "github.com/aws/aws-sdk-go/service/elbv2"
"github.com/go-logr/logr"
Expand Down Expand Up @@ -75,6 +76,12 @@ func (m *defaultLoadBalancerManager) Create(ctx context.Context, resLB *elbv2mod
return elbv2model.LoadBalancerStatus{}, err
}

if resLB.Spec.Type == elbv2model.LoadBalancerTypeNetwork && resLB.Spec.SecurityGroupsInboundRulesOnPrivateLink != nil {
if err := m.updateSDKLoadBalancerWithSecurityGroups(ctx, resLB, sdkLB); err != nil {
return elbv2model.LoadBalancerStatus{}, err
}
}

return buildResLoadBalancerStatus(sdkLB), nil
}

Expand Down Expand Up @@ -186,27 +193,39 @@ func (m *defaultLoadBalancerManager) updateSDKLoadBalancerWithSecurityGroups(ctx
}
desiredSecurityGroups := sets.NewString(awssdk.StringValueSlice(securityGroups)...)
currentSecurityGroups := sets.NewString(awssdk.StringValueSlice(sdkLB.LoadBalancer.SecurityGroups)...)
if desiredSecurityGroups.Equal(currentSecurityGroups) {

isEnforceSGInboundRulesOnPrivateLinkUpdated, currentEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic, desiredEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic := isEnforceSGInboundRulesOnPrivateLinkUpdated(resLB, sdkLB)
if desiredSecurityGroups.Equal(currentSecurityGroups) && !isEnforceSGInboundRulesOnPrivateLinkUpdated {
return nil
}

var changeDescriptions []string

if !desiredSecurityGroups.Equal(currentSecurityGroups) {
changeSecurityGroupsDesc := fmt.Sprintf("%v => %v", currentSecurityGroups.List(), desiredSecurityGroups.List())
changeDescriptions = append(changeDescriptions, "changeSecurityGroups", changeSecurityGroupsDesc)
}

req := &elbv2sdk.SetSecurityGroupsInput{
LoadBalancerArn: sdkLB.LoadBalancer.LoadBalancerArn,
SecurityGroups: securityGroups,
}
changeDesc := fmt.Sprintf("%v => %v", currentSecurityGroups.List(), desiredSecurityGroups.List())
m.logger.Info("modifying loadBalancer securityGroups",
"stackID", resLB.Stack().StackID(),
"resourceID", resLB.ID(),
"arn", awssdk.StringValue(sdkLB.LoadBalancer.LoadBalancerArn),
"change", changeDesc)

if isEnforceSGInboundRulesOnPrivateLinkUpdated {
changeEnforceSecurityGroupInboundRulesOnPrivateLinkTrafficDesc := fmt.Sprintf("%v => %v", currentEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic, desiredEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic)
changeDescriptions = append(changeDescriptions, "changeEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic", changeEnforceSecurityGroupInboundRulesOnPrivateLinkTrafficDesc)
req.EnforceSecurityGroupInboundRulesOnPrivateLinkTraffic = &desiredEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic
}

if _, err := m.elbv2Client.SetSecurityGroupsWithContext(ctx, req); err != nil {
return err
}
m.logger.Info("modified loadBalancer securityGroups",
"stackID", resLB.Stack().StackID(),
"resourceID", resLB.ID(),
"arn", awssdk.StringValue(sdkLB.LoadBalancer.LoadBalancerArn))
"arn", awssdk.StringValue(sdkLB.LoadBalancer.LoadBalancerArn),
"changeSecurityGroups", changeDescriptions,
)

return nil
}
Expand Down Expand Up @@ -298,3 +317,25 @@ func buildResLoadBalancerStatus(sdkLB LoadBalancerWithTags) elbv2model.LoadBalan
DNSName: awssdk.StringValue(sdkLB.LoadBalancer.DNSName),
}
}

func isEnforceSGInboundRulesOnPrivateLinkUpdated(resLB *elbv2model.LoadBalancer, sdkLB LoadBalancerWithTags) (bool, string, string) {

if resLB.Spec.Type != elbv2model.LoadBalancerTypeNetwork || resLB.Spec.SecurityGroupsInboundRulesOnPrivateLink == nil {
return false, "", ""
}

desiredEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic := string(*resLB.Spec.SecurityGroupsInboundRulesOnPrivateLink)

var currentEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic string

if sdkLB.LoadBalancer.EnforceSecurityGroupInboundRulesOnPrivateLinkTraffic != nil {
currentEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic = awssdk.StringValue(sdkLB.LoadBalancer.EnforceSecurityGroupInboundRulesOnPrivateLinkTraffic)
}

if desiredEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic == currentEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic {
return false, "", ""
}

return true, currentEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic, desiredEnforceSecurityGroupInboundRulesOnPrivateLinkTraffic

}
12 changes: 12 additions & 0 deletions pkg/model/elbv2/load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package elbv2

import (
"context"

"github.com/pkg/errors"
"sigs.k8s.io/aws-load-balancer-controller/pkg/model/core"
)
Expand Down Expand Up @@ -86,6 +87,13 @@ const (
IPAddressTypeDualStack IPAddressType = "dualstack"
)

type SecurityGroupsInboundRulesOnPrivateLinkStatus string

const (
SecurityGroupsInboundRulesOnPrivateLinkOn SecurityGroupsInboundRulesOnPrivateLinkStatus = "on"
SecurityGroupsInboundRulesOnPrivateLinkOff SecurityGroupsInboundRulesOnPrivateLinkStatus = "off"
)

type LoadBalancerScheme string

const (
Expand Down Expand Up @@ -143,6 +151,10 @@ type LoadBalancerSpec struct {
// +optional
SecurityGroups []core.StringToken `json:"securityGroups,omitempty"`

// [Network Load Balancers] The status of the security groups inbound rules on private link.
// +optional
SecurityGroupsInboundRulesOnPrivateLink *SecurityGroupsInboundRulesOnPrivateLinkStatus `json:"securityGroupsInboundRulesOnPrivateLink,omitempty"`

// [Application Load Balancers on Outposts] The ID of the customer-owned address pool (CoIP pool).
// +optional
CustomerOwnedIPv4Pool *string `json:"customerOwnedIPv4Pool,omitempty"`
Expand Down
27 changes: 27 additions & 0 deletions pkg/service/model_build_load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ func (t *defaultModelBuildTask) buildLoadBalancerSpec(ctx context.Context, schem
if err != nil {
return elbv2model.LoadBalancerSpec{}, err
}
securityGroupsInboundRulesOnPrivateLink, err := t.buildSecurityGroupsInboundRulesOnPrivateLink(ctx)
if err != nil {
return elbv2model.LoadBalancerSpec{}, err
}

spec := elbv2model.LoadBalancerSpec{
Name: name,
Type: elbv2model.LoadBalancerTypeNetwork,
Expand All @@ -87,6 +92,11 @@ func (t *defaultModelBuildTask) buildLoadBalancerSpec(ctx context.Context, schem
LoadBalancerAttributes: lbAttributes,
Tags: tags,
}

if securityGroupsInboundRulesOnPrivateLink != nil {
spec.SecurityGroupsInboundRulesOnPrivateLink = securityGroupsInboundRulesOnPrivateLink
}

return spec, nil
}

Expand Down Expand Up @@ -177,6 +187,23 @@ func (t *defaultModelBuildTask) buildLoadBalancerIPAddressType(_ context.Context
}
}

func (t *defaultModelBuildTask) buildSecurityGroupsInboundRulesOnPrivateLink(_ context.Context) (*elbv2model.SecurityGroupsInboundRulesOnPrivateLinkStatus, error) {
var rawSecurityGroupsInboundRulesOnPrivateLink string
if exists := t.annotationParser.ParseStringAnnotation(annotations.SvcLBSuffixEnforceSGInboundRulesOnPrivateLinkTraffic, &rawSecurityGroupsInboundRulesOnPrivateLink, t.service.Annotations); !exists {
return nil, nil
}
securityGroupsInboundRulesOnPrivateLink := elbv2model.SecurityGroupsInboundRulesOnPrivateLinkStatus(rawSecurityGroupsInboundRulesOnPrivateLink)

switch securityGroupsInboundRulesOnPrivateLink {
case elbv2model.SecurityGroupsInboundRulesOnPrivateLinkOn:
return &securityGroupsInboundRulesOnPrivateLink, nil
case elbv2model.SecurityGroupsInboundRulesOnPrivateLinkOff:
return &securityGroupsInboundRulesOnPrivateLink, nil
default:
return nil, errors.Errorf("Invalid value for securityGroupsInboundRulesOnPrivateLink status: %v, value must be one of [%v, %v]", securityGroupsInboundRulesOnPrivateLink, string(elbv2model.SecurityGroupsInboundRulesOnPrivateLinkOn), string(elbv2model.SecurityGroupsInboundRulesOnPrivateLinkOff))
}
}

func (t *defaultModelBuildTask) buildLoadBalancerScheme(ctx context.Context) (elbv2model.LoadBalancerScheme, error) {
scheme, explicitSchemeSpecified, err := t.buildLoadBalancerSchemeViaAnnotation(ctx)
if err != nil {
Expand Down
7 changes: 6 additions & 1 deletion pkg/service/model_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"sync"

"github.com/aws/aws-sdk-go/service/ec2"
"github.com/go-logr/logr"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets"
Expand Down Expand Up @@ -40,7 +41,7 @@ func NewDefaultModelBuilder(annotationParser annotations.Parser, subnetsResolver
elbv2TaggingManager elbv2deploy.TaggingManager, ec2Client services.EC2, featureGates config.FeatureGates, clusterName string, defaultTags map[string]string,
externalManagedTags []string, defaultSSLPolicy string, defaultTargetType string, enableIPTargetType bool, serviceUtils ServiceUtils,
backendSGProvider networking.BackendSGProvider, sgResolver networking.SecurityGroupResolver, enableBackendSG bool,
disableRestrictedSGRules bool) *defaultModelBuilder {
disableRestrictedSGRules bool, logger logr.Logger) *defaultModelBuilder {
return &defaultModelBuilder{
annotationParser: annotationParser,
subnetsResolver: subnetsResolver,
Expand All @@ -61,6 +62,7 @@ func NewDefaultModelBuilder(annotationParser annotations.Parser, subnetsResolver
ec2Client: ec2Client,
enableBackendSG: enableBackendSG,
disableRestrictedSGRules: disableRestrictedSGRules,
logger: logger,
}
}

Expand All @@ -87,6 +89,7 @@ type defaultModelBuilder struct {
defaultSSLPolicy string
defaultTargetType elbv2model.TargetType
enableIPTargetType bool
logger logr.Logger
}

func (b *defaultModelBuilder) Build(ctx context.Context, service *corev1.Service) (core.Stack, *elbv2model.LoadBalancer, bool, error) {
Expand All @@ -107,6 +110,7 @@ func (b *defaultModelBuilder) Build(ctx context.Context, service *corev1.Service
ec2Client: b.ec2Client,
enableBackendSG: b.enableBackendSG,
disableRestrictedSGRules: b.disableRestrictedSGRules,
logger: b.logger,

service: service,
stack: stack,
Expand Down Expand Up @@ -162,6 +166,7 @@ type defaultModelBuildTask struct {
serviceUtils ServiceUtils
enableIPTargetType bool
ec2Client services.EC2
logger logr.Logger

service *corev1.Service

Expand Down
Loading

0 comments on commit fa60f1e

Please sign in to comment.