Skip to content

Commit 52a0048

Browse files
Merge pull request #1212 from alebedev87/dns-record-check-lib
OCPBUGS-54966: Improve detection of missing DNSRecord for Gateway
2 parents afb2160 + 312078a commit 52a0048

File tree

3 files changed

+60
-16
lines changed

3 files changed

+60
-16
lines changed

pkg/operator/controller/gateway-service-dns/controller.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ func NewUnmanaged(mgr manager.Manager, config Config) (controller.Controller, er
7878
// A DNSRecord CR needs to be updated if, and only if,
7979
// the hostname has changed (a listener's port and
8080
// protocol have no bearing on the DNS record).
81-
return gatewayListenersHostnamesChanged(old, new)
81+
changed := gatewayListenersHostnamesChanged(old, new)
82+
if changed {
83+
log.Info("Listener hostname changed", "gateway", e.ObjectNew.(*gatewayapiv1.Gateway).Name)
84+
}
85+
return changed
8286
},
8387
}
8488
isInOperandNamespace := predicate.NewPredicateFuncs(func(o client.Object) bool {
@@ -103,6 +107,7 @@ func NewUnmanaged(mgr manager.Manager, config Config) (controller.Controller, er
103107
},
104108
}
105109
requests = append(requests, request)
110+
log.Info("Enqueuing service for gateway", "gateway", o.GetName(), "service", request.NamespacedName)
106111
}
107112
return requests
108113
}

pkg/resources/dnsrecord/dns.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,17 @@ func EnsureDNSRecord(client client.Client, name types.NamespacedName, dnsRecordL
7777
if err := client.Create(context.TODO(), desired); err != nil {
7878
return false, nil, fmt.Errorf("failed to create dnsrecord %s/%s: %v", desired.Namespace, desired.Name, err)
7979
}
80-
log.Info("created dnsrecord", "dnsrecord", desired)
80+
log.Info("Created dnsrecord", "dnsrecord", desired)
8181
return CurrentDNSRecord(client, name)
8282
case wantWC && haveWC:
8383
if updated, err := updateDNSRecord(client, current, desired); err != nil {
8484
return true, current, fmt.Errorf("failed to update dnsrecord %s/%s: %v", desired.Namespace, desired.Name, err)
8585
} else if updated {
86+
log.Info("Updated dnsrecord", "dnsrecord", desired)
8687
return CurrentDNSRecord(client, name)
8788
}
8889
}
90+
log.Info("No desired dnsrecord", "service", service)
8991

