mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
Merge pull request #111896 from deads2k/revert-compression-disable
Revert "Add an option to conditionally disable compression based on client ip."
This commit is contained in:
commit
ae62cd6ce2
@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 filters
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
)
|
||||
|
||||
// CompressionDisabledFunc checks if a given request should disable compression.
|
||||
type CompressionDisabledFunc func(*http.Request) (bool, error)
|
||||
|
||||
// WithCompressionDisabled stores result of CompressionDisabledFunc in context.
|
||||
func WithCompressionDisabled(handler http.Handler, predicate CompressionDisabledFunc) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
ctx := req.Context()
|
||||
decision, err := predicate(req)
|
||||
if err != nil {
|
||||
responsewriters.InternalError(w, req, fmt.Errorf("failed to determine if request should disable compression: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
req = req.WithContext(request.WithCompressionDisabled(ctx, decision))
|
||||
handler.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 filters
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
)
|
||||
|
||||
func TestWithCompressionDisabled(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
checkDecision bool
|
||||
checkErr error
|
||||
want bool
|
||||
wantHandlerCalled bool
|
||||
}{
|
||||
{
|
||||
name: "decision=true",
|
||||
checkDecision: true,
|
||||
want: true,
|
||||
wantHandlerCalled: true,
|
||||
},
|
||||
{
|
||||
name: "decision=false",
|
||||
checkDecision: false,
|
||||
want: false,
|
||||
wantHandlerCalled: true,
|
||||
},
|
||||
{
|
||||
name: "check error",
|
||||
checkErr: errors.New("check failed"),
|
||||
want: false,
|
||||
wantHandlerCalled: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
handlerCalled := false
|
||||
handler := http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
|
||||
handlerCalled = true
|
||||
if got, want := request.CompressionDisabledFrom(req.Context()), tt.checkDecision; got != want {
|
||||
t.Errorf("request.CompressionDisabledFrom(req.Context())=%v; want=%v", got, want)
|
||||
}
|
||||
})
|
||||
fake := func(*http.Request) (bool, error) {
|
||||
return tt.checkDecision, tt.checkErr
|
||||
}
|
||||
wrapped := WithCompressionDisabled(handler, fake)
|
||||
testRequest, err := http.NewRequest(http.MethodGet, "/path", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w := httptest.NewRecorder()
|
||||
wrapped.ServeHTTP(w, testRequest)
|
||||
if handlerCalled != tt.wantHandlerCalled {
|
||||
t.Errorf("expected handlerCalled=%v, got=%v", handlerCalled, tt.wantHandlerCalled)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -87,21 +87,19 @@ func StreamObject(statusCode int, gv schema.GroupVersion, s runtime.NegotiatedSe
|
||||
// The context is optional and can be nil. This method will perform optional content compression if requested by
|
||||
// a client and the feature gate for APIResponseCompression is enabled.
|
||||
func SerializeObject(mediaType string, encoder runtime.Encoder, hw http.ResponseWriter, req *http.Request, statusCode int, object runtime.Object) {
|
||||
disableCompression := request.CompressionDisabledFrom(req.Context())
|
||||
trace := utiltrace.New("SerializeObject",
|
||||
utiltrace.Field{"audit-id", request.GetAuditIDTruncated(req.Context())},
|
||||
utiltrace.Field{"method", req.Method},
|
||||
utiltrace.Field{"url", req.URL.Path},
|
||||
utiltrace.Field{"protocol", req.Proto},
|
||||
utiltrace.Field{"mediaType", mediaType},
|
||||
utiltrace.Field{"encoder", encoder.Identifier()},
|
||||
utiltrace.Field{"disableCompression", disableCompression})
|
||||
utiltrace.Field{"encoder", encoder.Identifier()})
|
||||
defer trace.LogIfLong(5 * time.Second)
|
||||
|
||||
w := &deferredResponseWriter{
|
||||
mediaType: mediaType,
|
||||
statusCode: statusCode,
|
||||
contentEncoding: negotiateContentEncoding(req, disableCompression),
|
||||
contentEncoding: negotiateContentEncoding(req),
|
||||
hw: hw,
|
||||
trace: trace,
|
||||
}
|
||||
@ -157,12 +155,12 @@ const (
|
||||
// negotiateContentEncoding returns a supported client-requested content encoding for the
|
||||
// provided request. It will return the empty string if no supported content encoding was
|
||||
// found or if response compression is disabled.
|
||||
func negotiateContentEncoding(req *http.Request, disableCompression bool) string {
|
||||
func negotiateContentEncoding(req *http.Request) string {
|
||||
encoding := req.Header.Get("Accept-Encoding")
|
||||
if len(encoding) == 0 {
|
||||
return ""
|
||||
}
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.APIResponseCompression) || disableCompression {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.APIResponseCompression) {
|
||||
return ""
|
||||
}
|
||||
for len(encoding) > 0 {
|
||||
|
@ -19,7 +19,6 @@ package responsewriters
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@ -42,7 +41,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
@ -233,7 +231,7 @@ func TestSerializeObject(t *testing.T) {
|
||||
},
|
||||
|
||||
{
|
||||
name: "compress on gzip, request's context has no decision",
|
||||
name: "compress on gzip",
|
||||
compressionEnabled: true,
|
||||
out: largePayload,
|
||||
mediaType: "application/json",
|
||||
@ -251,40 +249,6 @@ func TestSerializeObject(t *testing.T) {
|
||||
},
|
||||
wantBody: gzipContent(largePayload, defaultGzipContentEncodingLevel),
|
||||
},
|
||||
{
|
||||
name: "compress on gzip, request's context allows compression",
|
||||
compressionEnabled: true,
|
||||
out: largePayload,
|
||||
mediaType: "application/json",
|
||||
req: (&http.Request{
|
||||
Header: http.Header{
|
||||
"Accept-Encoding": []string{"gzip"},
|
||||
},
|
||||
URL: &url.URL{Path: "/path"},
|
||||
}).WithContext(request.WithCompressionDisabled(context.Background(), false)),
|
||||
wantCode: http.StatusOK,
|
||||
wantHeaders: http.Header{
|
||||
"Content-Type": []string{"application/json"},
|
||||
"Content-Encoding": []string{"gzip"},
|
||||
"Vary": []string{"Accept-Encoding"},
|
||||
},
|
||||
wantBody: gzipContent(largePayload, defaultGzipContentEncodingLevel),
|
||||
},
|
||||
{
|
||||
name: "compress on gzip, request's context disables compression",
|
||||
compressionEnabled: true,
|
||||
out: largePayload,
|
||||
mediaType: "application/json",
|
||||
req: (&http.Request{
|
||||
Header: http.Header{
|
||||
"Accept-Encoding": []string{"gzip"},
|
||||
},
|
||||
URL: &url.URL{Path: "/path"},
|
||||
}).WithContext(request.WithCompressionDisabled(context.Background(), true)),
|
||||
wantCode: http.StatusOK,
|
||||
wantHeaders: http.Header{"Content-Type": []string{"application/json"}},
|
||||
wantBody: largePayload,
|
||||
},
|
||||
|
||||
{
|
||||
name: "compression is not performed on small objects",
|
||||
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 request
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type disableCompressionIDKeyType int
|
||||
|
||||
const disableCompressionIDKey disableCompressionIDKeyType = iota
|
||||
|
||||
// WithCompressionDisabled stores bool in context.
|
||||
func WithCompressionDisabled(parent context.Context, disableCompression bool) context.Context {
|
||||
return WithValue(parent, disableCompressionIDKey, disableCompression)
|
||||
}
|
||||
|
||||
// CompressionDisabledFrom retrieves bool from context.
|
||||
// Defaults to false if not set.
|
||||
func CompressionDisabledFrom(ctx context.Context) bool {
|
||||
decision, _ := ctx.Value(disableCompressionIDKey).(bool)
|
||||
return decision
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompressionDisabled(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
// Default value is false.
|
||||
if got, want := CompressionDisabledFrom(ctx), false; got != want {
|
||||
t.Errorf("CompressionDisabledFrom(ctx) = %v; want = %v", got, want)
|
||||
}
|
||||
|
||||
// We retrieve stored true.
|
||||
ctx = WithCompressionDisabled(ctx, true)
|
||||
if got, want := CompressionDisabledFrom(ctx), true; got != want {
|
||||
t.Errorf("CompressionDisabledFrom(ctx) = %v; want = %v", got, want)
|
||||
}
|
||||
|
||||
// We retrieve stored false.
|
||||
ctx = WithCompressionDisabled(ctx, false)
|
||||
if got, want := CompressionDisabledFrom(ctx), false; got != want {
|
||||
t.Errorf("CompressionDisabledFrom(ctx) = %v; want = %v", got, want)
|
||||
}
|
||||
}
|
@ -257,9 +257,6 @@ type Config struct {
|
||||
|
||||
// StorageVersionManager holds the storage versions of the API resources installed by this server.
|
||||
StorageVersionManager storageversion.Manager
|
||||
|
||||
// CompressionDisabledFunc returns whether compression should be disabled for a given request.
|
||||
CompressionDisabledFunc genericapifilters.CompressionDisabledFunc
|
||||
}
|
||||
|
||||
type RecommendedConfig struct {
|
||||
@ -859,9 +856,6 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
|
||||
if c.ShutdownSendRetryAfter {
|
||||
handler = genericfilters.WithRetryAfter(handler, c.lifecycleSignals.NotAcceptingNewRequest.Signaled())
|
||||
}
|
||||
if c.CompressionDisabledFunc != nil {
|
||||
handler = genericapifilters.WithCompressionDisabled(handler, c.CompressionDisabledFunc)
|
||||
}
|
||||
handler = genericfilters.WithHTTPLogging(handler)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerTracing) {
|
||||
handler = genericapifilters.WithTracing(handler, c.TracerProvider)
|
||||
|
@ -26,9 +26,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/util/disablecompression"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
netutils "k8s.io/utils/net"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
@ -65,27 +63,21 @@ type ServerRunOptions struct {
|
||||
// If enabled, after ShutdownDelayDuration elapses, any incoming request is
|
||||
// rejected with a 429 status code and a 'Retry-After' response.
|
||||
ShutdownSendRetryAfter bool
|
||||
|
||||
// DisableCompressionForClientIPs is a comma separated list of CIDR IP ranges
|
||||
// (parsable by net.ParseCIDR, as defined in RFC 4632 and RFC 4291) for which
|
||||
// traffic compression should be disabled.
|
||||
DisableCompressionForClientIPs []string
|
||||
}
|
||||
|
||||
func NewServerRunOptions() *ServerRunOptions {
|
||||
defaults := server.NewConfig(serializer.CodecFactory{})
|
||||
return &ServerRunOptions{
|
||||
MaxRequestsInFlight: defaults.MaxRequestsInFlight,
|
||||
MaxMutatingRequestsInFlight: defaults.MaxMutatingRequestsInFlight,
|
||||
RequestTimeout: defaults.RequestTimeout,
|
||||
LivezGracePeriod: defaults.LivezGracePeriod,
|
||||
MinRequestTimeout: defaults.MinRequestTimeout,
|
||||
ShutdownDelayDuration: defaults.ShutdownDelayDuration,
|
||||
JSONPatchMaxCopyBytes: defaults.JSONPatchMaxCopyBytes,
|
||||
MaxRequestBodyBytes: defaults.MaxRequestBodyBytes,
|
||||
EnablePriorityAndFairness: true,
|
||||
ShutdownSendRetryAfter: false,
|
||||
DisableCompressionForClientIPs: nil,
|
||||
MaxRequestsInFlight: defaults.MaxRequestsInFlight,
|
||||
MaxMutatingRequestsInFlight: defaults.MaxMutatingRequestsInFlight,
|
||||
RequestTimeout: defaults.RequestTimeout,
|
||||
LivezGracePeriod: defaults.LivezGracePeriod,
|
||||
MinRequestTimeout: defaults.MinRequestTimeout,
|
||||
ShutdownDelayDuration: defaults.ShutdownDelayDuration,
|
||||
JSONPatchMaxCopyBytes: defaults.JSONPatchMaxCopyBytes,
|
||||
MaxRequestBodyBytes: defaults.MaxRequestBodyBytes,
|
||||
EnablePriorityAndFairness: true,
|
||||
ShutdownSendRetryAfter: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,13 +97,6 @@ func (s *ServerRunOptions) ApplyTo(c *server.Config) error {
|
||||
c.MaxRequestBodyBytes = s.MaxRequestBodyBytes
|
||||
c.PublicAddress = s.AdvertiseAddress
|
||||
c.ShutdownSendRetryAfter = s.ShutdownSendRetryAfter
|
||||
if len(s.DisableCompressionForClientIPs) != 0 {
|
||||
pred, err := disablecompression.NewClientIPPredicate(s.DisableCompressionForClientIPs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.CompressionDisabledFunc = pred.Predicate
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -176,10 +161,6 @@ func (s *ServerRunOptions) Validate() []error {
|
||||
if err := validateHSTSDirectives(s.HSTSDirectives); err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
if _, err := netutils.ParseCIDRs(s.DisableCompressionForClientIPs); err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
@ -275,8 +256,5 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
|
||||
"during this window all incoming requests will be rejected with a status code 429 and a 'Retry-After' response header, "+
|
||||
"in addition 'Connection: close' response header is set in order to tear down the TCP connection when idle.")
|
||||
|
||||
fs.StringSliceVar(&s.DisableCompressionForClientIPs, "disable-compression-for-client-ips", s.DisableCompressionForClientIPs, ""+
|
||||
"A comma separated list of client IP ranges in CIDR notation like \"192.0.2.0/24\" or \"2001:db8::/32\", as defined in RFC 4632 and RFC 4291, for which traffic compression will be disabled.")
|
||||
|
||||
utilfeature.DefaultMutableFeatureGate.AddFlag(fs)
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 disablecompression
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// ClientIPPredicate.Predicate implements CompressionDisabledFunc interface that decides
|
||||
// based on client IP.
|
||||
type ClientIPPredicate struct {
|
||||
cidrs []*net.IPNet
|
||||
}
|
||||
|
||||
// NewClientIPPredicate creates a new ClientIPPredicate instance.
|
||||
func NewClientIPPredicate(cidrStrings []string) (*ClientIPPredicate, error) {
|
||||
cidrs, err := netutils.ParseCIDRs(cidrStrings)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse cidrs: %v", err)
|
||||
}
|
||||
return &ClientIPPredicate{cidrs: cidrs}, nil
|
||||
}
|
||||
|
||||
// Predicate checks if ClientIP matches any cidr.
|
||||
func (c *ClientIPPredicate) Predicate(req *http.Request) (bool, error) {
|
||||
ip := utilnet.GetClientIP(req)
|
||||
if ip == nil {
|
||||
return false, fmt.Errorf("unable to determine source IP for %v", req)
|
||||
}
|
||||
|
||||
for _, cidr := range c.cidrs {
|
||||
if cidr.Contains(ip) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
Copyright 2022 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 disablecompression
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewClientIPPredicate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cidrStrings []string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "rfc1918",
|
||||
cidrStrings: []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"},
|
||||
},
|
||||
{
|
||||
name: "rfc4193 (ipv6)",
|
||||
cidrStrings: []string{"fc00::/7"},
|
||||
},
|
||||
{
|
||||
name: "ipv6 loopback",
|
||||
cidrStrings: []string{"::1/128"},
|
||||
},
|
||||
{
|
||||
name: "bad cidr",
|
||||
cidrStrings: []string{"not a cidr string"},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := NewClientIPPredicate(tt.cidrStrings)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Fatalf("NewClientIPPredicate() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
if tt.wantErr {
|
||||
return
|
||||
}
|
||||
if got, want := len(got.cidrs), len(tt.cidrStrings); got != want {
|
||||
t.Errorf("len(NewClientIPPredicate.cidrs()) = %v, want %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientIPPredicate_Predicate(t *testing.T) {
|
||||
check, err := NewClientIPPredicate([]string{"::1/128", "10.0.0.0/8"})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to construct NewClientIPPredicate: %v", err)
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
req *http.Request
|
||||
want bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "ipv4, in range",
|
||||
req: &http.Request{RemoteAddr: "10.0.0.1:123"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "ipv4, out of range",
|
||||
req: &http.Request{RemoteAddr: "11.0.0.1:123"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "ipv6, in range",
|
||||
req: &http.Request{RemoteAddr: "[::1]:123"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "ipv6, out of range",
|
||||
req: &http.Request{RemoteAddr: "[::2]:123"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "no IP",
|
||||
req: &http.Request{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "RemoteAddr doesn't parse",
|
||||
req: &http.Request{RemoteAddr: "this is definitely not an IP address and port"},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := check.Predicate(tt.req)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ClientIPPredicate.Predicate() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("ClientIPPredicate.Predicate() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -1656,7 +1656,6 @@ k8s.io/apiserver/pkg/storage/value/encrypt/identity
|
||||
k8s.io/apiserver/pkg/storage/value/encrypt/secretbox
|
||||
k8s.io/apiserver/pkg/storageversion
|
||||
k8s.io/apiserver/pkg/util/apihelpers
|
||||
k8s.io/apiserver/pkg/util/disablecompression
|
||||
k8s.io/apiserver/pkg/util/dryrun
|
||||
k8s.io/apiserver/pkg/util/feature
|
||||
k8s.io/apiserver/pkg/util/flowcontrol
|
||||
|
Loading…
Reference in New Issue
Block a user