@@ -18,6 +18,7 @@ package controller
18
18
19
19
import (
20
20
"context"
21
+ "fmt"
21
22
"reflect"
22
23
"strconv"
23
24
"strings"
@@ -69,50 +70,75 @@ func (r *IngressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
69
70
func (r * IngressReconciler ) reconcileIngress (ctx context.Context , ingress * networkingv1.Ingress , annotations map [string ]string ) (ctrl.Result , error ) {
70
71
log := ctrl .LoggerFrom (ctx )
71
72
72
- dnsRecords := & cloudflareoperatoriov1. DNSRecordList {}
73
- if err := r . List ( ctx , dnsRecords , client . InNamespace ( ingress . Namespace ), client. MatchingFields { cloudflareoperatoriov1 . OwnerRefUIDIndexKey : string ( ingress . UID )}); err != nil {
73
+ dnsRecords , err := r . getDNSRecords ( ctx , ingress )
74
+ if err != nil {
74
75
log .Error (err , "Failed to list DNSRecords" )
75
76
return ctrl.Result {RequeueAfter : time .Second * 30 }, nil
76
77
}
77
78
78
79
dnsRecordSpec := r .parseAnnotations (annotations )
80
+ existingRecords := make (map [string ]cloudflareoperatoriov1.DNSRecord )
81
+ for _ , record := range dnsRecords .Items {
82
+ existingRecords [record .Spec .Name ] = record
83
+ }
79
84
80
- dnsRecordMap := make (map [string ]cloudflareoperatoriov1.DNSRecord )
81
- for _ , dnsRecord := range dnsRecords .Items {
82
- dnsRecordMap [dnsRecord .Spec .Name ] = dnsRecord
85
+ ingressHosts := r .getIngressHosts (ingress )
86
+
87
+ if err := r .reconcileDNSRecords (ctx , ingress , dnsRecordSpec , existingRecords , ingressHosts ); err != nil {
88
+ log .Error (err , "Failed to reconcile DNS records" )
89
+ return ctrl.Result {}, err
83
90
}
84
91
85
- ingressRules := make (map [string ]struct {})
92
+ return ctrl.Result {}, nil
93
+ }
94
+
95
+ func (r * IngressReconciler ) getDNSRecords (ctx context.Context , ingress * networkingv1.Ingress ) (* cloudflareoperatoriov1.DNSRecordList , error ) {
96
+ dnsRecords := & cloudflareoperatoriov1.DNSRecordList {}
97
+ err := r .List (ctx , dnsRecords , client .InNamespace (ingress .Namespace ), client.MatchingFields {cloudflareoperatoriov1 .OwnerRefUIDIndexKey : string (ingress .UID )})
98
+ return dnsRecords , err
99
+ }
100
+
101
+ func (r * IngressReconciler ) getIngressHosts (ingress * networkingv1.Ingress ) map [string ]struct {} {
102
+ hosts := make (map [string ]struct {})
86
103
for _ , rule := range ingress .Spec .Rules {
87
- if rule .Host = = "" {
88
- continue
104
+ if rule .Host ! = "" {
105
+ hosts [ rule . Host ] = struct {}{}
89
106
}
90
- ingressRules [rule .Host ] = struct {}{}
91
- dnsRecordSpec .Name = rule .Host
92
- if dnsRecord , found := dnsRecordMap [rule .Host ]; ! found {
107
+ }
108
+ return hosts
109
+ }
110
+
111
+ func (r * IngressReconciler ) reconcileDNSRecords (ctx context.Context , ingress * networkingv1.Ingress , dnsRecordSpec cloudflareoperatoriov1.DNSRecordSpec , existingRecords map [string ]cloudflareoperatoriov1.DNSRecord , ingressHosts map [string ]struct {}) error {
112
+ log := ctrl .LoggerFrom (ctx )
113
+
114
+ for host := range ingressHosts {
115
+ record , exists := existingRecords [host ]
116
+ dnsRecordSpec .Name = host
117
+
118
+ if ! exists {
93
119
if err := r .createDNSRecord (ctx , ingress , dnsRecordSpec ); err != nil {
94
- log .Error (err , "Failed to create DNSRecord" )
95
- return ctrl.Result {}, err
120
+ return fmt .Errorf ("failed to create DNSRecord for %s: %w" , host , err )
96
121
}
97
- } else if ! reflect .DeepEqual (dnsRecord .Spec , dnsRecordSpec ) {
98
- dnsRecord .Spec = dnsRecordSpec
99
- if err := r .Update (ctx , & dnsRecord ); err != nil {
100
- log .Error (err , "Failed to update DNSRecord" )
101
- return ctrl.Result {}, err
122
+ continue
123
+ }
124
+
125
+ if ! reflect .DeepEqual (record .Spec , dnsRecordSpec ) {
126
+ record .Spec = dnsRecordSpec
127
+ if err := r .Update (ctx , & record ); err != nil {
128
+ return fmt .Errorf ("failed to update DNSRecord for %s: %w" , host , err )
102
129
}
103
130
}
104
131
}
105
132
106
- for _ , dnsRecord := range dnsRecords .Items {
107
- if _ , found := ingressRules [dnsRecord .Spec .Name ]; found {
108
- continue
109
- }
110
- if err := r .Delete (ctx , & dnsRecord ); err != nil {
111
- log .Error (err , "Failed to delete DNSRecord" )
133
+ for host , record := range existingRecords {
134
+ if _ , exists := ingressHosts [host ]; ! exists {
135
+ if err := r .Delete (ctx , & record ); err != nil {
136
+ log .Error (err , "Failed to delete DNSRecord" , "host" , host )
137
+ }
112
138
}
113
139
}
114
140
115
- return ctrl. Result {}, nil
141
+ return nil
116
142
}
117
143
118
144
// parseAnnotations parses ingress annotations and returns a DNSRecordSpec
0 commit comments