Merge pull request #12067 from h3poteto/iss-11608

Support AWS LB access log configuration in cluster spec
This commit is contained in:
Kubernetes Prow Robot 2021-08-25 16:51:23 -07:00 committed by GitHub
commit bb38a3e52e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 293 additions and 8 deletions

View File

@ -81,6 +81,22 @@ spec:
description: LoadBalancer is the configuration for the kube-apiserver description: LoadBalancer is the configuration for the kube-apiserver
ELB ELB
properties: properties:
accessLog:
description: AccessLog is the configuration of access logs
properties:
bucket:
description: Bucket is S3 bucket name to store the logs
in
type: string
bucketPrefix:
description: BucketPrefix is S3 bucket prefix. Logs are
stored in the root if not configured.
type: string
interval:
description: Interval is publishing interval in minutes.
This parameter is only used with classic load balancer.
type: integer
type: object
additionalSecurityGroups: additionalSecurityGroups:
description: AdditionalSecurityGroups attaches additional description: AdditionalSecurityGroups attaches additional
security groups (e.g. sg-123456). security groups (e.g. sg-123456).

View File

@ -414,6 +414,15 @@ const (
LoadBalancerClassNetwork LoadBalancerClass = "Network" LoadBalancerClassNetwork LoadBalancerClass = "Network"
) )
type AccessLogSpec struct {
// Interval is the publishing interval in minutes. This parameter is only used with classic load balancer.
Interval int `json:"interval,omitempty"`
// Bucket is the S3 bucket name to store the logs in.
Bucket string `json:"bucket,omitempty"`
// BucketPrefix is the S3 bucket prefix. Logs are stored in the root if not configured.
BucketPrefix string `json:"bucketPrefix,omitempty"`
}
var SupportedLoadBalancerClasses = []string{ var SupportedLoadBalancerClasses = []string{
string(LoadBalancerClassClassic), string(LoadBalancerClassClassic),
string(LoadBalancerClassNetwork), string(LoadBalancerClassNetwork),
@ -451,6 +460,8 @@ type LoadBalancerAccessSpec struct {
CrossZoneLoadBalancing *bool `json:"crossZoneLoadBalancing,omitempty"` CrossZoneLoadBalancing *bool `json:"crossZoneLoadBalancing,omitempty"`
// Subnets allows you to specify the subnets that must be used for the load balancer // Subnets allows you to specify the subnets that must be used for the load balancer
Subnets []LoadBalancerSubnetSpec `json:"subnets,omitempty"` Subnets []LoadBalancerSubnetSpec `json:"subnets,omitempty"`
// AccessLog is the configuration of access logs.
AccessLog *AccessLogSpec `json:"accessLog,omitempty"`
} }
// KubeDNSConfig defines the kube dns configuration // KubeDNSConfig defines the kube dns configuration

View File

@ -415,6 +415,15 @@ const (
LoadBalancerClassNetwork LoadBalancerClass = "Network" LoadBalancerClassNetwork LoadBalancerClass = "Network"
) )
type AccessLogSpec struct {
// Interval is publishing interval in minutes. This parameter is only used with classic load balancer.
Interval int `json:"interval,omitempty"`
// Bucket is S3 bucket name to store the logs in
Bucket string `json:"bucket,omitempty"`
// BucketPrefix is S3 bucket prefix. Logs are stored in the root if not configured.
BucketPrefix string `json:"bucketPrefix,omitempty"`
}
var SupportedLoadBalancerClasses = []string{ var SupportedLoadBalancerClasses = []string{
string(LoadBalancerClassClassic), string(LoadBalancerClassClassic),
string(LoadBalancerClassNetwork), string(LoadBalancerClassNetwork),
@ -452,6 +461,8 @@ type LoadBalancerAccessSpec struct {
CrossZoneLoadBalancing *bool `json:"crossZoneLoadBalancing,omitempty"` CrossZoneLoadBalancing *bool `json:"crossZoneLoadBalancing,omitempty"`
// Subnets allows you to specify the subnets that must be used for the load balancer // Subnets allows you to specify the subnets that must be used for the load balancer
Subnets []LoadBalancerSubnetSpec `json:"subnets,omitempty"` Subnets []LoadBalancerSubnetSpec `json:"subnets,omitempty"`
// AccessLog is the configuration of access logs
AccessLog *AccessLogSpec `json:"accessLog,omitempty"`
} }
// KubeDNSConfig defines the kube dns configuration // KubeDNSConfig defines the kube dns configuration

View File

@ -63,6 +63,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*AccessLogSpec)(nil), (*kops.AccessLogSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha2_AccessLogSpec_To_kops_AccessLogSpec(a.(*AccessLogSpec), b.(*kops.AccessLogSpec), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kops.AccessLogSpec)(nil), (*AccessLogSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kops_AccessLogSpec_To_v1alpha2_AccessLogSpec(a.(*kops.AccessLogSpec), b.(*AccessLogSpec), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*AccessSpec)(nil), (*kops.AccessSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*AccessSpec)(nil), (*kops.AccessSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha2_AccessSpec_To_kops_AccessSpec(a.(*AccessSpec), b.(*kops.AccessSpec), scope) return Convert_v1alpha2_AccessSpec_To_kops_AccessSpec(a.(*AccessSpec), b.(*kops.AccessSpec), scope)
}); err != nil { }); err != nil {
@ -1194,6 +1204,30 @@ func Convert_kops_AWSPermission_To_v1alpha2_AWSPermission(in *kops.AWSPermission
return autoConvert_kops_AWSPermission_To_v1alpha2_AWSPermission(in, out, s) return autoConvert_kops_AWSPermission_To_v1alpha2_AWSPermission(in, out, s)
} }
func autoConvert_v1alpha2_AccessLogSpec_To_kops_AccessLogSpec(in *AccessLogSpec, out *kops.AccessLogSpec, s conversion.Scope) error {
out.Interval = in.Interval
out.Bucket = in.Bucket
out.BucketPrefix = in.BucketPrefix
return nil
}
// Convert_v1alpha2_AccessLogSpec_To_kops_AccessLogSpec is an autogenerated conversion function.
func Convert_v1alpha2_AccessLogSpec_To_kops_AccessLogSpec(in *AccessLogSpec, out *kops.AccessLogSpec, s conversion.Scope) error {
return autoConvert_v1alpha2_AccessLogSpec_To_kops_AccessLogSpec(in, out, s)
}
func autoConvert_kops_AccessLogSpec_To_v1alpha2_AccessLogSpec(in *kops.AccessLogSpec, out *AccessLogSpec, s conversion.Scope) error {
out.Interval = in.Interval
out.Bucket = in.Bucket
out.BucketPrefix = in.BucketPrefix
return nil
}
// Convert_kops_AccessLogSpec_To_v1alpha2_AccessLogSpec is an autogenerated conversion function.
func Convert_kops_AccessLogSpec_To_v1alpha2_AccessLogSpec(in *kops.AccessLogSpec, out *AccessLogSpec, s conversion.Scope) error {
return autoConvert_kops_AccessLogSpec_To_v1alpha2_AccessLogSpec(in, out, s)
}
func autoConvert_v1alpha2_AccessSpec_To_kops_AccessSpec(in *AccessSpec, out *kops.AccessSpec, s conversion.Scope) error { func autoConvert_v1alpha2_AccessSpec_To_kops_AccessSpec(in *AccessSpec, out *kops.AccessSpec, s conversion.Scope) error {
if in.DNS != nil { if in.DNS != nil {
in, out := &in.DNS, &out.DNS in, out := &in.DNS, &out.DNS
@ -5457,6 +5491,15 @@ func autoConvert_v1alpha2_LoadBalancerAccessSpec_To_kops_LoadBalancerAccessSpec(
} else { } else {
out.Subnets = nil out.Subnets = nil
} }
if in.AccessLog != nil {
in, out := &in.AccessLog, &out.AccessLog
*out = new(kops.AccessLogSpec)
if err := Convert_v1alpha2_AccessLogSpec_To_kops_AccessLogSpec(*in, *out, s); err != nil {
return err
}
} else {
out.AccessLog = nil
}
return nil return nil
} }
@ -5486,6 +5529,15 @@ func autoConvert_kops_LoadBalancerAccessSpec_To_v1alpha2_LoadBalancerAccessSpec(
} else { } else {
out.Subnets = nil out.Subnets = nil
} }
if in.AccessLog != nil {
in, out := &in.AccessLog, &out.AccessLog
*out = new(AccessLogSpec)
if err := Convert_kops_AccessLogSpec_To_v1alpha2_AccessLogSpec(*in, *out, s); err != nil {
return err
}
} else {
out.AccessLog = nil
}
return nil return nil
} }

