Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
15 changes: 12 additions & 3 deletions internal/controller/indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ const (
ControllerName = "controllerName"
)

const (
ingressClassNameAnnotation = "kubernetes.io/ingress.class"
)
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constant ingressClassNameAnnotation is duplicated across multiple files (utils.go, ingress_controller.go, and indexer.go). Consider defining it once in a shared constants file to avoid inconsistencies and improve maintainability.

Suggested change
const (
ingressClassNameAnnotation = "kubernetes.io/ingress.class"
)
// Use shared constant from internal/utils instead of local definition.

Copilot uses AI. Check for mistakes.

func SetupIndexer(mgr ctrl.Manager) error {
setupLog := ctrl.LoggerFrom(context.Background()).WithName("indexer-setup")

Expand Down Expand Up @@ -444,10 +448,15 @@ func IngressClassIndexFunc(rawObj client.Object) []string {

func IngressClassRefIndexFunc(rawObj client.Object) []string {
ingress := rawObj.(*networkingv1.Ingress)
if ingress.Spec.IngressClassName == nil {
return nil
if ingress.Spec.IngressClassName != nil && *ingress.Spec.IngressClassName != "" {
return []string{*ingress.Spec.IngressClassName}
}
return []string{*ingress.Spec.IngressClassName}
if annotations := ingress.GetAnnotations(); annotations != nil {
if className := annotations[ingressClassNameAnnotation]; className != "" {
return []string{className}
}
}
return nil
}

func IngressServiceIndexFunc(rawObj client.Object) []string {
Expand Down
16 changes: 13 additions & 3 deletions internal/controller/ingress_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,19 @@ func (r *IngressReconciler) listIngressForIngressClass(ctx context.Context, obj
}

requests := make([]reconcile.Request, 0, len(ingressList.Items))
for _, ingress := range ingressList.Items {
if ingress.Spec.IngressClassName == nil || *ingress.Spec.IngressClassName == "" ||
*ingress.Spec.IngressClassName == ingressClass.GetName() {
for i := range ingressList.Items {
ingress := &ingressList.Items[i]
specClassName := ptr.Deref(ingress.Spec.IngressClassName, "")
annotationClassName := ""
if annotations := ingress.GetAnnotations(); annotations != nil {
annotationClassName = annotations[ingressClassNameAnnotation]
}
effectiveClassName := specClassName
if effectiveClassName == "" {
effectiveClassName = annotationClassName
}
hasExplicitClass := specClassName != "" || annotationClassName != ""
if !hasExplicitClass || effectiveClassName == ingressClass.GetName() {
requests = append(requests, reconcile.Request{
NamespacedName: client.ObjectKey{
Namespace: ingress.Namespace,
Expand Down
9 changes: 8 additions & 1 deletion internal/controller/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ const (
const (
defaultIngressClassAnnotation = "ingressclass.kubernetes.io/is-default-class"
parametersNamespaceAnnotation = "apisix.apache.org/parameters-namespace"
ingressClassNameAnnotation = "kubernetes.io/ingress.class"
)

var (
Expand Down Expand Up @@ -1718,7 +1719,13 @@ func MatchesIngressClass(c client.Client, log logr.Logger, obj client.Object, ap
func ExtractIngressClass(obj client.Object) string {
switch v := obj.(type) {
case *networkingv1.Ingress:
return ptr.Deref(v.Spec.IngressClassName, "")
if className := ptr.Deref(v.Spec.IngressClassName, ""); className != "" {
return className
}
if annotations := v.GetAnnotations(); annotations != nil {
return annotations[ingressClassNameAnnotation]
}
return ""
case *apiv2.ApisixConsumer:
return v.Spec.IngressClassName
case *apiv2.ApisixRoute:
Expand Down
48 changes: 48 additions & 0 deletions test/e2e/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,54 @@ spec:
})
})

Context("Ingress Annotation", func() {
var ingressSpecWithAnnotation = `
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: %s
annotations:
kubernetes.io/ingress.class: %s
spec:
rules:
- host: annotation.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpbin-service-e2e-test
port:
number: 80
`

It("kubernetes.io/ingress.class", func() {
By("create GatewayProxy")
err := s.CreateResourceFromString(s.GetGatewayProxySpec())
Expect(err).NotTo(HaveOccurred(), "creating GatewayProxy")
time.Sleep(5 * time.Second)

By("create IngressClass")
err = s.CreateResourceFromStringWithNamespace(s.GetIngressClassYaml(), s.Namespace())
Expect(err).NotTo(HaveOccurred(), "creating GatewayProxy")
time.Sleep(5 * time.Second)

By("create Ingress with annotation-defined class")
ingressName := s.Namespace() + "-annotation"
err = s.CreateResourceFromString(fmt.Sprintf(ingressSpecWithAnnotation, ingressName, s.Namespace()))
Expect(err).NotTo(HaveOccurred(), "creating Ingress with kubernetes.io/ingress.class annotation")

By("verify ingress served through annotated class")
s.RequestAssert(&scaffold.RequestAssert{
Method: "GET",
Path: "/get",
Host: "annotation.example.com",
Check: scaffold.WithExpectedStatus(http.StatusOK),
})
})
})

// Tests concerning the default ingress class need to be run serially
Context("IngressClass with GatewayProxy", Serial, func() {
gatewayProxyYaml := `
Expand Down
Loading