@@ -4,6 +4,11 @@ import (
4
4
"context"
5
5
"fmt"
6
6
7
+ "k8s.io/apimachinery/pkg/util/sets"
8
+
9
+ "github.com/kubernetes-sigs/aws-alb-ingress-controller/internal/ingress/annotations/parser"
10
+ "github.com/pkg/errors"
11
+
7
12
"github.com/kubernetes-sigs/aws-alb-ingress-controller/internal/ingress/auth"
8
13
9
14
"github.com/aws/aws-sdk-go/aws/awsutil"
@@ -18,6 +23,15 @@ import (
18
23
extensions "k8s.io/api/extensions/v1beta1"
19
24
)
20
25
26
+ const (
27
+ AnnotationSSLPolicy = "ssl-policy"
28
+ AnnotationCertificateARN = "certificate-arn"
29
+ )
30
+
31
+ const (
32
+ DefaultSSLPolicy = "ELBSecurityPolicy-2016-08"
33
+ )
34
+
21
35
type ReconcileOptions struct {
22
36
LBArn string
23
37
Ingress * extensions.Ingress
@@ -52,9 +66,11 @@ type defaultController struct {
52
66
type listenerConfig struct {
53
67
Port * int64
54
68
Protocol * string
55
- SslPolicy * string
56
- Certificates []* elbv2.Certificate
57
69
DefaultActions []* elbv2.Action
70
+
71
+ SslPolicy * string
72
+ DefaultCertificate []* elbv2.Certificate
73
+ ExtraCertificateARNs []string
58
74
}
59
75
60
76
func (controller * defaultController ) Reconcile (ctx context.Context , options ReconcileOptions ) error {
@@ -73,6 +89,14 @@ func (controller *defaultController) Reconcile(ctx context.Context, options Reco
73
89
return fmt .Errorf ("failed to reconcile listener due to %v" , err )
74
90
}
75
91
}
92
+
93
+ if options .Port .Scheme == elbv2 .ProtocolEnumHttps {
94
+ lsArn := aws .StringValue (instance .ListenerArn )
95
+ if err := controller .reconcileExtraCertificates (ctx , lsArn , config .ExtraCertificateARNs ); err != nil {
96
+ return errors .Wrapf (err , "failed to reconcile extra certificates on listener %v" , lsArn )
97
+ }
98
+ }
99
+
76
100
if err := controller .rulesController .Reconcile (ctx , instance , options .Ingress , options .IngressAnnos , options .TGGroup ); err != nil {
77
101
return fmt .Errorf ("failed to reconcile rules due to %v" , err )
78
102
}
@@ -85,7 +109,7 @@ func (controller *defaultController) newLSInstance(ctx context.Context, lbArn st
85
109
LoadBalancerArn : aws .String (lbArn ),
86
110
Port : config .Port ,
87
111
Protocol : config .Protocol ,
88
- Certificates : config .Certificates ,
112
+ Certificates : config .DefaultCertificate ,
89
113
SslPolicy : config .SslPolicy ,
90
114
DefaultActions : config .DefaultActions ,
91
115
})
@@ -102,7 +126,7 @@ func (controller *defaultController) reconcileLSInstance(ctx context.Context, in
102
126
ListenerArn : instance .ListenerArn ,
103
127
Port : config .Port ,
104
128
Protocol : config .Protocol ,
105
- Certificates : config .Certificates ,
129
+ Certificates : config .DefaultCertificate ,
106
130
SslPolicy : config .SslPolicy ,
107
131
DefaultActions : config .DefaultActions ,
108
132
})
@@ -124,8 +148,8 @@ func (controller *defaultController) LSInstanceNeedsModification(ctx context.Con
124
148
albctx .GetLogger (ctx ).DebugLevelf (1 , "listener protocol needs modification: %v => %v" , awsutil .Prettify (instance .Protocol ), awsutil .Prettify (config .Protocol ))
125
149
needModification = true
126
150
}
127
- if ! util .DeepEqual (instance .Certificates , config .Certificates ) {
128
- albctx .GetLogger (ctx ).DebugLevelf (1 , "listener certificates needs modification: %v => %v" , awsutil .Prettify (instance .Certificates ), awsutil .Prettify (config .Certificates ))
151
+ if ! util .DeepEqual (instance .Certificates , config .DefaultCertificate ) {
152
+ albctx .GetLogger (ctx ).DebugLevelf (1 , "listener certificates needs modification: %v => %v" , awsutil .Prettify (instance .Certificates ), awsutil .Prettify (config .DefaultCertificate ))
129
153
needModification = true
130
154
}
131
155
if ! util .DeepEqual (instance .SslPolicy , config .SslPolicy ) {
@@ -139,22 +163,71 @@ func (controller *defaultController) LSInstanceNeedsModification(ctx context.Con
139
163
return needModification
140
164
}
141
165
166
+ func (controller * defaultController ) reconcileExtraCertificates (ctx context.Context , lsArn string , extraCertificateARNs []string ) error {
167
+ certificates , err := controller .cloud .DescribeListenerCertificates (ctx , lsArn )
168
+ if err != nil {
169
+ return err
170
+ }
171
+ actualExtraCertificateArns := sets .NewString ()
172
+ for _ , certificate := range certificates {
173
+ if ! aws .BoolValue (certificate .IsDefault ) {
174
+ actualExtraCertificateArns .Insert (aws .StringValue (certificate .CertificateArn ))
175
+ }
176
+ }
177
+ desiredExtraCertificateArns := sets .NewString (extraCertificateARNs ... )
178
+
179
+ certificatesToAdd := desiredExtraCertificateArns .Difference (actualExtraCertificateArns )
180
+ certificatesToRemove := actualExtraCertificateArns .Difference (desiredExtraCertificateArns )
181
+ for certARN := range certificatesToAdd {
182
+ albctx .GetLogger (ctx ).Infof ("adding certificate %v to listener %v" , certARN , lsArn )
183
+ if _ , err := controller .cloud .AddListenerCertificates (ctx , & elbv2.AddListenerCertificatesInput {
184
+ ListenerArn : aws .String (lsArn ),
185
+ Certificates : []* elbv2.Certificate {
186
+ {
187
+ CertificateArn : aws .String (certARN ),
188
+ },
189
+ },
190
+ }); err != nil {
191
+ return err
192
+ }
193
+ }
194
+ for certARN := range certificatesToRemove {
195
+ albctx .GetLogger (ctx ).Infof ("removing certificate %v from listener %v" , certARN , lsArn )
196
+ if _ , err := controller .cloud .RemoveListenerCertificates (ctx , & elbv2.RemoveListenerCertificatesInput {
197
+ ListenerArn : aws .String (lsArn ),
198
+ Certificates : []* elbv2.Certificate {
199
+ {
200
+ CertificateArn : aws .String (certARN ),
201
+ },
202
+ },
203
+ }); err != nil {
204
+ return err
205
+ }
206
+ }
207
+ return nil
208
+ }
209
+
142
210
func (controller * defaultController ) buildListenerConfig (ctx context.Context , options ReconcileOptions ) (listenerConfig , error ) {
143
211
config := listenerConfig {
144
212
Port : aws .Int64 (options .Port .Port ),
145
213
Protocol : aws .String (options .Port .Scheme ),
146
214
}
147
215
if options .Port .Scheme == elbv2 .ProtocolEnumHttps {
148
- if options .IngressAnnos .Listener .CertificateArn != nil {
149
- config .Certificates = []* elbv2.Certificate {
150
- {
151
- CertificateArn : options .IngressAnnos .Listener .CertificateArn ,
152
- },
153
- }
216
+ sslPolicy := DefaultSSLPolicy
217
+ _ = annotations .LoadStringAnnotation (AnnotationSSLPolicy , & sslPolicy , options .Ingress .Annotations )
218
+ config .SslPolicy = aws .String (sslPolicy )
219
+
220
+ var certificateARNs []string
221
+ _ = annotations .LoadStringSliceAnnotation (AnnotationCertificateARN , & certificateARNs , options .Ingress .Annotations )
222
+ if len (certificateARNs ) == 0 {
223
+ return config , errors .Errorf ("annotation %v must be specified for https listener" , parser .GetAnnotationWithPrefix (AnnotationCertificateARN ))
154
224
}
155
- if options .IngressAnnos .Listener .SslPolicy != nil {
156
- config .SslPolicy = options .IngressAnnos .Listener .SslPolicy
225
+ config .DefaultCertificate = []* elbv2.Certificate {
226
+ {
227
+ CertificateArn : aws .String (certificateARNs [0 ]),
228
+ },
157
229
}
230
+ config .ExtraCertificateARNs = certificateARNs [1 :]
158
231
}
159
232
160
233
actions , err := controller .buildDefaultActions (ctx , options )
0 commit comments