View File

@ -104,6 +104,22 @@ func (in *AWSPermission) DeepCopy() *AWSPermission {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AccessLogSpec) DeepCopyInto(out *AccessLogSpec) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessLogSpec.
func (in *AccessLogSpec) DeepCopy() *AccessLogSpec {
if in == nil {
return nil
}
out := new(AccessLogSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AccessSpec) DeepCopyInto(out *AccessSpec) { func (in *AccessSpec) DeepCopyInto(out *AccessSpec) {
*out = *in *out = *in
@ -3649,6 +3665,11 @@ func (in *LoadBalancerAccessSpec) DeepCopyInto(out *LoadBalancerAccessSpec) {
(*in)[i].DeepCopyInto(&(*out)[i]) (*in)[i].DeepCopyInto(&(*out)[i])
} }
} }
if in.AccessLog != nil {
in, out := &in.AccessLog, &out.AccessLog
*out = new(AccessLogSpec)
**out = **in
}
return return
} }

View File

@ -104,6 +104,22 @@ func (in *AWSPermission) DeepCopy() *AWSPermission {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AccessLogSpec) DeepCopyInto(out *AccessLogSpec) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessLogSpec.
func (in *AccessLogSpec) DeepCopy() *AccessLogSpec {
if in == nil {
return nil
}
out := new(AccessLogSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AccessSpec) DeepCopyInto(out *AccessSpec) { func (in *AccessSpec) DeepCopyInto(out *AccessSpec) {
*out = *in *out = *in
@ -3831,6 +3847,11 @@ func (in *LoadBalancerAccessSpec) DeepCopyInto(out *LoadBalancerAccessSpec) {
(*in)[i].DeepCopyInto(&(*out)[i]) (*in)[i].DeepCopyInto(&(*out)[i])
} }
} }
if in.AccessLog != nil {
in, out := &in.AccessLog, &out.AccessLog
*out = new(AccessLogSpec)
**out = **in
}
return return
} }

