Skip to content

Commit

Permalink
feat: ApisixConsumer support ingressClass (#1717)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlinsRan authored Mar 16, 2023
1 parent 3abe8af commit 07c7d9d
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 6 deletions.
7 changes: 7 additions & 0 deletions pkg/kube/apisix/apis/config/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,13 @@ type ApisixConsumer struct {

// ApisixConsumerSpec defines the desired state of ApisixConsumer.
type ApisixConsumerSpec struct {
// IngressClassName is the name of an IngressClass cluster resource.
// controller implementations use this field to know whether they should be
// serving this ApisixConsumer resource, by a transitive connection
// (controller -> IngressClass -> ApisixConsumer resource).
// +optional
IngressClassName string `json:"ingressClassName,omitempty" yaml:"ingressClassName,omitempty"`

AuthParameter ApisixConsumerAuthParameter `json:"authParameter" yaml:"authParameter"`
}

Expand Down
22 changes: 21 additions & 1 deletion pkg/providers/apisix/apisix_consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ func (c *apisixConsumerController) onAdd(obj interface{}) {
if !c.namespaceProvider.IsWatchingNamespace(key) {
return
}
if !c.isEffective(ac) {
return
}
log.Debugw("ApisixConsumer add event arrived",
zap.Any("object", obj),
)
Expand Down Expand Up @@ -269,6 +272,9 @@ func (c *apisixConsumerController) onUpdate(oldObj, newObj interface{}) {
if !c.namespaceProvider.IsWatchingNamespace(key) {
return
}
if !c.isEffective(curr) {
return
}
log.Debugw("ApisixConsumer update event arrived",
zap.Any("new object", curr),
zap.Any("old object", prev),
Expand Down Expand Up @@ -308,6 +314,9 @@ func (c *apisixConsumerController) onDelete(obj interface{}) {
if !c.namespaceProvider.IsWatchingNamespace(key) {
return
}
if !c.isEffective(ac) {
return
}
log.Debugw("ApisixConsumer delete event arrived",
zap.Any("final state", ac),
)
Expand Down Expand Up @@ -337,7 +346,10 @@ func (c *apisixConsumerController) ResourceSync() {
ac, err := kube.NewApisixConsumer(obj)
if err != nil {
log.Errorw("found ApisixConsumer resource with bad type", zap.String("error", err.Error()))
return
continue
}
if !c.isEffective(ac) {
continue
}
c.workqueue.Add(&types.Event{
Type: types.EventAdd,
Expand Down Expand Up @@ -412,3 +424,11 @@ func (c *apisixConsumerController) recordStatus(at interface{}, reason string, e
log.Errorf("unsupported resource record: %s", v)
}
}

func (c *apisixConsumerController) isEffective(ac kube.ApisixConsumer) bool {
if ac.GroupVersion() == config.ApisixV2 {
return utils.MatchCRDsIngressClass(ac.V2().Spec.IngressClassName, c.Kubernetes.IngressClass)
}
// Compatible with legacy versions
return true
}
2 changes: 2 additions & 0 deletions samples/deploy/crd/v1/ApisixConsumer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ spec:
required:
- authParameter
properties:
ingressClassName:
type: string
authParameter:
type: object
oneOf:
Expand Down
177 changes: 172 additions & 5 deletions test/e2e/suite-ingress/suite-ingress-features/ingress-class.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ spec:
ups, err := s.ListApisixUpstreams()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), ups, 1)
assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 3)
assert.Equal(ginkgo.GinkgoT(), 3, *ups[0].Retries)

au = fmt.Sprintf(`
apiVersion: apisix.apache.org/v2
Expand All @@ -182,7 +182,7 @@ spec:
ups, err = s.ListApisixUpstreams()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), ups, 1)
assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 2)
assert.Equal(ginkgo.GinkgoT(), 2, *ups[0].Retries)

s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect().Status(http.StatusOK)
})
Expand Down Expand Up @@ -379,6 +379,99 @@ spec:
assert.Nil(ginkgo.GinkgoT(), err, "list tls error")
assert.Len(ginkgo.GinkgoT(), tls, 0, "tls number not expect")
})

ginkgo.It("ApisixConsumer should be ignored", func() {
// create ApisixConsumer resource with ingressClassName: ignore
ac := `
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: jack
spec:
ingressClassName: ignore
authParameter:
keyAuth:
value:
key: jack-key
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac))
time.Sleep(6 * time.Second)
acs, err := s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 0)

// update ApisixConsumer resource with ingressClassName: ignore2
ac = `
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: jack
spec:
ingressClassName: ignore2
authParameter:
keyAuth:
value:
key: jack-key
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac))
time.Sleep(6 * time.Second)

acs, err = s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 0)
})

ginkgo.It("ApisixConsumer should be handled", func() {
// create ApisixConsumer resource withoutput ingressClassName
ac := `
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: jack
spec:
authParameter:
keyAuth:
value:
key: jack-key
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac))
time.Sleep(6 * time.Second)

acs, err := s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 1)
assert.Contains(ginkgo.GinkgoT(), acs[0].Username, "jack")
assert.Equal(ginkgo.GinkgoT(), map[string]interface{}{"key": "jack-key"}, acs[0].Plugins["key-auth"])

