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
2b0de599
Commit
2b0de599
authored
May 15, 2017
by
Anirudh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PDB MaxUnavailable: API changes
parent
4a1483ef
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
81 additions
and
12 deletions
+81
-12
types.go
pkg/apis/policy/types.go
+8
-1
types.go
pkg/apis/policy/v1beta1/types.go
+7
-1
validation.go
pkg/apis/policy/validation/validation.go
+14
-2
validation_test.go
pkg/apis/policy/validation/validation_test.go
+30
-2
storage_test.go
...gistry/policy/poddisruptionbudget/storage/storage_test.go
+4
-2
strategy_test.go
pkg/registry/policy/poddisruptionbudget/strategy_test.go
+18
-4
No files found.
pkg/apis/policy/types.go
View file @
2b0de599
...
@@ -28,12 +28,19 @@ type PodDisruptionBudgetSpec struct {
...
@@ -28,12 +28,19 @@ type PodDisruptionBudgetSpec struct {
// absence of the evicted pod. So for example you can prevent all voluntary
// absence of the evicted pod. So for example you can prevent all voluntary
// evictions by specifying "100%".
// evictions by specifying "100%".
// +optional
// +optional
MinAvailable
intstr
.
IntOrString
MinAvailable
*
intstr
.
IntOrString
// Label query over pods whose evictions are managed by the disruption
// Label query over pods whose evictions are managed by the disruption
// budget.
// budget.
// +optional
// +optional
Selector
*
metav1
.
LabelSelector
Selector
*
metav1
.
LabelSelector
// An eviction is allowed if at most "maxUnavailable" pods selected by
// "selector" are unavailable after the eviction, i.e. even in absence of
// the evicted pod. For example, one can prevent all voluntary evictions
// by specifying 0. This is a mutually exclusive setting with "minAvailable".
// +optional
MaxUnavailable
*
intstr
.
IntOrString
}
}
// PodDisruptionBudgetStatus represents information about the status of a
// PodDisruptionBudgetStatus represents information about the status of a
...
...
pkg/apis/policy/v1beta1/types.go
View file @
2b0de599
...
@@ -27,11 +27,17 @@ type PodDisruptionBudgetSpec struct {
...
@@ -27,11 +27,17 @@ type PodDisruptionBudgetSpec struct {
// "selector" will still be available after the eviction, i.e. even in the
// "selector" will still be available after the eviction, i.e. even in the
// absence of the evicted pod. So for example you can prevent all voluntary
// absence of the evicted pod. So for example you can prevent all voluntary
// evictions by specifying "100%".
// evictions by specifying "100%".
MinAvailable
intstr
.
IntOrString
`json:"minAvailable,omitempty" protobuf:"bytes,1,opt,name=minAvailable"`
MinAvailable
*
intstr
.
IntOrString
`json:"minAvailable,omitempty" protobuf:"bytes,1,opt,name=minAvailable"`
// Label query over pods whose evictions are managed by the disruption
// Label query over pods whose evictions are managed by the disruption
// budget.
// budget.
Selector
*
metav1
.
LabelSelector
`json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"`
Selector
*
metav1
.
LabelSelector
`json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"`
// An eviction is allowed if at most "maxUnavailable" pods selected by
// "selector" are unavailable after the eviction, i.e. even in absence of
// the evicted pod. For example, one can prevent all voluntary evictions
// by specifying 0. This is a mutually exclusive setting with "minAvailable".
MaxUnavailable
*
intstr
.
IntOrString
`json:"maxUnavailable,omitempty" protobuf:"bytes,3,opt,name=maxUnavailable"`
}
}
// PodDisruptionBudgetStatus represents information about the status of a
// PodDisruptionBudgetStatus represents information about the status of a
...
...
pkg/apis/policy/validation/validation.go
View file @
2b0de599
...
@@ -50,8 +50,20 @@ func ValidatePodDisruptionBudgetUpdate(pdb, oldPdb *policy.PodDisruptionBudget)
...
@@ -50,8 +50,20 @@ func ValidatePodDisruptionBudgetUpdate(pdb, oldPdb *policy.PodDisruptionBudget)
func
ValidatePodDisruptionBudgetSpec
(
spec
policy
.
PodDisruptionBudgetSpec
,
fldPath
*
field
.
Path
)
field
.
ErrorList
{
func
ValidatePodDisruptionBudgetSpec
(
spec
policy
.
PodDisruptionBudgetSpec
,
fldPath
*
field
.
Path
)
field
.
ErrorList
{
allErrs
:=
field
.
ErrorList
{}
allErrs
:=
field
.
ErrorList
{}
allErrs
=
append
(
allErrs
,
extensionsvalidation
.
ValidatePositiveIntOrPercent
(
spec
.
MinAvailable
,
fldPath
.
Child
(
"minAvailable"
))
...
)
if
spec
.
MinAvailable
!=
nil
&&
spec
.
MaxUnavailable
!=
nil
{
allErrs
=
append
(
allErrs
,
extensionsvalidation
.
IsNotMoreThan100Percent
(
spec
.
MinAvailable
,
fldPath
.
Child
(
"minAvailable"
))
...
)
allErrs
=
append
(
allErrs
,
field
.
Invalid
(
fldPath
,
spec
,
"minAvailable and maxUnavailable cannot be both set"
))
}
if
spec
.
MinAvailable
!=
nil
{
allErrs
=
append
(
allErrs
,
extensionsvalidation
.
ValidatePositiveIntOrPercent
(
*
spec
.
MinAvailable
,
fldPath
.
Child
(
"minAvailable"
))
...
)
allErrs
=
append
(
allErrs
,
extensionsvalidation
.
IsNotMoreThan100Percent
(
*
spec
.
MinAvailable
,
fldPath
.
Child
(
"minAvailable"
))
...
)
}
if
spec
.
MaxUnavailable
!=
nil
{
allErrs
=
append
(
allErrs
,
extensionsvalidation
.
ValidatePositiveIntOrPercent
(
*
spec
.
MaxUnavailable
,
fldPath
.
Child
(
"maxUnavailable"
))
...
)
allErrs
=
append
(
allErrs
,
extensionsvalidation
.
IsNotMoreThan100Percent
(
*
spec
.
MaxUnavailable
,
fldPath
.
Child
(
"maxUnavailable"
))
...
)
}
allErrs
=
append
(
allErrs
,
unversionedvalidation
.
ValidateLabelSelector
(
spec
.
Selector
,
fldPath
.
Child
(
"selector"
))
...
)
allErrs
=
append
(
allErrs
,
unversionedvalidation
.
ValidateLabelSelector
(
spec
.
Selector
,
fldPath
.
Child
(
"selector"
))
...
)
return
allErrs
return
allErrs
...
...
pkg/apis/policy/validation/validation_test.go
View file @
2b0de599
...
@@ -25,6 +25,20 @@ import (
...
@@ -25,6 +25,20 @@ import (
)
)
func
TestValidatePodDisruptionBudgetSpec
(
t
*
testing
.
T
)
{
func
TestValidatePodDisruptionBudgetSpec
(
t
*
testing
.
T
)
{
minAvailable
:=
intstr
.
FromString
(
"0%"
)
maxUnavailable
:=
intstr
.
FromString
(
"10%"
)
spec
:=
policy
.
PodDisruptionBudgetSpec
{
MinAvailable
:
&
minAvailable
,
MaxUnavailable
:
&
maxUnavailable
,
}
errs
:=
ValidatePodDisruptionBudgetSpec
(
spec
,
field
.
NewPath
(
"foo"
))
if
len
(
errs
)
==
0
{
t
.
Errorf
(
"unexpected success for %v"
,
spec
)
}
}
func
TestValidateMinAvailablePodDisruptionBudgetSpec
(
t
*
testing
.
T
)
{
successCases
:=
[]
intstr
.
IntOrString
{
successCases
:=
[]
intstr
.
IntOrString
{
intstr
.
FromString
(
"0%"
),
intstr
.
FromString
(
"0%"
),
intstr
.
FromString
(
"1%"
),
intstr
.
FromString
(
"1%"
),
...
@@ -35,7 +49,7 @@ func TestValidatePodDisruptionBudgetSpec(t *testing.T) {
...
@@ -35,7 +49,7 @@ func TestValidatePodDisruptionBudgetSpec(t *testing.T) {
}
}
for
_
,
c
:=
range
successCases
{
for
_
,
c
:=
range
successCases
{
spec
:=
policy
.
PodDisruptionBudgetSpec
{
spec
:=
policy
.
PodDisruptionBudgetSpec
{
MinAvailable
:
c
,
MinAvailable
:
&
c
,
}
}
errs
:=
ValidatePodDisruptionBudgetSpec
(
spec
,
field
.
NewPath
(
"foo"
))
errs
:=
ValidatePodDisruptionBudgetSpec
(
spec
,
field
.
NewPath
(
"foo"
))
if
len
(
errs
)
!=
0
{
if
len
(
errs
)
!=
0
{
...
@@ -52,7 +66,7 @@ func TestValidatePodDisruptionBudgetSpec(t *testing.T) {
...
@@ -52,7 +66,7 @@ func TestValidatePodDisruptionBudgetSpec(t *testing.T) {
}
}
for
_
,
c
:=
range
failureCases
{
for
_
,
c
:=
range
failureCases
{
spec
:=
policy
.
PodDisruptionBudgetSpec
{
spec
:=
policy
.
PodDisruptionBudgetSpec
{
MinAvailable
:
c
,
MinAvailable
:
&
c
,
}
}
errs
:=
ValidatePodDisruptionBudgetSpec
(
spec
,
field
.
NewPath
(
"foo"
))
errs
:=
ValidatePodDisruptionBudgetSpec
(
spec
,
field
.
NewPath
(
"foo"
))
if
len
(
errs
)
==
0
{
if
len
(
errs
)
==
0
{
...
@@ -61,6 +75,20 @@ func TestValidatePodDisruptionBudgetSpec(t *testing.T) {
...
@@ -61,6 +75,20 @@ func TestValidatePodDisruptionBudgetSpec(t *testing.T) {
}
}
}
}
func
TestValidateMinAvailablePodAndMaxUnavailableDisruptionBudgetSpec
(
t
*
testing
.
T
)
{
c1
:=
intstr
.
FromString
(
"10%"
)
c2
:=
intstr
.
FromInt
(
1
)
spec
:=
policy
.
PodDisruptionBudgetSpec
{
MinAvailable
:
&
c1
,
MaxUnavailable
:
&
c2
,
}
errs
:=
ValidatePodDisruptionBudgetSpec
(
spec
,
field
.
NewPath
(
"foo"
))
if
len
(
errs
)
==
0
{
t
.
Errorf
(
"unexpected success for %v"
,
spec
)
}
}
func
TestValidatePodDisruptionBudgetStatus
(
t
*
testing
.
T
)
{
func
TestValidatePodDisruptionBudgetStatus
(
t
*
testing
.
T
)
{
successCases
:=
[]
policy
.
PodDisruptionBudgetStatus
{
successCases
:=
[]
policy
.
PodDisruptionBudgetStatus
{
{
PodDisruptionsAllowed
:
10
},
{
PodDisruptionsAllowed
:
10
},
...
...
pkg/registry/policy/poddisruptionbudget/storage/storage_test.go
View file @
2b0de599
...
@@ -51,6 +51,7 @@ func createPodDisruptionBudget(storage *REST, pdb policy.PodDisruptionBudget, t
...
@@ -51,6 +51,7 @@ func createPodDisruptionBudget(storage *REST, pdb policy.PodDisruptionBudget, t
}
}
func
validNewPodDisruptionBudget
()
*
policy
.
PodDisruptionBudget
{
func
validNewPodDisruptionBudget
()
*
policy
.
PodDisruptionBudget
{
minAvailable
:=
intstr
.
FromInt
(
7
)
return
&
policy
.
PodDisruptionBudget
{
return
&
policy
.
PodDisruptionBudget
{
ObjectMeta
:
metav1
.
ObjectMeta
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"foo"
,
Name
:
"foo"
,
...
@@ -59,7 +60,7 @@ func validNewPodDisruptionBudget() *policy.PodDisruptionBudget {
...
@@ -59,7 +60,7 @@ func validNewPodDisruptionBudget() *policy.PodDisruptionBudget {
},
},
Spec
:
policy
.
PodDisruptionBudgetSpec
{
Spec
:
policy
.
PodDisruptionBudgetSpec
{
Selector
:
&
metav1
.
LabelSelector
{
MatchLabels
:
map
[
string
]
string
{
"a"
:
"b"
}},
Selector
:
&
metav1
.
LabelSelector
{
MatchLabels
:
map
[
string
]
string
{
"a"
:
"b"
}},
MinAvailable
:
intstr
.
FromInt
(
7
)
,
MinAvailable
:
&
minAvailable
,
},
},
Status
:
policy
.
PodDisruptionBudgetStatus
{},
Status
:
policy
.
PodDisruptionBudgetStatus
{},
}
}
...
@@ -98,10 +99,11 @@ func TestStatusUpdate(t *testing.T) {
...
@@ -98,10 +99,11 @@ func TestStatusUpdate(t *testing.T) {
}
}
obtainedPdb
:=
obj
.
(
*
policy
.
PodDisruptionBudget
)
obtainedPdb
:=
obj
.
(
*
policy
.
PodDisruptionBudget
)
minAvailable
:=
intstr
.
FromInt
(
8
)
update
:=
policy
.
PodDisruptionBudget
{
update
:=
policy
.
PodDisruptionBudget
{
ObjectMeta
:
obtainedPdb
.
ObjectMeta
,
ObjectMeta
:
obtainedPdb
.
ObjectMeta
,
Spec
:
policy
.
PodDisruptionBudgetSpec
{
Spec
:
policy
.
PodDisruptionBudgetSpec
{
MinAvailable
:
intstr
.
FromInt
(
8
)
,
MinAvailable
:
&
minAvailable
,
},
},
Status
:
policy
.
PodDisruptionBudgetStatus
{
Status
:
policy
.
PodDisruptionBudgetStatus
{
ExpectedPods
:
8
,
ExpectedPods
:
8
,
...
...
pkg/registry/policy/poddisruptionbudget/strategy_test.go
View file @
2b0de599
...
@@ -35,10 +35,11 @@ func TestPodDisruptionBudgetStrategy(t *testing.T) {
...
@@ -35,10 +35,11 @@ func TestPodDisruptionBudgetStrategy(t *testing.T) {
}
}
validSelector
:=
map
[
string
]
string
{
"a"
:
"b"
}
validSelector
:=
map
[
string
]
string
{
"a"
:
"b"
}
minAvailable
:=
intstr
.
FromInt
(
3
)
pdb
:=
&
policy
.
PodDisruptionBudget
{
pdb
:=
&
policy
.
PodDisruptionBudget
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"abc"
,
Namespace
:
metav1
.
NamespaceDefault
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"abc"
,
Namespace
:
metav1
.
NamespaceDefault
},
Spec
:
policy
.
PodDisruptionBudgetSpec
{
Spec
:
policy
.
PodDisruptionBudgetSpec
{
MinAvailable
:
intstr
.
FromInt
(
3
)
,
MinAvailable
:
&
minAvailable
,
Selector
:
&
metav1
.
LabelSelector
{
MatchLabels
:
validSelector
},
Selector
:
&
metav1
.
LabelSelector
{
MatchLabels
:
validSelector
},
},
},
}
}
...
@@ -77,7 +78,16 @@ func TestPodDisruptionBudgetStrategy(t *testing.T) {
...
@@ -77,7 +78,16 @@ func TestPodDisruptionBudgetStrategy(t *testing.T) {
newPdb
.
Spec
.
Selector
=
pdb
.
Spec
.
Selector
newPdb
.
Spec
.
Selector
=
pdb
.
Spec
.
Selector
// Changing MinAvailable? Also no.
// Changing MinAvailable? Also no.
newPdb
.
Spec
.
MinAvailable
=
intstr
.
FromString
(
"28%"
)
newMinAvailable
:=
intstr
.
FromString
(
"28%"
)
newPdb
.
Spec
.
MinAvailable
=
&
newMinAvailable
Strategy
.
PrepareForUpdate
(
ctx
,
newPdb
,
pdb
)
errs
=
Strategy
.
ValidateUpdate
(
ctx
,
newPdb
,
pdb
)
if
len
(
errs
)
==
0
{
t
.
Errorf
(
"Expected a validation error since updates are disallowed on poddisruptionbudgets."
)
}
maxUnavailable
:=
intstr
.
FromString
(
"28%"
)
newPdb
.
Spec
.
MaxUnavailable
=
&
maxUnavailable
Strategy
.
PrepareForUpdate
(
ctx
,
newPdb
,
pdb
)
Strategy
.
PrepareForUpdate
(
ctx
,
newPdb
,
pdb
)
errs
=
Strategy
.
ValidateUpdate
(
ctx
,
newPdb
,
pdb
)
errs
=
Strategy
.
ValidateUpdate
(
ctx
,
newPdb
,
pdb
)
if
len
(
errs
)
==
0
{
if
len
(
errs
)
==
0
{
...
@@ -93,12 +103,16 @@ func TestPodDisruptionBudgetStatusStrategy(t *testing.T) {
...
@@ -93,12 +103,16 @@ func TestPodDisruptionBudgetStatusStrategy(t *testing.T) {
if
StatusStrategy
.
AllowCreateOnUpdate
()
{
if
StatusStrategy
.
AllowCreateOnUpdate
()
{
t
.
Errorf
(
"PodDisruptionBudgetStatus should not allow create on update"
)
t
.
Errorf
(
"PodDisruptionBudgetStatus should not allow create on update"
)
}
}
oldMinAvailable
:=
intstr
.
FromInt
(
3
)
newMinAvailable
:=
intstr
.
FromInt
(
2
)
validSelector
:=
map
[
string
]
string
{
"a"
:
"b"
}
validSelector
:=
map
[
string
]
string
{
"a"
:
"b"
}
oldPdb
:=
&
policy
.
PodDisruptionBudget
{
oldPdb
:=
&
policy
.
PodDisruptionBudget
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"abc"
,
Namespace
:
metav1
.
NamespaceDefault
,
ResourceVersion
:
"10"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"abc"
,
Namespace
:
metav1
.
NamespaceDefault
,
ResourceVersion
:
"10"
},
Spec
:
policy
.
PodDisruptionBudgetSpec
{
Spec
:
policy
.
PodDisruptionBudgetSpec
{
Selector
:
&
metav1
.
LabelSelector
{
MatchLabels
:
validSelector
},
Selector
:
&
metav1
.
LabelSelector
{
MatchLabels
:
validSelector
},
MinAvailable
:
intstr
.
FromInt
(
3
)
,
MinAvailable
:
&
oldMinAvailable
,
},
},
Status
:
policy
.
PodDisruptionBudgetStatus
{
Status
:
policy
.
PodDisruptionBudgetStatus
{
PodDisruptionsAllowed
:
1
,
PodDisruptionsAllowed
:
1
,
...
@@ -111,7 +125,7 @@ func TestPodDisruptionBudgetStatusStrategy(t *testing.T) {
...
@@ -111,7 +125,7 @@ func TestPodDisruptionBudgetStatusStrategy(t *testing.T) {
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"abc"
,
Namespace
:
metav1
.
NamespaceDefault
,
ResourceVersion
:
"9"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"abc"
,
Namespace
:
metav1
.
NamespaceDefault
,
ResourceVersion
:
"9"
},
Spec
:
policy
.
PodDisruptionBudgetSpec
{
Spec
:
policy
.
PodDisruptionBudgetSpec
{
Selector
:
&
metav1
.
LabelSelector
{
MatchLabels
:
validSelector
},
Selector
:
&
metav1
.
LabelSelector
{
MatchLabels
:
validSelector
},
MinAvailable
:
intstr
.
FromInt
(
2
)
,
MinAvailable
:
&
newMinAvailable
,
},
},
Status
:
policy
.
PodDisruptionBudgetStatus
{
Status
:
policy
.
PodDisruptionBudgetStatus
{
PodDisruptionsAllowed
:
0
,
PodDisruptionsAllowed
:
0
,
...
...
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