9092
return haveWC, current, nil
9193
}
@@ -130,6 +132,7 @@ func desiredWildcardDNSRecord(name types.NamespacedName, dnsRecordLabels map[str
130132
func desiredDNSRecord(name types.NamespacedName, dnsRecordLabels map[string]string, ownerRef metav1.OwnerReference, domain string, dnsPolicy iov1.DNSManagementPolicy, service *corev1.Service) (bool, *iov1.DNSRecord) {
131133
// No LB target exists for the domain record to point at.
132134
if len(service.Status.LoadBalancer.Ingress) == 0 {
135+
log.Info("No load balancer target for dnsrecord", "dnsrecord", name, "service", service.Name)
133136
return false, nil
134137
}
135138

@@ -138,6 +141,7 @@ func desiredDNSRecord(name types.NamespacedName, dnsRecordLabels map[string]stri
138141
// Quick sanity check since we don't know how to handle both being set (is
139142
// that even a valid state?)
140143
if len(ingress.Hostname) > 0 && len(ingress.IP) > 0 {
144+
log.Error(nil, "Both load balancer hostname and IP are set", "dnsrecord", name, "service", service.Name)
141145
return false, nil
142146
}
143147

test/e2e/util_gatewayapi_test.go

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -594,10 +594,11 @@ func assertGatewayClassSuccessful(t *testing.T, name string) (*gatewayapiv1.Gate
594594
return false, nil
595595
})
596596
if err != nil {
597+
t.Logf("[%s] Last observed gatewayclass:\n%s", time.Now().Format(time.DateTime), util.ToYaml(gwc))
597598
return nil, fmt.Errorf("gatewayclass %s is not %v; last recorded status message: %s", name, gatewayapiv1.GatewayClassConditionStatusAccepted, recordedConditionMsg)
598599
}
599600

600-
t.Logf("Observed that gatewayclass %s has been accepted: %+v", name, gwc.Status)
601+
t.Logf("[%s] Observed that gatewayclass %s has been accepted: %+v", time.Now().Format(time.DateTime), name, gwc.Status)
601602

602603
return gwc, nil
603604
}
@@ -609,30 +610,58 @@ func assertGatewaySuccessful(t *testing.T, namespace, name string) (*gatewayapiv
609610

610611
gw := &gatewayapiv1.Gateway{}
611612
nsName := types.NamespacedName{Namespace: namespace, Name: name}
612-
recordedConditionMsg := "not found"
613+
recordedAcceptedConditionMsg, recordedProgrammedConditionMsg := "", ""
613614

614-
err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 1*time.Minute, false, func(context context.Context) (bool, error) {
615+
// Wait for the gateway to be accepted and programmed.
616+
// Load balancer provisioning can take several minutes on some platforms.
617+
// Therefore, a timeout of 3 minutes is set to accommodate potential delays.
618+
err := wait.PollUntilContextTimeout(context.Background(), 3*time.Second, 3*time.Minute, false, func(context context.Context) (bool, error) {
615619
if err := kclient.Get(context, nsName, gw); err != nil {
616620
t.Logf("Failed to get gateway %v: %v; retrying...", nsName, err)
617621
return false, nil
618622
}
623+
acceptedConditionFound, programmedConditionFound := false, false
619624
for _, condition := range gw.Status.Conditions {
620625
if condition.Type == string(gatewayapiv1.GatewayConditionAccepted) {
621-
recordedConditionMsg = condition.Message
626+
recordedAcceptedConditionMsg = condition.Message
622627
if condition.Status == metav1.ConditionTrue {
623-
t.Logf("Found gateway %v as Accepted", nsName)
624-
return true, nil
628+
t.Logf("[%s] Found gateway %v as Accepted", time.Now().Format(time.DateTime), nsName)
629+
acceptedConditionFound = true
630+
}
631+
}
632+
// Ensuring the gateway configuration is ready.
633+
// `AddressNotAssigned` may happen if the gateway service
634+
// didn't get its load balancer target.
635+
if condition.Type == string(gatewayapiv1.GatewayConditionProgrammed) {
636+
recordedProgrammedConditionMsg = condition.Message
637+
if condition.Status == metav1.ConditionTrue {
638+
t.Logf("[%s] Found gateway %v as Programmed", time.Now().Format(time.DateTime), nsName)
639+
programmedConditionFound = true
625640
}
626641
}
627642
}
643+
if acceptedConditionFound && programmedConditionFound {
644+
return true, nil
645+
}
646+
t.Logf("[%s] Not all expected gateway conditions are found, checking gateway service...", time.Now().Format(time.DateTime))
647+
648+
// The creation of the gateway service may be delayed.
649+
// Check the current status of the service to see where we are.
650+
svc := &corev1.Service{}
651+
svcNsName := types.NamespacedName{Namespace: namespace, Name: gw.Name + "-" + string(gw.Spec.GatewayClassName)}
652+
if err := kclient.Get(context, svcNsName, svc); err != nil {
653+
t.Logf("Failed to get gateway service %v: %v; retrying...", svcNsName, err)
654+
return false, nil
655+
}
656+
t.Logf("[%s] Found gateway service: %+v", time.Now().Format(time.DateTime), svc)
628657
return false, nil
629658
})
630659
if err != nil {
631-
t.Logf("Last observed gateway:\n%s", util.ToYaml(gw))
632-
return nil, fmt.Errorf("gateway %v not %v, last recorded status message: %s", nsName, gatewayapiv1.GatewayConditionAccepted, recordedConditionMsg)
660+
t.Logf("[%s] Last observed gateway:\n%s", time.Now().Format(time.DateTime), util.ToYaml(gw))
661+
return nil, fmt.Errorf("gateway %v does not have all expected conditions, last recorded status messages status messages for Accepted: %q, Programmed: %q", nsName, recordedAcceptedConditionMsg, recordedProgrammedConditionMsg)
633662
}
634663

635-
t.Logf("Observed that gateway %v has been accepted: %+v", nsName, gw.Status)
664+
t.Logf("[%s] Observed that gateway %v has been accepted: %+v", time.Now().Format(time.DateTime), nsName, gw.Status)
636665

637666
return gw, nil
638667
}
@@ -1037,21 +1066,27 @@ func assertDNSRecord(t *testing.T, recordName types.NamespacedName) error {
10371066

10381067
err := wait.PollUntilContextTimeout(context.Background(), 10*time.Second, 10*time.Minute, false, func(context context.Context) (bool, error) {
10391068
if err := kclient.Get(context, recordName, dnsRecord); err != nil {
1040-
t.Logf("Failed to get DNSRecord %v: %v; retrying...", recordName, err)
1069+
t.Logf("[%s] Failed to get DNSRecord %v: %v; retrying...", time.Now().Format(time.DateTime), recordName, err)
10411070
return false, nil
10421071
}
10431072
// Determine the current state of the DNSRecord.
1073+
reason := "missing published condition"
10441074
if len(dnsRecord.Status.Zones) > 0 {
10451075
for _, zone := range dnsRecord.Status.Zones {
10461076
for _, condition := range zone.Conditions {
1047-
if condition.Type == v1.DNSRecordPublishedConditionType && condition.Status == string(metav1.ConditionTrue) {
1048-
t.Logf("Found DNSRecord %v %s=%s", recordName, condition.Type, condition.Status)
1049-
return true, nil
1077+
if condition.Type == v1.DNSRecordPublishedConditionType {
1078+
reason = "unexpected published condition value"
1079+
if condition.Status == string(metav1.ConditionTrue) {
1080+
t.Logf("[%s] Found DNSRecord %v %s=%s", time.Now().Format(time.DateTime), recordName, condition.Type, condition.Status)
1081+
return true, nil
1082+
}
10501083
}
10511084
}
10521085
}
1086+
} else {
1087+
reason = "missing zones"
10531088
}
1054-
t.Logf("Found DNSRecord %v but could not determine its readiness; retrying...", recordName)
1089+
t.Logf("[%s] Found DNSRecord %v but could not determine its readiness due to %s; retrying...", time.Now().Format(time.DateTime), recordName, reason)
10551090
return false, nil
10561091
})
10571092
return err

0 commit comments

Comments
 (0)