[Question]: When using Easegress as an Ingress controller, how can I add a global filter to the default HTTP server?
tjqc0512 opened this issue · 8 comments
This is not Bug report or Feature request
- I confirm that this is not bug report or feature request.
Is this question answered in the documentation?
- I have searched the documentation
Is there an existing issue for this?
- I have searched the existing issues
Your question
When using Easegress as an Ingress controller, I want to add a global filter to the default HTTP server created by the Easegress Ingress controller, to ensure all traffic first passes through the global filter before being forwarded to the backend services.
I have already configured a global filter for the HTTP server in the controller.yaml, but it does not take effect. All traffic is directly forwarded to the backend services without going through the global filter.
apiVersion: v1
data:
easegress-server.yaml: |
name: ingress-easegress
cluster-name: easegress-ingress-controller
cluster-role: primary
api-addr: 0.0.0.0:2381
data-dir: /opt/easegress/data
log-dir: /opt/easegress/log
debug: true
log: info
controller.yaml: |
kind: IngressController
name: easegress-ingress-controller
namespaces:
- ingress-easegress
- gw-cscc
- test
ingressClass: easegress
httpServer:
globalFilter: global-filter
port: 8080
https: false
keepAlive: true
keepAliveTimeout: 60s
maxConnections: 10240
However, in a new HTTP server that I created within the Easegress ingress controller, the traffic can normally pass through the global filter. Is it because the default HTTP server created by the Easegress ingress controller does not support configuring global filters?
pip.yaml: |
kind: HTTPServer
name: httpserver-test-rsa
globalFilter: global-filter
port: 8081
rules:
- paths:
- pathPrefix: /service2
backend: pipeline-demo
---
name: pipeline-demo
kind: Pipeline
flow:
- filter: rsa
jumpIf:
invalid: END
- filter: proxy
filters:
- name: rsa
kind: Validator
headers:
Is-Valid:
values: ["abc", "goodplan"]
- name: proxy
kind: Proxy
pools:
- servers:
- url: http://hello-service:60002
loadBalance:
policy: roundRobin
---
name: global-filter
kind: GlobalFilter
beforePipeline:
flow:
- filter: rsaAuthFilter
filters:
- name: rsaAuthFilter
kind: RsaAuthFilter
Can you post the log of the ingress controller pod, and is there any error that occurred?
Hi, easegress ingress controller implements the standard of k8s ingress controller. So, the globalFilter
is not support yet.
But i have just checked the code and find it seems simple to add this feature.
func newHTTPServerSpecBuilder(template *httpserver.Spec) *httpServerSpecBuilder {
return &httpServerSpecBuilder{
Kind: httpserver.Kind,
Name: "http-server-ingress-controller",
Spec: httpserver.Spec{
Port: template.Port,
KeepAlive: template.KeepAlive,
HTTPS: template.HTTPS,
KeepAliveTimeout: template.KeepAliveTimeout,
MaxConnections: template.MaxConnections,
},
}
}
the problem is when create builder for httpserver in ingress controller, template.GlobalFilter
is not copied. And since GlobalFilter
is a business controller, httpserver in ingress controller namespace can get it.
What do you think @xxx7xxxx? I can't see why we not support this feature?
Can you post the log of the ingress controller pod, and is there any error that occurred?
The logs do not show any exceptions, but the traffic is not passing through the global filter.
2024-03-13T09:38:46.998Z DEBUG httpserver/mux.go:395 http-server-ingress-controller: the matched backend(Pipeline) for [POST /WF_BEIJING] is "pipeline-ingress-easegress-hello-service-60001"
[2024-03-13T09:38:46.998Z] [10.42.0.1:63350 10.42.0.1 POST /WF_BEIJING HTTP/1.1 200] [8.92ms rx:640B tx:186B] [status code: 200 | pipeline(pipeline-ingress-easegress-hello-service-60001): proxy(6.868ms) | proxy#proxy#main#duration: 8.383ms]
Sure, we could support it by adding the copy line, and a profound solution would be adding a general HTTPServerSpeBuilder
for all of them. @tjqc0512 Do you want to address this issue?
➜ easegress rg newHTTPServerSpecBuilder
pkg/object/gatewaycontroller/translator.go
289:func newHTTPServerSpecBuilder(name string) *httpServerSpecBuilder {
590: sb := newHTTPServerSpecBuilder(fmt.Sprintf("http-server-%s-%s", g.Name, l.Name))
pkg/object/meshcontroller/worker/egress.go
101:func newHTTPServerSpecBuilder(httpServerName string, spec *httpserver.Spec) *httpServerSpecBuilder {
526: builder := newHTTPServerSpecBuilder(egs.egressServerName, httpServerSpec)
pkg/object/function/worker/ingress.go
99:func newHTTPServerSpecBuilder(controllerName string) *httpServerSpecBuilder {
194: builder := newHTTPServerSpecBuilder(ings.superSpec.Name())
212: builder := newHTTPServerSpecBuilder(ings.superSpec.Name())
pkg/object/ingresscontroller/translator.go
174:func newHTTPServerSpecBuilder(template *httpserver.Spec) *httpServerSpecBuilder {
482: b := newHTTPServerSpecBuilder(st.httpSvrCfg)
Hi, easegress ingress controller implements the standard of k8s ingress controller. So, the is not support yet.
globalFilter
But i have just checked the code and find it seems simple to add this feature.
func newHTTPServerSpecBuilder(template *httpserver.Spec) *httpServerSpecBuilder { return &httpServerSpecBuilder{ Kind: httpserver.Kind, Name: "http-server-ingress-controller", Spec: httpserver.Spec{ Port: template.Port, KeepAlive: template.KeepAlive, HTTPS: template.HTTPS, KeepAliveTimeout: template.KeepAliveTimeout, MaxConnections: template.MaxConnections, }, } }the problem is when create builder for httpserver in ingress controller, is not copied. And since is a business controller, httpserver in ingress controller namespace can get it.
template.GlobalFilter``GlobalFilter
What do you think @xxx7xxxx? I can't see why we not support this feature?
Sure, I appreciate your guidance. I'll try modifying this feature and rebuild the easegress-server for testing. Additionally, I have a question regarding how to print logs or output logs to a file for a custom-developed filter. Currently, I'm using the github.com/megaease/easegress/pkg/logger library for logging, but it's not outputting logs as expected, for example, logger.Warnf("RsaAuthFilter: 'X-Custom-WF-Name' header is not a string"). I've also tried solutions I found through searching, but none have been successful.
but it's not outputting logs as expected
What's the detail? Does it print all logs except for the log you added? It can't be.
but it's not outputting logs as expected
What's the detail? Does it print all logs except for the log you added? It can't be.
I am unable to print and output logs for all operations within my custom filter. I don't know how to implement printing and outputting logs for debugging purposes.
I don't know the reason. If other filters can print logs, yours can not be the exception. Do you register your filter in source code and make it sure that it has run? Or Just panic in your code to assert that your code has been executed.