This is an automated email from the ASF dual-hosted git repository.

zhangjintao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git


The following commit(s) were added to refs/heads/master by this push:
     new 5fcd3d0e feat: ApisixUpstream support IngressClass (#1674)
5fcd3d0e is described below

commit 5fcd3d0ed720b994447ca190127d9d137494b24b
Author: Xin Rong <[email protected]>
AuthorDate: Mon Mar 6 17:00:34 2023 +0800

    feat: ApisixUpstream support IngressClass (#1674)
---
 cmd/ingress/ingress.go                             |   2 +-
 conf/config-default.yaml                           |   3 +-
 pkg/config/config.go                               |   5 +-
 pkg/kube/apisix/apis/config/v2/types.go            |   6 +
 pkg/providers/apisix/apisix_upstream.go            |  19 ++
 pkg/providers/apisix/provider.go                   |   1 +
 pkg/providers/apisix/translation/translator.go     |   5 +-
 pkg/providers/controller.go                        |   1 +
 pkg/providers/ingress/ingress.go                   |  13 +-
 pkg/providers/k8s/endpoint/base.go                 |   7 +-
 pkg/providers/translation/service.go               |  21 +-
 pkg/providers/translation/translator.go            |   3 +-
 pkg/providers/utils/ingress_class.go               |  31 +++
 samples/deploy/crd/v1/ApisixUpstream.yaml          |   2 +
 test/e2e/scaffold/ingress.go                       |   6 +-
 test/e2e/scaffold/scaffold.go                      |   4 +
 .../suite-ingress-features/ingress-class.go        | 223 +++++++++++++++++++++
 17 files changed, 336 insertions(+), 16 deletions(-)

diff --git a/cmd/ingress/ingress.go b/cmd/ingress/ingress.go
index 7b84d8e3..038705d0 100644
--- a/cmd/ingress/ingress.go
+++ b/cmd/ingress/ingress.go
@@ -180,7 +180,7 @@ For example, no available LB exists in the bare metal 
environment.`)
        cmd.PersistentFlags().StringVar(&cfg.Kubernetes.Kubeconfig, 
"kubeconfig", "", "Kubernetes configuration file (by default in-cluster 
configuration will be used)")
        
cmd.PersistentFlags().DurationVar(&cfg.Kubernetes.ResyncInterval.Duration, 
"resync-interval", time.Minute, "the controller resync (with Kubernetes) 
interval, the minimum resync interval is 30s")
        cmd.PersistentFlags().StringSliceVar(&cfg.Kubernetes.NamespaceSelector, 
"namespace-selector", []string{""}, "labels that controller used to select 
namespaces which will watch for resources")
-       cmd.PersistentFlags().StringVar(&cfg.Kubernetes.IngressClass, 
"ingress-class", config.IngressClass, "the class of an Ingress object is set 
using the field IngressClassName in Kubernetes clusters version v1.18.0 or 
higher or the annotation \"kubernetes.io/ingress.class\" (deprecated)")
+       cmd.PersistentFlags().StringVar(&cfg.Kubernetes.IngressClass, 
"ingress-class", config.IngressClassApisixAndAll, "apisix-and-all is a special 
value, it handles Ingress resources with ingressClassName=apisix and all CRDs, 
the class of an Ingress object is set using the field IngressClassName in 
Kubernetes clusters version v1.18.0 or higher or the annotation 
\"kubernetes.io/ingress.class\" (deprecated)")
        cmd.PersistentFlags().StringVar(&cfg.Kubernetes.ElectionID, 
"election-id", config.IngressAPISIXLeader, "election id used for campaign the 
controller leader")
        cmd.PersistentFlags().StringVar(&cfg.Kubernetes.IngressVersion, 
"ingress-version", config.IngressNetworkingV1, "the supported ingress api group 
version, can be \"networking/v1beta1\", \"networking/v1\" (for Kubernetes 
version v1.19.0 or higher) and \"extensions/v1beta1\"")
        cmd.PersistentFlags().StringVar(&cfg.Kubernetes.APIVersion, 
"api-version", config.DefaultAPIVersion, config.APIVersionDescribe)
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index 9b3570a0..c80c3b37 100644
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -64,7 +64,8 @@ kubernetes:
   election_id: "ingress-apisix-leader" # the election id for the controller 
leader campaign,
                                        # only the leader will watch and 
delivery resource changes,
                                        # other instances (as candidates) stand 
by.
-  ingress_class: "apisix"              # the class of an Ingress object is set 
using the field
+  ingress_class: "apisix-and-all"      # apisix-and-all is a special value, it 
handles Ingress resources with ingressClassName=apisix and all CRDs.
+                                       # this field can be used for both 
Ingress Object and custom resources.
                                        # IngressClassName in Kubernetes 
clusters version v1.18.0
                                        # or higher or the annotation 
"kubernetes.io/ingress.class"
                                        # (deprecated).
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 2e7c63f2..d7ca396b 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -59,6 +59,9 @@ const (
        // ControllerName is the name of the controller used to identify
        // the controller of the GatewayClass.
        ControllerName = "apisix.apache.org/gateway-controller"
+
+       // Process Ingress resources with ingressClass=apisix and all CRDs
+       IngressClassApisixAndAll = "apisix-and-all"
 )
 
 var (
@@ -137,7 +140,7 @@ func NewDefaultConfig() *Config {
                        Kubeconfig:           "", // Use in-cluster 
configurations.
                        ResyncInterval:       types.TimeDuration{Duration: 6 * 
time.Hour},
                        ElectionID:           IngressAPISIXLeader,
-                       IngressClass:         IngressClass,
+                       IngressClass:         IngressClassApisixAndAll,
                        IngressVersion:       IngressNetworkingV1,
                        APIVersion:           DefaultAPIVersion,
                        WatchEndpointSlices:  false,
diff --git a/pkg/kube/apisix/apis/config/v2/types.go 
b/pkg/kube/apisix/apis/config/v2/types.go
index 6cef777e..ae518a5e 100644
--- a/pkg/kube/apisix/apis/config/v2/types.go
+++ b/pkg/kube/apisix/apis/config/v2/types.go
@@ -479,6 +479,12 @@ type ApisixUpstream struct {
 
 // ApisixUpstreamSpec describes the specification of ApisixUpstream.
 type ApisixUpstreamSpec struct {
+       // IngressClassName is the name of an IngressClass cluster resource.
+       // controller implementations use this field to know whether they 
should be
+       // serving this ApisixUpstream resource, by a transitive connection
+       // (controller -> IngressClass -> ApisixUpstream resource).
+       // +optional
+       IngressClassName string `json:"ingressClassName,omitempty" 
yaml:"ingressClassName,omitempty"`
        // ExternalNodes contains external nodes the Upstream should use
        // If this field is set, the upstream will use these nodes directly 
without any further resolves
        // +optional
diff --git a/pkg/providers/apisix/apisix_upstream.go 
b/pkg/providers/apisix/apisix_upstream.go
index afbfebe5..dbe6b7e8 100644
--- a/pkg/providers/apisix/apisix_upstream.go
+++ b/pkg/providers/apisix/apisix_upstream.go
@@ -546,6 +546,9 @@ func (c *apisixUpstreamController) onAdd(obj interface{}) {
        if !c.namespaceProvider.IsWatchingNamespace(key) {
                return
        }
+       if !c.isEffective(au) {
+               return
+       }
        log.Debugw("ApisixUpstream add event arrived",
                zap.Any("object", obj))
 
@@ -582,6 +585,9 @@ func (c *apisixUpstreamController) onUpdate(oldObj, newObj 
interface{}) {
        if !c.namespaceProvider.IsWatchingNamespace(key) {
                return
        }
+       if !c.isEffective(curr) {
+               return
+       }
        log.Debugw("ApisixUpstream update event arrived",
                zap.Any("new object", curr),
                zap.Any("old object", prev),
@@ -621,6 +627,9 @@ func (c *apisixUpstreamController) onDelete(obj 
interface{}) {
        if !c.namespaceProvider.IsWatchingNamespace(key) {
                return
        }
+       if !c.isEffective(au) {
+               return
+       }
        log.Debugw("ApisixUpstream delete event arrived",
                zap.Any("final state", au),
        )
@@ -866,3 +875,13 @@ func (c *apisixUpstreamController) recordStatus(at 
interface{}, reason string, e
                log.Errorf("unsupported resource record: %s", v)
        }
 }
+
+func (c *apisixUpstreamController) isEffective(au kube.ApisixUpstream) bool {
+       if au.GroupVersion() == config.ApisixV2 {
+               if au.V2().Spec != nil {
+                       return 
utils.MatchCRDsIngressClass(au.V2().Spec.IngressClassName, 
c.Kubernetes.IngressClass)
+               }
+       }
+       // Compatible with legacy versions
+       return true
+}
diff --git a/pkg/providers/apisix/provider.go b/pkg/providers/apisix/provider.go
index 503b0723..9a3e5fe3 100644
--- a/pkg/providers/apisix/provider.go
+++ b/pkg/providers/apisix/provider.go
@@ -80,6 +80,7 @@ func NewProvider(common *providertypes.Common, 
namespaceProvider namespace.Watch
        p.apisixTranslator = 
apisixtranslation.NewApisixTranslator(&apisixtranslation.TranslatorOptions{
                Apisix:               common.APISIX,
                ClusterName:          common.Config.APISIX.DefaultClusterName,
+               IngressClassName:     common.Config.Kubernetes.IngressClass,
                ServiceLister:        common.SvcLister,
                ApisixUpstreamLister: common.ApisixUpstreamLister,
                SecretLister:         common.SecretLister,
diff --git a/pkg/providers/apisix/translation/translator.go 
b/pkg/providers/apisix/translation/translator.go
index 192f4cd7..3dd23cde 100644
--- a/pkg/providers/apisix/translation/translator.go
+++ b/pkg/providers/apisix/translation/translator.go
@@ -28,8 +28,9 @@ import (
 )
 
 type TranslatorOptions struct {
-       Apisix      apisix.APISIX
-       ClusterName string
+       Apisix           apisix.APISIX
+       ClusterName      string
+       IngressClassName string
 
        ApisixUpstreamLister kube.ApisixUpstreamLister
        ServiceLister        listerscorev1.ServiceLister
diff --git a/pkg/providers/controller.go b/pkg/providers/controller.go
index 9a977044..74250380 100644
--- a/pkg/providers/controller.go
+++ b/pkg/providers/controller.go
@@ -435,6 +435,7 @@ func (c *Controller) run(ctx context.Context) {
                PodLister:            c.informers.PodLister,
                ApisixUpstreamLister: c.informers.ApisixUpstreamLister,
                PodProvider:          c.podProvider,
+               IngressClassName:     c.cfg.Kubernetes.IngressClass,
        })
 
        c.apisixProvider, c.apisixTranslator, err = 
apisixprovider.NewProvider(common, c.namespaceProvider, c.translator)
diff --git a/pkg/providers/ingress/ingress.go b/pkg/providers/ingress/ingress.go
index 7c3d405b..8f09aaaa 100644
--- a/pkg/providers/ingress/ingress.go
+++ b/pkg/providers/ingress/ingress.go
@@ -32,6 +32,7 @@ import (
        "k8s.io/client-go/tools/cache"
        "k8s.io/client-go/util/workqueue"
 
+       "github.com/apache/apisix-ingress-controller/pkg/config"
        "github.com/apache/apisix-ingress-controller/pkg/kube"
        "github.com/apache/apisix-ingress-controller/pkg/log"
        "github.com/apache/apisix-ingress-controller/pkg/providers/translation"
@@ -411,8 +412,9 @@ func (c *ingressController) OnDelete(obj interface{}) {
 
 func (c *ingressController) isIngressEffective(ing kube.Ingress) bool {
        var (
-               ic  *string
-               ica string
+               ic                 *string
+               ica                string
+               configIngressClass = c.Kubernetes.IngressClass
        )
        if ing.GroupVersion() == kube.IngressV1 {
                ic = ing.V1().Spec.IngressClassName
@@ -424,13 +426,16 @@ func (c *ingressController) isIngressEffective(ing 
kube.Ingress) bool {
                ic = ing.ExtensionsV1beta1().Spec.IngressClassName
                ica = ing.ExtensionsV1beta1().GetAnnotations()[_ingressKey]
        }
+       if configIngressClass == config.IngressClassApisixAndAll {
+               configIngressClass = config.IngressClass
+       }
 
        // kubernetes.io/ingress.class takes the precedence.
        if ica != "" {
-               return ica == c.Kubernetes.IngressClass
+               return ica == configIngressClass
        }
        if ic != nil {
-               return *ic == c.Kubernetes.IngressClass
+               return *ic == configIngressClass
        }
        return false
 }
diff --git a/pkg/providers/k8s/endpoint/base.go 
b/pkg/providers/k8s/endpoint/base.go
index 91d462af..ee5d6f78 100644
--- a/pkg/providers/k8s/endpoint/base.go
+++ b/pkg/providers/k8s/endpoint/base.go
@@ -31,6 +31,7 @@ import (
        "github.com/apache/apisix-ingress-controller/pkg/log"
        "github.com/apache/apisix-ingress-controller/pkg/providers/translation"
        providertypes 
"github.com/apache/apisix-ingress-controller/pkg/providers/types"
+       "github.com/apache/apisix-ingress-controller/pkg/providers/utils"
        "github.com/apache/apisix-ingress-controller/pkg/types"
        apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
@@ -98,12 +99,16 @@ func (c *baseEndpointController) syncEndpoint(ctx 
context.Context, ep kube.Endpo
                var subsets []configv2.ApisixUpstreamSubset
                subsets = append(subsets, configv2.ApisixUpstreamSubset{})
                auKube, err := c.apisixUpstreamLister.V2(namespace, svcName)
+               if auKube != nil && auKube.V2().Spec != nil &&
+                       
!utils.MatchCRDsIngressClass(auKube.V2().Spec.IngressClassName, 
c.Kubernetes.IngressClass) {
+                       auKube = nil
+               }
                if err != nil {
                        if !k8serrors.IsNotFound(err) {
                                log.Errorf("failed to get ApisixUpstream %s/%s: 
%s", namespace, svcName, err)
                                return err
                        }
-               } else if auKube.V2().Spec != nil && 
len(auKube.V2().Spec.Subsets) > 0 {
+               } else if auKube != nil && auKube.V2().Spec != nil && 
len(auKube.V2().Spec.Subsets) > 0 {
                        subsets = append(subsets, auKube.V2().Spec.Subsets...)
                }
                clusters := c.APISIX.ListClusters()
diff --git a/pkg/providers/translation/service.go 
b/pkg/providers/translation/service.go
index 2c097eaa..c06a149a 100644
--- a/pkg/providers/translation/service.go
+++ b/pkg/providers/translation/service.go
@@ -25,7 +25,9 @@ import (
 
        "github.com/apache/apisix-ingress-controller/pkg/config"
        "github.com/apache/apisix-ingress-controller/pkg/kube"
+       v2 
"github.com/apache/apisix-ingress-controller/pkg/kube/apisix/apis/config/v2"
        "github.com/apache/apisix-ingress-controller/pkg/log"
+       "github.com/apache/apisix-ingress-controller/pkg/providers/utils"
        "github.com/apache/apisix-ingress-controller/pkg/types"
        apisixv1 
"github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
 )
@@ -67,9 +69,23 @@ func (t *translator) translateUpstreamV2(ep *kube.Endpoint, 
namespace, name, sub
                        }
                }
        }
+       var (
+               subsets           []v2.ApisixUpstreamSubset
+               upsCfg            *v2.ApisixUpstreamConfig
+               portLevelSettings []v2.PortLevelSettings
+       )
+       if au != nil && au.V2().Spec != nil {
+               if !utils.MatchCRDsIngressClass(au.V2().Spec.IngressClassName, 
t.IngressClassName) {
+                       au = nil
+               } else {
+                       subsets = au.V2().Spec.Subsets
+                       upsCfg = &au.V2().Spec.ApisixUpstreamConfig
+                       portLevelSettings = au.V2().Spec.PortLevelSettings
+               }
+       }
        var labels types.Labels
        if subset != "" {
-               for _, ss := range au.V2().Spec.Subsets {
+               for _, ss := range subsets {
                        if ss.Name == subset {
                                labels = ss.Labels
                                break
@@ -86,8 +102,7 @@ func (t *translator) translateUpstreamV2(ep *kube.Endpoint, 
namespace, name, sub
                return ups, nil
        }
 
-       upsCfg := &au.V2().Spec.ApisixUpstreamConfig
-       for _, pls := range au.V2().Spec.PortLevelSettings {
+       for _, pls := range portLevelSettings {
                if pls.Port == port {
                        upsCfg = &pls.ApisixUpstreamConfig
                        break
diff --git a/pkg/providers/translation/translator.go 
b/pkg/providers/translation/translator.go
index 0627b6d0..f947ca90 100644
--- a/pkg/providers/translation/translator.go
+++ b/pkg/providers/translation/translator.go
@@ -66,7 +66,8 @@ type Translator interface {
 // TranslatorOptions contains options to help Translator
 // work well.
 type TranslatorOptions struct {
-       APIVersion string
+       APIVersion       string
+       IngressClassName string
 
        EndpointLister       kube.EndpointLister
        ServiceLister        listerscorev1.ServiceLister
diff --git a/pkg/providers/utils/ingress_class.go 
b/pkg/providers/utils/ingress_class.go
new file mode 100644
index 00000000..5b1c4cf8
--- /dev/null
+++ b/pkg/providers/utils/ingress_class.go
@@ -0,0 +1,31 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package utils
+
+import "github.com/apache/apisix-ingress-controller/pkg/config"
+
+func MatchCRDsIngressClass(resourceIngressClassName string, configIngressClass 
string) bool {
+       if configIngressClass == config.IngressClassApisixAndAll {
+               return true
+       }
+       if configIngressClass == "" {
+               return false
+       }
+
+       if resourceIngressClassName == "" || configIngressClass == 
resourceIngressClassName {
+               return true
+       }
+       return false
+}
diff --git a/samples/deploy/crd/v1/ApisixUpstream.yaml 
b/samples/deploy/crd/v1/ApisixUpstream.yaml
index 703c97b2..3bfcd5ac 100644
--- a/samples/deploy/crd/v1/ApisixUpstream.yaml
+++ b/samples/deploy/crd/v1/ApisixUpstream.yaml
@@ -432,6 +432,8 @@ spec:
             spec:
               type: object
               properties:
+                ingressClassName:
+                  type: string
                 discovery:
                   description: Discovery is used to configure service 
discovery for
                     upstream
diff --git a/test/e2e/scaffold/ingress.go b/test/e2e/scaffold/ingress.go
index 21b50e7c..baa17db5 100644
--- a/test/e2e/scaffold/ingress.go
+++ b/test/e2e/scaffold/ingress.go
@@ -398,6 +398,8 @@ spec:
             - "%s"
             - --enable-gateway-api
             - "true"
+            - --ingress-class
+            - %s
             %s
           %s
       volumes:
@@ -451,7 +453,7 @@ func (s *Scaffold) newIngressAPISIXController() error {
        }
 
        ingressAPISIXDeployment = 
fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate), 
s.opts.IngressAPISIXReplicas, s.namespace, s.opts.APISIXAdminAPIVersion, 
s.opts.ApisixResourceSyncInterval,
-               label, s.opts.ApisixResourceVersion, 
s.opts.APISIXPublishAddress, disableStatusStr, webhookVolumeMounts, 
_webhookCertSecret)
+               label, s.opts.ApisixResourceVersion, 
s.opts.APISIXPublishAddress, s.opts.IngressClass, disableStatusStr, 
webhookVolumeMounts, _webhookCertSecret)
 
        err = s.CreateResourceFromString(ingressAPISIXDeployment)
        assert.Nil(s.t, err, "create deployment")
@@ -572,7 +574,7 @@ func (s *Scaffold) ScaleIngressController(desired int) 
error {
 
        ingressDeployment = 
fmt.Sprintf(s.FormatRegistry(_ingressAPISIXDeploymentTemplate), desired, 
s.namespace,
                s.opts.APISIXAdminAPIVersion, 
s.opts.ApisixResourceSyncInterval, label, s.opts.ApisixResourceVersion, 
s.opts.APISIXPublishAddress,
-               disableStatusStr, webhookVolumeMounts, _webhookCertSecret)
+               s.opts.IngressClass, disableStatusStr, webhookVolumeMounts, 
_webhookCertSecret)
 
        if err := s.CreateResourceFromString(ingressDeployment); err != nil {
                return err
diff --git a/test/e2e/scaffold/scaffold.go b/test/e2e/scaffold/scaffold.go
index cf15b8a2..9052e113 100644
--- a/test/e2e/scaffold/scaffold.go
+++ b/test/e2e/scaffold/scaffold.go
@@ -60,6 +60,7 @@ type Options struct {
        ApisixResourceSyncInterval string
        ApisixResourceVersion      string
        DisableStatus              bool
+       IngressClass               string
 
        NamespaceSelectorLabel   map[string]string
        DisableNamespaceSelector bool
@@ -163,6 +164,9 @@ func NewScaffold(o *Options) *Scaffold {
        if o.HTTPBinServicePort == 0 {
                o.HTTPBinServicePort = 80
        }
+       if o.IngressClass == "" {
+               o.IngressClass = config.IngressClassApisixAndAll
+       }
        defer ginkgo.GinkgoRecover()
 
        s := &Scaffold{
diff --git a/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go 
b/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go
new file mode 100644
index 00000000..ef2face6
--- /dev/null
+++ b/test/e2e/suite-ingress/suite-ingress-features/ingress-class.go
@@ -0,0 +1,223 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package ingress
+
+import (
+       "fmt"
+       "net/http"
+       "time"
+
+       ginkgo "github.com/onsi/ginkgo/v2"
+       "github.com/stretchr/testify/assert"
+
+       "github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
+)
+
+var _ = ginkgo.Describe("suite-ingress-features: Testing CRDs with 
IngressClass", func() {
+       s := scaffold.NewScaffold(&scaffold.Options{
+               Name:                  "ingress-class",
+               IngressAPISIXReplicas: 1,
+               IngressClass:          "apisix",
+       })
+       ginkgo.It("ApisiUpstream should be ignored", func() {
+               backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+               au := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  name: %s
+spec:
+  ingressClassName: ignore
+  retries: 3
+`, backendSvc)
+               assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(au))
+               time.Sleep(6 * time.Second)
+
+               apisixRoute := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  name: httpbin-route
+spec:
+  http:
+  - name: rule1
+    match:
+      hosts:
+      - httpbin.org
+      paths:
+      - /ip
+    backends:
+    - serviceName: %s
+      servicePort: %d
+`, backendSvc, backendSvcPort[0])
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateResourceFromString(apisixRoute))
+               time.Sleep(6 * time.Second)
+
+               ups, err := s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Nil(ginkgo.GinkgoT(), ups[0].Retries)
+
+               err = s.EnsureNumApisixRoutesCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")
+               err = s.EnsureNumApisixUpstreamsCreated(1)
+               assert.Nil(ginkgo.GinkgoT(), err, "Checking number of 
upstreams")
+
+               s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect().Status(http.StatusOK)
+       })
+
+       ginkgo.It("ApisiUpstream should be handled", func() {
+               backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+               au := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  name: %s
+spec:
+  retries: 3
+`, backendSvc)
+               assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(au))
+               time.Sleep(6 * time.Second)
+
+               apisixRoute := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  name: httpbin-route
+spec:
+  http:
+  - name: rule1
+    match:
+      hosts:
+      - httpbin.org
+      paths:
+      - /ip
+    backends:
+    - serviceName: %s
+      servicePort: %d
+`, backendSvc, backendSvcPort[0])
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateResourceFromString(apisixRoute))
+               time.Sleep(6 * time.Second)
+
+               ups, err := s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 3)
+
+               au = fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  name: %s
+spec:
+  ingressClassName: apisix
+  retries: 2
+`, backendSvc)
+               assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(au))
+               time.Sleep(6 * time.Second)
+
+               ups, err = s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 2)
+
+               s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect().Status(http.StatusOK)
+       })
+})
+
+var _ = ginkgo.Describe("suite-ingress-features: Testing CRDs with 
IngressClass apisix-and-all", func() {
+       s := scaffold.NewScaffold(&scaffold.Options{
+               Name:                  "ingress-class",
+               IngressAPISIXReplicas: 1,
+               IngressClass:          "apisix-and-all",
+       })
+
+       ginkgo.It("ApisiUpstream should be handled", func() {
+               backendSvc, backendSvcPort := s.DefaultHTTPBackend()
+               au := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  name: %s
+spec:
+  retries: 3
+`, backendSvc)
+               assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(au))
+               time.Sleep(6 * time.Second)
+
+               apisixRoute := fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+  name: httpbin-route
+spec:
+  http:
+  - name: rule1
+    match:
+      hosts:
+      - httpbin.org
+      paths:
+      - /ip
+    backends:
+    - serviceName: %s
+      servicePort: %d
+`, backendSvc, backendSvcPort[0])
+               assert.Nil(ginkgo.GinkgoT(), 
s.CreateResourceFromString(apisixRoute))
+               time.Sleep(6 * time.Second)
+
+               ups, err := s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 3)
+
+               au = fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  name: %s
+spec:
+  ingressClassName: apisix
+  retries: 2
+`, backendSvc)
+               assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(au))
+               time.Sleep(6 * time.Second)
+
+               ups, err = s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 2)
+
+               s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect().Status(http.StatusOK)
+
+               au = fmt.Sprintf(`
+apiVersion: apisix.apache.org/v2
+kind: ApisixUpstream
+metadata:
+  name: %s
+spec:
+  ingressClassName: watch
+  retries: 1
+`, backendSvc)
+               assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(au))
+               time.Sleep(6 * time.Second)
+
+               ups, err = s.ListApisixUpstreams()
+               assert.Nil(ginkgo.GinkgoT(), err)
+               assert.Len(ginkgo.GinkgoT(), ups, 1)
+               assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 1)
+
+               s.NewAPISIXClient().GET("/ip").WithHeader("Host", 
"httpbin.org").Expect().Status(http.StatusOK)
+       })
+})

Reply via email to