Avoid race conditions by copying the list before sorting (#8573)

When creating several ingresses at the same time a race condition can
happen by modifying a variable deep in another object. When this race
condition is triggered the generated nginx configuration is broken:

```
nginx: [emerg] invalid parameter "8.8.8.8/32,8" in /tmp/nginx-cfg4027854160:671
nginx: configuration file /tmp/nginx-cfg4027854160 test failed
```

Once it happens, the controller won't ever be able to generate the
configuration again. Thus the only option is to restart the process.

There is not really a good way to reproduce this issue. It happens quite
sporadically every 2 or 3 days. However, after this fix has been
applied, we haven't seen it happen after about 4 weeks.

Co-authored-by: Ruud van der Weijde <ruudvanderweijde@gmail.com>
This commit is contained in:
Renan Gonçalves 2022-05-23 14:50:03 +02:00 committed by GitHub
parent e0b2db057f
commit 869e18b264
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -62,18 +62,21 @@ func NewParser(r resolver.Resolver) parser.IngressAnnotation {
// e.g. `18.0.0.0/8,56.0.0.0/8`
func (a ipwhitelist) Parse(ing *networking.Ingress) (interface{}, error) {
defBackend := a.r.GetDefaultBackend()
sort.Strings(defBackend.WhitelistSourceRange)
defaultWhitelistSourceRange := make([]string, len(defBackend.WhitelistSourceRange))
copy(defaultWhitelistSourceRange, defBackend.WhitelistSourceRange)
sort.Strings(defaultWhitelistSourceRange)
val, err := parser.GetStringAnnotation("whitelist-source-range", ing)
// A missing annotation is not a problem, just use the default
if err == ing_errors.ErrMissingAnnotations {
return &SourceRange{CIDR: defBackend.WhitelistSourceRange}, nil
return &SourceRange{CIDR: defaultWhitelistSourceRange}, nil
}
values := strings.Split(val, ",")
ipnets, ips, err := net.ParseIPNets(values...)
if err != nil && len(ips) == 0 {
return &SourceRange{CIDR: defBackend.WhitelistSourceRange}, ing_errors.LocationDenied{
return &SourceRange{CIDR: defaultWhitelistSourceRange}, ing_errors.LocationDenied{
Reason: fmt.Errorf("the annotation does not contain a valid IP address or network: %w", err),
}
}