Skip to content

Commit f83fca9

Browse files
authored
feat: gateway proxy plugin metadata (#69)
1 parent 3566e18 commit f83fca9

File tree

8 files changed

+146
-33
lines changed

8 files changed

+146
-33
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ $(GOLANGCI_LINT): $(LOCALBIN)
261261

262262
gofmt: ## Apply go fmt
263263
@gofmt -w -r 'interface{} -> any' .
264+
@gofmt -w -r 'FIt -> It' test
265+
@gofmt -w -r 'FContext -> Context' test
266+
@gofmt -w -r 'FDescribe -> Describe' test
267+
@gofmt -w -r 'FDescribeTable -> DescribeTable' test
264268
@go fmt ./...
265269
.PHONY: gofmt
266270

internal/provider/adc/adc.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,19 @@ func New() (provider.Provider, error) {
4646

4747
func (d *adcClient) Update(ctx context.Context, tctx *provider.TranslateContext, obj client.Object) error {
4848
log.Debugw("updating object", zap.Any("object", obj))
49+
var (
50+
result *translator.TranslateResult
51+
resourceTypes []string
52+
err error
53+
)
4954

50-
var result *translator.TranslateResult
51-
var resourceTypes []string
52-
var err error
53-
54-
switch obj := obj.(type) {
55+
switch t := obj.(type) {
5556
case *gatewayv1.HTTPRoute:
56-
result, err = d.translator.TranslateHTTPRoute(tctx, obj.DeepCopy())
57+
result, err = d.translator.TranslateHTTPRoute(tctx, t.DeepCopy())
5758
resourceTypes = append(resourceTypes, "service")
5859
case *gatewayv1.Gateway:
59-
result, err = d.translator.TranslateGateway(tctx, obj.DeepCopy())
60-
resourceTypes = append(resourceTypes, "global_rule", "ssl")
60+
result, err = d.translator.TranslateGateway(tctx, t.DeepCopy())
61+
resourceTypes = append(resourceTypes, "global_rule", "ssl", "plugin_metadata")
6162
}
6263
if err != nil {
6364
return err
@@ -70,9 +71,10 @@ func (d *adcClient) Update(ctx context.Context, tctx *provider.TranslateContext,
7071
Name: obj.GetName(),
7172
Labels: label.GenLabel(obj),
7273
Resources: types.Resources{
73-
Services: result.Services,
74-
SSLs: result.SSL,
75-
GlobalRules: result.GlobalRules,
74+
GlobalRules: result.GlobalRules,
75+
PluginMetadata: result.PluginMetadata,
76+
Services: result.Services,
77+
SSLs: result.SSL,
7678
},
7779
ResourceTypes: resourceTypes,
7880
})
@@ -81,12 +83,12 @@ func (d *adcClient) Update(ctx context.Context, tctx *provider.TranslateContext,
8183
func (d *adcClient) Delete(ctx context.Context, obj client.Object) error {
8284
log.Debugw("deleting object", zap.Any("object", obj))
8385

84-
resourceTypes := []string{}
86+
var resourceTypes []string
8587
switch obj.(type) {
8688
case *gatewayv1.HTTPRoute:
8789
resourceTypes = append(resourceTypes, "service")
8890
case *gatewayv1.Gateway:
89-
resourceTypes = append(resourceTypes, "global_rule", "ssl")
91+
resourceTypes = append(resourceTypes, "global_rule", "ssl", "plugin_metadata")
9092
}
9193

9294
return d.sync(Task{

internal/provider/adc/translator/gateway.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,15 @@ func (t *Translator) TranslateGateway(tctx *provider.TranslateContext, obj *gate
3333
}
3434
}
3535
if tctx.GatewayProxy != nil {
36-
globalRules := adctypes.Plugins{}
36+
var (
37+
globalRules = adctypes.Plugins{}
38+
pluginMetadata = adctypes.Plugins{}
39+
)
3740
// apply plugins from GatewayProxy to global rules
3841
t.fillPluginsFromGatewayProxy(globalRules, tctx.GatewayProxy)
42+
t.fillPluginMetadataFromGatewayProxy(pluginMetadata, tctx.GatewayProxy)
3943
result.GlobalRules = globalRules
44+
result.PluginMetadata = pluginMetadata
4045
}
4146
return result, nil
4247
}
@@ -192,3 +197,18 @@ func (t *Translator) fillPluginsFromGatewayProxy(plugins adctypes.Plugins, gatew
192197
plugins[pluginName] = pluginConfig
193198
}
194199
}
200+
201+
func (t *Translator) fillPluginMetadataFromGatewayProxy(pluginMetadata adctypes.Plugins, gatewayProxy *v1alpha1.GatewayProxy) {
202+
if gatewayProxy == nil {
203+
return
204+
}
205+
for pluginName, plugin := range gatewayProxy.Spec.PluginMetadata {
206+
var pluginConfig map[string]any
207+
if err := json.Unmarshal(plugin.Raw, &pluginConfig); err != nil {
208+
log.Errorw("gateway proxy plugin_metadata unmarshal failed", zap.Error(err), zap.Any("plugin", pluginName), zap.String("config", string(plugin.Raw)))
209+
continue
210+
}
211+
log.Debugw("fill plugin_metadata for gateway proxy", zap.String("plugin", pluginName), zap.Any("config", pluginConfig))
212+
pluginMetadata[pluginName] = pluginConfig
213+
}
214+
}

internal/provider/adc/translator/translator.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ type Translator struct {
1010
Log logr.Logger
1111
}
1212
type TranslateResult struct {
13-
Routes []*adctypes.Route
14-
Services []*adctypes.Service
15-
SSL []*adctypes.SSL
16-
GlobalRules adctypes.Plugins
13+
Routes []*adctypes.Route
14+
Services []*adctypes.Service
15+
SSL []*adctypes.SSL
16+
GlobalRules adctypes.Plugins
17+
PluginMetadata adctypes.Plugins
1718
}

test/e2e/framework/dashboard.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ dashboard_configuration:
9595
host: "0.0.0.0"
9696
cron_spec: "@every 1s"
9797
plugins:
98+
- error-page
9899
- real-ip
99100
#- ai
100101
- error-page

test/e2e/framework/manifests/dp.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ data:
3939
allow_admin:
4040
- all
4141
plugins:
42+
- error-page
4243
- real-ip
4344
- ai
4445
- client-control

test/e2e/gatewayapi/gatewayproxy.go

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gatewayapi
22

33
import (
44
"fmt"
5+
"net/http"
56
"time"
67

78
. "github.com/onsi/ginkgo/v2"
@@ -80,6 +81,46 @@ spec:
8081
headers:
8182
X-Proxy-Test: "disabled"
8283
`
84+
var (
85+
gatewayProxyWithPluginMetadata0 = `
86+
apiVersion: gateway.apisix.io/v1alpha1
87+
kind: GatewayProxy
88+
metadata:
89+
name: api7-proxy-config
90+
spec:
91+
plugins:
92+
- name: error-page
93+
enabled: true
94+
config: {}
95+
pluginMetadata:
96+
error-page: {
97+
"enable": true,
98+
"error_404": {
99+
"body": "404 from plugin metadata",
100+
"content-type": "text/plain"
101+
}
102+
}
103+
`
104+
gatewayProxyWithPluginMetadata1 = `
105+
apiVersion: gateway.apisix.io/v1alpha1
106+
kind: GatewayProxy
107+
metadata:
108+
name: api7-proxy-config
109+
spec:
110+
plugins:
111+
- name: error-page
112+
enabled: true
113+
config: {}
114+
pluginMetadata:
115+
error-page: {
116+
"enable": false,
117+
"error_404": {
118+
"body": "404 from plugin metadata",
119+
"content-type": "text/plain"
120+
}
121+
}
122+
`
123+
)
83124

84125
var httpRouteForTest = `
85126
apiVersion: gateway.networking.k8s.io/v1
@@ -101,15 +142,15 @@ spec:
101142
port: 80
102143
`
103144

104-
var ResourceApplied = func(resourceType, resourceName, resourceRaw string, observedGeneration int) {
145+
var resourceApplied = func(resourceType, resourceName, resourceRaw string, observedGeneration int) {
105146
Expect(s.CreateResourceFromString(resourceRaw)).
106147
NotTo(HaveOccurred(), fmt.Sprintf("creating %s", resourceType))
107148

108149
Eventually(func() string {
109150
hryaml, err := s.GetResourceYaml(resourceType, resourceName)
110151
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("getting %s yaml", resourceType))
111152
return hryaml
112-
}, "8s", "2s").
153+
}).WithTimeout(8*time.Second).ProbeEvery(2*time.Second).
113154
Should(
114155
SatisfyAll(
115156
ContainSubstring(`status: "True"`),
@@ -163,7 +204,7 @@ spec:
163204
Context("Test Gateway with enabled GatewayProxy plugin", func() {
164205
It("Should apply plugin configuration when enabled", func() {
165206
By("Create HTTPRoute for Gateway with GatewayProxy")
166-
ResourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
207+
resourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
167208

168209
By("Check if the plugin is applied")
169210
resp := s.NewAPISIXClient().
@@ -180,7 +221,7 @@ spec:
180221
time.Sleep(5 * time.Second)
181222

182223
By("Create HTTPRoute for Gateway with GatewayProxy")
183-
ResourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
224+
resourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
184225

185226
By("Check if the plugin is not applied")
186227
resp = s.NewAPISIXClient().
@@ -194,7 +235,7 @@ spec:
194235

195236
It("Should work normally without GatewayProxy", func() {
196237
By("Create HTTPRoute for Gateway with GatewayProxy")
197-
ResourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
238+
resourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
198239

199240
By("Check if the plugin is applied")
200241
resp := s.NewAPISIXClient().
@@ -211,7 +252,7 @@ spec:
211252
time.Sleep(5 * time.Second)
212253

213254
By("Create HTTPRoute for Gateway without GatewayProxy")
214-
ResourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
255+
resourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
215256

216257
By("Check if the route works without plugin")
217258
resp = s.NewAPISIXClient().
@@ -224,4 +265,53 @@ spec:
224265
})
225266
})
226267

268+
Context("Test Gateway with PluginMetadata", func() {
269+
var (
270+
err error
271+
)
272+
273+
It("Should work OK with error-page", func() {
274+
By("Update GatewayProxy with PluginMetadata")
275+
err = s.CreateResourceFromString(gatewayProxyWithPluginMetadata0)
276+
Expect(err).ShouldNot(HaveOccurred())
277+
time.Sleep(5 * time.Second)
278+
279+
By("Create HTTPRoute for Gateway with GatewayProxy")
280+
resourceApplied("HTTPRoute", "test-route", fmt.Sprintf(httpRouteForTest, "api7"), 1)
281+
282+
By("Check PluginMetadata working")
283+
s.NewAPISIXClient().
284+
GET("/not-found").
285+
WithHost("example.com").
286+
Expect().
287+
Status(http.StatusNotFound).
288+
Body().Contains("404 from plugin metadata")
289+
290+
By("Update GatewayProxy with PluginMetadata")
291+
err = s.CreateResourceFromString(gatewayProxyWithPluginMetadata1)
292+
Expect(err).ShouldNot(HaveOccurred())
293+
time.Sleep(5 * time.Second)
294+
295+
By("Check PluginMetadata working")
296+
s.NewAPISIXClient().
297+
GET("/not-found").
298+
WithHost("example.com").
299+
Expect().
300+
Status(http.StatusNotFound).
301+
Body().Contains(`{"error_msg":"404 Route Not Found"}`)
302+
303+
By("Delete GatewayProxy")
304+
err = s.DeleteResourceFromString(gatewayProxyWithPluginMetadata0)
305+
Expect(err).ShouldNot(HaveOccurred())
306+
time.Sleep(5 * time.Second)
307+
308+
By("Check PluginMetadata is not working")
309+
s.NewAPISIXClient().
310+
GET("/not-found").
311+
WithHost("example.com").
312+
Expect().
313+
Status(http.StatusNotFound).
314+
Body().Contains(`{"error_msg":"404 Route Not Found"}`)
315+
})
316+
})
227317
})

test/e2e/scaffold/scaffold.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -452,16 +452,10 @@ func (s *Scaffold) afterEach() {
452452
s.DeleteGatewayGroup(s.gatewaygroupid)
453453

454454
if CurrentSpecReport().Failed() {
455-
if os.Getenv("TSET_ENV") == "CI" {
455+
if os.Getenv("TEST_ENV") == "CI" {
456456
_, _ = fmt.Fprintln(GinkgoWriter, "Dumping namespace contents")
457-
output, _ := k8s.RunKubectlAndGetOutputE(GinkgoT(), s.kubectlOptions, "get", "deploy,sts,svc,pods")
458-
if output != "" {
459-
_, _ = fmt.Fprintln(GinkgoWriter, output)
460-
}
461-
output, _ = k8s.RunKubectlAndGetOutputE(GinkgoT(), s.kubectlOptions, "describe", "pods")
462-
if output != "" {
463-
_, _ = fmt.Fprintln(GinkgoWriter, output)
464-
}
457+
_, _ = k8s.RunKubectlAndGetOutputE(GinkgoT(), s.kubectlOptions, "get", "deploy,sts,svc,pods,gatewayproxy")
458+
_, _ = k8s.RunKubectlAndGetOutputE(GinkgoT(), s.kubectlOptions, "describe", "pods")
465459
}
466460

467461
output := s.GetDeploymentLogs("api7-ingress-controller")

0 commit comments

Comments
 (0)