The chain middleware in k8s use middlewareRef
This commit is contained in:
parent
261e7c1744
commit
770b3739e0
6 changed files with 269 additions and 21 deletions
|
@ -51,9 +51,9 @@ metadata:
|
||||||
spec:
|
spec:
|
||||||
chain:
|
chain:
|
||||||
middlewares:
|
middlewares:
|
||||||
- https-only
|
- name: https-only
|
||||||
- known-ips
|
- name: known-ips
|
||||||
- auth-users
|
- name: auth-users
|
||||||
---
|
---
|
||||||
apiVersion: traefik.containo.us/v1alpha1
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
|
|
|
@ -1,5 +1,17 @@
|
||||||
apiVersion: traefik.containo.us/v1alpha1
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: mychain
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
chain:
|
||||||
|
middlewares:
|
||||||
|
- name: stripprefix
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
metadata:
|
metadata:
|
||||||
name: stripprefix
|
name: stripprefix
|
||||||
namespace: default
|
namespace: default
|
||||||
|
@ -26,4 +38,4 @@ spec:
|
||||||
- name: whoami
|
- name: whoami
|
||||||
port: 80
|
port: 80
|
||||||
middlewares:
|
middlewares:
|
||||||
- name: stripprefix
|
- name: mychain
|
||||||
|
|
38
integration/testdata/rawdata-crd.json
vendored
38
integration/testdata/rawdata-crd.json
vendored
|
@ -20,7 +20,7 @@
|
||||||
"web"
|
"web"
|
||||||
],
|
],
|
||||||
"middlewares": [
|
"middlewares": [
|
||||||
"default/stripprefix"
|
"default/mychain"
|
||||||
],
|
],
|
||||||
"service": "default/test2.route-23c7f4c450289ee29016",
|
"service": "default/test2.route-23c7f4c450289ee29016",
|
||||||
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/tobestripped`)",
|
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/tobestripped`)",
|
||||||
|
@ -31,16 +31,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"middlewares": {
|
"middlewares": {
|
||||||
"default/stripprefix@kubernetescrd": {
|
"default/mychain@kubernetescrd": {
|
||||||
"stripPrefix": {
|
"chain": {
|
||||||
"prefixes": [
|
"middlewares": [
|
||||||
"/tobestripped"
|
"default/stripprefix"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"status": "enabled",
|
"status": "enabled",
|
||||||
"usedBy": [
|
"usedBy": [
|
||||||
"default/test2.route-23c7f4c450289ee29016@kubernetescrd"
|
"default/test2.route-23c7f4c450289ee29016@kubernetescrd"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"default/stripprefix@kubernetescrd": {
|
||||||
|
"stripPrefix": {
|
||||||
|
"prefixes": [
|
||||||
|
"/tobestripped"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"status": "enabled"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
|
@ -48,10 +56,10 @@
|
||||||
"loadBalancer": {
|
"loadBalancer": {
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.2:80"
|
"url": "http://10.42.0.3:80"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.6:80"
|
"url": "http://10.42.0.5:80"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"passHostHeader": true
|
"passHostHeader": true
|
||||||
|
@ -61,18 +69,18 @@
|
||||||
"default/test.route-6b204d94623b3df4370c@kubernetescrd"
|
"default/test.route-6b204d94623b3df4370c@kubernetescrd"
|
||||||
],
|
],
|
||||||
"serverStatus": {
|
"serverStatus": {
|
||||||
"http://10.42.0.2:80": "UP",
|
"http://10.42.0.3:80": "UP",
|
||||||
"http://10.42.0.6:80": "UP"
|
"http://10.42.0.5:80": "UP"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"default/test2.route-23c7f4c450289ee29016@kubernetescrd": {
|
"default/test2.route-23c7f4c450289ee29016@kubernetescrd": {
|
||||||
"loadBalancer": {
|
"loadBalancer": {
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.2:80"
|
"url": "http://10.42.0.3:80"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "http://10.42.0.6:80"
|
"url": "http://10.42.0.5:80"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"passHostHeader": true
|
"passHostHeader": true
|
||||||
|
@ -82,8 +90,8 @@
|
||||||
"default/test2.route-23c7f4c450289ee29016@kubernetescrd"
|
"default/test2.route-23c7f4c450289ee29016@kubernetescrd"
|
||||||
],
|
],
|
||||||
"serverStatus": {
|
"serverStatus": {
|
||||||
"http://10.42.0.2:80": "UP",
|
"http://10.42.0.3:80": "UP",
|
||||||
"http://10.42.0.6:80": "UP"
|
"http://10.42.0.5:80": "UP"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -109,10 +117,10 @@
|
||||||
"loadBalancer": {
|
"loadBalancer": {
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"address": "10.42.0.4:8080"
|
"address": "10.42.0.6:8080"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "10.42.0.5:8080"
|
"address": "10.42.0.7:8080"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
"github.com/containous/traefik/v2/pkg/job"
|
"github.com/containous/traefik/v2/pkg/job"
|
||||||
"github.com/containous/traefik/v2/pkg/log"
|
"github.com/containous/traefik/v2/pkg/log"
|
||||||
|
"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
||||||
"github.com/containous/traefik/v2/pkg/safe"
|
"github.com/containous/traefik/v2/pkg/safe"
|
||||||
"github.com/containous/traefik/v2/pkg/tls"
|
"github.com/containous/traefik/v2/pkg/tls"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
@ -146,12 +147,62 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, middleware := range client.GetMiddlewares() {
|
for _, middleware := range client.GetMiddlewares() {
|
||||||
conf.HTTP.Middlewares[makeID(middleware.Namespace, middleware.Name)] = &middleware.Spec
|
id := makeID(middleware.Namespace, middleware.Name)
|
||||||
|
ctxMid := log.With(ctx, log.Str(log.MiddlewareName, id))
|
||||||
|
conf.HTTP.Middlewares[id] = &dynamic.Middleware{
|
||||||
|
AddPrefix: middleware.Spec.AddPrefix,
|
||||||
|
StripPrefix: middleware.Spec.StripPrefix,
|
||||||
|
StripPrefixRegex: middleware.Spec.StripPrefixRegex,
|
||||||
|
ReplacePath: middleware.Spec.ReplacePath,
|
||||||
|
ReplacePathRegex: middleware.Spec.ReplacePathRegex,
|
||||||
|
Chain: createChainMiddleware(ctxMid, middleware.Namespace, middleware.Spec.Chain),
|
||||||
|
IPWhiteList: middleware.Spec.IPWhiteList,
|
||||||
|
Headers: middleware.Spec.Headers,
|
||||||
|
Errors: middleware.Spec.Errors,
|
||||||
|
RateLimit: middleware.Spec.RateLimit,
|
||||||
|
RedirectRegex: middleware.Spec.RedirectRegex,
|
||||||
|
RedirectScheme: middleware.Spec.RedirectScheme,
|
||||||
|
BasicAuth: middleware.Spec.BasicAuth,
|
||||||
|
DigestAuth: middleware.Spec.DigestAuth,
|
||||||
|
ForwardAuth: middleware.Spec.ForwardAuth,
|
||||||
|
InFlightReq: middleware.Spec.InFlightReq,
|
||||||
|
Buffering: middleware.Spec.Buffering,
|
||||||
|
CircuitBreaker: middleware.Spec.CircuitBreaker,
|
||||||
|
Compress: middleware.Spec.Compress,
|
||||||
|
PassTLSClientCert: middleware.Spec.PassTLSClientCert,
|
||||||
|
Retry: middleware.Spec.Retry,
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return conf
|
return conf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createChainMiddleware(ctx context.Context, namespace string, chain *v1alpha1.Chain) *dynamic.Chain {
|
||||||
|
if chain == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var mds []string
|
||||||
|
for _, mi := range chain.Middlewares {
|
||||||
|
if strings.Contains(mi.Name, "@") {
|
||||||
|
if len(mi.Namespace) > 0 {
|
||||||
|
log.FromContext(ctx).
|
||||||
|
Warnf("namespace %q is ignored in cross-provider context", mi.Namespace)
|
||||||
|
}
|
||||||
|
mds = append(mds, mi.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ns := mi.Namespace
|
||||||
|
if len(ns) == 0 {
|
||||||
|
ns = namespace
|
||||||
|
}
|
||||||
|
mds = append(mds, makeID(ns, mi.Name))
|
||||||
|
}
|
||||||
|
return &dynamic.Chain{Middlewares: mds}
|
||||||
|
}
|
||||||
|
|
||||||
func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options {
|
func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options {
|
||||||
tlsOptionsCRD := client.GetTLSOptions()
|
tlsOptionsCRD := client.GetTLSOptions()
|
||||||
var tlsOptions map[string]tls.Options
|
var tlsOptions map[string]tls.Options
|
||||||
|
|
|
@ -13,7 +13,41 @@ type Middleware struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata"`
|
metav1.ObjectMeta `json:"metadata"`
|
||||||
|
|
||||||
Spec dynamic.Middleware `json:"spec"`
|
Spec MiddlewareSpec `json:"spec"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
|
// Middleware holds the Middleware configuration.
|
||||||
|
type MiddlewareSpec struct {
|
||||||
|
AddPrefix *dynamic.AddPrefix `json:"addPrefix,omitempty" toml:"addPrefix,omitempty" yaml:"addPrefix,omitempty"`
|
||||||
|
StripPrefix *dynamic.StripPrefix `json:"stripPrefix,omitempty" toml:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty"`
|
||||||
|
StripPrefixRegex *dynamic.StripPrefixRegex `json:"stripPrefixRegex,omitempty" toml:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty"`
|
||||||
|
ReplacePath *dynamic.ReplacePath `json:"replacePath,omitempty" toml:"replacePath,omitempty" yaml:"replacePath,omitempty"`
|
||||||
|
ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty" toml:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty"`
|
||||||
|
Chain *Chain `json:"chain,omitempty" toml:"chain,omitempty" yaml:"chain,omitempty"`
|
||||||
|
IPWhiteList *dynamic.IPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty"`
|
||||||
|
Headers *dynamic.Headers `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty"`
|
||||||
|
Errors *dynamic.ErrorPage `json:"errors,omitempty" toml:"errors,omitempty" yaml:"errors,omitempty"`
|
||||||
|
RateLimit *dynamic.RateLimit `json:"rateLimit,omitempty" toml:"rateLimit,omitempty" yaml:"rateLimit,omitempty"`
|
||||||
|
RedirectRegex *dynamic.RedirectRegex `json:"redirectRegex,omitempty" toml:"redirectRegex,omitempty" yaml:"redirectRegex,omitempty"`
|
||||||
|
RedirectScheme *dynamic.RedirectScheme `json:"redirectScheme,omitempty" toml:"redirectScheme,omitempty" yaml:"redirectScheme,omitempty"`
|
||||||
|
BasicAuth *dynamic.BasicAuth `json:"basicAuth,omitempty" toml:"basicAuth,omitempty" yaml:"basicAuth,omitempty"`
|
||||||
|
DigestAuth *dynamic.DigestAuth `json:"digestAuth,omitempty" toml:"digestAuth,omitempty" yaml:"digestAuth,omitempty"`
|
||||||
|
ForwardAuth *dynamic.ForwardAuth `json:"forwardAuth,omitempty" toml:"forwardAuth,omitempty" yaml:"forwardAuth,omitempty"`
|
||||||
|
InFlightReq *dynamic.InFlightReq `json:"inFlightReq,omitempty" toml:"inFlightReq,omitempty" yaml:"inFlightReq,omitempty"`
|
||||||
|
Buffering *dynamic.Buffering `json:"buffering,omitempty" toml:"buffering,omitempty" yaml:"buffering,omitempty"`
|
||||||
|
CircuitBreaker *dynamic.CircuitBreaker `json:"circuitBreaker,omitempty" toml:"circuitBreaker,omitempty" yaml:"circuitBreaker,omitempty"`
|
||||||
|
Compress *dynamic.Compress `json:"compress,omitempty" toml:"compress,omitempty" yaml:"compress,omitempty" label:"allowEmpty"`
|
||||||
|
PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty" toml:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty"`
|
||||||
|
Retry *dynamic.Retry `json:"retry,omitempty" toml:"retry,omitempty" yaml:"retry,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
|
// Chain holds a chain of middlewares
|
||||||
|
type Chain struct {
|
||||||
|
Middlewares []MiddlewareRef `json:"middlewares,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
|
@ -29,9 +29,31 @@ THE SOFTWARE.
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
dynamic "github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Chain) DeepCopyInto(out *Chain) {
|
||||||
|
*out = *in
|
||||||
|
if in.Middlewares != nil {
|
||||||
|
in, out := &in.Middlewares, &out.Middlewares
|
||||||
|
*out = make([]MiddlewareRef, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Chain.
|
||||||
|
func (in *Chain) DeepCopy() *Chain {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Chain)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ClientAuth) DeepCopyInto(out *ClientAuth) {
|
func (in *ClientAuth) DeepCopyInto(out *ClientAuth) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@ -338,6 +360,127 @@ func (in *MiddlewareRef) DeepCopy() *MiddlewareRef {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) {
|
||||||
|
*out = *in
|
||||||
|
if in.AddPrefix != nil {
|
||||||
|
in, out := &in.AddPrefix, &out.AddPrefix
|
||||||
|
*out = new(dynamic.AddPrefix)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.StripPrefix != nil {
|
||||||
|
in, out := &in.StripPrefix, &out.StripPrefix
|
||||||
|
*out = new(dynamic.StripPrefix)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.StripPrefixRegex != nil {
|
||||||
|
in, out := &in.StripPrefixRegex, &out.StripPrefixRegex
|
||||||
|
*out = new(dynamic.StripPrefixRegex)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.ReplacePath != nil {
|
||||||
|
in, out := &in.ReplacePath, &out.ReplacePath
|
||||||
|
*out = new(dynamic.ReplacePath)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.ReplacePathRegex != nil {
|
||||||
|
in, out := &in.ReplacePathRegex, &out.ReplacePathRegex
|
||||||
|
*out = new(dynamic.ReplacePathRegex)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.Chain != nil {
|
||||||
|
in, out := &in.Chain, &out.Chain
|
||||||
|
*out = new(Chain)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.IPWhiteList != nil {
|
||||||
|
in, out := &in.IPWhiteList, &out.IPWhiteList
|
||||||
|
*out = new(dynamic.IPWhiteList)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.Headers != nil {
|
||||||
|
in, out := &in.Headers, &out.Headers
|
||||||
|
*out = new(dynamic.Headers)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.Errors != nil {
|
||||||
|
in, out := &in.Errors, &out.Errors
|
||||||
|
*out = new(dynamic.ErrorPage)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.RateLimit != nil {
|
||||||
|
in, out := &in.RateLimit, &out.RateLimit
|
||||||
|
*out = new(dynamic.RateLimit)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.RedirectRegex != nil {
|
||||||
|
in, out := &in.RedirectRegex, &out.RedirectRegex
|
||||||
|
*out = new(dynamic.RedirectRegex)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.RedirectScheme != nil {
|
||||||
|
in, out := &in.RedirectScheme, &out.RedirectScheme
|
||||||
|
*out = new(dynamic.RedirectScheme)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.BasicAuth != nil {
|
||||||
|
in, out := &in.BasicAuth, &out.BasicAuth
|
||||||
|
*out = new(dynamic.BasicAuth)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.DigestAuth != nil {
|
||||||
|
in, out := &in.DigestAuth, &out.DigestAuth
|
||||||
|
*out = new(dynamic.DigestAuth)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.ForwardAuth != nil {
|
||||||
|
in, out := &in.ForwardAuth, &out.ForwardAuth
|
||||||
|
*out = new(dynamic.ForwardAuth)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.InFlightReq != nil {
|
||||||
|
in, out := &in.InFlightReq, &out.InFlightReq
|
||||||
|
*out = new(dynamic.InFlightReq)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.Buffering != nil {
|
||||||
|
in, out := &in.Buffering, &out.Buffering
|
||||||
|
*out = new(dynamic.Buffering)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.CircuitBreaker != nil {
|
||||||
|
in, out := &in.CircuitBreaker, &out.CircuitBreaker
|
||||||
|
*out = new(dynamic.CircuitBreaker)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.Compress != nil {
|
||||||
|
in, out := &in.Compress, &out.Compress
|
||||||
|
*out = new(dynamic.Compress)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.PassTLSClientCert != nil {
|
||||||
|
in, out := &in.PassTLSClientCert, &out.PassTLSClientCert
|
||||||
|
*out = new(dynamic.PassTLSClientCert)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
if in.Retry != nil {
|
||||||
|
in, out := &in.Retry, &out.Retry
|
||||||
|
*out = new(dynamic.Retry)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MiddlewareSpec.
|
||||||
|
func (in *MiddlewareSpec) DeepCopy() *MiddlewareSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(MiddlewareSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Route) DeepCopyInto(out *Route) {
|
func (in *Route) DeepCopyInto(out *Route) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
|
Loading…
Reference in a new issue