@@ -266,31 +266,59 @@ func (controller *defaultController) buildDefaultActions(ctx context.Context, op
266
266
}
267
267
268
268
// inferCertARNs retrieves a set of certificates from ACM that matches the ingress' hosts list
269
+ // If multiple or none certificate were found for specific host, an error will be issued.
269
270
func (controller * defaultController ) inferCertARNs (ctx context.Context , ingress * extensions.Ingress ) ([]string , error ) {
270
271
var ingressHosts = uniqueHosts (ingress )
271
- certArns := sets . NewString ()
272
-
273
- logger := albctx . GetLogger ( ctx )
272
+ if len ( ingressHosts ) == 0 {
273
+ return nil , nil
274
+ }
274
275
275
- certs , err := controller .cloud . ListCertificates ([] string { acm . CertificateStatusIssued } )
276
+ domainsByCertArn , err := controller .loadDomainsByCertArn ( ctx )
276
277
if err != nil {
277
278
return nil , err
278
279
}
279
280
280
- for _ , c := range certs {
281
- for _ , h := range ingressHosts {
282
- if domainMatchesHost (aws .StringValue (c .DomainName ), h ) {
283
- logger .Infof ("Domain name '%s', matches TLS host '%v', adding to Listener" , aws .StringValue (c .DomainName ), h )
284
- certArns .Insert (aws .StringValue (c .CertificateArn ))
285
- } else {
286
- logger .Debugf ("Ignoring domain name '%s', doesn't match '%s'" , aws .StringValue (c .DomainName ), h )
281
+ certArns := sets .NewString ()
282
+ for host := range ingressHosts {
283
+ certArnsForHost := sets .NewString ()
284
+ for certArn , domains := range domainsByCertArn {
285
+ for _ , domain := range domains {
286
+ if domainMatchesHost (domain , host ) {
287
+ certArnsForHost .Insert (certArn )
288
+ break
289
+ }
287
290
}
288
291
}
292
+ if len (certArnsForHost ) > 1 {
293
+ return nil , errors .Errorf ("multiple certificate found for host: %s, certARNs: %v" , host , certArnsForHost .List ())
294
+ }
295
+ if len (certArnsForHost ) == 0 {
296
+ return nil , errors .Errorf ("none certificate found for host: %s" , host )
297
+ }
298
+ certArns = certArns .Union (certArnsForHost )
289
299
}
290
-
291
300
return certArns .List (), nil
292
301
}
293
302
303
+ func (controller * defaultController ) loadDomainsByCertArn (ctx context.Context ) (map [string ][]string , error ) {
304
+ certSummaries , err := controller .cloud .ListCertificates (ctx , & acm.ListCertificatesInput {
305
+ CertificateStatuses : aws .StringSlice ([]string {acm .CertificateStatusIssued }),
306
+ })
307
+ if err != nil {
308
+ return nil , err
309
+ }
310
+ domainsByCertArn := make (map [string ][]string , len (certSummaries ))
311
+ for _ , certSummary := range certSummaries {
312
+ certArn := aws .StringValue (certSummary .CertificateArn )
313
+ certDetail , err := controller .cloud .DescribeCertificate (ctx , certArn )
314
+ if err != nil {
315
+ return nil , err
316
+ }
317
+ domainsByCertArn [certArn ] = aws .StringValueSlice (certDetail .SubjectAlternativeNames )
318
+ }
319
+ return domainsByCertArn , nil
320
+ }
321
+
294
322
func domainMatchesHost (domainName string , tlsHost string ) bool {
295
323
if strings .HasPrefix (domainName , "*." ) {
296
324
ds := strings .Split (domainName , "." )
@@ -306,15 +334,19 @@ func domainMatchesHost(domainName string, tlsHost string) bool {
306
334
return domainName == tlsHost
307
335
}
308
336
309
- func uniqueHosts (ingress * extensions.Ingress ) [] string {
337
+ func uniqueHosts (ingress * extensions.Ingress ) sets. String {
310
338
hosts := sets .NewString ()
311
339
312
340
for _ , r := range ingress .Spec .Rules {
341
+ if r .Host == "" {
342
+ continue
343
+ }
313
344
hosts .Insert (r .Host )
314
345
}
346
+
315
347
for _ , t := range ingress .Spec .TLS {
316
348
hosts .Insert (t .Hosts ... )
317
349
}
318
350
319
- return hosts . List ()
351
+ return hosts
320
352
}
0 commit comments