// delete ApisixConsumer
assert.Nil(ginkgo.GinkgoT(), s.DeleteResourceFromString(ac))
time.Sleep(6 * time.Second)
acs, err = s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 0)

// create ApisixConsumer resource with ingressClassName: apisix
ac = `
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: james
spec:
ingressClassName: apisix
authParameter:
keyAuth:
value:
key: james-key
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac))
time.Sleep(6 * time.Second)

acs, err = s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 1)
assert.Contains(ginkgo.GinkgoT(), acs[0].Username, "james")
assert.Equal(ginkgo.GinkgoT(), map[string]interface{}{"key": "james-key"}, acs[0].Plugins["key-auth"])
})
})

var _ = ginkgo.Describe("suite-ingress-features: Testing CRDs with IngressClass apisix-and-all", func() {
Expand Down Expand Up @@ -424,7 +517,7 @@ spec:
ups, err := s.ListApisixUpstreams()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), ups, 1)
assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 3)
assert.Equal(ginkgo.GinkgoT(), 3, *ups[0].Retries)

au = fmt.Sprintf(`
apiVersion: apisix.apache.org/v2
Expand All @@ -441,7 +534,7 @@ spec:
ups, err = s.ListApisixUpstreams()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), ups, 1)
assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 2)
assert.Equal(ginkgo.GinkgoT(), 2, *ups[0].Retries)

s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect().Status(http.StatusOK)

Expand All @@ -460,7 +553,7 @@ spec:
ups, err = s.ListApisixUpstreams()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), ups, 1)
assert.Equal(ginkgo.GinkgoT(), *ups[0].Retries, 1)
assert.Equal(ginkgo.GinkgoT(), 1, *ups[0].Retries)

s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect().Status(http.StatusOK)
})
Expand Down Expand Up @@ -603,4 +696,78 @@ spec:
assert.Len(ginkgo.GinkgoT(), tls, 1, "tls number not expect")
assert.Equal(ginkgo.GinkgoT(), tls[0].Snis[0], host3, "tls host is error")
})

ginkgo.It("ApisixConsumer should be handled", func() {
// create ApisixConsumer resource withoutput ingressClassName
ac := `
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: jack
spec:
authParameter:
keyAuth:
value:
key: jack-key
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac))
time.Sleep(6 * time.Second)

acs, err := s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 1)
assert.Contains(ginkgo.GinkgoT(), acs[0].Username, "jack")
assert.Equal(ginkgo.GinkgoT(), map[string]interface{}{"key": "jack-key"}, acs[0].Plugins["key-auth"])

// delete ApisixConsumer
assert.Nil(ginkgo.GinkgoT(), s.DeleteResourceFromString(ac))
time.Sleep(6 * time.Second)
acs, err = s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 0)

// create ApisixConsumer resource with ingressClassName: apisix
ac = `
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: james
spec:
ingressClassName: apisix
authParameter:
keyAuth:
value:
key: james-key
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac))
time.Sleep(6 * time.Second)

acs, err = s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 1)
assert.Contains(ginkgo.GinkgoT(), acs[0].Username, "james")
assert.Equal(ginkgo.GinkgoT(), map[string]interface{}{"key": "james-key"}, acs[0].Plugins["key-auth"])

// update ApisixConsumer resource with ingressClassName: watch
ac = `
apiVersion: apisix.apache.org/v2
kind: ApisixConsumer
metadata:
name: james
spec:
ingressClassName: watch
authParameter:
keyAuth:
value:
key: james-password
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(ac))
time.Sleep(6 * time.Second)

acs, err = s.ListApisixConsumers()
assert.Nil(ginkgo.GinkgoT(), err)
assert.Len(ginkgo.GinkgoT(), acs, 1)
assert.Contains(ginkgo.GinkgoT(), acs[0].Username, "james")
assert.Equal(ginkgo.GinkgoT(), map[string]interface{}{"key": "james-password"}, acs[0].Plugins["key-auth"])
})
})

0 comments on commit 07c7d9d

Please sign in to comment.