mirror of https://github.com/k3s-io/k3s
Merge pull request #74998 from mbohlool/pippin
Webhook configurations can choose which version of Review request they acceptpull/564/head
commit
e318642946
|
@ -201,6 +201,13 @@
|
|||
"io.k8s.api.admissionregistration.v1beta1.Webhook": {
|
||||
"description": "Webhook describes an admission webhook and the resources and operations it applies to.",
|
||||
"properties": {
|
||||
"admissionReviewVersions": {
|
||||
"description": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"clientConfig": {
|
||||
"$ref": "#/definitions/io.k8s.api.admissionregistration.v1beta1.WebhookClientConfig",
|
||||
"description": "ClientConfig defines how to communicate with the hook. Required"
|
||||
|
@ -16161,6 +16168,13 @@
|
|||
"io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceConversion": {
|
||||
"description": "CustomResourceConversion describes how to convert different versions of a CR.",
|
||||
"properties": {
|
||||
"conversionReviewVersions": {
|
||||
"description": "ConversionReviewVersions is an ordered list of preferred `ConversionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, conversion will fail for this object. If a persisted Webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail. Default to `['v1beta1']`.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"strategy": {
|
||||
"description": "`strategy` specifies the conversion strategy. Allowed values are: - `None`: The converter only change the apiVersion and would not touch any other field in the CR. - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option.",
|
||||
"type": "string"
|
||||
|
|
|
@ -43,6 +43,7 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
|||
i := int32(30)
|
||||
obj.TimeoutSeconds = &i
|
||||
}
|
||||
obj.AdmissionReviewVersions = []string{"v1beta1"}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,6 +239,15 @@ type Webhook struct {
|
|||
// The timeout value must be between 1 and 30 seconds.
|
||||
// +optional
|
||||
TimeoutSeconds *int32
|
||||
|
||||
// AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
|
||||
// versions the Webhook expects. API server will try to use first version in
|
||||
// the list which it supports. If none of the versions specified in this list
|
||||
// supported by API server, validation will fail for this object.
|
||||
// If the webhook configuration has already been persisted with a version apiserver
|
||||
// does not understand, calls to the webhook will fail and be subject to the failure policy.
|
||||
// +optional
|
||||
AdmissionReviewVersions []string
|
||||
}
|
||||
|
||||
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
|
||||
|
|
|
@ -44,6 +44,10 @@ func SetDefaults_Webhook(obj *admissionregistrationv1beta1.Webhook) {
|
|||
obj.TimeoutSeconds = new(int32)
|
||||
*obj.TimeoutSeconds = 30
|
||||
}
|
||||
|
||||
if len(obj.AdmissionReviewVersions) == 0 {
|
||||
obj.AdmissionReviewVersions = []string{admissionregistrationv1beta1.SchemeGroupVersion.Version}
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_Rule(obj *admissionregistrationv1beta1.Rule) {
|
||||
|
|
|
@ -304,6 +304,7 @@ func autoConvert_v1beta1_Webhook_To_admissionregistration_Webhook(in *v1beta1.We
|
|||
out.NamespaceSelector = (*v1.LabelSelector)(unsafe.Pointer(in.NamespaceSelector))
|
||||
out.SideEffects = (*admissionregistration.SideEffectClass)(unsafe.Pointer(in.SideEffects))
|
||||
out.TimeoutSeconds = (*int32)(unsafe.Pointer(in.TimeoutSeconds))
|
||||
out.AdmissionReviewVersions = *(*[]string)(unsafe.Pointer(&in.AdmissionReviewVersions))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -322,6 +323,7 @@ func autoConvert_admissionregistration_Webhook_To_v1beta1_Webhook(in *admissionr
|
|||
out.NamespaceSelector = (*v1.LabelSelector)(unsafe.Pointer(in.NamespaceSelector))
|
||||
out.SideEffects = (*v1beta1.SideEffectClass)(unsafe.Pointer(in.SideEffects))
|
||||
out.TimeoutSeconds = (*int32)(unsafe.Pointer(in.TimeoutSeconds))
|
||||
out.AdmissionReviewVersions = *(*[]string)(unsafe.Pointer(&in.AdmissionReviewVersions))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ go_library(
|
|||
importpath = "k8s.io/kubernetes/pkg/apis/admissionregistration/validation",
|
||||
deps = [
|
||||
"//pkg/apis/admissionregistration:go_default_library",
|
||||
"//pkg/apis/admissionregistration/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
|
|
|
@ -24,9 +24,11 @@ import (
|
|||
metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/apiserver/pkg/util/webhook"
|
||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||
"k8s.io/kubernetes/pkg/apis/admissionregistration/v1beta1"
|
||||
)
|
||||
|
||||
func hasWildcard(slice []string) bool {
|
||||
|
@ -150,18 +152,71 @@ func validateRule(rule *admissionregistration.Rule, fldPath *field.Path, allowSu
|
|||
return allErrors
|
||||
}
|
||||
|
||||
var AcceptedAdmissionReviewVersions = []string{v1beta1.SchemeGroupVersion.Version}
|
||||
|
||||
func isAcceptedAdmissionReviewVersion(v string) bool {
|
||||
for _, version := range AcceptedAdmissionReviewVersions {
|
||||
if v == version {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func validateAdmissionReviewVersions(versions []string, requireRecognizedVersion bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrors := field.ErrorList{}
|
||||
|
||||
// Currently only v1beta1 accepted in AdmissionReviewVersions
|
||||
if len(versions) < 1 {
|
||||
allErrors = append(allErrors, field.Required(fldPath, ""))
|
||||
} else {
|
||||
seen := map[string]bool{}
|
||||
hasAcceptedVersion := false
|
||||
for i, v := range versions {
|
||||
if seen[v] {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath.Index(i), v, "duplicate version"))
|
||||
continue
|
||||
}
|
||||
seen[v] = true
|
||||
for _, errString := range utilvalidation.IsDNS1035Label(v) {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath.Index(i), v, errString))
|
||||
}
|
||||
if isAcceptedAdmissionReviewVersion(v) {
|
||||
hasAcceptedVersion = true
|
||||
}
|
||||
}
|
||||
if requireRecognizedVersion && !hasAcceptedVersion {
|
||||
allErrors = append(allErrors, field.Invalid(
|
||||
fldPath, versions,
|
||||
fmt.Sprintf("none of the versions accepted by this server. accepted version(s) are %v",
|
||||
strings.Join(AcceptedAdmissionReviewVersions, ", "))))
|
||||
}
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func ValidateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
||||
return validateValidatingWebhookConfiguration(e, true)
|
||||
}
|
||||
|
||||
func validateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration, requireRecognizedVersion bool) field.ErrorList {
|
||||
allErrors := genericvalidation.ValidateObjectMeta(&e.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
||||
for i, hook := range e.Webhooks {
|
||||
allErrors = append(allErrors, validateWebhook(&hook, field.NewPath("webhooks").Index(i))...)
|
||||
allErrors = append(allErrors, validateAdmissionReviewVersions(hook.AdmissionReviewVersions, requireRecognizedVersion, field.NewPath("webhooks").Index(i).Child("admissionReviewVersions"))...)
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func ValidateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
||||
return validateMutatingWebhookConfiguration(e, true)
|
||||
}
|
||||
|
||||
func validateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration, requireRecognizedVersion bool) field.ErrorList {
|
||||
allErrors := genericvalidation.ValidateObjectMeta(&e.ObjectMeta, false, genericvalidation.NameIsDNSSubdomain, field.NewPath("metadata"))
|
||||
for i, hook := range e.Webhooks {
|
||||
allErrors = append(allErrors, validateWebhook(&hook, field.NewPath("webhooks").Index(i))...)
|
||||
allErrors = append(allErrors, validateAdmissionReviewVersions(hook.AdmissionReviewVersions, requireRecognizedVersion, field.NewPath("webhooks").Index(i).Child("admissionReviewVersions"))...)
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
@ -247,10 +302,28 @@ func validateRuleWithOperations(ruleWithOperations *admissionregistration.RuleWi
|
|||
return allErrors
|
||||
}
|
||||
|
||||
// hasAcceptedAdmissionReviewVersions returns true if all webhooks have at least one
|
||||
// admission review version this apiserver accepts.
|
||||
func hasAcceptedAdmissionReviewVersions(webhooks []admissionregistration.Webhook) bool {
|
||||
for _, hook := range webhooks {
|
||||
hasRecognizedVersion := false
|
||||
for _, version := range hook.AdmissionReviewVersions {
|
||||
if isAcceptedAdmissionReviewVersion(version) {
|
||||
hasRecognizedVersion = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasRecognizedVersion && len(hook.AdmissionReviewVersions) > 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ValidateValidatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList {
|
||||
return ValidateValidatingWebhookConfiguration(newC)
|
||||
return validateValidatingWebhookConfiguration(newC, hasAcceptedAdmissionReviewVersions(oldC.Webhooks))
|
||||
}
|
||||
|
||||
func ValidateMutatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.MutatingWebhookConfiguration) field.ErrorList {
|
||||
return ValidateMutatingWebhookConfiguration(newC)
|
||||
return validateMutatingWebhookConfiguration(newC, hasAcceptedAdmissionReviewVersions(oldC.Webhooks))
|
||||
}
|
||||
|
|
|
@ -28,7 +28,14 @@ func strPtr(s string) *string { return &s }
|
|||
|
||||
func int32Ptr(i int32) *int32 { return &i }
|
||||
|
||||
func newValidatingWebhookConfiguration(hooks []admissionregistration.Webhook) *admissionregistration.ValidatingWebhookConfiguration {
|
||||
func newValidatingWebhookConfiguration(hooks []admissionregistration.Webhook, defaultAdmissionReviewVersions bool) *admissionregistration.ValidatingWebhookConfiguration {
|
||||
// If the test case did not specify an AdmissionReviewVersions, default it so the test passes as
|
||||
// this field will be defaulted in production code.
|
||||
for i := range hooks {
|
||||
if defaultAdmissionReviewVersions && len(hooks[i].AdmissionReviewVersions) == 0 {
|
||||
hooks[i].AdmissionReviewVersions = []string{"v1beta1"}
|
||||
}
|
||||
}
|
||||
return &admissionregistration.ValidatingWebhookConfiguration{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "config",
|
||||
|
@ -48,10 +55,64 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
config *admissionregistration.ValidatingWebhookConfiguration
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "should fail on bad AdmissionReviewVersion value",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"0v"},
|
||||
},
|
||||
}, true),
|
||||
expectedError: `Invalid value: "0v": a DNS-1035 label`,
|
||||
},
|
||||
{
|
||||
name: "should pass on valid AdmissionReviewVersion",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
},
|
||||
}, true),
|
||||
expectedError: ``,
|
||||
},
|
||||
{
|
||||
name: "should pass on mix of accepted and unaccepted AdmissionReviewVersion",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"v1beta1", "invalid-version"},
|
||||
},
|
||||
}, true),
|
||||
expectedError: ``,
|
||||
},
|
||||
{
|
||||
name: "should fail on invalid AdmissionReviewVersion",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"invalidVersion"},
|
||||
},
|
||||
}, true),
|
||||
expectedError: `Invalid value: []string{"invalidVersion"}`,
|
||||
},
|
||||
{
|
||||
name: "should fail on duplicate AdmissionReviewVersion",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"v1beta1", "v1beta1"},
|
||||
},
|
||||
}, true),
|
||||
expectedError: `Invalid value: "v1beta1": duplicate version`,
|
||||
},
|
||||
{
|
||||
name: "all Webhooks must have a fully qualified name",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -64,13 +125,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
Name: "",
|
||||
ClientConfig: validClientConfig,
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[1].name: Invalid value: "k8s.io": should be a domain with at least three segments separated by dots, webhooks[2].name: Required value`,
|
||||
},
|
||||
{
|
||||
name: "Operations must not be empty or nil",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -92,13 +152,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].rules[0].operations: Required value, webhooks[0].rules[1].operations: Required value`,
|
||||
},
|
||||
{
|
||||
name: "\"\" is NOT a valid operation",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -112,13 +171,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `Unsupported value: ""`,
|
||||
},
|
||||
{
|
||||
name: "operation must be either create/update/delete/connect",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -132,13 +190,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `Unsupported value: "PATCH"`,
|
||||
},
|
||||
{
|
||||
name: "wildcard operation cannot be mixed with other strings",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
Rules: []admissionregistration.RuleWithOperations{
|
||||
|
@ -152,13 +209,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `if '*' is present, must not specify other operations`,
|
||||
},
|
||||
{
|
||||
name: `resource "*" can co-exist with resources that have subresources`,
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -173,12 +229,11 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
},
|
||||
{
|
||||
name: `resource "*" cannot mix with resources that don't have subresources`,
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -193,13 +248,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `if '*' is present, must not specify other resources without subresources`,
|
||||
},
|
||||
{
|
||||
name: "resource a/* cannot mix with a/x",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -214,13 +268,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].rules[0].resources[1]: Invalid value: "a/x": if 'a/*' is present, must not specify a/x`,
|
||||
},
|
||||
{
|
||||
name: "resource a/* can mix with a",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -235,12 +288,11 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
},
|
||||
{
|
||||
name: "resource */a cannot mix with x/a",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -255,13 +307,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].rules[0].resources[1]: Invalid value: "x/a": if '*/a' is present, must not specify x/a`,
|
||||
},
|
||||
{
|
||||
name: "resource */* cannot mix with other resources",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -276,13 +327,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].rules[0].resources: Invalid value: []string{"*/*", "a"}: if '*/*' is present, must not specify other resources`,
|
||||
},
|
||||
{
|
||||
name: "FailurePolicy can only be \"Ignore\" or \"Fail\"",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -291,13 +341,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
return &r
|
||||
}(),
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].failurePolicy: Unsupported value: "other": supported values: "Fail", "Ignore"`,
|
||||
},
|
||||
{
|
||||
name: "SideEffects can only be \"Unknown\", \"None\", \"Some\", or \"NoneOnDryRun\"",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -306,24 +355,22 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
return &r
|
||||
}(),
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].sideEffects: Unsupported value: "other": supported values: "None", "NoneOnDryRun", "Some", "Unknown"`,
|
||||
},
|
||||
{
|
||||
name: "both service and URL missing",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `exactly one of`,
|
||||
},
|
||||
{
|
||||
name: "both service and URL provided",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
|
@ -334,104 +381,96 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
URL: strPtr("example.com/k8s/webhook"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `[0].clientConfig: Required value: exactly one of url or service is required`,
|
||||
},
|
||||
{
|
||||
name: "blank URL",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URL: strPtr(""),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `[0].clientConfig.url: Invalid value: "": host must be provided`,
|
||||
},
|
||||
{
|
||||
name: "wrong scheme",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URL: strPtr("http://example.com"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `https`,
|
||||
},
|
||||
{
|
||||
name: "missing host",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URL: strPtr("https:///fancy/webhook"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `host must be provided`,
|
||||
},
|
||||
{
|
||||
name: "fragment",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/#bookmark"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `"bookmark": fragments are not permitted`,
|
||||
},
|
||||
{
|
||||
name: "query",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com?arg=value"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `"arg=value": query parameters are not permitted`,
|
||||
},
|
||||
{
|
||||
name: "user",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URL: strPtr("https://harry.potter@example.com/"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `"harry.potter": user information is not permitted`,
|
||||
},
|
||||
{
|
||||
name: "just totally wrong",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
URL: strPtr("arg#backwards=thisis?html.index/port:host//:https"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `host must be provided`,
|
||||
},
|
||||
{
|
||||
name: "path must start with slash",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
|
@ -442,13 +481,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `clientConfig.service.path: Invalid value: "foo/": must start with a '/'`,
|
||||
},
|
||||
{
|
||||
name: "path accepts slash",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
|
@ -459,13 +497,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: ``,
|
||||
},
|
||||
{
|
||||
name: "path accepts no trailing slash",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
|
@ -476,13 +513,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: ``,
|
||||
},
|
||||
{
|
||||
name: "path fails //",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
|
@ -493,13 +529,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `clientConfig.service.path: Invalid value: "//": segment[0] may not be empty`,
|
||||
},
|
||||
{
|
||||
name: "path no empty step",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
|
@ -510,12 +545,11 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `clientConfig.service.path: Invalid value: "/foo//bar/": segment[1] may not be empty`,
|
||||
}, {
|
||||
name: "path no empty step 2",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
|
@ -526,13 +560,12 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `clientConfig.service.path: Invalid value: "/foo/bar//": segment[2] may not be empty`,
|
||||
},
|
||||
{
|
||||
name: "path no non-subdomain",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: admissionregistration.WebhookClientConfig{
|
||||
|
@ -543,49 +576,45 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `clientConfig.service.path: Invalid value: "/apis/foo.bar/v1alpha1/--bad": segment[3]: a DNS-1123 subdomain`,
|
||||
},
|
||||
{
|
||||
name: "timeout seconds cannot be greater than 30",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
TimeoutSeconds: int32Ptr(31),
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].timeoutSeconds: Invalid value: 31: the timeout value must be between 1 and 30 seconds`,
|
||||
},
|
||||
{
|
||||
name: "timeout seconds cannot be smaller than 1",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
TimeoutSeconds: int32Ptr(0),
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].timeoutSeconds: Invalid value: 0: the timeout value must be between 1 and 30 seconds`,
|
||||
},
|
||||
{
|
||||
name: "timeout seconds must be positive",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
TimeoutSeconds: int32Ptr(-1),
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
expectedError: `webhooks[0].timeoutSeconds: Invalid value: -1: the timeout value must be between 1 and 30 seconds`,
|
||||
},
|
||||
{
|
||||
name: "valid timeout seconds",
|
||||
config: newValidatingWebhookConfiguration(
|
||||
[]admissionregistration.Webhook{
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
|
@ -601,7 +630,7 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
ClientConfig: validClientConfig,
|
||||
TimeoutSeconds: int32Ptr(30),
|
||||
},
|
||||
}),
|
||||
}, true),
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
|
@ -621,3 +650,102 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateValidatingWebhookConfigurationUpdate(t *testing.T) {
|
||||
validClientConfig := admissionregistration.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com"),
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
oldconfig *admissionregistration.ValidatingWebhookConfiguration
|
||||
config *admissionregistration.ValidatingWebhookConfiguration
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
name: "should pass on valid new AdmissionReviewVersion",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
},
|
||||
}, true),
|
||||
oldconfig: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
},
|
||||
}, true),
|
||||
expectedError: ``,
|
||||
},
|
||||
{
|
||||
name: "should pass on invalid AdmissionReviewVersion with invalid previous versions",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"invalid-v1", "invalid-v2"},
|
||||
},
|
||||
}, true),
|
||||
oldconfig: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"invalid-v0"},
|
||||
},
|
||||
}, true),
|
||||
expectedError: ``,
|
||||
},
|
||||
{
|
||||
name: "should fail on invalid AdmissionReviewVersion with valid previous versions",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"invalid-v1"},
|
||||
},
|
||||
}, true),
|
||||
oldconfig: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"v1beta1", "invalid-v1"},
|
||||
},
|
||||
}, true),
|
||||
expectedError: `Invalid value: []string{"invalid-v1"}`,
|
||||
},
|
||||
{
|
||||
name: "should fail on invalid AdmissionReviewVersion with missing previous versions",
|
||||
config: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
AdmissionReviewVersions: []string{"invalid-v1"},
|
||||
},
|
||||
}, true),
|
||||
oldconfig: newValidatingWebhookConfiguration([]admissionregistration.Webhook{
|
||||
{
|
||||
Name: "webhook.k8s.io",
|
||||
ClientConfig: validClientConfig,
|
||||
},
|
||||
}, false),
|
||||
expectedError: `Invalid value: []string{"invalid-v1"}`,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
errs := ValidateValidatingWebhookConfigurationUpdate(test.config, test.oldconfig)
|
||||
err := errs.ToAggregate()
|
||||
if err != nil {
|
||||
if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" {
|
||||
t.Errorf("expected to contain %s, got %s", e, a)
|
||||
}
|
||||
} else {
|
||||
if test.expectedError != "" {
|
||||
t.Errorf("unexpected no error, expected to contain %s", test.expectedError)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,6 +267,11 @@ func (in *Webhook) DeepCopyInto(out *Webhook) {
|
|||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.AdmissionReviewVersions != nil {
|
||||
in, out := &in.AdmissionReviewVersions, &out.AdmissionReviewVersions
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -78,9 +78,7 @@ func (mutatingWebhookConfigurationStrategy) AllowCreateOnUpdate() bool {
|
|||
|
||||
// ValidateUpdate is the default update validation for an end user.
|
||||
func (mutatingWebhookConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||
validationErrorList := validation.ValidateMutatingWebhookConfiguration(obj.(*admissionregistration.MutatingWebhookConfiguration))
|
||||
updateErrorList := validation.ValidateMutatingWebhookConfigurationUpdate(obj.(*admissionregistration.MutatingWebhookConfiguration), old.(*admissionregistration.MutatingWebhookConfiguration))
|
||||
return append(validationErrorList, updateErrorList...)
|
||||
return validation.ValidateMutatingWebhookConfigurationUpdate(obj.(*admissionregistration.MutatingWebhookConfiguration), old.(*admissionregistration.MutatingWebhookConfiguration))
|
||||
}
|
||||
|
||||
// AllowUnconditionalUpdate is the default update policy for mutatingWebhookConfiguration objects. Status update should
|
||||
|
|
|
@ -63,8 +63,7 @@ func (validatingWebhookConfigurationStrategy) PrepareForUpdate(ctx context.Conte
|
|||
|
||||
// Validate validates a new validatingWebhookConfiguration.
|
||||
func (validatingWebhookConfigurationStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||
ic := obj.(*admissionregistration.ValidatingWebhookConfiguration)
|
||||
return validation.ValidateValidatingWebhookConfiguration(ic)
|
||||
return validation.ValidateValidatingWebhookConfiguration(obj.(*admissionregistration.ValidatingWebhookConfiguration))
|
||||
}
|
||||
|
||||
// Canonicalize normalizes the object after validation.
|
||||
|
@ -78,9 +77,7 @@ func (validatingWebhookConfigurationStrategy) AllowCreateOnUpdate() bool {
|
|||
|
||||
// ValidateUpdate is the default update validation for an end user.
|
||||
func (validatingWebhookConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||
validationErrorList := validation.ValidateValidatingWebhookConfiguration(obj.(*admissionregistration.ValidatingWebhookConfiguration))
|
||||
updateErrorList := validation.ValidateValidatingWebhookConfigurationUpdate(obj.(*admissionregistration.ValidatingWebhookConfiguration), old.(*admissionregistration.ValidatingWebhookConfiguration))
|
||||
return append(validationErrorList, updateErrorList...)
|
||||
return validation.ValidateValidatingWebhookConfigurationUpdate(obj.(*admissionregistration.ValidatingWebhookConfiguration), old.(*admissionregistration.ValidatingWebhookConfiguration))
|
||||
}
|
||||
|
||||
// AllowUnconditionalUpdate is the default update policy for validatingWebhookConfiguration objects. Status update should
|
||||
|
|
|
@ -473,6 +473,21 @@ func (m *Webhook) MarshalTo(dAtA []byte) (int, error) {
|
|||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds))
|
||||
}
|
||||
if len(m.AdmissionReviewVersions) > 0 {
|
||||
for _, s := range m.AdmissionReviewVersions {
|
||||
dAtA[i] = 0x42
|
||||
i++
|
||||
l = len(s)
|
||||
for l >= 1<<7 {
|
||||
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
|
||||
l >>= 7
|
||||
i++
|
||||
}
|
||||
dAtA[i] = uint8(l)
|
||||
i++
|
||||
i += copy(dAtA[i:], s)
|
||||
}
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -665,6 +680,12 @@ func (m *Webhook) Size() (n int) {
|
|||
if m.TimeoutSeconds != nil {
|
||||
n += 1 + sovGenerated(uint64(*m.TimeoutSeconds))
|
||||
}
|
||||
if len(m.AdmissionReviewVersions) > 0 {
|
||||
for _, s := range m.AdmissionReviewVersions {
|
||||
l = len(s)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -791,6 +812,7 @@ func (this *Webhook) String() string {
|
|||
`NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "k8s_io_apimachinery_pkg_apis_meta_v1.LabelSelector", 1) + `,`,
|
||||
`SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`,
|
||||
`TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`,
|
||||
`AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -1905,6 +1927,35 @@ func (m *Webhook) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
}
|
||||
m.TimeoutSeconds = &v
|
||||
case 8:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AdmissionReviewVersions", 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 > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.AdmissionReviewVersions = append(m.AdmissionReviewVersions, string(dAtA[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
|
@ -2180,66 +2231,67 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 962 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x55, 0xcf, 0x8f, 0xdb, 0x44,
|
||||
0x14, 0x5e, 0x37, 0x09, 0x89, 0x27, 0xbb, 0x6d, 0x77, 0xf8, 0x21, 0xb3, 0xaa, 0xec, 0x28, 0x07,
|
||||
0x14, 0x09, 0x6a, 0xb3, 0x0b, 0x42, 0xa8, 0x02, 0xa1, 0xf5, 0x42, 0x61, 0xa5, 0x6d, 0xbb, 0x4c,
|
||||
0x4a, 0x2b, 0x21, 0x0e, 0x4c, 0x9c, 0x97, 0x64, 0x88, 0xe3, 0xb1, 0x3c, 0xe3, 0x94, 0xbd, 0x21,
|
||||
0xf1, 0x0f, 0xf0, 0x5f, 0xf0, 0x57, 0x70, 0xe0, 0xb6, 0xc7, 0x72, 0x40, 0xf4, 0x64, 0xb1, 0xe6,
|
||||
0xcc, 0x81, 0xeb, 0x9e, 0xd0, 0xd8, 0x4e, 0x9c, 0x6c, 0xba, 0xdb, 0xf4, 0xc2, 0x81, 0x9b, 0xe7,
|
||||
0x7b, 0xef, 0xfb, 0xde, 0xfb, 0x66, 0xe6, 0x8d, 0xd1, 0x97, 0xe3, 0x0f, 0x85, 0xcd, 0xb8, 0x33,
|
||||
0x8e, 0x7b, 0x10, 0x05, 0x20, 0x41, 0x38, 0x53, 0x08, 0xfa, 0x3c, 0x72, 0x8a, 0x00, 0x0d, 0x99,
|
||||
0x43, 0xfb, 0x13, 0x26, 0x04, 0xe3, 0x41, 0x04, 0x43, 0x26, 0x64, 0x44, 0x25, 0xe3, 0x81, 0x33,
|
||||
0xdd, 0xed, 0x81, 0xa4, 0xbb, 0xce, 0x10, 0x02, 0x88, 0xa8, 0x84, 0xbe, 0x1d, 0x46, 0x5c, 0x72,
|
||||
0xdc, 0xc9, 0x99, 0x36, 0x0d, 0x99, 0xfd, 0x5c, 0xa6, 0x5d, 0x30, 0x77, 0x6e, 0x0f, 0x99, 0x1c,
|
||||
0xc5, 0x3d, 0xdb, 0xe3, 0x13, 0x67, 0xc8, 0x87, 0xdc, 0xc9, 0x04, 0x7a, 0xf1, 0x20, 0x5b, 0x65,
|
||||
0x8b, 0xec, 0x2b, 0x17, 0xde, 0x79, 0xbf, 0x6c, 0x69, 0x42, 0xbd, 0x11, 0x0b, 0x20, 0x3a, 0x71,
|
||||
0xc2, 0xf1, 0x50, 0x01, 0xc2, 0x99, 0x80, 0xa4, 0xce, 0x74, 0xa5, 0x9d, 0x1d, 0xe7, 0x32, 0x56,
|
||||
0x14, 0x07, 0x92, 0x4d, 0x60, 0x85, 0xf0, 0xc1, 0x8b, 0x08, 0xc2, 0x1b, 0xc1, 0x84, 0x5e, 0xe4,
|
||||
0xb5, 0x7f, 0xd7, 0xd0, 0xad, 0x7b, 0xb1, 0xa4, 0x92, 0x05, 0xc3, 0xc7, 0xd0, 0x1b, 0x71, 0x3e,
|
||||
0x3e, 0xe0, 0xc1, 0x80, 0x0d, 0xe3, 0xdc, 0x36, 0xfe, 0x16, 0x35, 0x54, 0x93, 0x7d, 0x2a, 0xa9,
|
||||
0xa1, 0xb5, 0xb4, 0x4e, 0x73, 0xef, 0x5d, 0xbb, 0xdc, 0xab, 0x79, 0x2d, 0x3b, 0x1c, 0x0f, 0x15,
|
||||
0x20, 0x6c, 0x95, 0x6d, 0x4f, 0x77, 0xed, 0x07, 0xbd, 0xef, 0xc0, 0x93, 0xf7, 0x40, 0x52, 0x17,
|
||||
0x9f, 0x26, 0xd6, 0x46, 0x9a, 0x58, 0xa8, 0xc4, 0xc8, 0x5c, 0x15, 0x77, 0x51, 0xa3, 0xa8, 0x2c,
|
||||
0x8c, 0x6b, 0xad, 0x4a, 0xa7, 0xb9, 0xb7, 0x6b, 0xaf, 0x7b, 0x1a, 0x76, 0xc1, 0x74, 0xab, 0xaa,
|
||||
0x04, 0x69, 0x3c, 0x29, 0x84, 0xda, 0x7f, 0x6b, 0xa8, 0x75, 0x95, 0xaf, 0x23, 0x26, 0x24, 0xfe,
|
||||
0x66, 0xc5, 0x9b, 0xbd, 0x9e, 0x37, 0xc5, 0xce, 0x9c, 0xdd, 0x2c, 0x9c, 0x35, 0x66, 0xc8, 0x82,
|
||||
0xaf, 0x31, 0xaa, 0x31, 0x09, 0x93, 0x99, 0xa9, 0xbb, 0xeb, 0x9b, 0xba, 0xaa, 0x71, 0x77, 0xab,
|
||||
0x28, 0x59, 0x3b, 0x54, 0xe2, 0x24, 0xaf, 0xd1, 0xfe, 0x55, 0x43, 0x55, 0x12, 0xfb, 0x80, 0xdf,
|
||||
0x46, 0x3a, 0x0d, 0xd9, 0xe7, 0x11, 0x8f, 0x43, 0x61, 0x68, 0xad, 0x4a, 0x47, 0x77, 0xb7, 0xd2,
|
||||
0xc4, 0xd2, 0xf7, 0x8f, 0x0f, 0x73, 0x90, 0x94, 0x71, 0xbc, 0x8b, 0x9a, 0x34, 0x64, 0x8f, 0x20,
|
||||
0x52, 0xad, 0xe4, 0x8d, 0xea, 0xee, 0x8d, 0x34, 0xb1, 0x9a, 0xfb, 0xc7, 0x87, 0x33, 0x98, 0x2c,
|
||||
0xe6, 0x28, 0xfd, 0x08, 0x04, 0x8f, 0x23, 0x0f, 0x84, 0x51, 0x29, 0xf5, 0xc9, 0x0c, 0x24, 0x65,
|
||||
0x1c, 0xbf, 0x83, 0x6a, 0xc2, 0xe3, 0x21, 0x18, 0xd5, 0x96, 0xd6, 0xd1, 0xdd, 0x37, 0x54, 0xdb,
|
||||
0x5d, 0x05, 0x9c, 0x27, 0x96, 0x9e, 0x7d, 0x3c, 0x3c, 0x09, 0x81, 0xe4, 0x49, 0xed, 0x9f, 0x35,
|
||||
0x84, 0x95, 0x87, 0xc7, 0x4c, 0x8e, 0x1e, 0x84, 0x90, 0xfb, 0x15, 0xf8, 0x13, 0x84, 0xf8, 0x7c,
|
||||
0x55, 0x58, 0xb2, 0xb2, 0xdb, 0x34, 0x47, 0xcf, 0x13, 0x6b, 0x6b, 0xbe, 0xca, 0x24, 0x17, 0x28,
|
||||
0xf8, 0x18, 0x55, 0xa3, 0xd8, 0x07, 0xe3, 0xda, 0xca, 0x11, 0xbf, 0xe0, 0x1c, 0x54, 0x33, 0xee,
|
||||
0x66, 0xb1, 0xdf, 0xd9, 0xf6, 0x92, 0x4c, 0xa9, 0xfd, 0xa3, 0x86, 0x6e, 0x76, 0x21, 0x9a, 0x32,
|
||||
0x0f, 0x08, 0x0c, 0x20, 0x82, 0xc0, 0x03, 0xec, 0x20, 0x3d, 0xa0, 0x13, 0x10, 0x21, 0xf5, 0x20,
|
||||
0xbb, 0x4e, 0xba, 0xbb, 0x5d, 0x70, 0xf5, 0xfb, 0xb3, 0x00, 0x29, 0x73, 0x70, 0x0b, 0x55, 0xd5,
|
||||
0x22, 0xeb, 0x4b, 0x2f, 0xeb, 0xa8, 0x5c, 0x92, 0x45, 0xf0, 0x2d, 0x54, 0x0d, 0xa9, 0x1c, 0x19,
|
||||
0x95, 0x2c, 0xa3, 0xa1, 0xa2, 0xc7, 0x54, 0x8e, 0x48, 0x86, 0xb6, 0xff, 0xd0, 0x90, 0xf9, 0x88,
|
||||
0xfa, 0xac, 0xff, 0xbf, 0x9b, 0xde, 0x7f, 0x34, 0xd4, 0xbe, 0xda, 0xd9, 0x7f, 0x30, 0xbf, 0x93,
|
||||
0xe5, 0xf9, 0xfd, 0x62, 0x7d, 0x5b, 0x57, 0xb7, 0x7e, 0xc9, 0x04, 0xff, 0x56, 0x45, 0xf5, 0x22,
|
||||
0x7d, 0x7e, 0x33, 0xb4, 0x4b, 0x6f, 0xc6, 0x13, 0xb4, 0xe9, 0xf9, 0x0c, 0x02, 0x99, 0x4b, 0x17,
|
||||
0x77, 0xfb, 0xe3, 0x97, 0xde, 0xfa, 0x83, 0x05, 0x11, 0xf7, 0xb5, 0xa2, 0xd0, 0xe6, 0x22, 0x4a,
|
||||
0x96, 0x0a, 0x61, 0x8a, 0x6a, 0x6a, 0x04, 0xf2, 0xd9, 0x6f, 0xee, 0x7d, 0xf4, 0x72, 0xd3, 0xb4,
|
||||
0x3c, 0xda, 0xe5, 0x4e, 0xa8, 0x98, 0x20, 0xb9, 0x32, 0x3e, 0x42, 0x5b, 0x03, 0xca, 0xfc, 0x38,
|
||||
0x82, 0x63, 0xee, 0x33, 0xef, 0xa4, 0x78, 0x3d, 0xde, 0x4a, 0x13, 0x6b, 0xeb, 0xee, 0x62, 0xe0,
|
||||
0x3c, 0xb1, 0xb6, 0x97, 0x80, 0x6c, 0xf4, 0x97, 0xc9, 0xf8, 0x7b, 0xb4, 0x3d, 0x1f, 0xb9, 0x2e,
|
||||
0xf8, 0xe0, 0x49, 0x1e, 0x19, 0xb5, 0x6c, 0xbb, 0xde, 0x5b, 0xf3, 0xb6, 0xd0, 0x1e, 0xf8, 0x33,
|
||||
0xaa, 0xfb, 0x7a, 0x9a, 0x58, 0xdb, 0xf7, 0x2f, 0x2a, 0x92, 0xd5, 0x22, 0xf8, 0x53, 0xd4, 0x14,
|
||||
0xac, 0x0f, 0x9f, 0x0d, 0x06, 0xe0, 0x49, 0x61, 0xbc, 0x92, 0xb9, 0x68, 0xab, 0xd7, 0xb5, 0x5b,
|
||||
0xc2, 0xe7, 0x89, 0x75, 0xa3, 0x5c, 0x1e, 0xf8, 0x54, 0x08, 0xb2, 0x48, 0xc3, 0x77, 0xd0, 0x75,
|
||||
0xf5, 0x03, 0xe7, 0xb1, 0xec, 0x82, 0xc7, 0x83, 0xbe, 0x30, 0xea, 0x2d, 0xad, 0x53, 0x73, 0x71,
|
||||
0x9a, 0x58, 0xd7, 0x1f, 0x2e, 0x45, 0xc8, 0x85, 0xcc, 0xf6, 0x2f, 0x1a, 0x7a, 0xf5, 0x39, 0x07,
|
||||
0x8d, 0x29, 0xaa, 0x8b, 0xfc, 0xf9, 0x2a, 0xe6, 0xe6, 0xce, 0xfa, 0xc7, 0x78, 0xf1, 0xdd, 0x73,
|
||||
0x9b, 0x69, 0x62, 0xd5, 0x67, 0xe8, 0x4c, 0x17, 0x77, 0x50, 0xc3, 0xa3, 0x6e, 0x1c, 0xf4, 0x8b,
|
||||
0x87, 0x77, 0xd3, 0xdd, 0x54, 0x73, 0x76, 0xb0, 0x9f, 0x63, 0x64, 0x1e, 0xc5, 0x6f, 0xa2, 0x4a,
|
||||
0x1c, 0xf9, 0xc5, 0x1b, 0x57, 0x4f, 0x13, 0xab, 0xf2, 0x15, 0x39, 0x22, 0x0a, 0x73, 0x6f, 0x9f,
|
||||
0x9e, 0x99, 0x1b, 0x4f, 0xcf, 0xcc, 0x8d, 0x67, 0x67, 0xe6, 0xc6, 0x0f, 0xa9, 0xa9, 0x9d, 0xa6,
|
||||
0xa6, 0xf6, 0x34, 0x35, 0xb5, 0x67, 0xa9, 0xa9, 0xfd, 0x99, 0x9a, 0xda, 0x4f, 0x7f, 0x99, 0x1b,
|
||||
0x5f, 0xd7, 0x8b, 0xd6, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xbb, 0xeb, 0xd8, 0xb0, 0x18, 0x0a,
|
||||
0x00, 0x00,
|
||||
// 989 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x55, 0x4f, 0x6f, 0xe3, 0x44,
|
||||
0x14, 0xaf, 0x37, 0x09, 0x49, 0x26, 0xed, 0xee, 0x76, 0xf8, 0xb3, 0xa1, 0xac, 0xec, 0x28, 0x07,
|
||||
0x14, 0x09, 0xd6, 0xa6, 0x05, 0x21, 0xb4, 0x02, 0xa1, 0xba, 0xb0, 0x50, 0xa9, 0xbb, 0x5b, 0x26,
|
||||
0xfb, 0x47, 0x42, 0x1c, 0x98, 0x38, 0x2f, 0xc9, 0x10, 0xc7, 0x63, 0x79, 0xc6, 0x29, 0xbd, 0x21,
|
||||
0xf1, 0x05, 0xf8, 0x16, 0xf0, 0x25, 0x38, 0x70, 0xeb, 0x71, 0x2f, 0x88, 0x3d, 0x59, 0xd4, 0x9c,
|
||||
0x39, 0x70, 0xed, 0x09, 0x8d, 0xed, 0xd8, 0x49, 0xd3, 0x76, 0xb3, 0x17, 0x0e, 0xdc, 0x3c, 0xbf,
|
||||
0xf7, 0x7e, 0xef, 0xbd, 0xdf, 0xcc, 0x7b, 0xcf, 0xe8, 0xab, 0xf1, 0x47, 0xc2, 0x64, 0xdc, 0x1a,
|
||||
0x87, 0x3d, 0x08, 0x3c, 0x90, 0x20, 0xac, 0x29, 0x78, 0x7d, 0x1e, 0x58, 0x99, 0x81, 0xfa, 0xcc,
|
||||
0xa2, 0xfd, 0x09, 0x13, 0x82, 0x71, 0x2f, 0x80, 0x21, 0x13, 0x32, 0xa0, 0x92, 0x71, 0xcf, 0x9a,
|
||||
0x6e, 0xf7, 0x40, 0xd2, 0x6d, 0x6b, 0x08, 0x1e, 0x04, 0x54, 0x42, 0xdf, 0xf4, 0x03, 0x2e, 0x39,
|
||||
0xee, 0xa4, 0x4c, 0x93, 0xfa, 0xcc, 0xbc, 0x90, 0x69, 0x66, 0xcc, 0xad, 0x3b, 0x43, 0x26, 0x47,
|
||||
0x61, 0xcf, 0x74, 0xf8, 0xc4, 0x1a, 0xf2, 0x21, 0xb7, 0x92, 0x00, 0xbd, 0x70, 0x90, 0x9c, 0x92,
|
||||
0x43, 0xf2, 0x95, 0x06, 0xde, 0xfa, 0xa0, 0x28, 0x69, 0x42, 0x9d, 0x11, 0xf3, 0x20, 0x38, 0xb6,
|
||||
0xfc, 0xf1, 0x50, 0x01, 0xc2, 0x9a, 0x80, 0xa4, 0xd6, 0x74, 0xa9, 0x9c, 0x2d, 0xeb, 0x32, 0x56,
|
||||
0x10, 0x7a, 0x92, 0x4d, 0x60, 0x89, 0xf0, 0xe1, 0x8b, 0x08, 0xc2, 0x19, 0xc1, 0x84, 0x9e, 0xe7,
|
||||
0xb5, 0x7f, 0xd7, 0xd0, 0xed, 0xfb, 0xa1, 0xa4, 0x92, 0x79, 0xc3, 0xa7, 0xd0, 0x1b, 0x71, 0x3e,
|
||||
0xde, 0xe3, 0xde, 0x80, 0x0d, 0xc3, 0x54, 0x36, 0xfe, 0x16, 0xd5, 0x54, 0x91, 0x7d, 0x2a, 0x69,
|
||||
0x53, 0x6b, 0x69, 0x9d, 0xc6, 0xce, 0x7b, 0x66, 0x71, 0x57, 0x79, 0x2e, 0xd3, 0x1f, 0x0f, 0x15,
|
||||
0x20, 0x4c, 0xe5, 0x6d, 0x4e, 0xb7, 0xcd, 0x87, 0xbd, 0xef, 0xc0, 0x91, 0xf7, 0x41, 0x52, 0x1b,
|
||||
0x9f, 0x44, 0xc6, 0x5a, 0x1c, 0x19, 0xa8, 0xc0, 0x48, 0x1e, 0x15, 0x77, 0x51, 0x2d, 0xcb, 0x2c,
|
||||
0x9a, 0xd7, 0x5a, 0xa5, 0x4e, 0x63, 0x67, 0xdb, 0x5c, 0xf5, 0x35, 0xcc, 0x8c, 0x69, 0x97, 0x55,
|
||||
0x0a, 0x52, 0x3b, 0xca, 0x02, 0xb5, 0xff, 0xd6, 0x50, 0xeb, 0x2a, 0x5d, 0x07, 0x4c, 0x48, 0xfc,
|
||||
0xcd, 0x92, 0x36, 0x73, 0x35, 0x6d, 0x8a, 0x9d, 0x28, 0xbb, 0x99, 0x29, 0xab, 0xcd, 0x90, 0x39,
|
||||
0x5d, 0x63, 0x54, 0x61, 0x12, 0x26, 0x33, 0x51, 0xf7, 0x56, 0x17, 0x75, 0x55, 0xe1, 0xf6, 0x46,
|
||||
0x96, 0xb2, 0xb2, 0xaf, 0x82, 0x93, 0x34, 0x47, 0xfb, 0x37, 0x0d, 0x95, 0x49, 0xe8, 0x02, 0x7e,
|
||||
0x07, 0xd5, 0xa9, 0xcf, 0xbe, 0x08, 0x78, 0xe8, 0x8b, 0xa6, 0xd6, 0x2a, 0x75, 0xea, 0xf6, 0x46,
|
||||
0x1c, 0x19, 0xf5, 0xdd, 0xc3, 0xfd, 0x14, 0x24, 0x85, 0x1d, 0x6f, 0xa3, 0x06, 0xf5, 0xd9, 0x13,
|
||||
0x08, 0x54, 0x29, 0x69, 0xa1, 0x75, 0xfb, 0x46, 0x1c, 0x19, 0x8d, 0xdd, 0xc3, 0xfd, 0x19, 0x4c,
|
||||
0xe6, 0x7d, 0x54, 0xfc, 0x00, 0x04, 0x0f, 0x03, 0x07, 0x44, 0xb3, 0x54, 0xc4, 0x27, 0x33, 0x90,
|
||||
0x14, 0x76, 0xfc, 0x2e, 0xaa, 0x08, 0x87, 0xfb, 0xd0, 0x2c, 0xb7, 0xb4, 0x4e, 0xdd, 0x7e, 0x43,
|
||||
0x95, 0xdd, 0x55, 0xc0, 0x59, 0x64, 0xd4, 0x93, 0x8f, 0x47, 0xc7, 0x3e, 0x90, 0xd4, 0xa9, 0xfd,
|
||||
0xb3, 0x86, 0xb0, 0xd2, 0xf0, 0x94, 0xc9, 0xd1, 0x43, 0x1f, 0x52, 0xbd, 0x02, 0x7f, 0x8a, 0x10,
|
||||
0xcf, 0x4f, 0x99, 0x24, 0x23, 0xe9, 0xa6, 0x1c, 0x3d, 0x8b, 0x8c, 0x8d, 0xfc, 0x94, 0x84, 0x9c,
|
||||
0xa3, 0xe0, 0x43, 0x54, 0x0e, 0x42, 0x17, 0x9a, 0xd7, 0x96, 0x9e, 0xf8, 0x05, 0xef, 0xa0, 0x8a,
|
||||
0xb1, 0xd7, 0xb3, 0xfb, 0x4e, 0xae, 0x97, 0x24, 0x91, 0xda, 0x3f, 0x6a, 0xe8, 0x66, 0x17, 0x82,
|
||||
0x29, 0x73, 0x80, 0xc0, 0x00, 0x02, 0xf0, 0x1c, 0xc0, 0x16, 0xaa, 0x7b, 0x74, 0x02, 0xc2, 0xa7,
|
||||
0x0e, 0x24, 0xed, 0x54, 0xb7, 0x37, 0x33, 0x6e, 0xfd, 0xc1, 0xcc, 0x40, 0x0a, 0x1f, 0xdc, 0x42,
|
||||
0x65, 0x75, 0x48, 0xea, 0xaa, 0x17, 0x79, 0x94, 0x2f, 0x49, 0x2c, 0xf8, 0x36, 0x2a, 0xfb, 0x54,
|
||||
0x8e, 0x9a, 0xa5, 0xc4, 0xa3, 0xa6, 0xac, 0x87, 0x54, 0x8e, 0x48, 0x82, 0xb6, 0xff, 0xd0, 0x90,
|
||||
0xfe, 0x84, 0xba, 0xac, 0xff, 0xbf, 0x9b, 0xde, 0x7f, 0x34, 0xd4, 0xbe, 0x5a, 0xd9, 0x7f, 0x30,
|
||||
0xbf, 0x93, 0xc5, 0xf9, 0xfd, 0x72, 0x75, 0x59, 0x57, 0x97, 0x7e, 0xc9, 0x04, 0xff, 0x52, 0x41,
|
||||
0xd5, 0xcc, 0x3d, 0xef, 0x0c, 0xed, 0xd2, 0xce, 0x38, 0x42, 0xeb, 0x8e, 0xcb, 0xc0, 0x93, 0x69,
|
||||
0xe8, 0xac, 0xb7, 0x3f, 0x79, 0xe9, 0xab, 0xdf, 0x9b, 0x0b, 0x62, 0xbf, 0x96, 0x25, 0x5a, 0x9f,
|
||||
0x47, 0xc9, 0x42, 0x22, 0x4c, 0x51, 0x45, 0x8d, 0x40, 0x3a, 0xfb, 0x8d, 0x9d, 0x8f, 0x5f, 0x6e,
|
||||
0x9a, 0x16, 0x47, 0xbb, 0xb8, 0x09, 0x65, 0x13, 0x24, 0x8d, 0x8c, 0x0f, 0xd0, 0xc6, 0x80, 0x32,
|
||||
0x37, 0x0c, 0xe0, 0x90, 0xbb, 0xcc, 0x39, 0xce, 0xb6, 0xc7, 0xdb, 0x71, 0x64, 0x6c, 0xdc, 0x9b,
|
||||
0x37, 0x9c, 0x45, 0xc6, 0xe6, 0x02, 0x90, 0x8c, 0xfe, 0x22, 0x19, 0x7f, 0x8f, 0x36, 0xf3, 0x91,
|
||||
0xeb, 0x82, 0x0b, 0x8e, 0xe4, 0x41, 0xb3, 0x92, 0x5c, 0xd7, 0xfb, 0x2b, 0x76, 0x0b, 0xed, 0x81,
|
||||
0x3b, 0xa3, 0xda, 0xaf, 0xc7, 0x91, 0xb1, 0xf9, 0xe0, 0x7c, 0x44, 0xb2, 0x9c, 0x04, 0x7f, 0x86,
|
||||
0x1a, 0x82, 0xf5, 0xe1, 0xf3, 0xc1, 0x00, 0x1c, 0x29, 0x9a, 0xaf, 0x24, 0x2a, 0xda, 0x6a, 0xbb,
|
||||
0x76, 0x0b, 0xf8, 0x2c, 0x32, 0x6e, 0x14, 0xc7, 0x3d, 0x97, 0x0a, 0x41, 0xe6, 0x69, 0xf8, 0x2e,
|
||||
0xba, 0xae, 0x7e, 0xe0, 0x3c, 0x94, 0x5d, 0x70, 0xb8, 0xd7, 0x17, 0xcd, 0x6a, 0x4b, 0xeb, 0x54,
|
||||
0x6c, 0x1c, 0x47, 0xc6, 0xf5, 0x47, 0x0b, 0x16, 0x72, 0xce, 0x13, 0x3f, 0x46, 0xb7, 0xf2, 0x37,
|
||||
0x21, 0x30, 0x65, 0x70, 0x94, 0xef, 0xfa, 0x5a, 0xb2, 0x47, 0xdf, 0x8a, 0x23, 0xe3, 0xd6, 0xee,
|
||||
0xc5, 0x2e, 0xe4, 0x32, 0x6e, 0xfb, 0x57, 0x0d, 0xbd, 0x7a, 0x41, 0xff, 0x60, 0x8a, 0xaa, 0x22,
|
||||
0xdd, 0x8a, 0xd9, 0x38, 0xde, 0x5d, 0xbd, 0x3b, 0xce, 0xaf, 0x53, 0xbb, 0x11, 0x47, 0x46, 0x75,
|
||||
0x86, 0xce, 0xe2, 0xe2, 0x0e, 0xaa, 0x39, 0xd4, 0x0e, 0xbd, 0x7e, 0xb6, 0xcf, 0xd7, 0xed, 0x75,
|
||||
0x35, 0xbe, 0x7b, 0xbb, 0x29, 0x46, 0x72, 0x2b, 0x7e, 0x13, 0x95, 0xc2, 0xc0, 0xcd, 0x56, 0x67,
|
||||
0x35, 0x8e, 0x8c, 0xd2, 0x63, 0x72, 0x40, 0x14, 0x66, 0xdf, 0x39, 0x39, 0xd5, 0xd7, 0x9e, 0x9d,
|
||||
0xea, 0x6b, 0xcf, 0x4f, 0xf5, 0xb5, 0x1f, 0x62, 0x5d, 0x3b, 0x89, 0x75, 0xed, 0x59, 0xac, 0x6b,
|
||||
0xcf, 0x63, 0x5d, 0xfb, 0x33, 0xd6, 0xb5, 0x9f, 0xfe, 0xd2, 0xd7, 0xbe, 0xae, 0x66, 0xa5, 0xfd,
|
||||
0x1b, 0x00, 0x00, 0xff, 0xff, 0xbb, 0xc0, 0x7c, 0xc4, 0x6f, 0x0a, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -237,6 +237,17 @@ message Webhook {
|
|||
// Default to 30 seconds.
|
||||
// +optional
|
||||
optional int32 timeoutSeconds = 7;
|
||||
|
||||
// AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
|
||||
// versions the Webhook expects. API server will try to use first version in
|
||||
// the list which it supports. If none of the versions specified in this list
|
||||
// supported by API server, validation will fail for this object.
|
||||
// If a persisted webhook configuration specifies allowed versions and does not
|
||||
// include any versions known to the API Server, calls to the webhook will fail
|
||||
// and be subject to the failure policy.
|
||||
// Default to `['v1beta1']`.
|
||||
// +optional
|
||||
repeated string admissionReviewVersions = 8;
|
||||
}
|
||||
|
||||
// WebhookClientConfig contains the information to make a TLS
|
||||
|
|
|
@ -248,6 +248,17 @@ type Webhook struct {
|
|||
// Default to 30 seconds.
|
||||
// +optional
|
||||
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"`
|
||||
|
||||
// AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
|
||||
// versions the Webhook expects. API server will try to use first version in
|
||||
// the list which it supports. If none of the versions specified in this list
|
||||
// supported by API server, validation will fail for this object.
|
||||
// If a persisted webhook configuration specifies allowed versions and does not
|
||||
// include any versions known to the API Server, calls to the webhook will fail
|
||||
// and be subject to the failure policy.
|
||||
// Default to `['v1beta1']`.
|
||||
// +optional
|
||||
AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty" protobuf:"bytes,8,rep,name=admissionReviewVersions"`
|
||||
}
|
||||
|
||||
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
|
||||
|
|
|
@ -108,6 +108,7 @@ var map_Webhook = map[string]string{
|
|||
"namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
|
||||
"sideEffects": "SideEffects states whether this webhookk has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission change and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.",
|
||||
"timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.",
|
||||
"admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.",
|
||||
}
|
||||
|
||||
func (Webhook) SwaggerDoc() map[string]string {
|
||||
|
|
|
@ -267,6 +267,11 @@ func (in *Webhook) DeepCopyInto(out *Webhook) {
|
|||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.AdmissionReviewVersions != nil {
|
||||
in, out := &in.AdmissionReviewVersions, &out.AdmissionReviewVersions
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
|||
Strategy: apiextensions.NoneConverter,
|
||||
}
|
||||
}
|
||||
if obj.Conversion.Strategy == apiextensions.WebhookConverter && len(obj.Conversion.ConversionReviewVersions) == 0 {
|
||||
obj.Conversion.ConversionReviewVersions = []string{"v1beta1"}
|
||||
}
|
||||
},
|
||||
func(obj *apiextensions.CustomResourceDefinition, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(obj)
|
||||
|
|
|
@ -84,6 +84,15 @@ type CustomResourceConversion struct {
|
|||
|
||||
// `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`.
|
||||
WebhookClientConfig *WebhookClientConfig
|
||||
|
||||
// ConversionReviewVersions is an ordered list of preferred `ConversionReview`
|
||||
// versions the Webhook expects. API server will try to use first version in
|
||||
// the list which it supports. If none of the versions specified in this list
|
||||
// supported by API server, conversion will fail for this object.
|
||||
// If a persisted Webhook configuration specifies allowed versions and does not
|
||||
// include any versions known to the API Server, calls to the webhook will fail.
|
||||
// +optional
|
||||
ConversionReviewVersions []string
|
||||
}
|
||||
|
||||
// WebhookClientConfig contains the information to make a TLS
|
||||
|
|
|
@ -68,6 +68,9 @@ func SetDefaults_CustomResourceDefinitionSpec(obj *CustomResourceDefinitionSpec)
|
|||
Strategy: NoneConverter,
|
||||
}
|
||||
}
|
||||
if obj.Conversion.Strategy == WebhookConverter && len(obj.Conversion.ConversionReviewVersions) == 0 {
|
||||
obj.Conversion.ConversionReviewVersions = []string{SchemeGroupVersion.Version}
|
||||
}
|
||||
}
|
||||
|
||||
// hasPerVersionColumns returns true if a CRD uses per-version columns.
|
||||
|
|
|
@ -416,6 +416,21 @@ func (m *CustomResourceConversion) MarshalTo(dAtA []byte) (int, error) {
|
|||
}
|
||||
i += n4
|
||||
}
|
||||
if len(m.ConversionReviewVersions) > 0 {
|
||||
for _, s := range m.ConversionReviewVersions {
|
||||
dAtA[i] = 0x1a
|
||||
i++
|
||||
l = len(s)
|
||||
for l >= 1<<7 {
|
||||
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
|
||||
l >>= 7
|
||||
i++
|
||||
}
|
||||
dAtA[i] = uint8(l)
|
||||
i++
|
||||
i += copy(dAtA[i:], s)
|
||||
}
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -1691,6 +1706,12 @@ func (m *CustomResourceConversion) Size() (n int) {
|
|||
l = m.WebhookClientConfig.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
if len(m.ConversionReviewVersions) > 0 {
|
||||
for _, s := range m.ConversionReviewVersions {
|
||||
l = len(s)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -2202,6 +2223,7 @@ func (this *CustomResourceConversion) String() string {
|
|||
s := strings.Join([]string{`&CustomResourceConversion{`,
|
||||
`Strategy:` + fmt.Sprintf("%v", this.Strategy) + `,`,
|
||||
`WebhookClientConfig:` + strings.Replace(fmt.Sprintf("%v", this.WebhookClientConfig), "WebhookClientConfig", "WebhookClientConfig", 1) + `,`,
|
||||
`ConversionReviewVersions:` + fmt.Sprintf("%v", this.ConversionReviewVersions) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -3217,6 +3239,35 @@ func (m *CustomResourceConversion) Unmarshal(dAtA []byte) error {
|
|||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ConversionReviewVersions", 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 > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ConversionReviewVersions = append(m.ConversionReviewVersions, string(dAtA[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
|
@ -7285,178 +7336,179 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 2762 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0x1c, 0x47,
|
||||
0x15, 0xf7, 0xec, 0x6a, 0xa5, 0x55, 0x4b, 0xb2, 0xa4, 0x76, 0xe4, 0x8c, 0x85, 0xbd, 0x2b, 0xad,
|
||||
0x71, 0x4a, 0x04, 0x7b, 0x15, 0x9b, 0x84, 0x84, 0x54, 0x71, 0xd0, 0x4a, 0x4a, 0x4a, 0xc6, 0xfa,
|
||||
0xa0, 0xd7, 0x76, 0x80, 0x7c, 0xb6, 0x66, 0x7b, 0x57, 0x63, 0xcd, 0x97, 0xa7, 0x67, 0x56, 0x52,
|
||||
0x05, 0x28, 0x48, 0x2a, 0x05, 0x45, 0x01, 0xa1, 0x88, 0x2f, 0x14, 0x70, 0x00, 0x8a, 0x0b, 0x07,
|
||||
0x38, 0xc0, 0x0d, 0xfe, 0x00, 0x1f, 0x53, 0x9c, 0x52, 0x1c, 0xb6, 0xf0, 0xe6, 0x5f, 0xa0, 0x8a,
|
||||
0x2a, 0x9d, 0xa8, 0xfe, 0x98, 0x9e, 0xd9, 0xd9, 0x5d, 0x5b, 0x15, 0xef, 0xc6, 0xdc, 0x34, 0xef,
|
||||
0xbd, 0x7e, 0xbf, 0xd7, 0xaf, 0xdf, 0x7b, 0xfd, 0xfa, 0xad, 0x40, 0x7d, 0xff, 0x25, 0x5a, 0x36,
|
||||
0xdd, 0xe5, 0xfd, 0x70, 0x97, 0xf8, 0x0e, 0x09, 0x08, 0x5d, 0x6e, 0x12, 0xa7, 0xe6, 0xfa, 0xcb,
|
||||
0x92, 0x81, 0x3d, 0x93, 0x1c, 0x06, 0xc4, 0xa1, 0xa6, 0xeb, 0xd0, 0x2b, 0xd8, 0x33, 0x29, 0xf1,
|
||||
0x9b, 0xc4, 0x5f, 0xf6, 0xf6, 0x1b, 0x8c, 0x47, 0x3b, 0x05, 0x96, 0x9b, 0x57, 0x77, 0x49, 0x80,
|
||||
0xaf, 0x2e, 0x37, 0x88, 0x43, 0x7c, 0x1c, 0x90, 0x5a, 0xd9, 0xf3, 0xdd, 0xc0, 0x85, 0x5f, 0x17,
|
||||
0xea, 0xca, 0x1d, 0xd2, 0x6f, 0x2b, 0x75, 0x65, 0x6f, 0xbf, 0xc1, 0x78, 0xb4, 0x53, 0xa0, 0x2c,
|
||||
0xd5, 0xcd, 0x5f, 0x69, 0x98, 0xc1, 0x5e, 0xb8, 0x5b, 0x36, 0x5c, 0x7b, 0xb9, 0xe1, 0x36, 0xdc,
|
||||
0x65, 0xae, 0x75, 0x37, 0xac, 0xf3, 0x2f, 0xfe, 0xc1, 0xff, 0x12, 0x68, 0xf3, 0xcf, 0xc7, 0xc6,
|
||||
0xdb, 0xd8, 0xd8, 0x33, 0x1d, 0xe2, 0x1f, 0xc5, 0x16, 0xdb, 0x24, 0xc0, 0xcb, 0xcd, 0x2e, 0x1b,
|
||||
0xe7, 0x97, 0xfb, 0xad, 0xf2, 0x43, 0x27, 0x30, 0x6d, 0xd2, 0xb5, 0xe0, 0xab, 0x8f, 0x5a, 0x40,
|
||||
0x8d, 0x3d, 0x62, 0xe3, 0xf4, 0xba, 0xd2, 0xb1, 0x06, 0x66, 0x57, 0x5d, 0xa7, 0x49, 0x7c, 0xb6,
|
||||
0x4b, 0x44, 0xee, 0x86, 0x84, 0x06, 0xb0, 0x02, 0xb2, 0xa1, 0x59, 0xd3, 0xb5, 0x05, 0x6d, 0x69,
|
||||
0xbc, 0xf2, 0xdc, 0xfd, 0x56, 0xf1, 0x54, 0xbb, 0x55, 0xcc, 0xde, 0xda, 0x58, 0x3b, 0x6e, 0x15,
|
||||
0x17, 0xfb, 0x21, 0x05, 0x47, 0x1e, 0xa1, 0xe5, 0x5b, 0x1b, 0x6b, 0x88, 0x2d, 0x86, 0xaf, 0x82,
|
||||
0xd9, 0x1a, 0xa1, 0xa6, 0x4f, 0x6a, 0x2b, 0x3b, 0x1b, 0xb7, 0x85, 0x7e, 0x3d, 0xc3, 0x35, 0x9e,
|
||||
0x93, 0x1a, 0x67, 0xd7, 0xd2, 0x02, 0xa8, 0x7b, 0x0d, 0xfc, 0x16, 0x18, 0x73, 0x77, 0xef, 0x10,
|
||||
0x23, 0xa0, 0x7a, 0x76, 0x21, 0xbb, 0x34, 0x71, 0xed, 0x4a, 0x39, 0x3e, 0x41, 0x65, 0x02, 0x3f,
|
||||
0x36, 0xb9, 0xd9, 0x32, 0xc2, 0x07, 0xeb, 0xd1, 0xc9, 0x55, 0xa6, 0x25, 0xda, 0xd8, 0xb6, 0xd0,
|
||||
0x82, 0x22, 0x75, 0xa5, 0x3f, 0x64, 0x00, 0x4c, 0x6e, 0x9e, 0x7a, 0xae, 0x43, 0xc9, 0x40, 0x76,
|
||||
0x4f, 0xc1, 0x8c, 0xc1, 0x35, 0x07, 0xa4, 0x26, 0x71, 0xf5, 0xcc, 0x67, 0xb1, 0x5e, 0x97, 0xf8,
|
||||
0x33, 0xab, 0x29, 0x75, 0xa8, 0x0b, 0x00, 0xde, 0x04, 0xa3, 0x3e, 0xa1, 0xa1, 0x15, 0xe8, 0xd9,
|
||||
0x05, 0x6d, 0x69, 0xe2, 0xda, 0xe5, 0xbe, 0x50, 0x3c, 0xbe, 0x59, 0xf0, 0x95, 0x9b, 0x57, 0xcb,
|
||||
0xd5, 0x00, 0x07, 0x21, 0xad, 0x9c, 0x96, 0x48, 0xa3, 0x88, 0xeb, 0x40, 0x52, 0x57, 0xe9, 0xc7,
|
||||
0x19, 0x30, 0x93, 0xf4, 0x52, 0xd3, 0x24, 0x07, 0xf0, 0x00, 0x8c, 0xf9, 0x22, 0x58, 0xb8, 0x9f,
|
||||
0x26, 0xae, 0xed, 0x94, 0x1f, 0x2b, 0xad, 0xca, 0x5d, 0x41, 0x58, 0x99, 0x60, 0x67, 0x26, 0x3f,
|
||||
0x50, 0x84, 0x06, 0xdf, 0x05, 0x79, 0x5f, 0x1e, 0x14, 0x8f, 0xa6, 0x89, 0x6b, 0xdf, 0x1c, 0x20,
|
||||
0xb2, 0x50, 0x5c, 0x99, 0x6c, 0xb7, 0x8a, 0xf9, 0xe8, 0x0b, 0x29, 0xc0, 0xd2, 0x47, 0x19, 0x50,
|
||||
0x58, 0x0d, 0x69, 0xe0, 0xda, 0x88, 0x50, 0x37, 0xf4, 0x0d, 0xb2, 0xea, 0x5a, 0xa1, 0xed, 0xac,
|
||||
0x91, 0xba, 0xe9, 0x98, 0x01, 0x8b, 0xd6, 0x05, 0x30, 0xe2, 0x60, 0x9b, 0xc8, 0xe8, 0x99, 0x94,
|
||||
0x3e, 0x1d, 0xd9, 0xc2, 0x36, 0x41, 0x9c, 0xc3, 0x24, 0x58, 0xb0, 0xc8, 0x5c, 0x50, 0x12, 0x37,
|
||||
0x8f, 0x3c, 0x82, 0x38, 0x07, 0x3e, 0x03, 0x46, 0xeb, 0xae, 0x6f, 0x63, 0x71, 0x8e, 0xe3, 0xf1,
|
||||
0xc9, 0xbc, 0xc2, 0xa9, 0x48, 0x72, 0xe1, 0x0b, 0x60, 0xa2, 0x46, 0xa8, 0xe1, 0x9b, 0x1e, 0x83,
|
||||
0xd6, 0x47, 0xb8, 0xf0, 0x19, 0x29, 0x3c, 0xb1, 0x16, 0xb3, 0x50, 0x52, 0x0e, 0x5e, 0x06, 0x79,
|
||||
0xcf, 0x37, 0x5d, 0xdf, 0x0c, 0x8e, 0xf4, 0xdc, 0x82, 0xb6, 0x94, 0xab, 0xcc, 0xc8, 0x35, 0xf9,
|
||||
0x1d, 0x49, 0x47, 0x4a, 0x02, 0x2e, 0x80, 0xfc, 0xf5, 0xea, 0xf6, 0xd6, 0x0e, 0x0e, 0xf6, 0xf4,
|
||||
0x51, 0x8e, 0x30, 0xc2, 0xa4, 0x51, 0xfe, 0x8e, 0xa4, 0x96, 0xde, 0xcb, 0x00, 0x3d, 0xed, 0x95,
|
||||
0xc8, 0xa5, 0xf0, 0x15, 0x90, 0xa7, 0x01, 0xab, 0x38, 0x8d, 0x23, 0xe9, 0x93, 0x67, 0x23, 0xb0,
|
||||
0xaa, 0xa4, 0x1f, 0xb7, 0x8a, 0x67, 0xe3, 0x15, 0x11, 0x95, 0xfb, 0x43, 0xad, 0x85, 0xbf, 0xd5,
|
||||
0xc0, 0x99, 0x03, 0xb2, 0xbb, 0xe7, 0xba, 0xfb, 0xab, 0x96, 0x49, 0x9c, 0x60, 0xd5, 0x75, 0xea,
|
||||
0x66, 0x43, 0xc6, 0x00, 0x7a, 0xcc, 0x18, 0x78, 0xad, 0x5b, 0x73, 0xe5, 0xe9, 0x76, 0xab, 0x78,
|
||||
0xa6, 0x07, 0x03, 0xf5, 0xb2, 0xa3, 0xf4, 0x7e, 0x36, 0xed, 0x84, 0x44, 0x50, 0xbc, 0x03, 0xf2,
|
||||
0x2c, 0xd9, 0x6a, 0x38, 0xc0, 0x32, 0x5d, 0x9e, 0x3b, 0x59, 0x6a, 0x8a, 0xcc, 0xde, 0x24, 0x01,
|
||||
0xae, 0x40, 0xe9, 0x36, 0x10, 0xd3, 0x90, 0xd2, 0x0a, 0xbf, 0x07, 0x46, 0xa8, 0x47, 0x0c, 0xe9,
|
||||
0x8e, 0xd7, 0x1f, 0x37, 0x25, 0xfa, 0x6c, 0xa4, 0xea, 0x11, 0x23, 0x8e, 0x58, 0xf6, 0x85, 0x38,
|
||||
0x2c, 0xfc, 0x40, 0x03, 0xa3, 0x94, 0x97, 0x11, 0x59, 0x7a, 0xde, 0x1c, 0x96, 0x05, 0xa9, 0x5a,
|
||||
0x25, 0xbe, 0x91, 0x04, 0x2f, 0xfd, 0x27, 0x03, 0x16, 0xfb, 0x2d, 0x5d, 0x75, 0x9d, 0x9a, 0x38,
|
||||
0x8e, 0x0d, 0x99, 0x81, 0x22, 0x1e, 0x5f, 0x48, 0x66, 0xe0, 0x71, 0xab, 0x78, 0xe9, 0x91, 0x0a,
|
||||
0x12, 0xa9, 0xfa, 0x35, 0xb5, 0x6f, 0x91, 0xce, 0x8b, 0x9d, 0x86, 0x1d, 0xb7, 0x8a, 0xd3, 0x6a,
|
||||
0x59, 0xa7, 0xad, 0xb0, 0x09, 0xa0, 0x85, 0x69, 0x70, 0xd3, 0xc7, 0x0e, 0x15, 0x6a, 0x4d, 0x9b,
|
||||
0x48, 0xf7, 0x3d, 0x7b, 0xb2, 0xf0, 0x60, 0x2b, 0x2a, 0xf3, 0x12, 0x12, 0xde, 0xe8, 0xd2, 0x86,
|
||||
0x7a, 0x20, 0xb0, 0xea, 0xe2, 0x13, 0x4c, 0x55, 0xc1, 0x48, 0xd4, 0x7d, 0x46, 0x45, 0x92, 0x0b,
|
||||
0xbf, 0x04, 0xc6, 0x6c, 0x42, 0x29, 0x6e, 0x10, 0x5e, 0x25, 0xc6, 0xe3, 0x8b, 0x74, 0x53, 0x90,
|
||||
0x51, 0xc4, 0x67, 0x5d, 0xc4, 0xf9, 0x7e, 0x5e, 0xbb, 0x61, 0xd2, 0x00, 0xbe, 0xd1, 0x95, 0x00,
|
||||
0xe5, 0x93, 0xed, 0x90, 0xad, 0xe6, 0xe1, 0xaf, 0x4a, 0x54, 0x44, 0x49, 0x04, 0xff, 0x77, 0x41,
|
||||
0xce, 0x0c, 0x88, 0x1d, 0xdd, 0xb0, 0xaf, 0x0d, 0x29, 0xf6, 0x2a, 0x53, 0xd2, 0x86, 0xdc, 0x06,
|
||||
0x43, 0x43, 0x02, 0xb4, 0xf4, 0xc7, 0x0c, 0xb8, 0xd0, 0x6f, 0x09, 0x2b, 0xfb, 0x94, 0x79, 0xdc,
|
||||
0xb3, 0x42, 0x1f, 0x5b, 0x32, 0xe2, 0x94, 0xc7, 0x77, 0x38, 0x15, 0x49, 0x2e, 0x2b, 0xcc, 0xd4,
|
||||
0x74, 0x1a, 0xa1, 0x85, 0x7d, 0x19, 0x4e, 0x6a, 0xd7, 0x55, 0x49, 0x47, 0x4a, 0x02, 0x96, 0x01,
|
||||
0xa0, 0x7b, 0xae, 0x1f, 0x70, 0x0c, 0xde, 0x1a, 0x8d, 0x57, 0x4e, 0xb3, 0x02, 0x51, 0x55, 0x54,
|
||||
0x94, 0x90, 0x60, 0xf7, 0xce, 0xbe, 0xe9, 0xd4, 0xe4, 0xa9, 0xab, 0x2c, 0xfe, 0x86, 0xe9, 0xd4,
|
||||
0x10, 0xe7, 0x30, 0x7c, 0xcb, 0xa4, 0x01, 0xa3, 0xc8, 0x23, 0xef, 0xf0, 0x3a, 0x97, 0x54, 0x12,
|
||||
0x0c, 0xdf, 0x60, 0xb5, 0xd9, 0xf5, 0x4d, 0x42, 0xf5, 0xd1, 0x18, 0x7f, 0x55, 0x51, 0x51, 0x42,
|
||||
0xa2, 0xf4, 0xeb, 0x7c, 0xff, 0x20, 0x61, 0xa5, 0x04, 0x5e, 0x04, 0xb9, 0x86, 0xef, 0x86, 0x9e,
|
||||
0xf4, 0x92, 0xf2, 0xf6, 0xab, 0x8c, 0x88, 0x04, 0x8f, 0x45, 0x65, 0xb3, 0xa3, 0x99, 0x54, 0x51,
|
||||
0x19, 0xb5, 0x90, 0x11, 0x1f, 0xfe, 0x50, 0x03, 0x39, 0x47, 0x3a, 0x87, 0x85, 0xdc, 0x1b, 0x43,
|
||||
0x8a, 0x0b, 0xee, 0xde, 0xd8, 0x5c, 0xe1, 0x79, 0x81, 0x0c, 0x9f, 0x07, 0x39, 0x6a, 0xb8, 0x1e,
|
||||
0x91, 0x5e, 0x2f, 0x44, 0x42, 0x55, 0x46, 0x3c, 0x6e, 0x15, 0xa7, 0x22, 0x75, 0x9c, 0x80, 0x84,
|
||||
0x30, 0xfc, 0x91, 0x06, 0x40, 0x13, 0x5b, 0x66, 0x0d, 0xf3, 0x8b, 0x3d, 0xc7, 0xcd, 0x1f, 0x6c,
|
||||
0x58, 0xdf, 0x56, 0xea, 0xc5, 0xa1, 0xc5, 0xdf, 0x28, 0x01, 0x0d, 0x3f, 0xd4, 0xc0, 0x24, 0x0d,
|
||||
0x77, 0x7d, 0xb9, 0x8a, 0xf2, 0x16, 0x60, 0xe2, 0xda, 0xb7, 0x07, 0x6a, 0x4b, 0x35, 0x01, 0x50,
|
||||
0x99, 0x69, 0xb7, 0x8a, 0x93, 0x49, 0x0a, 0xea, 0x30, 0x00, 0xfe, 0x54, 0x03, 0x79, 0x79, 0xc2,
|
||||
0x54, 0x1f, 0xe3, 0x09, 0xff, 0xd6, 0x90, 0x0e, 0x56, 0x46, 0x54, 0x9c, 0x05, 0x92, 0x40, 0x91,
|
||||
0xb2, 0x00, 0xfe, 0x5d, 0x03, 0x3a, 0xae, 0x89, 0x02, 0x8f, 0xad, 0x1d, 0xdf, 0x74, 0x02, 0xe2,
|
||||
0x8b, 0xae, 0x90, 0xea, 0x79, 0x6e, 0xde, 0x60, 0xef, 0xc2, 0x74, 0xc7, 0x59, 0x59, 0x90, 0xd6,
|
||||
0xe9, 0x2b, 0x7d, 0xcc, 0x40, 0x7d, 0x0d, 0xe4, 0x81, 0x66, 0xa8, 0xd6, 0x4b, 0x1f, 0x1f, 0x42,
|
||||
0xa0, 0xc5, 0x9d, 0x9d, 0xac, 0x0e, 0x71, 0xbb, 0x9d, 0x80, 0x2e, 0x7d, 0x98, 0x4d, 0xb7, 0xd6,
|
||||
0xe9, 0x4b, 0x1f, 0xde, 0x13, 0xc6, 0x8a, 0xad, 0x50, 0x5d, 0xe3, 0xce, 0x7d, 0x67, 0x48, 0x67,
|
||||
0xaf, 0x6e, 0xed, 0xb8, 0xf1, 0x52, 0x24, 0x8a, 0x12, 0x76, 0xc0, 0x5f, 0x69, 0x60, 0x0a, 0x1b,
|
||||
0x06, 0xf1, 0x02, 0x52, 0x13, 0xb5, 0x38, 0xf3, 0x39, 0x94, 0x9b, 0x39, 0x69, 0xd5, 0xd4, 0x4a,
|
||||
0x12, 0x1a, 0x75, 0x5a, 0x02, 0x5f, 0x06, 0xa7, 0x69, 0xe0, 0xfa, 0xa4, 0x16, 0x45, 0xae, 0xbc,
|
||||
0x27, 0x60, 0xbb, 0x55, 0x3c, 0x5d, 0xed, 0xe0, 0xa0, 0x94, 0x64, 0xe9, 0xd3, 0x11, 0x50, 0x7c,
|
||||
0x44, 0x66, 0x9c, 0xe0, 0xb5, 0xf3, 0x0c, 0x18, 0xe5, 0xdb, 0xad, 0x71, 0xaf, 0xe4, 0x13, 0x9d,
|
||||
0x1b, 0xa7, 0x22, 0xc9, 0x65, 0x75, 0x9d, 0xe1, 0xb3, 0x6e, 0x23, 0xcb, 0x05, 0x55, 0x5d, 0xaf,
|
||||
0x0a, 0x32, 0x8a, 0xf8, 0xf0, 0x5d, 0x30, 0x2a, 0xa6, 0x19, 0xbc, 0xa8, 0x0e, 0xb1, 0x30, 0x02,
|
||||
0x6e, 0x27, 0x87, 0x42, 0x12, 0xb2, 0xbb, 0x20, 0xe6, 0x9e, 0x74, 0x41, 0x7c, 0x68, 0x05, 0x1a,
|
||||
0xfd, 0x3f, 0xaf, 0x40, 0xa5, 0xff, 0x6a, 0xe9, 0xbc, 0x4f, 0x6c, 0xb5, 0x6a, 0x60, 0x8b, 0xc0,
|
||||
0x35, 0x30, 0xc3, 0x1e, 0x19, 0x88, 0x78, 0x96, 0x69, 0x60, 0xca, 0x5f, 0xa2, 0x22, 0xe0, 0xd4,
|
||||
0x70, 0xa4, 0x9a, 0xe2, 0xa3, 0xae, 0x15, 0xf0, 0x3a, 0x80, 0xa2, 0xf1, 0xee, 0xd0, 0x23, 0x7a,
|
||||
0x08, 0xd5, 0x42, 0x57, 0xbb, 0x24, 0x50, 0x8f, 0x55, 0x70, 0x15, 0xcc, 0x5a, 0x78, 0x97, 0x58,
|
||||
0x55, 0x62, 0x11, 0x23, 0x70, 0x7d, 0xae, 0x4a, 0xbc, 0xd5, 0xe7, 0xda, 0xad, 0xe2, 0xec, 0x8d,
|
||||
0x34, 0x13, 0x75, 0xcb, 0x97, 0x16, 0xd3, 0xe9, 0x95, 0xdc, 0xb8, 0x78, 0xce, 0xfc, 0x2e, 0x03,
|
||||
0xe6, 0xfb, 0x47, 0x06, 0x7c, 0x2f, 0x7e, 0x75, 0x89, 0xa6, 0xfa, 0xad, 0x61, 0x45, 0xa1, 0x7c,
|
||||
0x76, 0x81, 0xee, 0x27, 0x17, 0xfc, 0x3e, 0xeb, 0x70, 0xb0, 0x15, 0x4d, 0x63, 0xde, 0x1c, 0x9a,
|
||||
0x09, 0x0c, 0xa4, 0x32, 0x2e, 0x9a, 0x27, 0x6c, 0xf1, 0x5e, 0x09, 0x5b, 0xa4, 0xf4, 0x27, 0x2d,
|
||||
0xfd, 0xf0, 0x8e, 0x33, 0x18, 0xfe, 0x4c, 0x03, 0xd3, 0xae, 0x47, 0x9c, 0x95, 0x9d, 0x8d, 0xdb,
|
||||
0x5f, 0x11, 0x99, 0x2c, 0x5d, 0xb5, 0xf5, 0x98, 0x76, 0x5e, 0xaf, 0x6e, 0x6f, 0x09, 0x85, 0x3b,
|
||||
0xbe, 0xeb, 0xd1, 0xca, 0x99, 0x76, 0xab, 0x38, 0xbd, 0xdd, 0x09, 0x85, 0xd2, 0xd8, 0x25, 0x1b,
|
||||
0xcc, 0xad, 0x1f, 0x06, 0xc4, 0x77, 0xb0, 0xb5, 0xe6, 0x1a, 0xa1, 0x4d, 0x9c, 0x40, 0x18, 0x9a,
|
||||
0x1a, 0xe5, 0x68, 0x27, 0x1c, 0xe5, 0x5c, 0x00, 0xd9, 0xd0, 0xb7, 0x64, 0x14, 0x4f, 0xa8, 0x51,
|
||||
0x25, 0xba, 0x81, 0x18, 0xbd, 0xb4, 0x08, 0x46, 0x98, 0x9d, 0xf0, 0x1c, 0xc8, 0xfa, 0xf8, 0x80,
|
||||
0x6b, 0x9d, 0xac, 0x8c, 0x31, 0x11, 0x84, 0x0f, 0x10, 0xa3, 0x95, 0xfe, 0x75, 0x1e, 0x4c, 0xa7,
|
||||
0xf6, 0x02, 0xe7, 0x41, 0x46, 0xcd, 0x3f, 0x81, 0x54, 0x9a, 0xd9, 0x58, 0x43, 0x19, 0xb3, 0x06,
|
||||
0x5f, 0x54, 0xc5, 0x57, 0x80, 0x16, 0x55, 0x3d, 0xe7, 0x54, 0xd6, 0xd2, 0xc6, 0xea, 0x98, 0x21,
|
||||
0x51, 0xe1, 0x64, 0x36, 0x90, 0xba, 0xcc, 0x12, 0x61, 0x03, 0xa9, 0x23, 0x46, 0xfb, 0xac, 0x73,
|
||||
0xac, 0x68, 0x90, 0x96, 0x3b, 0xc1, 0x20, 0x6d, 0xf4, 0xa1, 0x83, 0xb4, 0x8b, 0x20, 0x17, 0x98,
|
||||
0x81, 0x45, 0xf4, 0xb1, 0xce, 0x97, 0xc7, 0x4d, 0x46, 0x44, 0x82, 0x07, 0xef, 0x80, 0xb1, 0x1a,
|
||||
0xa9, 0xe3, 0xd0, 0x0a, 0xf4, 0x3c, 0x0f, 0xa1, 0xd5, 0x01, 0x84, 0x90, 0x98, 0x72, 0xae, 0x09,
|
||||
0xbd, 0x28, 0x02, 0x80, 0x97, 0xc0, 0x98, 0x8d, 0x0f, 0x4d, 0x3b, 0xb4, 0x79, 0x4f, 0xa6, 0x09,
|
||||
0xb1, 0x4d, 0x41, 0x42, 0x11, 0x8f, 0x55, 0x46, 0x72, 0x68, 0x58, 0x21, 0x35, 0x9b, 0x44, 0x32,
|
||||
0x75, 0xc0, 0x6f, 0x4f, 0x55, 0x19, 0xd7, 0x53, 0x7c, 0xd4, 0xb5, 0x82, 0x83, 0x99, 0x0e, 0x5f,
|
||||
0x3c, 0x91, 0x00, 0x13, 0x24, 0x14, 0xf1, 0x3a, 0xc1, 0xa4, 0xfc, 0x64, 0x3f, 0x30, 0xb9, 0xb8,
|
||||
0x6b, 0x05, 0xfc, 0x32, 0x18, 0xb7, 0xf1, 0xe1, 0x0d, 0xe2, 0x34, 0x82, 0x3d, 0x7d, 0x6a, 0x41,
|
||||
0x5b, 0xca, 0x56, 0xa6, 0xda, 0xad, 0xe2, 0xf8, 0x66, 0x44, 0x44, 0x31, 0x9f, 0x0b, 0x9b, 0x8e,
|
||||
0x14, 0x3e, 0x9d, 0x10, 0x8e, 0x88, 0x28, 0xe6, 0xb3, 0x0e, 0xc2, 0xc3, 0x01, 0x4b, 0x2e, 0x7d,
|
||||
0xba, 0xf3, 0x65, 0xb8, 0x23, 0xc8, 0x28, 0xe2, 0xc3, 0x25, 0x90, 0xb7, 0xf1, 0x21, 0x7f, 0xc5,
|
||||
0xeb, 0x33, 0x5c, 0x2d, 0x9f, 0xf8, 0x6e, 0x4a, 0x1a, 0x52, 0x5c, 0x2e, 0x69, 0x3a, 0x42, 0x72,
|
||||
0x36, 0x21, 0x29, 0x69, 0x48, 0x71, 0x59, 0x10, 0x87, 0x8e, 0x79, 0x37, 0x24, 0x42, 0x18, 0x72,
|
||||
0xcf, 0xa8, 0x20, 0xbe, 0x15, 0xb3, 0x50, 0x52, 0x8e, 0xbd, 0xa2, 0xed, 0xd0, 0x0a, 0x4c, 0xcf,
|
||||
0x22, 0xdb, 0x75, 0xfd, 0x0c, 0xf7, 0x3f, 0xef, 0x93, 0x37, 0x15, 0x15, 0x25, 0x24, 0x20, 0x01,
|
||||
0x23, 0xc4, 0x09, 0x6d, 0xfd, 0x29, 0x7e, 0xb1, 0x0f, 0x24, 0x04, 0x55, 0xe6, 0xac, 0x3b, 0xa1,
|
||||
0x8d, 0xb8, 0x7a, 0xf8, 0x22, 0x98, 0xb2, 0xf1, 0x21, 0x2b, 0x07, 0xc4, 0x0f, 0xd8, 0xfb, 0x7e,
|
||||
0x8e, 0x6f, 0x7e, 0x96, 0x75, 0x9c, 0x9b, 0x49, 0x06, 0xea, 0x94, 0xe3, 0x0b, 0x4d, 0x27, 0xb1,
|
||||
0xf0, 0x6c, 0x62, 0x61, 0x92, 0x81, 0x3a, 0xe5, 0x98, 0xa7, 0x7d, 0x72, 0x37, 0x34, 0x7d, 0x52,
|
||||
0xd3, 0x9f, 0xe6, 0x4d, 0xaa, 0x9c, 0xc2, 0x0b, 0x1a, 0x52, 0x5c, 0xd8, 0x8c, 0xc6, 0x3d, 0x3a,
|
||||
0x4f, 0xc3, 0x5b, 0x83, 0xad, 0xe4, 0xdb, 0xfe, 0x8a, 0xef, 0xe3, 0x23, 0x71, 0xd3, 0x24, 0x07,
|
||||
0x3d, 0x90, 0x82, 0x1c, 0xb6, 0xac, 0xed, 0xba, 0x7e, 0x8e, 0xfb, 0x7e, 0xd0, 0x37, 0x88, 0xaa,
|
||||
0x3a, 0x2b, 0x0c, 0x04, 0x09, 0x2c, 0x06, 0xea, 0x3a, 0x2c, 0x34, 0xe6, 0x87, 0x0b, 0xba, 0xcd,
|
||||
0x40, 0x90, 0xc0, 0xe2, 0x3b, 0x75, 0x8e, 0xb6, 0xeb, 0xfa, 0x17, 0x86, 0xbc, 0x53, 0x06, 0x82,
|
||||
0x04, 0x16, 0x34, 0x41, 0xd6, 0x71, 0x03, 0xfd, 0xfc, 0x50, 0xae, 0x67, 0x7e, 0xe1, 0x6c, 0xb9,
|
||||
0x01, 0x62, 0x18, 0xf0, 0x97, 0x1a, 0x00, 0x5e, 0x1c, 0xa2, 0x17, 0x06, 0x32, 0x45, 0x48, 0x41,
|
||||
0x96, 0xe3, 0xd8, 0x5e, 0x77, 0x02, 0xff, 0x28, 0x7e, 0x47, 0x26, 0x72, 0x20, 0x61, 0x05, 0xfc,
|
||||
0xbd, 0x06, 0x9e, 0x4a, 0xb6, 0xc9, 0xca, 0xbc, 0x02, 0xf7, 0xc8, 0xcd, 0x41, 0x87, 0x79, 0xc5,
|
||||
0x75, 0xad, 0x8a, 0xde, 0x6e, 0x15, 0x9f, 0x5a, 0xe9, 0x81, 0x8a, 0x7a, 0xda, 0x02, 0xff, 0xac,
|
||||
0x81, 0x59, 0x59, 0x45, 0x13, 0x16, 0x16, 0xb9, 0x03, 0xc9, 0xa0, 0x1d, 0x98, 0xc6, 0x11, 0x7e,
|
||||
0x54, 0xbf, 0x1e, 0x77, 0xf1, 0x51, 0xb7, 0x69, 0xf0, 0x6f, 0x1a, 0x98, 0xac, 0x11, 0x8f, 0x38,
|
||||
0x35, 0xe2, 0x18, 0xcc, 0xd6, 0x85, 0x81, 0x8c, 0x0d, 0xd2, 0xb6, 0xae, 0x25, 0x20, 0x84, 0x99,
|
||||
0x65, 0x69, 0xe6, 0x64, 0x92, 0x75, 0xdc, 0x2a, 0x9e, 0x8d, 0x97, 0x26, 0x39, 0xa8, 0xc3, 0x4a,
|
||||
0xf8, 0x91, 0x06, 0xa6, 0xe3, 0x03, 0x10, 0x57, 0xca, 0xe2, 0x10, 0xe3, 0x80, 0xb7, 0xaf, 0x2b,
|
||||
0x9d, 0x80, 0x28, 0x6d, 0x01, 0xfc, 0x8b, 0xc6, 0x3a, 0xb5, 0xe8, 0xdd, 0x47, 0xf5, 0x12, 0xf7,
|
||||
0xe5, 0xdb, 0x03, 0xf7, 0xa5, 0x42, 0x10, 0xae, 0xbc, 0x1c, 0xb7, 0x82, 0x8a, 0x73, 0xdc, 0x2a,
|
||||
0xce, 0x25, 0x3d, 0xa9, 0x18, 0x28, 0x69, 0x21, 0xfc, 0x89, 0x06, 0x26, 0x49, 0xdc, 0x71, 0x53,
|
||||
0xfd, 0xe2, 0x40, 0x9c, 0xd8, 0xb3, 0x89, 0x17, 0x2f, 0xf5, 0x04, 0x8b, 0xa2, 0x0e, 0x6c, 0xd6,
|
||||
0x41, 0x92, 0x43, 0x6c, 0x7b, 0x16, 0xd1, 0xbf, 0x38, 0xe0, 0x0e, 0x72, 0x5d, 0xe8, 0x45, 0x11,
|
||||
0x00, 0xbc, 0x0c, 0xf2, 0x4e, 0x68, 0x59, 0x78, 0xd7, 0x22, 0xfa, 0x25, 0xde, 0x8b, 0xa8, 0x29,
|
||||
0xe6, 0x96, 0xa4, 0x23, 0x25, 0x31, 0xcf, 0xde, 0x49, 0xa9, 0x3c, 0x83, 0x33, 0x20, 0xbb, 0x4f,
|
||||
0xe4, 0x8f, 0xb6, 0x88, 0xfd, 0x09, 0x6b, 0x20, 0xd7, 0xc4, 0x56, 0x18, 0x3d, 0xf5, 0x06, 0x5c,
|
||||
0xa3, 0x91, 0x50, 0xfe, 0x72, 0xe6, 0x25, 0x6d, 0xfe, 0x9e, 0x06, 0xce, 0xf6, 0x4e, 0xff, 0x27,
|
||||
0x6a, 0xd6, 0x6f, 0x34, 0x30, 0xdb, 0x95, 0xe9, 0x3d, 0x2c, 0xba, 0xdb, 0x69, 0xd1, 0xeb, 0x83,
|
||||
0x4e, 0xd9, 0x6a, 0xe0, 0x9b, 0x4e, 0x83, 0xf7, 0x29, 0x49, 0xf3, 0x7e, 0xae, 0x81, 0x99, 0x74,
|
||||
0xf2, 0x3c, 0x49, 0x7f, 0x95, 0xee, 0x65, 0xc0, 0xd9, 0xde, 0xed, 0x15, 0xf4, 0xd5, 0x3b, 0x72,
|
||||
0x38, 0xef, 0xf1, 0x5e, 0xb3, 0xbb, 0x0f, 0x34, 0x30, 0x71, 0x47, 0xc9, 0x45, 0x3f, 0x17, 0x0e,
|
||||
0x7c, 0x12, 0x10, 0x55, 0xab, 0x98, 0x41, 0x51, 0x12, 0xb7, 0xf4, 0x57, 0x0d, 0xcc, 0xf5, 0x2c,
|
||||
0xc3, 0xec, 0xc1, 0x8a, 0x2d, 0xcb, 0x3d, 0x10, 0x03, 0x9d, 0xc4, 0xb4, 0x74, 0x85, 0x53, 0x91,
|
||||
0xe4, 0x26, 0xbc, 0x97, 0xf9, 0xbc, 0xbc, 0x57, 0xfa, 0x87, 0x06, 0xce, 0x3f, 0x2c, 0x12, 0x9f,
|
||||
0xc8, 0x91, 0x2e, 0x81, 0xbc, 0x6c, 0xa1, 0x8e, 0xf8, 0x71, 0xca, 0x57, 0x83, 0x2c, 0x1a, 0xfc,
|
||||
0xff, 0x58, 0xc4, 0x5f, 0xa5, 0xf7, 0x35, 0x30, 0x53, 0x25, 0x7e, 0xd3, 0x34, 0x08, 0x22, 0x75,
|
||||
0xe2, 0x13, 0xc7, 0x20, 0x70, 0x19, 0x8c, 0xf3, 0xdf, 0xe9, 0x3c, 0x6c, 0x44, 0x43, 0xec, 0x59,
|
||||
0xe9, 0xf2, 0xf1, 0xad, 0x88, 0x81, 0x62, 0x19, 0x35, 0xf0, 0xce, 0xf4, 0x1d, 0x78, 0x9f, 0x07,
|
||||
0x23, 0x5e, 0x3c, 0x0e, 0xcc, 0x33, 0x2e, 0x9f, 0x00, 0x72, 0x6a, 0xe9, 0x9f, 0x1a, 0xe8, 0xf5,
|
||||
0x3f, 0x25, 0xb0, 0x09, 0xc6, 0xa8, 0x30, 0x4e, 0x3a, 0x6f, 0xfb, 0x31, 0x9d, 0x97, 0xde, 0xaa,
|
||||
0xb8, 0x26, 0x22, 0x6a, 0x04, 0xc6, 0xfc, 0x67, 0xe0, 0x4a, 0xe8, 0xd4, 0xe4, 0x00, 0x6f, 0x52,
|
||||
0xf8, 0x6f, 0x75, 0x45, 0xd0, 0x90, 0xe2, 0xc2, 0x73, 0x62, 0xd4, 0x94, 0x98, 0xdf, 0x44, 0x63,
|
||||
0xa6, 0xca, 0x95, 0xfb, 0x0f, 0x0a, 0xa7, 0x3e, 0x7e, 0x50, 0x38, 0xf5, 0xc9, 0x83, 0xc2, 0xa9,
|
||||
0x1f, 0xb4, 0x0b, 0xda, 0xfd, 0x76, 0x41, 0xfb, 0xb8, 0x5d, 0xd0, 0x3e, 0x69, 0x17, 0xb4, 0x7f,
|
||||
0xb7, 0x0b, 0xda, 0x2f, 0x3e, 0x2d, 0x9c, 0xfa, 0xce, 0x98, 0x34, 0xed, 0x7f, 0x01, 0x00, 0x00,
|
||||
0xff, 0xff, 0x3a, 0x56, 0xbb, 0xc0, 0xe9, 0x29, 0x00, 0x00,
|
||||
// 2783 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xdf, 0x6f, 0x23, 0x57,
|
||||
0xf5, 0xdf, 0xb1, 0xe3, 0xc4, 0xb9, 0x49, 0x36, 0xc9, 0xdd, 0x66, 0x3b, 0x9b, 0x6f, 0x6a, 0x27,
|
||||
0xee, 0xb7, 0x55, 0x28, 0xbb, 0x4e, 0xbb, 0xb4, 0xb4, 0x54, 0xe2, 0x21, 0x76, 0xd2, 0x2a, 0x65,
|
||||
0xf3, 0x83, 0xeb, 0xdd, 0xb6, 0xd0, 0x9f, 0x37, 0xe3, 0x6b, 0x67, 0x36, 0xf3, 0x6b, 0xe7, 0xce,
|
||||
0x38, 0x89, 0x0a, 0x08, 0xa8, 0x2a, 0x10, 0x02, 0x8a, 0xe8, 0xbe, 0x20, 0xe0, 0x01, 0x10, 0x2f,
|
||||
0x3c, 0xc0, 0x03, 0xbc, 0xc1, 0x1f, 0xb0, 0x8f, 0x15, 0x4f, 0x15, 0x42, 0x16, 0xeb, 0xfe, 0x0b,
|
||||
0x48, 0x48, 0x79, 0x42, 0xf7, 0xc7, 0xdc, 0x19, 0x8f, 0xed, 0xdd, 0xa8, 0x6b, 0x77, 0x79, 0xcb,
|
||||
0x9c, 0x73, 0xee, 0xf9, 0x9c, 0x7b, 0xee, 0x39, 0xe7, 0x9e, 0x7b, 0x1c, 0xd0, 0x38, 0x7c, 0x81,
|
||||
0x96, 0x4d, 0x77, 0xed, 0x30, 0xdc, 0x27, 0xbe, 0x43, 0x02, 0x42, 0xd7, 0x5a, 0xc4, 0xa9, 0xbb,
|
||||
0xfe, 0x9a, 0x64, 0x60, 0xcf, 0x24, 0xc7, 0x01, 0x71, 0xa8, 0xe9, 0x3a, 0xf4, 0x0a, 0xf6, 0x4c,
|
||||
0x4a, 0xfc, 0x16, 0xf1, 0xd7, 0xbc, 0xc3, 0x26, 0xe3, 0xd1, 0x6e, 0x81, 0xb5, 0xd6, 0x33, 0xfb,
|
||||
0x24, 0xc0, 0xcf, 0xac, 0x35, 0x89, 0x43, 0x7c, 0x1c, 0x90, 0x7a, 0xd9, 0xf3, 0xdd, 0xc0, 0x85,
|
||||
0x5f, 0x15, 0xea, 0xca, 0x5d, 0xd2, 0xef, 0x28, 0x75, 0x65, 0xef, 0xb0, 0xc9, 0x78, 0xb4, 0x5b,
|
||||
0xa0, 0x2c, 0xd5, 0x2d, 0x5e, 0x69, 0x9a, 0xc1, 0x41, 0xb8, 0x5f, 0x36, 0x5c, 0x7b, 0xad, 0xe9,
|
||||
0x36, 0xdd, 0x35, 0xae, 0x75, 0x3f, 0x6c, 0xf0, 0x2f, 0xfe, 0xc1, 0xff, 0x12, 0x68, 0x8b, 0xcf,
|
||||
0xc6, 0xc6, 0xdb, 0xd8, 0x38, 0x30, 0x1d, 0xe2, 0x9f, 0xc4, 0x16, 0xdb, 0x24, 0xc0, 0x6b, 0xad,
|
||||
0x1e, 0x1b, 0x17, 0xd7, 0x06, 0xad, 0xf2, 0x43, 0x27, 0x30, 0x6d, 0xd2, 0xb3, 0xe0, 0xcb, 0xf7,
|
||||
0x5b, 0x40, 0x8d, 0x03, 0x62, 0xe3, 0xf4, 0xba, 0xd2, 0xa9, 0x06, 0xe6, 0xab, 0xae, 0xd3, 0x22,
|
||||
0x3e, 0xdb, 0x25, 0x22, 0xb7, 0x42, 0x42, 0x03, 0x58, 0x01, 0xd9, 0xd0, 0xac, 0xeb, 0xda, 0xb2,
|
||||
0xb6, 0x3a, 0x59, 0x79, 0xfa, 0x4e, 0xbb, 0x78, 0xae, 0xd3, 0x2e, 0x66, 0x6f, 0x6c, 0x6d, 0x9c,
|
||||
0xb6, 0x8b, 0x2b, 0x83, 0x90, 0x82, 0x13, 0x8f, 0xd0, 0xf2, 0x8d, 0xad, 0x0d, 0xc4, 0x16, 0xc3,
|
||||
0x97, 0xc1, 0x7c, 0x9d, 0x50, 0xd3, 0x27, 0xf5, 0xf5, 0xbd, 0xad, 0x57, 0x85, 0x7e, 0x3d, 0xc3,
|
||||
0x35, 0x5e, 0x92, 0x1a, 0xe7, 0x37, 0xd2, 0x02, 0xa8, 0x77, 0x0d, 0x7c, 0x1d, 0x4c, 0xb8, 0xfb,
|
||||
0x37, 0x89, 0x11, 0x50, 0x3d, 0xbb, 0x9c, 0x5d, 0x9d, 0xba, 0x7a, 0xa5, 0x1c, 0x9f, 0xa0, 0x32,
|
||||
0x81, 0x1f, 0x9b, 0xdc, 0x6c, 0x19, 0xe1, 0xa3, 0xcd, 0xe8, 0xe4, 0x2a, 0xb3, 0x12, 0x6d, 0x62,
|
||||
0x57, 0x68, 0x41, 0x91, 0xba, 0xd2, 0xef, 0x32, 0x00, 0x26, 0x37, 0x4f, 0x3d, 0xd7, 0xa1, 0x64,
|
||||
0x28, 0xbb, 0xa7, 0x60, 0xce, 0xe0, 0x9a, 0x03, 0x52, 0x97, 0xb8, 0x7a, 0xe6, 0xb3, 0x58, 0xaf,
|
||||
0x4b, 0xfc, 0xb9, 0x6a, 0x4a, 0x1d, 0xea, 0x01, 0x80, 0xd7, 0xc1, 0xb8, 0x4f, 0x68, 0x68, 0x05,
|
||||
0x7a, 0x76, 0x59, 0x5b, 0x9d, 0xba, 0x7a, 0x79, 0x20, 0x14, 0x8f, 0x6f, 0x16, 0x7c, 0xe5, 0xd6,
|
||||
0x33, 0xe5, 0x5a, 0x80, 0x83, 0x90, 0x56, 0xce, 0x4b, 0xa4, 0x71, 0xc4, 0x75, 0x20, 0xa9, 0xab,
|
||||
0xf4, 0xc3, 0x0c, 0x98, 0x4b, 0x7a, 0xa9, 0x65, 0x92, 0x23, 0x78, 0x04, 0x26, 0x7c, 0x11, 0x2c,
|
||||
0xdc, 0x4f, 0x53, 0x57, 0xf7, 0xca, 0x0f, 0x94, 0x56, 0xe5, 0x9e, 0x20, 0xac, 0x4c, 0xb1, 0x33,
|
||||
0x93, 0x1f, 0x28, 0x42, 0x83, 0xef, 0x81, 0xbc, 0x2f, 0x0f, 0x8a, 0x47, 0xd3, 0xd4, 0xd5, 0xaf,
|
||||
0x0f, 0x11, 0x59, 0x28, 0xae, 0x4c, 0x77, 0xda, 0xc5, 0x7c, 0xf4, 0x85, 0x14, 0x60, 0xe9, 0xa3,
|
||||
0x0c, 0x28, 0x54, 0x43, 0x1a, 0xb8, 0x36, 0x22, 0xd4, 0x0d, 0x7d, 0x83, 0x54, 0x5d, 0x2b, 0xb4,
|
||||
0x9d, 0x0d, 0xd2, 0x30, 0x1d, 0x33, 0x60, 0xd1, 0xba, 0x0c, 0xc6, 0x1c, 0x6c, 0x13, 0x19, 0x3d,
|
||||
0xd3, 0xd2, 0xa7, 0x63, 0x3b, 0xd8, 0x26, 0x88, 0x73, 0x98, 0x04, 0x0b, 0x16, 0x99, 0x0b, 0x4a,
|
||||
0xe2, 0xfa, 0x89, 0x47, 0x10, 0xe7, 0xc0, 0x27, 0xc1, 0x78, 0xc3, 0xf5, 0x6d, 0x2c, 0xce, 0x71,
|
||||
0x32, 0x3e, 0x99, 0x97, 0x38, 0x15, 0x49, 0x2e, 0x7c, 0x0e, 0x4c, 0xd5, 0x09, 0x35, 0x7c, 0xd3,
|
||||
0x63, 0xd0, 0xfa, 0x18, 0x17, 0xbe, 0x20, 0x85, 0xa7, 0x36, 0x62, 0x16, 0x4a, 0xca, 0xc1, 0xcb,
|
||||
0x20, 0xef, 0xf9, 0xa6, 0xeb, 0x9b, 0xc1, 0x89, 0x9e, 0x5b, 0xd6, 0x56, 0x73, 0x95, 0x39, 0xb9,
|
||||
0x26, 0xbf, 0x27, 0xe9, 0x48, 0x49, 0xc0, 0x65, 0x90, 0x7f, 0xa5, 0xb6, 0xbb, 0xb3, 0x87, 0x83,
|
||||
0x03, 0x7d, 0x9c, 0x23, 0x8c, 0x31, 0x69, 0x94, 0xbf, 0x29, 0xa9, 0xa5, 0x7f, 0x66, 0x80, 0x9e,
|
||||
0xf6, 0x4a, 0xe4, 0x52, 0xf8, 0x12, 0xc8, 0xd3, 0x80, 0x55, 0x9c, 0xe6, 0x89, 0xf4, 0xc9, 0x53,
|
||||
0x11, 0x58, 0x4d, 0xd2, 0x4f, 0xdb, 0xc5, 0x8b, 0xf1, 0x8a, 0x88, 0xca, 0xfd, 0xa1, 0xd6, 0xc2,
|
||||
0x5f, 0x6b, 0xe0, 0xc2, 0x11, 0xd9, 0x3f, 0x70, 0xdd, 0xc3, 0xaa, 0x65, 0x12, 0x27, 0xa8, 0xba,
|
||||
0x4e, 0xc3, 0x6c, 0xca, 0x18, 0x40, 0x0f, 0x18, 0x03, 0xaf, 0xf5, 0x6a, 0xae, 0x3c, 0xda, 0x69,
|
||||
0x17, 0x2f, 0xf4, 0x61, 0xa0, 0x7e, 0x76, 0xc0, 0xd7, 0x81, 0x6e, 0xa4, 0x92, 0x44, 0x16, 0x30,
|
||||
0x51, 0xb6, 0x26, 0x2b, 0x4b, 0x9d, 0x76, 0x51, 0xaf, 0x0e, 0x90, 0x41, 0x03, 0x57, 0x97, 0xde,
|
||||
0xcf, 0xa6, 0xdd, 0x9b, 0x08, 0xb7, 0x77, 0x41, 0x9e, 0xa5, 0x71, 0x1d, 0x07, 0x58, 0x26, 0xe2,
|
||||
0xd3, 0x67, 0x4b, 0x7a, 0x51, 0x33, 0xb6, 0x49, 0x80, 0x2b, 0x50, 0x1e, 0x08, 0x88, 0x69, 0x48,
|
||||
0x69, 0x85, 0xdf, 0x06, 0x63, 0xd4, 0x23, 0x86, 0x74, 0xf4, 0x1b, 0x0f, 0x9a, 0x6c, 0x03, 0x36,
|
||||
0x52, 0xf3, 0x88, 0x11, 0xe7, 0x02, 0xfb, 0x42, 0x1c, 0x16, 0x7e, 0xa0, 0x81, 0x71, 0xca, 0x0b,
|
||||
0x94, 0x2c, 0x6a, 0x6f, 0x8d, 0xca, 0x82, 0x54, 0x15, 0x14, 0xdf, 0x48, 0x82, 0x97, 0xfe, 0x9d,
|
||||
0x01, 0x2b, 0x83, 0x96, 0x56, 0x5d, 0xa7, 0x2e, 0x8e, 0x63, 0x4b, 0xe6, 0xb6, 0x88, 0xf4, 0xe7,
|
||||
0x92, 0xb9, 0x7d, 0xda, 0x2e, 0x3e, 0x71, 0x5f, 0x05, 0x89, 0x22, 0xf0, 0x15, 0xb5, 0x6f, 0x51,
|
||||
0x28, 0x56, 0xba, 0x0d, 0x3b, 0x6d, 0x17, 0x67, 0xd5, 0xb2, 0x6e, 0x5b, 0x61, 0x0b, 0x40, 0x0b,
|
||||
0xd3, 0xe0, 0xba, 0x8f, 0x1d, 0x2a, 0xd4, 0x9a, 0x36, 0x91, 0xee, 0x7b, 0xea, 0x6c, 0xe1, 0xc1,
|
||||
0x56, 0x54, 0x16, 0x25, 0x24, 0xbc, 0xd6, 0xa3, 0x0d, 0xf5, 0x41, 0x60, 0x75, 0xcb, 0x27, 0x98,
|
||||
0xaa, 0x52, 0x94, 0xb8, 0x51, 0x18, 0x15, 0x49, 0x2e, 0xfc, 0x02, 0x98, 0xb0, 0x09, 0xa5, 0xb8,
|
||||
0x49, 0x78, 0xfd, 0x99, 0x8c, 0xaf, 0xe8, 0x6d, 0x41, 0x46, 0x11, 0x9f, 0xf5, 0x27, 0x4b, 0x83,
|
||||
0xbc, 0x76, 0xcd, 0xa4, 0x01, 0x7c, 0xb3, 0x27, 0x01, 0xca, 0x67, 0xdb, 0x21, 0x5b, 0xcd, 0xc3,
|
||||
0x5f, 0x15, 0xbf, 0x88, 0x92, 0x08, 0xfe, 0x6f, 0x81, 0x9c, 0x19, 0x10, 0x3b, 0xba, 0xbb, 0x5f,
|
||||
0x1b, 0x51, 0xec, 0x55, 0x66, 0xa4, 0x0d, 0xb9, 0x2d, 0x86, 0x86, 0x04, 0x68, 0xe9, 0xf7, 0x19,
|
||||
0xf0, 0xd8, 0xa0, 0x25, 0xec, 0x42, 0xa1, 0xcc, 0xe3, 0x9e, 0x15, 0xfa, 0xd8, 0x92, 0x11, 0xa7,
|
||||
0x3c, 0xbe, 0xc7, 0xa9, 0x48, 0x72, 0x59, 0xc9, 0xa7, 0xa6, 0xd3, 0x0c, 0x2d, 0xec, 0xcb, 0x70,
|
||||
0x52, 0xbb, 0xae, 0x49, 0x3a, 0x52, 0x12, 0xb0, 0x0c, 0x00, 0x3d, 0x70, 0xfd, 0x80, 0x63, 0xc8,
|
||||
0xea, 0x75, 0x9e, 0x15, 0x88, 0x9a, 0xa2, 0xa2, 0x84, 0x04, 0xbb, 0xd1, 0x0e, 0x4d, 0xa7, 0x2e,
|
||||
0x4f, 0x5d, 0x65, 0xf1, 0xd7, 0x4c, 0xa7, 0x8e, 0x38, 0x87, 0xe1, 0x5b, 0x26, 0x0d, 0x18, 0x45,
|
||||
0x1e, 0x79, 0x97, 0xd7, 0xb9, 0xa4, 0x92, 0x60, 0xf8, 0x06, 0xab, 0xfa, 0xae, 0x6f, 0x12, 0xaa,
|
||||
0x8f, 0xc7, 0xf8, 0x55, 0x45, 0x45, 0x09, 0x89, 0xd2, 0x2f, 0xf3, 0x83, 0x83, 0x84, 0x95, 0x12,
|
||||
0xf8, 0x38, 0xc8, 0x35, 0x7d, 0x37, 0xf4, 0xa4, 0x97, 0x94, 0xb7, 0x5f, 0x66, 0x44, 0x24, 0x78,
|
||||
0x2c, 0x2a, 0x5b, 0x5d, 0x6d, 0xaa, 0x8a, 0xca, 0xa8, 0x39, 0x8d, 0xf8, 0xf0, 0x7b, 0x1a, 0xc8,
|
||||
0x39, 0xd2, 0x39, 0x2c, 0xe4, 0xde, 0x1c, 0x51, 0x5c, 0x70, 0xf7, 0xc6, 0xe6, 0x0a, 0xcf, 0x0b,
|
||||
0x64, 0xf8, 0x2c, 0xc8, 0x51, 0xc3, 0xf5, 0x88, 0xf4, 0x7a, 0x21, 0x12, 0xaa, 0x31, 0xe2, 0x69,
|
||||
0xbb, 0x38, 0x13, 0xa9, 0xe3, 0x04, 0x24, 0x84, 0xe1, 0x0f, 0x34, 0x00, 0x5a, 0xd8, 0x32, 0xeb,
|
||||
0x98, 0xb7, 0x0c, 0x39, 0x6e, 0xfe, 0x70, 0xc3, 0xfa, 0x55, 0xa5, 0x5e, 0x1c, 0x5a, 0xfc, 0x8d,
|
||||
0x12, 0xd0, 0xf0, 0x43, 0x0d, 0x4c, 0xd3, 0x70, 0xdf, 0x97, 0xab, 0x28, 0x6f, 0x2e, 0xa6, 0xae,
|
||||
0x7e, 0x63, 0xa8, 0xb6, 0xd4, 0x12, 0x00, 0x95, 0xb9, 0x4e, 0xbb, 0x38, 0x9d, 0xa4, 0xa0, 0x2e,
|
||||
0x03, 0xe0, 0x8f, 0x35, 0x90, 0x6f, 0x45, 0x77, 0xf6, 0x04, 0x4f, 0xf8, 0xb7, 0x47, 0x74, 0xb0,
|
||||
0x32, 0xa2, 0xe2, 0x2c, 0x50, 0x7d, 0x80, 0xb2, 0x00, 0xfe, 0x55, 0x03, 0x3a, 0xae, 0x8b, 0x02,
|
||||
0x8f, 0xad, 0x3d, 0xdf, 0x74, 0x02, 0xe2, 0x8b, 0x7e, 0x93, 0xea, 0x79, 0x6e, 0xde, 0x70, 0xef,
|
||||
0xc2, 0x74, 0x2f, 0x5b, 0x59, 0x96, 0xd6, 0xe9, 0xeb, 0x03, 0xcc, 0x40, 0x03, 0x0d, 0xe4, 0x81,
|
||||
0x16, 0xb7, 0x34, 0xfa, 0xe4, 0x08, 0x02, 0x2d, 0xee, 0xa5, 0x64, 0x75, 0x88, 0x3b, 0xa8, 0x04,
|
||||
0x74, 0xe9, 0xc3, 0x6c, 0xba, 0x69, 0x4f, 0x5f, 0xfa, 0xf0, 0xb6, 0x30, 0x56, 0x6c, 0x85, 0xea,
|
||||
0x1a, 0x77, 0xee, 0xbb, 0x23, 0x3a, 0x7b, 0x75, 0x6b, 0xc7, 0x8d, 0x97, 0x22, 0x51, 0x94, 0xb0,
|
||||
0x03, 0xfe, 0x42, 0x03, 0x33, 0xd8, 0x30, 0x88, 0x17, 0x90, 0xba, 0xa8, 0xc5, 0x99, 0xcf, 0xa1,
|
||||
0xdc, 0x2c, 0x48, 0xab, 0x66, 0xd6, 0x93, 0xd0, 0xa8, 0xdb, 0x12, 0xf8, 0x22, 0x38, 0x4f, 0x03,
|
||||
0xd7, 0x27, 0xf5, 0x54, 0x97, 0x0b, 0x3b, 0xed, 0xe2, 0xf9, 0x5a, 0x17, 0x07, 0xa5, 0x24, 0x4b,
|
||||
0x9f, 0x8e, 0x81, 0xe2, 0x7d, 0x32, 0xe3, 0x0c, 0xef, 0xa8, 0x27, 0xc1, 0x38, 0xdf, 0x6e, 0x9d,
|
||||
0x7b, 0x25, 0x9f, 0xe8, 0xdc, 0x38, 0x15, 0x49, 0x2e, 0xab, 0xeb, 0x0c, 0x9f, 0x75, 0x1b, 0x59,
|
||||
0x2e, 0xa8, 0xea, 0x7a, 0x4d, 0x90, 0x51, 0xc4, 0x87, 0xef, 0x81, 0x71, 0x31, 0x27, 0xe1, 0x45,
|
||||
0x75, 0x84, 0x85, 0x11, 0x70, 0x3b, 0x39, 0x14, 0x92, 0x90, 0xbd, 0x05, 0x31, 0xf7, 0xb0, 0x0b,
|
||||
0xe2, 0x3d, 0x2b, 0xd0, 0xf8, 0xff, 0x78, 0x05, 0x2a, 0xfd, 0x47, 0x4b, 0xe7, 0x7d, 0x62, 0xab,
|
||||
0x35, 0x03, 0x5b, 0x04, 0x6e, 0x80, 0x39, 0xf6, 0xc8, 0x40, 0xc4, 0xb3, 0x4c, 0x03, 0x53, 0xfe,
|
||||
0xc6, 0x15, 0x01, 0xa7, 0xc6, 0x2e, 0xb5, 0x14, 0x1f, 0xf5, 0xac, 0x80, 0xaf, 0x00, 0x28, 0x1a,
|
||||
0xef, 0x2e, 0x3d, 0xa2, 0x87, 0x50, 0x2d, 0x74, 0xad, 0x47, 0x02, 0xf5, 0x59, 0x05, 0xab, 0x60,
|
||||
0xde, 0xc2, 0xfb, 0xc4, 0xaa, 0x11, 0x8b, 0x18, 0x81, 0xeb, 0x73, 0x55, 0x62, 0x0a, 0xb0, 0xd0,
|
||||
0x69, 0x17, 0xe7, 0xaf, 0xa5, 0x99, 0xa8, 0x57, 0xbe, 0xb4, 0x92, 0x4e, 0xaf, 0xe4, 0xc6, 0xc5,
|
||||
0x73, 0xe6, 0x37, 0x19, 0xb0, 0x38, 0x38, 0x32, 0xe0, 0xf7, 0xe3, 0x57, 0x97, 0x68, 0xaa, 0xdf,
|
||||
0x1e, 0x55, 0x14, 0xca, 0x67, 0x17, 0xe8, 0x7d, 0x72, 0xc1, 0xef, 0xb0, 0x0e, 0x07, 0x5b, 0xd1,
|
||||
0x9c, 0xe7, 0xad, 0x91, 0x99, 0xc0, 0x40, 0x2a, 0x93, 0xa2, 0x79, 0xc2, 0x16, 0xef, 0x95, 0xb0,
|
||||
0x45, 0x4a, 0x7f, 0xd0, 0xd2, 0x0f, 0xef, 0x38, 0x83, 0xe1, 0x4f, 0x34, 0x30, 0xeb, 0x7a, 0xc4,
|
||||
0x59, 0xdf, 0xdb, 0x7a, 0xf5, 0x4b, 0x22, 0x93, 0xa5, 0xab, 0x76, 0x1e, 0xd0, 0xce, 0x57, 0x6a,
|
||||
0xbb, 0x3b, 0x42, 0xe1, 0x9e, 0xef, 0x7a, 0xb4, 0x72, 0xa1, 0xd3, 0x2e, 0xce, 0xee, 0x76, 0x43,
|
||||
0xa1, 0x34, 0x76, 0xc9, 0x06, 0x0b, 0x9b, 0xc7, 0x01, 0xf1, 0x1d, 0x6c, 0x6d, 0xb8, 0x46, 0x68,
|
||||
0x13, 0x27, 0x10, 0x86, 0xa6, 0x86, 0x44, 0xda, 0x19, 0x87, 0x44, 0x8f, 0x81, 0x6c, 0xe8, 0x5b,
|
||||
0x32, 0x8a, 0xa7, 0xd4, 0x10, 0x14, 0x5d, 0x43, 0x8c, 0x5e, 0x5a, 0x01, 0x63, 0xcc, 0x4e, 0x78,
|
||||
0x09, 0x64, 0x7d, 0x7c, 0xc4, 0xb5, 0x4e, 0x57, 0x26, 0x98, 0x08, 0xc2, 0x47, 0x88, 0xd1, 0x4a,
|
||||
0xff, 0x58, 0x02, 0xb3, 0xa9, 0xbd, 0xc0, 0x45, 0x90, 0x51, 0x93, 0x55, 0x20, 0x95, 0x66, 0xb6,
|
||||
0x36, 0x50, 0xc6, 0xac, 0xc3, 0xe7, 0x55, 0xf1, 0x15, 0xa0, 0x45, 0x55, 0xcf, 0x39, 0x95, 0xb5,
|
||||
0xb4, 0xb1, 0x3a, 0x66, 0x48, 0x54, 0x38, 0x99, 0x0d, 0xa4, 0x21, 0xb3, 0x44, 0xd8, 0x40, 0x1a,
|
||||
0x88, 0xd1, 0x3e, 0xeb, 0x84, 0x2c, 0x1a, 0xd1, 0xe5, 0xce, 0x30, 0xa2, 0x1b, 0xbf, 0xe7, 0x88,
|
||||
0xee, 0x71, 0x90, 0x0b, 0xcc, 0xc0, 0x22, 0xfa, 0x44, 0xf7, 0xcb, 0xe3, 0x3a, 0x23, 0x22, 0xc1,
|
||||
0x83, 0x37, 0xc1, 0x44, 0x9d, 0x34, 0x70, 0x68, 0x05, 0x7a, 0x9e, 0x87, 0x50, 0x75, 0x08, 0x21,
|
||||
0x24, 0xe6, 0xa7, 0x1b, 0x42, 0x2f, 0x8a, 0x00, 0xe0, 0x13, 0x60, 0xc2, 0xc6, 0xc7, 0xa6, 0x1d,
|
||||
0xda, 0xbc, 0x27, 0xd3, 0x84, 0xd8, 0xb6, 0x20, 0xa1, 0x88, 0xc7, 0x2a, 0x23, 0x39, 0x36, 0xac,
|
||||
0x90, 0x9a, 0x2d, 0x22, 0x99, 0x3a, 0xe0, 0xb7, 0xa7, 0xaa, 0x8c, 0x9b, 0x29, 0x3e, 0xea, 0x59,
|
||||
0xc1, 0xc1, 0x4c, 0x87, 0x2f, 0x9e, 0x4a, 0x80, 0x09, 0x12, 0x8a, 0x78, 0xdd, 0x60, 0x52, 0x7e,
|
||||
0x7a, 0x10, 0x98, 0x5c, 0xdc, 0xb3, 0x02, 0x7e, 0x11, 0x4c, 0xda, 0xf8, 0xf8, 0x1a, 0x71, 0x9a,
|
||||
0xc1, 0x81, 0x3e, 0xb3, 0xac, 0xad, 0x66, 0x2b, 0x33, 0x9d, 0x76, 0x71, 0x72, 0x3b, 0x22, 0xa2,
|
||||
0x98, 0xcf, 0x85, 0x4d, 0x47, 0x0a, 0x9f, 0x4f, 0x08, 0x47, 0x44, 0x14, 0xf3, 0x59, 0x07, 0xe1,
|
||||
0xe1, 0x80, 0x25, 0x97, 0x3e, 0xdb, 0xfd, 0x32, 0xdc, 0x13, 0x64, 0x14, 0xf1, 0xe1, 0x2a, 0xc8,
|
||||
0xdb, 0xf8, 0x98, 0xbf, 0xe2, 0xf5, 0x39, 0xae, 0x96, 0xcf, 0x92, 0xb7, 0x25, 0x0d, 0x29, 0x2e,
|
||||
0x97, 0x34, 0x1d, 0x21, 0x39, 0x9f, 0x90, 0x94, 0x34, 0xa4, 0xb8, 0x2c, 0x88, 0x43, 0xc7, 0xbc,
|
||||
0x15, 0x12, 0x21, 0x0c, 0xb9, 0x67, 0x54, 0x10, 0xdf, 0x88, 0x59, 0x28, 0x29, 0xc7, 0x5e, 0xd1,
|
||||
0x76, 0x68, 0x05, 0xa6, 0x67, 0x91, 0xdd, 0x86, 0x7e, 0x81, 0xfb, 0x9f, 0xf7, 0xc9, 0xdb, 0x8a,
|
||||
0x8a, 0x12, 0x12, 0x90, 0x80, 0x31, 0xe2, 0x84, 0xb6, 0xfe, 0x08, 0xbf, 0xd8, 0x87, 0x12, 0x82,
|
||||
0x2a, 0x73, 0x36, 0x9d, 0xd0, 0x46, 0x5c, 0x3d, 0x7c, 0x1e, 0xcc, 0xd8, 0xf8, 0x98, 0x95, 0x03,
|
||||
0xe2, 0x07, 0xec, 0x7d, 0xbf, 0xc0, 0x37, 0x3f, 0xcf, 0x3a, 0xce, 0xed, 0x24, 0x03, 0x75, 0xcb,
|
||||
0xf1, 0x85, 0xa6, 0x93, 0x58, 0x78, 0x31, 0xb1, 0x30, 0xc9, 0x40, 0xdd, 0x72, 0xcc, 0xd3, 0x3e,
|
||||
0xb9, 0x15, 0x9a, 0x3e, 0xa9, 0xeb, 0x8f, 0xf2, 0x26, 0x55, 0xce, 0xf7, 0x05, 0x0d, 0x29, 0x2e,
|
||||
0x6c, 0x45, 0xe3, 0x1e, 0x9d, 0xa7, 0xe1, 0x8d, 0xe1, 0x56, 0xf2, 0x5d, 0x7f, 0xdd, 0xf7, 0xf1,
|
||||
0x89, 0xb8, 0x69, 0x92, 0x83, 0x1e, 0x48, 0x41, 0x0e, 0x5b, 0xd6, 0x6e, 0x43, 0xbf, 0xc4, 0x7d,
|
||||
0x3f, 0xec, 0x1b, 0x44, 0x55, 0x9d, 0x75, 0x06, 0x82, 0x04, 0x16, 0x03, 0x75, 0x1d, 0x16, 0x1a,
|
||||
0x8b, 0xa3, 0x05, 0xdd, 0x65, 0x20, 0x48, 0x60, 0xf1, 0x9d, 0x3a, 0x27, 0xbb, 0x0d, 0xfd, 0xff,
|
||||
0x46, 0xbc, 0x53, 0x06, 0x82, 0x04, 0x16, 0x34, 0x41, 0xd6, 0x71, 0x03, 0x7d, 0x69, 0x24, 0xd7,
|
||||
0x33, 0xbf, 0x70, 0x76, 0xdc, 0x00, 0x31, 0x0c, 0xf8, 0x73, 0x0d, 0x00, 0x2f, 0x0e, 0xd1, 0xc7,
|
||||
0x86, 0x32, 0x45, 0x48, 0x41, 0x96, 0xe3, 0xd8, 0xde, 0x74, 0x02, 0xff, 0x24, 0x7e, 0x47, 0x26,
|
||||
0x72, 0x20, 0x61, 0x05, 0xfc, 0xad, 0x06, 0x1e, 0x49, 0xb6, 0xc9, 0xca, 0xbc, 0x02, 0xf7, 0xc8,
|
||||
0xf5, 0x61, 0x87, 0x79, 0xc5, 0x75, 0xad, 0x8a, 0xde, 0x69, 0x17, 0x1f, 0x59, 0xef, 0x83, 0x8a,
|
||||
0xfa, 0xda, 0x02, 0xff, 0xa8, 0x81, 0x79, 0x59, 0x45, 0x13, 0x16, 0x16, 0xb9, 0x03, 0xc9, 0xb0,
|
||||
0x1d, 0x98, 0xc6, 0x11, 0x7e, 0x54, 0xbf, 0x4b, 0xf7, 0xf0, 0x51, 0xaf, 0x69, 0xf0, 0x2f, 0x1a,
|
||||
0x98, 0xae, 0x13, 0x8f, 0x38, 0x75, 0xe2, 0x18, 0xcc, 0xd6, 0xe5, 0xa1, 0x8c, 0x0d, 0xd2, 0xb6,
|
||||
0x6e, 0x24, 0x20, 0x84, 0x99, 0x65, 0x69, 0xe6, 0x74, 0x92, 0x75, 0xda, 0x2e, 0x5e, 0x8c, 0x97,
|
||||
0x26, 0x39, 0xa8, 0xcb, 0x4a, 0xf8, 0x91, 0x06, 0x66, 0xe3, 0x03, 0x10, 0x57, 0xca, 0xca, 0x08,
|
||||
0xe3, 0x80, 0xb7, 0xaf, 0xeb, 0xdd, 0x80, 0x28, 0x6d, 0x01, 0xfc, 0x93, 0xc6, 0x3a, 0xb5, 0xe8,
|
||||
0xdd, 0x47, 0xf5, 0x12, 0xf7, 0xe5, 0x3b, 0x43, 0xf7, 0xa5, 0x42, 0x10, 0xae, 0xbc, 0x1c, 0xb7,
|
||||
0x82, 0x8a, 0x73, 0xda, 0x2e, 0x2e, 0x24, 0x3d, 0xa9, 0x18, 0x28, 0x69, 0x21, 0xfc, 0x91, 0x06,
|
||||
0xa6, 0x49, 0xdc, 0x71, 0x53, 0xfd, 0xf1, 0xa1, 0x38, 0xb1, 0x6f, 0x13, 0x2f, 0x5e, 0xea, 0x09,
|
||||
0x16, 0x45, 0x5d, 0xd8, 0xac, 0x83, 0x24, 0xc7, 0xd8, 0xf6, 0x2c, 0xa2, 0xff, 0xff, 0x90, 0x3b,
|
||||
0xc8, 0x4d, 0xa1, 0x17, 0x45, 0x00, 0xf0, 0x32, 0xc8, 0x3b, 0xa1, 0x65, 0xe1, 0x7d, 0x8b, 0xe8,
|
||||
0x4f, 0xf0, 0x5e, 0x44, 0x4d, 0x31, 0x77, 0x24, 0x1d, 0x29, 0x89, 0x45, 0xf6, 0x4e, 0x4a, 0xe5,
|
||||
0x19, 0x9c, 0x03, 0xd9, 0x43, 0x22, 0x7f, 0x0e, 0x46, 0xec, 0x4f, 0x58, 0x07, 0xb9, 0x16, 0xb6,
|
||||
0xc2, 0xe8, 0xa9, 0x37, 0xe4, 0x1a, 0x8d, 0x84, 0xf2, 0x17, 0x33, 0x2f, 0x68, 0x8b, 0xb7, 0x35,
|
||||
0x70, 0xb1, 0x7f, 0xfa, 0x3f, 0x54, 0xb3, 0x7e, 0xa5, 0x81, 0xf9, 0x9e, 0x4c, 0xef, 0x63, 0xd1,
|
||||
0xad, 0x6e, 0x8b, 0xde, 0x18, 0x76, 0xca, 0xd6, 0x02, 0xdf, 0x74, 0x9a, 0xbc, 0x4f, 0x49, 0x9a,
|
||||
0xf7, 0x53, 0x0d, 0xcc, 0xa5, 0x93, 0xe7, 0x61, 0xfa, 0xab, 0x74, 0x3b, 0x03, 0x2e, 0xf6, 0x6f,
|
||||
0xaf, 0xa0, 0xaf, 0xde, 0x91, 0xa3, 0x79, 0x8f, 0xf7, 0x9b, 0xdd, 0x7d, 0xa0, 0x81, 0xa9, 0x9b,
|
||||
0x4a, 0x2e, 0xfa, 0xb9, 0x70, 0xe8, 0x93, 0x80, 0xa8, 0x5a, 0xc5, 0x0c, 0x8a, 0x92, 0xb8, 0xa5,
|
||||
0x3f, 0x6b, 0x60, 0xa1, 0x6f, 0x19, 0x66, 0x0f, 0x56, 0x6c, 0x59, 0xee, 0x91, 0x18, 0xe8, 0x24,
|
||||
0xa6, 0xa5, 0xeb, 0x9c, 0x8a, 0x24, 0x37, 0xe1, 0xbd, 0xcc, 0xe7, 0xe5, 0xbd, 0xd2, 0xdf, 0x34,
|
||||
0xb0, 0x74, 0xaf, 0x48, 0x7c, 0x28, 0x47, 0xba, 0x0a, 0xf2, 0xb2, 0x85, 0x3a, 0xe1, 0xc7, 0x29,
|
||||
0x5f, 0x0d, 0xb2, 0x68, 0xf0, 0xff, 0x90, 0x11, 0x7f, 0x95, 0xde, 0xd7, 0xc0, 0x5c, 0x8d, 0xf8,
|
||||
0x2d, 0xd3, 0x20, 0x88, 0x34, 0x88, 0x4f, 0x1c, 0x83, 0xc0, 0x35, 0x30, 0xc9, 0x7f, 0xa7, 0xf3,
|
||||
0xb0, 0x11, 0x0d, 0xb1, 0xe7, 0xa5, 0xcb, 0x27, 0x77, 0x22, 0x06, 0x8a, 0x65, 0xd4, 0xc0, 0x3b,
|
||||
0x33, 0x70, 0xe0, 0xbd, 0x04, 0xc6, 0xbc, 0x78, 0x1c, 0x98, 0x67, 0x5c, 0x3e, 0x01, 0xe4, 0xd4,
|
||||
0xd2, 0xdf, 0x35, 0xd0, 0xef, 0xbf, 0x55, 0x60, 0x0b, 0x4c, 0x50, 0x61, 0x9c, 0x74, 0xde, 0xee,
|
||||
0x03, 0x3a, 0x2f, 0xbd, 0x55, 0x71, 0x4d, 0x44, 0xd4, 0x08, 0x8c, 0xf9, 0xcf, 0xc0, 0x95, 0xd0,
|
||||
0xa9, 0xcb, 0x01, 0xde, 0xb4, 0xf0, 0x5f, 0x75, 0x5d, 0xd0, 0x90, 0xe2, 0xc2, 0x4b, 0x62, 0xd4,
|
||||
0x94, 0x98, 0xdf, 0x44, 0x63, 0xa6, 0xca, 0x95, 0x3b, 0x77, 0x0b, 0xe7, 0x3e, 0xbe, 0x5b, 0x38,
|
||||
0xf7, 0xc9, 0xdd, 0xc2, 0xb9, 0xef, 0x76, 0x0a, 0xda, 0x9d, 0x4e, 0x41, 0xfb, 0xb8, 0x53, 0xd0,
|
||||
0x3e, 0xe9, 0x14, 0xb4, 0x7f, 0x75, 0x0a, 0xda, 0xcf, 0x3e, 0x2d, 0x9c, 0xfb, 0xe6, 0x84, 0x34,
|
||||
0xed, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x16, 0xda, 0x75, 0x14, 0x43, 0x2a, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -113,6 +113,16 @@ message CustomResourceConversion {
|
|||
// alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
|
||||
// +optional
|
||||
optional WebhookClientConfig webhookClientConfig = 2;
|
||||
|
||||
// ConversionReviewVersions is an ordered list of preferred `ConversionReview`
|
||||
// versions the Webhook expects. API server will try to use first version in
|
||||
// the list which it supports. If none of the versions specified in this list
|
||||
// supported by API server, conversion will fail for this object.
|
||||
// If a persisted Webhook configuration specifies allowed versions and does not
|
||||
// include any versions known to the API Server, calls to the webhook will fail.
|
||||
// Default to `['v1beta1']`.
|
||||
// +optional
|
||||
repeated string conversionReviewVersions = 3;
|
||||
}
|
||||
|
||||
// CustomResourceDefinition represents a resource that should be exposed on the API server. Its name MUST be in the format
|
||||
|
|
|
@ -91,6 +91,16 @@ type CustomResourceConversion struct {
|
|||
// alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
|
||||
// +optional
|
||||
WebhookClientConfig *WebhookClientConfig `json:"webhookClientConfig,omitempty" protobuf:"bytes,2,name=webhookClientConfig"`
|
||||
|
||||
// ConversionReviewVersions is an ordered list of preferred `ConversionReview`
|
||||
// versions the Webhook expects. API server will try to use first version in
|
||||
// the list which it supports. If none of the versions specified in this list
|
||||
// supported by API server, conversion will fail for this object.
|
||||
// If a persisted Webhook configuration specifies allowed versions and does not
|
||||
// include any versions known to the API Server, calls to the webhook will fail.
|
||||
// Default to `['v1beta1']`.
|
||||
// +optional
|
||||
ConversionReviewVersions []string `json:"conversionReviewVersions,omitempty" protobuf:"bytes,3,rep,name=conversionReviewVersions"`
|
||||
}
|
||||
|
||||
// WebhookClientConfig contains the information to make a TLS
|
||||
|
|
|
@ -296,6 +296,7 @@ func Convert_apiextensions_CustomResourceColumnDefinition_To_v1beta1_CustomResou
|
|||
func autoConvert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(in *CustomResourceConversion, out *apiextensions.CustomResourceConversion, s conversion.Scope) error {
|
||||
out.Strategy = apiextensions.ConversionStrategyType(in.Strategy)
|
||||
out.WebhookClientConfig = (*apiextensions.WebhookClientConfig)(unsafe.Pointer(in.WebhookClientConfig))
|
||||
out.ConversionReviewVersions = *(*[]string)(unsafe.Pointer(&in.ConversionReviewVersions))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -307,6 +308,7 @@ func Convert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceCon
|
|||
func autoConvert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(in *apiextensions.CustomResourceConversion, out *CustomResourceConversion, s conversion.Scope) error {
|
||||
out.Strategy = ConversionStrategyType(in.Strategy)
|
||||
out.WebhookClientConfig = (*WebhookClientConfig)(unsafe.Pointer(in.WebhookClientConfig))
|
||||
out.ConversionReviewVersions = *(*[]string)(unsafe.Pointer(&in.ConversionReviewVersions))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,11 @@ func (in *CustomResourceConversion) DeepCopyInto(out *CustomResourceConversion)
|
|||
*out = new(WebhookClientConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ConversionReviewVersions != nil {
|
||||
in, out := &in.ConversionReviewVersions, &out.ConversionReviewVersions
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ go_library(
|
|||
importpath = "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation",
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/validation:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/features:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
|
|
|
@ -24,12 +24,14 @@ import (
|
|||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
genericvalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
|
||||
validationutil "k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/apiserver/pkg/util/webhook"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation"
|
||||
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
|
||||
)
|
||||
|
@ -113,6 +115,10 @@ func ValidateCustomResourceDefinitionVersion(version *apiextensions.CustomResour
|
|||
|
||||
// ValidateCustomResourceDefinitionSpec statically validates
|
||||
func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefinitionSpec, fldPath *field.Path) field.ErrorList {
|
||||
return validateCustomResourceDefinitionSpec(spec, true, fldPath)
|
||||
}
|
||||
|
||||
func validateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefinitionSpec, requireRecognizedVersion bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if len(spec.Group) == 0 {
|
||||
|
@ -205,7 +211,7 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi
|
|||
}
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, ValidateCustomResourceConversion(spec.Conversion, fldPath.Child("conversion"))...)
|
||||
allErrs = append(allErrs, validateCustomResourceConversion(spec.Conversion, requireRecognizedVersion, fldPath.Child("conversion"))...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
@ -225,8 +231,66 @@ func validateEnumStrings(fldPath *field.Path, value string, accepted []string, r
|
|||
return field.ErrorList{field.NotSupported(fldPath, value, accepted)}
|
||||
}
|
||||
|
||||
var acceptedConversionReviewVersion = []string{v1beta1.SchemeGroupVersion.Version}
|
||||
|
||||
func isAcceptedConversionReviewVersion(v string) bool {
|
||||
for _, version := range acceptedConversionReviewVersion {
|
||||
if v == version {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func validateConversionReviewVersions(versions []string, requireRecognizedVersion bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(versions) < 1 {
|
||||
allErrs = append(allErrs, field.Required(fldPath, ""))
|
||||
} else {
|
||||
seen := map[string]bool{}
|
||||
hasAcceptedVersion := false
|
||||
for i, v := range versions {
|
||||
if seen[v] {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Index(i), v, "duplicate version"))
|
||||
continue
|
||||
}
|
||||
seen[v] = true
|
||||
for _, errString := range utilvalidation.IsDNS1035Label(v) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Index(i), v, errString))
|
||||
}
|
||||
if isAcceptedConversionReviewVersion(v) {
|
||||
hasAcceptedVersion = true
|
||||
}
|
||||
}
|
||||
if requireRecognizedVersion && !hasAcceptedVersion {
|
||||
allErrs = append(allErrs, field.Invalid(
|
||||
fldPath, versions,
|
||||
fmt.Sprintf("none of the versions accepted by this server. accepted version(s) are %v",
|
||||
strings.Join(acceptedConversionReviewVersion, ", "))))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// hasValidConversionReviewVersion return true if there is a valid version or if the list is empty.
|
||||
func hasValidConversionReviewVersionOrEmpty(versions []string) bool {
|
||||
if len(versions) < 1 {
|
||||
return true
|
||||
}
|
||||
for _, v := range versions {
|
||||
if isAcceptedConversionReviewVersion(v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidateCustomResourceConversion statically validates
|
||||
func ValidateCustomResourceConversion(conversion *apiextensions.CustomResourceConversion, fldPath *field.Path) field.ErrorList {
|
||||
return validateCustomResourceConversion(conversion, true, fldPath)
|
||||
}
|
||||
|
||||
func validateCustomResourceConversion(conversion *apiextensions.CustomResourceConversion, requireRecognizedVersion bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if conversion == nil {
|
||||
return allErrs
|
||||
|
@ -250,15 +314,22 @@ func ValidateCustomResourceConversion(conversion *apiextensions.CustomResourceCo
|
|||
allErrs = append(allErrs, webhook.ValidateWebhookService(fldPath.Child("webhookClientConfig").Child("service"), cc.Service.Name, cc.Service.Namespace, cc.Service.Path)...)
|
||||
}
|
||||
}
|
||||
} else if conversion.WebhookClientConfig != nil {
|
||||
allErrs = append(allErrs, validateConversionReviewVersions(conversion.ConversionReviewVersions, requireRecognizedVersion, fldPath.Child("conversionReviewVersions"))...)
|
||||
} else {
|
||||
if conversion.WebhookClientConfig != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("webhookClientConfig"), "should not be set when strategy is not set to Webhook"))
|
||||
}
|
||||
if len(conversion.ConversionReviewVersions) > 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("conversionReviewVersions"), "should not be set when strategy is not set to Webhook"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateCustomResourceDefinitionSpecUpdate statically validates
|
||||
func ValidateCustomResourceDefinitionSpecUpdate(spec, oldSpec *apiextensions.CustomResourceDefinitionSpec, established bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := ValidateCustomResourceDefinitionSpec(spec, fldPath)
|
||||
requireRecognizedVersion := oldSpec.Conversion == nil || hasValidConversionReviewVersionOrEmpty(oldSpec.Conversion.ConversionReviewVersions)
|
||||
allErrs := validateCustomResourceDefinitionSpec(spec, requireRecognizedVersion, fldPath)
|
||||
|
||||
if established {
|
||||
// these effect the storage and cannot be changed therefore
|
||||
|
|
|
@ -35,6 +35,9 @@ func required(path ...string) validationMatch {
|
|||
func invalid(path ...string) validationMatch {
|
||||
return validationMatch{path: field.NewPath(path[0], path[1:]...), errorType: field.ErrorTypeInvalid}
|
||||
}
|
||||
func invalidIndex(index int, path ...string) validationMatch {
|
||||
return validationMatch{path: field.NewPath(path[0], path[1:]...).Index(index), errorType: field.ErrorTypeInvalid}
|
||||
}
|
||||
func unsupported(path ...string) validationMatch {
|
||||
return validationMatch{path: field.NewPath(path[0], path[1:]...), errorType: field.ErrorTypeNotSupported}
|
||||
}
|
||||
|
@ -65,7 +68,7 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
|||
errors []validationMatch
|
||||
}{
|
||||
{
|
||||
name: "webhookconfig: blank URL",
|
||||
name: "webhookconfig: both service and URL provided",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
|
@ -109,7 +112,7 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig: both service and URL provided",
|
||||
name: "webhookconfig: blank URL",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
|
@ -189,6 +192,207 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
|||
forbidden("spec", "conversion", "webhookClientConfig"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ConversionReviewVersions_should_not_be_set",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
ConversionReviewVersions: []string{"v1beta1"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
forbidden("spec", "conversion", "conversionReviewVersions"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig: invalid ConversionReviewVersion",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"invalid-version"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
invalid("spec", "conversion", "conversionReviewVersions"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig: invalid ConversionReviewVersion version string",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"0v"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
invalidIndex(0, "spec", "conversion", "conversionReviewVersions"),
|
||||
invalid("spec", "conversion", "conversionReviewVersions"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig: at least one valid ConversionReviewVersion",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"invalid-version", "v1beta1"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig: duplicate ConversionReviewVersion",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"v1beta1", "v1beta1"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
invalidIndex(1, "spec", "conversion", "conversionReviewVersions"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing_webhookconfig",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
|
@ -646,6 +850,10 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
// duplicate defaulting behaviour
|
||||
if tc.resource.Spec.Conversion != nil && tc.resource.Spec.Conversion.Strategy == apiextensions.WebhookConverter && len(tc.resource.Spec.Conversion.ConversionReviewVersions) == 0 {
|
||||
tc.resource.Spec.Conversion.ConversionReviewVersions = []string{"v1beta1"}
|
||||
}
|
||||
errs := ValidateCustomResourceDefinition(tc.resource)
|
||||
seenErrs := make([]bool, len(errs))
|
||||
|
||||
|
@ -679,6 +887,231 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) {
|
|||
resource *apiextensions.CustomResourceDefinition
|
||||
errors []validationMatch
|
||||
}{
|
||||
{
|
||||
name: "webhookconfig: should pass on invalid ConversionReviewVersion with old invalid versions",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "42"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"invalid-version"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
old: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "42"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"invalid-version_0, invalid-version"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig: should fail on invalid ConversionReviewVersion with old valid versions",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "42"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"invalid-version"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
old: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "42"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"v1beta1", "invalid-version"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
invalid("spec", "conversion", "conversionReviewVersions"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig: should fail on invalid ConversionReviewVersion with missing old versions",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "42"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
ConversionReviewVersions: []string{"invalid-version"},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
old: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "42"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
invalid("spec", "conversion", "conversionReviewVersions"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "unchanged",
|
||||
old: &apiextensions.CustomResourceDefinition{
|
||||
|
|
|
@ -48,6 +48,11 @@ func (in *CustomResourceConversion) DeepCopyInto(out *CustomResourceConversion)
|
|||
*out = new(WebhookClientConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ConversionReviewVersions != nil {
|
||||
in, out := &in.ConversionReviewVersions, &out.ConversionReviewVersions
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ type webhookConverter struct {
|
|||
restClient *rest.RESTClient
|
||||
name string
|
||||
nopConverter nopConverter
|
||||
|
||||
conversionReviewVersions []string
|
||||
}
|
||||
|
||||
func webhookClientConfigForCRD(crd *internal.CustomResourceDefinition) *webhook.ClientConfig {
|
||||
|
@ -96,6 +98,8 @@ func (f *webhookConverterFactory) NewWebhookConverter(validVersions map[schema.G
|
|||
restClient: restClient,
|
||||
name: crd.Name,
|
||||
nopConverter: nopConverter{validVersions: validVersions},
|
||||
|
||||
conversionReviewVersions: crd.Spec.Conversion.ConversionReviewVersions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -136,6 +140,16 @@ func (c *webhookConverter) Convert(in, out, context interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// hasConversionReviewVersion check whether a version is accepted by a given webhook.
|
||||
func (c *webhookConverter) hasConversionReviewVersion(v string) bool {
|
||||
for _, b := range c.conversionReviewVersions {
|
||||
if b == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func createConversionReview(obj runtime.Object, apiVersion string) *v1beta1.ConversionReview {
|
||||
listObj, isList := obj.(*unstructured.UnstructuredList)
|
||||
var objects []runtime.RawExtension
|
||||
|
@ -216,6 +230,12 @@ func (c *webhookConverter) ConvertToVersion(in runtime.Object, target runtime.Gr
|
|||
}
|
||||
}
|
||||
|
||||
// Currently converter only supports `v1beta1` ConversionReview
|
||||
// TODO: Make CRD webhooks caller capable of sending/receiving multiple ConversionReview versions
|
||||
if !c.hasConversionReviewVersion(v1beta1.SchemeGroupVersion.Version) {
|
||||
return nil, fmt.Errorf("webhook does not accept v1beta1 ConversionReview")
|
||||
}
|
||||
|
||||
request := createConversionReview(in, toGV.String())
|
||||
if len(request.Request.Objects) == 0 {
|
||||
if !isList {
|
||||
|
|
|
@ -94,6 +94,12 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta
|
|||
}
|
||||
}
|
||||
|
||||
// Currently dispatcher only supports `v1beta1` AdmissionReview
|
||||
// TODO: Make the dispatcher capable of sending multiple AdmissionReview versions
|
||||
if !util.HasAdmissionReviewVersion(v1beta1.SchemeGroupVersion.Version, h) {
|
||||
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("webhook does not accept v1beta1 AdmissionReview")}
|
||||
}
|
||||
|
||||
// Make the webhook request
|
||||
request := request.CreateAdmissionReview(attr)
|
||||
client, err := a.cm.HookClient(util.HookClientConfigForWebhook(h))
|
||||
|
|
|
@ -212,6 +212,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Operations: []registrationv1beta1.OperationType{registrationv1beta1.Create},
|
||||
}},
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
},
|
||||
|
@ -222,6 +223,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("allow"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
ExpectAnnotations: map[string]string{"allow.example.com/key1": "value1"},
|
||||
|
@ -233,6 +235,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("disallow"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ErrorContains: "without explanation",
|
||||
},
|
||||
|
@ -243,6 +246,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("disallowReason"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
|
||||
ErrorContains: "you shall not pass",
|
||||
|
@ -260,6 +264,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Operator: metav1.LabelSelectorOpIn,
|
||||
}},
|
||||
},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
|
||||
ExpectAllow: true,
|
||||
|
@ -277,6 +282,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Operator: metav1.LabelSelectorOpNotIn,
|
||||
}},
|
||||
},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
},
|
||||
|
@ -288,18 +294,21 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyIgnore,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}, {
|
||||
Name: "internalErr B",
|
||||
ClientConfig: ccfgSVC("internalErr"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyIgnore,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}, {
|
||||
Name: "internalErr C",
|
||||
ClientConfig: ccfgSVC("internalErr"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyIgnore,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
|
||||
ExpectAllow: true,
|
||||
|
@ -311,16 +320,19 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("internalErr"),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
Rules: matchEverythingRules,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}, {
|
||||
Name: "internalErr B",
|
||||
ClientConfig: ccfgSVC("internalErr"),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
Rules: matchEverythingRules,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}, {
|
||||
Name: "internalErr C",
|
||||
ClientConfig: ccfgSVC("internalErr"),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
Rules: matchEverythingRules,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: false,
|
||||
},
|
||||
|
@ -332,18 +344,21 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyFail,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}, {
|
||||
Name: "internalErr B",
|
||||
ClientConfig: ccfgSVC("internalErr"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyFail,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}, {
|
||||
Name: "internalErr C",
|
||||
ClientConfig: ccfgSVC("internalErr"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyFail,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: false,
|
||||
},
|
||||
|
@ -354,6 +369,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgURL("allow"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
ExpectAnnotations: map[string]string{"allow.example.com/key1": "value1"},
|
||||
|
@ -365,6 +381,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgURL("disallow"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ErrorContains: "without explanation",
|
||||
}, {
|
||||
|
@ -375,6 +392,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
FailurePolicy: &policyIgnore,
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
},
|
||||
|
@ -386,6 +404,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
FailurePolicy: &policyFail,
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ErrorContains: "Webhook response was absent",
|
||||
},
|
||||
|
@ -399,6 +418,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
}},
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
SideEffects: &sideEffectsSome,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
IsDryRun: true,
|
||||
ExpectAllow: true,
|
||||
|
@ -411,6 +431,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
SideEffects: &sideEffectsUnknown,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
IsDryRun: true,
|
||||
ErrorContains: "does not support dry run",
|
||||
|
@ -423,6 +444,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
SideEffects: &sideEffectsNone,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
IsDryRun: true,
|
||||
ExpectAllow: true,
|
||||
|
@ -436,6 +458,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
SideEffects: &sideEffectsSome,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
IsDryRun: true,
|
||||
ErrorContains: "does not support dry run",
|
||||
|
@ -448,6 +471,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
SideEffects: &sideEffectsNoneOnDryRun,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
IsDryRun: true,
|
||||
ExpectAllow: true,
|
||||
|
@ -460,6 +484,7 @@ func NewNonMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgURL("invalidAnnotation"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
},
|
||||
|
@ -480,6 +505,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("removeLabel"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
AdditionalLabels: map[string]string{"remove": "me"},
|
||||
|
@ -493,6 +519,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("addLabel"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
ExpectLabels: map[string]string{"pod.name": "my-pod", "added": "test"},
|
||||
|
@ -504,6 +531,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("addLabel"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
IsCRD: true,
|
||||
ExpectAllow: true,
|
||||
|
@ -516,6 +544,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("removeLabel"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
IsCRD: true,
|
||||
ExpectAllow: true,
|
||||
|
@ -530,6 +559,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
|||
ClientConfig: ccfgSVC("invalidMutation"),
|
||||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ErrorContains: "invalid character",
|
||||
},
|
||||
|
@ -541,6 +571,7 @@ func NewMutatingTestCases(url *url.URL) []Test {
|
|||
Rules: matchEverythingRules,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
SideEffects: &sideEffectsUnknown,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
IsDryRun: true,
|
||||
ErrorContains: "does not support dry run",
|
||||
|
@ -572,6 +603,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
|||
Rules: newMatchEverythingRules(),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyIgnore,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
ExpectCacheMiss: true,
|
||||
|
@ -584,6 +616,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
|||
Rules: newMatchEverythingRules(),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyIgnore,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
ExpectCacheMiss: true,
|
||||
|
@ -596,6 +629,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
|||
Rules: newMatchEverythingRules(),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyIgnore,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
ExpectCacheMiss: false,
|
||||
|
@ -608,6 +642,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
|||
Rules: newMatchEverythingRules(),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyIgnore,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
ExpectCacheMiss: true,
|
||||
|
@ -620,6 +655,7 @@ func NewCachedClientTestcases(url *url.URL) []CachedTest {
|
|||
Rules: newMatchEverythingRules(),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
FailurePolicy: &policyIgnore,
|
||||
AdmissionReviewVersions: []string{"v1beta1"},
|
||||
}},
|
||||
ExpectAllow: true,
|
||||
ExpectCacheMiss: false,
|
||||
|
|
|
@ -40,3 +40,13 @@ func HookClientConfigForWebhook(w *v1beta1.Webhook) webhook.ClientConfig {
|
|||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// HasAdmissionReviewVersion check whether a version is accepted by a given webhook.
|
||||
func HasAdmissionReviewVersion(a string, w *v1beta1.Webhook) bool {
|
||||
for _, b := range w.AdmissionReviewVersions {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -108,6 +108,12 @@ func (d *validatingDispatcher) callHook(ctx context.Context, h *v1beta1.Webhook,
|
|||
}
|
||||
}
|
||||
|
||||
// Currently dispatcher only supports `v1beta1` AdmissionReview
|
||||
// TODO: Make the dispatcher capable of sending multiple AdmissionReview versions
|
||||
if !util.HasAdmissionReviewVersion(v1beta1.SchemeGroupVersion.Version, h) {
|
||||
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("webhook does not accept v1beta1 AdmissionReviewRequest")}
|
||||
}
|
||||
|
||||
// Make the webhook request
|
||||
request := request.CreateAdmissionReview(attr)
|
||||
client, err := d.cm.HookClient(util.HookClientConfigForWebhook(h))
|
||||
|
|
Loading…
Reference in New Issue