View File

@ -237,6 +237,27 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error {
return fmt.Errorf("unknown load balancer Type: %q", lbSpec.Type) return fmt.Errorf("unknown load balancer Type: %q", lbSpec.Type)
} }
if lbSpec.AccessLog != nil {
clb.AccessLog = &awstasks.ClassicLoadBalancerAccessLog{
EmitInterval: fi.Int64(int64(lbSpec.AccessLog.Interval)),
Enabled: fi.Bool(true),
S3BucketName: fi.String(lbSpec.AccessLog.Bucket),
S3BucketPrefix: fi.String(lbSpec.AccessLog.BucketPrefix),
}
nlb.AccessLog = &awstasks.NetworkLoadBalancerAccessLog{
Enabled: fi.Bool(true),
S3BucketName: fi.String(lbSpec.AccessLog.Bucket),
S3BucketPrefix: fi.String(lbSpec.AccessLog.BucketPrefix),
}
} else {
clb.AccessLog = &awstasks.ClassicLoadBalancerAccessLog{
Enabled: fi.Bool(false),
}
nlb.AccessLog = &awstasks.NetworkLoadBalancerAccessLog{
Enabled: fi.Bool(false),
}
}
if b.APILoadBalancerClass() == kops.LoadBalancerClassClassic { if b.APILoadBalancerClass() == kops.LoadBalancerClassClassic {
c.AddTask(clb) c.AddTask(clb)
} else if b.APILoadBalancerClass() == kops.LoadBalancerClassNetwork { } else if b.APILoadBalancerClass() == kops.LoadBalancerClassNetwork {

View File

@ -1458,6 +1458,20 @@
"Key": "kubernetes.io/cluster/complex.example.com", "Key": "kubernetes.io/cluster/complex.example.com",
"Value": "owned" "Value": "owned"
} }
],
"LoadBalancerAttributes": [
{
"Key": "access_logs.s3.enabled",
"Value": "true"
},
{
"Key": "access_logs.s3.bucket",
"Value": "access-log-example"
},
{
"Key": "access_logs.s3.prefix",
"Value": ""
}
] ]
} }
}, },

