Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
f7dff472
Commit
f7dff472
authored
Mar 04, 2019
by
Mehdy Bohlool
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add AdmissionReviewVersions to admissionregistration and default it
parent
9eebfe7a
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
389 additions
and
110 deletions
+389
-110
fuzzer.go
pkg/apis/admissionregistration/fuzzer/fuzzer.go
+1
-0
types.go
pkg/apis/admissionregistration/types.go
+9
-0
defaults.go
pkg/apis/admissionregistration/v1beta1/defaults.go
+4
-0
validation.go
pkg/apis/admissionregistration/validation/validation.go
+75
-2
validation_test.go
pkg/apis/admissionregistration/validation/validation_test.go
+228
-100
strategy.go
...sionregistration/mutatingwebhookconfiguration/strategy.go
+1
-3
strategy.go
...onregistration/validatingwebhookconfiguration/strategy.go
+2
-5
types.go
...ing/src/k8s.io/api/admissionregistration/v1beta1/types.go
+11
-0
dispatcher.go
...erver/pkg/admission/plugin/webhook/mutating/dispatcher.go
+6
-0
testcase.go
...piserver/pkg/admission/plugin/webhook/testing/testcase.go
+36
-0
client_config.go
...server/pkg/admission/plugin/webhook/util/client_config.go
+10
-0
dispatcher.go
...ver/pkg/admission/plugin/webhook/validating/dispatcher.go
+6
-0
No files found.
pkg/apis/admissionregistration/fuzzer/fuzzer.go
View file @
f7dff472
...
...
@@ -43,6 +43,7 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
i
:=
int32
(
30
)
obj
.
TimeoutSeconds
=
&
i
}
obj
.
AdmissionReviewVersions
=
[]
string
{
"v1beta1"
}
},
}
}
pkg/apis/admissionregistration/types.go
View file @
f7dff472
...
...
@@ -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
...
...
pkg/apis/admissionregistration/v1beta1/defaults.go
View file @
f7dff472
...
...
@@ -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
)
{
...
...
pkg/apis/admissionregistration/validation/validation.go
View file @
f7dff472
...
...
@@ -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
)
)
}
pkg/apis/admissionregistration/validation/validation_test.go
View file @
f7dff472
...
...
@@ -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"
,
...
...
@@ -49,9 +56,63 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) {
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
)
}
}
})
}
}
pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go
View file @
f7dff472
...
...
@@ -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
...
...
pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go
View file @
f7dff472
...
...
@@ -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
...
...
staging/src/k8s.io/api/admissionregistration/v1beta1/types.go
View file @
f7dff472
...
...
@@ -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
...
...
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go
View file @
f7dff472
...
...
@@ -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
))
...
...
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/testing/testcase.go
View file @
f7dff472
...
...
@@ -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
,
...
...
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/util/client_config.go
View file @
f7dff472
...
...
@@ -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
}
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go
View file @
f7dff472
...
...
@@ -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
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment