Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fill in AttachedRoutes in Gateways' Listeners status #251

Merged
merged 9 commits into from
May 22, 2024
Merged
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
- `Gateway` do not have their `Ready` status condition set anymore.
This aligns with Gateway API and its conformance test suite.
[#246](https://github.com/Kong/gateway-operator/pull/246)
- `Gateway`s' listeners now have their `attachedRoutes` count filled in in status.
[#251](https://github.com/Kong/gateway-operator/pull/251)

### Fixes

Expand Down
141 changes: 141 additions & 0 deletions config/samples/gateway-httproute-allowedroutes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
apiVersion: v1
kind: Service
metadata:
name: echo
spec:
ports:
- protocol: TCP
name: http
port: 80
targetPort: http
selector:
app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: echo
name: echo
spec:
replicas: 1
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: registry.k8s.io/e2e-test-images/agnhost:2.40
command:
- /agnhost
- netexec
- --http-port=8080
ports:
- containerPort: 8080
name: http
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
resources:
requests:
cpu: 10m
---
kind: GatewayConfiguration
apiVersion: gateway-operator.konghq.com/v1beta1
metadata:
name: kong
namespace: default
spec:
dataPlaneOptions:
deployment:
podTemplateSpec:
spec:
containers:
- name: proxy
# renovate: datasource=docker versioning=docker
image: kong/kong-gateway:3.6
readinessProbe:
initialDelaySeconds: 1
periodSeconds: 1
controlPlaneOptions:
deployment:
podTemplateSpec:
spec:
containers:
- name: controller
# renovate: datasource=docker versioning=docker
image: kong/kubernetes-ingress-controller:3.1.5
readinessProbe:
initialDelaySeconds: 1
periodSeconds: 1
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong
spec:
controllerName: konghq.com/gateway-operator
parametersRef:
group: gateway-operator.konghq.com
kind: GatewayConfiguration
name: kong
namespace: default
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong
namespace: default
spec:
gatewayClassName: kong
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
# This label is added automatically as of K8s 1.22 to all namespaces
kubernetes.io/metadata.name: default
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httproute-echo
namespace: default
annotations:
konghq.com/strip-path: "true"
spec:
parentRefs:
- name: kong
rules:
- matches:
- path:
type: PathPrefix
value: /echo
backendRefs:
- name: echo
kind: Service
port: 80
23 changes: 18 additions & 5 deletions controller/gateway/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,17 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
Watches(
&gatewayv1beta1.ReferenceGrant{},
handler.EnqueueRequestsFromMapFunc(r.listReferenceGrantsForGateway),
builder.WithPredicates(predicate.NewPredicateFuncs(referenceGrantHasGatewayFrom)),
).
builder.WithPredicates(predicate.NewPredicateFuncs(referenceGrantHasGatewayFrom))).
// watch HTTPRoutes so that Gateway listener status can be updated.
Watches(
&gatewayv1beta1.HTTPRoute{},
handler.EnqueueRequestsFromMapFunc(r.listHTTPRoutesForGateway)).
// watch Namespaces so that managed routes have correct status reflected in Gateway's
// status in status.listeners.attachedRoutes
// This is required to properly support Gateway's listeners.allowedRoutes.namespaces.selector.
Watches(
&corev1.Namespace{},
handler.EnqueueRequestsFromMapFunc(r.listManagedGatewaysInNamespace)).
Complete(r)
}

Expand Down Expand Up @@ -152,15 +161,19 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
log.Trace(logger, "resource is supported, ensuring that it gets marked as accepted", gateway)
gwConditionAware.initListenersStatus()
gwConditionAware.setConflicted()
gwConditionAware.setAccepted()
if err = gwConditionAware.setAcceptedAndAttachedRoutes(ctx, r.Client); err != nil {
return ctrl.Result{}, err
}

gwConditionAware.initProgrammedAndListenersStatus()
if err := gwConditionAware.setResolvedRefsAndSupportedKinds(ctx, r.Client); err != nil {
return ctrl.Result{}, err
}
acceptedCondition, _ := k8sutils.GetCondition(k8sutils.ConditionType(gatewayv1.GatewayConditionAccepted), gwConditionAware)
// If the static Gateway API conditions (Accepted, ResolvedRefs, Conflicted) changed, we need to update the Gateway status
if gatewayStatusNeedsUpdate(oldGwConditionsAware, gwConditionAware) {
if err := r.patchStatus(ctx, &gateway, oldGateway); err != nil { // requeue will be triggered by the update of the dataplane status
_, err := patch.ApplyGatewayStatusPatchIfNotEmpty(ctx, r.Client, logger, &gateway, oldGateway) // requeue will be triggered by the update of the gateway status
if err != nil {
pmalek marked this conversation as resolved.
Show resolved Hide resolved
return ctrl.Result{}, err
}
if acceptedCondition.Status == metav1.ConditionTrue {
Expand Down Expand Up @@ -346,7 +359,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
gatewayConditionsAndListenersAware(&gateway))
}

gwConditionAware.setProgrammedAndListenersConditions()
gwConditionAware.setProgrammed()
res, err := patch.ApplyGatewayStatusPatchIfNotEmpty(ctx, r.Client, logger, &gateway, oldGateway)
if err != nil {
return ctrl.Result{}, err
Expand Down
Loading
Loading