Add annotation to enable rewrite logs in a location
This commit is contained in:
parent
1086ec6c7e
commit
c995031ffd
7 changed files with 157 additions and 18 deletions
|
@ -46,6 +46,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|
|||
|[nginx.ingress.kubernetes.io/proxy-request-buffering](#custom-timeouts)|string|
|
||||
|[nginx.ingress.kubernetes.io/proxy-redirect-from](#proxy-redirect)|string|
|
||||
|[nginx.ingress.kubernetes.io/proxy-redirect-to](#proxy-redirect)|string|
|
||||
|[nginx.ingress.kubernetes.io/rewrite-log](#enable-rewrite-log)|URI|
|
||||
|[nginx.ingress.kubernetes.io/rewrite-target](#rewrite)|URI|
|
||||
|[nginx.ingress.kubernetes.io/secure-backends](#secure-backends)|"true" or "false"|
|
||||
|[nginx.ingress.kubernetes.io/secure-verify-ca-secret](#secure-backends)|string|
|
||||
|
@ -467,6 +468,14 @@ In some scenarios could be required to disable NGINX access logs. To enable this
|
|||
nginx.ingress.kubernetes.io/enable-access-log: "false"
|
||||
```
|
||||
|
||||
### Enable Rewrite Log
|
||||
|
||||
In some scenarios it could be required to enable NGINX rewrite logs. Note that rewrite logs are sent to the error_log file at the notice level. To enable this feature use the annotation:
|
||||
|
||||
```yaml
|
||||
nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
|
||||
```
|
||||
|
||||
### Lua Resty WAF
|
||||
|
||||
Using `lua-resty-waf-*` annotations we can enable and control [lua-resty-waf](https://github.com/p0pr0ck5/lua-resty-waf) per location.
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -23,36 +23,46 @@ import (
|
|||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||
)
|
||||
|
||||
type cors struct {
|
||||
type log struct {
|
||||
r resolver.Resolver
|
||||
}
|
||||
|
||||
// Config contains the configuration to be used in the Ingress
|
||||
type Config struct {
|
||||
Access bool `json:"accessLog"`
|
||||
Access bool `json:"accessLog"`
|
||||
Rewrite bool `json:"rewriteLog"`
|
||||
}
|
||||
|
||||
// Equal tests for equality between two Config types
|
||||
func (bd1 *Config) Equal(bd2 *Config) bool {
|
||||
if bd1.Access == bd2.Access {
|
||||
return true
|
||||
if bd1.Access != bd2.Access {
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
if bd1.Rewrite != bd2.Rewrite {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// NewParser creates a new access log annotation parser
|
||||
// NewParser creates a new log annotations parser
|
||||
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
|
||||
return cors{r}
|
||||
return log{r}
|
||||
}
|
||||
|
||||
// Parse parses the annotations contained in the ingress
|
||||
// rule used to indicate if the location/s should enable logs
|
||||
func (c cors) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||
func (l log) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||
accessEnabled, err := parser.GetBoolAnnotation("enable-access-log", ing)
|
||||
if err != nil {
|
||||
accessEnabled = true
|
||||
}
|
||||
|
||||
return &Config{accessEnabled}, nil
|
||||
rewriteEnabled, err := parser.GetBoolAnnotation("enable-rewrite-log", ing)
|
||||
if err != nil {
|
||||
rewriteEnabled = false
|
||||
}
|
||||
|
||||
return &Config{Access: accessEnabled, Rewrite: rewriteEnabled}, nil
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIngressLogConfig(t *testing.T) {
|
||||
func TestIngressAccessLogConfig(t *testing.T) {
|
||||
ing := buildIngress()
|
||||
|
||||
data := map[string]string{}
|
||||
|
@ -79,3 +79,21 @@ func TestIngressLogConfig(t *testing.T) {
|
|||
t.Errorf("expected access be disabled but is enabled")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIngressRewriteLogConfig(t *testing.T) {
|
||||
ing := buildIngress()
|
||||
|
||||
data := map[string]string{}
|
||||
data[parser.GetAnnotationWithPrefix("enable-rewrite-log")] = "true"
|
||||
ing.SetAnnotations(data)
|
||||
|
||||
log, _ := NewParser(&resolver.Mock{}).Parse(ing)
|
||||
nginxLogs, ok := log.(*Config)
|
||||
if !ok {
|
||||
t.Errorf("expected a Config type")
|
||||
}
|
||||
|
||||
if !nginxLogs.Rewrite {
|
||||
t.Errorf("expected rewrite log to be enabled but it is disabled")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ type Location struct {
|
|||
// +optional
|
||||
XForwardedPrefix bool `json:"xForwardedPrefix,omitempty"`
|
||||
// Logs allows to enable or disable the nginx logs
|
||||
// By default this is enabled
|
||||
// By default access logs are enabled and rewrite logs are disabled
|
||||
Logs log.Config `json:"logs,omitempty"`
|
||||
// GRPC indicates if the kubernetes service exposes a gRPC interface
|
||||
// By default this is false
|
||||
|
|
|
@ -275,9 +275,9 @@ http {
|
|||
|
||||
# Reverse proxies can detect if a client provides a X-Request-ID header, and pass it on to the backend server.
|
||||
# If no such header is provided, it can provide a random value.
|
||||
map $http_x_request_id $req_id {
|
||||
default $http_x_request_id;
|
||||
"" $request_id;
|
||||
map $http_x_request_id $req_id {
|
||||
default $http_x_request_id;
|
||||
"" $request_id;
|
||||
}
|
||||
|
||||
{{ if $cfg.ComputeFullForwardedFor }}
|
||||
|
@ -297,8 +297,6 @@ http {
|
|||
server_name_in_redirect off;
|
||||
port_in_redirect off;
|
||||
|
||||
rewrite_log on;
|
||||
|
||||
ssl_protocols {{ $cfg.SSLProtocols }};
|
||||
|
||||
# turn on session caching to drastically improve performance
|
||||
|
@ -550,7 +548,7 @@ http {
|
|||
allow ::1;
|
||||
{{ end }}
|
||||
deny all;
|
||||
|
||||
|
||||
# this should be equals to configuration_data dict
|
||||
client_max_body_size "10m";
|
||||
proxy_buffering off;
|
||||
|
@ -895,6 +893,10 @@ stream {
|
|||
access_log off;
|
||||
{{ end }}
|
||||
|
||||
{{ if $location.Logs.Rewrite }}
|
||||
rewrite_log on;
|
||||
{{ end }}
|
||||
|
||||
port_in_redirect {{ if $location.UsePortInRedirects }}on{{ else }}off{{ end }};
|
||||
|
||||
{{ if $all.Cfg.EnableVtsStatus }}{{ if $location.VtsFilterKey }} vhost_traffic_status_filter_by_set_key {{ $location.VtsFilterKey }};{{ end }}{{ end }}
|
||||
|
|
100
test/e2e/annotations/rewrite_log.go
Normal file
100
test/e2e/annotations/rewrite_log.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed 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 annotations
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Annotations - Rewrite Log", func() {
|
||||
f := framework.NewDefaultFramework("rewrite-log")
|
||||
|
||||
BeforeEach(func() {
|
||||
err := f.NewEchoDeploymentWithReplicas(2)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
})
|
||||
|
||||
It("should write rewrite logs", func() {
|
||||
host := "rewrite.bar.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/rewrite-target": "/",
|
||||
"nginx.ingress.kubernetes.io/enable-rewrite-log": "true",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/something",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "rewrite_log on;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+"/something").
|
||||
Set("Host", host).
|
||||
End()
|
||||
|
||||
Expect(len(errs)).Should(Equal(0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
logs, err := f.NginxLogs()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(logs).To(ContainSubstring(`"/something" matches "/something", client:`))
|
||||
Expect(logs).To(ContainSubstring(`rewritten data: "/", args: "",`))
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue