Skip to content

Commit

Permalink
feat(aws): add PolicyNames for ELB to change listener's security policy
Browse files Browse the repository at this point in the history
  • Loading branch information
FrankYang0529 committed Aug 11, 2020
1 parent 40d9dbc commit 9cf770e
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 16 deletions.
6 changes: 4 additions & 2 deletions docs/cluster_spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The `Cluster` resource contains the specification of the cluster itself.

The complete list of keys can be found at the [Cluster](https://pkg.go.dev/k8s.io/kops/pkg/apis/kops#ClusterSpec) reference page.
The complete list of keys can be found at the [Cluster](https://pkg.go.dev/k8s.io/kops/pkg/apis/kops#ClusterSpec) reference page.

On this page, we will expand on the more important configuration keys.

Expand Down Expand Up @@ -48,14 +48,16 @@ spec:
idleTimeoutSeconds: 300
```

You can use a valid SSL Certificate for your API Server Load Balancer. Currently, only AWS is supported:
You can use a valid SSL Certificate for your API Server Load Balancer. Also, you can change listener's [security policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies) by `listenerPolices`. Currently, only AWS is supported:

```yaml
spec:
api:
loadBalancer:
type: Public
sslCertificate: arn:aws:acm:<region>:<accountId>:certificate/<uuid>
listenerPolicies:
- ELBSecurityPolicy-TLS-1-2-2017-01
```

*Openstack only*
Expand Down
6 changes: 6 additions & 0 deletions k8s/crds/kops.k8s.io_clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ spec:
loadbalancer.
format: int64
type: integer
listenerPolices:
description: ListenerPolices allows you to overwrite ELB listener's
Security Policy
items:
type: string
type: array
securityGroupOverride:
description: SecurityGroupOverride overrides the default Kops
created SG for the load balancer.
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kops/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ type LoadBalancerAccessSpec struct {
UseForInternalApi bool `json:"useForInternalApi,omitempty"`
// SSLCertificate allows you to specify the ACM cert to be used the LB
SSLCertificate string `json:"sslCertificate,omitempty"`
// ListenerPolices allows you to overwrite ELB listener's Security Policy
ListenerPolices []string `json:"listenerPolices,omitempty"`
// CrossZoneLoadBalancing allows you to enable the cross zone load balancing
CrossZoneLoadBalancing *bool `json:"crossZoneLoadBalancing,omitempty"`
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kops/v1alpha2/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ type LoadBalancerAccessSpec struct {
UseForInternalApi bool `json:"useForInternalApi,omitempty"`
// SSLCertificate allows you to specify the ACM cert to be used the LB
SSLCertificate string `json:"sslCertificate,omitempty"`
// ListenerPolices allows you to overwrite ELB listener's Security Policy
ListenerPolices []string `json:"listenerPolices,omitempty"`
// CrossZoneLoadBalancing allows you to enable the cross zone load balancing
CrossZoneLoadBalancing *bool `json:"crossZoneLoadBalancing,omitempty"`
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kops/v1alpha2/zz_generated.conversion.go

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

5 changes: 5 additions & 0 deletions pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go

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

5 changes: 5 additions & 0 deletions pkg/apis/kops/zz_generated.deepcopy.go

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

3 changes: 3 additions & 0 deletions pkg/model/awsmodel/api_loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error {

if lbSpec.SSLCertificate != "" {
listeners["443"] = &awstasks.LoadBalancerListener{InstancePort: 443, SSLCertificateID: lbSpec.SSLCertificate}
if len(lbSpec.ListenerPolices) != 0 {
listeners["443"].PolicyNames = lbSpec.ListenerPolices
}
}

if lbSpec.SecurityGroupOverride != nil {
Expand Down
70 changes: 56 additions & 14 deletions upup/pkg/fi/cloudup/awstasks/load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,31 @@ func (e *LoadBalancer) CompareWithID() *string {
type LoadBalancerListener struct {
InstancePort int
SSLCertificateID string
PolicyNames []string
}

func (e *LoadBalancerListener) mapToAWS(loadBalancerPort int64) *elb.Listener {
l := &elb.Listener{
LoadBalancerPort: aws.Int64(loadBalancerPort),
InstancePort: aws.Int64(int64(e.InstancePort)),
func (e *LoadBalancerListener) mapToAWS(loadBalancerPort int64) *elb.ListenerDescription {
ld := &elb.ListenerDescription{
Listener: &elb.Listener{
LoadBalancerPort: aws.Int64(loadBalancerPort),
InstancePort: aws.Int64(int64(e.InstancePort)),
},
PolicyNames: []*string{},
}

if e.SSLCertificateID != "" {
l.Protocol = aws.String("SSL")
l.InstanceProtocol = aws.String("SSL")
l.SSLCertificateId = aws.String(e.SSLCertificateID)
ld.Listener.Protocol = aws.String("SSL")
ld.Listener.InstanceProtocol = aws.String("SSL")
ld.Listener.SSLCertificateId = aws.String(e.SSLCertificateID)
for _, p := range e.PolicyNames {
ld.PolicyNames = append(ld.PolicyNames, aws.String(p))
}
} else {
l.Protocol = aws.String("TCP")
l.InstanceProtocol = aws.String("TCP")
ld.Listener.Protocol = aws.String("TCP")
ld.Listener.InstanceProtocol = aws.String("TCP")
}

return l
return ld
}

var _ fi.HasDependencies = &LoadBalancerListener{}
Expand Down Expand Up @@ -506,8 +513,8 @@ func (_ *LoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *LoadBalan
if err != nil {
return fmt.Errorf("error parsing load balancer listener port: %q", loadBalancerPort)
}
awsListener := listener.mapToAWS(loadBalancerPortInt)
request.Listeners = append(request.Listeners, awsListener)
awsListenerDescription := listener.mapToAWS(loadBalancerPortInt)
request.Listeners = append(request.Listeners, awsListenerDescription.Listener)
}

klog.V(2).Infof("Creating ELB with Name:%q", loadBalancerName)
Expand All @@ -529,6 +536,24 @@ func (_ *LoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *LoadBalan
return fmt.Errorf("Unable to find newly created ELB %q", loadBalancerName)
}
e.HostedZoneId = lb.CanonicalHostedZoneNameID

// Set ELB listener's Security Policy
if l, ok := e.Listeners["443"]; ok && len(l.PolicyNames) != 0 {
policyNames := []*string{}
for _, p := range l.PolicyNames {
policyNames = append(policyNames, aws.String(p))
}

klog.V(2).Infof("Updating LoadBalancer listener's security policy")
_, err = t.Cloud.ELB().SetLoadBalancerPoliciesOfListener(&elb.SetLoadBalancerPoliciesOfListenerInput{
LoadBalancerName: aws.String(loadBalancerName),
LoadBalancerPort: aws.Int64(443),
PolicyNames: policyNames,
})
if err != nil {
return fmt.Errorf("error updating load balancer listener's security policy: %v", err)
}
}
} else {
loadBalancerName = fi.StringValue(a.LoadBalancerName)

Expand Down Expand Up @@ -604,8 +629,8 @@ func (_ *LoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *LoadBalan
if err != nil {
return fmt.Errorf("error parsing load balancer listener port: %q", loadBalancerPort)
}
awsListener := listener.mapToAWS(loadBalancerPortInt)
request.Listeners = append(request.Listeners, awsListener)
awsListenerDescription := listener.mapToAWS(loadBalancerPortInt)
request.Listeners = append(request.Listeners, awsListenerDescription.Listener)
}

klog.V(2).Infof("Creating LoadBalancer listeners")
Expand All @@ -614,6 +639,23 @@ func (_ *LoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *LoadBalan
if err != nil {
return fmt.Errorf("error creating LoadBalancerListeners: %v", err)
}

if l, ok := changes.Listeners["443"]; ok && len(l.PolicyNames) != 0 {
policyNames := []*string{}
for _, p := range l.PolicyNames {
policyNames = append(policyNames, aws.String(p))
}

klog.V(2).Infof("Updating LoadBalancer listener's security policy")
_, err = t.Cloud.ELB().SetLoadBalancerPoliciesOfListener(&elb.SetLoadBalancerPoliciesOfListenerInput{
LoadBalancerName: aws.String(loadBalancerName),
LoadBalancerPort: aws.Int64(443),
PolicyNames: policyNames,
})
if err != nil {
return fmt.Errorf("error updating load balancer listener's security policy: %v", err)
}
}
}
}

Expand Down

0 comments on commit 9cf770e

Please sign in to comment.