Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions internal/controller/gateway_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,16 +329,6 @@ func (r *GatewayReconciler) ensureDownstreamGateway(
listenerCertHealth,
)

// A listener the user asked for that never reaches the downstream gateway
// makes the gateway dishonest about being programmed, whatever held it back.
// Derived from the listener set actually built, so a new reason to withhold
// one is covered without being enumerated here.
droppedListeners := summarizeDroppedListeners(
upstreamGateway,
desiredDownstreamGateway,
listenerCertHealth,
)

if err := writeDownstreamGateway(ctx, downstreamStrategy, upstreamGateway, downstreamGateway,
desiredDownstreamGateway.Spec, awaitsHostnameClaim(hostnameRefusals)); err != nil {
result.Err = err
Expand Down Expand Up @@ -388,6 +378,17 @@ func (r *GatewayReconciler) ensureDownstreamGateway(
clearCertificateServiceFailing(upstreamClusterName, upstreamGateway)
}

// A listener the user asked for that never reaches the downstream gateway
// makes the gateway dishonest about being programmed, whatever held it back.
// Derived from the listener set actually built, so a new reason to withhold
// one is covered without being enumerated here. Summarized after the
// certificate service so an entitlement block is known.
droppedListeners := summarizeDroppedListeners(
upstreamGateway,
desiredDownstreamGateway,
listenerCertHealth,
)

certResult := r.ensureListenerCertificates(
ctx,
upstreamGateway,
Expand Down Expand Up @@ -955,8 +956,8 @@ func (r *GatewayReconciler) getDesiredDownstreamGateway(
}

// listenerDropReport names the spec listeners that never reached the downstream
// gateway, and records whether an unusable certificate held back every one of
// them.
// gateway, and records whether a certificate still on its way held back every
// one of them.
type listenerDropReport struct {
names []gatewayv1.SectionName
allCertWithheld bool
Expand Down Expand Up @@ -1030,7 +1031,8 @@ func summarizeDroppedListeners(

report.names = append(report.names, l.Name)

if status, gated := listenerCertHealth[l.Name]; !gated || status.healthy {
if status, gated := listenerCertHealth[l.Name]; !gated || status.healthy ||
status.issuanceReason == certificateServiceReasonWildcardNotEntitled {
report.allCertWithheld = false
}
}
Expand Down
15 changes: 15 additions & 0 deletions internal/controller/gateway_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2161,6 +2161,21 @@ func TestReconcileGatewayStatus_DroppedListenerIsNotProgrammed(t *testing.T) {
expectStatus: metav1.ConditionFalse,
expectReason: string(gatewayv1.GatewayReasonPending),
},
{
name: "listener withheld by a wildcard the project is not entitled to",
listeners: []gatewayv1.Listener{customListener("custom-https", "*.claimed.example.com")},
claimedHostnames: []string{"*.claimed.example.com"},
certHealth: map[gatewayv1.SectionName]listenerCertStatus{
"custom-https": {
reason: gatewayv1.ListenerReasonInvalidCertificateRef,
message: "wildcard hostnames are not enabled",
issuanceBlocked: true,
issuanceReason: certificateServiceReasonWildcardNotEntitled,
},
},
expectStatus: metav1.ConditionFalse,
expectReason: string(gatewayv1.GatewayReasonListenersNotValid),
},
{
name: "certificate and hostname drops report the hostname",
listeners: []gatewayv1.Listener{
Expand Down
23 changes: 23 additions & 0 deletions internal/controller/wildcard_entitlement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,3 +492,26 @@ func seriesMatching(t *testing.T, vec prometheus.Collector, want prometheus.Labe
}
return count
}

func TestWildcardNotEntitledIsNotReportedPending(t *testing.T) {
f := newEntitlementFixture(t, "*.shop.example.com", false, fakeWildcardEntitlements{entitled: false})

_, created, _ := f.h.reconcile()
require.NotNil(t, created, "downstream gateway")
downstream := &gatewayv1.Gateway{}
require.NoError(t, f.h.downstream.Get(f.h.ctx, client.ObjectKeyFromObject(created), downstream))
apimeta.SetStatusCondition(&downstream.Status.Conditions, metav1.Condition{
Type: string(gatewayv1.GatewayConditionProgrammed),
Status: metav1.ConditionTrue,
Reason: string(gatewayv1.GatewayReasonProgrammed),
})
require.NoError(t, f.h.downstream.Status().Update(f.h.ctx, downstream))

upstream, _, _ := f.h.reconcile()

programmed := apimeta.FindStatusCondition(upstream.Status.Conditions, string(gatewayv1.GatewayConditionProgrammed))
require.NotNil(t, programmed, "upstream Programmed condition")
assert.Equal(t, metav1.ConditionFalse, programmed.Status)
assert.Equal(t, string(gatewayv1.GatewayReasonListenersNotValid), programmed.Reason,
"a wildcard the project is not entitled to never gets a certificate, so it is not Pending")
}
Loading