Skip to content

Commit

Permalink
feat: remove secretRef of plugins.config in v2beta3
Browse files Browse the repository at this point in the history
* remove secretRef of plugins.config in v2beta3
* add key logs output
* add test case to validate the plugins config priority
* add the corresponding doc section

Close #1408
  • Loading branch information
An-DJ committed Dec 6, 2022
1 parent 4e4e700 commit dd9e470
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 79 deletions.
45 changes: 45 additions & 0 deletions docs/en/latest/concepts/apisix_route.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,51 @@ spec:
enable: true
```

### Config with secretRef
Plugins are supported to be configured from kubernetes secret with `secretRef`.

The priority is `plugins.secretRef > plugins.config`. That is, the duplicated key in `plugins.config` are replaced by `plugins.secretRef`.

Example below configures echo plugin. The final values of `before_body`, `body` and `after_body` are "This is the replaced preface", "my custom body" and "This is the epilogue", respectively.
```yaml
apiVersion: v1
kind: Secret
metadata:
name: echo
data:
# content is "This is the replaced preface"
before_body: IlRoaXMgaXMgdGhlIHJlcGxhY2VkIHByZWZhY2Ui
# content is "my custom body"
body: Im15IGN1c3RvbSBib2R5Ig==
---
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
weight: 10
plugins:
- name: echo
enable: true
config:
before_body: "This is the preface"
after_body: "This is the epilogue"
headers:
X-Foo: v1
X-Foo2: v2
secretRef: echo
```

## Websocket proxy

You can route requests to [WebSocket](https://en.wikipedia.org/wiki/WebSocket#:~:text=WebSocket%20is%20a%20computer%20communications,WebSocket%20is%20distinct%20from%20HTTP.) services by setting the `websocket` attribute to `true` as shown below:
Expand Down
2 changes: 1 addition & 1 deletion pkg/kube/apisix/apis/config/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ type ApisixRoutePlugin struct {
// Plugin configuration.
Config ApisixRoutePluginConfig `json:"config" yaml:"config"`
// Plugin configuration secretRef.
SecretConfig string `json:"secretConfig" yaml:"secretConfig"`
SecretRef string `json:"secretRef" yaml:"secretRef"`
}

// ApisixRoutePluginConfig is the configuration for
Expand Down
2 changes: 0 additions & 2 deletions pkg/kube/apisix/apis/config/v2beta3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ type ApisixRouteHTTPPlugin struct {
Enable bool `json:"enable" yaml:"enable"`
// Plugin configuration.
Config ApisixRouteHTTPPluginConfig `json:"config" yaml:"config"`
// Plugin configuration secretRef.
SecretConfig string `json:"secretConfig" yaml:"secretConfig"`
}

// ApisixRouteHTTPPluginConfig is the configuration for
Expand Down
17 changes: 11 additions & 6 deletions pkg/providers/apisix/translation/apisix_pluginconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ func (t *translator) TranslatePluginConfigV2beta3(config *configv2beta3.ApisixPl
zap.Any("new", plugin.Config),
)
}
if sec, err := t.SecretLister.Secrets(config.Namespace).Get(plugin.SecretConfig); err == nil {
for key, value := range sec.Data {
plugin.Config[key] = string(value)
}
}
pluginMap[plugin.Name] = plugin.Config
} else {
pluginMap[plugin.Name] = make(map[string]interface{})
Expand Down Expand Up @@ -87,7 +82,17 @@ func (t *translator) TranslatePluginConfigV2(config *configv2.ApisixPluginConfig
zap.Any("new", plugin.Config),
)
}
if sec, err := t.SecretLister.Secrets(config.Namespace).Get(plugin.SecretConfig); err == nil {
if plugin.SecretRef != "" {
sec, err := t.SecretLister.Secrets(config.Namespace).Get(plugin.SecretRef)
if err != nil {
log.Errorw("The config secretRef is invalid",
zap.Any("plugin", plugin.Name),
zap.String("secretRef", plugin.SecretRef))
break
}
log.Debugw("Add new items, then override items with the same plugin key",
zap.Any("plugin", plugin.Name),
zap.String("secretRef", plugin.SecretRef))
for key, value := range sec.Data {
plugin.Config[key] = string(value)
}
Expand Down
29 changes: 22 additions & 7 deletions pkg/providers/apisix/translation/apisix_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,6 @@ func (t *translator) translateHTTPRouteV2beta3(ctx *translation.TranslateContext
continue
}
if plugin.Config != nil {
if sec, err := t.SecretLister.Secrets(ar.Namespace).Get(plugin.SecretConfig); err == nil {
for key, value := range sec.Data {
plugin.Config[key] = string(value)
}
}
pluginMap[plugin.Name] = plugin.Config
} else {
pluginMap[plugin.Name] = make(map[string]interface{})
Expand Down Expand Up @@ -256,7 +251,17 @@ func (t *translator) translateHTTPRouteV2(ctx *translation.TranslateContext, ar
continue
}
if plugin.Config != nil {
if sec, err := t.SecretLister.Secrets(ar.Namespace).Get(plugin.SecretConfig); err == nil {
if plugin.SecretRef != "" {
sec, err := t.SecretLister.Secrets(ar.Namespace).Get(plugin.SecretRef)
if err != nil {
log.Errorw("The config secretRef is invalid",
zap.Any("plugin", plugin.Name),
zap.String("secretRef", plugin.SecretRef))
break
}
log.Debugw("Add new items, then override items with the same plugin key",
zap.Any("plugin", plugin.Name),
zap.String("secretRef", plugin.SecretRef))
for key, value := range sec.Data {
plugin.Config[key] = string(value)
}
Expand Down Expand Up @@ -763,7 +768,17 @@ func (t *translator) translateStreamRouteV2(ctx *translation.TranslateContext, a
continue
}
if plugin.Config != nil {
if sec, err := t.SecretLister.Secrets(ar.Namespace).Get(plugin.SecretConfig); err == nil {
if plugin.SecretRef != "" {
sec, err := t.SecretLister.Secrets(ar.Namespace).Get(plugin.SecretRef)
if err != nil {
log.Errorw("The config secretRef is invalid",
zap.Any("plugin", plugin.Name),
zap.String("secretRef", plugin.SecretRef))
break
}
log.Debugw("Add new items, then override items with the same plugin key",
zap.Any("plugin", plugin.Name),
zap.String("secretRef", plugin.SecretRef))
for key, value := range sec.Data {
plugin.Config[key] = string(value)
}
Expand Down
4 changes: 1 addition & 3 deletions samples/deploy/crd/v1/ApisixPluginConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ spec:
config:
type: object
x-kubernetes-preserve-unknown-fields: true # we have to enable it since plugin config
secretConfig:
type: string
required:
- name
- enable
Expand Down Expand Up @@ -116,7 +114,7 @@ spec:
config:
type: object
x-kubernetes-preserve-unknown-fields: true # we have to enable it since plugin config
secretConfig:
secretRef:
type: string
required:
- name
Expand Down
6 changes: 2 additions & 4 deletions samples/deploy/crd/v1/ApisixRoute.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,6 @@ spec:
config:
type: object
x-kubernetes-preserve-unknown-fields: true # we have to enable it since plugin config
secretConfig:
type: string
required:
- name
- enable
Expand Down Expand Up @@ -506,7 +504,7 @@ spec:
config:
type: object
x-kubernetes-preserve-unknown-fields: true # we have to enable it since plugin config
secretConfig:
secretRef:
type: string
required:
- name
Expand Down Expand Up @@ -596,7 +594,7 @@ spec:
config:
type: object
x-kubernetes-preserve-unknown-fields: true # we have to enable it since plugin config
secretConfig:
secretRef:
type: string
required:
- name
Expand Down
56 changes: 0 additions & 56 deletions test/e2e/suite-plugins/suite-plugins-general/echo.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,62 +57,6 @@ spec:
X-Foo: v1
X-Foo2: v2
`, backendSvc, backendPorts[0])

assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixResource(ar))

err := s.EnsureNumApisixUpstreamsCreated(1)
assert.Nil(ginkgo.GinkgoT(), err, "Checking number of upstreams")
err = s.EnsureNumApisixRoutesCreated(1)
assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")

resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect()
resp.Status(http.StatusOK)
resp.Header("X-Foo").Equal("v1")
resp.Header("X-Foo2").Equal("v2")
resp.Body().Contains("This is the preface")
resp.Body().Contains("origin")
resp.Body().Contains("This is the epilogue")
})

ginkgo.It("suite-plugins-general: echo plugin with secretConfig", func() {
backendSvc, backendPorts := s.DefaultHTTPBackend()
secret := `
apiVersion: v1
kind: Secret
metadata:
name: echo
data:
before_body: IlRoaXMgaXMgdGhlIHByZWZhY2Ui
after_body: IlRoaXMgaXMgdGhlIGVwaWxvZ3VlIg==
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating echo secret for ApisixRoute")
ar := fmt.Sprintf(`
apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
hosts:
- httpbin.org
paths:
- /ip
backends:
- serviceName: %s
servicePort: %d
weight: 10
plugins:
- name: echo
enable: true
config:
headers:
X-Foo: v1
X-Foo2: v2
secretConfig: echo
`, backendSvc, backendPorts[0])

assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixResource(ar))
Expand Down
93 changes: 93 additions & 0 deletions test/e2e/suite-plugins/suite-plugins-general/secret_ref.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// 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 plugins

import (
"fmt"
ginkgo "github.com/onsi/ginkgo/v2"
"github.com/stretchr/testify/assert"
"net/http"

"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
)

var _ = ginkgo.Describe("suite-plugins-general: config plugin with secretRef", func() {
suites := func(scaffoldFunc func() *scaffold.Scaffold) {
s := scaffoldFunc()
ginkgo.It("suite-plugins-general: echo plugin config with secretRef", func() {
backendSvc, backendPorts := s.DefaultHTTPBackend()
secret := `
apiVersion: v1
kind: Secret
metadata:
name: echo
data:
# content is "This is the replaced preface"
before_body: IlRoaXMgaXMgdGhlIHJlcGxhY2VkIHByZWZhY2Ui
# content is "my custom body"
body: Im15IGN1c3RvbSBib2R5Ig==
`
assert.Nil(ginkgo.GinkgoT(), s.CreateResourceFromString(secret), "creating echo secret for ApisixRoute")
ar := 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
weight: 10
plugins:
- name: echo
enable: true
config:
before_body: "This is the preface"
after_body: "This is the epilogue"
headers:
X-Foo: v1
X-Foo2: v2
secretRef: echo
`, backendSvc, backendPorts[0])

assert.Nil(ginkgo.GinkgoT(), s.CreateVersionedApisixResource(ar))

err := s.EnsureNumApisixUpstreamsCreated(1)
assert.Nil(ginkgo.GinkgoT(), err, "Checking number of upstreams")
err = s.EnsureNumApisixRoutesCreated(1)
assert.Nil(ginkgo.GinkgoT(), err, "Checking number of routes")

resp := s.NewAPISIXClient().GET("/ip").WithHeader("Host", "httpbin.org").Expect()
resp.Status(http.StatusOK)
resp.Header("X-Foo").Equal("v1")
resp.Header("X-Foo2").Equal("v2")
resp.Body().Contains("This is the replaced preface")
resp.Body().Contains("This is the epilogue")
resp.Body().Contains("my custom body")
})
}
ginkgo.Describe("suite-plugins-general: scaffold v2", func() {
suites(scaffold.NewDefaultV2Scaffold)
})
})

0 comments on commit dd9e470

Please sign in to comment.