View File

@ -9,6 +9,8 @@ spec:
- 10.2.0.0/16 - 10.2.0.0/16
api: api:
loadBalancer: loadBalancer:
accessLog:
bucket: access-log-example
additionalSecurityGroups: additionalSecurityGroups:
- sg-exampleid5 - sg-exampleid5
- sg-exampleid6 - sg-exampleid6

View File

@ -17,6 +17,8 @@ spec:
subnets: subnets:
- name: us-test-1a - name: us-test-1a
allocationId: eipalloc-012345a678b9cdefa allocationId: eipalloc-012345a678b9cdefa
accessLog:
bucket: access-log-example
kubernetesApiAccess: kubernetesApiAccess:
- 1.1.1.0/24 - 1.1.1.0/24
channel: stable channel: stable

View File

@ -17,6 +17,8 @@ spec:
subnets: subnets:
- name: us-test-1a - name: us-test-1a
allocationId: eipalloc-012345a678b9cdefa allocationId: eipalloc-012345a678b9cdefa
accessLog:
bucket: access-log-example
kubernetesApiAccess: kubernetesApiAccess:
- 1.1.1.0/24 - 1.1.1.0/24
channel: stable channel: stable

View File

@ -523,6 +523,11 @@ resource "aws_launch_template" "nodes-complex-example-com" {
} }
resource "aws_lb" "api-complex-example-com" { resource "aws_lb" "api-complex-example-com" {
access_logs {
bucket = "access-log-example"
enabled = true
prefix = ""
}
enable_cross_zone_load_balancing = true enable_cross_zone_load_balancing = true
internal = false internal = false
load_balancer_type = "network" load_balancer_type = "network"

View File

@ -716,7 +716,7 @@ func (_ *ClassicLoadBalancer) RenderTerraform(t *terraform.TerraformTarget, a, e
} }
} }
if e.AccessLog != nil { if e.AccessLog != nil && fi.BoolValue(e.AccessLog.Enabled) {
tf.AccessLog = &terraformLoadBalancerAccessLog{ tf.AccessLog = &terraformLoadBalancerAccessLog{
EmitInterval: e.AccessLog.EmitInterval, EmitInterval: e.AccessLog.EmitInterval,
Enabled: e.AccessLog.Enabled, Enabled: e.AccessLog.Enabled,
@ -856,7 +856,7 @@ func (_ *ClassicLoadBalancer) RenderCloudformation(t *cloudformation.Cloudformat
} }
} }
if e.AccessLog != nil { if e.AccessLog != nil && fi.BoolValue(e.AccessLog.Enabled) {
tf.AccessLog = &cloudformationClassicLoadBalancerAccessLog{ tf.AccessLog = &cloudformationClassicLoadBalancerAccessLog{
EmitInterval: e.AccessLog.EmitInterval, EmitInterval: e.AccessLog.EmitInterval,
Enabled: e.AccessLog.Enabled, Enabled: e.AccessLog.Enabled,

View File

@ -153,6 +153,9 @@ func (_ *ClassicLoadBalancer) modifyLoadBalancerAttributes(t *awsup.AWSAPITarget
// request.LoadBalancerAttributes.AdditionalAttributes = additionalAttributes // request.LoadBalancerAttributes.AdditionalAttributes = additionalAttributes
//} //}
if e.AccessLog != nil && e.AccessLog.Enabled != nil {
request.LoadBalancerAttributes.AccessLog.Enabled = e.AccessLog.Enabled
}
if e.AccessLog != nil && e.AccessLog.EmitInterval != nil { if e.AccessLog != nil && e.AccessLog.EmitInterval != nil {
request.LoadBalancerAttributes.AccessLog.EmitInterval = e.AccessLog.EmitInterval request.LoadBalancerAttributes.AccessLog.EmitInterval = e.AccessLog.EmitInterval
} }

View File

@ -69,6 +69,7 @@ type NetworkLoadBalancer struct {
VPC *VPC VPC *VPC
TargetGroups []*TargetGroup TargetGroups []*TargetGroup
AccessLog *NetworkLoadBalancerAccessLog
} }
var _ fi.CompareWithID = &NetworkLoadBalancer{} var _ fi.CompareWithID = &NetworkLoadBalancer{}
@ -365,6 +366,25 @@ func (e *NetworkLoadBalancer) Find(c *fi.Context) (*NetworkLoadBalancer, error)
return nil, err return nil, err
} }
actual.CrossZoneLoadBalancing = fi.Bool(b) actual.CrossZoneLoadBalancing = fi.Bool(b)
case "access_logs.s3.enabled":
b, err := strconv.ParseBool(*value)
if err != nil {
return nil, err
}
if actual.AccessLog == nil {
actual.AccessLog = &NetworkLoadBalancerAccessLog{}
}
actual.AccessLog.Enabled = fi.Bool(b)
case "access_logs.s3.bucket":
if actual.AccessLog == nil {
actual.AccessLog = &NetworkLoadBalancerAccessLog{}
}
actual.AccessLog.S3BucketName = value
case "access_logs.s3.prefix":
if actual.AccessLog == nil {
actual.AccessLog = &NetworkLoadBalancerAccessLog{}
}
actual.AccessLog.S3BucketPrefix = value
default: default:
klog.V(2).Infof("unsupported key -- ignoring, %v.\n", key) klog.V(2).Infof("unsupported key -- ignoring, %v.\n", key)
} }
@ -454,6 +474,17 @@ func (s *NetworkLoadBalancer) CheckChanges(a, e, changes *NetworkLoadBalancer) e
return fi.RequiredField("CrossZoneLoadBalancing") return fi.RequiredField("CrossZoneLoadBalancing")
} }
} }
if e.AccessLog != nil {
if e.AccessLog.Enabled == nil {
return fi.RequiredField("Accesslog.Enabled")
}
if *e.AccessLog.Enabled {
if e.AccessLog.S3BucketName == nil {
return fi.RequiredField("Accesslog.S3Bucket")
}
}
}
} else { } else {
if len(changes.SubnetMappings) > 0 { if len(changes.SubnetMappings) > 0 {
expectedSubnets := make(map[string]*string) expectedSubnets := make(map[string]*string)
@ -666,6 +697,7 @@ type terraformNetworkLoadBalancer struct {
Type string `json:"load_balancer_type" cty:"load_balancer_type"` Type string `json:"load_balancer_type" cty:"load_balancer_type"`
SubnetMappings []terraformNetworkLoadBalancerSubnetMapping `json:"subnet_mapping" cty:"subnet_mapping"` SubnetMappings []terraformNetworkLoadBalancerSubnetMapping `json:"subnet_mapping" cty:"subnet_mapping"`
CrossZoneLoadBalancing bool `json:"enable_cross_zone_load_balancing" cty:"enable_cross_zone_load_balancing"` CrossZoneLoadBalancing bool `json:"enable_cross_zone_load_balancing" cty:"enable_cross_zone_load_balancing"`
AccessLog *terraformNetworkLoadBalancerAccessLog `json:"access_logs,omitempty" cty:"access_logs"`
Tags map[string]string `json:"tags" cty:"tags"` Tags map[string]string `json:"tags" cty:"tags"`
} }
@ -707,6 +739,14 @@ func (_ *NetworkLoadBalancer) RenderTerraform(t *terraform.TerraformTarget, a, e
}) })
} }
if e.AccessLog != nil && fi.BoolValue(e.AccessLog.Enabled) {
nlbTF.AccessLog = &terraformNetworkLoadBalancerAccessLog{
Enabled: e.AccessLog.Enabled,
S3BucketName: e.AccessLog.S3BucketName,
S3BucketPrefix: e.AccessLog.S3BucketPrefix,
}
}
err := t.RenderResource("aws_lb", *e.Name, nlbTF) err := t.RenderResource("aws_lb", *e.Name, nlbTF)
if err != nil { if err != nil {
return err return err
@ -748,6 +788,7 @@ func (_ *NetworkLoadBalancer) RenderTerraform(t *terraform.TerraformTarget, a, e
return err return err
} }
} }
return nil return nil
} }
@ -760,11 +801,12 @@ func (e *NetworkLoadBalancer) TerraformLink(params ...string) *terraformWriter.L
} }
type cloudformationNetworkLoadBalancer struct { type cloudformationNetworkLoadBalancer struct {
Name string `json:"Name"` Name string `json:"Name"`
Scheme string `json:"Scheme"` Scheme string `json:"Scheme"`
SubnetMappings []*cloudformationSubnetMapping `json:"SubnetMappings"` SubnetMappings []*cloudformationSubnetMapping `json:"SubnetMappings"`
Type string `json:"Type"` Type string `json:"Type"`
Tags []cloudformationTag `json:"Tags"` Tags []cloudformationTag `json:"Tags"`
LoadBalancerAttributes []cloudformationLoadBalancerAttribute `json:"LoadBalancerAttributes,omitempty"`
} }
type cloudformationSubnetMapping struct { type cloudformationSubnetMapping struct {
@ -773,6 +815,11 @@ type cloudformationSubnetMapping struct {
PrivateIPv4Address *string `json:"PrivateIPv4Address,omitempty"` PrivateIPv4Address *string `json:"PrivateIPv4Address,omitempty"`
} }
type cloudformationLoadBalancerAttribute struct {
Key *string `json:"Key"`
Value *string `json:"Value,omitempty"`
}
type cloudformationNetworkLoadBalancerListener struct { type cloudformationNetworkLoadBalancerListener struct {
Certificates []cloudformationNetworkLoadBalancerListenerCertificate `json:"Certificates,omitempty"` Certificates []cloudformationNetworkLoadBalancerListenerCertificate `json:"Certificates,omitempty"`
DefaultActions []cloudformationNetworkLoadBalancerListenerAction `json:"DefaultActions"` DefaultActions []cloudformationNetworkLoadBalancerListenerAction `json:"DefaultActions"`
@ -809,6 +856,25 @@ func (_ *NetworkLoadBalancer) RenderCloudformation(t *cloudformation.Cloudformat
} else { } else {
nlbCF.Scheme = elbv2.LoadBalancerSchemeEnumInternetFacing nlbCF.Scheme = elbv2.LoadBalancerSchemeEnumInternetFacing
} }
if e.AccessLog != nil && *e.AccessLog.Enabled {
var attributes []cloudformationLoadBalancerAttribute
attributes = append(attributes, cloudformationLoadBalancerAttribute{
Key: aws.String("access_logs.s3.enabled"),
Value: aws.String(strconv.FormatBool(aws.BoolValue(e.AccessLog.Enabled))),
})
attributes = append(attributes, cloudformationLoadBalancerAttribute{
Key: aws.String("access_logs.s3.bucket"),
Value: e.AccessLog.S3BucketName,
})
attributes = append(attributes, cloudformationLoadBalancerAttribute{
Key: aws.String("access_logs.s3.prefix"),
Value: e.AccessLog.S3BucketPrefix,
})
nlbCF.LoadBalancerAttributes = attributes
}
err := t.RenderResource("AWS::ElasticLoadBalancingV2::LoadBalancer", *e.Name, nlbCF) err := t.RenderResource("AWS::ElasticLoadBalancingV2::LoadBalancer", *e.Name, nlbCF)
if err != nil { if err != nil {
return err return err

View File

@ -27,6 +27,22 @@ import (
"k8s.io/kops/upup/pkg/fi/cloudup/awsup" "k8s.io/kops/upup/pkg/fi/cloudup/awsup"
) )
type NetworkLoadBalancerAccessLog struct {
Enabled *bool
S3BucketName *string
S3BucketPrefix *string
}
func (_ *NetworkLoadBalancerAccessLog) GetDependencies(tasks map[string]fi.Task) []fi.Task {
return nil
}
type terraformNetworkLoadBalancerAccessLog struct {
Enabled *bool `json:"enabled,omitempty" cty:"enabled"`
S3BucketName *string `json:"bucket,omitempty" cty:"bucket"`
S3BucketPrefix *string `json:"bucket_prefix,omitempty" cty:"prefix"`
}
func findNetworkLoadBalancerAttributes(cloud awsup.AWSCloud, LoadBalancerArn string) ([]*elbv2.LoadBalancerAttribute, error) { func findNetworkLoadBalancerAttributes(cloud awsup.AWSCloud, LoadBalancerArn string) ([]*elbv2.LoadBalancerAttribute, error) {
request := &elbv2.DescribeLoadBalancerAttributesInput{ request := &elbv2.DescribeLoadBalancerAttributesInput{
@ -52,7 +68,7 @@ func findNetworkLoadBalancerAttributes(cloud awsup.AWSCloud, LoadBalancerArn str
} }
func (_ *NetworkLoadBalancer) modifyLoadBalancerAttributes(t *awsup.AWSAPITarget, a, e, changes *NetworkLoadBalancer, loadBalancerArn string) error { func (_ *NetworkLoadBalancer) modifyLoadBalancerAttributes(t *awsup.AWSAPITarget, a, e, changes *NetworkLoadBalancer, loadBalancerArn string) error {
if changes.CrossZoneLoadBalancing == nil { if changes.CrossZoneLoadBalancing == nil && changes.AccessLog == nil {
klog.V(4).Infof("No LoadBalancerAttribute changes; skipping update") klog.V(4).Infof("No LoadBalancerAttribute changes; skipping update")
return nil return nil
} }
@ -74,6 +90,28 @@ func (_ *NetworkLoadBalancer) modifyLoadBalancerAttributes(t *awsup.AWSAPITarget
} }
attributes = append(attributes, attribute) attributes = append(attributes, attribute)
if e.AccessLog != nil {
attr := &elbv2.LoadBalancerAttribute{
Key: aws.String("access_logs.s3.enabled"),
Value: aws.String(strconv.FormatBool(aws.BoolValue(e.AccessLog.Enabled))),
}
attributes = append(attributes, attr)
}
if e.AccessLog != nil && e.AccessLog.S3BucketName != nil {
attr := &elbv2.LoadBalancerAttribute{
Key: aws.String("access_logs.s3.bucket"),
Value: e.AccessLog.S3BucketName,
}
attributes = append(attributes, attr)
}
if e.AccessLog != nil && e.AccessLog.S3BucketPrefix != nil {
attr := &elbv2.LoadBalancerAttribute{
Key: aws.String("access_logs.s3.prefix"),
Value: e.AccessLog.S3BucketPrefix,
}
attributes = append(attributes, attr)
}
request.Attributes = attributes request.Attributes = attributes
klog.V(2).Infof("Configuring NLB attributes for NLB %q", loadBalancerName) klog.V(2).Infof("Configuring NLB attributes for NLB %q", loadBalancerName)