diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index cc28f2d90fd..aa91b568932 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -10789,14 +10789,18 @@ "type": "object" }, "io.k8s.api.extensions.v1beta1.HTTPIngressPath": { - "description": "HTTPIngressPath associates a path regex with a backend. Incoming urls matching the path are forwarded to the backend.", + "description": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", "properties": { "backend": { "$ref": "#/definitions/io.k8s.api.extensions.v1beta1.IngressBackend", "description": "Backend defines the referenced service endpoint to which the traffic will be forwarded to." }, "path": { - "description": "Path is an extended POSIX regex as defined by IEEE Std 1003.1, (i.e this follows the egrep/unix syntax, not the perl syntax) matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. If unspecified, the path defaults to a catch all sending traffic to the backend.", + "description": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. When unspecified, all paths from incoming requests are matched.", + "type": "string" + }, + "pathType": { + "description": "PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types. Defaults to ImplementationSpecific.", "type": "string" } }, @@ -11714,14 +11718,18 @@ "type": "object" }, "io.k8s.api.networking.v1beta1.HTTPIngressPath": { - "description": "HTTPIngressPath associates a path regex with a backend. Incoming urls matching the path are forwarded to the backend.", + "description": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", "properties": { "backend": { "$ref": "#/definitions/io.k8s.api.networking.v1beta1.IngressBackend", "description": "Backend defines the referenced service endpoint to which the traffic will be forwarded to." }, "path": { - "description": "Path is an extended POSIX regex as defined by IEEE Std 1003.1, (i.e this follows the egrep/unix syntax, not the perl syntax) matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. If unspecified, the path defaults to a catch all sending traffic to the backend.", + "description": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. When unspecified, all paths from incoming requests are matched.", + "type": "string" + }, + "pathType": { + "description": "PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types. Defaults to ImplementationSpecific.", "type": "string" } }, diff --git a/hack/.golint_failures b/hack/.golint_failures index 00fb27756d0..f4f2155265f 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -34,6 +34,7 @@ pkg/apis/events/v1beta1 pkg/apis/extensions/v1beta1 pkg/apis/flowcontrol/v1alpha1 pkg/apis/networking/v1 +pkg/apis/networking/v1beta1 pkg/apis/node/v1alpha1 pkg/apis/policy/v1beta1 pkg/apis/rbac/v1 diff --git a/pkg/api/testing/defaulting_test.go b/pkg/api/testing/defaulting_test.go index 810b7563f1d..575c3be5513 100644 --- a/pkg/api/testing/defaulting_test.go +++ b/pkg/api/testing/defaulting_test.go @@ -113,6 +113,8 @@ func TestDefaulting(t *testing.T) { {Group: "apps", Version: "v1beta2", Kind: "DeploymentList"}: {}, {Group: "apps", Version: "v1", Kind: "Deployment"}: {}, {Group: "apps", Version: "v1", Kind: "DeploymentList"}: {}, + {Group: "extensions", Version: "v1beta1", Kind: "Ingress"}: {}, + {Group: "extensions", Version: "v1beta1", Kind: "IngressList"}: {}, {Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicy"}: {}, {Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicyList"}: {}, {Group: "apps", Version: "v1beta2", Kind: "ReplicaSet"}: {}, @@ -151,6 +153,8 @@ func TestDefaulting(t *testing.T) { {Group: "auditregistration.k8s.io", Version: "v1alpha1", Kind: "AuditSinkList"}: {}, {Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicy"}: {}, {Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicyList"}: {}, + {Group: "networking.k8s.io", Version: "v1beta1", Kind: "Ingress"}: {}, + {Group: "networking.k8s.io", Version: "v1beta1", Kind: "IngressList"}: {}, {Group: "storage.k8s.io", Version: "v1beta1", Kind: "StorageClass"}: {}, {Group: "storage.k8s.io", Version: "v1beta1", Kind: "StorageClassList"}: {}, {Group: "storage.k8s.io", Version: "v1beta1", Kind: "CSIDriver"}: {}, diff --git a/pkg/apis/extensions/v1beta1/conversion.go b/pkg/apis/extensions/v1beta1/conversion.go index 1fcb0c9b54c..8723b0771ef 100644 --- a/pkg/apis/extensions/v1beta1/conversion.go +++ b/pkg/apis/extensions/v1beta1/conversion.go @@ -20,7 +20,6 @@ import ( "fmt" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/labels" diff --git a/pkg/apis/extensions/v1beta1/defaults.go b/pkg/apis/extensions/v1beta1/defaults.go index 4bb885567b7..1631dcb0eed 100644 --- a/pkg/apis/extensions/v1beta1/defaults.go +++ b/pkg/apis/extensions/v1beta1/defaults.go @@ -165,3 +165,10 @@ func SetDefaults_NetworkPolicy(obj *extensionsv1beta1.NetworkPolicy) { } } } + +func SetDefaults_HTTPIngressPath(obj *extensionsv1beta1.HTTPIngressPath) { + var defaultPathType = extensionsv1beta1.PathTypeImplementationSpecific + if obj.PathType == nil { + obj.PathType = &defaultPathType + } +} diff --git a/pkg/apis/extensions/v1beta1/zz_generated.conversion.go b/pkg/apis/extensions/v1beta1/zz_generated.conversion.go index b5482619cf9..e8e4716efd1 100644 --- a/pkg/apis/extensions/v1beta1/zz_generated.conversion.go +++ b/pkg/apis/extensions/v1beta1/zz_generated.conversion.go @@ -1161,6 +1161,7 @@ func Convert_policy_FSGroupStrategyOptions_To_v1beta1_FSGroupStrategyOptions(in func autoConvert_v1beta1_HTTPIngressPath_To_networking_HTTPIngressPath(in *v1beta1.HTTPIngressPath, out *networking.HTTPIngressPath, s conversion.Scope) error { out.Path = in.Path + out.PathType = (*networking.PathType)(unsafe.Pointer(in.PathType)) if err := Convert_v1beta1_IngressBackend_To_networking_IngressBackend(&in.Backend, &out.Backend, s); err != nil { return err } @@ -1174,6 +1175,7 @@ func Convert_v1beta1_HTTPIngressPath_To_networking_HTTPIngressPath(in *v1beta1.H func autoConvert_networking_HTTPIngressPath_To_v1beta1_HTTPIngressPath(in *networking.HTTPIngressPath, out *v1beta1.HTTPIngressPath, s conversion.Scope) error { out.Path = in.Path + out.PathType = (*v1beta1.PathType)(unsafe.Pointer(in.PathType)) if err := Convert_networking_IngressBackend_To_v1beta1_IngressBackend(&in.Backend, &out.Backend, s); err != nil { return err } diff --git a/pkg/apis/extensions/v1beta1/zz_generated.defaults.go b/pkg/apis/extensions/v1beta1/zz_generated.defaults.go index 6c573d35d11..e03958755b0 100644 --- a/pkg/apis/extensions/v1beta1/zz_generated.defaults.go +++ b/pkg/apis/extensions/v1beta1/zz_generated.defaults.go @@ -34,6 +34,8 @@ func RegisterDefaults(scheme *runtime.Scheme) error { scheme.AddTypeDefaultingFunc(&v1beta1.DaemonSetList{}, func(obj interface{}) { SetObjectDefaults_DaemonSetList(obj.(*v1beta1.DaemonSetList)) }) scheme.AddTypeDefaultingFunc(&v1beta1.Deployment{}, func(obj interface{}) { SetObjectDefaults_Deployment(obj.(*v1beta1.Deployment)) }) scheme.AddTypeDefaultingFunc(&v1beta1.DeploymentList{}, func(obj interface{}) { SetObjectDefaults_DeploymentList(obj.(*v1beta1.DeploymentList)) }) + scheme.AddTypeDefaultingFunc(&v1beta1.Ingress{}, func(obj interface{}) { SetObjectDefaults_Ingress(obj.(*v1beta1.Ingress)) }) + scheme.AddTypeDefaultingFunc(&v1beta1.IngressList{}, func(obj interface{}) { SetObjectDefaults_IngressList(obj.(*v1beta1.IngressList)) }) scheme.AddTypeDefaultingFunc(&v1beta1.NetworkPolicy{}, func(obj interface{}) { SetObjectDefaults_NetworkPolicy(obj.(*v1beta1.NetworkPolicy)) }) scheme.AddTypeDefaultingFunc(&v1beta1.NetworkPolicyList{}, func(obj interface{}) { SetObjectDefaults_NetworkPolicyList(obj.(*v1beta1.NetworkPolicyList)) }) scheme.AddTypeDefaultingFunc(&v1beta1.PodSecurityPolicy{}, func(obj interface{}) { SetObjectDefaults_PodSecurityPolicy(obj.(*v1beta1.PodSecurityPolicy)) }) @@ -457,6 +459,25 @@ func SetObjectDefaults_DeploymentList(in *v1beta1.DeploymentList) { } } +func SetObjectDefaults_Ingress(in *v1beta1.Ingress) { + for i := range in.Spec.Rules { + a := &in.Spec.Rules[i] + if a.IngressRuleValue.HTTP != nil { + for j := range a.IngressRuleValue.HTTP.Paths { + b := &a.IngressRuleValue.HTTP.Paths[j] + SetDefaults_HTTPIngressPath(b) + } + } + } +} + +func SetObjectDefaults_IngressList(in *v1beta1.IngressList) { + for i := range in.Items { + a := &in.Items[i] + SetObjectDefaults_Ingress(a) + } +} + func SetObjectDefaults_NetworkPolicy(in *v1beta1.NetworkPolicy) { SetDefaults_NetworkPolicy(in) } diff --git a/pkg/apis/networking/fuzzer/fuzzer.go b/pkg/apis/networking/fuzzer/fuzzer.go index 3d36b7c97b2..bee51e18e55 100644 --- a/pkg/apis/networking/fuzzer/fuzzer.go +++ b/pkg/apis/networking/fuzzer/fuzzer.go @@ -44,5 +44,10 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} { np.Spec.PolicyTypes = []networking.PolicyType{networking.PolicyTypeIngress} } }, + func(path *networking.HTTPIngressPath, c fuzz.Continue) { + c.FuzzNoCustom(path) // fuzz self without calling this function again + pathTypes := []networking.PathType{networking.PathTypeExact, networking.PathTypePrefix, networking.PathTypeImplementationSpecific} + path.PathType = &pathTypes[c.Rand.Intn(len(pathTypes))] + }, } } diff --git a/pkg/apis/networking/types.go b/pkg/apis/networking/types.go index c10b7570549..4d8bf1897fe 100644 --- a/pkg/apis/networking/types.go +++ b/pkg/apis/networking/types.go @@ -345,8 +345,9 @@ type IngressStatus struct { } // IngressRule represents the rules mapping the paths under a specified host to -// the related backend services. Incoming requests are first evaluated for a host -// match, then routed to the backend associated with the matching IngressRuleValue. +// the related backend services. Incoming requests are first evaluated for a +// host match, then routed to the backend associated with the matching +// IngressRuleValue. type IngressRule struct { // Host is the fully qualified domain name of a network host, as defined // by RFC 3986. Note the following deviations from the "host" part of the @@ -362,11 +363,12 @@ type IngressRule struct { // specified IngressRuleValue. // +optional Host string - // IngressRuleValue represents a rule to route requests for this IngressRule. - // If unspecified, the rule defaults to a http catch-all. Whether that sends - // just traffic matching the host to the default backend or all traffic to the - // default backend, is left to the controller fulfilling the Ingress. Http is - // currently the only supported IngressRuleValue. + // IngressRuleValue represents a rule to route requests for this + // IngressRule. If unspecified, the rule defaults to a http catch-all. + // Whether that sends just traffic matching the host to the default backend + // or all traffic to the default backend, is left to the controller + // fulfilling the Ingress. Http is currently the only supported + // IngressRuleValue. // +optional IngressRuleValue } @@ -398,19 +400,52 @@ type HTTPIngressRuleValue struct { // options usable by a loadbalancer, like http keep-alive. } -// HTTPIngressPath associates a path regex with a backend. Incoming urls matching -// the path are forwarded to the backend. +// PathType represents the type of path referred to by a HTTPIngressPath. +type PathType string + +const ( + // PathTypeExact matches the URL path exactly and with case sensitivity. + PathTypeExact = PathType("Exact") + + // PathTypePrefix matches based on a URL path prefix split by '/'. Matching + // is case sensitive and done on a path element by element basis. A path + // element refers to the list of labels in the path split by the '/' + // separator. A request is a match for path p if every p is an element-wise + // prefix of p of the request path. Note that if the last element of the + // path is a substring of the last element in request path, it is not a + // match (e.g. /foo/bar matches /foo/bar/baz, but does not match + // /foo/barbaz). If multiple matching paths exist in an Ingress spec, the + // longest matching path is given priority. + // Examples: + // - /foo/bar does not match requests to /foo/barbaz + // - /foo/bar matches request to /foo/bar and /foo/bar/baz + // - /foo and /foo/ both match requests to /foo and /foo/. If both paths are + // present in an Ingress spec, the longest matching path (/foo/) is given + // priority. + PathTypePrefix = PathType("Prefix") + + // PathTypeImplementationSpecific matching is up to the IngressClass. + // Implementations can treat this as a separate PathType or treat it + // identically to Prefix or Exact path types. + PathTypeImplementationSpecific = PathType("ImplementationSpecific") +) + +// HTTPIngressPath associates a path with a backend. Incoming urls matching the +// path are forwarded to the backend. type HTTPIngressPath struct { - // Path is an extended POSIX regex as defined by IEEE Std 1003.1, - // (i.e this follows the egrep/unix syntax, not the perl syntax) - // matched against the path of an incoming request. Currently it can - // contain characters disallowed from the conventional "path" - // part of a URL as defined by RFC 3986. Paths must begin with - // a '/'. If unspecified, the path defaults to a catch all sending - // traffic to the backend. + // Path is matched against the path of an incoming request. Currently it can + // contain characters disallowed from the conventional "path" part of a URL + // as defined by RFC 3986. Paths must begin with a '/'. When unspecified, + // all paths from incoming requests are matched. // +optional Path string + // PathType determines the interpretation of the Path matching. PathType can + // be one of Exact, Prefix, or ImplementationSpecific. Implementations are + // required to support all path types. + // +optional + PathType *PathType + // Backend defines the referenced service endpoint to which the traffic // will be forwarded to. Backend IngressBackend diff --git a/pkg/apis/networking/v1/defaults_test.go b/pkg/apis/networking/v1/defaults_test.go index 7bc2a68339d..7da30adcc59 100644 --- a/pkg/apis/networking/v1/defaults_test.go +++ b/pkg/apis/networking/v1/defaults_test.go @@ -21,7 +21,6 @@ import ( "testing" networkingv1 "k8s.io/api/networking/v1" - apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -236,6 +235,7 @@ func TestSetDefaultNetworkPolicy(t *testing.T) { } func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { + t.Helper() data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(SchemeGroupVersion), obj) if err != nil { t.Errorf("%v\n %#v", err, obj) diff --git a/pkg/apis/networking/v1beta1/BUILD b/pkg/apis/networking/v1beta1/BUILD index e561152a209..1b99d063ba1 100644 --- a/pkg/apis/networking/v1beta1/BUILD +++ b/pkg/apis/networking/v1beta1/BUILD @@ -1,6 +1,6 @@ package(default_visibility = ["//visibility:public"]) -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -36,3 +36,16 @@ filegroup( srcs = [":package-srcs"], tags = ["automanaged"], ) + +go_test( + name = "go_default_test", + srcs = ["defaults_test.go"], + embed = [":go_default_library"], + deps = [ + "//pkg/api/legacyscheme:go_default_library", + "//pkg/apis/networking/install:go_default_library", + "//staging/src/k8s.io/api/networking/v1beta1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + ], +) diff --git a/pkg/apis/networking/v1beta1/defaults.go b/pkg/apis/networking/v1beta1/defaults.go index e2ef92ce7eb..0b7b3acff04 100644 --- a/pkg/apis/networking/v1beta1/defaults.go +++ b/pkg/apis/networking/v1beta1/defaults.go @@ -17,9 +17,17 @@ limitations under the License. package v1beta1 import ( + networkingv1beta1 "k8s.io/api/networking/v1beta1" "k8s.io/apimachinery/pkg/runtime" ) func addDefaultingFuncs(scheme *runtime.Scheme) error { return RegisterDefaults(scheme) } + +func SetDefaults_HTTPIngressPath(obj *networkingv1beta1.HTTPIngressPath) { + var defaultPathType = networkingv1beta1.PathTypeImplementationSpecific + if obj.PathType == nil { + obj.PathType = &defaultPathType + } +} diff --git a/pkg/apis/networking/v1beta1/defaults_test.go b/pkg/apis/networking/v1beta1/defaults_test.go new file mode 100644 index 00000000000..7ce1bd07cbe --- /dev/null +++ b/pkg/apis/networking/v1beta1/defaults_test.go @@ -0,0 +1,101 @@ +/* +Copyright 2020 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 v1beta1_test + +import ( + "reflect" + "testing" + + networkingv1beta1 "k8s.io/api/networking/v1beta1" + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/kubernetes/pkg/api/legacyscheme" + _ "k8s.io/kubernetes/pkg/apis/networking/install" + . "k8s.io/kubernetes/pkg/apis/networking/v1beta1" +) + +func TestSetIngressPathDefaults(t *testing.T) { + pathTypeImplementationSpecific := networkingv1beta1.PathTypeImplementationSpecific + pathTypeExact := networkingv1beta1.PathTypeExact + + testCases := map[string]struct { + original *networkingv1beta1.HTTPIngressPath + expected *networkingv1beta1.HTTPIngressPath + }{ + "empty pathType should default to ImplementationSpecific": { + original: &networkingv1beta1.HTTPIngressPath{}, + expected: &networkingv1beta1.HTTPIngressPath{PathType: &pathTypeImplementationSpecific}, + }, + "ImplementationSpecific pathType should not change": { + original: &networkingv1beta1.HTTPIngressPath{PathType: &pathTypeImplementationSpecific}, + expected: &networkingv1beta1.HTTPIngressPath{PathType: &pathTypeImplementationSpecific}, + }, + "Exact pathType should not change": { + original: &networkingv1beta1.HTTPIngressPath{PathType: &pathTypeExact}, + expected: &networkingv1beta1.HTTPIngressPath{PathType: &pathTypeExact}, + }, + } + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + ingressOriginal := wrapIngressPath(testCase.original) + ingressExpected := wrapIngressPath(testCase.expected) + runtimeObj := roundTrip(t, runtime.Object(ingressOriginal)) + ingressActual, ok := runtimeObj.(*networkingv1beta1.Ingress) + if !ok { + t.Fatalf("Unexpected object: %v", ingressActual) + } + if !apiequality.Semantic.DeepEqual(ingressActual.Spec, ingressExpected.Spec) { + t.Errorf("Expected: %+v, got: %+v", ingressExpected.Spec, ingressActual.Spec) + } + }) + } +} + +func wrapIngressPath(path *networkingv1beta1.HTTPIngressPath) *networkingv1beta1.Ingress { + return &networkingv1beta1.Ingress{ + Spec: networkingv1beta1.IngressSpec{ + Rules: []networkingv1beta1.IngressRule{{ + IngressRuleValue: networkingv1beta1.IngressRuleValue{ + HTTP: &networkingv1beta1.HTTPIngressRuleValue{ + Paths: []networkingv1beta1.HTTPIngressPath{*path}, + }, + }, + }}, + }, + } +} + +func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { + t.Helper() + data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(SchemeGroupVersion), obj) + if err != nil { + t.Errorf("%v\n %#v", err, obj) + return nil + } + obj2, err := runtime.Decode(legacyscheme.Codecs.UniversalDecoder(), data) + if err != nil { + t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj) + return nil + } + obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object) + err = legacyscheme.Scheme.Convert(obj2, obj3, nil) + if err != nil { + t.Errorf("%v\nSource: %#v", err, obj2) + return nil + } + return obj3 +} diff --git a/pkg/apis/networking/v1beta1/zz_generated.conversion.go b/pkg/apis/networking/v1beta1/zz_generated.conversion.go index 124e38788bb..076c4f39a49 100644 --- a/pkg/apis/networking/v1beta1/zz_generated.conversion.go +++ b/pkg/apis/networking/v1beta1/zz_generated.conversion.go @@ -174,6 +174,7 @@ func RegisterConversions(s *runtime.Scheme) error { func autoConvert_v1beta1_HTTPIngressPath_To_networking_HTTPIngressPath(in *v1beta1.HTTPIngressPath, out *networking.HTTPIngressPath, s conversion.Scope) error { out.Path = in.Path + out.PathType = (*networking.PathType)(unsafe.Pointer(in.PathType)) if err := Convert_v1beta1_IngressBackend_To_networking_IngressBackend(&in.Backend, &out.Backend, s); err != nil { return err } @@ -187,6 +188,7 @@ func Convert_v1beta1_HTTPIngressPath_To_networking_HTTPIngressPath(in *v1beta1.H func autoConvert_networking_HTTPIngressPath_To_v1beta1_HTTPIngressPath(in *networking.HTTPIngressPath, out *v1beta1.HTTPIngressPath, s conversion.Scope) error { out.Path = in.Path + out.PathType = (*v1beta1.PathType)(unsafe.Pointer(in.PathType)) if err := Convert_networking_IngressBackend_To_v1beta1_IngressBackend(&in.Backend, &out.Backend, s); err != nil { return err } diff --git a/pkg/apis/networking/v1beta1/zz_generated.defaults.go b/pkg/apis/networking/v1beta1/zz_generated.defaults.go index 73e63fc114d..03edf68ef81 100644 --- a/pkg/apis/networking/v1beta1/zz_generated.defaults.go +++ b/pkg/apis/networking/v1beta1/zz_generated.defaults.go @@ -21,6 +21,7 @@ limitations under the License. package v1beta1 import ( + v1beta1 "k8s.io/api/networking/v1beta1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -28,5 +29,26 @@ import ( // Public to allow building arbitrary schemes. // All generated defaulters are covering - they call all nested defaulters. func RegisterDefaults(scheme *runtime.Scheme) error { + scheme.AddTypeDefaultingFunc(&v1beta1.Ingress{}, func(obj interface{}) { SetObjectDefaults_Ingress(obj.(*v1beta1.Ingress)) }) + scheme.AddTypeDefaultingFunc(&v1beta1.IngressList{}, func(obj interface{}) { SetObjectDefaults_IngressList(obj.(*v1beta1.IngressList)) }) return nil } + +func SetObjectDefaults_Ingress(in *v1beta1.Ingress) { + for i := range in.Spec.Rules { + a := &in.Spec.Rules[i] + if a.IngressRuleValue.HTTP != nil { + for j := range a.IngressRuleValue.HTTP.Paths { + b := &a.IngressRuleValue.HTTP.Paths[j] + SetDefaults_HTTPIngressPath(b) + } + } + } +} + +func SetObjectDefaults_IngressList(in *v1beta1.IngressList) { + for i := range in.Items { + a := &in.Items[i] + SetObjectDefaults_Ingress(a) + } +} diff --git a/pkg/apis/networking/validation/BUILD b/pkg/apis/networking/validation/BUILD index 300489bad8a..6ef836b2bcf 100644 --- a/pkg/apis/networking/validation/BUILD +++ b/pkg/apis/networking/validation/BUILD @@ -17,8 +17,11 @@ go_test( "//pkg/apis/core:go_default_library", "//pkg/apis/networking:go_default_library", "//pkg/features:go_default_library", + "//staging/src/k8s.io/api/networking/v1:go_default_library", + "//staging/src/k8s.io/api/networking/v1beta1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", @@ -43,6 +46,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/validation/path:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", diff --git a/pkg/apis/networking/validation/validation.go b/pkg/apis/networking/validation/validation.go index 21f6bfe0bbd..bfe5462d3c8 100644 --- a/pkg/apis/networking/validation/validation.go +++ b/pkg/apis/networking/validation/validation.go @@ -17,6 +17,7 @@ limitations under the License. package validation import ( + "fmt" "net" "regexp" "strings" @@ -24,6 +25,7 @@ import ( apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" pathvalidation "k8s.io/apimachinery/pkg/api/validation/path" unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" @@ -38,6 +40,16 @@ const ( maxLenIngressClassController = 250 ) +var ( + supportedPathTypes = sets.NewString( + string(networking.PathTypeExact), + string(networking.PathTypePrefix), + string(networking.PathTypeImplementationSpecific), + ) + invalidPathSequences = []string{"//", "/./", "/../", "%2f", "%2F"} + invalidPathSuffixes = []string{"/..", "/."} +) + // ValidateNetworkPolicyName can be used to check whether the given networkpolicy // name is valid. func ValidateNetworkPolicyName(name string, prefix bool) []string { @@ -184,17 +196,27 @@ func ValidateIPBlock(ipb *networking.IPBlock, fldPath *field.Path) field.ErrorLi // name. var ValidateIngressName = apimachineryvalidation.NameIsDNSSubdomain +// IngressValidationOptions cover beta to GA transitions for HTTP PathType +type IngressValidationOptions struct { + requireRegexPath bool +} + // ValidateIngress validates Ingresses on create and update. -func ValidateIngress(ingress *networking.Ingress) field.ErrorList { +func validateIngress(ingress *networking.Ingress, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { allErrs := apivalidation.ValidateObjectMeta(&ingress.ObjectMeta, true, ValidateIngressName, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateIngressSpec(&ingress.Spec, field.NewPath("spec"))...) + allErrs = append(allErrs, ValidateIngressSpec(&ingress.Spec, field.NewPath("spec"), opts, requestGV)...) return allErrs } // ValidateIngressCreate validates Ingresses on create. -func ValidateIngressCreate(ingress *networking.Ingress) field.ErrorList { +func ValidateIngressCreate(ingress *networking.Ingress, requestGV schema.GroupVersion) field.ErrorList { allErrs := field.ErrorList{} - allErrs = append(allErrs, ValidateIngress(ingress)...) + var opts IngressValidationOptions + opts = IngressValidationOptions{ + // TODO(robscott): Remove regex validation for 1.19. + requireRegexPath: true, + } + allErrs = append(allErrs, validateIngress(ingress, opts, requestGV)...) annotationVal, annotationIsSet := ingress.Annotations[annotationIngressClass] if annotationIsSet && ingress.Spec.IngressClassName != nil { annotationPath := field.NewPath("annotations").Child(annotationIngressClass) @@ -204,9 +226,17 @@ func ValidateIngressCreate(ingress *networking.Ingress) field.ErrorList { } // ValidateIngressUpdate validates ingresses on update. -func ValidateIngressUpdate(ingress, oldIngress *networking.Ingress) field.ErrorList { +func ValidateIngressUpdate(ingress, oldIngress *networking.Ingress, requestGV schema.GroupVersion) field.ErrorList { allErrs := apivalidation.ValidateObjectMetaUpdate(&ingress.ObjectMeta, &oldIngress.ObjectMeta, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateIngress(ingress)...) + var opts IngressValidationOptions + opts = IngressValidationOptions{ + // TODO(robscott): Remove regex validation for 1.19. + // Only require regex path validation for this Ingress if the previous + // version of the Ingress also passed that validation. + requireRegexPath: allPathsPassRegexValidation(oldIngress), + } + + allErrs = append(allErrs, validateIngress(ingress, opts, requestGV)...) return allErrs } @@ -232,16 +262,17 @@ func validateIngressTLS(spec *networking.IngressSpec, fldPath *field.Path) field } // ValidateIngressSpec tests if required fields in the IngressSpec are set. -func ValidateIngressSpec(spec *networking.IngressSpec, fldPath *field.Path) field.ErrorList { +func ValidateIngressSpec(spec *networking.IngressSpec, fldPath *field.Path, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { allErrs := field.ErrorList{} - // TODO: Is a default backend mandatory? + if len(spec.Rules) == 0 && spec.Backend == nil { + errMsg := "either `backend` or `rules` must be specified" + allErrs = append(allErrs, field.Invalid(fldPath, spec.Rules, errMsg)) + } if spec.Backend != nil { allErrs = append(allErrs, validateIngressBackend(spec.Backend, fldPath.Child("backend"))...) - } else if len(spec.Rules) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath, spec.Rules, "either `backend` or `rules` must be specified")) } if len(spec.Rules) > 0 { - allErrs = append(allErrs, validateIngressRules(spec.Rules, fldPath.Child("rules"))...) + allErrs = append(allErrs, validateIngressRules(spec.Rules, fldPath.Child("rules"), opts)...) } if len(spec.TLS) > 0 { allErrs = append(allErrs, validateIngressTLS(spec, fldPath.Child("tls"))...) @@ -261,7 +292,7 @@ func ValidateIngressStatusUpdate(ingress, oldIngress *networking.Ingress) field. return allErrs } -func validateIngressRules(ingressRules []networking.IngressRule, fldPath *field.Path) field.ErrorList { +func validateIngressRules(ingressRules []networking.IngressRule, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if len(ingressRules) == 0 { return append(allErrs, field.Required(fldPath, "")) @@ -283,45 +314,74 @@ func validateIngressRules(ingressRules []networking.IngressRule, fldPath *field. allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, msg)) } } - allErrs = append(allErrs, validateIngressRuleValue(&ih.IngressRuleValue, fldPath.Index(0))...) + allErrs = append(allErrs, validateIngressRuleValue(&ih.IngressRuleValue, fldPath.Index(0), opts)...) } return allErrs } -func validateIngressRuleValue(ingressRule *networking.IngressRuleValue, fldPath *field.Path) field.ErrorList { +func validateIngressRuleValue(ingressRule *networking.IngressRuleValue, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if ingressRule.HTTP != nil { - allErrs = append(allErrs, validateHTTPIngressRuleValue(ingressRule.HTTP, fldPath.Child("http"))...) + allErrs = append(allErrs, validateHTTPIngressRuleValue(ingressRule.HTTP, fldPath.Child("http"), opts)...) } return allErrs } -func validateHTTPIngressRuleValue(httpIngressRuleValue *networking.HTTPIngressRuleValue, fldPath *field.Path) field.ErrorList { +func validateHTTPIngressRuleValue(httpIngressRuleValue *networking.HTTPIngressRuleValue, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if len(httpIngressRuleValue.Paths) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("paths"), "")) } - for i, rule := range httpIngressRuleValue.Paths { - if len(rule.Path) > 0 { - if !strings.HasPrefix(rule.Path, "/") { - allErrs = append(allErrs, field.Invalid(fldPath.Child("paths").Index(i).Child("path"), rule.Path, "must be an absolute path")) + for i, path := range httpIngressRuleValue.Paths { + allErrs = append(allErrs, validateHTTPIngressPath(&path, fldPath.Child("paths").Index(i), opts)...) + } + return allErrs +} + +func validateHTTPIngressPath(path *networking.HTTPIngressPath, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { + allErrs := field.ErrorList{} + + if path.PathType == nil { + return append(allErrs, field.Required(fldPath.Child("pathType"), "pathType must be specified")) + } + + switch *path.PathType { + case networking.PathTypeExact, networking.PathTypePrefix: + if !strings.HasPrefix(path.Path, "/") { + allErrs = append(allErrs, field.Invalid(fldPath.Child("path"), path.Path, "must be an absolute path")) + } + if len(path.Path) > 0 { + for _, invalidSeq := range invalidPathSequences { + if strings.Contains(path.Path, invalidSeq) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("path"), path.Path, fmt.Sprintf("must not contain '%s'", invalidSeq))) + } } - // TODO: More draconian path regex validation. - // Path must be a valid regex. This is the basic requirement. - // In addition to this any characters not allowed in a path per - // RFC 3986 section-3.3 cannot appear as a literal in the regex. - // Consider the example: http://host/valid?#bar, everything after - // the last '/' is a valid regex that matches valid#bar, which - // isn't a valid path, because the path terminates at the first ? - // or #. A more sophisticated form of validation would detect that - // the user is confusing url regexes with path regexes. - _, err := regexp.CompilePOSIX(rule.Path) - if err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("paths").Index(i).Child("path"), rule.Path, "must be a valid regex")) + + for _, invalidSuff := range invalidPathSuffixes { + if strings.HasSuffix(path.Path, invalidSuff) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("path"), path.Path, fmt.Sprintf("cannot end with '%s'", invalidSuff))) + } } } - allErrs = append(allErrs, validateIngressBackend(&rule.Backend, fldPath.Child("backend"))...) + case networking.PathTypeImplementationSpecific: + if len(path.Path) > 0 { + if !strings.HasPrefix(path.Path, "/") { + allErrs = append(allErrs, field.Invalid(fldPath.Child("path"), path.Path, "must be an absolute path")) + } + } + default: + allErrs = append(allErrs, field.NotSupported(fldPath.Child("pathType"), *path.PathType, supportedPathTypes.List())) } + + // TODO(robscott): Remove regex validation for 1.19. + if opts.requireRegexPath { + _, err := regexp.CompilePOSIX(path.Path) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("path"), path.Path, "must be a valid regex")) + } + } + + allErrs = append(allErrs, validateIngressBackend(&path.Backend, fldPath.Child("backend"))...) return allErrs } @@ -408,3 +468,22 @@ func validateIngressClassParameters(params *api.TypedLocalObjectReference, fldPa return allErrs } + +// allPathsPassRegexValidation returns true if the Ingress has paths that all +// match the Ingress path validation with requireRegexPath enabled. +func allPathsPassRegexValidation(ingress *networking.Ingress) bool { + for _, rule := range ingress.Spec.Rules { + if rule.HTTP == nil { + continue + } + for _, path := range rule.HTTP.Paths { + if len(path.Path) == 0 { + continue + } + if _, err := regexp.CompilePOSIX(path.Path); err != nil { + return false + } + } + } + return true +} diff --git a/pkg/apis/networking/validation/validation_test.go b/pkg/apis/networking/validation/validation_test.go index e7a9d861339..4031ef6d7fd 100644 --- a/pkg/apis/networking/validation/validation_test.go +++ b/pkg/apis/networking/validation/validation_test.go @@ -18,19 +18,22 @@ package validation import ( "fmt" - apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" - "k8s.io/apimachinery/pkg/util/validation/field" - utilpointer "k8s.io/utils/pointer" "strings" "testing" + networkingv1 "k8s.io/api/networking/v1" + networkingv1beta1 "k8s.io/api/networking/v1beta1" + apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/validation/field" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/networking" "k8s.io/kubernetes/pkg/features" + utilpointer "k8s.io/utils/pointer" ) func TestValidateNetworkPolicy(t *testing.T) { @@ -897,106 +900,265 @@ func TestValidateIngress(t *testing.T) { ServiceName: "default-backend", ServicePort: intstr.FromInt(80), } + pathTypePrefix := networking.PathTypePrefix + pathTypeImplementationSpecific := networking.PathTypeImplementationSpecific + pathTypeFoo := networking.PathType("foo") - newValid := func() networking.Ingress { - return networking.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: metav1.NamespaceDefault, + baseIngress := networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: metav1.NamespaceDefault, + }, + Spec: networking.IngressSpec{ + Backend: &networking.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), }, - Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), - }, - Rules: []networking.IngressRule{ - { - Host: "foo.bar.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{ - { - Path: "/foo", - Backend: defaultBackend, - }, + Rules: []networking.IngressRule{ + { + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/foo", + PathType: &pathTypeImplementationSpecific, + Backend: defaultBackend, }, }, }, }, }, }, - Status: networking.IngressStatus{ - LoadBalancer: api.LoadBalancerStatus{ - Ingress: []api.LoadBalancerIngress{ - {IP: "127.0.0.1"}, - }, + }, + Status: networking.IngressStatus{ + LoadBalancer: api.LoadBalancerStatus{ + Ingress: []api.LoadBalancerIngress{ + {IP: "127.0.0.1"}, }, }, - } - } - servicelessBackend := newValid() - servicelessBackend.Spec.Backend.ServiceName = "" - invalidNameBackend := newValid() - invalidNameBackend.Spec.Backend.ServiceName = "defaultBackend" - noPortBackend := newValid() - noPortBackend.Spec.Backend = &networking.IngressBackend{ServiceName: defaultBackend.ServiceName} - noForwardSlashPath := newValid() - noForwardSlashPath.Spec.Rules[0].IngressRuleValue.HTTP.Paths = []networking.HTTPIngressPath{ - { - Path: "invalid", - Backend: defaultBackend, }, } - noPaths := newValid() - noPaths.Spec.Rules[0].IngressRuleValue.HTTP.Paths = []networking.HTTPIngressPath{} - badHost := newValid() - badHost.Spec.Rules[0].Host = "foobar:80" - badRegexPath := newValid() - badPathExpr := "/invalid[" - badRegexPath.Spec.Rules[0].IngressRuleValue.HTTP.Paths = []networking.HTTPIngressPath{ - { - Path: badPathExpr, - Backend: defaultBackend, + + testCases := map[string]struct { + groupVersion *schema.GroupVersion + tweakIngress func(ing *networking.Ingress) + expectErrsOnFields []string + }{ + "empty path (implementation specific)": { + tweakIngress: func(ing *networking.Ingress) { + ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].Path = "" + }, + expectErrsOnFields: []string{}, + }, + "valid path": { + tweakIngress: func(ing *networking.Ingress) { + ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].Path = "/valid" + }, + expectErrsOnFields: []string{}, + }, + // invalid use cases + "backend (v1beta1) with no service": { + groupVersion: &networkingv1beta1.SchemeGroupVersion, + tweakIngress: func(ing *networking.Ingress) { + ing.Spec.Backend.ServiceName = "" + }, + expectErrsOnFields: []string{ + "spec.backend.serviceName", + }, + }, + "invalid path type": { + tweakIngress: func(ing *networking.Ingress) { + ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].PathType = &pathTypeFoo + }, + expectErrsOnFields: []string{ + "spec.rules[0].http.paths[0].pathType", + }, + }, + "empty path (prefix)": { + tweakIngress: func(ing *networking.Ingress) { + ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].Path = "" + ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].PathType = &pathTypePrefix + }, + expectErrsOnFields: []string{ + "spec.rules[0].http.paths[0].path", + }, + }, + "no paths": { + tweakIngress: func(ing *networking.Ingress) { + ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths = []networking.HTTPIngressPath{} + }, + expectErrsOnFields: []string{ + "spec.rules[0].http.paths", + }, + }, + "invalid host (foobar:80)": { + tweakIngress: func(ing *networking.Ingress) { + ing.Spec.Rules[0].Host = "foobar:80" + }, + expectErrsOnFields: []string{ + "spec.rules[0].host", + }, + }, + "invalid host (127.0.0.1)": { + tweakIngress: func(ing *networking.Ingress) { + ing.Spec.Rules[0].Host = "127.0.0.1" + }, + expectErrsOnFields: []string{ + "spec.rules[0].host", + }, }, } - badPathErr := fmt.Sprintf("spec.rules[0].http.paths[0].path: Invalid value: '%v'", badPathExpr) - hostIP := "127.0.0.1" - badHostIP := newValid() - badHostIP.Spec.Rules[0].Host = hostIP - badHostIPErr := fmt.Sprintf("spec.rules[0].host: Invalid value: '%v'", hostIP) - errorCases := map[string]networking.Ingress{ - "spec.backend.serviceName: Required value": servicelessBackend, - "spec.backend.serviceName: Invalid value": invalidNameBackend, - "spec.backend.servicePort: Invalid value": noPortBackend, - "spec.rules[0].host: Invalid value": badHost, - "spec.rules[0].http.paths: Required value": noPaths, - "spec.rules[0].http.paths[0].path: Invalid value": noForwardSlashPath, - } - errorCases[badPathErr] = badRegexPath - errorCases[badHostIPErr] = badHostIP - - wildcardHost := "foo.*.bar.com" - badWildcard := newValid() - badWildcard.Spec.Rules[0].Host = wildcardHost - badWildcardErr := fmt.Sprintf("spec.rules[0].host: Invalid value: '%v'", wildcardHost) - errorCases[badWildcardErr] = badWildcard - - for k, v := range errorCases { - errs := ValidateIngress(&v) - if len(errs) == 0 { - t.Errorf("expected failure for %q", k) - } else { - s := strings.Split(k, ":") - err := errs[0] - if err.Field != s[0] || !strings.Contains(err.Error(), s[1]) { - t.Errorf("unexpected error: %q, expected: %q", err, k) + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + ingress := baseIngress.DeepCopy() + testCase.tweakIngress(ingress) + gv := testCase.groupVersion + if gv == nil { + gv = &networkingv1.SchemeGroupVersion } - } + errs := validateIngress(ingress, IngressValidationOptions{requireRegexPath: true}, *gv) + if len(testCase.expectErrsOnFields) != len(errs) { + t.Fatalf("Expected %d errors, got %d errors: %v", len(testCase.expectErrsOnFields), len(errs), errs) + } + for i, err := range errs { + if err.Field != testCase.expectErrsOnFields[i] { + t.Errorf("Expected error on field: %s, got: %s", testCase.expectErrsOnFields[i], err.Error()) + } + } + }) + } +} + +func TestValidateIngressRuleValue(t *testing.T) { + fldPath := field.NewPath("testing.http.paths[0].path") + testCases := map[string]struct { + pathType networking.PathType + path string + requireRegexPath bool + expectedErrs field.ErrorList + }{ + "implementation specific: no leading slash": { + pathType: networking.PathTypeImplementationSpecific, + path: "foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "foo", "must be an absolute path")}, + }, + "implementation specific: leading slash": { + pathType: networking.PathTypeImplementationSpecific, + path: "/foo", + expectedErrs: field.ErrorList{}, + }, + "implementation specific: many slashes": { + pathType: networking.PathTypeImplementationSpecific, + path: "/foo/bar/foo", + expectedErrs: field.ErrorList{}, + }, + "implementation specific: repeating slashes": { + pathType: networking.PathTypeImplementationSpecific, + path: "/foo//bar/foo", + expectedErrs: field.ErrorList{}, + }, + "prefix: no leading slash": { + pathType: networking.PathTypePrefix, + path: "foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "foo", "must be an absolute path")}, + }, + "prefix: leading slash": { + pathType: networking.PathTypePrefix, + path: "/foo", + expectedErrs: field.ErrorList{}, + }, + "prefix: many slashes": { + pathType: networking.PathTypePrefix, + path: "/foo/bar/foo", + expectedErrs: field.ErrorList{}, + }, + "prefix: repeating slashes": { + pathType: networking.PathTypePrefix, + path: "/foo//bar/foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "/foo//bar/foo", "must not contain '//'")}, + }, + "exact: no leading slash": { + pathType: networking.PathTypeExact, + path: "foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "foo", "must be an absolute path")}, + }, + "exact: leading slash": { + pathType: networking.PathTypeExact, + path: "/foo", + expectedErrs: field.ErrorList{}, + }, + "exact: many slashes": { + pathType: networking.PathTypeExact, + path: "/foo/bar/foo", + expectedErrs: field.ErrorList{}, + }, + "exact: repeating slashes": { + pathType: networking.PathTypeExact, + path: "/foo//bar/foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "/foo//bar/foo", "must not contain '//'")}, + }, + "prefix: with /./": { + pathType: networking.PathTypePrefix, + path: "/foo/./foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "/foo/./foo", "must not contain '/./'")}, + }, + "exact: with /../": { + pathType: networking.PathTypeExact, + path: "/foo/../foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "/foo/../foo", "must not contain '/../'")}, + }, + "prefix: with %2f": { + pathType: networking.PathTypePrefix, + path: "/foo/%2f/foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "/foo/%2f/foo", "must not contain '%2f'")}, + }, + "exact: with %2F": { + pathType: networking.PathTypeExact, + path: "/foo/%2F/foo", + expectedErrs: field.ErrorList{field.Invalid(fldPath, "/foo/%2F/foo", "must not contain '%2F'")}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + irv := &networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: testCase.path, + PathType: &testCase.pathType, + Backend: networking.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), + }, + }, + }, + }, + } + + errs := validateIngressRuleValue(irv, field.NewPath("testing"), IngressValidationOptions{requireRegexPath: true}) + + if len(errs) != len(testCase.expectedErrs) { + t.Fatalf("Expected %d errors, got %d (%+v)", len(testCase.expectedErrs), len(errs), errs) + } + + for i, err := range errs { + if err.Error() != testCase.expectedErrs[i].Error() { + t.Fatalf("Expected error: %v, got %v", testCase.expectedErrs[i], err) + } + } + }) } } func TestValidateIngressCreate(t *testing.T) { + implementationPathType := networking.PathTypeImplementationSpecific + defaultBackend := networking.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), + } baseIngress := networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "test123", @@ -1004,10 +1166,8 @@ func TestValidateIngressCreate(t *testing.T) { ResourceVersion: "1234", }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), - }, + Backend: &defaultBackend, + Rules: []networking.IngressRule{}, }, } @@ -1034,6 +1194,40 @@ func TestValidateIngressCreate(t *testing.T) { }, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("annotations").Child(annotationIngressClass), "foo", "can not be set when the class field is also set")}, }, + "valid regex path": { + tweakIngress: func(ingress *networking.Ingress) { + ingress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/([a-z0-9]*)", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + }, + expectedErrs: field.ErrorList{}, + }, + "invalid regex path": { + tweakIngress: func(ingress *networking.Ingress) { + ingress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/([a-z0-9]*)[", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + }, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec.rules[0].http.paths[0].path"), "/([a-z0-9]*)[", "must be a valid regex")}, + }, } for name, testCase := range testCases { @@ -1041,7 +1235,7 @@ func TestValidateIngressCreate(t *testing.T) { newIngress := baseIngress.DeepCopy() testCase.tweakIngress(newIngress) - errs := ValidateIngressCreate(newIngress) + errs := ValidateIngressCreate(newIngress, networkingv1beta1.SchemeGroupVersion) if len(errs) != len(testCase.expectedErrs) { t.Fatalf("Expected %d errors, got %d (%+v)", len(testCase.expectedErrs), len(errs), errs) } @@ -1056,6 +1250,11 @@ func TestValidateIngressCreate(t *testing.T) { } func TestValidateIngressUpdate(t *testing.T) { + implementationPathType := networking.PathTypeImplementationSpecific + defaultBackend := networking.IngressBackend{ + ServiceName: "default-backend", + ServicePort: intstr.FromInt(80), + } baseIngress := networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "test123", @@ -1063,10 +1262,7 @@ func TestValidateIngressUpdate(t *testing.T) { ResourceVersion: "1234", }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), - }, + Backend: &defaultBackend, }, } @@ -1093,6 +1289,122 @@ func TestValidateIngressUpdate(t *testing.T) { }, expectedErrs: field.ErrorList{}, }, + "valid regex path -> valid regex path": { + tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { + oldIngress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/([a-z0-9]*)", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + newIngress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/([a-z0-9%]*)", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + }, + expectedErrs: field.ErrorList{}, + }, + "valid regex path -> invalid regex path": { + tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { + oldIngress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/([a-z0-9]*)", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + newIngress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/bar[", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + }, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec.rules[0].http.paths[0].path"), "/bar[", "must be a valid regex")}, + }, + "invalid regex path -> valid regex path": { + tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { + oldIngress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/bar[", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + newIngress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/([a-z0-9]*)", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + }, + expectedErrs: field.ErrorList{}, + }, + "invalid regex path -> invalid regex path": { + tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { + oldIngress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/foo[", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + newIngress.Spec.Rules = []networking.IngressRule{{ + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{{ + Path: "/bar[", + PathType: &implementationPathType, + Backend: defaultBackend, + }}, + }, + }, + }} + }, + expectedErrs: field.ErrorList{}, + }, } for name, testCase := range testCases { @@ -1101,7 +1413,7 @@ func TestValidateIngressUpdate(t *testing.T) { oldIngress := baseIngress.DeepCopy() testCase.tweakIngresses(newIngress, oldIngress) - errs := ValidateIngressUpdate(newIngress, oldIngress) + errs := ValidateIngressUpdate(newIngress, oldIngress, networkingv1beta1.SchemeGroupVersion) if len(errs) != len(testCase.expectedErrs) { t.Fatalf("Expected %d errors, got %d (%+v)", len(testCase.expectedErrs), len(errs), errs) @@ -1360,7 +1672,7 @@ func TestValidateIngressTLS(t *testing.T) { errorCases[badWildcardTLSErr] = badWildcardTLS for k, v := range errorCases { - errs := ValidateIngress(&v) + errs := validateIngress(&v, IngressValidationOptions{requireRegexPath: true}, networkingv1beta1.SchemeGroupVersion) if len(errs) == 0 { t.Errorf("expected failure for %q", k) } else { diff --git a/pkg/apis/networking/zz_generated.deepcopy.go b/pkg/apis/networking/zz_generated.deepcopy.go index 46983ce53e8..9e017c7bf03 100644 --- a/pkg/apis/networking/zz_generated.deepcopy.go +++ b/pkg/apis/networking/zz_generated.deepcopy.go @@ -30,6 +30,11 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPIngressPath) DeepCopyInto(out *HTTPIngressPath) { *out = *in + if in.PathType != nil { + in, out := &in.PathType, &out.PathType + *out = new(PathType) + **out = **in + } out.Backend = in.Backend return } @@ -50,7 +55,9 @@ func (in *HTTPIngressRuleValue) DeepCopyInto(out *HTTPIngressRuleValue) { if in.Paths != nil { in, out := &in.Paths, &out.Paths *out = make([]HTTPIngressPath, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } diff --git a/pkg/registry/networking/ingress/BUILD b/pkg/registry/networking/ingress/BUILD index 21dca0ec848..3a0e7c67c9e 100644 --- a/pkg/registry/networking/ingress/BUILD +++ b/pkg/registry/networking/ingress/BUILD @@ -19,7 +19,9 @@ go_library( "//pkg/apis/networking/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library", ], ) diff --git a/pkg/registry/networking/ingress/storage/storage_test.go b/pkg/registry/networking/ingress/storage/storage_test.go index 8cd243da1f6..612cc81b9e0 100644 --- a/pkg/registry/networking/ingress/storage/storage_test.go +++ b/pkg/registry/networking/ingress/storage/storage_test.go @@ -57,6 +57,7 @@ var ( defaultBackendPort = intstr.FromInt(80) defaultLoadBalancer = "127.0.0.1" defaultPath = "/foo" + defaultPathType = networking.PathTypeImplementationSpecific defaultPathMap = map[string]string{defaultPath: defaultBackendName} defaultTLS = []networking.IngressTLS{ {Hosts: []string{"foo.bar.com", "*.bar.com"}, SecretName: "fooSecret"}, @@ -69,7 +70,8 @@ func toHTTPIngressPaths(pathMap map[string]string) []networking.HTTPIngressPath httpPaths := []networking.HTTPIngressPath{} for path, backend := range pathMap { httpPaths = append(httpPaths, networking.HTTPIngressPath{ - Path: path, + Path: path, + PathType: &defaultPathType, Backend: networking.IngressBackend{ ServiceName: backend, ServicePort: defaultBackendPort, @@ -130,16 +132,16 @@ func TestCreate(t *testing.T) { defer storage.Store.DestroyFunc() test := genericregistrytest.New(t, storage.Store) ingress := validIngress() - noDefaultBackendAndRules := validIngress() - noDefaultBackendAndRules.Spec.Backend = &networking.IngressBackend{} - noDefaultBackendAndRules.Spec.Rules = []networking.IngressRule{} + noBackendAndRules := validIngress() + noBackendAndRules.Spec.Backend = &networking.IngressBackend{} + noBackendAndRules.Spec.Rules = []networking.IngressRule{} badPath := validIngress() badPath.Spec.Rules = toIngressRules(map[string]IngressRuleValues{ "foo.bar.com": {"/invalid[": "svc"}}) test.TestCreate( // valid ingress, - noDefaultBackendAndRules, + noBackendAndRules, badPath, ) } diff --git a/pkg/registry/networking/ingress/strategy.go b/pkg/registry/networking/ingress/strategy.go index 280dc06add2..5fac2499815 100644 --- a/pkg/registry/networking/ingress/strategy.go +++ b/pkg/registry/networking/ingress/strategy.go @@ -18,10 +18,11 @@ package ingress import ( "context" - apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/networking" @@ -67,11 +68,14 @@ func (ingressStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Ob } -// Validate validates a new Ingress. +// Validate validates ingresses on create. func (ingressStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { + var requestGV schema.GroupVersion + if requestInfo, ok := request.RequestInfoFrom(ctx); ok { + requestGV = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} + } ingress := obj.(*networking.Ingress) - err := validation.ValidateIngress(ingress) - return err + return validation.ValidateIngressCreate(ingress, requestGV) } // Canonicalize normalizes the object after validation. @@ -83,11 +87,13 @@ func (ingressStrategy) AllowCreateOnUpdate() bool { return false } -// ValidateUpdate is the default update validation for an end user. +// ValidateUpdate validates ingresses on update. func (ingressStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - validationErrorList := validation.ValidateIngress(obj.(*networking.Ingress)) - updateErrorList := validation.ValidateIngressUpdate(obj.(*networking.Ingress), old.(*networking.Ingress)) - return append(validationErrorList, updateErrorList...) + var requestGV schema.GroupVersion + if requestInfo, ok := request.RequestInfoFrom(ctx); ok { + requestGV = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} + } + return validation.ValidateIngressUpdate(obj.(*networking.Ingress), old.(*networking.Ingress), requestGV) } // AllowUnconditionalUpdate is the default update policy for Ingress objects. diff --git a/pkg/registry/networking/ingress/strategy_test.go b/pkg/registry/networking/ingress/strategy_test.go index ed8ff18de85..e81930cbf98 100644 --- a/pkg/registry/networking/ingress/strategy_test.go +++ b/pkg/registry/networking/ingress/strategy_test.go @@ -31,6 +31,7 @@ func newIngress() networking.Ingress { ServiceName: "default-backend", ServicePort: intstr.FromInt(80), } + implementationPathType := networking.PathTypeImplementationSpecific return networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", @@ -48,8 +49,9 @@ func newIngress() networking.Ingress { HTTP: &networking.HTTPIngressRuleValue{ Paths: []networking.HTTPIngressPath{ { - Path: "/foo", - Backend: defaultBackend, + Path: "/foo", + PathType: &implementationPathType, + Backend: defaultBackend, }, }, }, @@ -69,6 +71,11 @@ func newIngress() networking.Ingress { func TestIngressStrategy(t *testing.T) { ctx := genericapirequest.NewDefaultContext() + apiRequest := genericapirequest.RequestInfo{APIGroup: "networking.k8s.io", + APIVersion: "v1beta1", + Resource: "ingresses", + } + ctx = genericapirequest.WithRequestInfo(ctx, &apiRequest) if !Strategy.NamespaceScoped() { t.Errorf("Ingress must be namespace scoped") } diff --git a/staging/src/k8s.io/api/extensions/v1beta1/generated.pb.go b/staging/src/k8s.io/api/extensions/v1beta1/generated.pb.go index edd0b622d39..c781d29bf29 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/generated.pb.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/generated.pb.go @@ -1683,238 +1683,239 @@ func init() { } var fileDescriptor_cdc93917efc28165 = []byte{ - // 3684 bytes of a gzipped FileDescriptorProto + // 3705 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4f, 0x6c, 0x1b, 0x47, 0x77, 0xf7, 0x92, 0x94, 0x48, 0x3d, 0xfd, 0x1f, 0xc9, 0x12, 0x3f, 0xfb, 0xb3, 0xe8, 0x6f, 0x03, 0xb8, 0x4e, 0x6a, 0x93, 0xb1, 0x63, 0xfb, 0x73, 0x6d, 0x34, 0x89, 0x28, 0x59, 0xb6, 0x52, 0xfd, 0x61, 0x86, 0x92, 0x1b, 0x04, 0x4d, 0x9a, 0x15, 0x39, 0xa2, 0xd6, 0x5a, 0xee, 0x6e, 0x76, 0x96, - 0x8a, 0x08, 0xf4, 0xd0, 0x43, 0x51, 0xa0, 0x40, 0x8b, 0xf6, 0x92, 0xb6, 0xc7, 0x06, 0x05, 0x7a, - 0x6a, 0xd1, 0xde, 0xda, 0x43, 0x10, 0xb4, 0x40, 0x0a, 0x18, 0x45, 0x5a, 0xe4, 0xd6, 0x9c, 0x84, + 0x8a, 0x08, 0xf4, 0xd0, 0x43, 0x51, 0xa0, 0x40, 0x81, 0xf6, 0x92, 0xb6, 0xc7, 0x06, 0x05, 0x7a, + 0x6a, 0xd1, 0xde, 0xda, 0x43, 0x10, 0xb4, 0x68, 0x0a, 0x18, 0x45, 0x5a, 0xe4, 0xd6, 0x9c, 0x84, 0x46, 0x39, 0x15, 0x3d, 0xf5, 0x56, 0xf8, 0x54, 0xcc, 0xec, 0xec, 0xff, 0x5d, 0x71, 0xa5, 0xd8, - 0x42, 0x03, 0xf4, 0x26, 0xce, 0x7b, 0xef, 0xf7, 0xde, 0xcc, 0xbc, 0x79, 0xef, 0xcd, 0xec, 0x13, - 0xac, 0xec, 0xdf, 0xa7, 0x55, 0xd5, 0xa8, 0xed, 0xf7, 0x76, 0x88, 0xa5, 0x13, 0x9b, 0xd0, 0xda, - 0x01, 0xd1, 0xdb, 0x86, 0x55, 0x13, 0x04, 0xc5, 0x54, 0x6b, 0xe4, 0xd0, 0x26, 0x3a, 0x55, 0x0d, - 0x9d, 0xd6, 0x0e, 0x6e, 0xed, 0x10, 0x5b, 0xb9, 0x55, 0xeb, 0x10, 0x9d, 0x58, 0x8a, 0x4d, 0xda, - 0x55, 0xd3, 0x32, 0x6c, 0x03, 0x5d, 0x71, 0xd8, 0xab, 0x8a, 0xa9, 0x56, 0x7d, 0xf6, 0xaa, 0x60, - 0xbf, 0x74, 0xb3, 0xa3, 0xda, 0x7b, 0xbd, 0x9d, 0x6a, 0xcb, 0xe8, 0xd6, 0x3a, 0x46, 0xc7, 0xa8, - 0x71, 0xa9, 0x9d, 0xde, 0x2e, 0xff, 0xc5, 0x7f, 0xf0, 0xbf, 0x1c, 0xb4, 0x4b, 0x72, 0x40, 0x79, - 0xcb, 0xb0, 0x48, 0xed, 0x20, 0xa6, 0xf1, 0xd2, 0x1d, 0x9f, 0xa7, 0xab, 0xb4, 0xf6, 0x54, 0x9d, - 0x58, 0xfd, 0x9a, 0xb9, 0xdf, 0x61, 0x03, 0xb4, 0xd6, 0x25, 0xb6, 0x92, 0x24, 0x55, 0x4b, 0x93, - 0xb2, 0x7a, 0xba, 0xad, 0x76, 0x49, 0x4c, 0xe0, 0xde, 0x20, 0x01, 0xda, 0xda, 0x23, 0x5d, 0x25, - 0x26, 0xf7, 0x56, 0x9a, 0x5c, 0xcf, 0x56, 0xb5, 0x9a, 0xaa, 0xdb, 0xd4, 0xb6, 0xa2, 0x42, 0xf2, - 0x1d, 0x98, 0x5a, 0xd4, 0x34, 0xe3, 0x33, 0xd2, 0x5e, 0x6a, 0xae, 0x2e, 0x5b, 0xea, 0x01, 0xb1, - 0xd0, 0x55, 0x28, 0xe8, 0x4a, 0x97, 0x94, 0xa5, 0xab, 0xd2, 0xf5, 0x91, 0xfa, 0xd8, 0xf3, 0xa3, - 0xca, 0x85, 0xe3, 0xa3, 0x4a, 0x61, 0x43, 0xe9, 0x12, 0xcc, 0x29, 0xf2, 0x43, 0x98, 0x16, 0x52, - 0x2b, 0x1a, 0x39, 0x7c, 0x6a, 0x68, 0xbd, 0x2e, 0x41, 0xd7, 0x60, 0xb8, 0xcd, 0x01, 0x84, 0xe0, - 0x84, 0x10, 0x1c, 0x76, 0x60, 0xb1, 0xa0, 0xca, 0x14, 0x26, 0x85, 0xf0, 0x13, 0x83, 0xda, 0x0d, - 0xc5, 0xde, 0x43, 0xb7, 0x01, 0x4c, 0xc5, 0xde, 0x6b, 0x58, 0x64, 0x57, 0x3d, 0x14, 0xe2, 0x48, - 0x88, 0x43, 0xc3, 0xa3, 0xe0, 0x00, 0x17, 0xba, 0x01, 0x25, 0x8b, 0x28, 0xed, 0x4d, 0x5d, 0xeb, - 0x97, 0x73, 0x57, 0xa5, 0xeb, 0xa5, 0xfa, 0x94, 0x90, 0x28, 0x61, 0x31, 0x8e, 0x3d, 0x0e, 0xf9, - 0xf3, 0x1c, 0x8c, 0x2c, 0x2b, 0xa4, 0x6b, 0xe8, 0x4d, 0x62, 0xa3, 0x4f, 0xa0, 0xc4, 0xb6, 0xab, - 0xad, 0xd8, 0x0a, 0xd7, 0x36, 0x7a, 0xfb, 0xcd, 0xaa, 0xef, 0x4e, 0xde, 0xea, 0x55, 0xcd, 0xfd, - 0x0e, 0x1b, 0xa0, 0x55, 0xc6, 0x5d, 0x3d, 0xb8, 0x55, 0xdd, 0xdc, 0x79, 0x46, 0x5a, 0xf6, 0x3a, - 0xb1, 0x15, 0xdf, 0x3e, 0x7f, 0x0c, 0x7b, 0xa8, 0x68, 0x03, 0x0a, 0xd4, 0x24, 0x2d, 0x6e, 0xd9, - 0xe8, 0xed, 0x1b, 0xd5, 0x13, 0x9d, 0xb5, 0xea, 0x59, 0xd6, 0x34, 0x49, 0xcb, 0x5f, 0x71, 0xf6, - 0x0b, 0x73, 0x1c, 0xf4, 0x14, 0x86, 0xa9, 0xad, 0xd8, 0x3d, 0x5a, 0xce, 0x73, 0xc4, 0x6a, 0x66, - 0x44, 0x2e, 0xe5, 0x6f, 0x86, 0xf3, 0x1b, 0x0b, 0x34, 0xf9, 0x3f, 0x73, 0x80, 0x3c, 0xde, 0x25, - 0x43, 0x6f, 0xab, 0xb6, 0x6a, 0xe8, 0xe8, 0x01, 0x14, 0xec, 0xbe, 0xe9, 0xba, 0xc0, 0x35, 0xd7, - 0xa0, 0xad, 0xbe, 0x49, 0x5e, 0x1c, 0x55, 0xe6, 0xe2, 0x12, 0x8c, 0x82, 0xb9, 0x0c, 0x5a, 0xf3, - 0x4c, 0xcd, 0x71, 0xe9, 0x3b, 0x61, 0xd5, 0x2f, 0x8e, 0x2a, 0x09, 0x87, 0xad, 0xea, 0x21, 0x85, - 0x0d, 0x44, 0x07, 0x80, 0x34, 0x85, 0xda, 0x5b, 0x96, 0xa2, 0x53, 0x47, 0x93, 0xda, 0x25, 0x62, - 0x11, 0xde, 0xc8, 0xb6, 0x69, 0x4c, 0xa2, 0x7e, 0x49, 0x58, 0x81, 0xd6, 0x62, 0x68, 0x38, 0x41, - 0x03, 0xf3, 0x66, 0x8b, 0x28, 0xd4, 0xd0, 0xcb, 0x85, 0xb0, 0x37, 0x63, 0x3e, 0x8a, 0x05, 0x15, - 0xbd, 0x0e, 0xc5, 0x2e, 0xa1, 0x54, 0xe9, 0x90, 0xf2, 0x10, 0x67, 0x9c, 0x14, 0x8c, 0xc5, 0x75, - 0x67, 0x18, 0xbb, 0x74, 0xf9, 0x4b, 0x09, 0xc6, 0xbd, 0x95, 0x5b, 0x53, 0xa9, 0x8d, 0x7e, 0x2b, - 0xe6, 0x87, 0xd5, 0x6c, 0x53, 0x62, 0xd2, 0xdc, 0x0b, 0x3d, 0x9f, 0x77, 0x47, 0x02, 0x3e, 0xb8, - 0x0e, 0x43, 0xaa, 0x4d, 0xba, 0x6c, 0x1f, 0xf2, 0xd7, 0x47, 0x6f, 0x5f, 0xcf, 0xea, 0x32, 0xf5, - 0x71, 0x01, 0x3a, 0xb4, 0xca, 0xc4, 0xb1, 0x83, 0x22, 0xff, 0x69, 0x21, 0x60, 0x3e, 0x73, 0x4d, - 0xf4, 0x11, 0x94, 0x28, 0xd1, 0x48, 0xcb, 0x36, 0x2c, 0x61, 0xfe, 0x5b, 0x19, 0xcd, 0x57, 0x76, - 0x88, 0xd6, 0x14, 0xa2, 0xf5, 0x31, 0x66, 0xbf, 0xfb, 0x0b, 0x7b, 0x90, 0xe8, 0x7d, 0x28, 0xd9, - 0xa4, 0x6b, 0x6a, 0x8a, 0x4d, 0xc4, 0x39, 0x7a, 0x2d, 0x38, 0x05, 0xe6, 0x39, 0x0c, 0xac, 0x61, - 0xb4, 0xb7, 0x04, 0x1b, 0x3f, 0x3e, 0xde, 0x92, 0xb8, 0xa3, 0xd8, 0x83, 0x41, 0x07, 0x30, 0xd1, - 0x33, 0xdb, 0x8c, 0xd3, 0x66, 0x51, 0xb0, 0xd3, 0x17, 0x9e, 0x74, 0x2f, 0xeb, 0xda, 0x6c, 0x87, - 0xa4, 0xeb, 0x73, 0x42, 0xd7, 0x44, 0x78, 0x1c, 0x47, 0xb4, 0xa0, 0x45, 0x98, 0xec, 0xaa, 0x3a, - 0x8b, 0x4b, 0xfd, 0x26, 0x69, 0x19, 0x7a, 0x9b, 0x72, 0xb7, 0x1a, 0xaa, 0xcf, 0x0b, 0x80, 0xc9, - 0xf5, 0x30, 0x19, 0x47, 0xf9, 0xd1, 0x7b, 0x80, 0xdc, 0x69, 0x3c, 0x76, 0x82, 0xb8, 0x6a, 0xe8, - 0xdc, 0xe7, 0xf2, 0xbe, 0x73, 0x6f, 0xc5, 0x38, 0x70, 0x82, 0x14, 0x5a, 0x83, 0x59, 0x8b, 0x1c, - 0xa8, 0x6c, 0x8e, 0x4f, 0x54, 0x6a, 0x1b, 0x56, 0x7f, 0x4d, 0xed, 0xaa, 0x76, 0x79, 0x98, 0xdb, - 0x54, 0x3e, 0x3e, 0xaa, 0xcc, 0xe2, 0x04, 0x3a, 0x4e, 0x94, 0x92, 0xff, 0x6c, 0x18, 0x26, 0x23, - 0xf1, 0x06, 0x3d, 0x85, 0xb9, 0x56, 0xcf, 0xb2, 0x88, 0x6e, 0x6f, 0xf4, 0xba, 0x3b, 0xc4, 0x6a, - 0xb6, 0xf6, 0x48, 0xbb, 0xa7, 0x91, 0x36, 0x77, 0x94, 0xa1, 0xfa, 0x82, 0xb0, 0x78, 0x6e, 0x29, - 0x91, 0x0b, 0xa7, 0x48, 0xb3, 0x55, 0xd0, 0xf9, 0xd0, 0xba, 0x4a, 0xa9, 0x87, 0x99, 0xe3, 0x98, - 0xde, 0x2a, 0x6c, 0xc4, 0x38, 0x70, 0x82, 0x14, 0xb3, 0xb1, 0x4d, 0xa8, 0x6a, 0x91, 0x76, 0xd4, - 0xc6, 0x7c, 0xd8, 0xc6, 0xe5, 0x44, 0x2e, 0x9c, 0x22, 0x8d, 0xee, 0xc2, 0xa8, 0xa3, 0x8d, 0xef, - 0x9f, 0xd8, 0xe8, 0x19, 0x01, 0x36, 0xba, 0xe1, 0x93, 0x70, 0x90, 0x8f, 0x4d, 0xcd, 0xd8, 0xa1, - 0xc4, 0x3a, 0x20, 0xed, 0xf4, 0x0d, 0xde, 0x8c, 0x71, 0xe0, 0x04, 0x29, 0x36, 0x35, 0xc7, 0x03, - 0x63, 0x53, 0x1b, 0x0e, 0x4f, 0x6d, 0x3b, 0x91, 0x0b, 0xa7, 0x48, 0x33, 0x3f, 0x76, 0x4c, 0x5e, - 0x3c, 0x50, 0x54, 0x4d, 0xd9, 0xd1, 0x48, 0xb9, 0x18, 0xf6, 0xe3, 0x8d, 0x30, 0x19, 0x47, 0xf9, - 0xd1, 0x63, 0x98, 0x76, 0x86, 0xb6, 0x75, 0xc5, 0x03, 0x29, 0x71, 0x90, 0x9f, 0x09, 0x90, 0xe9, - 0x8d, 0x28, 0x03, 0x8e, 0xcb, 0xa0, 0x07, 0x30, 0xd1, 0x32, 0x34, 0x8d, 0xfb, 0xe3, 0x92, 0xd1, - 0xd3, 0xed, 0xf2, 0x08, 0x47, 0x41, 0xec, 0x3c, 0x2e, 0x85, 0x28, 0x38, 0xc2, 0x89, 0x08, 0x40, - 0xcb, 0x4d, 0x38, 0xb4, 0x0c, 0x3c, 0x3e, 0xde, 0xca, 0x1a, 0x03, 0xbc, 0x54, 0xe5, 0xd7, 0x00, - 0xde, 0x10, 0xc5, 0x01, 0x60, 0xf9, 0x5f, 0x24, 0x98, 0x4f, 0x09, 0x1d, 0xe8, 0x9d, 0x50, 0x8a, - 0xfd, 0xd5, 0x48, 0x8a, 0xbd, 0x9c, 0x22, 0x16, 0xc8, 0xb3, 0x3a, 0x8c, 0x5b, 0x6c, 0x56, 0x7a, - 0xc7, 0x61, 0x11, 0x31, 0xf2, 0xee, 0x80, 0x69, 0xe0, 0xa0, 0x8c, 0x1f, 0xf3, 0xa7, 0x8f, 0x8f, - 0x2a, 0xe3, 0x21, 0x1a, 0x0e, 0xc3, 0xcb, 0x7f, 0x9e, 0x03, 0x58, 0x26, 0xa6, 0x66, 0xf4, 0xbb, - 0x44, 0x3f, 0x8f, 0x1a, 0x6a, 0x33, 0x54, 0x43, 0xdd, 0x1c, 0xb4, 0x3d, 0x9e, 0x69, 0xa9, 0x45, - 0xd4, 0x6f, 0x46, 0x8a, 0xa8, 0x5a, 0x76, 0xc8, 0x93, 0xab, 0xa8, 0x7f, 0xcf, 0xc3, 0x8c, 0xcf, - 0xec, 0x97, 0x51, 0x0f, 0x43, 0x7b, 0xfc, 0x2b, 0x91, 0x3d, 0x9e, 0x4f, 0x10, 0x79, 0x65, 0x75, - 0xd4, 0x33, 0x98, 0x60, 0x55, 0x8e, 0xb3, 0x97, 0xbc, 0x86, 0x1a, 0x3e, 0x75, 0x0d, 0xe5, 0x65, - 0xbb, 0xb5, 0x10, 0x12, 0x8e, 0x20, 0xa7, 0xd4, 0x6c, 0xc5, 0x9f, 0x62, 0xcd, 0xf6, 0x95, 0x04, - 0x13, 0xfe, 0x36, 0x9d, 0x43, 0xd1, 0xb6, 0x11, 0x2e, 0xda, 0x5e, 0xcf, 0xec, 0xa2, 0x29, 0x55, - 0xdb, 0xff, 0xb0, 0x02, 0xdf, 0x63, 0x62, 0x07, 0x7c, 0x47, 0x69, 0xed, 0x0f, 0xbe, 0xe3, 0xa1, - 0xcf, 0x25, 0x40, 0x22, 0x0b, 0x2c, 0xea, 0xba, 0x61, 0x2b, 0x4e, 0xac, 0x74, 0xcc, 0x5a, 0xcd, - 0x6c, 0x96, 0xab, 0xb1, 0xba, 0x1d, 0xc3, 0x7a, 0xa4, 0xdb, 0x56, 0xdf, 0xdf, 0xe4, 0x38, 0x03, - 0x4e, 0x30, 0x00, 0x29, 0x00, 0x96, 0xc0, 0xdc, 0x32, 0xc4, 0x41, 0xbe, 0x99, 0x21, 0xe6, 0x31, - 0x81, 0x25, 0x43, 0xdf, 0x55, 0x3b, 0x7e, 0xd8, 0xc1, 0x1e, 0x10, 0x0e, 0x80, 0x5e, 0x7a, 0x04, - 0xf3, 0x29, 0xd6, 0xa2, 0x29, 0xc8, 0xef, 0x93, 0xbe, 0xb3, 0x6c, 0x98, 0xfd, 0x89, 0x66, 0x61, - 0xe8, 0x40, 0xd1, 0x7a, 0x4e, 0xf8, 0x1d, 0xc1, 0xce, 0x8f, 0x07, 0xb9, 0xfb, 0x92, 0xfc, 0xe5, - 0x50, 0xd0, 0x77, 0x78, 0xc5, 0x7c, 0x9d, 0x5d, 0x5a, 0x4d, 0x4d, 0x6d, 0x29, 0x54, 0x14, 0x42, - 0x63, 0xce, 0x85, 0xd5, 0x19, 0xc3, 0x1e, 0x35, 0x54, 0x5b, 0xe7, 0x5e, 0x6d, 0x6d, 0x9d, 0x7f, - 0x39, 0xb5, 0xf5, 0x6f, 0x43, 0x89, 0xba, 0x55, 0x75, 0x81, 0x43, 0xde, 0x3a, 0x45, 0x7c, 0x15, - 0x05, 0xb5, 0xa7, 0xc0, 0x2b, 0xa5, 0x3d, 0xd0, 0xa4, 0x22, 0x7a, 0xe8, 0x94, 0x45, 0xf4, 0x4b, - 0x2d, 0x7c, 0x59, 0xbc, 0x31, 0x95, 0x1e, 0x25, 0x6d, 0x1e, 0xdb, 0x4a, 0x7e, 0xbc, 0x69, 0xf0, - 0x51, 0x2c, 0xa8, 0xe8, 0xa3, 0x90, 0xcb, 0x96, 0xce, 0xe2, 0xb2, 0x13, 0xe9, 0xee, 0x8a, 0xb6, - 0x61, 0xde, 0xb4, 0x8c, 0x8e, 0x45, 0x28, 0x5d, 0x26, 0x4a, 0x5b, 0x53, 0x75, 0xe2, 0xae, 0x8f, - 0x53, 0x11, 0x5d, 0x3e, 0x3e, 0xaa, 0xcc, 0x37, 0x92, 0x59, 0x70, 0x9a, 0xac, 0xfc, 0xbc, 0x00, - 0x53, 0xd1, 0x0c, 0x98, 0x52, 0xa4, 0x4a, 0x67, 0x2a, 0x52, 0x6f, 0x04, 0x0e, 0x83, 0x53, 0xc1, - 0x07, 0x5e, 0x70, 0x62, 0x07, 0x62, 0x11, 0x26, 0x45, 0x34, 0x70, 0x89, 0xa2, 0x4c, 0xf7, 0x76, - 0x7f, 0x3b, 0x4c, 0xc6, 0x51, 0x7e, 0xf4, 0x10, 0xc6, 0x2d, 0x5e, 0x77, 0xbb, 0x00, 0x4e, 0xed, - 0x7a, 0x51, 0x00, 0x8c, 0xe3, 0x20, 0x11, 0x87, 0x79, 0x59, 0xdd, 0xea, 0x97, 0xa3, 0x2e, 0x40, - 0x21, 0x5c, 0xb7, 0x2e, 0x46, 0x19, 0x70, 0x5c, 0x06, 0xad, 0xc3, 0x4c, 0x4f, 0x8f, 0x43, 0x39, - 0xae, 0x7c, 0x59, 0x40, 0xcd, 0x6c, 0xc7, 0x59, 0x70, 0x92, 0x1c, 0xda, 0x0d, 0x95, 0xb2, 0xc3, - 0x3c, 0x3c, 0xdf, 0xce, 0x7c, 0xf0, 0x32, 0xd7, 0xb2, 0x09, 0xe5, 0x76, 0x29, 0x6b, 0xb9, 0x2d, - 0xff, 0x93, 0x14, 0x4c, 0x42, 0x5e, 0x09, 0x3c, 0xe8, 0x95, 0x29, 0x26, 0x11, 0xa8, 0x8e, 0x8c, - 0xe4, 0xea, 0xf7, 0xde, 0xa9, 0xaa, 0x5f, 0x3f, 0x79, 0x0e, 0x2e, 0x7f, 0xbf, 0x90, 0x60, 0x6e, - 0xa5, 0xf9, 0xd8, 0x32, 0x7a, 0xa6, 0x6b, 0xce, 0xa6, 0xe9, 0x2c, 0xcd, 0x2f, 0xa1, 0x60, 0xf5, - 0x34, 0x77, 0x1e, 0xaf, 0xb9, 0xf3, 0xc0, 0x3d, 0x8d, 0xcd, 0x63, 0x26, 0x22, 0xe5, 0x4c, 0x82, - 0x09, 0xa0, 0x0d, 0x18, 0xb6, 0x14, 0xbd, 0x43, 0xdc, 0xb4, 0x7a, 0x6d, 0x80, 0xf5, 0xab, 0xcb, - 0x98, 0xb1, 0x07, 0x0a, 0x1b, 0x2e, 0x8d, 0x05, 0x8a, 0xfc, 0x47, 0x12, 0x4c, 0x3e, 0xd9, 0xda, - 0x6a, 0xac, 0xea, 0xfc, 0x44, 0xf3, 0xb7, 0xd5, 0xab, 0x50, 0x30, 0x15, 0x7b, 0x2f, 0x9a, 0xe9, - 0x19, 0x0d, 0x73, 0x0a, 0xfa, 0x00, 0x8a, 0x2c, 0x92, 0x10, 0xbd, 0x9d, 0xb1, 0xd4, 0x16, 0xf0, - 0x75, 0x47, 0xc8, 0xaf, 0x9e, 0xc4, 0x00, 0x76, 0xe1, 0xe4, 0x7d, 0x98, 0x0d, 0x98, 0xc3, 0xd6, - 0xe3, 0x29, 0xcb, 0x8e, 0xa8, 0x09, 0x43, 0x4c, 0x33, 0xcb, 0x81, 0xf9, 0x0c, 0x8f, 0x99, 0x91, - 0x29, 0xf9, 0x95, 0x0e, 0xfb, 0x45, 0xb1, 0x83, 0x25, 0xaf, 0xc3, 0x38, 0x7f, 0x50, 0x36, 0x2c, - 0x9b, 0x2f, 0x0b, 0xba, 0x02, 0xf9, 0xae, 0xaa, 0x8b, 0x3c, 0x3b, 0x2a, 0x64, 0xf2, 0x2c, 0x47, - 0xb0, 0x71, 0x4e, 0x56, 0x0e, 0x45, 0xe4, 0xf1, 0xc9, 0xca, 0x21, 0x66, 0xe3, 0xf2, 0x63, 0x28, - 0x8a, 0xe5, 0x0e, 0x02, 0xe5, 0x4f, 0x06, 0xca, 0x27, 0x00, 0x6d, 0x42, 0x71, 0xb5, 0x51, 0xd7, - 0x0c, 0xa7, 0xea, 0x6a, 0xa9, 0x6d, 0x2b, 0xba, 0x17, 0x4b, 0xab, 0xcb, 0x18, 0x73, 0x0a, 0x92, - 0x61, 0x98, 0x1c, 0xb6, 0x88, 0x69, 0x73, 0x8f, 0x18, 0xa9, 0x03, 0xdb, 0xe5, 0x47, 0x7c, 0x04, - 0x0b, 0x8a, 0xfc, 0xc7, 0x39, 0x28, 0x8a, 0xe5, 0x38, 0x87, 0x5b, 0xd8, 0x5a, 0xe8, 0x16, 0xf6, - 0x46, 0x36, 0xd7, 0x48, 0xbd, 0x82, 0x6d, 0x45, 0xae, 0x60, 0x37, 0x32, 0xe2, 0x9d, 0x7c, 0xff, - 0xfa, 0x3b, 0x09, 0x26, 0xc2, 0x4e, 0x89, 0xee, 0xc2, 0x28, 0x4b, 0x38, 0x6a, 0x8b, 0x6c, 0xf8, - 0x75, 0xae, 0xf7, 0x08, 0xd3, 0xf4, 0x49, 0x38, 0xc8, 0x87, 0x3a, 0x9e, 0x18, 0xf3, 0x23, 0x31, - 0xe9, 0xf4, 0x25, 0xed, 0xd9, 0xaa, 0x56, 0x75, 0x3e, 0xad, 0x54, 0x57, 0x75, 0x7b, 0xd3, 0x6a, - 0xda, 0x96, 0xaa, 0x77, 0x62, 0x8a, 0xb8, 0x53, 0x06, 0x91, 0xe5, 0x7f, 0x90, 0x60, 0x54, 0x98, - 0x7c, 0x0e, 0xb7, 0x8a, 0xdf, 0x08, 0xdf, 0x2a, 0xae, 0x65, 0x3c, 0xe0, 0xc9, 0x57, 0x8a, 0xbf, - 0xf2, 0x4d, 0x67, 0x47, 0x9a, 0x79, 0xf5, 0x9e, 0x41, 0xed, 0xa8, 0x57, 0xb3, 0xc3, 0x88, 0x39, - 0x05, 0xf5, 0x60, 0x4a, 0x8d, 0xc4, 0x00, 0xb1, 0xb4, 0xb5, 0x6c, 0x96, 0x78, 0x62, 0xf5, 0xb2, - 0x80, 0x9f, 0x8a, 0x52, 0x70, 0x4c, 0x85, 0x4c, 0x20, 0xc6, 0x85, 0xde, 0x87, 0xc2, 0x9e, 0x6d, - 0x9b, 0x09, 0xef, 0xd5, 0x03, 0x22, 0x8f, 0x6f, 0x42, 0x89, 0xcf, 0x6e, 0x6b, 0xab, 0x81, 0x39, - 0x94, 0xfc, 0x8f, 0x39, 0x6f, 0x3d, 0x78, 0x91, 0xff, 0xae, 0x37, 0xdb, 0x25, 0x4d, 0xa1, 0x94, - 0xfb, 0x9f, 0x73, 0x21, 0x9d, 0x0d, 0x18, 0xee, 0xd1, 0x70, 0x8c, 0x1b, 0x6d, 0xf9, 0x11, 0x59, - 0x3a, 0x4b, 0x44, 0x1e, 0x4d, 0x8a, 0xc6, 0xe8, 0x09, 0xe4, 0x6d, 0x2d, 0xeb, 0xc5, 0x52, 0x20, - 0x6e, 0xad, 0x35, 0xfd, 0x90, 0xb6, 0xb5, 0xd6, 0xc4, 0x0c, 0x02, 0x6d, 0xc2, 0x10, 0xcb, 0x5f, - 0xec, 0x10, 0xe7, 0xb3, 0x07, 0x05, 0xb6, 0x82, 0xbe, 0x4b, 0xb1, 0x5f, 0x14, 0x3b, 0x38, 0xf2, - 0xa7, 0x30, 0x1e, 0x3a, 0xe9, 0xe8, 0x13, 0x18, 0xd3, 0x0c, 0xa5, 0x5d, 0x57, 0x34, 0x45, 0x6f, - 0x11, 0xf7, 0xf3, 0xc2, 0xb5, 0xa4, 0x3b, 0xca, 0x5a, 0x80, 0x4f, 0xc4, 0x89, 0x59, 0xa1, 0x64, - 0x2c, 0x48, 0xc3, 0x21, 0x44, 0x59, 0x01, 0xf0, 0xe7, 0x88, 0x2a, 0x30, 0xc4, 0x3c, 0xd5, 0xc9, - 0x48, 0x23, 0xf5, 0x11, 0x66, 0x21, 0x73, 0x60, 0x8a, 0x9d, 0x71, 0x74, 0x1b, 0x80, 0x92, 0x96, - 0x45, 0x6c, 0xbe, 0x9d, 0xb9, 0xf0, 0x27, 0xca, 0xa6, 0x47, 0xc1, 0x01, 0x2e, 0xf9, 0x9f, 0x25, - 0x18, 0xdf, 0x20, 0xf6, 0x67, 0x86, 0xb5, 0xdf, 0x30, 0x34, 0xb5, 0xd5, 0x3f, 0x87, 0x70, 0x8d, - 0x43, 0xe1, 0xfa, 0xcd, 0x01, 0x3b, 0x13, 0xb2, 0x2e, 0x2d, 0x68, 0xcb, 0x5f, 0x49, 0x30, 0x1f, - 0xe2, 0x7c, 0xe4, 0x1f, 0xfe, 0x6d, 0x18, 0x32, 0x0d, 0xcb, 0x76, 0x53, 0xf9, 0xa9, 0x14, 0xb2, - 0x40, 0x18, 0x48, 0xe6, 0x0c, 0x06, 0x3b, 0x68, 0x68, 0x0d, 0x72, 0xb6, 0x21, 0x5c, 0xf5, 0x74, - 0x98, 0x84, 0x58, 0x75, 0x10, 0x98, 0xb9, 0x2d, 0x03, 0xe7, 0x6c, 0x83, 0x6d, 0x44, 0x39, 0xc4, - 0x15, 0x0c, 0x5f, 0xaf, 0x68, 0x06, 0x18, 0x0a, 0xbb, 0x96, 0xd1, 0x3d, 0xf3, 0x1c, 0xbc, 0x8d, - 0x58, 0xb1, 0x8c, 0x2e, 0xe6, 0x58, 0xf2, 0xd7, 0x12, 0x4c, 0x87, 0x38, 0xcf, 0x21, 0x75, 0xbc, - 0x1f, 0x4e, 0x1d, 0x37, 0x4e, 0x33, 0x91, 0x94, 0x04, 0xf2, 0x75, 0x2e, 0x32, 0x0d, 0x36, 0x61, - 0xb4, 0x0b, 0xa3, 0xa6, 0xd1, 0x6e, 0xbe, 0x84, 0x0f, 0x8a, 0x93, 0x2c, 0xf3, 0x36, 0x7c, 0x2c, - 0x1c, 0x04, 0x46, 0x87, 0x30, 0xad, 0x2b, 0x5d, 0x42, 0x4d, 0xa5, 0x45, 0x9a, 0x2f, 0xe1, 0x89, - 0xe5, 0x22, 0xff, 0x62, 0x11, 0x45, 0xc4, 0x71, 0x25, 0x68, 0x1d, 0x8a, 0xaa, 0xc9, 0x2b, 0x41, - 0x51, 0xfd, 0x0c, 0xcc, 0xc3, 0x4e, 0xdd, 0xe8, 0xc4, 0x73, 0xf1, 0x03, 0xbb, 0x18, 0xf2, 0x5f, - 0x47, 0xbd, 0x81, 0xf9, 0x1f, 0x7a, 0x0c, 0x25, 0xde, 0xda, 0xd1, 0x32, 0x34, 0xf7, 0xdb, 0x02, - 0xdb, 0xd9, 0x86, 0x18, 0x7b, 0x71, 0x54, 0xb9, 0x9c, 0xf0, 0x6c, 0xec, 0x92, 0xb1, 0x27, 0x8c, - 0x36, 0xa0, 0x60, 0xfe, 0x98, 0x1a, 0x88, 0xa7, 0x49, 0x5e, 0xf8, 0x70, 0x1c, 0xf9, 0xf7, 0xf2, - 0x11, 0x73, 0x79, 0xb2, 0x7c, 0xf6, 0xd2, 0x76, 0xdd, 0xab, 0xb9, 0x52, 0x77, 0x7e, 0x07, 0x8a, - 0x22, 0xd5, 0x0a, 0x67, 0xfe, 0xe5, 0x69, 0x9c, 0x39, 0x98, 0xc5, 0xbc, 0x2b, 0x8f, 0x3b, 0xe8, - 0x02, 0xa3, 0x8f, 0x61, 0x98, 0x38, 0x2a, 0x9c, 0xdc, 0x78, 0xef, 0x34, 0x2a, 0xfc, 0xb8, 0xea, - 0x97, 0xba, 0x62, 0x4c, 0xa0, 0xa2, 0x77, 0xd8, 0x7a, 0x31, 0x5e, 0x76, 0x8d, 0xa4, 0xe5, 0x02, - 0x4f, 0x57, 0x57, 0x9c, 0x69, 0x7b, 0xc3, 0x2f, 0x8e, 0x2a, 0xe0, 0xff, 0xc4, 0x41, 0x09, 0xf9, - 0x5f, 0x25, 0x98, 0xe6, 0x2b, 0xd4, 0xea, 0x59, 0xaa, 0xdd, 0x3f, 0xb7, 0xc4, 0xf4, 0x34, 0x94, - 0x98, 0xee, 0x0c, 0x58, 0x96, 0x98, 0x85, 0xa9, 0xc9, 0xe9, 0x1b, 0x09, 0x2e, 0xc6, 0xb8, 0xcf, - 0x21, 0x2e, 0x6e, 0x87, 0xe3, 0xe2, 0x9b, 0xa7, 0x9d, 0x50, 0x4a, 0x6c, 0xfc, 0xef, 0xe9, 0x84, - 0xe9, 0xf0, 0x93, 0x72, 0x1b, 0xc0, 0xb4, 0xd4, 0x03, 0x55, 0x23, 0x1d, 0xf1, 0x19, 0xbd, 0x14, - 0x68, 0x92, 0xf2, 0x28, 0x38, 0xc0, 0x85, 0x28, 0xcc, 0xb5, 0xc9, 0xae, 0xd2, 0xd3, 0xec, 0xc5, - 0x76, 0x7b, 0x49, 0x31, 0x95, 0x1d, 0x55, 0x53, 0x6d, 0x55, 0x3c, 0x38, 0x8c, 0xd4, 0x1f, 0x3a, - 0x9f, 0xb7, 0x93, 0x38, 0x5e, 0x1c, 0x55, 0xae, 0x24, 0x7d, 0x5f, 0x72, 0x59, 0xfa, 0x38, 0x05, - 0x1a, 0xf5, 0xa1, 0x6c, 0x91, 0x4f, 0x7b, 0xaa, 0x45, 0xda, 0xcb, 0x96, 0x61, 0x86, 0xd4, 0xe6, - 0xb9, 0xda, 0x5f, 0x3f, 0x3e, 0xaa, 0x94, 0x71, 0x0a, 0xcf, 0x60, 0xc5, 0xa9, 0xf0, 0xe8, 0x19, - 0xcc, 0x28, 0xa2, 0x9d, 0x2d, 0xa8, 0xd5, 0x39, 0x25, 0xf7, 0x8f, 0x8f, 0x2a, 0x33, 0x8b, 0x71, - 0xf2, 0x60, 0x85, 0x49, 0xa0, 0xa8, 0x06, 0xc5, 0x03, 0xde, 0xf9, 0x46, 0xcb, 0x43, 0x1c, 0x9f, - 0x25, 0x82, 0xa2, 0xd3, 0x0c, 0xc7, 0x30, 0x87, 0x57, 0x9a, 0xfc, 0xf4, 0xb9, 0x5c, 0xec, 0x4a, - 0xca, 0x6a, 0x49, 0x71, 0xe2, 0xf9, 0x9b, 0x73, 0xc9, 0x8f, 0x5a, 0x4f, 0x7c, 0x12, 0x0e, 0xf2, - 0xa1, 0x8f, 0x60, 0x64, 0x4f, 0xbc, 0x6b, 0xd0, 0x72, 0x31, 0x53, 0x12, 0x0e, 0xbd, 0x83, 0xd4, - 0xa7, 0x85, 0x8a, 0x11, 0x77, 0x98, 0x62, 0x1f, 0x11, 0xbd, 0x0e, 0x45, 0xfe, 0x63, 0x75, 0x99, - 0x3f, 0xe8, 0x95, 0xfc, 0xd8, 0xf6, 0xc4, 0x19, 0xc6, 0x2e, 0xdd, 0x65, 0x5d, 0x6d, 0x2c, 0xf1, - 0x87, 0xe5, 0x08, 0xeb, 0x6a, 0x63, 0x09, 0xbb, 0x74, 0xf4, 0x09, 0x14, 0x29, 0x59, 0x53, 0xf5, - 0xde, 0x61, 0x19, 0x32, 0x7d, 0x96, 0x6e, 0x3e, 0xe2, 0xdc, 0x91, 0xa7, 0x35, 0x5f, 0x83, 0xa0, - 0x63, 0x17, 0x16, 0xed, 0xc1, 0x88, 0xd5, 0xd3, 0x17, 0xe9, 0x36, 0x25, 0x56, 0x79, 0x94, 0xeb, - 0x18, 0x14, 0xce, 0xb1, 0xcb, 0x1f, 0xd5, 0xe2, 0xad, 0x90, 0xc7, 0x81, 0x7d, 0x70, 0xb4, 0x07, - 0xc0, 0x7f, 0xf0, 0x57, 0xbc, 0xf2, 0x1c, 0x57, 0x75, 0x3f, 0x8b, 0xaa, 0xa4, 0xc7, 0x42, 0xf1, - 0x92, 0xef, 0x91, 0x71, 0x00, 0x1b, 0xfd, 0xa1, 0x04, 0x88, 0xf6, 0x4c, 0x53, 0x23, 0x5d, 0xa2, - 0xdb, 0x8a, 0xc6, 0x47, 0x69, 0x79, 0x8c, 0xab, 0x7c, 0x77, 0xd0, 0x0a, 0xc6, 0x04, 0xa3, 0xaa, - 0xbd, 0x07, 0xfa, 0x38, 0x2b, 0x4e, 0xd0, 0xcb, 0x36, 0x71, 0x57, 0xcc, 0x7a, 0x3c, 0xd3, 0x26, - 0x26, 0xbf, 0x8f, 0xfa, 0x9b, 0x28, 0xe8, 0xd8, 0x85, 0x45, 0x4f, 0x61, 0xce, 0x6d, 0xd1, 0xc4, - 0x86, 0x61, 0xaf, 0xa8, 0x1a, 0xa1, 0x7d, 0x6a, 0x93, 0x6e, 0x79, 0x82, 0x3b, 0x98, 0xd7, 0xa7, - 0x82, 0x13, 0xb9, 0x70, 0x8a, 0x34, 0xea, 0x42, 0xc5, 0x0d, 0x4e, 0xec, 0xe4, 0x7a, 0xd1, 0xf1, - 0x11, 0x6d, 0x29, 0x9a, 0xf3, 0xcd, 0x62, 0x92, 0x2b, 0x78, 0xed, 0xf8, 0xa8, 0x52, 0x59, 0x3e, - 0x99, 0x15, 0x0f, 0xc2, 0x42, 0x1f, 0x40, 0x59, 0x49, 0xd3, 0x33, 0xc5, 0xf5, 0xfc, 0x9c, 0x45, - 0xbc, 0x54, 0x05, 0xa9, 0xd2, 0xc8, 0x86, 0x29, 0x25, 0xdc, 0x2c, 0x4b, 0xcb, 0xd3, 0x99, 0x1e, - 0x4d, 0x23, 0x3d, 0xb6, 0xfe, 0xc3, 0x49, 0x84, 0x40, 0x71, 0x4c, 0x03, 0xfa, 0x1d, 0x40, 0x4a, - 0xb4, 0xbf, 0x97, 0x96, 0x51, 0xa6, 0x44, 0x17, 0x6b, 0x0c, 0xf6, 0xdd, 0x2e, 0x46, 0xa2, 0x38, - 0x41, 0x0f, 0x2b, 0xd0, 0x95, 0x48, 0x4f, 0x32, 0x2d, 0xcf, 0x73, 0xe5, 0xb5, 0x6c, 0xca, 0x3d, - 0xb9, 0xc0, 0xa7, 0x99, 0x28, 0x22, 0x8e, 0x2b, 0x41, 0x6b, 0x30, 0x2b, 0x06, 0xb7, 0x75, 0xaa, - 0xec, 0x92, 0x66, 0x9f, 0xb6, 0x6c, 0x8d, 0x96, 0x67, 0x78, 0x7c, 0xe7, 0x9f, 0x07, 0x17, 0x13, - 0xe8, 0x38, 0x51, 0x0a, 0xbd, 0x0b, 0x53, 0xbb, 0x86, 0xb5, 0xa3, 0xb6, 0xdb, 0x44, 0x77, 0x91, - 0x66, 0x39, 0x12, 0x7f, 0x07, 0x5a, 0x89, 0xd0, 0x70, 0x8c, 0x1b, 0x51, 0xb8, 0x28, 0x90, 0x1b, - 0x96, 0xd1, 0x5a, 0x37, 0x7a, 0xba, 0xed, 0x94, 0x7d, 0x17, 0xbd, 0x34, 0x7a, 0x71, 0x31, 0x89, - 0xe1, 0xc5, 0x51, 0xe5, 0x6a, 0x72, 0x95, 0xef, 0x33, 0xe1, 0x64, 0x6c, 0x64, 0xc2, 0x98, 0xe8, - 0x34, 0xe7, 0x0f, 0x52, 0xe5, 0x32, 0x3f, 0xfa, 0x0f, 0x06, 0x07, 0x3c, 0x4f, 0x24, 0x7a, 0xfe, - 0xa7, 0x8e, 0x8f, 0x2a, 0x63, 0x41, 0x06, 0x1c, 0xd2, 0xc0, 0x3b, 0x8b, 0xc4, 0xf7, 0xac, 0xf3, - 0xe9, 0xce, 0x3e, 0x5d, 0x67, 0x91, 0x6f, 0xda, 0x4b, 0xeb, 0x2c, 0x0a, 0x40, 0x9e, 0xfc, 0xb2, - 0xfd, 0x5f, 0x39, 0x98, 0xf1, 0x99, 0x33, 0x77, 0x16, 0x25, 0x88, 0xfc, 0x7f, 0x87, 0x76, 0xb6, - 0x6e, 0x1f, 0x7f, 0xe9, 0xfe, 0xef, 0x75, 0xfb, 0xf8, 0xb6, 0xa5, 0xdc, 0x1e, 0xfe, 0x36, 0x17, - 0x9c, 0xc0, 0x29, 0x5b, 0x4e, 0x5e, 0x42, 0x93, 0xf2, 0x4f, 0xae, 0x6b, 0x45, 0xfe, 0x26, 0x0f, - 0x53, 0xd1, 0xd3, 0x18, 0xea, 0x4c, 0x90, 0x06, 0x76, 0x26, 0x34, 0x60, 0x76, 0xb7, 0xa7, 0x69, - 0x7d, 0x3e, 0x87, 0x40, 0x7b, 0x82, 0xf3, 0x65, 0xf1, 0xe7, 0x42, 0x72, 0x76, 0x25, 0x81, 0x07, - 0x27, 0x4a, 0xc6, 0x1b, 0x15, 0x0a, 0x3f, 0xb6, 0x51, 0x61, 0xe8, 0x0c, 0x8d, 0x0a, 0xc9, 0xbd, - 0x1e, 0xf9, 0x33, 0xf5, 0x7a, 0x9c, 0xa5, 0x4b, 0x21, 0x21, 0x88, 0x0d, 0xec, 0xb8, 0x7d, 0x1b, - 0x26, 0xc2, 0x9d, 0x33, 0xce, 0x5e, 0x3a, 0xcd, 0x3b, 0xe2, 0x0b, 0x6e, 0x60, 0x2f, 0x9d, 0x71, - 0xec, 0x71, 0xc8, 0xbf, 0x2f, 0xc1, 0x5c, 0x72, 0x87, 0x2c, 0xd2, 0x60, 0xa2, 0xab, 0x1c, 0x06, - 0xbb, 0x96, 0xa5, 0x33, 0xbe, 0x8c, 0xf1, 0x96, 0x89, 0xf5, 0x10, 0x16, 0x8e, 0x60, 0xcb, 0x3f, - 0x48, 0x30, 0x9f, 0xd2, 0xac, 0x70, 0xbe, 0x96, 0xa0, 0x0f, 0xa1, 0xd4, 0x55, 0x0e, 0x9b, 0x3d, - 0xab, 0x43, 0xce, 0xfc, 0x16, 0xc8, 0x0f, 0xf4, 0xba, 0x40, 0xc1, 0x1e, 0x9e, 0xfc, 0x97, 0x12, - 0xfc, 0x2c, 0xf5, 0xaa, 0x84, 0xee, 0x85, 0xfa, 0x2a, 0xe4, 0x48, 0x5f, 0x05, 0x8a, 0x0b, 0xbe, - 0xa2, 0xb6, 0x8a, 0x2f, 0x24, 0x28, 0xa7, 0xdd, 0x1d, 0xd1, 0xdd, 0x90, 0x91, 0xbf, 0x88, 0x18, - 0x39, 0x1d, 0x93, 0x7b, 0x45, 0x36, 0xfe, 0x9b, 0x04, 0x97, 0x4f, 0xa8, 0xc1, 0xbc, 0x2b, 0x0a, - 0x69, 0x07, 0xb9, 0xf8, 0xb3, 0xb5, 0xf8, 0xe6, 0xe5, 0x5f, 0x51, 0x12, 0x78, 0x70, 0xaa, 0x34, - 0xda, 0x86, 0x79, 0x71, 0x3f, 0x8a, 0xd2, 0x44, 0x79, 0xc1, 0xdb, 0xcf, 0x96, 0x93, 0x59, 0x70, - 0x9a, 0xac, 0xfc, 0x37, 0x12, 0xcc, 0x25, 0x3f, 0x0a, 0xa0, 0xb7, 0x42, 0x4b, 0x5e, 0x89, 0x2c, - 0xf9, 0x64, 0x44, 0x4a, 0x2c, 0xf8, 0xc7, 0x30, 0x21, 0x9e, 0x0e, 0x04, 0x8c, 0x70, 0x66, 0x39, - 0x29, 0x83, 0x08, 0x08, 0xb7, 0x80, 0xe5, 0xc7, 0x24, 0x3c, 0x86, 0x23, 0x68, 0xf2, 0x1f, 0xe4, - 0x60, 0xa8, 0xd9, 0x52, 0x34, 0x72, 0x0e, 0xf5, 0xeb, 0x7b, 0xa1, 0xfa, 0x75, 0xd0, 0x3f, 0x76, - 0x71, 0xab, 0x52, 0x4b, 0x57, 0x1c, 0x29, 0x5d, 0xdf, 0xc8, 0x84, 0x76, 0x72, 0xd5, 0xfa, 0x6b, - 0x30, 0xe2, 0x29, 0x3d, 0x5d, 0x32, 0x95, 0xff, 0x22, 0x07, 0xa3, 0x01, 0x15, 0xa7, 0x4c, 0xc5, - 0xbb, 0xa1, 0xfa, 0x23, 0x9f, 0xe1, 0xa1, 0x26, 0xa0, 0xab, 0xea, 0x56, 0x1c, 0x4e, 0x63, 0xb2, - 0xdf, 0x8a, 0x1a, 0x2f, 0x44, 0xde, 0x86, 0x09, 0x5b, 0xb1, 0x3a, 0xc4, 0xf6, 0x3e, 0x5c, 0xe4, - 0xb9, 0x2f, 0x7a, 0x1d, 0xf2, 0x5b, 0x21, 0x2a, 0x8e, 0x70, 0x5f, 0x7a, 0x08, 0xe3, 0x21, 0x65, - 0xa7, 0xea, 0x2b, 0xfe, 0x7b, 0x09, 0x7e, 0x31, 0xf0, 0xb1, 0x07, 0xd5, 0x43, 0x87, 0xa4, 0x1a, - 0x39, 0x24, 0x0b, 0xe9, 0x00, 0xaf, 0xae, 0x3f, 0xad, 0x7e, 0xf3, 0xf9, 0xf7, 0x0b, 0x17, 0xbe, - 0xfd, 0x7e, 0xe1, 0xc2, 0x77, 0xdf, 0x2f, 0x5c, 0xf8, 0xdd, 0xe3, 0x05, 0xe9, 0xf9, 0xf1, 0x82, - 0xf4, 0xed, 0xf1, 0x82, 0xf4, 0xdd, 0xf1, 0x82, 0xf4, 0x1f, 0xc7, 0x0b, 0xd2, 0x9f, 0xfc, 0xb0, - 0x70, 0xe1, 0xc3, 0xa2, 0x80, 0xfb, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x27, 0x4b, 0x93, - 0x2b, 0x3e, 0x00, 0x00, + 0x42, 0x03, 0xf4, 0x64, 0x71, 0xde, 0x7b, 0xbf, 0xf7, 0x66, 0xe6, 0xcd, 0x7b, 0x6f, 0x66, 0x9f, + 0x61, 0x65, 0xff, 0x3e, 0xad, 0xaa, 0x46, 0x6d, 0xbf, 0xb7, 0x43, 0x2c, 0x9d, 0xd8, 0x84, 0xd6, + 0x0e, 0x88, 0xde, 0x36, 0xac, 0x9a, 0x20, 0x28, 0xa6, 0x5a, 0x23, 0x87, 0x36, 0xd1, 0xa9, 0x6a, + 0xe8, 0xb4, 0x76, 0x70, 0x6b, 0x87, 0xd8, 0xca, 0xad, 0x5a, 0x87, 0xe8, 0xc4, 0x52, 0x6c, 0xd2, + 0xae, 0x9a, 0x96, 0x61, 0x1b, 0xe8, 0x8a, 0xc3, 0x5e, 0x55, 0x4c, 0xb5, 0xea, 0xb3, 0x57, 0x05, + 0xfb, 0xa5, 0x9b, 0x1d, 0xd5, 0xde, 0xeb, 0xed, 0x54, 0x5b, 0x46, 0xb7, 0xd6, 0x31, 0x3a, 0x46, + 0x8d, 0x4b, 0xed, 0xf4, 0x76, 0xf9, 0x2f, 0xfe, 0x83, 0xff, 0xe5, 0xa0, 0x5d, 0x92, 0x03, 0xca, + 0x5b, 0x86, 0x45, 0x6a, 0x07, 0x31, 0x8d, 0x97, 0xee, 0xf8, 0x3c, 0x5d, 0xa5, 0xb5, 0xa7, 0xea, + 0xc4, 0xea, 0xd7, 0xcc, 0xfd, 0x0e, 0x1b, 0xa0, 0xb5, 0x2e, 0xb1, 0x95, 0x24, 0xa9, 0x5a, 0x9a, + 0x94, 0xd5, 0xd3, 0x6d, 0xb5, 0x4b, 0x62, 0x02, 0xf7, 0x06, 0x09, 0xd0, 0xd6, 0x1e, 0xe9, 0x2a, + 0x31, 0xb9, 0xb7, 0xd2, 0xe4, 0x7a, 0xb6, 0xaa, 0xd5, 0x54, 0xdd, 0xa6, 0xb6, 0x15, 0x15, 0x92, + 0xef, 0xc0, 0xd4, 0xa2, 0xa6, 0x19, 0x9f, 0x91, 0xf6, 0x52, 0x73, 0x75, 0xd9, 0x52, 0x0f, 0x88, + 0x85, 0xae, 0x42, 0x41, 0x57, 0xba, 0xa4, 0x2c, 0x5d, 0x95, 0xae, 0x8f, 0xd4, 0xc7, 0x9e, 0x1f, + 0x55, 0x2e, 0x1c, 0x1f, 0x55, 0x0a, 0x1b, 0x4a, 0x97, 0x60, 0x4e, 0x91, 0x1f, 0xc2, 0xb4, 0x90, + 0x5a, 0xd1, 0xc8, 0xe1, 0x53, 0x43, 0xeb, 0x75, 0x09, 0xba, 0x06, 0xc3, 0x6d, 0x0e, 0x20, 0x04, + 0x27, 0x84, 0xe0, 0xb0, 0x03, 0x8b, 0x05, 0x55, 0xa6, 0x30, 0x29, 0x84, 0x9f, 0x18, 0xd4, 0x6e, + 0x28, 0xf6, 0x1e, 0xba, 0x0d, 0x60, 0x2a, 0xf6, 0x5e, 0xc3, 0x22, 0xbb, 0xea, 0xa1, 0x10, 0x47, + 0x42, 0x1c, 0x1a, 0x1e, 0x05, 0x07, 0xb8, 0xd0, 0x0d, 0x28, 0x59, 0x44, 0x69, 0x6f, 0xea, 0x5a, + 0xbf, 0x9c, 0xbb, 0x2a, 0x5d, 0x2f, 0xd5, 0xa7, 0x84, 0x44, 0x09, 0x8b, 0x71, 0xec, 0x71, 0xc8, + 0x9f, 0xe7, 0x60, 0x64, 0x59, 0x21, 0x5d, 0x43, 0x6f, 0x12, 0x1b, 0x7d, 0x02, 0x25, 0xb6, 0x5d, + 0x6d, 0xc5, 0x56, 0xb8, 0xb6, 0xd1, 0xdb, 0x6f, 0x56, 0x7d, 0x77, 0xf2, 0x56, 0xaf, 0x6a, 0xee, + 0x77, 0xd8, 0x00, 0xad, 0x32, 0xee, 0xea, 0xc1, 0xad, 0xea, 0xe6, 0xce, 0x33, 0xd2, 0xb2, 0xd7, + 0x89, 0xad, 0xf8, 0xf6, 0xf9, 0x63, 0xd8, 0x43, 0x45, 0x1b, 0x50, 0xa0, 0x26, 0x69, 0x71, 0xcb, + 0x46, 0x6f, 0xdf, 0xa8, 0x9e, 0xe8, 0xac, 0x55, 0xcf, 0xb2, 0xa6, 0x49, 0x5a, 0xfe, 0x8a, 0xb3, + 0x5f, 0x98, 0xe3, 0xa0, 0xa7, 0x30, 0x4c, 0x6d, 0xc5, 0xee, 0xd1, 0x72, 0x9e, 0x23, 0x56, 0x33, + 0x23, 0x72, 0x29, 0x7f, 0x33, 0x9c, 0xdf, 0x58, 0xa0, 0xc9, 0xff, 0x99, 0x03, 0xe4, 0xf1, 0x2e, + 0x19, 0x7a, 0x5b, 0xb5, 0x55, 0x43, 0x47, 0x0f, 0xa0, 0x60, 0xf7, 0x4d, 0xd7, 0x05, 0xae, 0xb9, + 0x06, 0x6d, 0xf5, 0x4d, 0xf2, 0xe2, 0xa8, 0x32, 0x17, 0x97, 0x60, 0x14, 0xcc, 0x65, 0xd0, 0x9a, + 0x67, 0x6a, 0x8e, 0x4b, 0xdf, 0x09, 0xab, 0x7e, 0x71, 0x54, 0x49, 0x38, 0x6c, 0x55, 0x0f, 0x29, + 0x6c, 0x20, 0x3a, 0x00, 0xa4, 0x29, 0xd4, 0xde, 0xb2, 0x14, 0x9d, 0x3a, 0x9a, 0xd4, 0x2e, 0x11, + 0x8b, 0xf0, 0x46, 0xb6, 0x4d, 0x63, 0x12, 0xf5, 0x4b, 0xc2, 0x0a, 0xb4, 0x16, 0x43, 0xc3, 0x09, + 0x1a, 0x98, 0x37, 0x5b, 0x44, 0xa1, 0x86, 0x5e, 0x2e, 0x84, 0xbd, 0x19, 0xf3, 0x51, 0x2c, 0xa8, + 0xe8, 0x75, 0x28, 0x76, 0x09, 0xa5, 0x4a, 0x87, 0x94, 0x87, 0x38, 0xe3, 0xa4, 0x60, 0x2c, 0xae, + 0x3b, 0xc3, 0xd8, 0xa5, 0xcb, 0x5f, 0x4a, 0x30, 0xee, 0xad, 0xdc, 0x9a, 0x4a, 0x6d, 0xf4, 0x5b, + 0x31, 0x3f, 0xac, 0x66, 0x9b, 0x12, 0x93, 0xe6, 0x5e, 0xe8, 0xf9, 0xbc, 0x3b, 0x12, 0xf0, 0xc1, + 0x75, 0x18, 0x52, 0x6d, 0xd2, 0x65, 0xfb, 0x90, 0xbf, 0x3e, 0x7a, 0xfb, 0x7a, 0x56, 0x97, 0xa9, + 0x8f, 0x0b, 0xd0, 0xa1, 0x55, 0x26, 0x8e, 0x1d, 0x14, 0xf9, 0x4f, 0x0a, 0x01, 0xf3, 0x99, 0x6b, + 0xa2, 0x8f, 0xa0, 0x44, 0x89, 0x46, 0x5a, 0xb6, 0x61, 0x09, 0xf3, 0xdf, 0xca, 0x68, 0xbe, 0xb2, + 0x43, 0xb4, 0xa6, 0x10, 0xad, 0x8f, 0x31, 0xfb, 0xdd, 0x5f, 0xd8, 0x83, 0x44, 0xef, 0x43, 0xc9, + 0x26, 0x5d, 0x53, 0x53, 0x6c, 0x22, 0xce, 0xd1, 0x6b, 0xc1, 0x29, 0x30, 0xcf, 0x61, 0x60, 0x0d, + 0xa3, 0xbd, 0x25, 0xd8, 0xf8, 0xf1, 0xf1, 0x96, 0xc4, 0x1d, 0xc5, 0x1e, 0x0c, 0x3a, 0x80, 0x89, + 0x9e, 0xd9, 0x66, 0x9c, 0x36, 0x8b, 0x82, 0x9d, 0xbe, 0xf0, 0xa4, 0x7b, 0x59, 0xd7, 0x66, 0x3b, + 0x24, 0x5d, 0x9f, 0x13, 0xba, 0x26, 0xc2, 0xe3, 0x38, 0xa2, 0x05, 0x2d, 0xc2, 0x64, 0x57, 0xd5, + 0x59, 0x5c, 0xea, 0x37, 0x49, 0xcb, 0xd0, 0xdb, 0x94, 0xbb, 0xd5, 0x50, 0x7d, 0x5e, 0x00, 0x4c, + 0xae, 0x87, 0xc9, 0x38, 0xca, 0x8f, 0xde, 0x03, 0xe4, 0x4e, 0xe3, 0xb1, 0x13, 0xc4, 0x55, 0x43, + 0xe7, 0x3e, 0x97, 0xf7, 0x9d, 0x7b, 0x2b, 0xc6, 0x81, 0x13, 0xa4, 0xd0, 0x1a, 0xcc, 0x5a, 0xe4, + 0x40, 0x65, 0x73, 0x7c, 0xa2, 0x52, 0xdb, 0xb0, 0xfa, 0x6b, 0x6a, 0x57, 0xb5, 0xcb, 0xc3, 0xdc, + 0xa6, 0xf2, 0xf1, 0x51, 0x65, 0x16, 0x27, 0xd0, 0x71, 0xa2, 0x94, 0xfc, 0xa7, 0xc3, 0x30, 0x19, + 0x89, 0x37, 0xe8, 0x29, 0xcc, 0xb5, 0x7a, 0x96, 0x45, 0x74, 0x7b, 0xa3, 0xd7, 0xdd, 0x21, 0x56, + 0xb3, 0xb5, 0x47, 0xda, 0x3d, 0x8d, 0xb4, 0xb9, 0xa3, 0x0c, 0xd5, 0x17, 0x84, 0xc5, 0x73, 0x4b, + 0x89, 0x5c, 0x38, 0x45, 0x9a, 0xad, 0x82, 0xce, 0x87, 0xd6, 0x55, 0x4a, 0x3d, 0xcc, 0x1c, 0xc7, + 0xf4, 0x56, 0x61, 0x23, 0xc6, 0x81, 0x13, 0xa4, 0x98, 0x8d, 0x6d, 0x42, 0x55, 0x8b, 0xb4, 0xa3, + 0x36, 0xe6, 0xc3, 0x36, 0x2e, 0x27, 0x72, 0xe1, 0x14, 0x69, 0x74, 0x17, 0x46, 0x1d, 0x6d, 0x7c, + 0xff, 0xc4, 0x46, 0xcf, 0x08, 0xb0, 0xd1, 0x0d, 0x9f, 0x84, 0x83, 0x7c, 0x6c, 0x6a, 0xc6, 0x0e, + 0x25, 0xd6, 0x01, 0x69, 0xa7, 0x6f, 0xf0, 0x66, 0x8c, 0x03, 0x27, 0x48, 0xb1, 0xa9, 0x39, 0x1e, + 0x18, 0x9b, 0xda, 0x70, 0x78, 0x6a, 0xdb, 0x89, 0x5c, 0x38, 0x45, 0x9a, 0xf9, 0xb1, 0x63, 0xf2, + 0xe2, 0x81, 0xa2, 0x6a, 0xca, 0x8e, 0x46, 0xca, 0xc5, 0xb0, 0x1f, 0x6f, 0x84, 0xc9, 0x38, 0xca, + 0x8f, 0x1e, 0xc3, 0xb4, 0x33, 0xb4, 0xad, 0x2b, 0x1e, 0x48, 0x89, 0x83, 0xfc, 0x4c, 0x80, 0x4c, + 0x6f, 0x44, 0x19, 0x70, 0x5c, 0x06, 0x3d, 0x80, 0x89, 0x96, 0xa1, 0x69, 0xdc, 0x1f, 0x97, 0x8c, + 0x9e, 0x6e, 0x97, 0x47, 0x38, 0x0a, 0x62, 0xe7, 0x71, 0x29, 0x44, 0xc1, 0x11, 0x4e, 0x44, 0x00, + 0x5a, 0x6e, 0xc2, 0xa1, 0x65, 0xe0, 0xf1, 0xf1, 0x56, 0xd6, 0x18, 0xe0, 0xa5, 0x2a, 0xbf, 0x06, + 0xf0, 0x86, 0x28, 0x0e, 0x00, 0xcb, 0xff, 0x22, 0xc1, 0x7c, 0x4a, 0xe8, 0x40, 0xef, 0x84, 0x52, + 0xec, 0xaf, 0x46, 0x52, 0xec, 0xe5, 0x14, 0xb1, 0x40, 0x9e, 0xd5, 0x61, 0xdc, 0x62, 0xb3, 0xd2, + 0x3b, 0x0e, 0x8b, 0x88, 0x91, 0x77, 0x07, 0x4c, 0x03, 0x07, 0x65, 0xfc, 0x98, 0x3f, 0x7d, 0x7c, + 0x54, 0x19, 0x0f, 0xd1, 0x70, 0x18, 0x5e, 0xfe, 0xb3, 0x1c, 0xc0, 0x32, 0x31, 0x35, 0xa3, 0xdf, + 0x25, 0xfa, 0x79, 0xd4, 0x50, 0x9b, 0xa1, 0x1a, 0xea, 0xe6, 0xa0, 0xed, 0xf1, 0x4c, 0x4b, 0x2d, + 0xa2, 0x7e, 0x33, 0x52, 0x44, 0xd5, 0xb2, 0x43, 0x9e, 0x5c, 0x45, 0xfd, 0x7b, 0x1e, 0x66, 0x7c, + 0x66, 0xbf, 0x8c, 0x7a, 0x18, 0xda, 0xe3, 0x5f, 0x89, 0xec, 0xf1, 0x7c, 0x82, 0xc8, 0x2b, 0xab, + 0xa3, 0x9e, 0xc1, 0x04, 0xab, 0x72, 0x9c, 0xbd, 0xe4, 0x35, 0xd4, 0xf0, 0xa9, 0x6b, 0x28, 0x2f, + 0xdb, 0xad, 0x85, 0x90, 0x70, 0x04, 0x39, 0xa5, 0x66, 0x2b, 0xfe, 0x14, 0x6b, 0xb6, 0xaf, 0x24, + 0x98, 0xf0, 0xb7, 0xe9, 0x1c, 0x8a, 0xb6, 0x8d, 0x70, 0xd1, 0xf6, 0x7a, 0x66, 0x17, 0x4d, 0xa9, + 0xda, 0xfe, 0x87, 0x15, 0xf8, 0x1e, 0x13, 0x3b, 0xe0, 0x3b, 0x4a, 0x6b, 0x7f, 0xf0, 0x1d, 0x0f, + 0x7d, 0x2e, 0x01, 0x12, 0x59, 0x60, 0x51, 0xd7, 0x0d, 0x5b, 0x71, 0x62, 0xa5, 0x63, 0xd6, 0x6a, + 0x66, 0xb3, 0x5c, 0x8d, 0xd5, 0xed, 0x18, 0xd6, 0x23, 0xdd, 0xb6, 0xfa, 0xfe, 0x26, 0xc7, 0x19, + 0x70, 0x82, 0x01, 0x48, 0x01, 0xb0, 0x04, 0xe6, 0x96, 0x21, 0x0e, 0xf2, 0xcd, 0x0c, 0x31, 0x8f, + 0x09, 0x2c, 0x19, 0xfa, 0xae, 0xda, 0xf1, 0xc3, 0x0e, 0xf6, 0x80, 0x70, 0x00, 0xf4, 0xd2, 0x23, + 0x98, 0x4f, 0xb1, 0x16, 0x4d, 0x41, 0x7e, 0x9f, 0xf4, 0x9d, 0x65, 0xc3, 0xec, 0x4f, 0x34, 0x0b, + 0x43, 0x07, 0x8a, 0xd6, 0x73, 0xc2, 0xef, 0x08, 0x76, 0x7e, 0x3c, 0xc8, 0xdd, 0x97, 0xe4, 0x2f, + 0x87, 0x82, 0xbe, 0xc3, 0x2b, 0xe6, 0xeb, 0xec, 0xd2, 0x6a, 0x6a, 0x6a, 0x4b, 0xa1, 0xa2, 0x10, + 0x1a, 0x73, 0x2e, 0xac, 0xce, 0x18, 0xf6, 0xa8, 0xa1, 0xda, 0x3a, 0xf7, 0x6a, 0x6b, 0xeb, 0xfc, + 0xcb, 0xa9, 0xad, 0x7f, 0x1b, 0x4a, 0xd4, 0xad, 0xaa, 0x0b, 0x1c, 0xf2, 0xd6, 0x29, 0xe2, 0xab, + 0x28, 0xa8, 0x3d, 0x05, 0x5e, 0x29, 0xed, 0x81, 0x26, 0x15, 0xd1, 0x43, 0xa7, 0x2c, 0xa2, 0x5f, + 0x6a, 0xe1, 0xcb, 0xe2, 0x8d, 0xa9, 0xf4, 0x28, 0x69, 0xf3, 0xd8, 0x56, 0xf2, 0xe3, 0x4d, 0x83, + 0x8f, 0x62, 0x41, 0x45, 0x1f, 0x85, 0x5c, 0xb6, 0x74, 0x16, 0x97, 0x9d, 0x48, 0x77, 0x57, 0xb4, + 0x0d, 0xf3, 0xa6, 0x65, 0x74, 0x2c, 0x42, 0xe9, 0x32, 0x51, 0xda, 0x9a, 0xaa, 0x13, 0x77, 0x7d, + 0x9c, 0x8a, 0xe8, 0xf2, 0xf1, 0x51, 0x65, 0xbe, 0x91, 0xcc, 0x82, 0xd3, 0x64, 0xe5, 0xe7, 0x05, + 0x98, 0x8a, 0x66, 0xc0, 0x94, 0x22, 0x55, 0x3a, 0x53, 0x91, 0x7a, 0x23, 0x70, 0x18, 0x9c, 0x0a, + 0x3e, 0xf0, 0x82, 0x13, 0x3b, 0x10, 0x8b, 0x30, 0x29, 0xa2, 0x81, 0x4b, 0x14, 0x65, 0xba, 0xb7, + 0xfb, 0xdb, 0x61, 0x32, 0x8e, 0xf2, 0xa3, 0x87, 0x30, 0x6e, 0xf1, 0xba, 0xdb, 0x05, 0x70, 0x6a, + 0xd7, 0x8b, 0x02, 0x60, 0x1c, 0x07, 0x89, 0x38, 0xcc, 0xcb, 0xea, 0x56, 0xbf, 0x1c, 0x75, 0x01, + 0x0a, 0xe1, 0xba, 0x75, 0x31, 0xca, 0x80, 0xe3, 0x32, 0x68, 0x1d, 0x66, 0x7a, 0x7a, 0x1c, 0xca, + 0x71, 0xe5, 0xcb, 0x02, 0x6a, 0x66, 0x3b, 0xce, 0x82, 0x93, 0xe4, 0xd0, 0x6e, 0xa8, 0x94, 0x1d, + 0xe6, 0xe1, 0xf9, 0x76, 0xe6, 0x83, 0x97, 0xb9, 0x96, 0x4d, 0x28, 0xb7, 0x4b, 0x59, 0xcb, 0x6d, + 0xf9, 0x1f, 0xa5, 0x60, 0x12, 0xf2, 0x4a, 0xe0, 0x41, 0xaf, 0x4c, 0x31, 0x89, 0x40, 0x75, 0x64, + 0x24, 0x57, 0xbf, 0xf7, 0x4e, 0x55, 0xfd, 0xfa, 0xc9, 0x73, 0x70, 0xf9, 0xfb, 0x85, 0x04, 0x73, + 0x2b, 0xcd, 0xc7, 0x96, 0xd1, 0x33, 0x5d, 0x73, 0x36, 0x4d, 0x67, 0x69, 0x7e, 0x09, 0x05, 0xab, + 0xa7, 0xb9, 0xf3, 0x78, 0xcd, 0x9d, 0x07, 0xee, 0x69, 0x6c, 0x1e, 0x33, 0x11, 0x29, 0x67, 0x12, + 0x4c, 0x00, 0x6d, 0xc0, 0xb0, 0xa5, 0xe8, 0x1d, 0xe2, 0xa6, 0xd5, 0x6b, 0x03, 0xac, 0x5f, 0x5d, + 0xc6, 0x8c, 0x3d, 0x50, 0xd8, 0x70, 0x69, 0x2c, 0x50, 0xe4, 0x7f, 0x92, 0x60, 0xf2, 0xc9, 0xd6, + 0x56, 0x63, 0x55, 0xe7, 0x27, 0x9a, 0xbf, 0xad, 0x5e, 0x85, 0x82, 0xa9, 0xd8, 0x7b, 0xd1, 0x4c, + 0xcf, 0x68, 0x98, 0x53, 0xd0, 0x1d, 0x28, 0xb1, 0x7f, 0x99, 0x5d, 0xfc, 0x48, 0x8d, 0xf0, 0x40, + 0x58, 0x6a, 0x88, 0xb1, 0x17, 0x81, 0xbf, 0xb1, 0xc7, 0x89, 0x3e, 0x80, 0x22, 0x8b, 0x3f, 0x44, + 0x6f, 0x67, 0x2c, 0xd0, 0x85, 0x51, 0x75, 0x47, 0xc8, 0xaf, 0xb9, 0xc4, 0x00, 0x76, 0xe1, 0xe4, + 0x7d, 0x98, 0x0d, 0x4c, 0x82, 0xad, 0xe2, 0x53, 0x96, 0x53, 0x51, 0x13, 0x86, 0x98, 0x76, 0x96, + 0x39, 0xf3, 0x19, 0x9e, 0x40, 0x23, 0x0b, 0xe1, 0xd7, 0x47, 0xec, 0x17, 0xc5, 0x0e, 0x96, 0xbc, + 0x0e, 0xe3, 0xfc, 0x19, 0xda, 0xb0, 0x6c, 0xbe, 0x98, 0xe8, 0x0a, 0xe4, 0xbb, 0xaa, 0x2e, 0xb2, + 0xf3, 0xa8, 0x90, 0xc9, 0xb3, 0xcc, 0xc2, 0xc6, 0x39, 0x59, 0x39, 0x14, 0xf1, 0xca, 0x27, 0x2b, + 0x87, 0x98, 0x8d, 0xcb, 0x8f, 0xa1, 0x28, 0x36, 0x29, 0x08, 0x94, 0x3f, 0x19, 0x28, 0x9f, 0x00, + 0xb4, 0x09, 0xc5, 0xd5, 0x46, 0x5d, 0x33, 0x9c, 0x5a, 0xad, 0xa5, 0xb6, 0xad, 0xe8, 0x0e, 0x2e, + 0xad, 0x2e, 0x63, 0xcc, 0x29, 0x48, 0x86, 0x61, 0x72, 0xd8, 0x22, 0xa6, 0xcd, 0xfd, 0x68, 0xa4, + 0x0e, 0xcc, 0x37, 0x1e, 0xf1, 0x11, 0x2c, 0x28, 0xf2, 0x1f, 0xe5, 0xa0, 0x28, 0x96, 0xe3, 0x1c, + 0xee, 0x6e, 0x6b, 0xa1, 0xbb, 0xdb, 0x1b, 0xd9, 0x5c, 0x23, 0xf5, 0xe2, 0xb6, 0x15, 0xb9, 0xb8, + 0xdd, 0xc8, 0x88, 0x77, 0xf2, 0xad, 0xed, 0x6f, 0x25, 0x98, 0x08, 0x3b, 0x25, 0xba, 0x0b, 0xa3, + 0x2c, 0x4d, 0xa9, 0x2d, 0xb2, 0xe1, 0x57, 0xc7, 0xde, 0xd3, 0x4d, 0xd3, 0x27, 0xe1, 0x20, 0x1f, + 0xea, 0x78, 0x62, 0xcc, 0x8f, 0xc4, 0xa4, 0xd3, 0x97, 0xb4, 0x67, 0xab, 0x5a, 0xd5, 0xf9, 0x20, + 0x53, 0x5d, 0xd5, 0xed, 0x4d, 0xab, 0x69, 0x5b, 0xaa, 0xde, 0x89, 0x29, 0xe2, 0x4e, 0x19, 0x44, + 0x96, 0xff, 0x5e, 0x82, 0x51, 0x61, 0xf2, 0x39, 0xdc, 0x45, 0x7e, 0x23, 0x7c, 0x17, 0xb9, 0x96, + 0xf1, 0x80, 0x27, 0x5f, 0x44, 0xfe, 0xd2, 0x37, 0x9d, 0x1d, 0x69, 0xe6, 0xd5, 0x7b, 0x06, 0xb5, + 0xa3, 0x5e, 0xcd, 0x0e, 0x23, 0xe6, 0x14, 0xd4, 0x83, 0x29, 0x35, 0x12, 0x03, 0xc4, 0xd2, 0xd6, + 0xb2, 0x59, 0xe2, 0x89, 0xd5, 0xcb, 0x02, 0x7e, 0x2a, 0x4a, 0xc1, 0x31, 0x15, 0x32, 0x81, 0x18, + 0x17, 0x7a, 0x1f, 0x0a, 0x7b, 0xb6, 0x6d, 0x26, 0xbc, 0x72, 0x0f, 0x88, 0x3c, 0xbe, 0x09, 0x25, + 0x3e, 0xbb, 0xad, 0xad, 0x06, 0xe6, 0x50, 0xf2, 0x3f, 0xe4, 0xbc, 0xf5, 0xe0, 0x57, 0x83, 0x77, + 0xbd, 0xd9, 0x2e, 0x69, 0x0a, 0xa5, 0xdc, 0xff, 0x9c, 0x6b, 0xec, 0x6c, 0xc0, 0x70, 0x8f, 0x86, + 0x63, 0xdc, 0x68, 0xcb, 0x8f, 0xc8, 0xd2, 0x59, 0x22, 0xf2, 0x68, 0x52, 0x34, 0x46, 0x4f, 0x20, + 0x6f, 0x6b, 0x59, 0xaf, 0xa3, 0x02, 0x71, 0x6b, 0xad, 0xe9, 0x87, 0xb4, 0xad, 0xb5, 0x26, 0x66, + 0x10, 0x68, 0x13, 0x86, 0x58, 0xd6, 0x63, 0x87, 0x38, 0x9f, 0x3d, 0x28, 0xb0, 0x15, 0xf4, 0x5d, + 0x8a, 0xfd, 0xa2, 0xd8, 0xc1, 0x91, 0x3f, 0x85, 0xf1, 0xd0, 0x49, 0x47, 0x9f, 0xc0, 0x98, 0x66, + 0x28, 0xed, 0xba, 0xa2, 0x29, 0x7a, 0x8b, 0xb8, 0x1f, 0x25, 0xae, 0x25, 0xdd, 0x6c, 0xd6, 0x02, + 0x7c, 0x22, 0x4e, 0xcc, 0x0a, 0x25, 0x63, 0x41, 0x1a, 0x0e, 0x21, 0xca, 0x0a, 0x80, 0x3f, 0x47, + 0x54, 0x81, 0x21, 0xe6, 0xa9, 0x4e, 0x46, 0x1a, 0xa9, 0x8f, 0x30, 0x0b, 0x99, 0x03, 0x53, 0xec, + 0x8c, 0xa3, 0xdb, 0x00, 0x94, 0xb4, 0x2c, 0x62, 0xf3, 0xed, 0xcc, 0x85, 0x3f, 0x6c, 0x36, 0x3d, + 0x0a, 0x0e, 0x70, 0xc9, 0xff, 0x2c, 0xc1, 0xf8, 0x06, 0xb1, 0x3f, 0x33, 0xac, 0xfd, 0x86, 0xa1, + 0xa9, 0xad, 0xfe, 0x39, 0x84, 0x6b, 0x1c, 0x0a, 0xd7, 0x6f, 0x0e, 0xd8, 0x99, 0x90, 0x75, 0x69, + 0x41, 0x5b, 0xfe, 0x4a, 0x82, 0xf9, 0x10, 0xe7, 0x23, 0xff, 0xf0, 0x6f, 0xc3, 0x90, 0x69, 0x58, + 0xb6, 0x9b, 0xca, 0x4f, 0xa5, 0x90, 0x05, 0xc2, 0x40, 0x32, 0x67, 0x30, 0xd8, 0x41, 0x43, 0x6b, + 0x90, 0xb3, 0x0d, 0xe1, 0xaa, 0xa7, 0xc3, 0x24, 0xc4, 0xaa, 0x83, 0xc0, 0xcc, 0x6d, 0x19, 0x38, + 0x67, 0x1b, 0x6c, 0x23, 0xca, 0x21, 0xae, 0x60, 0xf8, 0x7a, 0x45, 0x33, 0xc0, 0x50, 0xd8, 0xb5, + 0x8c, 0xee, 0x99, 0xe7, 0xe0, 0x6d, 0xc4, 0x8a, 0x65, 0x74, 0x31, 0xc7, 0x92, 0xbf, 0x96, 0x60, + 0x3a, 0xc4, 0x79, 0x0e, 0xa9, 0xe3, 0xfd, 0x70, 0xea, 0xb8, 0x71, 0x9a, 0x89, 0xa4, 0x24, 0x90, + 0xaf, 0x73, 0x91, 0x69, 0xb0, 0x09, 0xa3, 0x5d, 0x18, 0x35, 0x8d, 0x76, 0xf3, 0x25, 0x7c, 0x86, + 0x9c, 0x64, 0x99, 0xb7, 0xe1, 0x63, 0xe1, 0x20, 0x30, 0x3a, 0x84, 0x69, 0x5d, 0xe9, 0x12, 0x6a, + 0x2a, 0x2d, 0xd2, 0x7c, 0x09, 0x0f, 0x33, 0x17, 0xf9, 0x77, 0x8e, 0x28, 0x22, 0x8e, 0x2b, 0x41, + 0xeb, 0x50, 0x54, 0x4d, 0x5e, 0x09, 0x8a, 0xea, 0x67, 0x60, 0x1e, 0x76, 0xea, 0x46, 0x27, 0x9e, + 0x8b, 0x1f, 0xd8, 0xc5, 0x90, 0xff, 0x2a, 0xea, 0x0d, 0xcc, 0xff, 0xd0, 0x63, 0x28, 0xf1, 0x86, + 0x90, 0x96, 0xa1, 0xb9, 0x5f, 0x24, 0xf8, 0x1d, 0x40, 0x8c, 0xbd, 0x38, 0xaa, 0x5c, 0x4e, 0x78, + 0x6c, 0x76, 0xc9, 0xd8, 0x13, 0x46, 0x1b, 0x50, 0x30, 0x7f, 0x4c, 0x0d, 0xc4, 0xd3, 0x24, 0x2f, + 0x7c, 0x38, 0x8e, 0xfc, 0x7b, 0xf9, 0x88, 0xb9, 0x3c, 0x59, 0x3e, 0x7b, 0x69, 0xbb, 0xee, 0xd5, + 0x5c, 0xa9, 0x3b, 0xbf, 0x03, 0x45, 0x91, 0x6a, 0x85, 0x33, 0xff, 0xf2, 0x34, 0xce, 0x1c, 0xcc, + 0x62, 0xde, 0x95, 0xc7, 0x1d, 0x74, 0x81, 0xd1, 0xc7, 0x30, 0x4c, 0x1c, 0x15, 0x4e, 0x6e, 0xbc, + 0x77, 0x1a, 0x15, 0x7e, 0x5c, 0xf5, 0x4b, 0x5d, 0x31, 0x26, 0x50, 0xd1, 0x3b, 0x6c, 0xbd, 0x18, + 0x2f, 0xbb, 0xba, 0xd1, 0x72, 0x81, 0xa7, 0xab, 0x2b, 0xce, 0xb4, 0xbd, 0xe1, 0x17, 0x47, 0x15, + 0xf0, 0x7f, 0xe2, 0xa0, 0x84, 0xfc, 0xaf, 0x12, 0x4c, 0xf3, 0x15, 0x6a, 0xf5, 0x2c, 0xd5, 0xee, + 0x9f, 0x5b, 0x62, 0x7a, 0x1a, 0x4a, 0x4c, 0x77, 0x06, 0x2c, 0x4b, 0xcc, 0xc2, 0xd4, 0xe4, 0xf4, + 0x8d, 0x04, 0x17, 0x63, 0xdc, 0xe7, 0x10, 0x17, 0xb7, 0xc3, 0x71, 0xf1, 0xcd, 0xd3, 0x4e, 0x28, + 0x25, 0x36, 0xfe, 0xf7, 0x74, 0xc2, 0x74, 0xf8, 0x49, 0xb9, 0x0d, 0x60, 0x5a, 0xea, 0x81, 0xaa, + 0x91, 0x8e, 0xf8, 0xf8, 0x5e, 0x0a, 0xb4, 0x56, 0x79, 0x14, 0x1c, 0xe0, 0x42, 0x14, 0xe6, 0xda, + 0x64, 0x57, 0xe9, 0x69, 0xf6, 0x62, 0xbb, 0xbd, 0xa4, 0x98, 0xca, 0x8e, 0xaa, 0xa9, 0xb6, 0x2a, + 0x9e, 0x29, 0x46, 0xea, 0x0f, 0x9d, 0x8f, 0xe2, 0x49, 0x1c, 0x2f, 0x8e, 0x2a, 0x57, 0x92, 0xbe, + 0x4a, 0xb9, 0x2c, 0x7d, 0x9c, 0x02, 0x8d, 0xfa, 0x50, 0xb6, 0xc8, 0xa7, 0x3d, 0xd5, 0x22, 0xed, + 0x65, 0xcb, 0x30, 0x43, 0x6a, 0xf3, 0x5c, 0xed, 0xaf, 0x1f, 0x1f, 0x55, 0xca, 0x38, 0x85, 0x67, + 0xb0, 0xe2, 0x54, 0x78, 0xf4, 0x0c, 0x66, 0x14, 0xd1, 0x04, 0x17, 0xd4, 0xea, 0x9c, 0x92, 0xfb, + 0xc7, 0x47, 0x95, 0x99, 0xc5, 0x38, 0x79, 0xb0, 0xc2, 0x24, 0x50, 0x54, 0x83, 0xe2, 0x01, 0xef, + 0x97, 0xa3, 0xe5, 0x21, 0x8e, 0xcf, 0x12, 0x41, 0xd1, 0x69, 0xa1, 0x63, 0x98, 0xc3, 0x2b, 0x4d, + 0x7e, 0xfa, 0x5c, 0x2e, 0x76, 0x25, 0x65, 0xb5, 0xa4, 0x38, 0xf1, 0xfc, 0xa5, 0xba, 0xe4, 0x47, + 0xad, 0x27, 0x3e, 0x09, 0x07, 0xf9, 0xd0, 0x47, 0x30, 0xb2, 0x27, 0xde, 0x35, 0x68, 0xb9, 0x98, + 0x29, 0x09, 0x87, 0xde, 0x41, 0xea, 0xd3, 0x42, 0xc5, 0x88, 0x3b, 0x4c, 0xb1, 0x8f, 0x88, 0x5e, + 0x87, 0x22, 0xff, 0xb1, 0xba, 0xcc, 0x9f, 0x01, 0x4b, 0x7e, 0x6c, 0x7b, 0xe2, 0x0c, 0x63, 0x97, + 0xee, 0xb2, 0xae, 0x36, 0x96, 0xf8, 0x73, 0x74, 0x84, 0x75, 0xb5, 0xb1, 0x84, 0x5d, 0x3a, 0xfa, + 0x04, 0x8a, 0x94, 0xac, 0xa9, 0x7a, 0xef, 0xb0, 0x0c, 0x99, 0x3e, 0x66, 0x37, 0x1f, 0x71, 0xee, + 0xc8, 0x83, 0x9c, 0xaf, 0x41, 0xd0, 0xb1, 0x0b, 0x8b, 0xf6, 0x60, 0xc4, 0xea, 0xe9, 0x8b, 0x74, + 0x9b, 0x12, 0xab, 0x3c, 0xca, 0x75, 0x0c, 0x0a, 0xe7, 0xd8, 0xe5, 0x8f, 0x6a, 0xf1, 0x56, 0xc8, + 0xe3, 0xc0, 0x3e, 0x38, 0xda, 0x03, 0xe0, 0x3f, 0xf8, 0xdb, 0x5f, 0x79, 0x8e, 0xab, 0xba, 0x9f, + 0x45, 0x55, 0xd2, 0x13, 0xa3, 0x78, 0xff, 0xf7, 0xc8, 0x38, 0x80, 0x8d, 0xfe, 0x50, 0x02, 0x44, + 0x7b, 0xa6, 0xa9, 0x91, 0x2e, 0xd1, 0x6d, 0x45, 0xe3, 0xa3, 0xb4, 0x3c, 0xc6, 0x55, 0xbe, 0x3b, + 0x68, 0x05, 0x63, 0x82, 0x51, 0xd5, 0xde, 0xb3, 0x7e, 0x9c, 0x15, 0x27, 0xe8, 0x65, 0x9b, 0xb8, + 0x2b, 0x66, 0x3d, 0x9e, 0x69, 0x13, 0x93, 0x5f, 0x55, 0xfd, 0x4d, 0x14, 0x74, 0xec, 0xc2, 0xa2, + 0xa7, 0x30, 0xe7, 0x36, 0x76, 0x62, 0xc3, 0xb0, 0x57, 0x54, 0x8d, 0xd0, 0x3e, 0xb5, 0x49, 0xb7, + 0x3c, 0xc1, 0x1d, 0xcc, 0xeb, 0x6e, 0xc1, 0x89, 0x5c, 0x38, 0x45, 0x1a, 0x75, 0xa1, 0xe2, 0x06, + 0x27, 0x76, 0x72, 0xbd, 0xe8, 0xf8, 0x88, 0xb6, 0x14, 0xcd, 0xf9, 0xd2, 0x31, 0xc9, 0x15, 0xbc, + 0x76, 0x7c, 0x54, 0xa9, 0x2c, 0x9f, 0xcc, 0x8a, 0x07, 0x61, 0xa1, 0x0f, 0xa0, 0xac, 0xa4, 0xe9, + 0x99, 0xe2, 0x7a, 0x7e, 0xce, 0x22, 0x5e, 0xaa, 0x82, 0x54, 0x69, 0x64, 0xc3, 0x94, 0x12, 0x6e, + 0xb1, 0xa5, 0xe5, 0xe9, 0x4c, 0x8f, 0xa6, 0x91, 0xce, 0x5c, 0xff, 0xe1, 0x24, 0x42, 0xa0, 0x38, + 0xa6, 0x01, 0xfd, 0x0e, 0x20, 0x25, 0xda, 0x15, 0x4c, 0xcb, 0x28, 0x53, 0xa2, 0x8b, 0xb5, 0x13, + 0xfb, 0x6e, 0x17, 0x23, 0x51, 0x9c, 0xa0, 0x87, 0x15, 0xe8, 0x4a, 0xa4, 0x93, 0x99, 0x96, 0xe7, + 0xb9, 0xf2, 0x5a, 0x36, 0xe5, 0x9e, 0x5c, 0xe0, 0x83, 0x4e, 0x14, 0x11, 0xc7, 0x95, 0xa0, 0x35, + 0x98, 0x15, 0x83, 0xdb, 0x3a, 0x55, 0x76, 0x49, 0xb3, 0x4f, 0x5b, 0xb6, 0x46, 0xcb, 0x33, 0x3c, + 0xbe, 0xf3, 0x8f, 0x8a, 0x8b, 0x09, 0x74, 0x9c, 0x28, 0x85, 0xde, 0x85, 0xa9, 0x5d, 0xc3, 0xda, + 0x51, 0xdb, 0x6d, 0xa2, 0xbb, 0x48, 0xb3, 0x1c, 0x89, 0xbf, 0x03, 0xad, 0x44, 0x68, 0x38, 0xc6, + 0x8d, 0x28, 0x5c, 0x14, 0xc8, 0x0d, 0xcb, 0x68, 0xad, 0x1b, 0x3d, 0xdd, 0x76, 0xca, 0xbe, 0x8b, + 0x5e, 0x1a, 0xbd, 0xb8, 0x98, 0xc4, 0xf0, 0xe2, 0xa8, 0x72, 0x35, 0xb9, 0xca, 0xf7, 0x99, 0x70, + 0x32, 0x36, 0x32, 0x61, 0x4c, 0xf4, 0xa7, 0xf3, 0x07, 0xa9, 0x72, 0x99, 0x1f, 0xfd, 0x07, 0x83, + 0x03, 0x9e, 0x27, 0x12, 0x3d, 0xff, 0x53, 0xc7, 0x47, 0x95, 0xb1, 0x20, 0x03, 0x0e, 0x69, 0xe0, + 0xfd, 0x48, 0xe2, 0x2b, 0xd8, 0xf9, 0xf4, 0x74, 0x9f, 0xae, 0x1f, 0xc9, 0x37, 0xed, 0xa5, 0xf5, + 0x23, 0x05, 0x20, 0x4f, 0x7e, 0xd9, 0xfe, 0xaf, 0x1c, 0xcc, 0xf8, 0xcc, 0x99, 0xfb, 0x91, 0x12, + 0x44, 0xfe, 0xbf, 0xaf, 0x3b, 0x5b, 0x8f, 0x90, 0xbf, 0x74, 0xff, 0xf7, 0x7a, 0x84, 0x7c, 0xdb, + 0x52, 0x6e, 0x0f, 0x7f, 0x93, 0x0b, 0x4e, 0xe0, 0x94, 0x8d, 0x2a, 0x2f, 0xa1, 0xb5, 0xf9, 0x27, + 0xd7, 0xeb, 0x22, 0x7f, 0x93, 0x87, 0xa9, 0xe8, 0x69, 0x0c, 0xf5, 0x33, 0x48, 0x03, 0xfb, 0x19, + 0x1a, 0x30, 0xbb, 0xdb, 0xd3, 0xb4, 0x3e, 0x9f, 0x43, 0xa0, 0xa9, 0xc1, 0xf9, 0xb2, 0xf8, 0x73, + 0x21, 0x39, 0xbb, 0x92, 0xc0, 0x83, 0x13, 0x25, 0xe3, 0xed, 0x0d, 0x85, 0x1f, 0xdb, 0xde, 0x30, + 0x74, 0x86, 0xf6, 0x86, 0xe4, 0x0e, 0x91, 0xfc, 0x99, 0x3a, 0x44, 0xce, 0xd2, 0xdb, 0x90, 0x10, + 0xc4, 0x06, 0xf6, 0xe9, 0xbe, 0x0d, 0x13, 0xe1, 0x7e, 0x1b, 0x67, 0x2f, 0x9d, 0x96, 0x1f, 0xf1, + 0x05, 0x37, 0xb0, 0x97, 0xce, 0x38, 0xf6, 0x38, 0xe4, 0xdf, 0x97, 0x60, 0x2e, 0xb9, 0xaf, 0x16, + 0x69, 0x30, 0xd1, 0x55, 0x0e, 0x83, 0xbd, 0xce, 0xd2, 0x19, 0x5f, 0xc6, 0x78, 0xa3, 0xc5, 0x7a, + 0x08, 0x0b, 0x47, 0xb0, 0xe5, 0x1f, 0x24, 0x98, 0x4f, 0x69, 0x71, 0x38, 0x5f, 0x4b, 0xd0, 0x87, + 0x50, 0xea, 0x2a, 0x87, 0xcd, 0x9e, 0xd5, 0x21, 0x67, 0x7e, 0x0b, 0xe4, 0x07, 0x7a, 0x5d, 0xa0, + 0x60, 0x0f, 0x4f, 0xfe, 0x0b, 0x09, 0x7e, 0x96, 0x7a, 0x55, 0x42, 0xf7, 0x42, 0xdd, 0x18, 0x72, + 0xa4, 0x1b, 0x03, 0xc5, 0x05, 0x5f, 0x51, 0x33, 0xc6, 0x17, 0x12, 0x94, 0xd3, 0xee, 0x8e, 0xe8, + 0x6e, 0xc8, 0xc8, 0x5f, 0x44, 0x8c, 0x9c, 0x8e, 0xc9, 0xbd, 0x22, 0x1b, 0xff, 0x4d, 0x82, 0xcb, + 0x27, 0xd4, 0x60, 0xde, 0x15, 0x85, 0xb4, 0x83, 0x5c, 0xfc, 0xd9, 0x5a, 0x7c, 0xf3, 0xf2, 0xaf, + 0x28, 0x09, 0x3c, 0x38, 0x55, 0x1a, 0x6d, 0xc3, 0xbc, 0xb8, 0x1f, 0x45, 0x69, 0xa2, 0xbc, 0xe0, + 0x4d, 0x6b, 0xcb, 0xc9, 0x2c, 0x38, 0x4d, 0x56, 0xfe, 0x6b, 0x09, 0xe6, 0x92, 0x1f, 0x05, 0xd0, + 0x5b, 0xa1, 0x25, 0xaf, 0x44, 0x96, 0x7c, 0x32, 0x22, 0x25, 0x16, 0xfc, 0x63, 0x98, 0x10, 0x4f, + 0x07, 0x02, 0x46, 0x38, 0xb3, 0x9c, 0x94, 0x41, 0x04, 0x84, 0x5b, 0xc0, 0xf2, 0x63, 0x12, 0x1e, + 0xc3, 0x11, 0x34, 0xf9, 0x0f, 0x72, 0x30, 0xd4, 0x6c, 0x29, 0x1a, 0x39, 0x87, 0xfa, 0xf5, 0xbd, + 0x50, 0xfd, 0x3a, 0xe8, 0xbf, 0x83, 0x71, 0xab, 0x52, 0x4b, 0x57, 0x1c, 0x29, 0x5d, 0xdf, 0xc8, + 0x84, 0x76, 0x72, 0xd5, 0xfa, 0x6b, 0x30, 0xe2, 0x29, 0x3d, 0x5d, 0x32, 0x95, 0xff, 0x3c, 0x07, + 0xa3, 0x01, 0x15, 0xa7, 0x4c, 0xc5, 0xbb, 0xa1, 0xfa, 0x23, 0x9f, 0xe1, 0xa1, 0x26, 0xa0, 0xab, + 0xea, 0x56, 0x1c, 0x4e, 0x3b, 0xb3, 0xdf, 0xc0, 0x1a, 0x2f, 0x44, 0xde, 0x86, 0x09, 0x5b, 0xb1, + 0x3a, 0xc4, 0xf6, 0x3e, 0x5c, 0x38, 0xed, 0x56, 0x5e, 0x5f, 0xfd, 0x56, 0x88, 0x8a, 0x23, 0xdc, + 0x97, 0x1e, 0xc2, 0x78, 0x48, 0xd9, 0xa9, 0xba, 0x91, 0xff, 0x4e, 0x82, 0x5f, 0x0c, 0x7c, 0xec, + 0x41, 0xf5, 0xd0, 0x21, 0xa9, 0x46, 0x0e, 0xc9, 0x42, 0x3a, 0xc0, 0xab, 0xeb, 0x6a, 0xab, 0xdf, + 0x7c, 0xfe, 0xfd, 0xc2, 0x85, 0x6f, 0xbf, 0x5f, 0xb8, 0xf0, 0xdd, 0xf7, 0x0b, 0x17, 0x7e, 0xf7, + 0x78, 0x41, 0x7a, 0x7e, 0xbc, 0x20, 0x7d, 0x7b, 0xbc, 0x20, 0x7d, 0x77, 0xbc, 0x20, 0xfd, 0xc7, + 0xf1, 0x82, 0xf4, 0xc7, 0x3f, 0x2c, 0x5c, 0xf8, 0xb0, 0x28, 0xe0, 0xfe, 0x37, 0x00, 0x00, 0xff, + 0xff, 0xb6, 0xd9, 0x2e, 0xa8, 0x61, 0x3e, 0x00, 0x00, } func (m *AllowedCSIDriver) Marshal() (dAtA []byte, err error) { @@ -2814,6 +2815,13 @@ func (m *HTTPIngressPath) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PathType != nil { + i -= len(*m.PathType) + copy(dAtA[i:], *m.PathType) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.PathType))) + i-- + dAtA[i] = 0x1a + } { size, err := m.Backend.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -5088,6 +5096,10 @@ func (m *HTTPIngressPath) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = m.Backend.Size() n += 1 + l + sovGenerated(uint64(l)) + if m.PathType != nil { + l = len(*m.PathType) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -6072,6 +6084,7 @@ func (this *HTTPIngressPath) String() string { s := strings.Join([]string{`&HTTPIngressPath{`, `Path:` + fmt.Sprintf("%v", this.Path) + `,`, `Backend:` + strings.Replace(strings.Replace(this.Backend.String(), "IngressBackend", "IngressBackend", 1), `&`, ``, 1) + `,`, + `PathType:` + valueToStringGenerated(this.PathType) + `,`, `}`, }, "") return s @@ -9614,6 +9627,39 @@ func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PathType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := PathType(dAtA[iNdEx:postIndex]) + m.PathType = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/api/extensions/v1beta1/generated.proto b/staging/src/k8s.io/api/extensions/v1beta1/generated.proto index a92cc5668f1..5f1e33b57e1 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/extensions/v1beta1/generated.proto @@ -408,19 +408,33 @@ message FSGroupStrategyOptions { repeated IDRange ranges = 2; } -// HTTPIngressPath associates a path regex with a backend. Incoming urls matching -// the path are forwarded to the backend. +// HTTPIngressPath associates a path with a backend. Incoming urls matching the +// path are forwarded to the backend. message HTTPIngressPath { - // Path is an extended POSIX regex as defined by IEEE Std 1003.1, - // (i.e this follows the egrep/unix syntax, not the perl syntax) - // matched against the path of an incoming request. Currently it can - // contain characters disallowed from the conventional "path" - // part of a URL as defined by RFC 3986. Paths must begin with - // a '/'. If unspecified, the path defaults to a catch all sending - // traffic to the backend. + // Path is matched against the path of an incoming request. Currently it can + // contain characters disallowed from the conventional "path" part of a URL + // as defined by RFC 3986. Paths must begin with a '/'. When unspecified, + // all paths from incoming requests are matched. // +optional optional string path = 1; + // PathType determines the interpretation of the Path matching. PathType can + // be one of the following values: + // * Exact: Matches the URL path exactly. + // * Prefix: Matches based on a URL path prefix split by '/'. Matching is + // done on a path element by element basis. A path element refers is the + // list of labels in the path split by the '/' separator. A request is a + // match for path p if every p is an element-wise prefix of p of the + // request path. Note that if the last element of the path is a substring + // of the last element in request path, it is not a match (e.g. /foo/bar + // matches /foo/bar/baz, but does not match /foo/barbaz). + // * ImplementationSpecific: Interpretation of the Path matching is up to + // the IngressClass. Implementations can treat this as a separate PathType + // or treat it identically to Prefix or Exact path types. + // Implementations are required to support all path types. + // Defaults to ImplementationSpecific. + optional string pathType = 3; + // Backend defines the referenced service endpoint to which the traffic // will be forwarded to. optional IngressBackend backend = 2; diff --git a/staging/src/k8s.io/api/extensions/v1beta1/types.go b/staging/src/k8s.io/api/extensions/v1beta1/types.go index 3f1cb4fa6d0..af35e2cf67c 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/types.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/types.go @@ -683,19 +683,63 @@ type HTTPIngressRuleValue struct { // options usable by a loadbalancer, like http keep-alive. } -// HTTPIngressPath associates a path regex with a backend. Incoming urls matching -// the path are forwarded to the backend. +// PathType represents the type of path referred to by a HTTPIngressPath. +type PathType string + +const ( + // PathTypeExact matches the URL path exactly and with case sensitivity. + PathTypeExact = PathType("Exact") + + // PathTypePrefix matches based on a URL path prefix split by '/'. Matching + // is case sensitive and done on a path element by element basis. A path + // element refers to the list of labels in the path split by the '/' + // separator. A request is a match for path p if every p is an element-wise + // prefix of p of the request path. Note that if the last element of the + // path is a substring of the last element in request path, it is not a + // match (e.g. /foo/bar matches /foo/bar/baz, but does not match + // /foo/barbaz). If multiple matching paths exist in an Ingress spec, the + // longest matching path is given priority. + // Examples: + // - /foo/bar does not match requests to /foo/barbaz + // - /foo/bar matches request to /foo/bar and /foo/bar/baz + // - /foo and /foo/ both match requests to /foo and /foo/. If both paths are + // present in an Ingress spec, the longest matching path (/foo/) is given + // priority. + PathTypePrefix = PathType("Prefix") + + // PathTypeImplementationSpecific matching is up to the IngressClass. + // Implementations can treat this as a separate PathType or treat it + // identically to Prefix or Exact path types. + PathTypeImplementationSpecific = PathType("ImplementationSpecific") +) + +// HTTPIngressPath associates a path with a backend. Incoming urls matching the +// path are forwarded to the backend. type HTTPIngressPath struct { - // Path is an extended POSIX regex as defined by IEEE Std 1003.1, - // (i.e this follows the egrep/unix syntax, not the perl syntax) - // matched against the path of an incoming request. Currently it can - // contain characters disallowed from the conventional "path" - // part of a URL as defined by RFC 3986. Paths must begin with - // a '/'. If unspecified, the path defaults to a catch all sending - // traffic to the backend. + // Path is matched against the path of an incoming request. Currently it can + // contain characters disallowed from the conventional "path" part of a URL + // as defined by RFC 3986. Paths must begin with a '/'. When unspecified, + // all paths from incoming requests are matched. // +optional Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"` + // PathType determines the interpretation of the Path matching. PathType can + // be one of the following values: + // * Exact: Matches the URL path exactly. + // * Prefix: Matches based on a URL path prefix split by '/'. Matching is + // done on a path element by element basis. A path element refers is the + // list of labels in the path split by the '/' separator. A request is a + // match for path p if every p is an element-wise prefix of p of the + // request path. Note that if the last element of the path is a substring + // of the last element in request path, it is not a match (e.g. /foo/bar + // matches /foo/bar/baz, but does not match /foo/barbaz). + // * ImplementationSpecific: Interpretation of the Path matching is up to + // the IngressClass. Implementations can treat this as a separate PathType + // or treat it identically to Prefix or Exact path types. + // Implementations are required to support all path types. + // Defaults to ImplementationSpecific. + PathType *PathType `json:"pathType,omitempty" protobuf:"bytes,3,opt,name=pathType"` + // Backend defines the referenced service endpoint to which the traffic // will be forwarded to. Backend IngressBackend `json:"backend" protobuf:"bytes,2,opt,name=backend"` diff --git a/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go index 5e8f5d160a6..ed20ebc8597 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go @@ -230,9 +230,10 @@ func (FSGroupStrategyOptions) SwaggerDoc() map[string]string { } var map_HTTPIngressPath = map[string]string{ - "": "HTTPIngressPath associates a path regex with a backend. Incoming urls matching the path are forwarded to the backend.", - "path": "Path is an extended POSIX regex as defined by IEEE Std 1003.1, (i.e this follows the egrep/unix syntax, not the perl syntax) matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. If unspecified, the path defaults to a catch all sending traffic to the backend.", - "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", + "": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", + "path": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. When unspecified, all paths from incoming requests are matched.", + "pathType": "PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types. Defaults to ImplementationSpecific.", + "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", } func (HTTPIngressPath) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go index 5750d707cdd..a529a2a2366 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go @@ -458,6 +458,11 @@ func (in *FSGroupStrategyOptions) DeepCopy() *FSGroupStrategyOptions { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPIngressPath) DeepCopyInto(out *HTTPIngressPath) { *out = *in + if in.PathType != nil { + in, out := &in.PathType, &out.PathType + *out = new(PathType) + **out = **in + } out.Backend = in.Backend return } @@ -478,7 +483,9 @@ func (in *HTTPIngressRuleValue) DeepCopyInto(out *HTTPIngressRuleValue) { if in.Paths != nil { in, out := &in.Paths, &out.Paths *out = make([]HTTPIngressPath, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } diff --git a/staging/src/k8s.io/api/networking/v1beta1/generated.pb.go b/staging/src/k8s.io/api/networking/v1beta1/generated.pb.go index 86e3eeb3792..b004cc2f11f 100644 --- a/staging/src/k8s.io/api/networking/v1beta1/generated.pb.go +++ b/staging/src/k8s.io/api/networking/v1beta1/generated.pb.go @@ -429,66 +429,68 @@ func init() { } var fileDescriptor_5bea11de0ceb8f53 = []byte{ - // 941 bytes of a gzipped FileDescriptorProto + // 965 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0x8f, 0x93, 0x66, 0xdb, 0x4e, 0xba, 0xdd, 0x6a, 0xe8, 0x21, 0xaa, 0x84, 0x5b, 0xf9, 0x80, - 0xca, 0x9f, 0xda, 0xb4, 0x0b, 0x88, 0x23, 0xf2, 0x4a, 0xa8, 0x15, 0x81, 0x86, 0x89, 0x85, 0x10, - 0x02, 0x69, 0x27, 0xce, 0x5b, 0xc7, 0xc4, 0xb1, 0xcd, 0xcc, 0x38, 0x68, 0x6f, 0x7c, 0x01, 0x04, - 0x5f, 0x02, 0xce, 0x1c, 0x39, 0x22, 0xb8, 0xf4, 0xb8, 0xc7, 0x3d, 0xad, 0x68, 0xf8, 0x22, 0x68, - 0xc6, 0x53, 0xdb, 0x49, 0x1a, 0xd6, 0xcb, 0xa1, 0x37, 0xcf, 0xbc, 0xf7, 0x7e, 0xef, 0xfd, 0x7e, - 0xef, 0xf9, 0x0d, 0xfa, 0x78, 0xf2, 0x21, 0xb7, 0xc3, 0xc4, 0x99, 0x64, 0x43, 0x60, 0x31, 0x08, - 0xe0, 0xce, 0x0c, 0xe2, 0x51, 0xc2, 0x1c, 0x6d, 0xa0, 0x69, 0xe8, 0xc4, 0x20, 0xbe, 0x4f, 0xd8, - 0x24, 0x8c, 0x03, 0x67, 0x76, 0x3a, 0x04, 0x41, 0x4f, 0x9d, 0x00, 0x62, 0x60, 0x54, 0xc0, 0xc8, - 0x4e, 0x59, 0x22, 0x12, 0xfc, 0x7a, 0xee, 0x6e, 0xd3, 0x34, 0xb4, 0x4b, 0x77, 0x5b, 0xbb, 0x1f, - 0x9c, 0x04, 0xa1, 0x18, 0x67, 0x43, 0xdb, 0x4f, 0xa6, 0x4e, 0x90, 0x04, 0x89, 0xa3, 0xa2, 0x86, - 0xd9, 0x13, 0x75, 0x52, 0x07, 0xf5, 0x95, 0xa3, 0x1d, 0x58, 0x95, 0xe4, 0x7e, 0xc2, 0xc0, 0x99, - 0xad, 0x64, 0x3c, 0x78, 0xaf, 0xf4, 0x99, 0x52, 0x7f, 0x1c, 0xc6, 0xc0, 0x9e, 0x3a, 0xe9, 0x24, - 0x90, 0x17, 0xdc, 0x99, 0x82, 0xa0, 0xb7, 0x45, 0x39, 0xeb, 0xa2, 0x58, 0x16, 0x8b, 0x70, 0x0a, - 0x2b, 0x01, 0x1f, 0xbc, 0x2c, 0x80, 0xfb, 0x63, 0x98, 0xd2, 0x95, 0xb8, 0x87, 0xeb, 0xe2, 0x32, - 0x11, 0x46, 0x4e, 0x18, 0x0b, 0x2e, 0xd8, 0x72, 0x90, 0xf5, 0xa3, 0x81, 0x1e, 0x9c, 0x7b, 0x5e, - 0xff, 0x22, 0x0e, 0x18, 0x70, 0xde, 0xa7, 0x62, 0x8c, 0x8f, 0xd0, 0x46, 0x4a, 0xc5, 0xb8, 0x6b, - 0x1c, 0x19, 0xc7, 0xdb, 0xee, 0xce, 0xd5, 0x8b, 0xc3, 0xc6, 0xfc, 0xc5, 0xe1, 0x86, 0xb4, 0x11, - 0x65, 0xc1, 0x5f, 0xa2, 0xcd, 0x21, 0xf5, 0x27, 0x10, 0x8f, 0xba, 0xcd, 0x23, 0xe3, 0xb8, 0x73, - 0x76, 0x62, 0xff, 0x67, 0x37, 0x6c, 0x0d, 0xef, 0xe6, 0x41, 0xee, 0x03, 0x8d, 0xb9, 0xa9, 0x2f, - 0xc8, 0x0d, 0x9c, 0x35, 0x41, 0xfb, 0x95, 0x72, 0x48, 0x16, 0xc1, 0x17, 0x34, 0xca, 0x00, 0x0f, - 0x50, 0x5b, 0x66, 0xe6, 0x5d, 0xe3, 0xa8, 0x75, 0xdc, 0x39, 0xb3, 0x5f, 0x92, 0x6f, 0x89, 0x92, - 0x7b, 0x5f, 0x27, 0x6c, 0xcb, 0x13, 0x27, 0x39, 0x96, 0xf5, 0x53, 0x13, 0x6d, 0x6a, 0x2f, 0xfc, - 0x18, 0x6d, 0xc9, 0x0e, 0x8e, 0xa8, 0xa0, 0x8a, 0x78, 0xe7, 0xec, 0xdd, 0x4a, 0x8e, 0x42, 0x50, - 0x3b, 0x9d, 0x04, 0xf2, 0x82, 0xdb, 0xd2, 0xdb, 0x9e, 0x9d, 0xda, 0x97, 0xc3, 0x6f, 0xc1, 0x17, - 0x9f, 0x82, 0xa0, 0x2e, 0xd6, 0x59, 0x50, 0x79, 0x47, 0x0a, 0x54, 0xdc, 0x43, 0x1b, 0x3c, 0x05, - 0x5f, 0x2b, 0xf6, 0x56, 0x3d, 0xc5, 0x06, 0x29, 0xf8, 0x65, 0x0b, 0xe4, 0x89, 0x28, 0x14, 0xec, - 0xa1, 0x7b, 0x5c, 0x50, 0x91, 0xf1, 0x6e, 0x4b, 0xe1, 0xbd, 0x53, 0x13, 0x4f, 0xc5, 0xb8, 0xbb, - 0x1a, 0xf1, 0x5e, 0x7e, 0x26, 0x1a, 0xcb, 0xfa, 0xcd, 0x40, 0xbb, 0x8b, 0xbd, 0xc2, 0xef, 0xa3, - 0x0e, 0x07, 0x36, 0x0b, 0x7d, 0xf8, 0x8c, 0x4e, 0x41, 0x0f, 0xc5, 0x6b, 0x3a, 0xbe, 0x33, 0x28, - 0x4d, 0xa4, 0xea, 0x87, 0x83, 0x22, 0xac, 0x9f, 0x30, 0xa1, 0x49, 0xaf, 0x97, 0x54, 0xce, 0xa8, - 0x9d, 0xcf, 0xa8, 0x7d, 0x11, 0x8b, 0x4b, 0x36, 0x10, 0x2c, 0x8c, 0x83, 0x95, 0x44, 0x12, 0x8c, - 0x54, 0x91, 0xad, 0xbf, 0x0c, 0xb4, 0xa3, 0x4b, 0x7e, 0x14, 0xd1, 0x3b, 0xe9, 0xe4, 0xe7, 0x0b, - 0x9d, 0x74, 0xea, 0x29, 0xaf, 0x8a, 0x5b, 0xd7, 0x4e, 0xeb, 0x4f, 0x03, 0xed, 0x55, 0x1d, 0x7b, - 0x21, 0x17, 0xf8, 0xeb, 0x15, 0x26, 0x76, 0x3d, 0x26, 0x32, 0x5a, 0xf1, 0xd8, 0xd3, 0xa9, 0xb6, - 0x6e, 0x6e, 0x2a, 0x2c, 0xfa, 0xa8, 0x1d, 0x0a, 0x98, 0xf2, 0x6e, 0x53, 0xfd, 0x52, 0x6f, 0xbf, - 0x02, 0x8d, 0xf2, 0x7f, 0xba, 0x90, 0x08, 0x24, 0x07, 0xb2, 0x7e, 0x59, 0x22, 0x21, 0xf9, 0xe1, - 0x33, 0x84, 0xfc, 0x24, 0x16, 0x2c, 0x89, 0x22, 0x60, 0x7a, 0x7c, 0x0a, 0x79, 0x1f, 0x15, 0x16, - 0x52, 0xf1, 0xc2, 0xdf, 0x20, 0x94, 0x52, 0x46, 0xa7, 0x20, 0x80, 0xf1, 0xdb, 0x56, 0x8c, 0x5c, - 0xd1, 0x92, 0xa8, 0xf7, 0x34, 0x85, 0x51, 0x2f, 0xf1, 0x69, 0x94, 0x37, 0x8a, 0xc0, 0x13, 0x60, - 0x10, 0xfb, 0xe0, 0xee, 0x4a, 0xf8, 0x7e, 0x01, 0x42, 0x2a, 0x80, 0xd6, 0xef, 0x06, 0xea, 0xe8, - 0x3a, 0xef, 0x40, 0xe7, 0x4f, 0x16, 0x75, 0x7e, 0xa3, 0xe6, 0xaa, 0xbc, 0x5d, 0xe2, 0x5f, 0xcb, - 0xd2, 0xe5, 0x72, 0x94, 0xbb, 0x7a, 0x9c, 0x70, 0xb1, 0xbc, 0xab, 0xcf, 0x13, 0x2e, 0x88, 0xb2, - 0xe0, 0x0c, 0xed, 0x85, 0x4b, 0xdb, 0xf4, 0xd5, 0x06, 0xb7, 0x08, 0x73, 0xbb, 0x1a, 0x7e, 0x6f, - 0xd9, 0x42, 0x56, 0x52, 0x58, 0x80, 0x56, 0xbc, 0xe4, 0x7f, 0x33, 0x16, 0x22, 0xd5, 0x1a, 0x3f, - 0xac, 0xbf, 0xc3, 0xcb, 0x12, 0xb6, 0x14, 0x3b, 0xcf, 0xeb, 0x13, 0x05, 0x65, 0xfd, 0xd1, 0x2c, - 0xf4, 0x50, 0xd3, 0xf6, 0x51, 0xc1, 0x56, 0x4d, 0xa0, 0x5a, 0x59, 0x1b, 0x4a, 0x9b, 0xfd, 0x4a, - 0xe1, 0x85, 0x8d, 0xac, 0x78, 0x63, 0xaf, 0x7c, 0xdb, 0x8c, 0xff, 0xf3, 0xb6, 0x75, 0x6e, 0x7b, - 0xd7, 0xf0, 0x39, 0x6a, 0x89, 0xe8, 0x66, 0x04, 0xde, 0xac, 0x87, 0xe8, 0xf5, 0x06, 0x6e, 0x47, - 0x4b, 0xde, 0xf2, 0x7a, 0x03, 0x22, 0x21, 0xf0, 0x25, 0x6a, 0xb3, 0x2c, 0x02, 0xb9, 0xf7, 0x5b, - 0xf5, 0xdf, 0x11, 0xa9, 0x60, 0x39, 0x52, 0xf2, 0xc4, 0x49, 0x8e, 0x63, 0x7d, 0x87, 0xee, 0x2f, - 0x3c, 0x0e, 0xf8, 0x31, 0xda, 0x89, 0x12, 0x3a, 0x72, 0x69, 0x44, 0x63, 0x5f, 0xff, 0xb3, 0x4b, - 0x73, 0x7b, 0xf3, 0xff, 0xf5, 0x2a, 0x7e, 0xfa, 0x69, 0xd9, 0xd7, 0x49, 0x76, 0xaa, 0x36, 0xb2, - 0x80, 0x68, 0x51, 0x84, 0x4a, 0x8e, 0xf8, 0x10, 0xb5, 0xe5, 0xa4, 0xe6, 0x6f, 0xfb, 0xb6, 0xbb, - 0x2d, 0x2b, 0x94, 0x03, 0xcc, 0x49, 0x7e, 0x2f, 0x57, 0x08, 0x07, 0x9f, 0x81, 0x50, 0xed, 0x6c, - 0x2e, 0xae, 0x90, 0x41, 0x61, 0x21, 0x15, 0x2f, 0xf7, 0xe4, 0xea, 0xda, 0x6c, 0x3c, 0xbb, 0x36, - 0x1b, 0xcf, 0xaf, 0xcd, 0xc6, 0x0f, 0x73, 0xd3, 0xb8, 0x9a, 0x9b, 0xc6, 0xb3, 0xb9, 0x69, 0x3c, - 0x9f, 0x9b, 0xc6, 0xdf, 0x73, 0xd3, 0xf8, 0xf9, 0x1f, 0xb3, 0xf1, 0xd5, 0xa6, 0x96, 0xe9, 0xdf, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0x2a, 0x50, 0x9d, 0x96, 0x0a, 0x00, 0x00, + 0x14, 0x8f, 0x93, 0x66, 0x9b, 0x4e, 0xba, 0xdd, 0x6a, 0xe8, 0x21, 0xaa, 0x84, 0x5b, 0xf9, 0x80, + 0xca, 0x9f, 0xda, 0x34, 0xbb, 0x20, 0x8e, 0xc8, 0x2b, 0xa1, 0x56, 0x04, 0x1a, 0x26, 0x16, 0x42, + 0x08, 0xa4, 0x9d, 0x38, 0x6f, 0x1d, 0x13, 0xc7, 0x36, 0x33, 0xe3, 0xa0, 0xbd, 0xf1, 0x0d, 0xe0, + 0x4b, 0xc0, 0x99, 0x23, 0x47, 0x04, 0x97, 0x1e, 0xf7, 0xb8, 0xa7, 0x8a, 0x86, 0x6f, 0xc1, 0x09, + 0xcd, 0x78, 0x6a, 0x3b, 0x49, 0xcb, 0x66, 0xf7, 0xd0, 0x53, 0x32, 0xf3, 0x7e, 0xef, 0xf7, 0xde, + 0xfb, 0xbd, 0xe7, 0x37, 0xe8, 0x93, 0xc9, 0x47, 0xdc, 0x0e, 0x13, 0x67, 0x92, 0x0d, 0x81, 0xc5, + 0x20, 0x80, 0x3b, 0x33, 0x88, 0x47, 0x09, 0x73, 0xb4, 0x81, 0xa6, 0xa1, 0x13, 0x83, 0xf8, 0x21, + 0x61, 0x93, 0x30, 0x0e, 0x9c, 0xd9, 0xc9, 0x10, 0x04, 0x3d, 0x71, 0x02, 0x88, 0x81, 0x51, 0x01, + 0x23, 0x3b, 0x65, 0x89, 0x48, 0xf0, 0x9b, 0x39, 0xdc, 0xa6, 0x69, 0x68, 0x97, 0x70, 0x5b, 0xc3, + 0xf7, 0x8f, 0x83, 0x50, 0x8c, 0xb3, 0xa1, 0xed, 0x27, 0x53, 0x27, 0x48, 0x82, 0xc4, 0x51, 0x5e, + 0xc3, 0xec, 0xa9, 0x3a, 0xa9, 0x83, 0xfa, 0x97, 0xb3, 0xed, 0x5b, 0x95, 0xe0, 0x7e, 0xc2, 0xc0, + 0x99, 0xad, 0x44, 0xdc, 0x7f, 0x54, 0x62, 0xa6, 0xd4, 0x1f, 0x87, 0x31, 0xb0, 0x67, 0x4e, 0x3a, + 0x09, 0xe4, 0x05, 0x77, 0xa6, 0x20, 0xe8, 0x4d, 0x5e, 0xce, 0x6d, 0x5e, 0x2c, 0x8b, 0x45, 0x38, + 0x85, 0x15, 0x87, 0x0f, 0x5f, 0xe6, 0xc0, 0xfd, 0x31, 0x4c, 0xe9, 0x8a, 0xdf, 0xc3, 0xdb, 0xfc, + 0x32, 0x11, 0x46, 0x4e, 0x18, 0x0b, 0x2e, 0xd8, 0xb2, 0x93, 0xf5, 0x97, 0x81, 0x1e, 0x9c, 0x7a, + 0x5e, 0xff, 0x2c, 0x0e, 0x18, 0x70, 0xde, 0xa7, 0x62, 0x8c, 0x0f, 0xd1, 0x46, 0x4a, 0xc5, 0xb8, + 0x63, 0x1c, 0x1a, 0x47, 0x5b, 0xee, 0xf6, 0xc5, 0xe5, 0x41, 0x6d, 0x7e, 0x79, 0xb0, 0x21, 0x6d, + 0x44, 0x59, 0xf0, 0x23, 0xd4, 0x92, 0xbf, 0xde, 0xb3, 0x14, 0x3a, 0x0d, 0x85, 0xea, 0xcc, 0x2f, + 0x0f, 0x5a, 0x7d, 0x7d, 0xf7, 0x6f, 0xe5, 0x3f, 0x29, 0x90, 0xf8, 0x2b, 0xb4, 0x39, 0xa4, 0xfe, + 0x04, 0xe2, 0x51, 0xa7, 0x7e, 0x68, 0x1c, 0xb5, 0xbb, 0xc7, 0xf6, 0xff, 0xf6, 0xd0, 0xd6, 0x49, + 0xb9, 0xb9, 0x93, 0xfb, 0x40, 0x67, 0xb2, 0xa9, 0x2f, 0xc8, 0x35, 0x9d, 0x35, 0x41, 0x7b, 0x95, + 0x22, 0x48, 0x16, 0xc1, 0x97, 0x34, 0xca, 0x00, 0x0f, 0x50, 0x53, 0x46, 0xe7, 0x1d, 0xe3, 0xb0, + 0x71, 0xd4, 0xee, 0xda, 0x2f, 0x89, 0xb7, 0x24, 0x84, 0x7b, 0x5f, 0x07, 0x6c, 0xca, 0x13, 0x27, + 0x39, 0x97, 0xf5, 0x53, 0x1d, 0x6d, 0x6a, 0x14, 0x7e, 0x82, 0x5a, 0xb2, 0xef, 0x23, 0x2a, 0xa8, + 0x92, 0xab, 0xdd, 0x7d, 0xbf, 0x12, 0xa3, 0x68, 0x83, 0x9d, 0x4e, 0x02, 0x79, 0xc1, 0x6d, 0x89, + 0xb6, 0x67, 0x27, 0xf6, 0xf9, 0xf0, 0x3b, 0xf0, 0xc5, 0x67, 0x20, 0xa8, 0x8b, 0x75, 0x14, 0x54, + 0xde, 0x91, 0x82, 0x15, 0xf7, 0xd0, 0x06, 0x4f, 0xc1, 0xd7, 0x8a, 0xbd, 0xb3, 0x9e, 0x62, 0x83, + 0x14, 0xfc, 0xb2, 0x71, 0xf2, 0x44, 0x14, 0x0b, 0xf6, 0xd0, 0x3d, 0x2e, 0xa8, 0xc8, 0xb8, 0x6a, + 0x5b, 0xbb, 0xfb, 0xde, 0x9a, 0x7c, 0xca, 0xc7, 0xdd, 0xd1, 0x8c, 0xf7, 0xf2, 0x33, 0xd1, 0x5c, + 0xd6, 0x6f, 0x06, 0xda, 0x59, 0xec, 0x15, 0xfe, 0x00, 0xb5, 0x39, 0xb0, 0x59, 0xe8, 0xc3, 0xe7, + 0x74, 0x0a, 0x7a, 0x94, 0xde, 0xd0, 0xfe, 0xed, 0x41, 0x69, 0x22, 0x55, 0x1c, 0x0e, 0x0a, 0xb7, + 0x7e, 0xc2, 0x84, 0x2e, 0xfa, 0x76, 0x49, 0xe5, 0x64, 0xdb, 0xf9, 0x64, 0xdb, 0x67, 0xb1, 0x38, + 0x67, 0x03, 0xc1, 0xc2, 0x38, 0x58, 0x09, 0x24, 0xc9, 0x48, 0x95, 0x59, 0xce, 0xfd, 0xb6, 0x4e, + 0xf9, 0x71, 0x44, 0xef, 0xa4, 0x93, 0x5f, 0x2c, 0x74, 0xd2, 0x59, 0x4f, 0x79, 0x95, 0xdc, 0x6d, + 0xed, 0xb4, 0xfe, 0x34, 0xd0, 0x6e, 0x15, 0xd8, 0x0b, 0xb9, 0xc0, 0xdf, 0xac, 0x54, 0x62, 0xaf, + 0x57, 0x89, 0xf4, 0x56, 0x75, 0xec, 0xea, 0x50, 0xad, 0xeb, 0x9b, 0x4a, 0x15, 0x7d, 0xd4, 0x0c, + 0x05, 0x4c, 0x79, 0xa7, 0xae, 0x3e, 0xa9, 0x77, 0x5f, 0xa1, 0x8c, 0xf2, 0x7b, 0x3a, 0x93, 0x0c, + 0x24, 0x27, 0xb2, 0x7e, 0x59, 0x2a, 0x42, 0xd6, 0x87, 0xbb, 0x08, 0xf9, 0x49, 0x2c, 0x58, 0x12, + 0x45, 0xc0, 0xf4, 0xf8, 0x14, 0xf2, 0x3e, 0x2e, 0x2c, 0xa4, 0x82, 0xc2, 0xdf, 0x22, 0x94, 0x52, + 0x46, 0xa7, 0x20, 0x80, 0xf1, 0x9b, 0x56, 0x8c, 0x5c, 0xec, 0xb2, 0x50, 0xb9, 0x8d, 0x46, 0xbd, + 0xc4, 0xa7, 0x51, 0xde, 0x28, 0x02, 0x4f, 0x81, 0x41, 0xec, 0x83, 0xbb, 0x23, 0xe9, 0xfb, 0x05, + 0x09, 0xa9, 0x10, 0x5a, 0xbf, 0x1b, 0xa8, 0xad, 0xf3, 0xbc, 0x03, 0x9d, 0x3f, 0x5d, 0xd4, 0xf9, + 0xad, 0x35, 0x57, 0xe5, 0xcd, 0x12, 0xff, 0x5a, 0xa6, 0x2e, 0x97, 0xa3, 0xdc, 0xf0, 0xe3, 0x84, + 0x8b, 0xe5, 0x0d, 0x7f, 0x9a, 0x70, 0x41, 0x94, 0x05, 0x67, 0x68, 0x37, 0x5c, 0xda, 0xa6, 0xaf, + 0x36, 0xb8, 0x85, 0x9b, 0xdb, 0xd1, 0xf4, 0xbb, 0xcb, 0x16, 0xb2, 0x12, 0xc2, 0x02, 0xb4, 0x82, + 0x92, 0xdf, 0xcd, 0x58, 0x88, 0x54, 0x6b, 0xfc, 0x70, 0xfd, 0x1d, 0x5e, 0xa6, 0xd0, 0x52, 0xd5, + 0x79, 0x5e, 0x9f, 0x28, 0x2a, 0xeb, 0x8f, 0x7a, 0xa1, 0x87, 0x9a, 0xb6, 0x8f, 0x8b, 0x6a, 0xd5, + 0x04, 0xaa, 0x95, 0xb5, 0xa1, 0xb4, 0xd9, 0xab, 0x24, 0x5e, 0xd8, 0xc8, 0x0a, 0x1a, 0x7b, 0xe5, + 0xdb, 0x66, 0xbc, 0xce, 0xdb, 0xd6, 0xbe, 0xe9, 0x5d, 0xc3, 0xa7, 0xa8, 0x21, 0xa2, 0xeb, 0x11, + 0x78, 0x7b, 0x3d, 0x46, 0xaf, 0x37, 0x70, 0xdb, 0x5a, 0xf2, 0x86, 0xd7, 0x1b, 0x10, 0x49, 0x81, + 0xcf, 0x51, 0x93, 0x65, 0x11, 0xc8, 0xbd, 0xdf, 0x58, 0xff, 0x1d, 0x91, 0x0a, 0x96, 0x23, 0x25, + 0x4f, 0x9c, 0xe4, 0x3c, 0xd6, 0xf7, 0xe8, 0xfe, 0xc2, 0xe3, 0x80, 0x9f, 0xa0, 0xed, 0x28, 0xa1, + 0x23, 0x97, 0x46, 0x34, 0xf6, 0xf5, 0x37, 0xbb, 0x34, 0xb7, 0xd7, 0xdf, 0x5f, 0xaf, 0x82, 0xd3, + 0x4f, 0xcb, 0x9e, 0x0e, 0xb2, 0x5d, 0xb5, 0x91, 0x05, 0x46, 0x8b, 0x22, 0x54, 0xd6, 0x88, 0x0f, + 0x50, 0x53, 0x4e, 0x6a, 0xfe, 0xb6, 0x6f, 0xb9, 0x5b, 0x32, 0x43, 0x39, 0xc0, 0x9c, 0xe4, 0xf7, + 0x72, 0x85, 0x70, 0xf0, 0x19, 0x08, 0xd5, 0xce, 0xfa, 0xe2, 0x0a, 0x19, 0x14, 0x16, 0x52, 0x41, + 0xb9, 0xc7, 0x17, 0x57, 0x66, 0xed, 0xf9, 0x95, 0x59, 0x7b, 0x71, 0x65, 0xd6, 0x7e, 0x9c, 0x9b, + 0xc6, 0xc5, 0xdc, 0x34, 0x9e, 0xcf, 0x4d, 0xe3, 0xc5, 0xdc, 0x34, 0xfe, 0x9e, 0x9b, 0xc6, 0xcf, + 0xff, 0x98, 0xb5, 0xaf, 0x37, 0xb5, 0x4c, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x12, 0x75, + 0x26, 0xcc, 0x0a, 0x00, 0x00, } func (m *HTTPIngressPath) Marshal() (dAtA []byte, err error) { @@ -511,6 +513,13 @@ func (m *HTTPIngressPath) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PathType != nil { + i -= len(*m.PathType) + copy(dAtA[i:], *m.PathType) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.PathType))) + i-- + dAtA[i] = 0x1a + } { size, err := m.Backend.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -1068,6 +1077,10 @@ func (m *HTTPIngressPath) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = m.Backend.Size() n += 1 + l + sovGenerated(uint64(l)) + if m.PathType != nil { + l = len(*m.PathType) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -1272,6 +1285,7 @@ func (this *HTTPIngressPath) String() string { s := strings.Join([]string{`&HTTPIngressPath{`, `Path:` + fmt.Sprintf("%v", this.Path) + `,`, `Backend:` + strings.Replace(strings.Replace(this.Backend.String(), "IngressBackend", "IngressBackend", 1), `&`, ``, 1) + `,`, + `PathType:` + valueToStringGenerated(this.PathType) + `,`, `}`, }, "") return s @@ -1535,6 +1549,39 @@ func (m *HTTPIngressPath) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PathType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := PathType(dAtA[iNdEx:postIndex]) + m.PathType = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/api/networking/v1beta1/generated.proto b/staging/src/k8s.io/api/networking/v1beta1/generated.proto index 30a96c31d81..c51395c3361 100644 --- a/staging/src/k8s.io/api/networking/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/networking/v1beta1/generated.proto @@ -30,19 +30,33 @@ import "k8s.io/apimachinery/pkg/util/intstr/generated.proto"; // Package-wide variables from generator "generated". option go_package = "v1beta1"; -// HTTPIngressPath associates a path regex with a backend. Incoming urls matching -// the path are forwarded to the backend. +// HTTPIngressPath associates a path with a backend. Incoming urls matching the +// path are forwarded to the backend. message HTTPIngressPath { - // Path is an extended POSIX regex as defined by IEEE Std 1003.1, - // (i.e this follows the egrep/unix syntax, not the perl syntax) - // matched against the path of an incoming request. Currently it can - // contain characters disallowed from the conventional "path" - // part of a URL as defined by RFC 3986. Paths must begin with - // a '/'. If unspecified, the path defaults to a catch all sending - // traffic to the backend. + // Path is matched against the path of an incoming request. Currently it can + // contain characters disallowed from the conventional "path" part of a URL + // as defined by RFC 3986. Paths must begin with a '/'. When unspecified, + // all paths from incoming requests are matched. // +optional optional string path = 1; + // PathType determines the interpretation of the Path matching. PathType can + // be one of the following values: + // * Exact: Matches the URL path exactly. + // * Prefix: Matches based on a URL path prefix split by '/'. Matching is + // done on a path element by element basis. A path element refers is the + // list of labels in the path split by the '/' separator. A request is a + // match for path p if every p is an element-wise prefix of p of the + // request path. Note that if the last element of the path is a substring + // of the last element in request path, it is not a match (e.g. /foo/bar + // matches /foo/bar/baz, but does not match /foo/barbaz). + // * ImplementationSpecific: Interpretation of the Path matching is up to + // the IngressClass. Implementations can treat this as a separate PathType + // or treat it identically to Prefix or Exact path types. + // Implementations are required to support all path types. + // Defaults to ImplementationSpecific. + optional string pathType = 3; + // Backend defines the referenced service endpoint to which the traffic // will be forwarded to. optional IngressBackend backend = 2; diff --git a/staging/src/k8s.io/api/networking/v1beta1/types.go b/staging/src/k8s.io/api/networking/v1beta1/types.go index d66d10ed029..80a6829704e 100644 --- a/staging/src/k8s.io/api/networking/v1beta1/types.go +++ b/staging/src/k8s.io/api/networking/v1beta1/types.go @@ -177,19 +177,63 @@ type HTTPIngressRuleValue struct { // options usable by a loadbalancer, like http keep-alive. } -// HTTPIngressPath associates a path regex with a backend. Incoming urls matching -// the path are forwarded to the backend. +// PathType represents the type of path referred to by a HTTPIngressPath. +type PathType string + +const ( + // PathTypeExact matches the URL path exactly and with case sensitivity. + PathTypeExact = PathType("Exact") + + // PathTypePrefix matches based on a URL path prefix split by '/'. Matching + // is case sensitive and done on a path element by element basis. A path + // element refers to the list of labels in the path split by the '/' + // separator. A request is a match for path p if every p is an element-wise + // prefix of p of the request path. Note that if the last element of the + // path is a substring of the last element in request path, it is not a + // match (e.g. /foo/bar matches /foo/bar/baz, but does not match + // /foo/barbaz). If multiple matching paths exist in an Ingress spec, the + // longest matching path is given priority. + // Examples: + // - /foo/bar does not match requests to /foo/barbaz + // - /foo/bar matches request to /foo/bar and /foo/bar/baz + // - /foo and /foo/ both match requests to /foo and /foo/. If both paths are + // present in an Ingress spec, the longest matching path (/foo/) is given + // priority. + PathTypePrefix = PathType("Prefix") + + // PathTypeImplementationSpecific matching is up to the IngressClass. + // Implementations can treat this as a separate PathType or treat it + // identically to Prefix or Exact path types. + PathTypeImplementationSpecific = PathType("ImplementationSpecific") +) + +// HTTPIngressPath associates a path with a backend. Incoming urls matching the +// path are forwarded to the backend. type HTTPIngressPath struct { - // Path is an extended POSIX regex as defined by IEEE Std 1003.1, - // (i.e this follows the egrep/unix syntax, not the perl syntax) - // matched against the path of an incoming request. Currently it can - // contain characters disallowed from the conventional "path" - // part of a URL as defined by RFC 3986. Paths must begin with - // a '/'. If unspecified, the path defaults to a catch all sending - // traffic to the backend. + // Path is matched against the path of an incoming request. Currently it can + // contain characters disallowed from the conventional "path" part of a URL + // as defined by RFC 3986. Paths must begin with a '/'. When unspecified, + // all paths from incoming requests are matched. // +optional Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"` + // PathType determines the interpretation of the Path matching. PathType can + // be one of the following values: + // * Exact: Matches the URL path exactly. + // * Prefix: Matches based on a URL path prefix split by '/'. Matching is + // done on a path element by element basis. A path element refers is the + // list of labels in the path split by the '/' separator. A request is a + // match for path p if every p is an element-wise prefix of p of the + // request path. Note that if the last element of the path is a substring + // of the last element in request path, it is not a match (e.g. /foo/bar + // matches /foo/bar/baz, but does not match /foo/barbaz). + // * ImplementationSpecific: Interpretation of the Path matching is up to + // the IngressClass. Implementations can treat this as a separate PathType + // or treat it identically to Prefix or Exact path types. + // Implementations are required to support all path types. + // Defaults to ImplementationSpecific. + PathType *PathType `json:"pathType,omitempty" protobuf:"bytes,3,opt,name=pathType"` + // Backend defines the referenced service endpoint to which the traffic // will be forwarded to. Backend IngressBackend `json:"backend" protobuf:"bytes,2,opt,name=backend"` diff --git a/staging/src/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go index a32a19a8703..b0dbbf14d5d 100644 --- a/staging/src/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go @@ -28,9 +28,10 @@ package v1beta1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_HTTPIngressPath = map[string]string{ - "": "HTTPIngressPath associates a path regex with a backend. Incoming urls matching the path are forwarded to the backend.", - "path": "Path is an extended POSIX regex as defined by IEEE Std 1003.1, (i.e this follows the egrep/unix syntax, not the perl syntax) matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. If unspecified, the path defaults to a catch all sending traffic to the backend.", - "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", + "": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", + "path": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. When unspecified, all paths from incoming requests are matched.", + "pathType": "PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types. Defaults to ImplementationSpecific.", + "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", } func (HTTPIngressPath) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/api/networking/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/networking/v1beta1/zz_generated.deepcopy.go index ca282c594f2..c44704f9e96 100644 --- a/staging/src/k8s.io/api/networking/v1beta1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/api/networking/v1beta1/zz_generated.deepcopy.go @@ -28,6 +28,11 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPIngressPath) DeepCopyInto(out *HTTPIngressPath) { *out = *in + if in.PathType != nil { + in, out := &in.PathType, &out.PathType + *out = new(PathType) + **out = **in + } out.Backend = in.Backend return } @@ -48,7 +53,9 @@ func (in *HTTPIngressRuleValue) DeepCopyInto(out *HTTPIngressRuleValue) { if in.Paths != nil { in, out := &in.Paths, &out.Paths *out = make([]HTTPIngressPath, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } diff --git a/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.json b/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.json index 155f4e0ece5..09d35dc974e 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.json +++ b/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.json @@ -61,9 +61,10 @@ "paths": [ { "path": "25", + "pathType": "", "backend": { "serviceName": "26", - "servicePort": "27" + "servicePort": -783752440 } } ] @@ -75,8 +76,8 @@ "loadBalancer": { "ingress": [ { - "ip": "28", - "hostname": "29" + "ip": "27", + "hostname": "28" } ] } diff --git a/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.pb b/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.pb index 9d28c04a029..4f3a477b7ec 100644 Binary files a/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.pb and b/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.pb differ diff --git a/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.yaml b/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.yaml index 191a18c10bf..6281cb0816e 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/extensions.v1beta1.Ingress.yaml @@ -40,8 +40,9 @@ spec: paths: - backend: serviceName: "26" - servicePort: "27" + servicePort: -783752440 path: "25" + pathType: "" tls: - hosts: - "22" @@ -49,5 +50,5 @@ spec: status: loadBalancer: ingress: - - hostname: "29" - ip: "28" + - hostname: "28" + ip: "27" diff --git a/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.json b/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.json index 0a8e35fa1c3..ae2283e9e8c 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.json +++ b/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.json @@ -61,9 +61,10 @@ "paths": [ { "path": "25", + "pathType": "", "backend": { "serviceName": "26", - "servicePort": "27" + "servicePort": -783752440 } } ] @@ -75,8 +76,8 @@ "loadBalancer": { "ingress": [ { - "ip": "28", - "hostname": "29" + "ip": "27", + "hostname": "28" } ] } diff --git a/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.pb b/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.pb index f361c8da74a..dbcbe014d46 100644 Binary files a/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.pb and b/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.pb differ diff --git a/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.yaml b/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.yaml index e9e88ea55be..a5066a5a475 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/networking.k8s.io.v1beta1.Ingress.yaml @@ -40,8 +40,9 @@ spec: paths: - backend: serviceName: "26" - servicePort: "27" + servicePort: -783752440 path: "25" + pathType: "" tls: - hosts: - "22" @@ -49,5 +50,5 @@ spec: status: loadBalancer: ingress: - - hostname: "29" - ip: "28" + - hostname: "28" + ip: "27"