Skip to content

Commit 915a344

Browse files
committed
check gateway class and do not skip listeners when gateway class is not managed by KIC
1 parent 5eea70b commit 915a344

File tree

10 files changed

+74
-15
lines changed

10 files changed

+74
-15
lines changed

hack/generators/cache-stores/spec.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ var supportedTypes = []cacheStoreSupportedType{
6060
Type: "Gateway",
6161
Package: "gatewayapi",
6262
},
63+
{
64+
Type: "GatewayClass",
65+
Package: "gatewayapi",
66+
KeyFunc: clusterWideKeyFunc,
67+
},
6368
{
6469
Type: "BackendTLSPolicy",
6570
Package: "gatewayapi",

internal/controllers/gateway/gateway_controller.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func (r *GatewayReconciler) gatewayHasMatchingGatewayClass(obj client.Object) bo
181181
r.Log.Error(err, "Could not retrieve gatewayclass", "gatewayclass", gateway.Spec.GatewayClassName)
182182
return false
183183
}
184+
184185
return isGatewayClassControlled(gatewayClass)
185186
}
186187

@@ -440,6 +441,11 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
440441
debug(log, gateway, "Ensured gateway was removed from the data-plane (if ever present)")
441442
return ctrl.Result{}, nil
442443
}
444+
err := r.DataplaneClient.UpdateObject(gwc)
445+
if err != nil {
446+
debug(log, gwc, "Failed to update GatewayClass in dataplane, requeueing")
447+
return ctrl.Result{}, err
448+
}
443449

444450
// if there's any deletion timestamp on the object, we can simply ignore it. At this point
445451
// with unmanaged mode being the only option supported there are no finalizers and

