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
065b6529
Commit
065b6529
authored
Nov 18, 2016
by
Michail Kargakis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kubectl: add create pdb subcommand
parent
86c515eb
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
220 additions
and
3 deletions
+220
-3
test-cmd.sh
hack/make-rules/test-cmd.sh
+12
-0
known-flags.txt
hack/verify-flags/known-flags.txt
+1
-0
create.go
pkg/kubectl/cmd/create.go
+1
-0
create_pdb.go
pkg/kubectl/cmd/create_pdb.go
+90
-0
create_quota.go
pkg/kubectl/cmd/create_quota.go
+2
-2
create_serviceaccount.go
pkg/kubectl/cmd/create_serviceaccount.go
+1
-1
factory.go
pkg/kubectl/cmd/util/factory.go
+1
-0
pdb.go
pkg/kubectl/pdb.go
+102
-0
intstr.go
pkg/util/intstr/intstr.go
+10
-0
No files found.
hack/make-rules/test-cmd.sh
View file @
065b6529
...
@@ -342,6 +342,7 @@ runTests() {
...
@@ -342,6 +342,7 @@ runTests() {
deployment_image_field
=
"(index .spec.template.spec.containers 0).image"
deployment_image_field
=
"(index .spec.template.spec.containers 0).image"
deployment_second_image_field
=
"(index .spec.template.spec.containers 1).image"
deployment_second_image_field
=
"(index .spec.template.spec.containers 1).image"
change_cause_annotation
=
'.*kubernetes.io/change-cause.*'
change_cause_annotation
=
'.*kubernetes.io/change-cause.*'
pdb_min_available
=
".spec.minAvailable"
# Passing no arguments to create is an error
# Passing no arguments to create is an error
!
kubectl create
!
kubectl create
...
@@ -590,6 +591,16 @@ runTests() {
...
@@ -590,6 +591,16 @@ runTests() {
# Post-condition: configmap exists and has expected values
# Post-condition: configmap exists and has expected values
kube::test::get_object_assert
'configmap/test-configmap --namespace=test-kubectl-describe-pod'
"{{
$id_field
}}"
'test-configmap'
kube::test::get_object_assert
'configmap/test-configmap --namespace=test-kubectl-describe-pod'
"{{
$id_field
}}"
'test-configmap'
### Create a pod disruption budget
# Command
kubectl create pdb test-pdb
--selector
=
app
=
rails
--min-available
=
2
--namespace
=
test-kubectl-describe-pod
# Post-condition: pdb exists and has expected values
kube::test::get_object_assert
'pdb/test-pdb --namespace=test-kubectl-describe-pod'
"{{
$pdb_min_available
}}"
'2'
# Command
kubectl create pdb test-pdb-2
--selector
=
app
=
rails
--min-available
=
50%
--namespace
=
test-kubectl-describe-pod
# Post-condition: pdb exists and has expected values
kube::test::get_object_assert
'pdb/test-pdb-2 --namespace=test-kubectl-describe-pod'
"{{
$pdb_min_available
}}"
'50%'
# Create a pod that consumes secret, configmap, and downward API keys as envs
# Create a pod that consumes secret, configmap, and downward API keys as envs
kube::test::get_object_assert
'pods --namespace=test-kubectl-describe-pod'
"{{range.items}}{{
$id_field
}}:{{end}}"
''
kube::test::get_object_assert
'pods --namespace=test-kubectl-describe-pod'
"{{range.items}}{{
$id_field
}}:{{end}}"
''
kubectl create
-f
hack/testdata/pod-with-api-env.yaml
--namespace
=
test-kubectl-describe-pod
kubectl create
-f
hack/testdata/pod-with-api-env.yaml
--namespace
=
test-kubectl-describe-pod
...
@@ -602,6 +613,7 @@ runTests() {
...
@@ -602,6 +613,7 @@ runTests() {
kubectl delete pod env-test-pod
--namespace
=
test-kubectl-describe-pod
kubectl delete pod env-test-pod
--namespace
=
test-kubectl-describe-pod
kubectl delete secret test-secret
--namespace
=
test-kubectl-describe-pod
kubectl delete secret test-secret
--namespace
=
test-kubectl-describe-pod
kubectl delete configmap test-configmap
--namespace
=
test-kubectl-describe-pod
kubectl delete configmap test-configmap
--namespace
=
test-kubectl-describe-pod
kubectl delete pdb/test-pdb pdb/test-pdb-2
--namespace
=
test-kubectl-describe-pod
kubectl delete namespace test-kubectl-describe-pod
kubectl delete namespace test-kubectl-describe-pod
### Create two PODs
### Create two PODs
...
...
hack/verify-flags/known-flags.txt
View file @
065b6529
...
@@ -388,6 +388,7 @@ mesos-launch-grace-period
...
@@ -388,6 +388,7 @@ mesos-launch-grace-period
mesos-master
mesos-master
mesos-sandbox-overlay
mesos-sandbox-overlay
mesos-user
mesos-user
min-available
min-pr-number
min-pr-number
min-request-timeout
min-request-timeout
min-resync-period
min-resync-period
...
...
pkg/kubectl/cmd/create.go
View file @
065b6529
...
@@ -88,6 +88,7 @@ func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
...
@@ -88,6 +88,7 @@ func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
cmd
.
AddCommand
(
NewCmdCreateService
(
f
,
out
,
errOut
))
cmd
.
AddCommand
(
NewCmdCreateService
(
f
,
out
,
errOut
))
cmd
.
AddCommand
(
NewCmdCreateDeployment
(
f
,
out
))
cmd
.
AddCommand
(
NewCmdCreateDeployment
(
f
,
out
))
cmd
.
AddCommand
(
NewCmdCreateClusterRoleBinding
(
f
,
out
))
cmd
.
AddCommand
(
NewCmdCreateClusterRoleBinding
(
f
,
out
))
cmd
.
AddCommand
(
NewCmdCreatePodDisruptionBudget
(
f
,
out
))
return
cmd
return
cmd
}
}
...
...
pkg/kubectl/cmd/create_pdb.go
0 → 100644
View file @
065b6529
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
cmd
import
(
"fmt"
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
)
var
(
pdbLong
=
templates
.
LongDesc
(
`
Create a pod disruption budget with the specified name, selector, and desired minimum available pods`
)
pdbExample
=
templates
.
Examples
(
`
# Create a pod disruption budget named my-pdb that will select all pods with the app=rails label
# and require at least one of them being available at any point in time.
kubectl create poddisruptionbudget my-pdb --selector=app=rails --min-available=1
# Create a pod disruption budget named my-pdb that will select all pods with the app=nginx label
# and require at least half of the pods selected to be available at any point in time.
kubectl create pdb my-pdb --selector=app=nginx --min-available=50%`
)
)
// NewCmdCreatePodDisruptionBudget is a macro command to create a new pod disruption budget.
func
NewCmdCreatePodDisruptionBudget
(
f
cmdutil
.
Factory
,
cmdOut
io
.
Writer
)
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"poddisruptionbudget NAME --selector=SELECTOR --min-available=N [--dry-run]"
,
Aliases
:
[]
string
{
"pdb"
},
Short
:
"Create a pod disruption budget with the specified name."
,
Long
:
pdbLong
,
Example
:
pdbExample
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
err
:=
CreatePodDisruptionBudget
(
f
,
cmdOut
,
cmd
,
args
)
cmdutil
.
CheckErr
(
err
)
},
}
cmdutil
.
AddApplyAnnotationFlags
(
cmd
)
cmdutil
.
AddValidateFlags
(
cmd
)
cmdutil
.
AddPrinterFlags
(
cmd
)
cmdutil
.
AddGeneratorFlags
(
cmd
,
cmdutil
.
PodDisruptionBudgetV1GeneratorName
)
cmd
.
Flags
()
.
String
(
"min-available"
,
"1"
,
"The minimum number or percentage of available pods this budget requires."
)
cmd
.
Flags
()
.
String
(
"selector"
,
""
,
"A label selector to use for this budget. Only equality-based selector requirements are supported."
)
return
cmd
}
// CreatePodDisruptionBudget implements the behavior to run the create pdb command.
func
CreatePodDisruptionBudget
(
f
cmdutil
.
Factory
,
cmdOut
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
)
error
{
name
,
err
:=
NameFromCommandArgs
(
cmd
,
args
)
if
err
!=
nil
{
return
err
}
var
generator
kubectl
.
StructuredGenerator
switch
generatorName
:=
cmdutil
.
GetFlagString
(
cmd
,
"generator"
);
generatorName
{
case
cmdutil
.
PodDisruptionBudgetV1GeneratorName
:
generator
=
&
kubectl
.
PodDisruptionBudgetV1Generator
{
Name
:
name
,
MinAvailable
:
cmdutil
.
GetFlagString
(
cmd
,
"min-available"
),
Selector
:
cmdutil
.
GetFlagString
(
cmd
,
"selector"
),
}
default
:
return
cmdutil
.
UsageError
(
cmd
,
fmt
.
Sprintf
(
"Generator: %s not supported."
,
generatorName
))
}
return
RunCreateSubcommand
(
f
,
cmd
,
cmdOut
,
&
CreateSubcommandOptions
{
Name
:
name
,
StructuredGenerator
:
generator
,
DryRun
:
cmdutil
.
GetFlagBool
(
cmd
,
"dry-run"
),
OutputFormat
:
cmdutil
.
GetFlagString
(
cmd
,
"output"
),
})
}
pkg/kubectl/cmd/create_quota.go
View file @
065b6529
...
@@ -33,10 +33,10 @@ var (
...
@@ -33,10 +33,10 @@ var (
quotaExample
=
templates
.
Examples
(
`
quotaExample
=
templates
.
Examples
(
`
# Create a new resourcequota named my-quota
# Create a new resourcequota named my-quota
$
kubectl create quota my-quota --hard=cpu=1,memory=1G,pods=2,services=3,replicationcontrollers=2,resourcequotas=1,secrets=5,persistentvolumeclaims=10
kubectl create quota my-quota --hard=cpu=1,memory=1G,pods=2,services=3,replicationcontrollers=2,resourcequotas=1,secrets=5,persistentvolumeclaims=10
# Create a new resourcequota named best-effort
# Create a new resourcequota named best-effort
$
kubectl create quota best-effort --hard=pods=100 --scopes=BestEffort`
)
kubectl create quota best-effort --hard=pods=100 --scopes=BestEffort`
)
)
)
// NewCmdCreateQuota is a macro command to create a new quota
// NewCmdCreateQuota is a macro command to create a new quota
...
...
pkg/kubectl/cmd/create_serviceaccount.go
View file @
065b6529
...
@@ -33,7 +33,7 @@ var (
...
@@ -33,7 +33,7 @@ var (
serviceAccountExample
=
templates
.
Examples
(
`
serviceAccountExample
=
templates
.
Examples
(
`
# Create a new service account named my-service-account
# Create a new service account named my-service-account
$
kubectl create serviceaccount my-service-account`
)
kubectl create serviceaccount my-service-account`
)
)
)
// NewCmdCreateServiceAccount is a macro command to create a new service account
// NewCmdCreateServiceAccount is a macro command to create a new service account
...
...
pkg/kubectl/cmd/util/factory.go
View file @
065b6529
...
@@ -211,6 +211,7 @@ const (
...
@@ -211,6 +211,7 @@ const (
ConfigMapV1GeneratorName
=
"configmap/v1"
ConfigMapV1GeneratorName
=
"configmap/v1"
ClusterRoleBindingV1GeneratorName
=
"clusterrolebinding.rbac.authorization.k8s.io/v1alpha1"
ClusterRoleBindingV1GeneratorName
=
"clusterrolebinding.rbac.authorization.k8s.io/v1alpha1"
ClusterV1Beta1GeneratorName
=
"cluster/v1beta1"
ClusterV1Beta1GeneratorName
=
"cluster/v1beta1"
PodDisruptionBudgetV1GeneratorName
=
"poddisruptionbudget/v1beta1"
)
)
// DefaultGenerators returns the set of default generators for use in Factory instances
// DefaultGenerators returns the set of default generators for use in Factory instances
...
...
pkg/kubectl/pdb.go
0 → 100644
View file @
065b6529
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
kubectl
import
(
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/intstr"
)
// PodDisruptionBudgetV1Generator supports stable generation of a pod disruption budget.
type
PodDisruptionBudgetV1Generator
struct
{
Name
string
MinAvailable
string
Selector
string
}
// Ensure it supports the generator pattern that uses parameters specified during construction.
var
_
StructuredGenerator
=
&
PodDisruptionBudgetV1Generator
{}
func
(
PodDisruptionBudgetV1Generator
)
ParamNames
()
[]
GeneratorParam
{
return
[]
GeneratorParam
{
{
"name"
,
true
},
{
"mim-available"
,
true
},
{
"selector"
,
true
},
}
}
func
(
s
PodDisruptionBudgetV1Generator
)
Generate
(
params
map
[
string
]
interface
{})
(
runtime
.
Object
,
error
)
{
err
:=
ValidateParams
(
s
.
ParamNames
(),
params
)
if
err
!=
nil
{
return
nil
,
err
}
name
,
isString
:=
params
[
"name"
]
.
(
string
)
if
!
isString
{
return
nil
,
fmt
.
Errorf
(
"expected string, saw %v for 'name'"
,
name
)
}
minAvailable
,
isString
:=
params
[
"mim-available"
]
.
(
string
)
if
!
isString
{
return
nil
,
fmt
.
Errorf
(
"expected string, found %v"
,
minAvailable
)
}
selector
,
isString
:=
params
[
"selecor"
]
.
(
string
)
if
!
isString
{
return
nil
,
fmt
.
Errorf
(
"expected string, found %v"
,
selector
)
}
delegate
:=
&
PodDisruptionBudgetV1Generator
{
Name
:
name
,
MinAvailable
:
minAvailable
,
Selector
:
selector
}
return
delegate
.
StructuredGenerate
()
}
// StructuredGenerate outputs a pod disruption budget object using the configured fields.
func
(
s
*
PodDisruptionBudgetV1Generator
)
StructuredGenerate
()
(
runtime
.
Object
,
error
)
{
if
err
:=
s
.
validate
();
err
!=
nil
{
return
nil
,
err
}
selector
,
err
:=
unversioned
.
ParseToLabelSelector
(
s
.
Selector
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
policy
.
PodDisruptionBudget
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
s
.
Name
,
},
Spec
:
policy
.
PodDisruptionBudgetSpec
{
MinAvailable
:
intstr
.
Parse
(
s
.
MinAvailable
),
Selector
:
selector
,
},
},
nil
}
// validate validates required fields are set to support structured generation.
func
(
s
*
PodDisruptionBudgetV1Generator
)
validate
()
error
{
if
len
(
s
.
Name
)
==
0
{
return
fmt
.
Errorf
(
"name must be specified"
)
}
if
len
(
s
.
Selector
)
==
0
{
return
fmt
.
Errorf
(
"a selector must be specified"
)
}
if
len
(
s
.
MinAvailable
)
==
0
{
return
fmt
.
Errorf
(
"the minimim number of available pods required must be specified"
)
}
return
nil
}
pkg/util/intstr/intstr.go
View file @
065b6529
...
@@ -70,6 +70,16 @@ func FromString(val string) IntOrString {
...
@@ -70,6 +70,16 @@ func FromString(val string) IntOrString {
return
IntOrString
{
Type
:
String
,
StrVal
:
val
}
return
IntOrString
{
Type
:
String
,
StrVal
:
val
}
}
}
// Parse the given string and try to convert it to an integer before
// setting it as a string value.
func
Parse
(
val
string
)
IntOrString
{
i
,
err
:=
strconv
.
Atoi
(
val
)
if
err
!=
nil
{
return
FromString
(
val
)
}
return
FromInt
(
i
)
}
// UnmarshalJSON implements the json.Unmarshaller interface.
// UnmarshalJSON implements the json.Unmarshaller interface.
func
(
intstr
*
IntOrString
)
UnmarshalJSON
(
value
[]
byte
)
error
{
func
(
intstr
*
IntOrString
)
UnmarshalJSON
(
value
[]
byte
)
error
{
if
value
[
0
]
==
'"'
{
if
value
[
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