internal/dataplane/fallback/graph_dependencies.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func ResolveDependencies(cache store.CacheStores, obj client.Object) ([]client.O
6262
*discoveryv1.EndpointSlice,
6363
*gatewayapi.ReferenceGrant,
6464
*gatewayapi.Gateway,
65+
*gatewayapi.GatewayClass,
6566
*gatewayapi.BackendTLSPolicy,
6667
*configurationv1.KongIngress,
6768
*configurationv1beta1.KongUpstreamPolicy,

internal/dataplane/translator/translate_certs.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import (
99

1010
"github.com/go-logr/logr"
1111
"github.com/kong/go-kong/kong"
12+
"github.com/samber/lo"
1213
corev1 "k8s.io/api/core/v1"
1314
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1415

16+
"github.com/kong/kubernetes-ingress-controller/v3/internal/annotations"
1517
"github.com/kong/kubernetes-ingress-controller/v3/internal/dataplane/kongstate"
1618
"github.com/kong/kubernetes-ingress-controller/v3/internal/gatewayapi"
1719
"github.com/kong/kubernetes-ingress-controller/v3/internal/logging"
@@ -55,11 +57,16 @@ func (t *Translator) getGatewayCerts() []certWrapper {
5557
return certs
5658
}
5759
for _, gateway := range gateways {
58-
statuses := make(map[gatewayapi.SectionName]gatewayapi.ListenerStatus, len(gateway.Status.Listeners))
59-
for _, status := range gateway.Status.Listeners {
60-
statuses[status.Name] = status
60+
gwc, err := s.GetGatewayClass(string(gateway.Spec.GatewayClassName))
61+
if err != nil {
62+
logger.Error(err, "Failed to get GatewayClass for Gateway, skipping", "gateway", gateway.Name, "gateway_class", gateway.Spec.GatewayClassName)
63+
continue
6164
}
6265

66+
statuses := lo.SliceToMap(gateway.Status.Listeners, func(status gatewayapi.ListenerStatus) (gatewayapi.SectionName, gatewayapi.ListenerStatus) {
67+
return status.Name, status
68+
})
69+
6370
for _, listener := range gateway.Spec.Listeners {
6471
status, ok := statuses[listener.Name]
6572
if !ok {
@@ -72,14 +79,18 @@ func (t *Translator) getGatewayCerts() []certWrapper {
7279
continue
7380
}
7481

75-
// Check if listener is marked as programmed
76-
if !util.CheckCondition(
77-
status.Conditions,
78-
util.ConditionType(gatewayapi.ListenerConditionProgrammed),
79-
util.ConditionReason(gatewayapi.ListenerReasonProgrammed),
80-
metav1.ConditionTrue,
81-
gateway.Generation,
82-
) {
82+
// Check if listener is marked as programmed when the gateway is controlled by KIC in its spec and has the "Unmanaged" annotation.
83+
// If the GatewayClass is does not satify the condition, the gateway is considered to be managed by other components (for example Kong Oprator),
84+
// So we do not check the "Programmed" condition before extracting the certificate from the listener.
85+
if gwc.Spec.ControllerName == gatewayapi.GatewayController(t.gatewayControllerName) &&
86+
annotations.ExtractUnmanagedGatewayClassMode(gwc.Annotations) != "" &&
87+
!util.CheckCondition(
88+
status.Conditions,
89+
util.ConditionType(gatewayapi.ListenerConditionProgrammed),
90+
util.ConditionReason(gatewayapi.ListenerReasonProgrammed),
91+
metav1.ConditionTrue,
92+
gateway.Generation,
93+
) {
8394
continue
8495
}
8596

internal/dataplane/translator/translator.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ type Translator struct {
109109
failuresCollector *failures.ResourceFailuresCollector
110110
translatedObjectsCollector *ObjectsCollector
111111

112-
clusterDomain string
113-
enableDrainSupport bool
112+
clusterDomain string
113+
enableDrainSupport bool
114+
gatewayControllerName string
114115
}
115116

116117
// Config is a configuration for the Translator.
@@ -120,6 +121,10 @@ type Config struct {
120121

121122
// ClusterDomain is the cluster domain used for translating Kubernetes objects.
122123
ClusterDomain string
124+
125+
// GatewayControllerName is the gateway controller name used by KIC.
126+
// GatewayClasses with this controller name in spec.ControllerName are managed by KIC, otherwise they are managed by other components(like Kong Operator).
127+
GatewayControllerName string
123128
}
124129

125130
// NewTranslator produces a new Translator object provided a logging mechanism
@@ -152,6 +157,7 @@ func NewTranslator(
152157
translatedObjectsCollector: translatedObjectsCollector,
153158
clusterDomain: config.ClusterDomain,
154159
enableDrainSupport: config.EnableDrainSupport,
160+
gatewayControllerName: config.GatewayControllerName,
155161
}, nil
156162
}
157163

internal/manager/run.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,9 @@ func New(
221221

222222
configTranslator, err := translator.NewTranslator(logger, storer, c.KongWorkspace, kongSemVersion, translatorFeatureFlags, NewSchemaServiceGetter(clientsManager),
223223
translator.Config{
224-
ClusterDomain: c.ClusterDomain,
225-
EnableDrainSupport: c.EnableDrainSupport,
224+
ClusterDomain: c.ClusterDomain,
225+
EnableDrainSupport: c.EnableDrainSupport,
226+
GatewayControllerName: c.GatewayAPIControllerName,
226227
},
227228
)
228229
if err != nil {

internal/store/fake_store.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type FakeObjects struct {
4141
GRPCRoutes []*gatewayapi.GRPCRoute
4242
ReferenceGrants []*gatewayapi.ReferenceGrant
4343
Gateways []*gatewayapi.Gateway
44+
GatewayClasses []*gatewayapi.GatewayClass
4445
BackendTLSPolicies []*gatewayapi.BackendTLSPolicy
4546
TCPIngresses []*configurationv1beta1.TCPIngress
4647
UDPIngresses []*configurationv1beta1.UDPIngress

internal/store/store.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ type Storer interface {
9999

100100
// Gateway API resources.
101101
GetGateway(namespace string, name string) (*gatewayapi.Gateway, error)
102+
GetGatewayClass(name string) (*gatewayapi.GatewayClass, error)
102103
ListHTTPRoutes() ([]*gatewayapi.HTTPRoute, error)
103104
ListUDPRoutes() ([]*gatewayapi.UDPRoute, error)
104105
ListTCPRoutes() ([]*gatewayapi.TCPRoute, error)
@@ -607,6 +608,18 @@ func (s Store) GetGateway(namespace string, name string) (*gatewayapi.Gateway, e
607608
return obj.(*gatewayapi.Gateway), nil
608609
}
609610

611+
// GetGatewayClass returns gatewayclass resource having the specified name.
612+
func (s Store) GetGatewayClass(name string) (*gatewayapi.GatewayClass, error) {
613+
obj, exists, err := s.stores.GatewayClass.GetByKey(name)
614+
if err != nil {
615+
return nil, err
616+
}
617+
if !exists {
618+
return nil, NotFoundError{fmt.Sprintf("GatewayClass %v not found", name)}
619+
}
620+
return obj.(*gatewayapi.GatewayClass), nil
621+
}
622+
610623
// GetKongVault returns kongvault resource having specified name.
611624
func (s Store) GetKongVault(name string) (*configurationv1alpha1.KongVault, error) {
612625
p, exists, err := s.stores.KongVault.GetByKey(name)

internal/store/zz_generated.cache_stores.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/store/zz_generated.cache_stores_test.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)